public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 00/40] C++ify target_ops, toward multi-target
@ 2018-04-14 19:09 Pedro Alves
  2018-04-14 19:10 ` [PATCH 02/40] make-target-delegates: line break between return type and function name Pedro Alves
                   ` (41 more replies)
  0 siblings, 42 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:09 UTC (permalink / raw)
  To: gdb-patches

Here's another chunk from the multi-target branch.

This converts target_ops to a C++ class with virtual methods.

The reason this is part of the multi-target effort is that with
multi-target, we will want to be able to instantiate the remote, core,
etc. targets more than once at the same time.  In order to get there,
there are globals associated with these targets that will naturally
need to be made per-instance.  Perhaps naively, one of the first
things I did in the branch was to go ahead and convert target_ops to a
proper C++ class with virtual methods, thinking about how a C++ class
makes it easier to associate data with each instance, and also
thinking about how the current target_ops is really more the vtable
than the object, and it is preferable to avoid duplicating the whole
vtable in memory for each target instance...  In the end, I'm
convinced this paid off.

The hurdle is that doing this requires touching _every_ target in the
tree.  There's no partial transition possible.  I've worked on the
branch sitting on top of a version of this patch that only did a
partial transition, ignoring many native target_ops instances, but in
order to continue with upstreaming the multi-target work, I converted
all targets now, the best I could.  There are certainly many of native
targets here that I have no way to test.  My hope with posting this a
bit early (I'm missing some ChangeLogs) is that maybe someone will be
able to lend a hand with testing on their favorite port while I finish
that up and work through any review comments as they come.

There are actually three across-all-targets changes in this series.

  - target_ops function pointers -> virtual methods
  - target_ops use bool throughout
  - target_ops::open -> target factories (the last patch in the series)

I'm sending it all together thinking that that might save testing
rounds to those willing to lend a hand with testing.

And it goes without saying, but, testing help would be really
appreciated!

For testing and review convenience, I've pushed this to the
users/palves/target_ops-cxx branch, along with the few other related
patches that I posted this week that haven't been merged to master
yet.

The multi-target work will require at least one more round of touching
prototypes of some target methods, but I think that will be a smaller
patch (once I manage to split it cleanly from the rest of the branch).

After this, the main multi-target changes will be (in no particular
order):

 - per-inferior thread lists
 - a target stack per-inferior
 - use thread and inferior pointers more throughout instead of ptid_t
 - getting rid of more global state in the core and remote targets
 - actually instantiate multiple copies of core and remote targets
 - user interface, documentation, tests, etc.

Though that's still around 150 patches of fixes of fixes in the branch
to clean up, so it'll take a bit to get there.  Meanwhile, I'd
appreciate getting this chunk in, since it's a large burden to
maintain it off trunk.

Pedro Alves (40):
  Convert struct target_ops to C++
  make-target-delegates: line break between return type and function
    name
  target_ops/C++: exec target
  target_ops/C++: core target
  target_ops/C++: ctf/tfile targets
  target_ops/C++: spu-multiarch
  target_ops/C++: ravenscar-thread
  target_ops/C++: bsd-uthread
  target_ops/C++: bfd-target
  target_ops/C++: record targets
  target_ops/C++: remote/extended-remote targets
  target_ops/C++: target remote-sim
  target_ops/C++: GNU/Linux + x86/AMD64
  target_ops/C++: PPC/PPC64 GNU/Linux
  target_ops/C++: Solaris/procfs
  target_ops/C++: Windows targets
  target_ops/C++: macOS/Darwin target
  target_ops/C++: linux_trad_target, MIPS and Alpha GNU/Linux
  target_ops/C++: AIX target
  target_ops/C++: ARM GNU/Linux
  target_ops/C++: Aarch64 GNU/Linux
  target_ops/C++: HP-PA GNU/Linux
  target_ops/C++: IA-64 GNU/Linux
  target_ops/C++: m32r GNU/Linux
  target_ops/C++: m68k GNU/Linux
  target_ops/C++: s390 GNU/Linux
  target_ops/C++: SPARC GNU/Linux
  target_ops/C++: SPU/Linux
  target_ops/C++: Tile-Gx GNU/Linux
  target_ops/C++: Xtensa GNU/Linux
  target_ops/C++: Base FreeBSD target
  target_ops/C++: Generic i386/AMD64 BSD targets
  target_ops/C++: The rest of the BSD targets
  target_ops/C++: bsd_kvm_add_target, BSD libkvm target
  target_ops/C++: NTO/QNX, nto-procfs.c
  target_ops/C++: go32/DJGPP
  target_ops/C++: The Hurd
  target_ops: Use bool throughout
  linux_nat_target: More low methods
  target factories, target open and multiple instances of targets

 gdb/aarch64-fbsd-nat.c                             |   27 +-
 gdb/aarch64-linux-nat.c                            |  227 +-
 gdb/aix-thread.c                                   |  163 +-
 gdb/alpha-bsd-nat.c                                |   25 +-
 gdb/alpha-linux-nat.c                              |   17 +-
 gdb/amd64-bsd-nat.c                                |   24 +-
 gdb/amd64-bsd-nat.h                                |   44 +
 gdb/amd64-fbsd-nat.c                               |   26 +-
 gdb/amd64-linux-nat.c                              |   53 +-
 gdb/amd64-nat.h                                    |    5 -
 gdb/amd64-nbsd-nat.c                               |   10 +-
 gdb/amd64-obsd-nat.c                               |    6 +-
 gdb/arm-fbsd-nat.c                                 |   35 +-
 gdb/arm-linux-nat.c                                |  185 +-
 gdb/arm-nbsd-nat.c                                 |   27 +-
 gdb/auxv.c                                         |   13 +-
 gdb/auxv.h                                         |    3 +-
 gdb/avr-tdep.c                                     |    4 +-
 gdb/bfd-target.c                                   |  105 +-
 gdb/breakpoint.c                                   |    9 +-
 gdb/bsd-kvm.c                                      |  104 +-
 gdb/bsd-uthread.c                                  |  139 +-
 gdb/corefile.c                                     |   16 +-
 gdb/corelow.c                                      |  204 +-
 gdb/ctf.c                                          |  103 +-
 gdb/darwin-nat.c                                   |  146 +-
 gdb/darwin-nat.h                                   |   46 +-
 gdb/elfread.c                                      |   10 +-
 gdb/eval.c                                         |    2 +-
 gdb/exceptions.c                                   |    6 +-
 gdb/exec.c                                         |  131 +-
 gdb/fbsd-nat.c                                     |  218 +-
 gdb/fbsd-nat.h                                     |   70 +-
 gdb/frame.c                                        |    2 +-
 gdb/gdbarch-selftests.c                            |    4 +-
 gdb/gdbcore.h                                      |   10 +-
 gdb/gnu-nat.c                                      |  101 +-
 gdb/gnu-nat.h                                      |   34 +-
 gdb/gnu-v3-abi.c                                   |    2 +-
 gdb/go32-nat.c                                     |  181 +-
 gdb/hppa-linux-nat.c                               |   32 +-
 gdb/hppa-nbsd-nat.c                                |   30 +-
 gdb/hppa-obsd-nat.c                                |   25 +-
 gdb/i386-bsd-nat.c                                 |   24 +-
 gdb/i386-bsd-nat.h                                 |   22 +-
 gdb/i386-darwin-nat.c                              |   28 +-
 gdb/i386-fbsd-nat.c                                |   37 +-
 gdb/i386-gnu-nat.c                                 |   29 +-
 gdb/i386-linux-nat.c                               |   42 +-
 gdb/i386-nbsd-nat.c                                |    9 +-
 gdb/i386-obsd-nat.c                                |    5 +-
 gdb/ia64-linux-nat.c                               |  148 +-
 gdb/ia64-tdep.c                                    |    2 +-
 gdb/ia64-vms-tdep.c                                |    2 +-
 gdb/inf-child.c                                    |  327 +-
 gdb/inf-child.h                                    |  113 +-
 gdb/inf-ptrace.c                                   |  142 +-
 gdb/inf-ptrace.h                                   |   67 +-
 gdb/infcall.c                                      |    4 +-
 gdb/infcmd.c                                       |   36 +-
 gdb/infrun.c                                       |   12 +-
 gdb/linux-fork.c                                   |    2 +-
 gdb/linux-nat-trad.c                               |   54 +-
 gdb/linux-nat-trad.h                               |   24 +-
 gdb/linux-nat.c                                    |  636 +--
 gdb/linux-nat.h                                    |  217 +-
 gdb/linux-tdep.c                                   |   18 +-
 gdb/linux-thread-db.c                              |  157 +-
 gdb/m32r-linux-nat.c                               |   29 +-
 gdb/m68k-bsd-nat.c                                 |   25 +-
 gdb/m68k-linux-nat.c                               |   32 +-
 gdb/m88k-bsd-nat.c                                 |   25 +-
 gdb/make-target-delegates                          |  223 +-
 gdb/mi/mi-main.c                                   |   13 +-
 gdb/minsyms.c                                      |    4 +-
 gdb/mips-fbsd-nat.c                                |   25 +-
 gdb/mips-linux-nat.c                               |  192 +-
 gdb/mips-nbsd-nat.c                                |   25 +-
 gdb/mips64-obsd-nat.c                              |   23 +-
 gdb/nbsd-nat.c                                     |    2 +-
 gdb/nbsd-nat.h                                     |   10 +-
 gdb/nto-procfs.c                                   |  345 +-
 gdb/obsd-nat.c                                     |   32 +-
 gdb/obsd-nat.h                                     |   10 +-
 gdb/parse.c                                        |    2 +-
 gdb/ppc-fbsd-nat.c                                 |   26 +-
 gdb/ppc-linux-nat.c                                |  208 +-
 gdb/ppc-linux-tdep.c                               |   10 +-
 gdb/ppc-nbsd-nat.c                                 |   26 +-
 gdb/ppc-obsd-nat.c                                 |   26 +-
 gdb/procfs.c                                       |  316 +-
 gdb/ravenscar-thread.c                             |  240 +-
 gdb/record-btrace.c                                |  566 +--
 gdb/record-full.c                                  |  618 +--
 gdb/record.c                                       |   18 +-
 gdb/regcache.c                                     |   64 +-
 gdb/remote-sim.c                                   |  233 +-
 gdb/remote.c                                       | 1386 +++---
 gdb/rs6000-nat.c                                   |   95 +-
 gdb/rs6000-tdep.c                                  |    2 +-
 gdb/s390-linux-nat.c                               |  162 +-
 gdb/s390-tdep.c                                    |    2 +-
 gdb/sh-nbsd-nat.c                                  |   24 +-
 gdb/sol-thread.c                                   |  173 +-
 gdb/solib-aix.c                                    |    2 +-
 gdb/solib-darwin.c                                 |    2 +-
 gdb/solib-dsbt.c                                   |    4 +-
 gdb/solib-spu.c                                    |    6 +-
 gdb/solib-svr4.c                                   |   18 +-
 gdb/solib-target.c                                 |    2 +-
 gdb/sparc-linux-nat.c                              |   24 +-
 gdb/sparc-nat.c                                    |   39 +-
 gdb/sparc-nat.h                                    |   41 +-
 gdb/sparc-nbsd-nat.c                               |    5 +-
 gdb/sparc-tdep.c                                   |    2 +-
 gdb/sparc64-fbsd-nat.c                             |    9 +-
 gdb/sparc64-linux-nat.c                            |   33 +-
 gdb/sparc64-nbsd-nat.c                             |    6 +-
 gdb/sparc64-obsd-nat.c                             |    5 +-
 gdb/sparc64-tdep.c                                 |    4 +-
 gdb/spu-linux-nat.c                                |   78 +-
 gdb/spu-multiarch.c                                |  164 +-
 gdb/spu-tdep.c                                     |   30 +-
 gdb/symfile.c                                      |    2 +-
 gdb/target-debug.h                                 |    6 +
 gdb/target-delegates.c                             | 5194 +++++++++-----------
 gdb/target-descriptions.c                          |    4 +-
 gdb/target-memory.c                                |    4 +-
 gdb/target.c                                       |  954 ++--
 gdb/target.h                                       |  926 ++--
 gdb/testsuite/gdb.base/breakpoint-in-ro-region.exp |    4 +-
 gdb/testsuite/gdb.base/sss-bp-on-user-bp-2.exp     |    4 +-
 gdb/tilegx-linux-nat.c                             |   34 +-
 gdb/tracefile-tfile.c                              |  122 +-
 gdb/tracefile.c                                    |   38 +-
 gdb/tracefile.h                                    |   16 +-
 gdb/tracepoint.c                                   |    2 +-
 gdb/valops.c                                       |    4 +-
 gdb/valprint.c                                     |    2 +-
 gdb/value.c                                        |    2 +-
 gdb/vax-bsd-nat.c                                  |   25 +-
 gdb/windows-nat.c                                  |  223 +-
 gdb/windows-tdep.c                                 |    2 +-
 gdb/x86-bsd-nat.c                                  |   27 +-
 gdb/x86-bsd-nat.h                                  |   21 +-
 gdb/x86-linux-nat.c                                |   91 +-
 gdb/x86-linux-nat.h                                |   62 +-
 gdb/x86-nat.c                                      |   64 +-
 gdb/x86-nat.h                                      |   79 +-
 gdb/xtensa-linux-nat.c                             |   32 +-
 150 files changed, 9106 insertions(+), 9305 deletions(-)
 create mode 100644 gdb/amd64-bsd-nat.h

-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 37/40] target_ops/C++: The Hurd
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (10 preceding siblings ...)
  2018-04-14 19:10 ` [PATCH 27/40] target_ops/C++: SPARC GNU/Linux Pedro Alves
@ 2018-04-14 19:10 ` Pedro Alves
  2018-04-14 19:10 ` [PATCH 39/40] linux_nat_target: More low methods Pedro Alves
                   ` (29 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:10 UTC (permalink / raw)
  To: gdb-patches

Straightforward conversion.  Not tested.
---
 gdb/gnu-nat.c      | 101 ++++++++++++++++++++---------------------------------
 gdb/gnu-nat.h      |  34 ++++++++++++++++--
 gdb/i386-gnu-nat.c |  29 +++++++++------
 3 files changed, 87 insertions(+), 77 deletions(-)

diff --git a/gdb/gnu-nat.c b/gdb/gnu-nat.c
index 8271565a04..89df55fdde 100644
--- a/gdb/gnu-nat.c
+++ b/gdb/gnu-nat.c
@@ -1461,9 +1461,10 @@ extern "C" int notify_server (mach_msg_header_t *, mach_msg_header_t *);
 extern "C" int process_reply_server (mach_msg_header_t *, mach_msg_header_t *);
 
 /* Wait for something to happen in the inferior, returning what in STATUS.  */
-static ptid_t
-gnu_wait (struct target_ops *ops,
-	  ptid_t ptid, struct target_waitstatus *status, int options)
+
+ptid_t
+gnu_nat_target::wait (ptid_t ptid, struct target_waitstatus *status,
+		      int options)
 {
   struct msg
     {
@@ -1998,9 +1999,8 @@ port_msgs_queued (mach_port_t port)
    still unprocessed from the last resume we did (any given resume may result
    in multiple events returned by wait).  */
 
-static void
-gnu_resume (struct target_ops *ops,
-	    ptid_t ptid, int step, enum gdb_signal sig)
+void
+gnu_nat_target::resume (ptid_t ptid, int step, enum gdb_signal sig)
 {
   struct proc *step_thread = 0;
   int resume_all;
@@ -2075,8 +2075,8 @@ gnu_resume (struct target_ops *ops,
 }
 
 \f
-static void
-gnu_kill_inferior (struct target_ops *ops)
+void
+gnu_nat_target::kill ()
 {
   struct proc *task = gnu_current_inf->task;
 
@@ -2090,12 +2090,12 @@ gnu_kill_inferior (struct target_ops *ops)
 }
 
 /* Clean up after the inferior dies.  */
-static void
-gnu_mourn_inferior (struct target_ops *ops)
+void
+gnu_nat_target::mourn_inferior ()
 {
   inf_debug (gnu_current_inf, "rip");
   inf_detach (gnu_current_inf);
-  inf_child_mourn_inferior (ops);
+  inf_child_target::mourn_inferior ();
 }
 
 \f
@@ -2131,11 +2131,11 @@ gnu_ptrace_me (void)
     trace_start_error_with_name ("ptrace");
 }
 
-static void
-gnu_create_inferior (struct target_ops *ops, 
-		     const char *exec_file, const std::string &allargs,
-		     char **env,
-		     int from_tty)
+void
+gnu_nat_target::create_inferior (const char *exec_file,
+				 const std::string &allargs,
+				 char **env,
+				 int from_tty)
 {
   struct inf *inf = cur_inf ();
   int pid;
@@ -2155,7 +2155,7 @@ gnu_create_inferior (struct target_ops *ops,
 
   inf_attach (inf, pid);
 
-  push_target (ops);
+  push_target (this);
 
   inf->pending_execs = 1;
   inf->nomsg = 1;
@@ -2190,8 +2190,8 @@ gnu_create_inferior (struct target_ops *ops,
 \f
 /* Attach to process PID, then initialize for debugging it
    and wait for the trace-trap that results from attaching.  */
-static void
-gnu_attach (struct target_ops *ops, const char *args, int from_tty)
+void
+gnu_nat_target::attach (const char *args, int from_tty)
 {
   int pid;
   char *exec_file;
@@ -2220,7 +2220,7 @@ gnu_attach (struct target_ops *ops, const char *args, int from_tty)
 
   inf_attach (inf, pid);
 
-  push_target (ops);
+  push_target (this);
 
   inferior = current_inferior ();
   inferior_appeared (inferior, pid);
@@ -2254,8 +2254,8 @@ gnu_attach (struct target_ops *ops, const char *args, int from_tty)
    to work, it may be necessary for the process to have been
    previously attached.  It *might* work if the program was
    started via fork.  */
-static void
-gnu_detach (struct target_ops *ops, inferior *inf, int from_tty)
+void
+gnu_nat_target::detach (inferior *inf, int from_tty)
 {
   int pid;
 
@@ -2282,14 +2282,14 @@ gnu_detach (struct target_ops *ops, inferior *inf, int from_tty)
 }
 \f
 
-static void
-gnu_stop (struct target_ops *self, ptid_t ptid)
+void
+gnu_nat_target::stop (ptid_t ptid)
 {
-  error (_("to_stop target function not implemented"));
+  error (_("stop target function not implemented"));
 }
 
-static int
-gnu_thread_alive (struct target_ops *ops, ptid_t ptid)
+int
+gnu_nat_target::thread_alive (ptid_t ptid)
 {
   inf_update_procs (gnu_current_inf);
   return !!inf_tid_to_thread (gnu_current_inf,
@@ -2599,11 +2599,11 @@ gnu_xfer_auxv (gdb_byte *readbuf, const gdb_byte *writebuf,
 
 /* Target to_xfer_partial implementation.  */
 
-static enum target_xfer_status
-gnu_xfer_partial (struct target_ops *ops, enum target_object object,
-		  const char *annex, gdb_byte *readbuf,
-		  const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
-		  ULONGEST *xfered_len)
+enum target_xfer_status
+gnu_nat_target::xfer_partial (enum target_object object,
+			      const char *annex, gdb_byte *readbuf,
+			      const gdb_byte *writebuf, ULONGEST offset,
+			      ULONGEST len, ULONGEST *xfered_len)
 {
   switch (object)
     {
@@ -2617,9 +2617,10 @@ gnu_xfer_partial (struct target_ops *ops, enum target_object object,
 }
 
 /* Call FUNC on each memory region in the task.  */
-static int
-gnu_find_memory_regions (struct target_ops *self,
-			 find_memory_region_ftype func, void *data)
+
+int
+gnu_nat_target::find_memory_regions (find_memory_region_ftype func,
+				     void *data)
 {
   kern_return_t err;
   task_t task;
@@ -2711,8 +2712,8 @@ proc_string (struct proc *proc)
   return tid_str;
 }
 
-static const char *
-gnu_pid_to_str (struct target_ops *ops, ptid_t ptid)
+const char *
+gnu_nat_target::pid_to_str (ptid_t ptid)
 {
   struct inf *inf = gnu_current_inf;
   int tid = ptid_get_lwp (ptid);
@@ -2730,32 +2731,6 @@ gnu_pid_to_str (struct target_ops *ops, ptid_t ptid)
 }
 
 \f
-/* Create a prototype generic GNU/Hurd target.  The client can
-   override it with local methods.  */
-
-struct target_ops *
-gnu_target (void)
-{
-  struct target_ops *t = inf_child_target ();
-
-  t->to_attach = gnu_attach;
-  t->to_attach_no_wait = 1;
-  t->to_detach = gnu_detach;
-  t->to_resume = gnu_resume;
-  t->to_wait = gnu_wait;
-  t->to_xfer_partial = gnu_xfer_partial;
-  t->to_find_memory_regions = gnu_find_memory_regions;
-  t->to_kill = gnu_kill_inferior;
-  t->to_create_inferior = gnu_create_inferior;
-  t->to_mourn_inferior = gnu_mourn_inferior;
-  t->to_thread_alive = gnu_thread_alive;
-  t->to_pid_to_str = gnu_pid_to_str;
-  t->to_stop = gnu_stop;
-
-  return t;
-}
-
-\f
 /* User task commands.  */
 
 static struct cmd_list_element *set_task_cmd_list = 0;
diff --git a/gdb/gnu-nat.h b/gdb/gnu-nat.h
index fb96b2980d..4189eaf026 100644
--- a/gdb/gnu-nat.h
+++ b/gdb/gnu-nat.h
@@ -103,8 +103,36 @@ extern int gnu_debug_flag;
         fprintf_unfiltered (gdb_stdlog, "%s:%d: " msg "\r\n", \
 			    __FILE__ , __LINE__ , ##args); } while (0)
 
-/* Create a prototype generic GNU/Hurd target.  The client can
-   override it with local methods.  */
-struct target_ops *gnu_target (void);
+/* A prototype generic GNU/Hurd target.  The client can override it
+   with local methods.  */
+
+struct gnu_nat_target : public inf_child_target
+{
+  void attach (const char *, int) override;
+  bool attach_no_wait () override
+  { return true; }
+
+  void detach (inferior *, int) override;
+  void resume (ptid_t, int, enum gdb_signal) override;
+
+  ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
+  enum target_xfer_status xfer_partial (enum target_object object,
+					const char *annex,
+					gdb_byte *readbuf,
+					const gdb_byte *writebuf,
+					ULONGEST offset, ULONGEST len,
+					ULONGEST *xfered_len) override;
+
+  int find_memory_regions (find_memory_region_ftype func, void *data)
+    override;
+  void kill () override;
+
+  void create_inferior (const char *, const std::string &,
+			char **, int) override;
+  void mourn_inferior () override;
+  int thread_alive (ptid_t ptid) override;
+  const char *pid_to_str (ptid_t) override;
+  void stop (ptid_t) override;
+};
 
 #endif /* __GNU_NAT_H__ */
diff --git a/gdb/i386-gnu-nat.c b/gdb/i386-gnu-nat.c
index f0674158a3..de7d62a269 100644
--- a/gdb/i386-gnu-nat.c
+++ b/gdb/i386-gnu-nat.c
@@ -54,6 +54,23 @@ static int reg_offset[] =
 #define REG_ADDR(state, regnum) ((char *)(state) + reg_offset[regnum])
 
 \f
+
+/* The i386 GNU Hurd target.  */
+
+#ifdef i386_DEBUG_STATE
+using gnu_base_target = x86_nat_target<gnu_nat_target>;
+#else
+using gnu_base_target = gnu_nat_target;
+#endif
+
+struct i386_gnu_nat_target final : public gnu_base_target
+{
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+};
+
+static i386_gnu_nat_target the_i386_gnu_nat_target;
+
 /* Get the whole floating-point state of THREAD and record the values
    of the corresponding (pseudo) registers.  */
 
@@ -412,14 +429,7 @@ i386_gnu_dr_get_control (void)
 void
 _initialize_i386gnu_nat (void)
 {
-  struct target_ops *t;
-
-  /* Fill in the generic GNU/Hurd methods.  */
-  t = gnu_target ();
-
 #ifdef i386_DEBUG_STATE
-  x86_use_watchpoints (t);
-
   x86_dr_low.set_control = i386_gnu_dr_set_control;
   gdb_assert (DR_FIRSTADDR == 0 && DR_LASTADDR < i386_DEBUG_STATE_COUNT);
   x86_dr_low.set_addr = i386_gnu_dr_set_addr;
@@ -429,9 +439,6 @@ _initialize_i386gnu_nat (void)
   x86_set_debug_register_length (4);
 #endif /* i386_DEBUG_STATE */
 
-  t->to_fetch_registers = gnu_fetch_registers;
-  t->to_store_registers = gnu_store_registers;
-
   /* Register the target.  */
-  add_target (t);
+  add_target (&the_i386_gnu_nat_target);
 }
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 20/40] target_ops/C++: ARM GNU/Linux
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (12 preceding siblings ...)
  2018-04-14 19:10 ` [PATCH 39/40] linux_nat_target: More low methods Pedro Alves
@ 2018-04-14 19:10 ` Pedro Alves
  2018-04-14 19:10 ` [PATCH 09/40] target_ops/C++: bfd-target Pedro Alves
                   ` (27 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:10 UTC (permalink / raw)
  To: gdb-patches

Straighforward conversion.  Smoke tested on the compile farm.
---
 gdb/arm-linux-nat.c | 137 +++++++++++++++++++++++++++-------------------------
 1 file changed, 71 insertions(+), 66 deletions(-)

diff --git a/gdb/arm-linux-nat.c b/gdb/arm-linux-nat.c
index d41ef723ff..75d89f284e 100644
--- a/gdb/arm-linux-nat.c
+++ b/gdb/arm-linux-nat.c
@@ -66,6 +66,38 @@
 
 extern int arm_apcs_32;
 
+class arm_linux_nat_target final : public linux_nat_target
+{
+public:
+  /* Add our register access methods.  */
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+
+  /* Add our hardware breakpoint and watchpoint implementation.  */
+  int can_use_hw_breakpoint (enum bptype, int, int) override;
+
+  int insert_hw_breakpoint (struct gdbarch *, struct bp_target_info *) override;
+
+  int remove_hw_breakpoint (struct gdbarch *, struct bp_target_info *) override;
+
+  int region_ok_for_hw_watchpoint (CORE_ADDR, int) override;
+
+  int insert_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
+			 struct expression *) override;
+
+  int remove_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
+			 struct expression *) override;
+  int stopped_by_watchpoint () override;
+
+  int stopped_data_address (CORE_ADDR *) override;
+
+  int watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, int) override;
+
+  const struct target_desc *read_description () override;
+};
+
+static arm_linux_nat_target the_arm_linux_nat_target;
+
 /* Get the whole floating point state of the process and store it
    into regcache.  */
 
@@ -374,9 +406,8 @@ store_vfp_regs (const struct regcache *regcache)
    regno == -1, otherwise fetch all general registers or all floating
    point registers depending upon the value of regno.  */
 
-static void
-arm_linux_fetch_inferior_registers (struct target_ops *ops,
-				    struct regcache *regcache, int regno)
+void
+arm_linux_nat_target::fetch_registers (struct regcache *regcache, int regno)
 {
   struct gdbarch *gdbarch = regcache->arch ();
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
@@ -412,9 +443,8 @@ arm_linux_fetch_inferior_registers (struct target_ops *ops,
    regno == -1, otherwise store all general registers or all floating
    point registers depending upon the value of regno.  */
 
-static void
-arm_linux_store_inferior_registers (struct target_ops *ops,
-				    struct regcache *regcache, int regno)
+void
+arm_linux_nat_target::store_registers (struct regcache *regcache, int regno)
 {
   struct gdbarch *gdbarch = regcache->arch ();
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
@@ -495,8 +525,8 @@ ps_get_thread_area (struct ps_prochandle *ph,
   return PS_OK;
 }
 
-static const struct target_desc *
-arm_linux_read_description (struct target_ops *ops)
+const struct target_desc *
+arm_linux_nat_target::read_description ()
 {
   CORE_ADDR arm_hwcap = 0;
 
@@ -516,9 +546,9 @@ arm_linux_read_description (struct target_ops *ops)
 	have_ptrace_getregset = TRIBOOL_TRUE;
     }
 
-  if (target_auxv_search (ops, AT_HWCAP, &arm_hwcap) != 1)
+  if (target_auxv_search (this, AT_HWCAP, &arm_hwcap) != 1)
     {
-      return ops->beneath->to_read_description (ops->beneath);
+      return this->beneath->read_description ();
     }
 
   if (arm_hwcap & HWCAP_IWMMXT)
@@ -551,7 +581,7 @@ arm_linux_read_description (struct target_ops *ops)
       return result;
     }
 
-  return ops->beneath->to_read_description (ops->beneath);
+  return this->beneath->read_description ();
 }
 
 /* Information describing the hardware breakpoint capabilities.  */
@@ -635,10 +665,9 @@ arm_linux_get_hw_watchpoint_count (void)
 
 /* Have we got a free break-/watch-point available for use?  Returns -1 if
    there is not an appropriate resource available, otherwise returns 1.  */
-static int
-arm_linux_can_use_hw_breakpoint (struct target_ops *self,
-				 enum bptype type,
-				 int cnt, int ot)
+int
+arm_linux_nat_target::can_use_hw_breakpoint (enum bptype type,
+					     int cnt, int ot)
 {
   if (type == bp_hardware_watchpoint || type == bp_read_watchpoint
       || type == bp_access_watchpoint || type == bp_watchpoint)
@@ -1026,10 +1055,9 @@ arm_linux_remove_hw_breakpoint1 (const struct arm_linux_hw_breakpoint *bpt,
 }
 
 /* Insert a Hardware breakpoint.  */
-static int
-arm_linux_insert_hw_breakpoint (struct target_ops *self,
-				struct gdbarch *gdbarch, 
-				struct bp_target_info *bp_tgt)
+int
+arm_linux_nat_target::insert_hw_breakpoint (struct gdbarch *gdbarch,
+					    struct bp_target_info *bp_tgt)
 {
   struct lwp_info *lp;
   struct arm_linux_hw_breakpoint p;
@@ -1045,10 +1073,9 @@ arm_linux_insert_hw_breakpoint (struct target_ops *self,
 }
 
 /* Remove a hardware breakpoint.  */
-static int
-arm_linux_remove_hw_breakpoint (struct target_ops *self,
-				struct gdbarch *gdbarch, 
-				struct bp_target_info *bp_tgt)
+int
+arm_linux_nat_target::remove_hw_breakpoint (struct gdbarch *gdbarch,
+					    struct bp_target_info *bp_tgt)
 {
   struct lwp_info *lp;
   struct arm_linux_hw_breakpoint p;
@@ -1065,9 +1092,8 @@ arm_linux_remove_hw_breakpoint (struct target_ops *self,
 
 /* Are we able to use a hardware watchpoint for the LEN bytes starting at 
    ADDR?  */
-static int
-arm_linux_region_ok_for_hw_watchpoint (struct target_ops *self,
-				       CORE_ADDR addr, int len)
+int
+arm_linux_nat_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
 {
   const struct arm_linux_hwbp_cap *cap = arm_linux_get_hwbp_cap ();
   CORE_ADDR max_wp_length, aligned_addr;
@@ -1098,11 +1124,10 @@ arm_linux_region_ok_for_hw_watchpoint (struct target_ops *self,
 }
 
 /* Insert a Hardware breakpoint.  */
-static int
-arm_linux_insert_watchpoint (struct target_ops *self,
-			     CORE_ADDR addr, int len,
-			     enum target_hw_bp_type rw,
-			     struct expression *cond)
+int
+arm_linux_nat_target::insert_watchpoint (CORE_ADDR addr, int len,
+					 enum target_hw_bp_type rw,
+					 struct expression *cond)
 {
   struct lwp_info *lp;
   struct arm_linux_hw_breakpoint p;
@@ -1118,10 +1143,10 @@ arm_linux_insert_watchpoint (struct target_ops *self,
 }
 
 /* Remove a hardware breakpoint.  */
-static int
-arm_linux_remove_watchpoint (struct target_ops *self, CORE_ADDR addr,
-			     int len, enum target_hw_bp_type rw,
-			     struct expression *cond)
+int
+arm_linux_nat_target::remove_watchpoint (CORE_ADDR addr,
+					 int len, enum target_hw_bp_type rw,
+					 struct expression *cond)
 {
   struct lwp_info *lp;
   struct arm_linux_hw_breakpoint p;
@@ -1137,8 +1162,8 @@ arm_linux_remove_watchpoint (struct target_ops *self, CORE_ADDR addr,
 }
 
 /* What was the data address the target was stopped on accessing.  */
-static int
-arm_linux_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p)
+int
+arm_linux_nat_target::stopped_data_address (CORE_ADDR *addr_p)
 {
   siginfo_t siginfo;
   int slot;
@@ -1167,17 +1192,17 @@ arm_linux_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p)
 }
 
 /* Has the target been stopped by hitting a watchpoint?  */
-static int
-arm_linux_stopped_by_watchpoint (struct target_ops *ops)
+int
+arm_linux_nat_target::stopped_by_watchpoint ()
 {
   CORE_ADDR addr;
-  return arm_linux_stopped_data_address (ops, &addr);
+  return stopped_data_address (&addr);
 }
 
-static int
-arm_linux_watchpoint_addr_within_range (struct target_ops *target,
-					CORE_ADDR addr,
-					CORE_ADDR start, int length)
+int
+arm_linux_nat_target::watchpoint_addr_within_range (CORE_ADDR addr,
+						    CORE_ADDR start,
+						    int length)
 {
   return start <= addr && start + length - 1 >= addr;
 }
@@ -1294,30 +1319,10 @@ arm_linux_new_fork (struct lwp_info *parent, pid_t child_pid)
 void
 _initialize_arm_linux_nat (void)
 {
-  struct target_ops *t;
-
-  /* Fill in the generic GNU/Linux methods.  */
-  t = linux_target ();
-
-  /* Add our register access methods.  */
-  t->to_fetch_registers = arm_linux_fetch_inferior_registers;
-  t->to_store_registers = arm_linux_store_inferior_registers;
-
-  /* Add our hardware breakpoint and watchpoint implementation.  */
-  t->to_can_use_hw_breakpoint = arm_linux_can_use_hw_breakpoint;
-  t->to_insert_hw_breakpoint = arm_linux_insert_hw_breakpoint;
-  t->to_remove_hw_breakpoint = arm_linux_remove_hw_breakpoint;
-  t->to_region_ok_for_hw_watchpoint = arm_linux_region_ok_for_hw_watchpoint;
-  t->to_insert_watchpoint = arm_linux_insert_watchpoint;
-  t->to_remove_watchpoint = arm_linux_remove_watchpoint;
-  t->to_stopped_by_watchpoint = arm_linux_stopped_by_watchpoint;
-  t->to_stopped_data_address = arm_linux_stopped_data_address;
-  t->to_watchpoint_addr_within_range = arm_linux_watchpoint_addr_within_range;
-
-  t->to_read_description = arm_linux_read_description;
+  target_ops *t = &the_arm_linux_nat_target;
 
   /* Register the target.  */
-  linux_nat_add_target (t);
+  add_target (t);
 
   /* Handle thread creation and exit.  */
   linux_nat_set_new_thread (t, arm_linux_new_thread);
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 17/40] target_ops/C++: macOS/Darwin target
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
  2018-04-14 19:10 ` [PATCH 02/40] make-target-delegates: line break between return type and function name Pedro Alves
@ 2018-04-14 19:10 ` Pedro Alves
  2018-04-14 19:10 ` [PATCH 03/40] target_ops/C++: exec target Pedro Alves
                   ` (39 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:10 UTC (permalink / raw)
  To: gdb-patches

Straighforward conversion.  I'd checked that this builds with a cross
compiler.
---
 gdb/darwin-nat.c      | 142 +++++++++++++++-----------------------------------
 gdb/darwin-nat.h      |  46 ++++++++++++++--
 gdb/i386-darwin-nat.c |  28 ++++++----
 3 files changed, 99 insertions(+), 117 deletions(-)

diff --git a/gdb/darwin-nat.c b/gdb/darwin-nat.c
index e98ac6c548..919643145a 100644
--- a/gdb/darwin-nat.c
+++ b/gdb/darwin-nat.c
@@ -83,36 +83,12 @@
 #define PTRACE(CMD, PID, ADDR, SIG) \
  darwin_ptrace(#CMD, CMD, (PID), (ADDR), (SIG))
 
-static void darwin_interrupt (struct target_ops *self);
-
-static void darwin_resume_to (struct target_ops *ops, ptid_t ptid, int step,
-                              enum gdb_signal signal);
-static void darwin_resume (ptid_t ptid, int step,
-			   enum gdb_signal signal);
-
-static ptid_t darwin_wait_to (struct target_ops *ops, ptid_t ptid,
-                              struct target_waitstatus *status, int options);
 static ptid_t darwin_wait (ptid_t ptid, struct target_waitstatus *status);
 
-static void darwin_mourn_inferior (struct target_ops *ops);
-
-static void darwin_kill_inferior (struct target_ops *ops);
-
 static void darwin_ptrace_me (void);
 
 static void darwin_ptrace_him (int pid);
 
-static void darwin_create_inferior (struct target_ops *ops,
-				    const char *exec_file,
-				    const std::string &allargs,
-				    char **env, int from_tty);
-
-static void darwin_files_info (struct target_ops *ops);
-
-static const char *darwin_pid_to_str (struct target_ops *ops, ptid_t tpid);
-
-static int darwin_thread_alive (struct target_ops *ops, ptid_t tpid);
-
 static void darwin_encode_reply (mig_reply_error_t *reply,
 				 mach_msg_header_t *hdr, integer_t code);
 
@@ -942,8 +918,8 @@ darwin_suspend_inferior_threads (struct inferior *inf)
     }
 }
 
-static void
-darwin_resume (ptid_t ptid, int step, enum gdb_signal signal)
+void
+darwin_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signal)
 {
   struct target_waitstatus status;
   int pid;
@@ -1007,13 +983,6 @@ darwin_resume (ptid_t ptid, int step, enum gdb_signal signal)
     }
 }
 
-static void
-darwin_resume_to (struct target_ops *ops, ptid_t ptid, int step,
-                  enum gdb_signal signal)
-{
-  return darwin_resume (ptid, step, signal);
-}
-
 static ptid_t
 darwin_decode_message (mach_msg_header_t *hdr,
 		       darwin_thread_t **pthread,
@@ -1334,22 +1303,22 @@ darwin_wait (ptid_t ptid, struct target_waitstatus *status)
   return res;
 }
 
-static ptid_t
-darwin_wait_to (struct target_ops *ops,
-                ptid_t ptid, struct target_waitstatus *status, int options)
+ptid_t
+darwin_nat_target::wait (ptid_t ptid, struct target_waitstatus *status,
+			 int options)
 {
   return darwin_wait (ptid, status);
 }
 
-static void
-darwin_interrupt (struct target_ops *self)
+void
+darwin_nat_target::interrupt ()
 {
   struct inferior *inf = current_inferior ();
   darwin_inferior *priv = get_darwin_inferior (inf);
 
   /* FIXME: handle in no_ptrace mode.  */
   gdb_assert (!priv->no_ptrace);
-  kill (inf->pid, SIGINT);
+  ::kill (inf->pid, SIGINT);
 }
 
 /* Deallocate threads port and vector.  */
@@ -1368,8 +1337,8 @@ darwin_deallocate_threads (struct inferior *inf)
   priv->threads.clear ();
 }
 
-static void
-darwin_mourn_inferior (struct target_ops *ops)
+void
+darwin_nat_target::mourn_inferior ()
 {
   struct inferior *inf = current_inferior ();
   darwin_inferior *priv = get_darwin_inferior (inf);
@@ -1414,7 +1383,7 @@ darwin_mourn_inferior (struct target_ops *ops)
 
   inf->priv = NULL;
 
-  inf_child_mourn_inferior (ops);
+  inf_child_target::mourn_inferior ();
 }
 
 static void
@@ -1538,8 +1507,8 @@ darwin_setup_exceptions (struct inferior *inf)
 	   kret);
 }
 
-static void
-darwin_kill_inferior (struct target_ops *ops)
+void
+darwin_nat_target::kill ()
 {
   struct inferior *inf = current_inferior ();
   darwin_inferior *priv = get_darwin_inferior (inf);
@@ -1559,7 +1528,7 @@ darwin_kill_inferior (struct target_ops *ops)
 
   darwin_reply_to_all_pending_messages (inf);
 
-  res = kill (inf->pid, 9);
+  res = ::kill (inf->pid, 9);
 
   if (res == 0)
     {
@@ -1835,11 +1804,10 @@ darwin_execvp (const char *file, char * const argv[], char * const env[])
   posix_spawnp (NULL, argv[0], NULL, &attr, argv, env);
 }
 
-static void
-darwin_create_inferior (struct target_ops *ops,
-			const char *exec_file,
-			const std::string &allargs,
-			char **env, int from_tty)
+void
+darwin_nat_target::create_inferior (const char *exec_file,
+				    const std::string &allargs,
+				    char **env, int from_tty)
 {
   /* Do the hard work.  */
   fork_inferior (exec_file, allargs, env, darwin_ptrace_me,
@@ -1877,8 +1845,8 @@ darwin_setup_fake_stop_event (struct inferior *inf)
 
 /* Attach to process PID, then initialize for debugging it
    and wait for the trace-trap that results from attaching.  */
-static void
-darwin_attach (struct target_ops *ops, const char *args, int from_tty)
+void
+darwin_nat_target::attach (const char *args, int from_tty)
 {
   pid_t pid;
   pid_t pid2;
@@ -1906,7 +1874,7 @@ darwin_attach (struct target_ops *ops, const char *args, int from_tty)
       gdb_flush (gdb_stdout);
     }
 
-  if (pid == 0 || kill (pid, 0) < 0)
+  if (pid == 0 || ::kill (pid, 0) < 0)
     error (_("Can't attach to process %d: %s (%d)"),
            pid, safe_strerror (errno), errno);
 
@@ -1937,8 +1905,9 @@ darwin_attach (struct target_ops *ops, const char *args, int from_tty)
    to work, it may be necessary for the process to have been
    previously attached.  It *might* work if the program was
    started via fork.  */
-static void
-darwin_detach (struct target_ops *ops, inferior *inf, int from_tty)
+
+void
+darwin_nat_target::detach (inferior *inf, int from_tty)
 {
   pid_t pid = ptid_get_pid (inferior_ptid);
   darwin_inferior *priv = get_darwin_inferior (inf);
@@ -1971,16 +1940,11 @@ darwin_detach (struct target_ops *ops, inferior *inf, int from_tty)
   if (priv->no_ptrace)
     darwin_resume_inferior (inf);
 
-  darwin_mourn_inferior (ops);
+  mourn_inferior ();
 }
 
-static void
-darwin_files_info (struct target_ops *ops)
-{
-}
-
-static const char *
-darwin_pid_to_str (struct target_ops *ops, ptid_t ptid)
+const char *
+darwin_nat_target::pid_to_str (ptid_t ptid)
 {
   static char buf[80];
   long tid = ptid_get_tid (ptid);
@@ -1995,8 +1959,8 @@ darwin_pid_to_str (struct target_ops *ops, ptid_t ptid)
   return normal_pid_to_str (ptid);
 }
 
-static int
-darwin_thread_alive (struct target_ops *ops, ptid_t ptid)
+int
+darwin_nat_target::thread_alive (ptid_t ptid)
 {
   return 1;
 }
@@ -2193,11 +2157,11 @@ darwin_read_dyld_info (task_t task, CORE_ADDR addr, gdb_byte *rdaddr,
 
 \f
 
-static enum target_xfer_status
-darwin_xfer_partial (struct target_ops *ops,
-		     enum target_object object, const char *annex,
-		     gdb_byte *readbuf, const gdb_byte *writebuf,
-		     ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
+enum target_xfer_status
+darwin_nat_target::xfer_partial (enum target_object object, const char *annex,
+				 gdb_byte *readbuf, const gdb_byte *writebuf,
+				 ULONGEST offset, ULONGEST len,
+				 ULONGEST *xfered_len)
 {
   struct inferior *inf = current_inferior ();
   darwin_inferior *priv = get_darwin_inferior (inf);
@@ -2264,8 +2228,8 @@ set_enable_mach_exceptions (const char *args, int from_tty,
     }
 }
 
-static char *
-darwin_pid_to_exec_file (struct target_ops *self, int pid)
+char *
+darwin_nat_target::pid_to_exec_file (int pid)
 {
   static char path[PATH_MAX];
   int res;
@@ -2277,8 +2241,8 @@ darwin_pid_to_exec_file (struct target_ops *self, int pid)
     return NULL;
 }
 
-static ptid_t
-darwin_get_ada_task_ptid (struct target_ops *self, long lwp, long thread)
+ptid_t
+darwin_nat_target::get_ada_task_ptid (long lwp, long thread)
 {
   struct inferior *inf = current_inferior ();
   darwin_inferior *priv = get_darwin_inferior (inf);
@@ -2342,14 +2306,14 @@ darwin_get_ada_task_ptid (struct target_ops *self, long lwp, long thread)
     return null_ptid;
 }
 
-static int
-darwin_supports_multi_process (struct target_ops *self)
+int
+darwin_nat_target::supports_multi_process ()
 {
   return 1;
 }
 
 void
-_initialize_darwin_inferior (void)
+_initialize_darwin_nat (void)
 {
   kern_return_t kret;
 
@@ -2364,30 +2328,6 @@ _initialize_darwin_inferior (void)
       MACH_CHECK_ERROR (kret);
     }
 
-  darwin_ops = inf_child_target ();
-
-  darwin_ops->to_create_inferior = darwin_create_inferior;
-  darwin_ops->to_attach = darwin_attach;
-  darwin_ops->to_attach_no_wait = 0;
-  darwin_ops->to_detach = darwin_detach;
-  darwin_ops->to_files_info = darwin_files_info;
-  darwin_ops->to_wait = darwin_wait_to;
-  darwin_ops->to_mourn_inferior = darwin_mourn_inferior;
-  darwin_ops->to_kill = darwin_kill_inferior;
-  darwin_ops->to_interrupt = darwin_interrupt;
-  darwin_ops->to_resume = darwin_resume_to;
-  darwin_ops->to_thread_alive = darwin_thread_alive;
-  darwin_ops->to_pid_to_str = darwin_pid_to_str;
-  darwin_ops->to_pid_to_exec_file = darwin_pid_to_exec_file;
-  darwin_ops->to_load = NULL;
-  darwin_ops->to_xfer_partial = darwin_xfer_partial;
-  darwin_ops->to_supports_multi_process = darwin_supports_multi_process;
-  darwin_ops->to_get_ada_task_ptid = darwin_get_ada_task_ptid;
-
-  darwin_complete_target (darwin_ops);
-
-  add_target (darwin_ops);
-
   inferior_debug (2, _("GDB task: 0x%lx, pid: %d\n"),
 		  (unsigned long) mach_task_self (), getpid ());
 
diff --git a/gdb/darwin-nat.h b/gdb/darwin-nat.h
index 0eacb5530d..d4a06d9c27 100644
--- a/gdb/darwin-nat.h
+++ b/gdb/darwin-nat.h
@@ -17,9 +17,50 @@
 #ifndef __DARWIN_NAT_H__
 #define __DARWIN_NAT_H__
 
+#include "inf-child.h"
 #include <mach/mach.h>
 #include "gdbthread.h"
 
+/* This needs to be overridden by the platform specific nat code.  */
+
+class darwin_nat_target : public inf_child_target
+{
+  void create_inferior (const char *exec_file,
+			const std::string &allargs,
+			char **env, int from_tty);
+
+  void attach (const char *, int) override;
+
+  void detach (inferior *, int) override;
+
+  ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
+
+  void mourn_inferior () override;
+
+  void kill () override;
+
+  void interrupt () override;
+
+  void resume (ptid_t, int , enum gdb_signal) override;
+
+  int thread_alive (ptid_t ptid) override;
+
+  const char *pid_to_str (ptid_t) override;
+
+  char *pid_to_exec_file (int pid) override;
+
+  enum target_xfer_status xfer_partial (enum target_object object,
+					const char *annex,
+					gdb_byte *readbuf,
+					const gdb_byte *writebuf,
+					ULONGEST offset, ULONGEST len,
+					ULONGEST *xfered_len) override;
+
+  int supports_multi_process () override;
+
+  ptid_t get_ada_task_ptid (long lwp, long thread) override;
+};
+
 /* Describe the mach exception handling state for a task.  This state is saved
    before being changed and restored when a process is detached.
    For more information on these fields see task_get_exception_ports manual
@@ -158,11 +199,6 @@ extern void mach_check_error (kern_return_t ret, const char *file,
 
 void darwin_set_sstep (thread_t thread, int enable);
 
-/* This one is called in darwin-nat.c, but needs to be provided by the
-   platform specific nat code.  It allows each platform to add platform specific
-   stuff to the darwin_ops.  */
-extern void darwin_complete_target (struct target_ops *target);
-
 void darwin_check_osabi (darwin_inferior *inf, thread_t thread);
 
 #endif /* __DARWIN_NAT_H__ */
diff --git a/gdb/i386-darwin-nat.c b/gdb/i386-darwin-nat.c
index 023643fa56..48f1a7921d 100644
--- a/gdb/i386-darwin-nat.c
+++ b/gdb/i386-darwin-nat.c
@@ -43,12 +43,21 @@
 #include "amd64-darwin-tdep.h"
 #endif
 
+struct i386_darwin_nat_target final : public x86_nat_target<darwin_nat_target>
+{
+  /* Add our register access methods.  */
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+};
+
+static struct i386_darwin_nat_target darwin_target;
+
 /* Read register values from the inferior process.
    If REGNO is -1, do this for all registers.
    Otherwise, REGNO specifies which register (so we can save time).  */
-static void
-i386_darwin_fetch_inferior_registers (struct target_ops *ops,
-				      struct regcache *regcache, int regno)
+
+void
+i386_darwin_nat_target::fetch_registers (struct regcache *regcache, int regno)
 {
   thread_t current_thread = ptid_get_tid (regcache_get_ptid (regcache));
   int fetched = 0;
@@ -163,9 +172,9 @@ i386_darwin_fetch_inferior_registers (struct target_ops *ops,
    If REGNO is -1, do this for all registers.
    Otherwise, REGNO specifies which register (so we can save time).  */
 
-static void
-i386_darwin_store_inferior_registers (struct target_ops *ops,
-				      struct regcache *regcache, int regno)
+void
+i386_darwin_nat_target::store_registers (struct regcache *regcache,
+					 int regno)
 {
   thread_t current_thread = ptid_get_tid (regcache_get_ptid (regcache));
   struct gdbarch *gdbarch = regcache->arch ();
@@ -628,7 +637,7 @@ darwin_set_sstep (thread_t thread, int enable)
 }
 
 void
-darwin_complete_target (struct target_ops *target)
+_initialize_i386_darwin_nat (void)
 {
 #ifdef BFD64
   amd64_native_gregset64_reg_offset = amd64_darwin_thread_state_reg_offset;
@@ -637,8 +646,6 @@ darwin_complete_target (struct target_ops *target)
   amd64_native_gregset32_num_regs = i386_darwin_thread_state_num_regs;
 #endif
 
-  x86_use_watchpoints (target);
-
   x86_dr_low.set_control = i386_darwin_dr_set_control;
   x86_dr_low.set_addr = i386_darwin_dr_set_addr;
   x86_dr_low.get_addr = i386_darwin_dr_get_addr;
@@ -652,6 +659,5 @@ darwin_complete_target (struct target_ops *target)
   x86_set_debug_register_length (4);
 #endif
 
-  target->to_fetch_registers = i386_darwin_fetch_inferior_registers;
-  target->to_store_registers = i386_darwin_store_inferior_registers;
+  add_target (&darwin_target);
 }
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 02/40] make-target-delegates: line break between return type and function name
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
@ 2018-04-14 19:10 ` Pedro Alves
  2018-04-14 19:10 ` [PATCH 17/40] target_ops/C++: macOS/Darwin target Pedro Alves
                   ` (40 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:10 UTC (permalink / raw)
  To: gdb-patches

Before the target_ops C++ification, this wasn't necessary simply
because the methods were wrapped in ()'s, like
  '(*to_my_long_method_name) (target_ops *)',
so
  std::vector<long_type_name>(*to_my_long_method_name) ()TARGET_DEFAULT_IGNORE ()

still parsed correctly.  With the (*) gone, we need this.

gdb/ChangeLog:
yyyy-mm-dd  Pedro Alves  <palves@redhat.com>

	* make-target-delegates (scan_target_h): Don't trim lines here.
	Replace sequences of tabs and/or whitespace with a single
	whitespace.
	(top level, parsing methods): Trim each line before processing it
	here.
---
 gdb/make-target-delegates | 20 +++++++++++++++++++-
 gdb/target.h              |  3 ++-
 2 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/gdb/make-target-delegates b/gdb/make-target-delegates
index 10853e3e20..83a1afcadf 100755
--- a/gdb/make-target-delegates
+++ b/gdb/make-target-delegates
@@ -102,7 +102,6 @@ sub scan_target_h() {
 
 	# Strip // comments.
 	$_ =~ s,//.*$,,;
-	$_ = trim ($_);
 
 	$all_the_text .= $_;
     }
@@ -110,6 +109,21 @@ sub scan_target_h() {
     # Now strip out the C comments.
     $all_the_text =~ s,/\*(.*?)\*/,,g;
 
+    # Replace sequences of tabs and/or whitespace with a single
+    # whitespace character.  We need the whitespace because the method
+    # may have been split between multiple lines, like e.g.:
+    #
+    #  virtual std::vector<long_type_name>
+    #    my_long_method_name ()
+    #    TARGET_DEFAULT_IGNORE ();
+    #
+    # If we didn't preserve the whitespace, then we'd end up with:
+    #
+    #  virtual std::vector<long_type_name>my_long_method_name ()TARGET_DEFAULT_IGNORE ()
+    #
+    # ... which wouldn't later be parsed correctly.
+    $all_the_text =~ s/[\t\s]+/ /g;
+
     return split (/;/, $all_the_text);
 }
 
@@ -348,6 +362,10 @@ print "\n";
 @argtypes_array = ();
 
 foreach $current_line (@lines) {
+    # See comments in scan_target_h.  Here we strip away the leading
+    # and trailing whitespace.
+    $current_line = trim ($current_line);
+
     next unless $current_line =~ m/$METHOD/;
 
     my $name = $+{name};
diff --git a/gdb/target.h b/gdb/target.h
index b23b7625be..f78eb459dc 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -1067,7 +1067,8 @@ struct target_ops
 
     /* Return a vector of all tracepoints markers string id ID, or all
        markers if ID is NULL.  */
-    virtual std::vector<static_tracepoint_marker> static_tracepoint_markers_by_strid (const char *id)
+    virtual std::vector<static_tracepoint_marker>
+      static_tracepoint_markers_by_strid (const char *id)
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
     /* Return a traceframe info object describing the current
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 39/40] linux_nat_target: More low methods
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (11 preceding siblings ...)
  2018-04-14 19:10 ` [PATCH 37/40] target_ops/C++: The Hurd Pedro Alves
@ 2018-04-14 19:10 ` Pedro Alves
  2018-04-18  0:40   ` John Baldwin
  2018-04-14 19:10 ` [PATCH 20/40] target_ops/C++: ARM GNU/Linux Pedro Alves
                   ` (28 subsequent siblings)
  41 siblings, 1 reply; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:10 UTC (permalink / raw)
  To: gdb-patches

This converts the remaining linux-nat.c hooks low_ methods like had
been started in a previous patch.  The linux_nat_set_foo routines are
all gone with this.

gdb/ChangeLog:
yyyy-mm-dd  Pedro Alves  <palves@redhat.com>

	* linux-nat.h (linux_nat_target) <low_new_thread,
	low_delete_thread, low_new_fork, low_forget_process,
	low_prepare_to_resume, low_siginfo_fixup, low_status_is_event>:
	New virtual methods.
	(linux_nat_set_new_thread, linux_nat_set_delete_thread)
	(linux_nat_new_fork_ftype, linux_nat_set_new_fork)
	(linux_nat_forget_process_ftype, linux_nat_set_forget_process)
	(linux_nat_forget_process, linux_nat_set_siginfo_fixup)
	(linux_nat_set_prepare_to_resume, linux_nat_set_status_is_event):
	Delete.
	* linux-fork.c (delete_fork): Adjust to call low method.
	* linux-nat.c (linux_nat_new_thread, linux_nat_delete_thread)
	(linux_nat_new_fork, linux_nat_forget_process_hook)
	(linux_nat_prepare_to_resume, linux_nat_siginfo_fixup)
	(linux_nat_status_is_event):
	(linux_nat_target::follow_fork, lwp_free, add_lwp, detach_one_lwp)
	(linux_resume_one_lwp_throw, linux_handle_extended_wait): Adjust
	to call low method.
	(sigtrap_is_event): Rename to ...
	(linux_nat_target::low_status_is_event): ... this.
	(linux_nat_set_status_is_event): Delete.
	(save_stop_reason, linux_nat_wait_1)
	(linux_nat_target::mourn_inferior, siginfo_fixup): Adjust to call
	low methods.
	(linux_nat_set_new_thread, linux_nat_set_delete_thread)
	(linux_nat_set_new_fork, linux_nat_set_forget_process)
	(linux_nat_forget_process, linux_nat_set_siginfo_fixup)
	(linux_nat_set_prepare_to_resume): Delete.
	* aarch64-linux-nat.c: All linux_nat_set_* callbacks converted to
	low virtual methods.
	* amd64-linux-nat.c: Likewise.
	* arm-linux-nat.c: Likewise.
	* i386-linux-nat.c: Likewise.
	* ia64-linux-nat.c: Likewise.
	* mips-linux-nat.c: Likewise.
	* ppc-linux-nat.c: Likewise.
	* s390-linux-nat.c: Likewise.
	* sparc64-linux-nat.c: Likewise.
	* x86-linux-nat.c: Likewise.
	* x86-linux-nat.h: Include "nat/x86-linux.h".
	(x86_linux_nat_target) <low_new_fork, low_forget_process,
	low_prepare_to_resume, low_new_thread, low_delete_thread>:
	Override methods.
---
 gdb/aarch64-linux-nat.c |  43 ++++++++------
 gdb/amd64-linux-nat.c   |  24 ++++----
 gdb/arm-linux-nat.c     |  40 +++++++------
 gdb/i386-linux-nat.c    |   2 +-
 gdb/ia64-linux-nat.c    |   9 +--
 gdb/linux-fork.c        |   2 +-
 gdb/linux-nat.c         | 154 +++++-------------------------------------------
 gdb/linux-nat.h         |  76 +++++++++++-------------
 gdb/mips-linux-nat.c    |  13 ++--
 gdb/ppc-linux-nat.c     |   9 +--
 gdb/s390-linux-nat.c    |  32 +++++-----
 gdb/sparc64-linux-nat.c |   9 ++-
 gdb/x86-linux-nat.c     |  17 ++----
 gdb/x86-linux-nat.h     |  20 +++++--
 14 files changed, 172 insertions(+), 278 deletions(-)

diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
index 058ee4365d..724ca9c3ff 100644
--- a/gdb/aarch64-linux-nat.c
+++ b/gdb/aarch64-linux-nat.c
@@ -75,6 +75,21 @@ public:
 
   /* Override the GNU/Linux inferior startup hook.  */
   void post_startup_inferior (ptid_t) override;
+
+  /* These three defer to common nat/ code.  */
+  void low_new_thread (struct lwp_info *lp) override
+  { aarch64_linux_new_thread (lp); }
+  void low_delete_thread (struct arch_lwp_info *lp) override
+  { aarch64_linux_delete_thread (lp); }
+  void low_prepare_to_resume (struct lwp_info *lp) override
+  { aarch64_linux_prepare_to_resume (lp); }
+
+  void low_new_fork (struct lwp_info *parent, pid_t child_pid) override;
+  void low_forget_process (pid_t pid) override;
+
+  /* Add our siginfo layout converter.  */
+  bool low_siginfo_fixup (siginfo_t *ptrace, gdb_byte *inf, int direction)
+    override;
 };
 
 static aarch64_linux_nat_target the_aarch64_linux_nat_target;
@@ -147,8 +162,8 @@ aarch64_process_info_get (pid_t pid)
 /* Called whenever GDB is no longer debugging process PID.  It deletes
    data structures that keep track of debug register state.  */
 
-static void
-aarch64_forget_process (pid_t pid)
+void
+aarch64_linux_nat_target::low_forget_process (pid_t pid)
 {
   struct aarch64_process_info *proc, **proc_link;
 
@@ -456,8 +471,9 @@ supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp)
 
 /* linux_nat_new_fork hook.   */
 
-static void
-aarch64_linux_new_fork (struct lwp_info *parent, pid_t child_pid)
+void
+aarch64_linux_nat_target::low_new_fork (struct lwp_info *parent,
+					pid_t child_pid)
 {
   pid_t parent_pid;
   struct aarch64_debug_reg_state *parent_state;
@@ -500,7 +516,7 @@ ps_get_thread_area (struct ps_prochandle *ph,
 void
 aarch64_linux_nat_target::post_startup_inferior (ptid_t ptid)
 {
-  aarch64_forget_process (ptid_get_pid (ptid));
+  low_forget_process (ptid_get_pid (ptid));
   aarch64_linux_get_debug_reg_capacity (ptid_get_pid (ptid));
   linux_nat_target::post_startup_inferior (ptid);
 }
@@ -534,8 +550,9 @@ aarch64_linux_nat_target::read_description ()
    from INF to NATIVE.  If DIRECTION is 0, copy from NATIVE to
    INF.  */
 
-static int
-aarch64_linux_siginfo_fixup (siginfo_t *native, gdb_byte *inf, int direction)
+bool
+aarch64_linux_nat_target::low_siginfo_fixup (siginfo_t *native, gdb_byte *inf,
+					     int direction)
 {
   struct gdbarch *gdbarch = get_frame_arch (get_current_frame ());
 
@@ -550,10 +567,10 @@ aarch64_linux_siginfo_fixup (siginfo_t *native, gdb_byte *inf, int direction)
 	aarch64_siginfo_from_compat_siginfo (native,
 					     (struct compat_siginfo *) inf);
 
-      return 1;
+      return true;
     }
 
-  return 0;
+  return false;
 }
 
 /* Returns the number of hardware watchpoints of type TYPE that we can
@@ -826,12 +843,4 @@ _initialize_aarch64_linux_nat (void)
 
   /* Register the target.  */
   add_target (t);
-  linux_nat_set_new_thread (t, aarch64_linux_new_thread);
-  linux_nat_set_delete_thread (t, aarch64_linux_delete_thread);
-  linux_nat_set_new_fork (t, aarch64_linux_new_fork);
-  linux_nat_set_forget_process (t, aarch64_forget_process);
-  linux_nat_set_prepare_to_resume (t, aarch64_linux_prepare_to_resume);
-
-  /* Add our siginfo layout converter.  */
-  linux_nat_set_siginfo_fixup (t, aarch64_linux_siginfo_fixup);
 }
diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c
index cee364476c..9177c3eec2 100644
--- a/gdb/amd64-linux-nat.c
+++ b/gdb/amd64-linux-nat.c
@@ -50,6 +50,9 @@ struct amd64_linux_nat_target final : public x86_linux_nat_target
   /* Add our register access methods.  */
   void fetch_registers (struct regcache *, int) override;
   void store_registers (struct regcache *, int) override;
+
+  bool low_siginfo_fixup (siginfo_t *ptrace, gdb_byte *inf, int direction)
+    override;
 };
 
 static amd64_linux_nat_target the_amd64_linux_nat_target;
@@ -384,22 +387,24 @@ ps_get_thread_area (struct ps_prochandle *ph,
    from INF to PTRACE.  If DIRECTION is 0, copy from PTRACE to
    INF.  */
 
-static int
-amd64_linux_siginfo_fixup (siginfo_t *ptrace, gdb_byte *inf, int direction)
+bool
+amd64_linux_nat_target::low_siginfo_fixup (siginfo_t *ptrace,
+					   gdb_byte *inf,
+					   int direction)
 {
   struct gdbarch *gdbarch = get_frame_arch (get_current_frame ());
 
   /* Is the inferior 32-bit?  If so, then do fixup the siginfo
      object.  */
   if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32)
-      return amd64_linux_siginfo_fixup_common (ptrace, inf, direction,
-					       FIXUP_32);
+    return amd64_linux_siginfo_fixup_common (ptrace, inf, direction,
+					     FIXUP_32);
   /* No fixup for native x32 GDB.  */
   else if (gdbarch_addr_bit (gdbarch) == 32 && sizeof (void *) == 8)
-      return amd64_linux_siginfo_fixup_common (ptrace, inf, direction,
-					       FIXUP_X32);
+    return amd64_linux_siginfo_fixup_common (ptrace, inf, direction,
+					     FIXUP_X32);
   else
-    return 0;
+    return false;
 }
 
 void
@@ -416,8 +421,5 @@ _initialize_amd64_linux_nat (void)
   linux_target = &the_amd64_linux_nat_target;
 
   /* Add the target.  */
-  x86_linux_add_target (linux_target);
-
-  /* Add our siginfo layout converter.  */
-  linux_nat_set_siginfo_fixup (linux_target, amd64_linux_siginfo_fixup);
+  add_target (linux_target);
 }
diff --git a/gdb/arm-linux-nat.c b/gdb/arm-linux-nat.c
index c66c65f505..aac90fd223 100644
--- a/gdb/arm-linux-nat.c
+++ b/gdb/arm-linux-nat.c
@@ -94,6 +94,17 @@ public:
   bool watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, int) override;
 
   const struct target_desc *read_description () override;
+
+  /* Override linux_nat_target low methods.  */
+
+  /* Handle thread creation and exit.  */
+  void low_new_thread (struct lwp_info *lp) override;
+  void low_delete_thread (struct arch_lwp_info *lp) override;
+  void low_prepare_to_resume (struct lwp_info *lp) override;
+
+  /* Handle process creation and exit.  */
+  void low_new_fork (struct lwp_info *parent, pid_t child_pid) override;
+  void low_forget_process (pid_t pid) override;
 };
 
 static arm_linux_nat_target the_arm_linux_nat_target;
@@ -815,8 +826,8 @@ arm_linux_process_info_get (pid_t pid)
 /* Called whenever GDB is no longer debugging process PID.  It deletes
    data structures that keep track of debug register state.  */
 
-static void
-arm_linux_forget_process (pid_t pid)
+void
+arm_linux_nat_target::low_forget_process (pid_t pid)
 {
   struct arm_linux_process_info *proc, **proc_link;
 
@@ -1209,8 +1220,8 @@ arm_linux_nat_target::watchpoint_addr_within_range (CORE_ADDR addr,
 
 /* Handle thread creation.  We need to copy the breakpoints and watchpoints
    in the parent thread to the child thread.  */
-static void
-arm_linux_new_thread (struct lwp_info *lp)
+void
+arm_linux_nat_target::low_new_thread (struct lwp_info *lp)
 {
   int i;
   struct arch_lwp_info *info = XCNEW (struct arch_lwp_info);
@@ -1229,8 +1240,8 @@ arm_linux_new_thread (struct lwp_info *lp)
 
 /* Function to call when a thread is being deleted.  */
 
-static void
-arm_linux_delete_thread (struct arch_lwp_info *arch_lwp)
+void
+arm_linux_nat_target::low_delete_thread (struct arch_lwp_info *arch_lwp)
 {
   xfree (arch_lwp);
 }
@@ -1238,8 +1249,8 @@ arm_linux_delete_thread (struct arch_lwp_info *arch_lwp)
 /* Called when resuming a thread.
    The hardware debug registers are updated when there is any change.  */
 
-static void
-arm_linux_prepare_to_resume (struct lwp_info *lwp)
+void
+arm_linux_nat_target::low_prepare_to_resume (struct lwp_info *lwp)
 {
   int pid, i;
   struct arm_linux_hw_breakpoint *bpts, *wpts;
@@ -1292,8 +1303,8 @@ arm_linux_prepare_to_resume (struct lwp_info *lwp)
 
 /* linux_nat_new_fork hook.  */
 
-static void
-arm_linux_new_fork (struct lwp_info *parent, pid_t child_pid)
+void
+arm_linux_nat_target::low_new_fork (struct lwp_info *parent, pid_t child_pid)
 {
   pid_t parent_pid;
   struct arm_linux_debug_reg_state *parent_state;
@@ -1323,13 +1334,4 @@ _initialize_arm_linux_nat (void)
 
   /* Register the target.  */
   add_target (t);
-
-  /* Handle thread creation and exit.  */
-  linux_nat_set_new_thread (t, arm_linux_new_thread);
-  linux_nat_set_delete_thread (t, arm_linux_delete_thread);
-  linux_nat_set_prepare_to_resume (t, arm_linux_prepare_to_resume);
-
-  /* Handle process creation and exit.  */
-  linux_nat_set_new_fork (t, arm_linux_new_fork);
-  linux_nat_set_forget_process (t, arm_linux_forget_process);
 }
diff --git a/gdb/i386-linux-nat.c b/gdb/i386-linux-nat.c
index b923e65712..786eec227f 100644
--- a/gdb/i386-linux-nat.c
+++ b/gdb/i386-linux-nat.c
@@ -717,5 +717,5 @@ _initialize_i386_linux_nat (void)
   linux_target = &the_i386_linux_nat_target;
 
   /* Add the target.  */
-  x86_linux_add_target (linux_target);
+  add_target (linux_target);
 }
diff --git a/gdb/ia64-linux-nat.c b/gdb/ia64-linux-nat.c
index 9435bcf1ab..1e7ff6dcd5 100644
--- a/gdb/ia64-linux-nat.c
+++ b/gdb/ia64-linux-nat.c
@@ -79,6 +79,9 @@ public:
 			 struct expression *) override;
   int remove_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
 			 struct expression *) override;
+  /* Override linux_nat_target low methods.  */
+  void low_new_thread (struct lwp_info *lp) override;
+  bool low_status_is_event (int status) override;
 };
 
 static ia64_linux_nat_target the_ia64_linux_nat_target;
@@ -916,8 +919,8 @@ ia64_linux_nat_target::xfer_partial (enum target_object object,
    ia64 does not use gdbarch_decr_pc_after_break so we do not have to make any
    difference for the signals here.  */
 
-static int
-ia64_linux_status_is_event (int status)
+bool
+ia64_linux_nat_target::low_status_is_event (int status)
 {
   return WIFSTOPPED (status) && (WSTOPSIG (status) == SIGTRAP
 				 || WSTOPSIG (status) == SIGILL);
@@ -930,6 +933,4 @@ _initialize_ia64_linux_nat (void)
 
   /* Register the target.  */
   add_target (t);
-  linux_nat_set_new_thread (t, ia64_linux_new_thread);
-  linux_nat_set_status_is_event (t, ia64_linux_status_is_event);
 }
diff --git a/gdb/linux-fork.c b/gdb/linux-fork.c
index 9ffab1ff6c..8d94f8007e 100644
--- a/gdb/linux-fork.c
+++ b/gdb/linux-fork.c
@@ -141,7 +141,7 @@ delete_fork (ptid_t ptid)
 
   fpprev = NULL;
 
-  linux_nat_forget_process (ptid_get_pid (ptid));
+  linux_target->low_forget_process (ptid_get_pid (ptid));
 
   for (fp = fork_list; fp; fpprev = fp, fp = fp->next)
     if (ptid_equal (fp->ptid, ptid))
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index 701a7db05b..445b59fa4a 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -191,29 +191,6 @@ struct linux_nat_target *linux_target;
 /* Does the current host support PTRACE_GETREGSET?  */
 enum tribool have_ptrace_getregset = TRIBOOL_UNKNOWN;
 
-/* The method to call, if any, when a new thread is attached.  */
-static void (*linux_nat_new_thread) (struct lwp_info *);
-
-/* The method to call, if any, when a thread is destroyed.  */
-static void (*linux_nat_delete_thread) (struct arch_lwp_info *);
-
-/* The method to call, if any, when a new fork is attached.  */
-static linux_nat_new_fork_ftype *linux_nat_new_fork;
-
-/* The method to call, if any, when a process is no longer
-   attached.  */
-static linux_nat_forget_process_ftype *linux_nat_forget_process_hook;
-
-/* Hook to call prior to resuming a thread.  */
-static void (*linux_nat_prepare_to_resume) (struct lwp_info *);
-
-/* The method to call, if any, when the siginfo object needs to be
-   converted between the layout returned by ptrace, and the layout in
-   the architecture of the inferior.  */
-static int (*linux_nat_siginfo_fixup) (siginfo_t *,
-				       gdb_byte *,
-				       int);
-
 /* The saved to_close method, inherited from inf-ptrace.c.
    Called by our to_close.  */
 static void (*super_close) (struct target_ops *);
@@ -302,9 +279,6 @@ static struct lwp_info *find_lwp_pid (ptid_t ptid);
 
 static int lwp_status_pending_p (struct lwp_info *lp);
 
-static int sigtrap_is_event (int status);
-static int (*linux_nat_status_is_event) (int status) = sigtrap_is_event;
-
 static void save_stop_reason (struct lwp_info *lp);
 
 \f
@@ -497,8 +471,7 @@ linux_nat_target::follow_fork (int follow_child, int detach_fork)
 	  struct cleanup *old_chain = make_cleanup (delete_lwp_cleanup,
 						    child_lp);
 
-	  if (linux_nat_prepare_to_resume != NULL)
-	    linux_nat_prepare_to_resume (child_lp);
+	  linux_target->low_prepare_to_resume (child_lp);
 
 	  /* When debugging an inferior in an architecture that supports
 	     hardware single stepping on a kernel without commit
@@ -835,10 +808,7 @@ static void
 lwp_free (struct lwp_info *lp)
 {
   /* Let the arch specific bits release arch_lwp_info.  */
-  if (linux_nat_delete_thread != NULL)
-    linux_nat_delete_thread (lp->arch_private);
-  else
-    gdb_assert (lp->arch_private == NULL);
+  linux_target->low_delete_thread (lp->arch_private);
 
   xfree (lp);
 }
@@ -924,8 +894,7 @@ add_lwp (ptid_t ptid)
      clients of this callback take the opportunity to install
      watchpoints in the new thread.  We don't do this for the first
      thread though.  See add_initial_lwp.  */
-  if (linux_nat_new_thread != NULL)
-    linux_nat_new_thread (lp);
+  linux_target->low_new_thread (lp);
 
   return lp;
 }
@@ -1425,8 +1394,7 @@ detach_one_lwp (struct lwp_info *lp, int *signo_p)
      it below, when detach fails with ESRCH.  */
   TRY
     {
-      if (linux_nat_prepare_to_resume != NULL)
-	linux_nat_prepare_to_resume (lp);
+      linux_target->low_prepare_to_resume (lp);
     }
   CATCH (ex, RETURN_MASK_ERROR)
     {
@@ -1553,8 +1521,7 @@ linux_resume_one_lwp_throw (struct lwp_info *lp, int step,
   else
     lp->stop_pc = 0;
 
-  if (linux_nat_prepare_to_resume != NULL)
-    linux_nat_prepare_to_resume (lp);
+  linux_target->low_prepare_to_resume (lp);
   linux_target->low_resume (lp->ptid, step, signo);
 
   /* Successfully resumed.  Clear state that no longer makes sense,
@@ -1998,8 +1965,7 @@ linux_handle_extended_wait (struct lwp_info *lp, int status)
 	  /* The arch-specific native code may need to know about new
 	     forks even if those end up never mapped to an
 	     inferior.  */
-	  if (linux_nat_new_fork != NULL)
-	    linux_nat_new_fork (lp, new_pid);
+	  linux_target->low_new_fork (lp, new_pid);
 	}
 
       if (event == PTRACE_EVENT_FORK
@@ -2498,23 +2464,12 @@ linux_nat_target::stopped_data_address (CORE_ADDR *addr_p)
 
 /* Commonly any breakpoint / watchpoint generate only SIGTRAP.  */
 
-static int
-sigtrap_is_event (int status)
+bool
+linux_nat_target::low_status_is_event (int status)
 {
   return WIFSTOPPED (status) && WSTOPSIG (status) == SIGTRAP;
 }
 
-/* Set alternative SIGTRAP-like events recognizer.  If
-   breakpoint_inserted_here_p there then gdbarch_decr_pc_after_break will be
-   applied.  */
-
-void
-linux_nat_set_status_is_event (struct target_ops *t,
-			       int (*status_is_event) (int status))
-{
-  linux_nat_status_is_event = status_is_event;
-}
-
 /* Wait until LP is stopped.  */
 
 static int
@@ -2729,7 +2684,7 @@ save_stop_reason (struct lwp_info *lp)
   gdb_assert (lp->stop_reason == TARGET_STOPPED_BY_NO_REASON);
   gdb_assert (lp->status != 0);
 
-  if (!linux_nat_status_is_event (lp->status))
+  if (!linux_target->low_status_is_event (lp->status))
     return;
 
   regcache = get_thread_regcache (lp->ptid);
@@ -3468,7 +3423,7 @@ linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus,
       resume_clear_callback (lp, NULL);
     }
 
-  if (linux_nat_status_is_event (status))
+  if (linux_target->low_status_is_event (status))
     {
       if (debug_linux_nat)
 	fprintf_unfiltered (gdb_stdlog,
@@ -3735,7 +3690,7 @@ kill_unfollowed_fork_children (struct inferior *inf)
 
 	    /* Let the arch-specific native code know this process is
 	       gone.  */
-	    linux_nat_forget_process (child_pid);
+	    linux_target->low_forget_process (child_pid);
 	  }
       }
 }
@@ -3788,7 +3743,7 @@ linux_nat_target::mourn_inferior ()
     linux_fork_mourn_inferior ();
 
   /* Let the arch-specific native code know this process is gone.  */
-  linux_nat_forget_process (pid);
+  linux_target->low_forget_process (pid);
 }
 
 /* Convert a native/host siginfo object, into/from the siginfo in the
@@ -3797,14 +3752,9 @@ linux_nat_target::mourn_inferior ()
 static void
 siginfo_fixup (siginfo_t *siginfo, gdb_byte *inf_siginfo, int direction)
 {
-  int done = 0;
-
-  if (linux_nat_siginfo_fixup != NULL)
-    done = linux_nat_siginfo_fixup (siginfo, inf_siginfo, direction);
-
-  /* If there was no callback, or the callback didn't do anything,
-     then just do a straight memcpy.  */
-  if (!done)
+  /* If the low target didn't do anything, then just do a straight
+     memcpy.  */
+  if (!linux_target->low_siginfo_fixup (siginfo, inf_siginfo, direction))
     {
       if (direction == 1)
 	memcpy (siginfo, inf_siginfo, sizeof (siginfo_t));
@@ -4681,80 +4631,6 @@ linux_nat_target::linux_nat_target ()
      also want to be used for single-threaded processes.  */
 }
 
-/* Register a method to call whenever a new thread is attached.  */
-void
-linux_nat_set_new_thread (struct target_ops *t,
-			  void (*new_thread) (struct lwp_info *))
-{
-  /* Save the pointer.  We only support a single registered instance
-     of the GNU/Linux native target, so we do not need to map this to
-     T.  */
-  linux_nat_new_thread = new_thread;
-}
-
-/* Register a method to call whenever a new thread is attached.  */
-void
-linux_nat_set_delete_thread (struct target_ops *t,
-			     void (*delete_thread) (struct arch_lwp_info *))
-{
-  /* Save the pointer.  We only support a single registered instance
-     of the GNU/Linux native target, so we do not need to map this to
-     T.  */
-  linux_nat_delete_thread = delete_thread;
-}
-
-/* See declaration in linux-nat.h.  */
-
-void
-linux_nat_set_new_fork (struct target_ops *t,
-			linux_nat_new_fork_ftype *new_fork)
-{
-  /* Save the pointer.  */
-  linux_nat_new_fork = new_fork;
-}
-
-/* See declaration in linux-nat.h.  */
-
-void
-linux_nat_set_forget_process (struct target_ops *t,
-			      linux_nat_forget_process_ftype *fn)
-{
-  /* Save the pointer.  */
-  linux_nat_forget_process_hook = fn;
-}
-
-/* See declaration in linux-nat.h.  */
-
-void
-linux_nat_forget_process (pid_t pid)
-{
-  if (linux_nat_forget_process_hook != NULL)
-    linux_nat_forget_process_hook (pid);
-}
-
-/* Register a method that converts a siginfo object between the layout
-   that ptrace returns, and the layout in the architecture of the
-   inferior.  */
-void
-linux_nat_set_siginfo_fixup (struct target_ops *t,
-			     int (*siginfo_fixup) (siginfo_t *,
-						   gdb_byte *,
-						   int))
-{
-  /* Save the pointer.  */
-  linux_nat_siginfo_fixup = siginfo_fixup;
-}
-
-/* Register a method to call prior to resuming a thread.  */
-
-void
-linux_nat_set_prepare_to_resume (struct target_ops *t,
-				 void (*prepare_to_resume) (struct lwp_info *))
-{
-  /* Save the pointer.  */
-  linux_nat_prepare_to_resume = prepare_to_resume;
-}
-
 /* See linux-nat.h.  */
 
 int
diff --git a/gdb/linux-nat.h b/gdb/linux-nat.h
index fbee35e9b6..ad8fa4d46d 100644
--- a/gdb/linux-nat.h
+++ b/gdb/linux-nat.h
@@ -145,6 +145,42 @@ public:
 
   virtual bool low_stopped_data_address (CORE_ADDR *addr_p)
   { return false; }
+
+  /* The method to call, if any, when a new thread is attached.  */
+  virtual void low_new_thread (struct lwp_info *)
+  {}
+
+  /* The method to call, if any, when a thread is destroyed.  */
+  virtual void low_delete_thread (struct arch_lwp_info *lp)
+  {
+    gdb_assert (lp == NULL);
+  }
+
+  /* The method to call, if any, when a new fork is attached.  */
+  virtual void low_new_fork (struct lwp_info *parent, pid_t child_pid)
+  {}
+
+  /* The method to call, if any, when a process is no longer
+     attached.  */
+  virtual void low_forget_process (pid_t pid)
+  {}
+
+  /* Hook to call prior to resuming a thread.  */
+  virtual void low_prepare_to_resume (struct lwp_info *)
+  {}
+
+  /* Convert a ptrace/host siginfo object, into/from the siginfo in
+     the layout of the inferiors' architecture.  Returns true if any
+     conversion was done; false otherwise, in which case the caller
+     does a straight memcpy.  If DIRECTION is 1, then copy from INF to
+     PTRACE.  If DIRECTION is 0, copy from PTRACE to INF.  */
+  virtual bool low_siginfo_fixup (siginfo_t *ptrace, gdb_byte *inf,
+				  int direction)
+  { return false; }
+
+  /* SIGTRAP-like breakpoint status events recognizer.  The default
+     recognizes SIGTRAP only.  */
+  virtual bool low_status_is_event (int status);
 };
 
 /* The final/concrete instance.  */
@@ -278,42 +314,6 @@ extern void linux_stop_and_wait_all_lwps (void);
    left stopped.)  */
 extern void linux_unstop_all_lwps (void);
 
-/* Register a method to call whenever a new thread is attached.  */
-void linux_nat_set_new_thread (struct target_ops *, void (*) (struct lwp_info *));
-
-/* Register a method to call whenever a new thread is deleted.  */
-void linux_nat_set_delete_thread (struct target_ops *,
-				  void (*) (struct arch_lwp_info *));
-
-/* Register a method to call whenever a new fork is attached.  */
-typedef void (linux_nat_new_fork_ftype) (struct lwp_info *parent,
-					 pid_t child_pid);
-void linux_nat_set_new_fork (struct target_ops *ops,
-			     linux_nat_new_fork_ftype *fn);
-
-/* Register a method to call whenever a process is killed or
-   detached.  */
-typedef void (linux_nat_forget_process_ftype) (pid_t pid);
-void linux_nat_set_forget_process (struct target_ops *ops,
-				   linux_nat_forget_process_ftype *fn);
-
-/* Call the method registered with the function above.  PID is the
-   process to forget about.  */
-void linux_nat_forget_process (pid_t pid);
-
-/* Register a method that converts a siginfo object between the layout
-   that ptrace returns, and the layout in the architecture of the
-   inferior.  */
-void linux_nat_set_siginfo_fixup (struct target_ops *,
-				  int (*) (siginfo_t *,
-					   gdb_byte *,
-					   int));
-
-/* Register a method to call prior to resuming a thread.  */
-
-void linux_nat_set_prepare_to_resume (struct target_ops *,
-				      void (*) (struct lwp_info *));
-
 /* Update linux-nat internal state when changing from one fork
    to another.  */
 void linux_nat_switch_fork (ptid_t new_ptid);
@@ -322,7 +322,3 @@ void linux_nat_switch_fork (ptid_t new_ptid);
    Return 1 if it was retrieved successfully, 0 otherwise (*SIGINFO is
    uninitialized in such case).  */
 int linux_nat_get_siginfo (ptid_t ptid, siginfo_t *siginfo);
-
-/* Set alternative SIGTRAP-like events recognizer.  */
-void linux_nat_set_status_is_event (struct target_ops *t,
-				    int (*status_is_event) (int status));
diff --git a/gdb/mips-linux-nat.c b/gdb/mips-linux-nat.c
index 0659c2e90d..8432171890 100644
--- a/gdb/mips-linux-nat.c
+++ b/gdb/mips-linux-nat.c
@@ -72,6 +72,9 @@ protected:
   CORE_ADDR register_u_offset (struct gdbarch *gdbarch,
 			       int regno, int store_p) override;
 
+  /* Override linux_nat_target low methods.  */
+  void low_new_thread (struct lwp_info *lp) override;
+
 private:
   /* Helpers.  See definitions.  */
   void mips64_regsets_store_registers (struct regcache *regcache,
@@ -642,11 +645,11 @@ write_watchpoint_regs (void)
   return 0;
 }
 
-/* linux_nat new_thread implementation.  Write the mirrored watch
- register values for the new thread.  */
+/* linux_nat_target::low_new_thread implementation.  Write the
+   mirrored watch register values for the new thread.  */
 
-static void
-mips_linux_new_thread (struct lwp_info *lp)
+void
+mips_linux_nat_target::low_new_thread (struct lwp_info *lp)
 {
   long tid = lp->ptid.lwp ();
 
@@ -799,6 +802,4 @@ triggers a breakpoint or watchpoint."),
 			   &maintenance_show_cmdlist);
 
   add_target (&the_mips_linux_nat_target);
-  linux_nat_set_new_thread (&the_mips_linux_nat_target,
-			    mips_linux_new_thread);
 }
diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c
index 7362bee4ef..a1c3dc8fe3 100644
--- a/gdb/ppc-linux-nat.c
+++ b/gdb/ppc-linux-nat.c
@@ -314,6 +314,9 @@ struct ppc_linux_nat_target final : public linux_nat_target
   int auxv_parse (gdb_byte **readptr,
 		  gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
     override;
+
+  /* Override linux_nat_target low methods.  */
+  void low_new_thread (struct lwp_info *lp) override;
 };
 
 static ppc_linux_nat_target the_ppc_linux_nat_target;
@@ -2151,8 +2154,8 @@ ppc_linux_nat_target::remove_watchpoint (CORE_ADDR addr, int len,
   return ret;
 }
 
-static void
-ppc_linux_new_thread (struct lwp_info *lp)
+void
+ppc_linux_nat_target::low_new_thread (struct lwp_info *lp)
 {
   int tid = ptid_get_lwp (lp->ptid);
 
@@ -2507,6 +2510,4 @@ _initialize_ppc_linux_nat (void)
 
   /* Register the target.  */
   add_target (linux_target);
-
-  linux_nat_set_new_thread (linux_target, ppc_linux_new_thread);
 }
diff --git a/gdb/s390-linux-nat.c b/gdb/s390-linux-nat.c
index 2d82f53c04..637d12f4b2 100644
--- a/gdb/s390-linux-nat.c
+++ b/gdb/s390-linux-nat.c
@@ -135,6 +135,13 @@ public:
   int auxv_parse (gdb_byte **readptr,
 		  gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
     override;
+
+  /* Override linux_nat_target low methods.  */
+  void low_new_thread (struct lwp_info *lp) override;
+  void low_delete_thread (struct arch_lwp_info *lp) override;
+  void low_prepare_to_resume (struct lwp_info *lp) override;
+  void low_new_fork (struct lwp_info *parent, pid_t child_pid) override;
+  void low_forget_process (pid_t pid) override;
 };
 
 static s390_linux_nat_target the_s390_linux_nat_target;
@@ -575,8 +582,8 @@ s390_get_debug_reg_state (pid_t pid)
 /* Called whenever GDB is no longer debugging process PID.  It deletes
    data structures that keep track of hardware debug state.  */
 
-static void
-s390_forget_process (pid_t pid)
+void
+s390_linux_nat_target::low_forget_process (pid_t pid)
 {
   struct s390_process_info *proc, **proc_link;
 
@@ -601,8 +608,8 @@ s390_forget_process (pid_t pid)
 
 /* linux_nat_new_fork hook.   */
 
-static void
-s390_linux_new_fork (struct lwp_info *parent, pid_t child_pid)
+void
+s390_linux_nat_target::low_new_fork (struct lwp_info *parent, pid_t child_pid)
 {
   pid_t parent_pid;
   struct s390_debug_reg_state *parent_state;
@@ -694,8 +701,8 @@ s390_linux_nat_target::stopped_by_watchpoint ()
 
 /* Each time before resuming a thread, update its PER info.  */
 
-static void
-s390_prepare_to_resume (struct lwp_info *lp)
+void
+s390_linux_nat_target::low_prepare_to_resume (struct lwp_info *lp)
 {
   int tid;
   pid_t pid = ptid_get_pid (ptid_of_lwp (lp));
@@ -811,16 +818,16 @@ s390_mark_per_info_changed (struct lwp_info *lp)
 
 /* When attaching to a new thread, mark its PER info as changed.  */
 
-static void
-s390_new_thread (struct lwp_info *lp)
+void
+s390_linux_nat_target::low_new_thread (struct lwp_info *lp)
 {
   s390_mark_per_info_changed (lp);
 }
 
 /* Function to call when a thread is being deleted.  */
 
-static void
-s390_delete_thread (struct arch_lwp_info *arch_lwp)
+void
+s390_linux_nat_target::low_delete_thread (struct arch_lwp_info *arch_lwp)
 {
   xfree (arch_lwp);
 }
@@ -1062,11 +1069,6 @@ _initialize_s390_nat (void)
 
   /* Register the target.  */
   add_target (t);
-  linux_nat_set_new_thread (t, s390_new_thread);
-  linux_nat_set_delete_thread (t, s390_delete_thread);
-  linux_nat_set_prepare_to_resume (t, s390_prepare_to_resume);
-  linux_nat_set_forget_process (t, s390_forget_process);
-  linux_nat_set_new_fork (t, s390_linux_new_fork);
 
   /* A maintenance command to enable showing the PER state.  */
   add_setshow_boolean_cmd ("show-debug-regs", class_maintenance,
diff --git a/gdb/sparc64-linux-nat.c b/gdb/sparc64-linux-nat.c
index ea7cfb43f6..bc7855acfa 100644
--- a/gdb/sparc64-linux-nat.c
+++ b/gdb/sparc64-linux-nat.c
@@ -39,6 +39,12 @@ public:
 
   void store_registers (struct regcache *regcache, int regnum) override;
   { sparc_store_inferior_registers (this, regcache, regnum); }
+
+  /* Override linux_nat_target low methods.  */
+
+  /* ADI support */
+  void low_forget_process (pid_t pid) override
+  { sparc_forget_process (pid); }
 };
 
 static sparc64_linux_nat_target the_sparc64_linux_nat_target;
@@ -92,8 +98,5 @@ _initialize_sparc64_linux_nat (void)
   /* Register the target.  */
   add_target (t);
 
-  /* ADI support */
-  linux_nat_set_forget_process (t, sparc64_forget_process);
-
   sparc_gregmap = &sparc64_linux_ptrace_gregmap;
 }
diff --git a/gdb/x86-linux-nat.c b/gdb/x86-linux-nat.c
index 0910d0047e..90e5c19048 100644
--- a/gdb/x86-linux-nat.c
+++ b/gdb/x86-linux-nat.c
@@ -42,10 +42,10 @@
 #include "nat/x86-linux-dregs.h"
 #include "nat/linux-ptrace.h"
 
-/* linux_nat_new_fork hook.   */
+/* linux_nat_target::low_new_fork implementation.  */
 
-static void
-x86_linux_new_fork (struct lwp_info *parent, pid_t child_pid)
+void
+x86_linux_nat_target::low_new_fork (struct lwp_info *parent, pid_t child_pid)
 {
   pid_t parent_pid;
   struct x86_debug_reg_state *parent_state;
@@ -311,10 +311,8 @@ x86_linux_get_thread_area (pid_t pid, void *addr, unsigned int *base_addr)
 }
 \f
 
-/* Add an x86 GNU/Linux target.  */
-
 void
-x86_linux_add_target (linux_nat_target *t)
+_initialize_x86_linux_nat ()
 {
   /* Initialize the debug register function vectors.  */
   x86_dr_low.set_control = x86_linux_dr_set_control;
@@ -323,11 +321,4 @@ x86_linux_add_target (linux_nat_target *t)
   x86_dr_low.get_status = x86_linux_dr_get_status;
   x86_dr_low.get_control = x86_linux_dr_get_control;
   x86_set_debug_register_length (sizeof (void *));
-
-  add_target (t);
-  linux_nat_set_new_thread (t, x86_linux_new_thread);
-  linux_nat_set_delete_thread (t, x86_linux_delete_thread);
-  linux_nat_set_new_fork (t, x86_linux_new_fork);
-  linux_nat_set_forget_process (t, x86_forget_process);
-  linux_nat_set_prepare_to_resume (t, x86_linux_prepare_to_resume);
 }
diff --git a/gdb/x86-linux-nat.h b/gdb/x86-linux-nat.h
index 7cbb27184a..9eac2a0f87 100644
--- a/gdb/x86-linux-nat.h
+++ b/gdb/x86-linux-nat.h
@@ -23,6 +23,7 @@
 #include "gdb_proc_service.h"  /* For ps_err_e.  */
 #include "linux-nat.h"
 #include "x86-nat.h"
+#include "nat/x86-linux.h"
 
 struct x86_linux_nat_target : public x86_nat_target<linux_nat_target>
 {
@@ -58,6 +59,20 @@ struct x86_linux_nat_target : public x86_nat_target<linux_nat_target>
 
   bool low_stopped_data_address (CORE_ADDR *addr_p) override
   { return x86_nat_target::stopped_data_address (addr_p); }
+
+  void low_new_fork (struct lwp_info *parent, pid_t child_pid) override;
+
+  void low_forget_process (pid_t pid) override
+  { x86_forget_process (pid); }
+
+  void low_prepare_to_resume (struct lwp_info *lwp) override
+  { x86_linux_prepare_to_resume (lwp); }
+
+  void low_new_thread (struct lwp_info *lwp) override
+  { x86_linux_new_thread (lwp); }
+
+  void low_delete_thread (struct arch_lwp_info *lwp) override
+  { x86_linux_delete_thread (lwp); }
 };
 
 \f
@@ -68,10 +83,5 @@ struct x86_linux_nat_target : public x86_nat_target<linux_nat_target>
 
 extern ps_err_e x86_linux_get_thread_area (pid_t pid, void *addr,
 					   unsigned int *base_addr);
-\f
-
-/* Add an x86 GNU/Linux target.  */
-
-extern void x86_linux_add_target (linux_nat_target *t);
 
 #endif
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 38/40] target_ops: Use bool throughout
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (3 preceding siblings ...)
  2018-04-14 19:10 ` [PATCH 07/40] target_ops/C++: ravenscar-thread Pedro Alves
@ 2018-04-14 19:10 ` Pedro Alves
  2018-04-14 19:10 ` [PATCH 32/40] target_ops/C++: Generic i386/AMD64 BSD targets Pedro Alves
                   ` (36 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:10 UTC (permalink / raw)
  To: gdb-patches

After the previous target_ops/C++ patches are all squashed and merged,
this one can go in separately.

This patch adjusts all the target methods to return bool instead of int
when they're returning a boolean.

gdb/ChangeLog:
yyyy-mm-dd  Pedro Alves  <palves@redhat.com>

	* target.h (target_ops)
	<stopped_by_sw_breakpoint, supports_stopped_by_sw_breakpoint,
	stopped_by_hw_breakpoint, supports_stopped_by_hw_breakpoint,
	stopped_by_watchpoint, have_continuable_watchpoint,
	stopped_data_address, watchpoint_addr_within_range,
	can_accel_watchpoint_condition, can_run, thread_alive,
	has_all_memory, has_memory, has_stack, has_registers,
	has_execution, can_async_p, is_async_p, supports_non_stop,
	always_non_stop_p, can_execute_reverse, supports_multi_process,
	supports_enable_disable_tracepoint,
	supports_disable_randomization, supports_string_tracing,
	supports_evaluation_of_breakpoint_conditions,
	can_run_breakpoint_commands, filesystem_is_local,
	can_download_tracepoint, get_trace_state_variable_value,
	set_trace_notes, get_tib_address, use_agent, can_use_agent,
	record_is_replaying, record_will_replay,
	augmented_libraries_svr4_read>: Adjust to return bool.
	* aarch64-linux-nat.c: All implementations adjusted.
	* aix-thread.c: All implementations adjusted.
	* arm-linux-nat.c: All implementations adjusted.
	* breakpoint.c: All implementations adjusted.
	* bsd-kvm.c: All implementations adjusted.
	* bsd-uthread.c: All implementations adjusted.
	* corelow.c: All implementations adjusted.
	* ctf.c: All implementations adjusted.
	* darwin-nat.c: All implementations adjusted.
	* darwin-nat.h: All implementations adjusted.
	* exec.c: All implementations adjusted.
	* fbsd-nat.c: All implementations adjusted.
	* fbsd-nat.h: All implementations adjusted.
	* gnu-nat.c: All implementations adjusted.
	* gnu-nat.h: All implementations adjusted.
	* go32-nat.c: All implementations adjusted.
	* ia64-linux-nat.c: All implementations adjusted.
	* inf-child.c: All implementations adjusted.
	* inf-child.h: All implementations adjusted.
	* inf-ptrace.c: All implementations adjusted.
	* inf-ptrace.h: All implementations adjusted.
	* linux-nat.c: All implementations adjusted.
	* linux-nat.h: All implementations adjusted.
	* mips-linux-nat.c: All implementations adjusted.
	* nto-procfs.c: All implementations adjusted.
	* ppc-linux-nat.c: All implementations adjusted.
	* procfs.c: All implementations adjusted.
	* ravenscar-thread.c: All implementations adjusted.
	* record-btrace.c: All implementations adjusted.
	* record-full.c: All implementations adjusted.
	* remote-sim.c: All implementations adjusted.
	* remote.c: All implementations adjusted.
	* s390-linux-nat.c: All implementations adjusted.
	* sol-thread.c: All implementations adjusted.
	* spu-multiarch.c: All implementations adjusted.
	* target-delegates.c: All implementations adjusted.
	* target.c: All implementations adjusted.
	* target.h: All implementations adjusted.
	* tracefile-tfile.c: All implementations adjusted.
	* tracefile.c: All implementations adjusted.
	* tracefile.h: All implementations adjusted.
	* windows-nat.c: All implementations adjusted.
	* x86-linux-nat.h: All implementations adjusted.
	* x86-nat.h: All implementations adjusted.
---
 gdb/aarch64-linux-nat.c |  20 +-
 gdb/aix-thread.c        |   4 +-
 gdb/arm-linux-nat.c     |  20 +-
 gdb/breakpoint.c        |   2 +-
 gdb/bsd-kvm.c           |  12 +-
 gdb/bsd-uthread.c       |   6 +-
 gdb/corelow.c           |  18 +-
 gdb/ctf.c               |   8 +-
 gdb/darwin-nat.c        |   8 +-
 gdb/darwin-nat.h        |   4 +-
 gdb/exec.c              |   4 +-
 gdb/fbsd-nat.c          |  16 +-
 gdb/fbsd-nat.h          |   6 +-
 gdb/gnu-nat.c           |   2 +-
 gdb/gnu-nat.h           |   2 +-
 gdb/go32-nat.c          |   4 +-
 gdb/ia64-linux-nat.c    |  16 +-
 gdb/inf-child.c         |  24 +--
 gdb/inf-child.h         |  20 +-
 gdb/inf-ptrace.c        |   2 +-
 gdb/inf-ptrace.h        |   2 +-
 gdb/linux-nat.c         |  30 +--
 gdb/linux-nat.h         |  36 ++--
 gdb/mips-linux-nat.c    |  16 +-
 gdb/nto-procfs.c        |  17 +-
 gdb/ppc-linux-nat.c     |  24 +--
 gdb/procfs.c            |  22 +--
 gdb/ravenscar-thread.c  |  40 ++--
 gdb/record-btrace.c     |  42 ++---
 gdb/record-full.c       |  50 ++---
 gdb/remote-sim.c        |  32 ++--
 gdb/remote.c            | 166 ++++++++---------
 gdb/s390-linux-nat.c    |  15 +-
 gdb/sol-thread.c        |  10 +-
 gdb/spu-multiarch.c     |   3 +-
 gdb/target-delegates.c  | 486 ++++++++++++++++++++++++------------------------
 gdb/target.c            |   4 +-
 gdb/target.h            | 152 +++++++--------
 gdb/tracefile-tfile.c   |   8 +-
 gdb/tracefile.c         |  10 +-
 gdb/tracefile.h         |  10 +-
 gdb/windows-nat.c       |  15 +-
 gdb/x86-linux-nat.h     |   8 +-
 gdb/x86-nat.h           |   6 +-
 44 files changed, 701 insertions(+), 701 deletions(-)

diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
index 1919241466..058ee4365d 100644
--- a/gdb/aarch64-linux-nat.c
+++ b/gdb/aarch64-linux-nat.c
@@ -67,9 +67,9 @@ public:
 			 struct expression *) override;
   int remove_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
 			 struct expression *) override;
-  int stopped_by_watchpoint () override;
-  int stopped_data_address (CORE_ADDR *) override;
-  int watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, int) override;
+  bool stopped_by_watchpoint () override;
+  bool stopped_data_address (CORE_ADDR *) override;
+  bool watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, int) override;
 
   int can_do_single_step () override;
 
@@ -733,7 +733,7 @@ aarch64_linux_nat_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
 
 /* Implement the "stopped_data_address" target_ops method.  */
 
-int
+bool
 aarch64_linux_nat_target::stopped_data_address (CORE_ADDR *addr_p)
 {
   siginfo_t siginfo;
@@ -741,12 +741,12 @@ aarch64_linux_nat_target::stopped_data_address (CORE_ADDR *addr_p)
   struct aarch64_debug_reg_state *state;
 
   if (!linux_nat_get_siginfo (inferior_ptid, &siginfo))
-    return 0;
+    return false;
 
   /* This must be a hardware breakpoint.  */
   if (siginfo.si_signo != SIGTRAP
       || (siginfo.si_code & 0xffff) != TRAP_HWBKPT)
-    return 0;
+    return false;
 
   /* Check if the address matches any watched address.  */
   state = aarch64_get_debug_reg_state (ptid_get_pid (inferior_ptid));
@@ -762,16 +762,16 @@ aarch64_linux_nat_target::stopped_data_address (CORE_ADDR *addr_p)
 	  && addr_trap < addr_watch + len)
 	{
 	  *addr_p = addr_trap;
-	  return 1;
+	  return true;
 	}
     }
 
-  return 0;
+  return false;
 }
 
 /* Implement the "stopped_by_watchpoint" target_ops method.  */
 
-int
+bool
 aarch64_linux_nat_target::stopped_by_watchpoint ()
 {
   CORE_ADDR addr;
@@ -781,7 +781,7 @@ aarch64_linux_nat_target::stopped_by_watchpoint ()
 
 /* Implement the "watchpoint_addr_within_range" target_ops method.  */
 
-int
+bool
 aarch64_linux_nat_target::watchpoint_addr_within_range (CORE_ADDR addr,
 							CORE_ADDR start, int length)
 {
diff --git a/gdb/aix-thread.c b/gdb/aix-thread.c
index 3727336fcb..410fb55e72 100644
--- a/gdb/aix-thread.c
+++ b/gdb/aix-thread.c
@@ -137,7 +137,7 @@ public:
 
   void mourn_inferior () override;
 
-  int thread_alive (ptid_t ptid) override;
+  bool thread_alive (ptid_t ptid) override;
 
   const char *pid_to_str (ptid_t) override;
 
@@ -1762,7 +1762,7 @@ aix_thread_target::mourn_inferior ()
 
 /* Return whether thread PID is still valid.  */
 
-int
+bool
 aix_thread_target::thread_alive (ptid_t ptid)
 {
   struct target_ops *beneath = find_target_beneath (this);
diff --git a/gdb/arm-linux-nat.c b/gdb/arm-linux-nat.c
index 75d89f284e..c66c65f505 100644
--- a/gdb/arm-linux-nat.c
+++ b/gdb/arm-linux-nat.c
@@ -87,11 +87,11 @@ public:
 
   int remove_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
 			 struct expression *) override;
-  int stopped_by_watchpoint () override;
+  bool stopped_by_watchpoint () override;
 
-  int stopped_data_address (CORE_ADDR *) override;
+  bool stopped_data_address (CORE_ADDR *) override;
 
-  int watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, int) override;
+  bool watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, int) override;
 
   const struct target_desc *read_description () override;
 };
@@ -1162,19 +1162,19 @@ arm_linux_nat_target::remove_watchpoint (CORE_ADDR addr,
 }
 
 /* What was the data address the target was stopped on accessing.  */
-int
+bool
 arm_linux_nat_target::stopped_data_address (CORE_ADDR *addr_p)
 {
   siginfo_t siginfo;
   int slot;
 
   if (!linux_nat_get_siginfo (inferior_ptid, &siginfo))
-    return 0;
+    return false;
 
   /* This must be a hardware breakpoint.  */
   if (siginfo.si_signo != SIGTRAP
       || (siginfo.si_code & 0xffff) != 0x0004 /* TRAP_HWBKPT */)
-    return 0;
+    return false;
 
   /* We must be able to set hardware watchpoints.  */
   if (arm_linux_get_hw_watchpoint_count () == 0)
@@ -1185,21 +1185,21 @@ arm_linux_nat_target::stopped_data_address (CORE_ADDR *addr_p)
   /* If we are in a positive slot then we're looking at a breakpoint and not
      a watchpoint.  */
   if (slot >= 0)
-    return 0;
+    return false;
 
   *addr_p = (CORE_ADDR) (uintptr_t) siginfo.si_addr;
-  return 1;
+  return true;
 }
 
 /* Has the target been stopped by hitting a watchpoint?  */
-int
+bool
 arm_linux_nat_target::stopped_by_watchpoint ()
 {
   CORE_ADDR addr;
   return stopped_data_address (&addr);
 }
 
-int
+bool
 arm_linux_nat_target::watchpoint_addr_within_range (CORE_ADDR addr,
 						    CORE_ADDR start,
 						    int length)
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index a5287128d0..5098aed7e1 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -4733,7 +4733,7 @@ bpstats::bpstats ()
 int
 watchpoints_triggered (struct target_waitstatus *ws)
 {
-  int stopped_by_watchpoint = target_stopped_by_watchpoint ();
+  bool stopped_by_watchpoint = target_stopped_by_watchpoint ();
   CORE_ADDR addr;
   struct breakpoint *b;
 
diff --git a/gdb/bsd-kvm.c b/gdb/bsd-kvm.c
index f6b7ad15db..804cddb927 100644
--- a/gdb/bsd-kvm.c
+++ b/gdb/bsd-kvm.c
@@ -93,12 +93,12 @@ Optionally specify the filename of a core dump.");
 					ULONGEST *xfered_len) override;
 
   void files_info () override;
-  int thread_alive (ptid_t ptid) override;
+  bool thread_alive (ptid_t ptid) override;
   const char *pid_to_str (ptid_t) override;
 
-  int has_memory () override { return 1; }
-  int has_stack () override { return 1; }
-  int has_registers () override { return 1; }
+  bool has_memory () override { return true; }
+  bool has_stack () override { return true; }
+  bool has_registers () override { return true; }
 };
 
 /* Target ops for libkvm interface.  */
@@ -364,10 +364,10 @@ bsd_kvm_pcb_cmd (const char *arg, int fromtty)
   print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC, 1);
 }
 
-int
+bool
 bsd_kvm_target::thread_alive (ptid_t ptid)
 {
-  return 1;
+  return true;
 }
 
 const char *
diff --git a/gdb/bsd-uthread.c b/gdb/bsd-uthread.c
index 19d49c76f9..efcec1e396 100644
--- a/gdb/bsd-uthread.c
+++ b/gdb/bsd-uthread.c
@@ -57,7 +57,7 @@ struct bsd_uthread_target final : public target_ops
   ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
   void resume (ptid_t, int, enum gdb_signal) override;
 
-  int thread_alive (ptid_t ptid) override;
+  bool thread_alive (ptid_t ptid) override;
 
   void update_thread_list () override;
 
@@ -437,7 +437,7 @@ bsd_uthread_target::resume (ptid_t ptid, int step, enum gdb_signal sig)
   beneath->resume (ptid, step, sig);
 }
 
-int
+bool
 bsd_uthread_target::thread_alive (ptid_t ptid)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
@@ -453,7 +453,7 @@ bsd_uthread_target::thread_alive (ptid_t ptid)
 
       state = read_memory_unsigned_integer (addr + offset, 4, byte_order);
       if (state == BSD_UTHREAD_PS_DEAD)
-	return 0;
+	return false;
     }
 
   return beneath->thread_alive (ptid);
diff --git a/gdb/corelow.c b/gdb/corelow.c
index f7202f75e3..e7d9a7ed51 100644
--- a/gdb/corelow.c
+++ b/gdb/corelow.c
@@ -83,16 +83,16 @@ Use a core file as a target.  Specify the filename of the core file.");
 					ULONGEST *xfered_len) override;
   void files_info () override;
 
-  int thread_alive (ptid_t ptid) override;
+  bool thread_alive (ptid_t ptid) override;
   const struct target_desc *read_description () override;
 
   const char *pid_to_str (ptid_t) override;
 
   const char *thread_name (struct thread_info *) override;
 
-  int has_memory () override;
-  int has_stack () override;
-  int has_registers () override;
+  bool has_memory () override;
+  bool has_stack () override;
+  bool has_registers () override;
   bool info_proc (const char *, enum info_proc_what) override;
 };
 
@@ -922,10 +922,10 @@ core_target::xfer_partial (enum target_object object, const char *annex,
    to appear in an "info thread" command, which is quite a useful
    behaviour.
  */
-int
+bool
 core_target::thread_alive (ptid_t ptid)
 {
-  return 1;
+  return true;
 }
 
 /* Ask the current architecture what it knows about this core file.
@@ -989,19 +989,19 @@ core_target::thread_name (struct thread_info *thr)
   return NULL;
 }
 
-int
+bool
 core_target::has_memory ()
 {
   return (core_bfd != NULL);
 }
 
-int
+bool
 core_target::has_stack ()
 {
   return (core_bfd != NULL);
 }
 
-int
+bool
 core_target::has_registers ()
 {
   return (core_bfd != NULL);
diff --git a/gdb/ctf.c b/gdb/ctf.c
index b09cebbf07..90d6f6c025 100644
--- a/gdb/ctf.c
+++ b/gdb/ctf.c
@@ -62,7 +62,7 @@ Specify the filename of the CTF directory.");
   void files_info () override;
   int trace_find (enum trace_find_type type, int num,
 			  CORE_ADDR addr1, CORE_ADDR addr2, int *tpp) override;
-  int get_trace_state_variable_value (int tsv, LONGEST *val) override;
+  bool get_trace_state_variable_value (int tsv, LONGEST *val) override;
   traceframe_info_up traceframe_info () override;
 };
 
@@ -1430,11 +1430,11 @@ ctf_target::xfer_partial (enum target_object object,
    trace variable is found, set the value of it to *VAL and return
    true, otherwise return false.  */
 
-int
+bool
 ctf_target::get_trace_state_variable_value (int tsvnum, LONGEST *val)
 {
   struct bt_iter_pos *pos;
-  int found = 0;
+  bool found = false;
 
   gdb_assert (ctf_iter != NULL);
   /* Save the current position.  */
@@ -1465,7 +1465,7 @@ ctf_target::get_trace_state_variable_value (int tsvnum, LONGEST *val)
 	      def = bt_ctf_get_field (event, scope, "val");
 	      *val = bt_ctf_get_uint64 (def);
 
-	      found = 1;
+	      found = true;
 	    }
 	}
 
diff --git a/gdb/darwin-nat.c b/gdb/darwin-nat.c
index 919643145a..8af542863a 100644
--- a/gdb/darwin-nat.c
+++ b/gdb/darwin-nat.c
@@ -1959,10 +1959,10 @@ darwin_nat_target::pid_to_str (ptid_t ptid)
   return normal_pid_to_str (ptid);
 }
 
-int
+bool
 darwin_nat_target::thread_alive (ptid_t ptid)
 {
-  return 1;
+  return true;
 }
 
 /* If RDADDR is not NULL, read inferior task's LEN bytes from ADDR and
@@ -2306,10 +2306,10 @@ darwin_nat_target::get_ada_task_ptid (long lwp, long thread)
     return null_ptid;
 }
 
-int
+bool
 darwin_nat_target::supports_multi_process ()
 {
-  return 1;
+  return true;
 }
 
 void
diff --git a/gdb/darwin-nat.h b/gdb/darwin-nat.h
index d4a06d9c27..9d45bdabe8 100644
--- a/gdb/darwin-nat.h
+++ b/gdb/darwin-nat.h
@@ -43,7 +43,7 @@ class darwin_nat_target : public inf_child_target
 
   void resume (ptid_t, int , enum gdb_signal) override;
 
-  int thread_alive (ptid_t ptid) override;
+  bool thread_alive (ptid_t ptid) override;
 
   const char *pid_to_str (ptid_t) override;
 
@@ -56,7 +56,7 @@ class darwin_nat_target : public inf_child_target
 					ULONGEST offset, ULONGEST len,
 					ULONGEST *xfered_len) override;
 
-  int supports_multi_process () override;
+  bool supports_multi_process () override;
 
   ptid_t get_ada_task_ptid (long lwp, long thread) override;
 };
diff --git a/gdb/exec.c b/gdb/exec.c
index 14d0668591..4c71abd35f 100644
--- a/gdb/exec.c
+++ b/gdb/exec.c
@@ -80,7 +80,7 @@ Specify the filename of the executable file.");
   struct target_section_table *get_section_table () override;
   void files_info () override;
 
-  int has_memory () override;
+  bool has_memory () override;
   char *make_corefile_notes (bfd *, int *) override;
   int find_memory_regions (find_memory_region_ftype func, void *data) override;
 };
@@ -1031,7 +1031,7 @@ exec_set_section_address (const char *filename, int index, CORE_ADDR address)
     }
 }
 
-int
+bool
 exec_target::has_memory ()
 {
   /* We can provide memory if we have any file/target sections to read
diff --git a/gdb/fbsd-nat.c b/gdb/fbsd-nat.c
index 5324f8b07e..c6f8b802e3 100644
--- a/gdb/fbsd-nat.c
+++ b/gdb/fbsd-nat.c
@@ -813,7 +813,7 @@ show_fbsd_nat_debug (struct ui_file *file, int from_tty,
 
 /* Return true if PTID is still active in the inferior.  */
 
-int
+bool
 fbsd_nat_target::thread_alive (ptid_t ptid)
 {
   if (ptid_lwp_p (ptid))
@@ -822,14 +822,14 @@ fbsd_nat_target::thread_alive (ptid_t ptid)
 
       if (ptrace (PT_LWPINFO, ptid_get_lwp (ptid), (caddr_t) &pl, sizeof pl)
 	  == -1)
-	return 0;
+	return false;
 #ifdef PL_FLAG_EXITED
       if (pl.pl_flags & PL_FLAG_EXITED)
-	return 0;
+	return false;
 #endif
     }
 
-  return 1;
+  return true;
 }
 
 /* Convert PTID to a string.  Returns the string in a static
@@ -1458,14 +1458,14 @@ fbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
 #ifdef USE_SIGTRAP_SIGINFO
 /* Implement the "stopped_by_sw_breakpoint" target_ops method.  */
 
-int
+bool
 fbsd_nat_target::stopped_by_sw_breakpoint ()
 {
   struct ptrace_lwpinfo pl;
 
   if (ptrace (PT_LWPINFO, get_ptrace_pid (inferior_ptid), (caddr_t) &pl,
 	      sizeof pl) == -1)
-    return 0;
+    return false;
 
   return ((pl.pl_flags & PL_FLAG_SI)
 	  && pl.pl_siginfo.si_signo == SIGTRAP
@@ -1475,10 +1475,10 @@ fbsd_nat_target::stopped_by_sw_breakpoint ()
 /* Implement the "supports_stopped_by_sw_breakpoint" target_ops
    method.  */
 
-int
+bool
 fbsd_nat_target::supports_stopped_by_sw_breakpoint ()
 {
-  return 1;
+  return true;
 }
 #endif
 
diff --git a/gdb/fbsd-nat.h b/gdb/fbsd-nat.h
index a4418bb8f8..031d7d6d27 100644
--- a/gdb/fbsd-nat.h
+++ b/gdb/fbsd-nat.h
@@ -41,7 +41,7 @@ public:
 #endif
 
 #ifdef PT_LWPINFO
-  int thread_alive (ptid_t ptid) override;
+  bool thread_alive (ptid_t ptid) override;
   const char *pid_to_str (ptid_t) override;
 
 #ifdef HAVE_STRUCT_PTRACE_LWPINFO_PL_TDNAME
@@ -61,8 +61,8 @@ public:
   void post_attach (int) override;
 
 #ifdef USE_SIGTRAP_SIGINFO
-  int supports_stopped_by_sw_breakpoint () override;
-  int stopped_by_sw_breakpoint () override;
+  bool supports_stopped_by_sw_breakpoint () override;
+  bool stopped_by_sw_breakpoint () override;
 #endif
 
 #ifdef TDP_RFPPWAIT
diff --git a/gdb/gnu-nat.c b/gdb/gnu-nat.c
index 89df55fdde..c7a40400fc 100644
--- a/gdb/gnu-nat.c
+++ b/gdb/gnu-nat.c
@@ -2288,7 +2288,7 @@ gnu_nat_target::stop (ptid_t ptid)
   error (_("stop target function not implemented"));
 }
 
-int
+bool
 gnu_nat_target::thread_alive (ptid_t ptid)
 {
   inf_update_procs (gnu_current_inf);
diff --git a/gdb/gnu-nat.h b/gdb/gnu-nat.h
index 4189eaf026..f8ec692064 100644
--- a/gdb/gnu-nat.h
+++ b/gdb/gnu-nat.h
@@ -130,7 +130,7 @@ struct gnu_nat_target : public inf_child_target
   void create_inferior (const char *, const std::string &,
 			char **, int) override;
   void mourn_inferior () override;
-  int thread_alive (ptid_t ptid) override;
+  bool thread_alive (ptid_t ptid) override;
   const char *pid_to_str (ptid_t) override;
   void stop (ptid_t) override;
 };
diff --git a/gdb/go32-nat.c b/gdb/go32-nat.c
index dcf60cb3d2..6f6aedea7e 100644
--- a/gdb/go32-nat.c
+++ b/gdb/go32-nat.c
@@ -375,7 +375,7 @@ class go32_nat_target : public x86_nat_target<inf_child_target>
 
   void mourn_inferior () override;
 
-  int thread_alive (ptid_t ptid) override;
+  bool thread_alive (ptid_t ptid) override;
 
   const char *pid_to_str (ptid_t) override;
 };
@@ -987,7 +987,7 @@ go32_nat_target::pass_ctrlc ()
 {
 }
 
-int
+bool
 go32_nat_target::thread_alive (ptid_t ptid)
 {
   return !ptid_equal (ptid, null_ptid);
diff --git a/gdb/ia64-linux-nat.c b/gdb/ia64-linux-nat.c
index 2aa66a5682..9435bcf1ab 100644
--- a/gdb/ia64-linux-nat.c
+++ b/gdb/ia64-linux-nat.c
@@ -70,11 +70,11 @@ public:
      has determined that a hardware watchpoint has indeed been hit.
      The CPU will then be able to execute one instruction without
      triggering a watchpoint.  */
-  int have_steppable_watchpoint () { return 1; }
+  bool have_steppable_watchpoint () { return 1; }
 
   int can_use_hw_breakpoint (enum bptype, int, int) override;
-  int stopped_by_watchpoint () override;
-  int stopped_data_address (CORE_ADDR *) override;
+  bool stopped_by_watchpoint () override;
+  bool stopped_data_address (CORE_ADDR *) override;
   int insert_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
 			 struct expression *) override;
   int remove_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
@@ -688,7 +688,7 @@ ia64_linux_new_thread (struct lwp_info *lp)
     enable_watchpoints_in_psr (lp->ptid);
 }
 
-int
+bool
 ia64_linux_nat_target::stopped_data_address (CORE_ADDR *addr_p)
 {
   CORE_ADDR psr;
@@ -696,11 +696,11 @@ ia64_linux_nat_target::stopped_data_address (CORE_ADDR *addr_p)
   struct regcache *regcache = get_current_regcache ();
 
   if (!linux_nat_get_siginfo (inferior_ptid, &siginfo))
-    return 0;
+    return false;
 
   if (siginfo.si_signo != SIGTRAP
       || (siginfo.si_code & 0xffff) != 0x0004 /* TRAP_HWBKPT */)
-    return 0;
+    return false;
 
   regcache_cooked_read_unsigned (regcache, IA64_PSR_REGNUM, &psr);
   psr |= IA64_PSR_DD;	/* Set the dd bit - this will disable the watchpoint
@@ -708,10 +708,10 @@ ia64_linux_nat_target::stopped_data_address (CORE_ADDR *addr_p)
   regcache_cooked_write_unsigned (regcache, IA64_PSR_REGNUM, psr);
 
   *addr_p = (CORE_ADDR) siginfo.si_addr;
-  return 1;
+  return true;
 }
 
-int
+bool
 ia64_linux_nat_target::stopped_by_watchpoint ()
 {
   CORE_ADDR addr;
diff --git a/gdb/inf-child.c b/gdb/inf-child.c
index 7b2f2a25a2..8e5ebfa2c2 100644
--- a/gdb/inf-child.c
+++ b/gdb/inf-child.c
@@ -200,10 +200,10 @@ inf_child_target::post_startup_inferior (ptid_t ptid)
      operation by a debugger.  */
 }
 
-int
+bool
 inf_child_target::can_run ()
 {
-  return 1;
+  return true;
 }
 
 bool
@@ -226,31 +226,31 @@ inf_child_target::pid_to_exec_file (int pid)
   return NULL;
 }
 
-int
+bool
 inf_child_target::has_all_memory ()
 {
   return default_child_has_all_memory ();
 }
 
-int
+bool
 inf_child_target::has_memory ()
 {
   return default_child_has_memory ();
 }
 
-int
+bool
 inf_child_target::has_stack ()
 {
   return default_child_has_stack ();
 }
 
-int
+bool
 inf_child_target::has_registers ()
 {
   return default_child_has_registers ();
 }
 
-int
+bool
 inf_child_target::has_execution (ptid_t ptid)
 {
   return default_child_has_execution (ptid);
@@ -404,19 +404,19 @@ inf_child_target::fileio_readlink (struct inferior *inf, const char *filename,
 #endif
 }
 
-int
-inf_child_target::use_agent (int use)
+bool
+inf_child_target::use_agent (bool use)
 {
   if (agent_loaded_p ())
     {
       ::use_agent = use;
-      return 1;
+      return true;
     }
   else
-    return 0;
+    return false;
 }
 
-int
+bool
 inf_child_target::can_use_agent ()
 {
   return agent_loaded_p ();
diff --git a/gdb/inf-child.h b/gdb/inf-child.h
index 1b9c8c53ae..755c462fb8 100644
--- a/gdb/inf-child.h
+++ b/gdb/inf-child.h
@@ -65,7 +65,7 @@ public:
 
   void mourn_inferior () override;
 
-  int can_run () override;
+  bool can_run () override;
 
   bool can_create_inferior () override;
   void create_inferior (const char *, const std::string &,
@@ -78,16 +78,16 @@ public:
 
   /* We must default these because they must be implemented by any
      target that can run.  */
-  int can_async_p ()  override { return 0; }
-  int supports_non_stop ()  override { return 0; }
+  bool can_async_p ()  override { return false; }
+  bool supports_non_stop ()  override { return false; }
 
   char *pid_to_exec_file (int pid) override;
 
-  int has_all_memory () override;
-  int has_memory () override;
-  int has_stack () override;
-  int has_registers () override;
-  int has_execution (ptid_t) override;
+  bool has_all_memory () override;
+  bool has_memory () override;
+  bool has_stack () override;
+  bool has_registers () override;
+  bool has_execution (ptid_t) override;
 
   int fileio_open (struct inferior *inf, const char *filename,
 		   int flags, int mode, int warn_if_slow,
@@ -104,9 +104,9 @@ public:
   gdb::optional<std::string> fileio_readlink (struct inferior *inf,
 					      const char *filename,
 					      int *target_errno) override;
-  int use_agent (int use) override;
+  bool use_agent (bool use) override;
 
-  int can_use_agent () override;
+  bool can_use_agent () override;
 
 protected:
   /* Unpush the target if it wasn't explicitly open with "target native"
diff --git a/gdb/inf-ptrace.c b/gdb/inf-ptrace.c
index 8f5a378353..78b57730d2 100644
--- a/gdb/inf-ptrace.c
+++ b/gdb/inf-ptrace.c
@@ -607,7 +607,7 @@ inf_ptrace_target::xfer_partial (enum target_object object,
 
 /* Return non-zero if the thread specified by PTID is alive.  */
 
-int
+bool
 inf_ptrace_target::thread_alive (ptid_t ptid)
 {
   /* ??? Is kill the right way to do this?  */
diff --git a/gdb/inf-ptrace.h b/gdb/inf-ptrace.h
index bd9b609ab4..de284f9536 100644
--- a/gdb/inf-ptrace.h
+++ b/gdb/inf-ptrace.h
@@ -57,7 +57,7 @@ struct inf_ptrace_target : public inf_child_target
 
   void mourn_inferior () override;
 
-  int thread_alive (ptid_t ptid) override;
+  bool thread_alive (ptid_t ptid) override;
 
   const char *pid_to_str (ptid_t) override;
 
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index bfc2e46ed6..701a7db05b 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -2474,7 +2474,7 @@ check_stopped_by_watchpoint (struct lwp_info *lp)
 
 /* Returns true if the LWP had stopped for a watchpoint.  */
 
-int
+bool
 linux_nat_target::stopped_by_watchpoint ()
 {
   struct lwp_info *lp = find_lwp_pid (inferior_ptid);
@@ -2484,7 +2484,7 @@ linux_nat_target::stopped_by_watchpoint ()
   return lp->stop_reason == TARGET_STOPPED_BY_WATCHPOINT;
 }
 
-int
+bool
 linux_nat_target::stopped_data_address (CORE_ADDR *addr_p)
 {
   struct lwp_info *lp = find_lwp_pid (inferior_ptid);
@@ -2835,7 +2835,7 @@ save_stop_reason (struct lwp_info *lp)
 
 /* Returns true if the LWP had stopped for a software breakpoint.  */
 
-int
+bool
 linux_nat_target::stopped_by_sw_breakpoint ()
 {
   struct lwp_info *lp = find_lwp_pid (inferior_ptid);
@@ -2847,7 +2847,7 @@ linux_nat_target::stopped_by_sw_breakpoint ()
 
 /* Implement the supports_stopped_by_sw_breakpoint method.  */
 
-int
+bool
 linux_nat_target::supports_stopped_by_sw_breakpoint ()
 {
   return USE_SIGTRAP_SIGINFO;
@@ -2856,7 +2856,7 @@ linux_nat_target::supports_stopped_by_sw_breakpoint ()
 /* Returns true if the LWP had stopped for a hardware
    breakpoint/watchpoint.  */
 
-int
+bool
 linux_nat_target::stopped_by_hw_breakpoint ()
 {
   struct lwp_info *lp = find_lwp_pid (inferior_ptid);
@@ -2868,7 +2868,7 @@ linux_nat_target::stopped_by_hw_breakpoint ()
 
 /* Implement the supports_stopped_by_hw_breakpoint method.  */
 
-int
+bool
 linux_nat_target::supports_stopped_by_hw_breakpoint ()
 {
   return USE_SIGTRAP_SIGINFO;
@@ -3940,7 +3940,7 @@ linux_nat_target::xfer_partial (enum target_object object,
 					  offset, len, xfered_len);
 }
 
-int
+bool
 linux_nat_target::thread_alive (ptid_t ptid)
 {
   /* As long as a PTID is in lwp list, consider it alive.  */
@@ -4322,7 +4322,7 @@ linux_nat_target::static_tracepoint_markers_by_strid (const char *strid)
 
 /* target_is_async_p implementation.  */
 
-int
+bool
 linux_nat_target::is_async_p ()
 {
   return linux_is_async_p ();
@@ -4330,7 +4330,7 @@ linux_nat_target::is_async_p ()
 
 /* target_can_async_p implementation.  */
 
-int
+bool
 linux_nat_target::can_async_p ()
 {
   /* We're always async, unless the user explicitly prevented it with the
@@ -4338,7 +4338,7 @@ linux_nat_target::can_async_p ()
   return target_async_permitted;
 }
 
-int
+bool
 linux_nat_target::supports_non_stop ()
 {
   return 1;
@@ -4346,7 +4346,7 @@ linux_nat_target::supports_non_stop ()
 
 /* to_always_non_stop_p implementation.  */
 
-int
+bool
 linux_nat_target::always_non_stop_p ()
 {
   return 1;
@@ -4357,13 +4357,13 @@ linux_nat_target::always_non_stop_p ()
 
 int linux_multi_process = 1;
 
-int
+bool
 linux_nat_target::supports_multi_process ()
 {
   return linux_multi_process;
 }
 
-int
+bool
 linux_nat_target::supports_disable_randomization ()
 {
 #ifdef HAVE_PERSONALITY
@@ -4574,13 +4574,13 @@ linux_nat_target::core_of_thread (ptid_t ptid)
 
 /* Implementation of to_filesystem_is_local.  */
 
-int
+bool
 linux_nat_target::filesystem_is_local ()
 {
   struct inferior *inf = current_inferior ();
 
   if (inf->fake_pid_p || inf->pid == 0)
-    return 1;
+    return true;
 
   return linux_ns_same (inf->pid, LINUX_NS_MNT);
 }
diff --git a/gdb/linux-nat.h b/gdb/linux-nat.h
index da5357a21e..fbee35e9b6 100644
--- a/gdb/linux-nat.h
+++ b/gdb/linux-nat.h
@@ -57,7 +57,7 @@ public:
   void kill () override;
 
   void mourn_inferior () override;
-  int thread_alive (ptid_t ptid) override;
+  bool thread_alive (ptid_t ptid) override;
 
   void update_thread_list () override;
 
@@ -67,23 +67,23 @@ public:
 
   struct address_space *thread_address_space (ptid_t) override;
 
-  int stopped_by_watchpoint () override;
+  bool stopped_by_watchpoint () override;
 
-  int stopped_data_address (CORE_ADDR *) override;
+  bool stopped_data_address (CORE_ADDR *) override;
 
-  int stopped_by_sw_breakpoint () override;
-  int supports_stopped_by_sw_breakpoint () override;
+  bool stopped_by_sw_breakpoint () override;
+  bool supports_stopped_by_sw_breakpoint () override;
 
-  int stopped_by_hw_breakpoint () override;
-  int supports_stopped_by_hw_breakpoint () override;
+  bool stopped_by_hw_breakpoint () override;
+  bool supports_stopped_by_hw_breakpoint () override;
 
   void thread_events (int) override;
 
-  int can_async_p () override;
-  int is_async_p () override;
+  bool can_async_p () override;
+  bool is_async_p () override;
 
-  int supports_non_stop () override;
-  int always_non_stop_p () override;
+  bool supports_non_stop () override;
+  bool always_non_stop_p () override;
 
   void async (int) override;
 
@@ -91,13 +91,13 @@ public:
 
   void stop (ptid_t) override;
 
-  int supports_multi_process () override;
+  bool supports_multi_process () override;
 
-  int supports_disable_randomization () override;
+  bool supports_disable_randomization () override;
 
   int core_of_thread (ptid_t ptid) override;
 
-  int filesystem_is_local () override;
+  bool filesystem_is_local () override;
 
   int fileio_open (struct inferior *inf, const char *filename,
 		   int flags, int mode, int warn_if_slow,
@@ -140,11 +140,11 @@ public:
   virtual void low_resume (ptid_t ptid, int step, enum gdb_signal sig)
   { inf_ptrace_target::resume (ptid, step, sig); }
 
-  virtual int low_stopped_by_watchpoint ()
-  { return 0; }
+  virtual bool low_stopped_by_watchpoint ()
+  { return false; }
 
-  virtual int low_stopped_data_address (CORE_ADDR *addr_p)
-  { return 0; }
+  virtual bool low_stopped_data_address (CORE_ADDR *addr_p)
+  { return false; }
 };
 
 /* The final/concrete instance.  */
diff --git a/gdb/mips-linux-nat.c b/gdb/mips-linux-nat.c
index 1cd97d53c7..0659c2e90d 100644
--- a/gdb/mips-linux-nat.c
+++ b/gdb/mips-linux-nat.c
@@ -59,9 +59,9 @@ public:
   int insert_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
 			 struct expression *) override;
 
-  int stopped_by_watchpoint () override;
+  bool stopped_by_watchpoint () override;
 
-  int stopped_data_address (CORE_ADDR *) override;
+  bool stopped_data_address (CORE_ADDR *) override;
 
   int region_ok_for_hw_watchpoint (CORE_ADDR, int) override;
 
@@ -572,7 +572,7 @@ mips_linux_nat_target::can_use_hw_breakpoint (enum bptype type,
    stopped by watchpoint.  The watchhi R and W bits indicate the watch
    register triggered.  */
 
-int
+bool
 mips_linux_nat_target::stopped_by_watchpoint ()
 {
   int n;
@@ -581,27 +581,27 @@ mips_linux_nat_target::stopped_by_watchpoint ()
   if (!mips_linux_read_watch_registers (ptid_get_lwp (inferior_ptid),
 					&watch_readback,
 					&watch_readback_valid, 1))
-    return 0;
+    return false;
 
   num_valid = mips_linux_watch_get_num_valid (&watch_readback);
 
   for (n = 0; n < MAX_DEBUG_REGISTER && n < num_valid; n++)
     if (mips_linux_watch_get_watchhi (&watch_readback, n) & (R_MASK | W_MASK))
-      return 1;
+      return true;
 
-  return 0;
+  return false;
 }
 
 /* Target to_stopped_data_address implementation.  Set the address
    where the watch triggered (if known).  Return 1 if the address was
    known.  */
 
-int
+bool
 mips_linux_nat_target::stopped_data_address (CORE_ADDR *paddr)
 {
   /* On mips we don't know the low order 3 bits of the data address,
      so we must return false.  */
-  return 0;
+  return false;
 }
 
 /* Target to_region_ok_for_hw_watchpoint implementation.  Return 1 if
diff --git a/gdb/nto-procfs.c b/gdb/nto-procfs.c
index 1ca4bac336..f3ba877840 100644
--- a/gdb/nto-procfs.c
+++ b/gdb/nto-procfs.c
@@ -100,7 +100,7 @@ struct nto_procfs_target : public inf_child_target
   int remove_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
 			 struct expression *) override;
 
-  int stopped_by_watchpoint () override;
+  bool stopped_by_watchpoint () override;
 
   void kill () override;
 
@@ -111,7 +111,7 @@ struct nto_procfs_target : public inf_child_target
 
   void pass_signals (int, unsigned char *) override;
 
-  int thread_alive (ptid_t ptid) override;
+  bool thread_alive (ptid_t ptid) override;
 
   void update_thread_list () override;
 
@@ -297,8 +297,9 @@ procfs_set_thread (ptid_t ptid)
   devctl (ctl_fd, DCMD_PROC_CURTHREAD, &tid, sizeof (tid), 0);
 }
 
-/*  Return nonzero if the thread TH is still alive.  */
-int
+/*  Return true if the thread TH is still alive.  */
+
+bool
 nto_procfs_target::thread_alive (ptid_t ptid)
 {
   pid_t tid;
@@ -310,12 +311,12 @@ nto_procfs_target::thread_alive (ptid_t ptid)
   pid = ptid_get_pid (ptid);
 
   if (kill (pid, 0) == -1)
-    return 0;
+    return false;
 
   status.tid = tid;
   if ((err = devctl (ctl_fd, DCMD_PROC_TIDSTATUS,
 		     &status, sizeof (status), 0)) != EOK)
-    return 0;
+    return false;
 
   /* Thread is alive or dead but not yet joined,
      or dead and there is an alive (or dead unjoined) thread with
@@ -1583,7 +1584,7 @@ procfs_hw_watchpoint (int addr, int len, enum target_hw_bp_type type)
   return 0;
 }
 
-int
+bool
 nto_procfs_target::can_use_hw_breakpoint (enum bptype type,
 					  int cnt, int othertype)
 {
@@ -1606,7 +1607,7 @@ nto_procfs_target::insert_hw_watchpoint (CORE_ADDR addr, int len,
   return procfs_hw_watchpoint (addr, len, type);
 }
 
-int
+bool
 nto_procfs_target::stopped_by_watchpoint ()
 {
   /* NOTE: nto_stopped_by_watchpoint will be called ONLY while we are
diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c
index c9f0f9d48d..7362bee4ef 100644
--- a/gdb/ppc-linux-nat.c
+++ b/gdb/ppc-linux-nat.c
@@ -296,13 +296,13 @@ struct ppc_linux_nat_target final : public linux_nat_target
   int remove_mask_watchpoint (CORE_ADDR, CORE_ADDR, enum target_hw_bp_type)
     override;
 
-  int stopped_by_watchpoint () override;
+  bool stopped_by_watchpoint () override;
 
-  int stopped_data_address (CORE_ADDR *) override;
+  bool stopped_data_address (CORE_ADDR *) override;
 
-  int watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, int) override;
+  bool watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, int) override;
 
-  int can_accel_watchpoint_condition (CORE_ADDR, int, int, struct expression *)
+  bool can_accel_watchpoint_condition (CORE_ADDR, int, int, struct expression *)
     override;
 
   int masked_watch_num_registers (CORE_ADDR, CORE_ADDR) override;
@@ -1986,7 +1986,7 @@ check_condition (CORE_ADDR watch_addr, struct expression *cond,
 /* Return non-zero if the target is capable of using hardware to evaluate
    the condition expression, thus only triggering the watchpoint when it is
    true.  */
-int
+bool
 ppc_linux_nat_target::can_accel_watchpoint_condition (CORE_ADDR addr, int len,
 						      int rw,
 						      struct expression *cond)
@@ -2222,17 +2222,17 @@ ppc_linux_thread_exit (struct thread_info *tp, int silent)
   xfree (t);
 }
 
-int
+bool
 ppc_linux_nat_target::stopped_data_address (CORE_ADDR *addr_p)
 {
   siginfo_t siginfo;
 
   if (!linux_nat_get_siginfo (inferior_ptid, &siginfo))
-    return 0;
+    return false;
 
   if (siginfo.si_signo != SIGTRAP
       || (siginfo.si_code & 0xffff) != 0x0004 /* TRAP_HWBKPT */)
-    return 0;
+    return false;
 
   if (have_ptrace_hwdebug_interface ())
     {
@@ -2253,22 +2253,22 @@ ppc_linux_nat_target::stopped_data_address (CORE_ADDR *addr_p)
 	   if (hw_breaks[i].hw_break && hw_breaks[i].slot == slot
 	       && hw_breaks[i].hw_break->trigger_type
 		    == PPC_BREAKPOINT_TRIGGER_EXECUTE)
-	     return 0;
+	     return false;
 	}
     }
 
   *addr_p = (CORE_ADDR) (uintptr_t) siginfo.si_addr;
-  return 1;
+  return true;
 }
 
-int
+bool
 ppc_linux_nat_target::stopped_by_watchpoint ()
 {
   CORE_ADDR addr;
   return stopped_data_address (&addr);
 }
 
-int
+bool
 ppc_linux_nat_target::watchpoint_addr_within_range (CORE_ADDR addr,
 						    CORE_ADDR start,
 						    int length)
diff --git a/gdb/procfs.c b/gdb/procfs.c
index abae358c44..749b2b4833 100644
--- a/gdb/procfs.c
+++ b/gdb/procfs.c
@@ -124,7 +124,7 @@ public:
 
   void update_thread_list () override;
 
-  int thread_alive (ptid_t ptid) override;
+  bool thread_alive (ptid_t ptid) override;
 
   const char *pid_to_str (ptid_t) override;
 
@@ -145,7 +145,7 @@ public:
     override;
 #endif
 
-  int stopped_by_watchpoint () override;
+  bool stopped_by_watchpoint () override;
 
   int insert_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
 			 struct expression *) override;
@@ -156,7 +156,7 @@ public:
   int region_ok_for_hw_watchpoint (CORE_ADDR, int) override;
 
   int can_use_hw_breakpoint (enum bptype, int, int) override;
-  int stopped_data_address (CORE_ADDR *) override;
+  bool stopped_data_address (CORE_ADDR *) override;
 };
 
 static procfs_target the_procfs_target;
@@ -3179,7 +3179,7 @@ procfs_target::update_thread_list ()
    really seem to be doing his job.  Got to investigate how to tell
    when a thread is really gone.  */
 
-int
+bool
 procfs_target::thread_alive (ptid_t ptid)
 {
   int proc, thread;
@@ -3189,18 +3189,18 @@ procfs_target::thread_alive (ptid_t ptid)
   thread  = ptid_get_lwp (ptid);
   /* If I don't know it, it ain't alive!  */
   if ((pi = find_procinfo (proc, thread)) == NULL)
-    return 0;
+    return false;
 
   /* If I can't get its status, it ain't alive!
      What's more, I need to forget about it!  */
   if (!proc_get_status (pi))
     {
       destroy_procinfo (pi);
-      return 0;
+      return false;
     }
   /* I couldn't have got its status if it weren't alive, so it's
      alive.  */
-  return 1;
+  return true;
 }
 
 /* Convert PTID to a string.  Returns the string in a static
@@ -3301,7 +3301,7 @@ procfs_target::can_use_hw_breakpoint (enum bptype type, int cnt, int othertype)
 /* Returns non-zero if process is stopped on a hardware watchpoint
    fault, else returns zero.  */
 
-int
+bool
 procfs_target::stopped_by_watchpoint ()
 {
   procinfo *pi;
@@ -3313,10 +3313,10 @@ procfs_target::stopped_by_watchpoint ()
       if (proc_why (pi) == PR_FAULTED)
 	{
 	  if (proc_what (pi) == FLTWATCH)
-	    return 1;
+	    return true;
 	}
     }
-  return 0;
+  return false;
 }
 
 /* Returns 1 if the OS knows the position of the triggered watchpoint,
@@ -3325,7 +3325,7 @@ procfs_target::stopped_by_watchpoint ()
    procfs_stopped_by_watchpoint returned 1, thus no further checks are
    done.  The function also assumes that ADDR is not NULL.  */
 
-int
+bool
 procfs_target::stopped_data_address (CORE_ADDR *addr)
 {
   procinfo *pi;
diff --git a/gdb/ravenscar-thread.c b/gdb/ravenscar-thread.c
index e850ef7507..03cbe3d9e7 100644
--- a/gdb/ravenscar-thread.c
+++ b/gdb/ravenscar-thread.c
@@ -95,15 +95,15 @@ struct ravenscar_thread_target final : public target_ops
 
   void prepare_to_store (struct regcache *) override;
 
-  int stopped_by_sw_breakpoint () override;
+  bool stopped_by_sw_breakpoint () override;
 
-  int stopped_by_hw_breakpoint () override;
+  bool stopped_by_hw_breakpoint () override;
 
-  int stopped_by_watchpoint () override;
+  bool stopped_by_watchpoint () override;
 
-  int stopped_data_address (CORE_ADDR *) override;
+  bool stopped_data_address (CORE_ADDR *) override;
 
-  int thread_alive (ptid_t ptid) override;
+  bool thread_alive (ptid_t ptid) override;
 
   int core_of_thread (ptid_t ptid) override;
 
@@ -117,11 +117,11 @@ struct ravenscar_thread_target final : public target_ops
 
   void mourn_inferior () override;
 
-  int has_all_memory ()  override { return default_child_has_all_memory (); }
-  int has_memory ()  override { return default_child_has_memory (); }
-  int has_stack ()  override { return default_child_has_stack (); }
-  int has_registers ()  override { return default_child_has_registers (); }
-  int has_execution (ptid_t ptid) override
+  bool has_all_memory ()  override { return default_child_has_all_memory (); }
+  bool has_memory ()  override { return default_child_has_memory (); }
+  bool has_stack ()  override { return default_child_has_stack (); }
+  bool has_registers ()  override { return default_child_has_registers (); }
+  bool has_execution (ptid_t ptid) override
   { return default_child_has_execution (ptid); }
 };
 
@@ -396,11 +396,11 @@ ravenscar_thread_target::extra_thread_info (thread_info *tp)
   return "Ravenscar task";
 }
 
-int
+bool
 ravenscar_thread_target::thread_alive (ptid_t ptid)
 {
   /* Ravenscar tasks are non-terminating.  */
-  return 1;
+  return true;
 }
 
 const char *
@@ -475,12 +475,12 @@ ravenscar_thread_target::prepare_to_store (struct regcache *regcache)
 
 /* Implement the to_stopped_by_sw_breakpoint target_ops "method".  */
 
-int
+bool
 ravenscar_thread_target::stopped_by_sw_breakpoint ()
 {
   ptid_t saved_ptid = inferior_ptid;
   struct target_ops *beneath = find_target_beneath (this);
-  int result;
+  bool result;
 
   inferior_ptid = get_base_thread_from_ravenscar_task (saved_ptid);
   result = beneath->stopped_by_sw_breakpoint ();
@@ -490,12 +490,12 @@ ravenscar_thread_target::stopped_by_sw_breakpoint ()
 
 /* Implement the to_stopped_by_hw_breakpoint target_ops "method".  */
 
-int
+bool
 ravenscar_thread_target::stopped_by_hw_breakpoint ()
 {
   ptid_t saved_ptid = inferior_ptid;
   struct target_ops *beneath = find_target_beneath (this);
-  int result;
+  bool result;
 
   inferior_ptid = get_base_thread_from_ravenscar_task (saved_ptid);
   result = beneath->stopped_by_hw_breakpoint ();
@@ -505,12 +505,12 @@ ravenscar_thread_target::stopped_by_hw_breakpoint ()
 
 /* Implement the to_stopped_by_watchpoint target_ops "method".  */
 
-int
+bool
 ravenscar_thread_target::stopped_by_watchpoint ()
 {
   ptid_t saved_ptid = inferior_ptid;
   struct target_ops *beneath = find_target_beneath (this);
-  int result;
+  bool result;
 
   inferior_ptid = get_base_thread_from_ravenscar_task (saved_ptid);
   result = beneath->stopped_by_watchpoint ();
@@ -520,12 +520,12 @@ ravenscar_thread_target::stopped_by_watchpoint ()
 
 /* Implement the to_stopped_data_address target_ops "method".  */
 
-int
+bool
 ravenscar_thread_target::stopped_data_address (CORE_ADDR *addr_p)
 {
   ptid_t saved_ptid = inferior_ptid;
   struct target_ops *beneath = find_target_beneath (this);
-  int result;
+  bool result;
 
   inferior_ptid = get_base_thread_from_ravenscar_task (saved_ptid);
   result = beneath->stopped_data_address (addr_p);
diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
index cce188e71a..3c1cfb6601 100644
--- a/gdb/record-btrace.c
+++ b/gdb/record-btrace.c
@@ -89,8 +89,8 @@ public:
   void call_history_range (ULONGEST begin, ULONGEST end, record_print_flags flags)
     override;
 
-  int record_is_replaying (ptid_t ptid) override;
-  int record_will_replay (ptid_t ptid, int dir) override;
+  bool record_is_replaying (ptid_t ptid) override;
+  bool record_will_replay (ptid_t ptid, int dir) override;
   void record_stop_replaying () override;
 
   enum target_xfer_status xfer_partial (enum target_object object,
@@ -120,18 +120,18 @@ public:
 
   void stop (ptid_t) override;
   void update_thread_list () override;
-  int thread_alive (ptid_t ptid) override;
+  bool thread_alive (ptid_t ptid) override;
   void goto_record_begin () override;
   void goto_record_end () override;
   void goto_record (ULONGEST insn) override;
 
-  int can_execute_reverse () override;
+  bool can_execute_reverse () override;
 
-  int stopped_by_sw_breakpoint () override;
-  int supports_stopped_by_sw_breakpoint () override;
+  bool stopped_by_sw_breakpoint () override;
+  bool supports_stopped_by_sw_breakpoint () override;
 
-  int stopped_by_hw_breakpoint () override;
-  int supports_stopped_by_hw_breakpoint () override;
+  bool stopped_by_hw_breakpoint () override;
+  bool supports_stopped_by_hw_breakpoint () override;
 
   enum exec_direction_kind execution_direction () override;
   void prepare_to_generate_core () override;
@@ -1359,21 +1359,21 @@ record_btrace_target::record_method (ptid_t ptid)
 
 /* The record_is_replaying method of target record-btrace.  */
 
-int
+bool
 record_btrace_target::record_is_replaying (ptid_t ptid)
 {
   struct thread_info *tp;
 
   ALL_NON_EXITED_THREADS (tp)
     if (ptid_match (tp->ptid, ptid) && btrace_is_replaying (tp))
-      return 1;
+      return true;
 
-  return 0;
+  return false;
 }
 
 /* The record_will_replay method of target record-btrace.  */
 
-int
+bool
 record_btrace_target::record_will_replay (ptid_t ptid, int dir)
 {
   return dir == EXEC_REVERSE || record_is_replaying (ptid);
@@ -2671,15 +2671,15 @@ record_btrace_target::stop (ptid_t ptid)
 
 /* The can_execute_reverse method of target record-btrace.  */
 
-int
+bool
 record_btrace_target::can_execute_reverse ()
 {
-  return 1;
+  return true;
 }
 
 /* The stopped_by_sw_breakpoint method of target record-btrace.  */
 
-int
+bool
 record_btrace_target::stopped_by_sw_breakpoint ()
 {
   if (record_is_replaying (minus_one_ptid))
@@ -2695,18 +2695,18 @@ record_btrace_target::stopped_by_sw_breakpoint ()
 /* The supports_stopped_by_sw_breakpoint method of target
    record-btrace.  */
 
-int
+bool
 record_btrace_target::supports_stopped_by_sw_breakpoint ()
 {
   if (record_is_replaying (minus_one_ptid))
-    return 1;
+    return true;
 
   return this->beneath->supports_stopped_by_sw_breakpoint ();
 }
 
 /* The stopped_by_sw_breakpoint method of target record-btrace.  */
 
-int
+bool
 record_btrace_target::stopped_by_hw_breakpoint ()
 {
   if (record_is_replaying (minus_one_ptid))
@@ -2722,11 +2722,11 @@ record_btrace_target::stopped_by_hw_breakpoint ()
 /* The supports_stopped_by_hw_breakpoint method of target
    record-btrace.  */
 
-int
+bool
 record_btrace_target::supports_stopped_by_hw_breakpoint ()
 {
   if (record_is_replaying (minus_one_ptid))
-    return 1;
+    return true;
 
   return this->beneath->supports_stopped_by_hw_breakpoint ();
 }
@@ -2746,7 +2746,7 @@ record_btrace_target::update_thread_list ()
 
 /* The thread_alive method of target record-btrace.  */
 
-int
+bool
 record_btrace_target::thread_alive (ptid_t ptid)
 {
   /* We don't add or remove threads during replay.  */
diff --git a/gdb/record-full.c b/gdb/record-full.c
index de96574baf..58f4be4fea 100644
--- a/gdb/record-full.c
+++ b/gdb/record-full.c
@@ -227,16 +227,16 @@ public:
   void close () override;
   void async (int) override;
   ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
-  int stopped_by_watchpoint () override;
-  int stopped_data_address (CORE_ADDR *) override;
+  bool stopped_by_watchpoint () override;
+  bool stopped_data_address (CORE_ADDR *) override;
 
-  int stopped_by_sw_breakpoint () override;
-  int supports_stopped_by_sw_breakpoint () override;
+  bool stopped_by_sw_breakpoint () override;
+  bool supports_stopped_by_sw_breakpoint () override;
 
-  int stopped_by_hw_breakpoint () override;
-  int supports_stopped_by_hw_breakpoint () override;
+  bool stopped_by_hw_breakpoint () override;
+  bool supports_stopped_by_hw_breakpoint () override;
 
-  int can_execute_reverse () override;
+  bool can_execute_reverse () override;
 
   /* Add bookmark target methods.  */
   gdb_byte *get_bookmark (const char *, int) override;
@@ -247,8 +247,8 @@ public:
   void save_record (const char *filename) override;
   bool supports_delete_record () override;
   void delete_record () override;
-  int record_is_replaying (ptid_t ptid) override;
-  int record_will_replay (ptid_t ptid, int dir) override;
+  bool record_is_replaying (ptid_t ptid) override;
+  bool record_will_replay (ptid_t ptid, int dir) override;
   void record_stop_replaying () override;
   void goto_record_begin () override;
   void goto_record_end () override;
@@ -309,7 +309,7 @@ public:
 			 struct bp_target_info *,
 			 enum remove_bp_reason) override;
 
-  int has_execution (ptid_t) override;
+  bool has_execution (ptid_t) override;
 };
 
 static record_full_target record_full_ops;
@@ -1463,7 +1463,7 @@ record_full_base_target::wait (ptid_t ptid, struct target_waitstatus *status,
   return return_ptid;
 }
 
-int
+bool
 record_full_base_target::stopped_by_watchpoint ()
 {
   if (RECORD_FULL_IS_REPLAY)
@@ -1472,18 +1472,18 @@ record_full_base_target::stopped_by_watchpoint ()
     return beneath->stopped_by_watchpoint ();
 }
 
-int
+bool
 record_full_base_target::stopped_data_address (CORE_ADDR *addr_p)
 {
   if (RECORD_FULL_IS_REPLAY)
-    return 0;
+    return false;
   else
     return this->beneath->stopped_data_address (addr_p);
 }
 
 /* The stopped_by_sw_breakpoint method of target record-full.  */
 
-int
+bool
 record_full_base_target::stopped_by_sw_breakpoint ()
 {
   return record_full_stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT;
@@ -1492,15 +1492,15 @@ record_full_base_target::stopped_by_sw_breakpoint ()
 /* The supports_stopped_by_sw_breakpoint method of target
    record-full.  */
 
-int
+bool
 record_full_base_target::supports_stopped_by_sw_breakpoint ()
 {
-  return 1;
+  return true;
 }
 
 /* The stopped_by_hw_breakpoint method of target record-full.  */
 
-int
+bool
 record_full_base_target::stopped_by_hw_breakpoint ()
 {
   return record_full_stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT;
@@ -1509,10 +1509,10 @@ record_full_base_target::stopped_by_hw_breakpoint ()
 /* The supports_stopped_by_sw_breakpoint method of target
    record-full.  */
 
-int
+bool
 record_full_base_target::supports_stopped_by_hw_breakpoint ()
 {
-  return 1;
+  return true;
 }
 
 /* Record registers change (by user or by GDB) to list as an instruction.  */
@@ -1834,10 +1834,10 @@ record_full_target::remove_breakpoint (struct gdbarch *gdbarch,
 
 /* "can_execute_reverse" method for process record target.  */
 
-int
+bool
 record_full_base_target::can_execute_reverse ()
 {
-  return 1;
+  return true;
 }
 
 /* "get_bookmark" method for process record and prec over core.  */
@@ -1962,7 +1962,7 @@ record_full_base_target::delete_record ()
 
 /* The "record_is_replaying" target method.  */
 
-int
+bool
 record_full_base_target::record_is_replaying (ptid_t ptid)
 {
   return RECORD_FULL_IS_REPLAY;
@@ -1970,7 +1970,7 @@ record_full_base_target::record_is_replaying (ptid_t ptid)
 
 /* The "record_will_replay" target method.  */
 
-int
+bool
 record_full_base_target::record_will_replay (ptid_t ptid, int dir)
 {
   /* We can currently only record when executing forwards.  Should we be able
@@ -2240,10 +2240,10 @@ record_full_core_target::remove_breakpoint (struct gdbarch *gdbarch,
 
 /* "has_execution" method for prec over corefile.  */
 
-int
+bool
 record_full_core_target::has_execution (ptid_t the_ptid)
 {
-  return 1;
+  return true;
 }
 
 /* Record log save-file format
diff --git a/gdb/remote-sim.c b/gdb/remote-sim.c
index 3d484bcd85..91dbd7c7bb 100644
--- a/gdb/remote-sim.c
+++ b/gdb/remote-sim.c
@@ -123,20 +123,20 @@ struct gdbsim_target
 
   void interrupt () override;
 
-  int thread_alive (ptid_t ptid) override;
+  bool thread_alive (ptid_t ptid) override;
 
   const char *pid_to_str (ptid_t) override;
 
-  int has_all_memory ()  override;
-  int has_memory ()  override;
+  bool has_all_memory ()  override;
+  bool has_memory ()  override;
 
-  int has_stack ()  override
+  bool has_stack ()  override
   { return default_child_has_stack (); }
 
-  int has_registers ()  override
+  bool has_registers ()  override
   { return default_child_has_registers (); }
 
-  int has_execution (ptid_t ptid) override
+  bool has_execution (ptid_t ptid) override
   { return default_child_has_execution (ptid); }
 };
 
@@ -1288,20 +1288,20 @@ sim_command_completer (struct cmd_list_element *ignore,
 
 /* Check to see if a thread is still alive.  */
 
-int
+bool
 gdbsim_target::thread_alive (ptid_t ptid)
 {
   struct sim_inferior_data *sim_data
     = get_sim_inferior_data_by_ptid (ptid, SIM_INSTANCE_NOT_NEEDED);
 
   if (sim_data == NULL)
-    return 0;
+    return false;
 
   if (ptid_equal (ptid, sim_data->remote_sim_ptid))
     /* The simulators' task is always alive.  */
-    return 1;
+    return true;
 
-  return 0;
+  return false;
 }
 
 /* Convert a thread ID to a string.  Returns the string in a static
@@ -1315,28 +1315,28 @@ gdbsim_target::pid_to_str (ptid_t ptid)
 
 /* Simulator memory may be accessed after the program has been loaded.  */
 
-int
+bool
 gdbsim_target::has_all_memory ()
 {
   struct sim_inferior_data *sim_data
     = get_sim_inferior_data (current_inferior (), SIM_INSTANCE_NOT_NEEDED);
 
   if (!sim_data->program_loaded)
-    return 0;
+    return false;
 
-  return 1;
+  return true;
 }
 
-int
+bool
 gdbsim_target::has_memory ()
 {
   struct sim_inferior_data *sim_data
     = get_sim_inferior_data (current_inferior (), SIM_INSTANCE_NOT_NEEDED);
 
   if (!sim_data->program_loaded)
-    return 0;
+    return false;
 
-  return 1;
+  return true;
 }
 
 void
diff --git a/gdb/remote.c b/gdb/remote.c
index 0b22b11c09..4790bc7f5e 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -125,18 +125,18 @@ Specify the serial device it is connected to\n\
 			 enum remove_bp_reason) override;
 
 
-  int stopped_by_sw_breakpoint () override;
-  int supports_stopped_by_sw_breakpoint () override;
+  bool stopped_by_sw_breakpoint () override;
+  bool supports_stopped_by_sw_breakpoint () override;
 
-  int stopped_by_hw_breakpoint () override;
+  bool stopped_by_hw_breakpoint () override;
 
-  int supports_stopped_by_hw_breakpoint () override;
+  bool supports_stopped_by_hw_breakpoint () override;
 
-  int stopped_by_watchpoint () override;
+  bool stopped_by_watchpoint () override;
 
-  int stopped_data_address (CORE_ADDR *) override;
+  bool stopped_data_address (CORE_ADDR *) override;
 
-  int watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, int) override;
+  bool watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, int) override;
 
   int can_use_hw_breakpoint (enum bptype, int, int) override;
 
@@ -165,7 +165,7 @@ Specify the serial device it is connected to\n\
 
   void program_signals (int, unsigned char *) override;
 
-  int thread_alive (ptid_t ptid) override;
+  bool thread_alive (ptid_t ptid) override;
 
   const char *thread_name (struct thread_info *) override;
 
@@ -209,13 +209,13 @@ Specify the serial device it is connected to\n\
 				      CORE_ADDR load_module_addr,
 				      CORE_ADDR offset) override;
 
-  int has_all_memory ()  override { return default_child_has_all_memory (); }
-  int has_memory ()  override { return default_child_has_memory (); }
-  int has_stack ()  override { return default_child_has_stack (); }
-  int has_registers ()  override { return default_child_has_registers (); }
-  int has_execution (ptid_t ptid)  override { return default_child_has_execution (ptid); }
+  bool has_all_memory ()  override { return default_child_has_all_memory (); }
+  bool has_memory ()  override { return default_child_has_memory (); }
+  bool has_stack ()  override { return default_child_has_stack (); }
+  bool has_registers ()  override { return default_child_has_registers (); }
+  bool has_execution (ptid_t ptid)  override { return default_child_has_execution (ptid); }
 
-  int can_execute_reverse () override;
+  bool can_execute_reverse () override;
 
   std::vector<mem_region> memory_map () override;
 
@@ -229,9 +229,9 @@ Specify the serial device it is connected to\n\
 		     const gdb_byte *pattern, ULONGEST pattern_len,
 		     CORE_ADDR *found_addrp) override;
 
-  int can_async_p () override;
+  bool can_async_p () override;
 
-  int is_async_p () override;
+  bool is_async_p () override;
 
   void async (int) override;
 
@@ -243,13 +243,13 @@ Specify the serial device it is connected to\n\
 
   void terminal_ours () override;
 
-  int supports_non_stop () override;
+  bool supports_non_stop () override;
 
-  int supports_multi_process () override;
+  bool supports_multi_process () override;
 
-  int supports_disable_randomization () override;
+  bool supports_disable_randomization () override;
 
-  int filesystem_is_local () override;
+  bool filesystem_is_local () override;
 
 
   int fileio_open (struct inferior *inf, const char *filename,
@@ -275,19 +275,19 @@ Specify the serial device it is connected to\n\
 		     const char *filename,
 		     int *target_errno) override;
 
-  int supports_enable_disable_tracepoint () override;
+  bool supports_enable_disable_tracepoint () override;
 
-  int supports_string_tracing () override;
+  bool supports_string_tracing () override;
 
-  int supports_evaluation_of_breakpoint_conditions () override;
+  bool supports_evaluation_of_breakpoint_conditions () override;
 
-  int can_run_breakpoint_commands () override;
+  bool can_run_breakpoint_commands () override;
 
   void trace_init () override;
 
   void download_tracepoint (struct bp_location *location) override;
 
-  int can_download_tracepoint () override;
+  bool can_download_tracepoint () override;
 
   void download_trace_state_variable (const trace_state_variable &tsv) override;
 
@@ -309,7 +309,7 @@ Specify the serial device it is connected to\n\
   int trace_find (enum trace_find_type type, int num,
 		  CORE_ADDR addr1, CORE_ADDR addr2, int *tpp) override;
 
-  int get_trace_state_variable_value (int tsv, LONGEST *val) override;
+  bool get_trace_state_variable_value (int tsv, LONGEST *val) override;
 
   int save_trace_data (const char *filename) override;
 
@@ -327,8 +327,8 @@ Specify the serial device it is connected to\n\
 
   void set_trace_buffer_size (LONGEST val) override;
 
-  int set_trace_notes (const char *user, const char *notes,
-		       const char *stopnotes) override;
+  bool set_trace_notes (const char *user, const char *notes,
+			const char *stopnotes) override;
 
   int core_of_thread (ptid_t ptid) override;
 
@@ -336,7 +336,7 @@ Specify the serial device it is connected to\n\
 		     CORE_ADDR memaddr, ULONGEST size) override;
 
 
-  int get_tib_address (ptid_t ptid, CORE_ADDR *addr) override;
+  bool get_tib_address (ptid_t ptid, CORE_ADDR *addr) override;
 
   void set_permissions () override;
 
@@ -349,8 +349,8 @@ Specify the serial device it is connected to\n\
 
   traceframe_info_up traceframe_info () override;
 
-  int use_agent (int use) override;
-  int can_use_agent () override;
+  bool use_agent (bool use) override;
+  bool can_use_agent () override;
 
   struct btrace_target_info *enable_btrace (ptid_t ptid,
 					    const struct btrace_config *conf) override;
@@ -364,7 +364,7 @@ Specify the serial device it is connected to\n\
 				 enum btrace_read_type type) override;
 
   const struct btrace_config *btrace_conf (const struct btrace_target_info *) override;
-  int augmented_libraries_svr4_read () override;
+  bool augmented_libraries_svr4_read () override;
   int follow_fork (int, int) override;
   void follow_exec (struct inferior *, char *) override;
   int insert_fork_catchpoint (int) override;
@@ -404,7 +404,7 @@ public:
   void attach (const char *, int) override;
 
   void post_attach (int) override;
-  int supports_disable_randomization () override;
+  bool supports_disable_randomization () override;
 };
 
 /* Per-program-space data key.  */
@@ -2520,7 +2520,7 @@ remote_thread_always_alive (ptid_t ptid)
 /* Return nonzero if the thread PTID is still alive on the remote
    system.  */
 
-int
+bool
 remote_target::thread_alive (ptid_t ptid)
 {
   struct remote_state *rs = get_remote_state ();
@@ -9702,7 +9702,7 @@ remote_target::mourn_inferior ()
     }
 }
 
-int
+bool
 extended_remote_target::supports_disable_randomization ()
 {
   return packet_support (PACKET_QDisableRandomization) == PACKET_ENABLE;
@@ -10160,7 +10160,7 @@ remote_target::insert_watchpoint (CORE_ADDR addr, int len,
 		  _("remote_insert_watchpoint: reached end of function"));
 }
 
-int
+bool
 remote_target::watchpoint_addr_within_range (CORE_ADDR addr,
 					     CORE_ADDR start, int length)
 {
@@ -10253,7 +10253,7 @@ remote_target::can_use_hw_breakpoint (enum bptype type, int cnt, int ot)
 
 /* The to_stopped_by_sw_breakpoint method of target remote.  */
 
-int
+bool
 remote_target::stopped_by_sw_breakpoint ()
 {
   struct thread_info *thread = inferior_thread ();
@@ -10266,7 +10266,7 @@ remote_target::stopped_by_sw_breakpoint ()
 /* The to_supports_stopped_by_sw_breakpoint method of target
    remote.  */
 
-int
+bool
 remote_target::supports_stopped_by_sw_breakpoint ()
 {
   return (packet_support (PACKET_swbreak_feature) == PACKET_ENABLE);
@@ -10274,7 +10274,7 @@ remote_target::supports_stopped_by_sw_breakpoint ()
 
 /* The to_stopped_by_hw_breakpoint method of target remote.  */
 
-int
+bool
 remote_target::stopped_by_hw_breakpoint ()
 {
   struct thread_info *thread = inferior_thread ();
@@ -10287,13 +10287,13 @@ remote_target::stopped_by_hw_breakpoint ()
 /* The to_supports_stopped_by_hw_breakpoint method of target
    remote.  */
 
-int
+bool
 remote_target::supports_stopped_by_hw_breakpoint ()
 {
   return (packet_support (PACKET_hwbreak_feature) == PACKET_ENABLE);
 }
 
-int
+bool
 remote_target::stopped_by_watchpoint ()
 {
   struct thread_info *thread = inferior_thread ();
@@ -10303,7 +10303,7 @@ remote_target::stopped_by_watchpoint ()
 	      == TARGET_STOPPED_BY_WATCHPOINT));
 }
 
-int
+bool
 remote_target::stopped_data_address (CORE_ADDR *addr_p)
 {
   struct thread_info *thread = inferior_thread ();
@@ -10313,10 +10313,10 @@ remote_target::stopped_data_address (CORE_ADDR *addr_p)
 	  == TARGET_STOPPED_BY_WATCHPOINT))
     {
       *addr_p = get_remote_thread_info (thread)->watch_data_address;
-      return 1;
+      return true;
     }
 
-  return 0;
+  return false;
 }
 
 
@@ -11332,7 +11332,7 @@ remote_target::get_thread_local_address (ptid_t ptid, CORE_ADDR lm,
 /* Provide thread local base, i.e. Thread Information Block address.
    Returns 1 if ptid is found and thread_local_base is non zero.  */
 
-int
+bool
 remote_target::get_tib_address (ptid_t ptid, CORE_ADDR *addr)
 {
   if (packet_support (PACKET_qGetTIBAddr) != PACKET_DISABLE)
@@ -11358,7 +11358,7 @@ remote_target::get_tib_address (ptid_t ptid, CORE_ADDR *addr)
 	  unpack_varlen_hex (rs->buf, &result);
 	  if (addr)
 	    *addr = (CORE_ADDR) result;
-	  return 1;
+	  return true;
 	}
       else if (result == PACKET_UNKNOWN)
 	error (_("Remote target doesn't support qGetTIBAddr packet"));
@@ -11368,7 +11368,7 @@ remote_target::get_tib_address (ptid_t ptid, CORE_ADDR *addr)
   else
     error (_("qGetTIBAddr not supported or disabled on this target"));
   /* Not reached.  */
-  return 0;
+  return false;
 }
 
 /* Support for inferring a target description based on the current
@@ -12087,7 +12087,7 @@ remote_target::fileio_fstat (int fd, struct stat *st, int *remote_errno)
 
 /* Implementation of to_filesystem_is_local.  */
 
-int
+bool
 remote_target::filesystem_is_local ()
 {
   /* Valgrind GDB presents itself as a remote target but works
@@ -12129,11 +12129,11 @@ remote_target::filesystem_is_local ()
 	      warning_issued = 1;
 	    }
 
-	  return 1;
+	  return true;
 	}
     }
 
-  return 0;
+  return false;
 }
 
 static int
@@ -12418,30 +12418,30 @@ remote_command (const char *args, int from_tty)
   help_list (remote_cmdlist, "remote ", all_commands, gdb_stdout);
 }
 
-int
+bool
 remote_target::can_execute_reverse ()
 {
   if (packet_support (PACKET_bs) == PACKET_ENABLE
       || packet_support (PACKET_bc) == PACKET_ENABLE)
-    return 1;
+    return true;
   else
-    return 0;
+    return false;
 }
 
-int
+bool
 remote_target::supports_non_stop ()
 {
-  return 1;
+  return true;
 }
 
-int
+bool
 remote_target::supports_disable_randomization ()
 {
   /* Only supported in extended mode.  */
-  return 0;
+  return false;
 }
 
-int
+bool
 remote_target::supports_multi_process ()
 {
   struct remote_state *rs = get_remote_state ();
@@ -12455,7 +12455,7 @@ remote_supports_cond_tracepoints ()
   return packet_support (PACKET_ConditionalTracepoints) == PACKET_ENABLE;
 }
 
-int
+bool
 remote_target::supports_evaluation_of_breakpoint_conditions ()
 {
   return packet_support (PACKET_ConditionalBreakpoints) == PACKET_ENABLE;
@@ -12479,20 +12479,20 @@ remote_supports_install_in_trace ()
   return packet_support (PACKET_InstallInTrace) == PACKET_ENABLE;
 }
 
-int
+bool
 remote_target::supports_enable_disable_tracepoint ()
 {
   return (packet_support (PACKET_EnableDisableTracepoints_feature)
 	  == PACKET_ENABLE);
 }
 
-int
+bool
 remote_target::supports_string_tracing ()
 {
   return packet_support (PACKET_tracenz_feature) == PACKET_ENABLE;
 }
 
-int
+bool
 remote_target::can_run_breakpoint_commands ()
 {
   return packet_support (PACKET_BreakpointCommands) == PACKET_ENABLE;
@@ -12713,7 +12713,7 @@ remote_target::download_tracepoint (struct bp_location *loc)
     }
 }
 
-int
+bool
 remote_target::can_download_tracepoint ()
 {
   struct remote_state *rs = get_remote_state ();
@@ -12724,20 +12724,20 @@ remote_target::can_download_tracepoint ()
      symbols, and fetched and merged the target's tracepoint list with
      ours.  */
   if (rs->starting_up)
-    return 0;
+    return false;
 
   ts = current_trace_status ();
   status = get_trace_status (ts);
 
   if (status == -1 || !ts->running_known || !ts->running)
-    return 0;
+    return false;
 
   /* If we are in a tracing experiment, but remote stub doesn't support
      installing tracepoint in trace, we have to return.  */
   if (!remote_supports_install_in_trace ())
-    return 0;
+    return false;
 
-  return 1;
+  return true;
 }
 
 
@@ -13055,7 +13055,7 @@ remote_target::trace_find (enum trace_find_type type, int num,
   return target_frameno;
 }
 
-int
+bool
 remote_target::get_trace_state_variable_value (int tsvnum, LONGEST *val)
 {
   struct remote_state *rs = get_remote_state ();
@@ -13073,10 +13073,10 @@ remote_target::get_trace_state_variable_value (int tsvnum, LONGEST *val)
 	{
 	  unpack_varlen_hex (reply + 1, &uval);
 	  *val = (LONGEST) uval;
-	  return 1;
+	  return true;
 	}
     }
-  return 0;
+  return false;
 }
 
 int
@@ -13268,7 +13268,7 @@ remote_target::set_trace_buffer_size (LONGEST val)
     }
 }
 
-int
+bool
 remote_target::set_trace_notes (const char *user, const char *notes,
 				const char *stop_notes)
 {
@@ -13306,16 +13306,16 @@ remote_target::set_trace_notes (const char *user, const char *notes,
   putpkt (rs->buf);
   reply = remote_get_noisy_reply ();
   if (*reply == '\0')
-    return 0;
+    return false;
 
   if (strcmp (reply, "OK") != 0)
     error (_("Bogus reply from target: %s"), reply);
 
-  return 1;
+  return true;
 }
 
-int
-remote_target::use_agent (int use)
+bool
+remote_target::use_agent (bool use)
 {
   if (packet_support (PACKET_QAgent) != PACKET_DISABLE)
     {
@@ -13329,14 +13329,14 @@ remote_target::use_agent (int use)
       if (strcmp (rs->buf, "OK") == 0)
 	{
 	  ::use_agent = use;
-	  return 1;
+	  return true;
 	}
     }
 
-  return 0;
+  return false;
 }
 
-int
+bool
 remote_target::can_use_agent ()
 {
   return (packet_support (PACKET_QAgent) != PACKET_DISABLE);
@@ -13637,7 +13637,7 @@ remote_target::btrace_conf (const struct btrace_target_info *tinfo)
   return &tinfo->conf;
 }
 
-int
+bool
 remote_target::augmented_libraries_svr4_read ()
 {
   return (packet_support (PACKET_augmented_libraries_svr4_read_feature)
@@ -13747,7 +13747,7 @@ remote_target::thread_handle_to_thread_info (const gdb_byte *thread_handle,
   return NULL;
 }
 
-int
+bool
 remote_target::can_async_p ()
 {
   struct remote_state *rs = get_remote_state ();
@@ -13755,20 +13755,20 @@ remote_target::can_async_p ()
   /* We don't go async if the user has explicitly prevented it with the
      "maint set target-async" command.  */
   if (!target_async_permitted)
-    return 0;
+    return false;
 
   /* We're async whenever the serial device is.  */
   return serial_can_async_p (rs->remote_desc);
 }
 
-int
+bool
 remote_target::is_async_p ()
 {
   struct remote_state *rs = get_remote_state ();
 
   if (!target_async_permitted)
     /* We only enable async when the user specifically asks for it.  */
-    return 0;
+    return false;
 
   /* We're async whenever the serial device is.  */
   return serial_is_async_p (rs->remote_desc);
diff --git a/gdb/s390-linux-nat.c b/gdb/s390-linux-nat.c
index d3d98014ac..2d82f53c04 100644
--- a/gdb/s390-linux-nat.c
+++ b/gdb/s390-linux-nat.c
@@ -122,9 +122,9 @@ public:
   int remove_hw_breakpoint (struct gdbarch *, struct bp_target_info *)
     override;
   int region_ok_for_hw_watchpoint (CORE_ADDR, int) override;
-  int have_continuable_watchpoint () { return 1; }
-  int stopped_by_watchpoint () override;
-  int watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, int) override;
+  bool have_continuable_watchpoint () { return 1; }
+  bool stopped_by_watchpoint () override;
+  bool watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, int) override;
   int insert_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
 			 struct expression *) override;
   int remove_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
@@ -657,21 +657,20 @@ s390_show_debug_regs (int tid, const char *where)
 		per_info.lowcore.words.access_id);
 }
 
-int
+bool
 s390_linux_nat_target::stopped_by_watchpoint ()
 {
   struct s390_debug_reg_state *state
     = s390_get_debug_reg_state (ptid_get_pid (inferior_ptid));
   per_lowcore_bits per_lowcore;
   ptrace_area parea;
-  int result;
 
   if (show_debug_regs)
     s390_show_debug_regs (s390_inferior_tid (), "stop");
 
   /* Speed up common case.  */
   if (VEC_empty (s390_watch_area, state->watch_areas))
-    return 0;
+    return false;
 
   parea.len = sizeof (per_lowcore);
   parea.process_addr = (addr_t) & per_lowcore;
@@ -679,8 +678,8 @@ s390_linux_nat_target::stopped_by_watchpoint ()
   if (ptrace (PTRACE_PEEKUSR_AREA, s390_inferior_tid (), &parea, 0) < 0)
     perror_with_name (_("Couldn't retrieve watchpoint status"));
 
-  result = (per_lowcore.perc_storage_alteration == 1
-	    && per_lowcore.perc_store_real_address == 0);
+  bool result = (per_lowcore.perc_storage_alteration == 1
+		 && per_lowcore.perc_store_real_address == 0);
 
   if (result)
     {
diff --git a/gdb/sol-thread.c b/gdb/sol-thread.c
index 0572da30c0..8f2ac3a6a3 100644
--- a/gdb/sol-thread.c
+++ b/gdb/sol-thread.c
@@ -99,7 +99,7 @@ public:
 					ULONGEST offset, ULONGEST len,
 					ULONGEST *xfered_len) override;
 
-  int thread_alive (ptid_t ptid) override;
+  bool thread_alive (ptid_t ptid) override;
   void update_thread_list () override;
 };
 
@@ -700,7 +700,7 @@ sol_thread_target::mourn_inferior ()
 
 /* Return true if PTID is still active in the inferior.  */
 
-int
+bool
 sol_thread_target::thread_alive (ptid_t ptid)
 {
   if (ptid_tid_p (ptid))
@@ -712,10 +712,10 @@ sol_thread_target::thread_alive (ptid_t ptid)
 
       pid = ptid_get_tid (ptid);
       if ((val = p_td_ta_map_id2thr (main_ta, pid, &th)) != TD_OK)
-	return 0;		/* Thread not found.  */
+	return false;		/* Thread not found.  */
       if ((val = p_td_thr_validate (&th)) != TD_OK)
-	return 0;		/* Thread not valid.  */
-      return 1;			/* Known thread.  */
+	return false;		/* Thread not valid.  */
+      return true;		/* Known thread.  */
     }
   else
     {
diff --git a/gdb/spu-multiarch.c b/gdb/spu-multiarch.c
index 4e3397fdfe..1886807d37 100644
--- a/gdb/spu-multiarch.c
+++ b/gdb/spu-multiarch.c
@@ -52,7 +52,7 @@ struct spu_multiarch_target final : public target_ops
 
   void mourn_inferior () override;
 
-    void fetch_registers (struct regcache *, int) override;
+  void fetch_registers (struct regcache *, int) override;
   void store_registers (struct regcache *, int) override;
 
   enum target_xfer_status xfer_partial (enum target_object object,
@@ -162,6 +162,7 @@ spu_multiarch_target::thread_architecture (ptid_t ptid)
 }
 
 /* Override the to_region_ok_for_hw_watchpoint routine.  */
+
 int
 spu_multiarch_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
 {
diff --git a/gdb/target-delegates.c b/gdb/target-delegates.c
index 3aea00ea9d..c06b700d6f 100644
--- a/gdb/target-delegates.c
+++ b/gdb/target-delegates.c
@@ -24,10 +24,10 @@ struct dummy_target : public target_ops
   void files_info () override;
   int insert_breakpoint (struct gdbarch *arg0, struct bp_target_info *arg1) override;
   int remove_breakpoint (struct gdbarch *arg0, struct bp_target_info *arg1, enum remove_bp_reason arg2) override;
-  int stopped_by_sw_breakpoint () override;
-  int supports_stopped_by_sw_breakpoint () override;
-  int stopped_by_hw_breakpoint () override;
-  int supports_stopped_by_hw_breakpoint () override;
+  bool stopped_by_sw_breakpoint () override;
+  bool supports_stopped_by_sw_breakpoint () override;
+  bool stopped_by_hw_breakpoint () override;
+  bool supports_stopped_by_hw_breakpoint () override;
   int can_use_hw_breakpoint (enum bptype arg0, int arg1, int arg2) override;
   int ranged_break_num_registers () override;
   int insert_hw_breakpoint (struct gdbarch *arg0, struct bp_target_info *arg1) override;
@@ -36,13 +36,13 @@ struct dummy_target : public target_ops
   int insert_watchpoint (CORE_ADDR arg0, int arg1, enum target_hw_bp_type arg2, struct expression *arg3) override;
   int insert_mask_watchpoint (CORE_ADDR arg0, CORE_ADDR arg1, enum target_hw_bp_type arg2) override;
   int remove_mask_watchpoint (CORE_ADDR arg0, CORE_ADDR arg1, enum target_hw_bp_type arg2) override;
-  int stopped_by_watchpoint () override;
+  bool stopped_by_watchpoint () override;
   int have_steppable_watchpoint () override;
   bool have_continuable_watchpoint () override;
-  int stopped_data_address (CORE_ADDR *arg0) override;
-  int watchpoint_addr_within_range (CORE_ADDR arg0, CORE_ADDR arg1, int arg2) override;
+  bool stopped_data_address (CORE_ADDR *arg0) override;
+  bool watchpoint_addr_within_range (CORE_ADDR arg0, CORE_ADDR arg1, int arg2) override;
   int region_ok_for_hw_watchpoint (CORE_ADDR arg0, int arg1) override;
-  int can_accel_watchpoint_condition (CORE_ADDR arg0, int arg1, int arg2, struct expression *arg3) override;
+  bool can_accel_watchpoint_condition (CORE_ADDR arg0, int arg1, int arg2, struct expression *arg3) override;
   int masked_watch_num_registers (CORE_ADDR arg0, CORE_ADDR arg1) override;
   int can_do_single_step () override;
   bool supports_terminal_ours () override;
@@ -67,7 +67,7 @@ struct dummy_target : public target_ops
   void mourn_inferior () override;
   void pass_signals (int arg0, unsigned char * arg1) override;
   void program_signals (int arg0, unsigned char * arg1) override;
-  int thread_alive (ptid_t arg0) override;
+  bool thread_alive (ptid_t arg0) override;
   void update_thread_list () override;
   const char *pid_to_str (ptid_t arg0) override;
   const char *extra_thread_info (thread_info *arg0) override;
@@ -82,12 +82,12 @@ struct dummy_target : public target_ops
   struct target_section_table *get_section_table () override;
   thread_control_capabilities get_thread_control_capabilities () override;
   bool attach_no_wait () override;
-  int can_async_p () override;
-  int is_async_p () override;
+  bool can_async_p () override;
+  bool is_async_p () override;
   void async (int arg0) override;
   void thread_events (int arg0) override;
-  int supports_non_stop () override;
-  int always_non_stop_p () override;
+  bool supports_non_stop () override;
+  bool always_non_stop_p () override;
   int find_memory_regions (find_memory_region_ftype arg0, void *arg1) override;
   char *make_corefile_notes (bfd *arg0, int *arg1) override;
   gdb_byte *get_bookmark (const char *arg0, int arg1) override;
@@ -102,20 +102,20 @@ struct dummy_target : public target_ops
   ptid_t get_ada_task_ptid (long arg0, long arg1) override;
   int auxv_parse (gdb_byte **arg0, gdb_byte *arg1, CORE_ADDR *arg2, CORE_ADDR *arg3) override;
   int search_memory (CORE_ADDR arg0, ULONGEST arg1, const gdb_byte *arg2, ULONGEST arg3, CORE_ADDR *arg4) override;
-  int can_execute_reverse () override;
+  bool can_execute_reverse () override;
   enum exec_direction_kind execution_direction () override;
-  int supports_multi_process () override;
-  int supports_enable_disable_tracepoint () override;
-  int supports_disable_randomization () override;
-  int supports_string_tracing () override;
-  int supports_evaluation_of_breakpoint_conditions () override;
-  int can_run_breakpoint_commands () override;
+  bool supports_multi_process () override;
+  bool supports_enable_disable_tracepoint () override;
+  bool supports_disable_randomization () override;
+  bool supports_string_tracing () override;
+  bool supports_evaluation_of_breakpoint_conditions () override;
+  bool can_run_breakpoint_commands () override;
   struct gdbarch *thread_architecture (ptid_t arg0) override;
   struct address_space *thread_address_space (ptid_t arg0) override;
-  int filesystem_is_local () override;
+  bool filesystem_is_local () override;
   void trace_init () override;
   void download_tracepoint (struct bp_location *arg0) override;
-  int can_download_tracepoint () override;
+  bool can_download_tracepoint () override;
   void download_trace_state_variable (const trace_state_variable &arg0) override;
   void enable_tracepoint (struct bp_location *arg0) override;
   void disable_tracepoint (struct bp_location *arg0) override;
@@ -125,7 +125,7 @@ struct dummy_target : public target_ops
   void get_tracepoint_status (struct breakpoint *arg0, struct uploaded_tp *arg1) override;
   void trace_stop () override;
   int trace_find (enum trace_find_type arg0, int arg1, CORE_ADDR arg2, CORE_ADDR arg3, int *arg4) override;
-  int get_trace_state_variable_value (int arg0, LONGEST *arg1) override;
+  bool get_trace_state_variable_value (int arg0, LONGEST *arg1) override;
   int save_trace_data (const char *arg0) override;
   int upload_tracepoints (struct uploaded_tp **arg0) override;
   int upload_trace_state_variables (struct uploaded_tsv **arg0) override;
@@ -134,16 +134,16 @@ struct dummy_target : public target_ops
   void set_disconnected_tracing (int arg0) override;
   void set_circular_trace_buffer (int arg0) override;
   void set_trace_buffer_size (LONGEST arg0) override;
-  int set_trace_notes (const char *arg0, const char *arg1, const char *arg2) override;
+  bool set_trace_notes (const char *arg0, const char *arg1, const char *arg2) override;
   int core_of_thread (ptid_t arg0) override;
   int verify_memory (const gdb_byte *arg0, CORE_ADDR arg1, ULONGEST arg2) override;
-  int get_tib_address (ptid_t arg0, CORE_ADDR *arg1) override;
+  bool get_tib_address (ptid_t arg0, CORE_ADDR *arg1) override;
   void set_permissions () override;
   bool static_tracepoint_marker_at (CORE_ADDR arg0, static_tracepoint_marker *arg1) override;
   std::vector<static_tracepoint_marker> static_tracepoint_markers_by_strid (const char *arg0) override;
   traceframe_info_up traceframe_info () override;
-  int use_agent (int arg0) override;
-  int can_use_agent () override;
+  bool use_agent (bool arg0) override;
+  bool can_use_agent () override;
   struct btrace_target_info *enable_btrace (ptid_t arg0, const struct btrace_config *arg1) override;
   void disable_btrace (struct btrace_target_info *arg0) override;
   void teardown_btrace (struct btrace_target_info *arg0) override;
@@ -155,8 +155,8 @@ struct dummy_target : public target_ops
   void save_record (const char *arg0) override;
   bool supports_delete_record () override;
   void delete_record () override;
-  int record_is_replaying (ptid_t arg0) override;
-  int record_will_replay (ptid_t arg0, int arg1) override;
+  bool record_is_replaying (ptid_t arg0) override;
+  bool record_will_replay (ptid_t arg0, int arg1) override;
   void record_stop_replaying () override;
   void goto_record_begin () override;
   void goto_record_end () override;
@@ -167,7 +167,7 @@ struct dummy_target : public target_ops
   void call_history (int arg0, record_print_flags arg1) override;
   void call_history_from (ULONGEST arg0, int arg1, record_print_flags arg2) override;
   void call_history_range (ULONGEST arg0, ULONGEST arg1, record_print_flags arg2) override;
-  int augmented_libraries_svr4_read () override;
+  bool augmented_libraries_svr4_read () override;
   const struct frame_unwind *get_unwinder () override;
   const struct frame_unwind *get_tailcall_unwinder () override;
   void prepare_to_generate_core () override;
@@ -194,10 +194,10 @@ struct debug_target : public target_ops
   void files_info () override;
   int insert_breakpoint (struct gdbarch *arg0, struct bp_target_info *arg1) override;
   int remove_breakpoint (struct gdbarch *arg0, struct bp_target_info *arg1, enum remove_bp_reason arg2) override;
-  int stopped_by_sw_breakpoint () override;
-  int supports_stopped_by_sw_breakpoint () override;
-  int stopped_by_hw_breakpoint () override;
-  int supports_stopped_by_hw_breakpoint () override;
+  bool stopped_by_sw_breakpoint () override;
+  bool supports_stopped_by_sw_breakpoint () override;
+  bool stopped_by_hw_breakpoint () override;
+  bool supports_stopped_by_hw_breakpoint () override;
   int can_use_hw_breakpoint (enum bptype arg0, int arg1, int arg2) override;
   int ranged_break_num_registers () override;
   int insert_hw_breakpoint (struct gdbarch *arg0, struct bp_target_info *arg1) override;
@@ -206,13 +206,13 @@ struct debug_target : public target_ops
   int insert_watchpoint (CORE_ADDR arg0, int arg1, enum target_hw_bp_type arg2, struct expression *arg3) override;
   int insert_mask_watchpoint (CORE_ADDR arg0, CORE_ADDR arg1, enum target_hw_bp_type arg2) override;
   int remove_mask_watchpoint (CORE_ADDR arg0, CORE_ADDR arg1, enum target_hw_bp_type arg2) override;
-  int stopped_by_watchpoint () override;
+  bool stopped_by_watchpoint () override;
   int have_steppable_watchpoint () override;
   bool have_continuable_watchpoint () override;
-  int stopped_data_address (CORE_ADDR *arg0) override;
-  int watchpoint_addr_within_range (CORE_ADDR arg0, CORE_ADDR arg1, int arg2) override;
+  bool stopped_data_address (CORE_ADDR *arg0) override;
+  bool watchpoint_addr_within_range (CORE_ADDR arg0, CORE_ADDR arg1, int arg2) override;
   int region_ok_for_hw_watchpoint (CORE_ADDR arg0, int arg1) override;
-  int can_accel_watchpoint_condition (CORE_ADDR arg0, int arg1, int arg2, struct expression *arg3) override;
+  bool can_accel_watchpoint_condition (CORE_ADDR arg0, int arg1, int arg2, struct expression *arg3) override;
   int masked_watch_num_registers (CORE_ADDR arg0, CORE_ADDR arg1) override;
   int can_do_single_step () override;
   bool supports_terminal_ours () override;
@@ -237,7 +237,7 @@ struct debug_target : public target_ops
   void mourn_inferior () override;
   void pass_signals (int arg0, unsigned char * arg1) override;
   void program_signals (int arg0, unsigned char * arg1) override;
-  int thread_alive (ptid_t arg0) override;
+  bool thread_alive (ptid_t arg0) override;
   void update_thread_list () override;
   const char *pid_to_str (ptid_t arg0) override;
   const char *extra_thread_info (thread_info *arg0) override;
@@ -252,12 +252,12 @@ struct debug_target : public target_ops
   struct target_section_table *get_section_table () override;
   thread_control_capabilities get_thread_control_capabilities () override;
   bool attach_no_wait () override;
-  int can_async_p () override;
-  int is_async_p () override;
+  bool can_async_p () override;
+  bool is_async_p () override;
   void async (int arg0) override;
   void thread_events (int arg0) override;
-  int supports_non_stop () override;
-  int always_non_stop_p () override;
+  bool supports_non_stop () override;
+  bool always_non_stop_p () override;
   int find_memory_regions (find_memory_region_ftype arg0, void *arg1) override;
   char *make_corefile_notes (bfd *arg0, int *arg1) override;
   gdb_byte *get_bookmark (const char *arg0, int arg1) override;
@@ -272,20 +272,20 @@ struct debug_target : public target_ops
   ptid_t get_ada_task_ptid (long arg0, long arg1) override;
   int auxv_parse (gdb_byte **arg0, gdb_byte *arg1, CORE_ADDR *arg2, CORE_ADDR *arg3) override;
   int search_memory (CORE_ADDR arg0, ULONGEST arg1, const gdb_byte *arg2, ULONGEST arg3, CORE_ADDR *arg4) override;
-  int can_execute_reverse () override;
+  bool can_execute_reverse () override;
   enum exec_direction_kind execution_direction () override;
-  int supports_multi_process () override;
-  int supports_enable_disable_tracepoint () override;
-  int supports_disable_randomization () override;
-  int supports_string_tracing () override;
-  int supports_evaluation_of_breakpoint_conditions () override;
-  int can_run_breakpoint_commands () override;
+  bool supports_multi_process () override;
+  bool supports_enable_disable_tracepoint () override;
+  bool supports_disable_randomization () override;
+  bool supports_string_tracing () override;
+  bool supports_evaluation_of_breakpoint_conditions () override;
+  bool can_run_breakpoint_commands () override;
   struct gdbarch *thread_architecture (ptid_t arg0) override;
   struct address_space *thread_address_space (ptid_t arg0) override;
-  int filesystem_is_local () override;
+  bool filesystem_is_local () override;
   void trace_init () override;
   void download_tracepoint (struct bp_location *arg0) override;
-  int can_download_tracepoint () override;
+  bool can_download_tracepoint () override;
   void download_trace_state_variable (const trace_state_variable &arg0) override;
   void enable_tracepoint (struct bp_location *arg0) override;
   void disable_tracepoint (struct bp_location *arg0) override;
@@ -295,7 +295,7 @@ struct debug_target : public target_ops
   void get_tracepoint_status (struct breakpoint *arg0, struct uploaded_tp *arg1) override;
   void trace_stop () override;
   int trace_find (enum trace_find_type arg0, int arg1, CORE_ADDR arg2, CORE_ADDR arg3, int *arg4) override;
-  int get_trace_state_variable_value (int arg0, LONGEST *arg1) override;
+  bool get_trace_state_variable_value (int arg0, LONGEST *arg1) override;
   int save_trace_data (const char *arg0) override;
   int upload_tracepoints (struct uploaded_tp **arg0) override;
   int upload_trace_state_variables (struct uploaded_tsv **arg0) override;
@@ -304,16 +304,16 @@ struct debug_target : public target_ops
   void set_disconnected_tracing (int arg0) override;
   void set_circular_trace_buffer (int arg0) override;
   void set_trace_buffer_size (LONGEST arg0) override;
-  int set_trace_notes (const char *arg0, const char *arg1, const char *arg2) override;
+  bool set_trace_notes (const char *arg0, const char *arg1, const char *arg2) override;
   int core_of_thread (ptid_t arg0) override;
   int verify_memory (const gdb_byte *arg0, CORE_ADDR arg1, ULONGEST arg2) override;
-  int get_tib_address (ptid_t arg0, CORE_ADDR *arg1) override;
+  bool get_tib_address (ptid_t arg0, CORE_ADDR *arg1) override;
   void set_permissions () override;
   bool static_tracepoint_marker_at (CORE_ADDR arg0, static_tracepoint_marker *arg1) override;
   std::vector<static_tracepoint_marker> static_tracepoint_markers_by_strid (const char *arg0) override;
   traceframe_info_up traceframe_info () override;
-  int use_agent (int arg0) override;
-  int can_use_agent () override;
+  bool use_agent (bool arg0) override;
+  bool can_use_agent () override;
   struct btrace_target_info *enable_btrace (ptid_t arg0, const struct btrace_config *arg1) override;
   void disable_btrace (struct btrace_target_info *arg0) override;
   void teardown_btrace (struct btrace_target_info *arg0) override;
@@ -325,8 +325,8 @@ struct debug_target : public target_ops
   void save_record (const char *arg0) override;
   bool supports_delete_record () override;
   void delete_record () override;
-  int record_is_replaying (ptid_t arg0) override;
-  int record_will_replay (ptid_t arg0, int arg1) override;
+  bool record_is_replaying (ptid_t arg0) override;
+  bool record_will_replay (ptid_t arg0, int arg1) override;
   void record_stop_replaying () override;
   void goto_record_begin () override;
   void goto_record_end () override;
@@ -337,7 +337,7 @@ struct debug_target : public target_ops
   void call_history (int arg0, record_print_flags arg1) override;
   void call_history_from (ULONGEST arg0, int arg1, record_print_flags arg2) override;
   void call_history_range (ULONGEST arg0, ULONGEST arg1, record_print_flags arg2) override;
-  int augmented_libraries_svr4_read () override;
+  bool augmented_libraries_svr4_read () override;
   const struct frame_unwind *get_unwinder () override;
   const struct frame_unwind *get_tailcall_unwinder () override;
   void prepare_to_generate_core () override;
@@ -635,102 +635,102 @@ debug_target::remove_breakpoint (struct gdbarch *arg0, struct bp_target_info *ar
   return result;
 }
 
-int
+bool
 target_ops::stopped_by_sw_breakpoint ()
 {
   return this->beneath->stopped_by_sw_breakpoint ();
 }
 
-int
+bool
 dummy_target::stopped_by_sw_breakpoint ()
 {
-  return 0;
+  return false;
 }
 
-int
+bool
 debug_target::stopped_by_sw_breakpoint ()
 {
-  int result;
+  bool result;
   fprintf_unfiltered (gdb_stdlog, "-> %s->stopped_by_sw_breakpoint (...)\n", this->beneath->shortname ());
   result = this->beneath->stopped_by_sw_breakpoint ();
   fprintf_unfiltered (gdb_stdlog, "<- %s->stopped_by_sw_breakpoint (", this->beneath->shortname ());
   fputs_unfiltered (") = ", gdb_stdlog);
-  target_debug_print_int (result);
+  target_debug_print_bool (result);
   fputs_unfiltered ("\n", gdb_stdlog);
   return result;
 }
 
-int
+bool
 target_ops::supports_stopped_by_sw_breakpoint ()
 {
   return this->beneath->supports_stopped_by_sw_breakpoint ();
 }
 
-int
+bool
 dummy_target::supports_stopped_by_sw_breakpoint ()
 {
-  return 0;
+  return false;
 }
 
-int
+bool
 debug_target::supports_stopped_by_sw_breakpoint ()
 {
-  int result;
+  bool result;
   fprintf_unfiltered (gdb_stdlog, "-> %s->supports_stopped_by_sw_breakpoint (...)\n", this->beneath->shortname ());
   result = this->beneath->supports_stopped_by_sw_breakpoint ();
   fprintf_unfiltered (gdb_stdlog, "<- %s->supports_stopped_by_sw_breakpoint (", this->beneath->shortname ());
   fputs_unfiltered (") = ", gdb_stdlog);
-  target_debug_print_int (result);
+  target_debug_print_bool (result);
   fputs_unfiltered ("\n", gdb_stdlog);
   return result;
 }
 
-int
+bool
 target_ops::stopped_by_hw_breakpoint ()
 {
   return this->beneath->stopped_by_hw_breakpoint ();
 }
 
-int
+bool
 dummy_target::stopped_by_hw_breakpoint ()
 {
-  return 0;
+  return false;
 }
 
-int
+bool
 debug_target::stopped_by_hw_breakpoint ()
 {
-  int result;
+  bool result;
   fprintf_unfiltered (gdb_stdlog, "-> %s->stopped_by_hw_breakpoint (...)\n", this->beneath->shortname ());
   result = this->beneath->stopped_by_hw_breakpoint ();
   fprintf_unfiltered (gdb_stdlog, "<- %s->stopped_by_hw_breakpoint (", this->beneath->shortname ());
   fputs_unfiltered (") = ", gdb_stdlog);
-  target_debug_print_int (result);
+  target_debug_print_bool (result);
   fputs_unfiltered ("\n", gdb_stdlog);
   return result;
 }
 
-int
+bool
 target_ops::supports_stopped_by_hw_breakpoint ()
 {
   return this->beneath->supports_stopped_by_hw_breakpoint ();
 }
 
-int
+bool
 dummy_target::supports_stopped_by_hw_breakpoint ()
 {
-  return 0;
+  return false;
 }
 
-int
+bool
 debug_target::supports_stopped_by_hw_breakpoint ()
 {
-  int result;
+  bool result;
   fprintf_unfiltered (gdb_stdlog, "-> %s->supports_stopped_by_hw_breakpoint (...)\n", this->beneath->shortname ());
   result = this->beneath->supports_stopped_by_hw_breakpoint ();
   fprintf_unfiltered (gdb_stdlog, "<- %s->supports_stopped_by_hw_breakpoint (", this->beneath->shortname ());
   fputs_unfiltered (") = ", gdb_stdlog);
-  target_debug_print_int (result);
+  target_debug_print_bool (result);
   fputs_unfiltered ("\n", gdb_stdlog);
   return result;
 }
@@ -970,27 +970,27 @@ debug_target::remove_mask_watchpoint (CORE_ADDR arg0, CORE_ADDR arg1, enum targe
   return result;
 }
 
-int
+bool
 target_ops::stopped_by_watchpoint ()
 {
   return this->beneath->stopped_by_watchpoint ();
 }
 
-int
+bool
 dummy_target::stopped_by_watchpoint ()
 {
-  return 0;
+  return false;
 }
 
-int
+bool
 debug_target::stopped_by_watchpoint ()
 {
-  int result;
+  bool result;
   fprintf_unfiltered (gdb_stdlog, "-> %s->stopped_by_watchpoint (...)\n", this->beneath->shortname ());
   result = this->beneath->stopped_by_watchpoint ();
   fprintf_unfiltered (gdb_stdlog, "<- %s->stopped_by_watchpoint (", this->beneath->shortname ());
   fputs_unfiltered (") = ", gdb_stdlog);
-  target_debug_print_int (result);
+  target_debug_print_bool (result);
   fputs_unfiltered ("\n", gdb_stdlog);
   return result;
 }
@@ -1004,7 +1004,7 @@ target_ops::have_steppable_watchpoint ()
 int
 dummy_target::have_steppable_watchpoint ()
 {
-  return 0;
+  return false;
 }
 
 int
@@ -1029,7 +1029,7 @@ target_ops::have_continuable_watchpoint ()
 bool
 dummy_target::have_continuable_watchpoint ()
 {
-  return 0;
+  return false;
 }
 
 bool
@@ -1045,48 +1045,48 @@ debug_target::have_continuable_watchpoint ()
   return result;
 }
 
-int
+bool
 target_ops::stopped_data_address (CORE_ADDR *arg0)
 {
   return this->beneath->stopped_data_address (arg0);
 }
 
-int
+bool
 dummy_target::stopped_data_address (CORE_ADDR *arg0)
 {
-  return 0;
+  return false;
 }
 
-int
+bool
 debug_target::stopped_data_address (CORE_ADDR *arg0)
 {
-  int result;
+  bool result;
   fprintf_unfiltered (gdb_stdlog, "-> %s->stopped_data_address (...)\n", this->beneath->shortname ());
   result = this->beneath->stopped_data_address (arg0);
   fprintf_unfiltered (gdb_stdlog, "<- %s->stopped_data_address (", this->beneath->shortname ());
   target_debug_print_CORE_ADDR_p (arg0);
   fputs_unfiltered (") = ", gdb_stdlog);
-  target_debug_print_int (result);
+  target_debug_print_bool (result);
   fputs_unfiltered ("\n", gdb_stdlog);
   return result;
 }
 
-int
+bool
 target_ops::watchpoint_addr_within_range (CORE_ADDR arg0, CORE_ADDR arg1, int arg2)
 {
   return this->beneath->watchpoint_addr_within_range (arg0, arg1, arg2);
 }
 
-int
+bool
 dummy_target::watchpoint_addr_within_range (CORE_ADDR arg0, CORE_ADDR arg1, int arg2)
 {
   return default_watchpoint_addr_within_range (this, arg0, arg1, arg2);
 }
 
-int
+bool
 debug_target::watchpoint_addr_within_range (CORE_ADDR arg0, CORE_ADDR arg1, int arg2)
 {
-  int result;
+  bool result;
   fprintf_unfiltered (gdb_stdlog, "-> %s->watchpoint_addr_within_range (...)\n", this->beneath->shortname ());
   result = this->beneath->watchpoint_addr_within_range (arg0, arg1, arg2);
   fprintf_unfiltered (gdb_stdlog, "<- %s->watchpoint_addr_within_range (", this->beneath->shortname ());
@@ -1096,7 +1096,7 @@ debug_target::watchpoint_addr_within_range (CORE_ADDR arg0, CORE_ADDR arg1, int
   fputs_unfiltered (", ", gdb_stdlog);
   target_debug_print_int (arg2);
   fputs_unfiltered (") = ", gdb_stdlog);
-  target_debug_print_int (result);
+  target_debug_print_bool (result);
   fputs_unfiltered ("\n", gdb_stdlog);
   return result;
 }
@@ -1129,22 +1129,22 @@ debug_target::region_ok_for_hw_watchpoint (CORE_ADDR arg0, int arg1)
   return result;
 }
 
-int
+bool
 target_ops::can_accel_watchpoint_condition (CORE_ADDR arg0, int arg1, int arg2, struct expression *arg3)
 {
   return this->beneath->can_accel_watchpoint_condition (arg0, arg1, arg2, arg3);
 }
 
-int
+bool
 dummy_target::can_accel_watchpoint_condition (CORE_ADDR arg0, int arg1, int arg2, struct expression *arg3)
 {
-  return 0;
+  return false;
 }
 
-int
+bool
 debug_target::can_accel_watchpoint_condition (CORE_ADDR arg0, int arg1, int arg2, struct expression *arg3)
 {
-  int result;
+  bool result;
   fprintf_unfiltered (gdb_stdlog, "-> %s->can_accel_watchpoint_condition (...)\n", this->beneath->shortname ());
   result = this->beneath->can_accel_watchpoint_condition (arg0, arg1, arg2, arg3);
   fprintf_unfiltered (gdb_stdlog, "<- %s->can_accel_watchpoint_condition (", this->beneath->shortname ());
@@ -1156,7 +1156,7 @@ debug_target::can_accel_watchpoint_condition (CORE_ADDR arg0, int arg1, int arg2
   fputs_unfiltered (", ", gdb_stdlog);
   target_debug_print_struct_expression_p (arg3);
   fputs_unfiltered (") = ", gdb_stdlog);
-  target_debug_print_int (result);
+  target_debug_print_bool (result);
   fputs_unfiltered ("\n", gdb_stdlog);
   return result;
 }
@@ -1223,7 +1223,7 @@ target_ops::supports_terminal_ours ()
 bool
 dummy_target::supports_terminal_ours ()
 {
-  return 0;
+  return false;
 }
 
 bool
@@ -1735,28 +1735,28 @@ debug_target::program_signals (int arg0, unsigned char * arg1)
   fputs_unfiltered (")\n", gdb_stdlog);
 }
 
-int
+bool
 target_ops::thread_alive (ptid_t arg0)
 {
   return this->beneath->thread_alive (arg0);
 }
 
-int
+bool
 dummy_target::thread_alive (ptid_t arg0)
 {
-  return 0;
+  return false;
 }
 
-int
+bool
 debug_target::thread_alive (ptid_t arg0)
 {
-  int result;
+  bool result;
   fprintf_unfiltered (gdb_stdlog, "-> %s->thread_alive (...)\n", this->beneath->shortname ());
   result = this->beneath->thread_alive (arg0);
   fprintf_unfiltered (gdb_stdlog, "<- %s->thread_alive (", this->beneath->shortname ());
   target_debug_print_ptid_t (arg0);
   fputs_unfiltered (") = ", gdb_stdlog);
-  target_debug_print_int (result);
+  target_debug_print_bool (result);
   fputs_unfiltered ("\n", gdb_stdlog);
   return result;
 }
@@ -2097,52 +2097,52 @@ debug_target::attach_no_wait ()
   return result;
 }
 
-int
+bool
 target_ops::can_async_p ()
 {
   return this->beneath->can_async_p ();
 }
 
-int
+bool
 dummy_target::can_async_p ()
 {
-  return 0;
+  return false;
 }
 
-int
+bool
 debug_target::can_async_p ()
 {
-  int result;
+  bool result;
   fprintf_unfiltered (gdb_stdlog, "-> %s->can_async_p (...)\n", this->beneath->shortname ());
   result = this->beneath->can_async_p ();
   fprintf_unfiltered (gdb_stdlog, "<- %s->can_async_p (", this->beneath->shortname ());
   fputs_unfiltered (") = ", gdb_stdlog);
-  target_debug_print_int (result);
+  target_debug_print_bool (result);
   fputs_unfiltered ("\n", gdb_stdlog);
   return result;
 }
 
-int
+bool
 target_ops::is_async_p ()
 {
   return this->beneath->is_async_p ();
 }
 
-int
+bool
 dummy_target::is_async_p ()
 {
-  return 0;
+  return false;
 }
 
-int
+bool
 debug_target::is_async_p ()
 {
-  int result;
+  bool result;
   fprintf_unfiltered (gdb_stdlog, "-> %s->is_async_p (...)\n", this->beneath->shortname ());
   result = this->beneath->is_async_p ();
   fprintf_unfiltered (gdb_stdlog, "<- %s->is_async_p (", this->beneath->shortname ());
   fputs_unfiltered (") = ", gdb_stdlog);
-  target_debug_print_int (result);
+  target_debug_print_bool (result);
   fputs_unfiltered ("\n", gdb_stdlog);
   return result;
 }
@@ -2190,52 +2190,52 @@ debug_target::thread_events (int arg0)
   fputs_unfiltered (")\n", gdb_stdlog);
 }
 
-int
+bool
 target_ops::supports_non_stop ()
 {
   return this->beneath->supports_non_stop ();
 }
 
-int
+bool
 dummy_target::supports_non_stop ()
 {
-  return 0;
+  return false;
 }
 
-int
+bool
 debug_target::supports_non_stop ()
 {
-  int result;
+  bool result;
   fprintf_unfiltered (gdb_stdlog, "-> %s->supports_non_stop (...)\n", this->beneath->shortname ());
   result = this->beneath->supports_non_stop ();
   fprintf_unfiltered (gdb_stdlog, "<- %s->supports_non_stop (", this->beneath->shortname ());
   fputs_unfiltered (") = ", gdb_stdlog);
-  target_debug_print_int (result);
+  target_debug_print_bool (result);
   fputs_unfiltered ("\n", gdb_stdlog);
   return result;
 }
 
-int
+bool
 target_ops::always_non_stop_p ()
 {
   return this->beneath->always_non_stop_p ();
 }
 
-int
+bool
 dummy_target::always_non_stop_p ()
 {
-  return 0;
+  return false;
 }
 
-int
+bool
 debug_target::always_non_stop_p ()
 {
-  int result;
+  bool result;
   fprintf_unfiltered (gdb_stdlog, "-> %s->always_non_stop_p (...)\n", this->beneath->shortname ());
   result = this->beneath->always_non_stop_p ();
   fprintf_unfiltered (gdb_stdlog, "<- %s->always_non_stop_p (", this->beneath->shortname ());
   fputs_unfiltered (") = ", gdb_stdlog);
-  target_debug_print_int (result);
+  target_debug_print_bool (result);
   fputs_unfiltered ("\n", gdb_stdlog);
   return result;
 }
@@ -2630,27 +2630,27 @@ debug_target::search_memory (CORE_ADDR arg0, ULONGEST arg1, const gdb_byte *arg2
   return result;
 }
 
-int
+bool
 target_ops::can_execute_reverse ()
 {
   return this->beneath->can_execute_reverse ();
 }
 
-int
+bool
 dummy_target::can_execute_reverse ()
 {
-  return 0;
+  return false;
 }
 
-int
+bool
 debug_target::can_execute_reverse ()
 {
-  int result;
+  bool result;
   fprintf_unfiltered (gdb_stdlog, "-> %s->can_execute_reverse (...)\n", this->beneath->shortname ());
   result = this->beneath->can_execute_reverse ();
   fprintf_unfiltered (gdb_stdlog, "<- %s->can_execute_reverse (", this->beneath->shortname ());
   fputs_unfiltered (") = ", gdb_stdlog);
-  target_debug_print_int (result);
+  target_debug_print_bool (result);
   fputs_unfiltered ("\n", gdb_stdlog);
   return result;
 }
@@ -2680,152 +2680,152 @@ debug_target::execution_direction ()
   return result;
 }
 
-int
+bool
 target_ops::supports_multi_process ()
 {
   return this->beneath->supports_multi_process ();
 }
 
-int
+bool
 dummy_target::supports_multi_process ()
 {
-  return 0;
+  return false;
 }
 
-int
+bool
 debug_target::supports_multi_process ()
 {
-  int result;
+  bool result;
   fprintf_unfiltered (gdb_stdlog, "-> %s->supports_multi_process (...)\n", this->beneath->shortname ());
   result = this->beneath->supports_multi_process ();
   fprintf_unfiltered (gdb_stdlog, "<- %s->supports_multi_process (", this->beneath->shortname ());
   fputs_unfiltered (") = ", gdb_stdlog);
-  target_debug_print_int (result);
+  target_debug_print_bool (result);
   fputs_unfiltered ("\n", gdb_stdlog);
   return result;
 }
 
-int
+bool
 target_ops::supports_enable_disable_tracepoint ()
 {
   return this->beneath->supports_enable_disable_tracepoint ();
 }
 
-int
+bool
 dummy_target::supports_enable_disable_tracepoint ()
 {
-  return 0;
+  return false;
 }
 
-int
+bool
 debug_target::supports_enable_disable_tracepoint ()
 {
-  int result;
+  bool result;
   fprintf_unfiltered (gdb_stdlog, "-> %s->supports_enable_disable_tracepoint (...)\n", this->beneath->shortname ());
   result = this->beneath->supports_enable_disable_tracepoint ();
   fprintf_unfiltered (gdb_stdlog, "<- %s->supports_enable_disable_tracepoint (", this->beneath->shortname ());
   fputs_unfiltered (") = ", gdb_stdlog);
-  target_debug_print_int (result);
+  target_debug_print_bool (result);
   fputs_unfiltered ("\n", gdb_stdlog);
   return result;
 }
 
-int
+bool
 target_ops::supports_disable_randomization ()
 {
   return this->beneath->supports_disable_randomization ();
 }
 
-int
+bool
 dummy_target::supports_disable_randomization ()
 {
   return find_default_supports_disable_randomization (this);
 }
 
-int
+bool
 debug_target::supports_disable_randomization ()
 {
-  int result;
+  bool result;
   fprintf_unfiltered (gdb_stdlog, "-> %s->supports_disable_randomization (...)\n", this->beneath->shortname ());
   result = this->beneath->supports_disable_randomization ();
   fprintf_unfiltered (gdb_stdlog, "<- %s->supports_disable_randomization (", this->beneath->shortname ());
   fputs_unfiltered (") = ", gdb_stdlog);
-  target_debug_print_int (result);
+  target_debug_print_bool (result);
   fputs_unfiltered ("\n", gdb_stdlog);
   return result;
 }
 
-int
+bool
 target_ops::supports_string_tracing ()
 {
   return this->beneath->supports_string_tracing ();
 }
 
-int
+bool
 dummy_target::supports_string_tracing ()
 {
-  return 0;
+  return false;
 }
 
-int
+bool
 debug_target::supports_string_tracing ()
 {
-  int result;
+  bool result;
   fprintf_unfiltered (gdb_stdlog, "-> %s->supports_string_tracing (...)\n", this->beneath->shortname ());
   result = this->beneath->supports_string_tracing ();
   fprintf_unfiltered (gdb_stdlog, "<- %s->supports_string_tracing (", this->beneath->shortname ());
   fputs_unfiltered (") = ", gdb_stdlog);
-  target_debug_print_int (result);
+  target_debug_print_bool (result);
   fputs_unfiltered ("\n", gdb_stdlog);
   return result;
 }
 
-int
+bool
 target_ops::supports_evaluation_of_breakpoint_conditions ()
 {
   return this->beneath->supports_evaluation_of_breakpoint_conditions ();
 }
 
-int
+bool
 dummy_target::supports_evaluation_of_breakpoint_conditions ()
 {
-  return 0;
+  return false;
 }
 
-int
+bool
 debug_target::supports_evaluation_of_breakpoint_conditions ()
 {
-  int result;
+  bool result;
   fprintf_unfiltered (gdb_stdlog, "-> %s->supports_evaluation_of_breakpoint_conditions (...)\n", this->beneath->shortname ());
   result = this->beneath->supports_evaluation_of_breakpoint_conditions ();
   fprintf_unfiltered (gdb_stdlog, "<- %s->supports_evaluation_of_breakpoint_conditions (", this->beneath->shortname ());
   fputs_unfiltered (") = ", gdb_stdlog);
-  target_debug_print_int (result);
+  target_debug_print_bool (result);
   fputs_unfiltered ("\n", gdb_stdlog);
   return result;
 }
 
-int
+bool
 target_ops::can_run_breakpoint_commands ()
 {
   return this->beneath->can_run_breakpoint_commands ();
 }
 
-int
+bool
 dummy_target::can_run_breakpoint_commands ()
 {
-  return 0;
+  return false;
 }
 
-int
+bool
 debug_target::can_run_breakpoint_commands ()
 {
-  int result;
+  bool result;
   fprintf_unfiltered (gdb_stdlog, "-> %s->can_run_breakpoint_commands (...)\n", this->beneath->shortname ());
   result = this->beneath->can_run_breakpoint_commands ();
   fprintf_unfiltered (gdb_stdlog, "<- %s->can_run_breakpoint_commands (", this->beneath->shortname ());
   fputs_unfiltered (") = ", gdb_stdlog);
-  target_debug_print_int (result);
+  target_debug_print_bool (result);
   fputs_unfiltered ("\n", gdb_stdlog);
   return result;
 }
@@ -2882,27 +2882,27 @@ debug_target::thread_address_space (ptid_t arg0)
   return result;
 }
 
-int
+bool
 target_ops::filesystem_is_local ()
 {
   return this->beneath->filesystem_is_local ();
 }
 
-int
+bool
 dummy_target::filesystem_is_local ()
 {
-  return 1;
+  return true;
 }
 
-int
+bool
 debug_target::filesystem_is_local ()
 {
-  int result;
+  bool result;
   fprintf_unfiltered (gdb_stdlog, "-> %s->filesystem_is_local (...)\n", this->beneath->shortname ());
   result = this->beneath->filesystem_is_local ();
   fprintf_unfiltered (gdb_stdlog, "<- %s->filesystem_is_local (", this->beneath->shortname ());
   fputs_unfiltered (") = ", gdb_stdlog);
-  target_debug_print_int (result);
+  target_debug_print_bool (result);
   fputs_unfiltered ("\n", gdb_stdlog);
   return result;
 }
@@ -2950,27 +2950,27 @@ debug_target::download_tracepoint (struct bp_location *arg0)
   fputs_unfiltered (")\n", gdb_stdlog);
 }
 
-int
+bool
 target_ops::can_download_tracepoint ()
 {
   return this->beneath->can_download_tracepoint ();
 }
 
-int
+bool
 dummy_target::can_download_tracepoint ()
 {
-  return 0;
+  return false;
 }
 
-int
+bool
 debug_target::can_download_tracepoint ()
 {
-  int result;
+  bool result;
   fprintf_unfiltered (gdb_stdlog, "-> %s->can_download_tracepoint (...)\n", this->beneath->shortname ());
   result = this->beneath->can_download_tracepoint ();
   fprintf_unfiltered (gdb_stdlog, "<- %s->can_download_tracepoint (", this->beneath->shortname ());
   fputs_unfiltered (") = ", gdb_stdlog);
-  target_debug_print_int (result);
+  target_debug_print_bool (result);
   fputs_unfiltered ("\n", gdb_stdlog);
   return result;
 }
@@ -3188,22 +3188,22 @@ debug_target::trace_find (enum trace_find_type arg0, int arg1, CORE_ADDR arg2, C
   return result;
 }
 
-int
+bool
 target_ops::get_trace_state_variable_value (int arg0, LONGEST *arg1)
 {
   return this->beneath->get_trace_state_variable_value (arg0, arg1);
 }
 
-int
+bool
 dummy_target::get_trace_state_variable_value (int arg0, LONGEST *arg1)
 {
-  return 0;
+  return false;
 }
 
-int
+bool
 debug_target::get_trace_state_variable_value (int arg0, LONGEST *arg1)
 {
-  int result;
+  bool result;
   fprintf_unfiltered (gdb_stdlog, "-> %s->get_trace_state_variable_value (...)\n", this->beneath->shortname ());
   result = this->beneath->get_trace_state_variable_value (arg0, arg1);
   fprintf_unfiltered (gdb_stdlog, "<- %s->get_trace_state_variable_value (", this->beneath->shortname ());
@@ -3211,7 +3211,7 @@ debug_target::get_trace_state_variable_value (int arg0, LONGEST *arg1)
   fputs_unfiltered (", ", gdb_stdlog);
   target_debug_print_LONGEST_p (arg1);
   fputs_unfiltered (") = ", gdb_stdlog);
-  target_debug_print_int (result);
+  target_debug_print_bool (result);
   fputs_unfiltered ("\n", gdb_stdlog);
   return result;
 }
@@ -3412,22 +3412,22 @@ debug_target::set_trace_buffer_size (LONGEST arg0)
   fputs_unfiltered (")\n", gdb_stdlog);
 }
 
-int
+bool
 target_ops::set_trace_notes (const char *arg0, const char *arg1, const char *arg2)
 {
   return this->beneath->set_trace_notes (arg0, arg1, arg2);
 }
 
-int
+bool
 dummy_target::set_trace_notes (const char *arg0, const char *arg1, const char *arg2)
 {
-  return 0;
+  return false;
 }
 
-int
+bool
 debug_target::set_trace_notes (const char *arg0, const char *arg1, const char *arg2)
 {
-  int result;
+  bool result;
   fprintf_unfiltered (gdb_stdlog, "-> %s->set_trace_notes (...)\n", this->beneath->shortname ());
   result = this->beneath->set_trace_notes (arg0, arg1, arg2);
   fprintf_unfiltered (gdb_stdlog, "<- %s->set_trace_notes (", this->beneath->shortname ());
@@ -3437,7 +3437,7 @@ debug_target::set_trace_notes (const char *arg0, const char *arg1, const char *a
   fputs_unfiltered (", ", gdb_stdlog);
   target_debug_print_const_char_p (arg2);
   fputs_unfiltered (") = ", gdb_stdlog);
-  target_debug_print_int (result);
+  target_debug_print_bool (result);
   fputs_unfiltered ("\n", gdb_stdlog);
   return result;
 }
@@ -3498,22 +3498,22 @@ debug_target::verify_memory (const gdb_byte *arg0, CORE_ADDR arg1, ULONGEST arg2
   return result;
 }
 
-int
+bool
 target_ops::get_tib_address (ptid_t arg0, CORE_ADDR *arg1)
 {
   return this->beneath->get_tib_address (arg0, arg1);
 }
 
-int
+bool
 dummy_target::get_tib_address (ptid_t arg0, CORE_ADDR *arg1)
 {
   tcomplain ();
 }
 
-int
+bool
 debug_target::get_tib_address (ptid_t arg0, CORE_ADDR *arg1)
 {
-  int result;
+  bool result;
   fprintf_unfiltered (gdb_stdlog, "-> %s->get_tib_address (...)\n", this->beneath->shortname ());
   result = this->beneath->get_tib_address (arg0, arg1);
   fprintf_unfiltered (gdb_stdlog, "<- %s->get_tib_address (", this->beneath->shortname ());
@@ -3521,7 +3521,7 @@ debug_target::get_tib_address (ptid_t arg0, CORE_ADDR *arg1)
   fputs_unfiltered (", ", gdb_stdlog);
   target_debug_print_CORE_ADDR_p (arg1);
   fputs_unfiltered (") = ", gdb_stdlog);
-  target_debug_print_int (result);
+  target_debug_print_bool (result);
   fputs_unfiltered ("\n", gdb_stdlog);
   return result;
 }
@@ -3625,53 +3625,53 @@ debug_target::traceframe_info ()
   return result;
 }
 
-int
-target_ops::use_agent (int arg0)
+bool
+target_ops::use_agent (bool arg0)
 {
   return this->beneath->use_agent (arg0);
 }
 
-int
-dummy_target::use_agent (int arg0)
+bool
+dummy_target::use_agent (bool arg0)
 {
   tcomplain ();
 }
 
-int
-debug_target::use_agent (int arg0)
+bool
+debug_target::use_agent (bool arg0)
 {
-  int result;
+  bool result;
   fprintf_unfiltered (gdb_stdlog, "-> %s->use_agent (...)\n", this->beneath->shortname ());
   result = this->beneath->use_agent (arg0);
   fprintf_unfiltered (gdb_stdlog, "<- %s->use_agent (", this->beneath->shortname ());
-  target_debug_print_int (arg0);
+  target_debug_print_bool (arg0);
   fputs_unfiltered (") = ", gdb_stdlog);
-  target_debug_print_int (result);
+  target_debug_print_bool (result);
   fputs_unfiltered ("\n", gdb_stdlog);
   return result;
 }
 
-int
+bool
 target_ops::can_use_agent ()
 {
   return this->beneath->can_use_agent ();
 }
 
-int
+bool
 dummy_target::can_use_agent ()
 {
-  return 0;
+  return false;
 }
 
-int
+bool
 debug_target::can_use_agent ()
 {
-  int result;
+  bool result;
   fprintf_unfiltered (gdb_stdlog, "-> %s->can_use_agent (...)\n", this->beneath->shortname ());
   result = this->beneath->can_use_agent ();
   fprintf_unfiltered (gdb_stdlog, "<- %s->can_use_agent (", this->beneath->shortname ());
   fputs_unfiltered (") = ", gdb_stdlog);
-  target_debug_print_int (result);
+  target_debug_print_bool (result);
   fputs_unfiltered ("\n", gdb_stdlog);
   return result;
 }
@@ -3938,48 +3938,48 @@ debug_target::delete_record ()
   fputs_unfiltered (")\n", gdb_stdlog);
 }
 
-int
+bool
 target_ops::record_is_replaying (ptid_t arg0)
 {
   return this->beneath->record_is_replaying (arg0);
 }
 
-int
+bool
 dummy_target::record_is_replaying (ptid_t arg0)
 {
-  return 0;
+  return false;
 }
 
-int
+bool
 debug_target::record_is_replaying (ptid_t arg0)
 {
-  int result;
+  bool result;
   fprintf_unfiltered (gdb_stdlog, "-> %s->record_is_replaying (...)\n", this->beneath->shortname ());
   result = this->beneath->record_is_replaying (arg0);
   fprintf_unfiltered (gdb_stdlog, "<- %s->record_is_replaying (", this->beneath->shortname ());
   target_debug_print_ptid_t (arg0);
   fputs_unfiltered (") = ", gdb_stdlog);
-  target_debug_print_int (result);
+  target_debug_print_bool (result);
   fputs_unfiltered ("\n", gdb_stdlog);
   return result;
 }
 
-int
+bool
 target_ops::record_will_replay (ptid_t arg0, int arg1)
 {
   return this->beneath->record_will_replay (arg0, arg1);
 }
 
-int
+bool
 dummy_target::record_will_replay (ptid_t arg0, int arg1)
 {
-  return 0;
+  return false;
 }
 
-int
+bool
 debug_target::record_will_replay (ptid_t arg0, int arg1)
 {
-  int result;
+  bool result;
   fprintf_unfiltered (gdb_stdlog, "-> %s->record_will_replay (...)\n", this->beneath->shortname ());
   result = this->beneath->record_will_replay (arg0, arg1);
   fprintf_unfiltered (gdb_stdlog, "<- %s->record_will_replay (", this->beneath->shortname ());
@@ -3987,7 +3987,7 @@ debug_target::record_will_replay (ptid_t arg0, int arg1)
   fputs_unfiltered (", ", gdb_stdlog);
   target_debug_print_int (arg1);
   fputs_unfiltered (") = ", gdb_stdlog);
-  target_debug_print_int (result);
+  target_debug_print_bool (result);
   fputs_unfiltered ("\n", gdb_stdlog);
   return result;
 }
@@ -4228,27 +4228,27 @@ debug_target::call_history_range (ULONGEST arg0, ULONGEST arg1, record_print_fla
   fputs_unfiltered (")\n", gdb_stdlog);
 }
 
-int
+bool
 target_ops::augmented_libraries_svr4_read ()
 {
   return this->beneath->augmented_libraries_svr4_read ();
 }
 
-int
+bool
 dummy_target::augmented_libraries_svr4_read ()
 {
-  return 0;
+  return false;
 }
 
-int
+bool
 debug_target::augmented_libraries_svr4_read ()
 {
-  int result;
+  bool result;
   fprintf_unfiltered (gdb_stdlog, "-> %s->augmented_libraries_svr4_read (...)\n", this->beneath->shortname ());
   result = this->beneath->augmented_libraries_svr4_read ();
   fprintf_unfiltered (gdb_stdlog, "<- %s->augmented_libraries_svr4_read (", this->beneath->shortname ());
   fputs_unfiltered (") = ", gdb_stdlog);
-  target_debug_print_int (result);
+  target_debug_print_bool (result);
   fputs_unfiltered ("\n", gdb_stdlog);
   return result;
 }
diff --git a/gdb/target.c b/gdb/target.c
index 022da5919a..3ed5537e2d 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -2650,10 +2650,10 @@ target_ops::create_inferior (const char *, const std::string &,
   gdb_assert_not_reached ("target_ops::create_inferior called");
 }
 
-int
+bool
 target_ops::can_run ()
 {
-  return 0;
+  return false;
 }
 
 int
diff --git a/gdb/target.h b/gdb/target.h
index f78eb459dc..cd49fce92b 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -482,11 +482,11 @@ struct target_ops
        done from the target, so GDB needs to be able to tell whether
        it should ignore the event and whether it should adjust the PC.
        See adjust_pc_after_break.  */
-    virtual int stopped_by_sw_breakpoint ()
-      TARGET_DEFAULT_RETURN (0);
+    virtual bool stopped_by_sw_breakpoint ()
+      TARGET_DEFAULT_RETURN (false);
     /* Returns true if the above method is supported.  */
-    virtual int supports_stopped_by_sw_breakpoint ()
-      TARGET_DEFAULT_RETURN (0);
+    virtual bool supports_stopped_by_sw_breakpoint ()
+      TARGET_DEFAULT_RETURN (false);
 
     /* Returns true if the target stopped for a hardware breakpoint.
        Likewise, if the target supports hardware breakpoints, this
@@ -495,11 +495,11 @@ struct target_ops
        require PC adjustment, GDB needs to be able to tell whether the
        hardware breakpoint event is a delayed event for a breakpoint
        that is already gone and should thus be ignored.  */
-    virtual int stopped_by_hw_breakpoint ()
-      TARGET_DEFAULT_RETURN (0);
+    virtual bool stopped_by_hw_breakpoint ()
+      TARGET_DEFAULT_RETURN (false);
     /* Returns true if the above method is supported.  */
-    virtual int supports_stopped_by_hw_breakpoint ()
-      TARGET_DEFAULT_RETURN (0);
+    virtual bool supports_stopped_by_hw_breakpoint ()
+      TARGET_DEFAULT_RETURN (false);
 
     virtual int can_use_hw_breakpoint (enum bptype, int, int)
       TARGET_DEFAULT_RETURN (0);
@@ -527,15 +527,15 @@ struct target_ops
     virtual int remove_mask_watchpoint (CORE_ADDR, CORE_ADDR,
 					enum target_hw_bp_type)
       TARGET_DEFAULT_RETURN (1);
-    virtual int stopped_by_watchpoint ()
-      TARGET_DEFAULT_RETURN (0);
+    virtual bool stopped_by_watchpoint ()
+      TARGET_DEFAULT_RETURN (false);
     virtual int have_steppable_watchpoint ()
-      TARGET_DEFAULT_RETURN (0);
+      TARGET_DEFAULT_RETURN (false);
     virtual bool have_continuable_watchpoint ()
-      TARGET_DEFAULT_RETURN (0);
-    virtual int stopped_data_address (CORE_ADDR *)
-      TARGET_DEFAULT_RETURN (0);
-    virtual int watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, int)
+      TARGET_DEFAULT_RETURN (false);
+    virtual bool stopped_data_address (CORE_ADDR *)
+      TARGET_DEFAULT_RETURN (false);
+    virtual bool watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, int)
       TARGET_DEFAULT_FUNC (default_watchpoint_addr_within_range);
 
     /* Documentation of this routine is provided with the corresponding
@@ -543,9 +543,9 @@ struct target_ops
     virtual int region_ok_for_hw_watchpoint (CORE_ADDR, int)
       TARGET_DEFAULT_FUNC (default_region_ok_for_hw_watchpoint);
 
-    virtual int can_accel_watchpoint_condition (CORE_ADDR, int, int,
-						struct expression *)
-      TARGET_DEFAULT_RETURN (0);
+    virtual bool can_accel_watchpoint_condition (CORE_ADDR, int, int,
+						 struct expression *)
+      TARGET_DEFAULT_RETURN (false);
     virtual int masked_watch_num_registers (CORE_ADDR, CORE_ADDR)
       TARGET_DEFAULT_RETURN (-1);
 
@@ -555,7 +555,7 @@ struct target_ops
       TARGET_DEFAULT_RETURN (-1);
 
     virtual bool supports_terminal_ours ()
-      TARGET_DEFAULT_RETURN (0);
+      TARGET_DEFAULT_RETURN (false);
     virtual void terminal_init ()
       TARGET_DEFAULT_IGNORE ();
     virtual void terminal_inferior ()
@@ -607,7 +607,7 @@ struct target_ops
     /* Note that can_run is special and can be invoked on an unpushed
        target.  Targets defining this method must also define
        to_can_async_p and to_supports_non_stop.  */
-    virtual int can_run ();
+    virtual bool can_run ();
 
     /* Documentation of this routine is provided with the corresponding
        target_* macro.  */
@@ -621,8 +621,8 @@ struct target_ops
 				  unsigned char * TARGET_DEBUG_PRINTER (target_debug_print_signals))
       TARGET_DEFAULT_IGNORE ();
 
-    virtual int thread_alive (ptid_t ptid)
-      TARGET_DEFAULT_RETURN (0);
+    virtual bool thread_alive (ptid_t ptid)
+      TARGET_DEFAULT_RETURN (false);
     virtual void update_thread_list ()
       TARGET_DEFAULT_IGNORE ();
     virtual const char *pid_to_str (ptid_t)
@@ -652,11 +652,11 @@ struct target_ops
     enum strata to_stratum;
 
     /* Provide default values for all "must have" methods.  */
-    virtual int has_all_memory () { return 0; }
-    virtual int has_memory () { return 0; }
-    virtual int has_stack () { return 0; }
-    virtual int has_registers () { return 0; }
-    virtual int has_execution (ptid_t) { return 0; }
+    virtual bool has_all_memory () { return false; }
+    virtual bool has_memory () { return false; }
+    virtual bool has_stack () { return false; }
+    virtual bool has_registers () { return false; }
+    virtual bool has_execution (ptid_t) { return false; }
 
     /* Control thread execution.  */
     virtual thread_control_capabilities get_thread_control_capabilities ()
@@ -665,22 +665,22 @@ struct target_ops
       TARGET_DEFAULT_RETURN (0);
     /* This method must be implemented in some situations.  See the
        comment on 'can_run'.  */
-    virtual int can_async_p ()
-      TARGET_DEFAULT_RETURN (0);
-    virtual int is_async_p ()
-      TARGET_DEFAULT_RETURN (0);
+    virtual bool can_async_p ()
+      TARGET_DEFAULT_RETURN (false);
+    virtual bool is_async_p ()
+      TARGET_DEFAULT_RETURN (false);
     virtual void async (int)
       TARGET_DEFAULT_NORETURN (tcomplain ());
     virtual void thread_events (int)
       TARGET_DEFAULT_IGNORE ();
     /* This method must be implemented in some situations.  See the
        comment on 'can_run'.  */
-    virtual int supports_non_stop ()
-      TARGET_DEFAULT_RETURN (0);
+    virtual bool supports_non_stop ()
+      TARGET_DEFAULT_RETURN (false);
     /* Return true if the target operates in non-stop mode even with
        "set non-stop off".  */
-    virtual int always_non_stop_p ()
-      TARGET_DEFAULT_RETURN (0);
+    virtual bool always_non_stop_p ()
+      TARGET_DEFAULT_RETURN (false);
     /* find_memory_regions support method for gcore */
     virtual int find_memory_regions (find_memory_region_ftype func, void *data)
       TARGET_DEFAULT_FUNC (dummy_find_memory_regions);
@@ -815,8 +815,8 @@ struct target_ops
       TARGET_DEFAULT_FUNC (default_search_memory);
 
     /* Can target execute in reverse?  */
-    virtual int can_execute_reverse ()
-      TARGET_DEFAULT_RETURN (0);
+    virtual bool can_execute_reverse ()
+      TARGET_DEFAULT_RETURN (false);
 
     /* The direction the target is currently executing.  Must be
        implemented on targets that support reverse execution and async
@@ -826,31 +826,31 @@ struct target_ops
 
     /* Does this target support debugging multiple processes
        simultaneously?  */
-    virtual int supports_multi_process ()
-      TARGET_DEFAULT_RETURN (0);
+    virtual bool supports_multi_process ()
+      TARGET_DEFAULT_RETURN (false);
 
     /* Does this target support enabling and disabling tracepoints while a trace
        experiment is running?  */
-    virtual int supports_enable_disable_tracepoint ()
-      TARGET_DEFAULT_RETURN (0);
+    virtual bool supports_enable_disable_tracepoint ()
+      TARGET_DEFAULT_RETURN (false);
 
     /* Does this target support disabling address space randomization?  */
-    virtual int supports_disable_randomization ()
+    virtual bool supports_disable_randomization ()
       TARGET_DEFAULT_FUNC (find_default_supports_disable_randomization);
 
     /* Does this target support the tracenz bytecode for string collection?  */
-    virtual int supports_string_tracing ()
-      TARGET_DEFAULT_RETURN (0);
+    virtual bool supports_string_tracing ()
+      TARGET_DEFAULT_RETURN (false);
 
     /* Does this target support evaluation of breakpoint conditions on its
        end?  */
-    virtual int supports_evaluation_of_breakpoint_conditions ()
-      TARGET_DEFAULT_RETURN (0);
+    virtual bool supports_evaluation_of_breakpoint_conditions ()
+      TARGET_DEFAULT_RETURN (false);
 
     /* Does this target support evaluation of breakpoint commands on its
        end?  */
-    virtual int can_run_breakpoint_commands ()
-      TARGET_DEFAULT_RETURN (0);
+    virtual bool can_run_breakpoint_commands ()
+      TARGET_DEFAULT_RETURN (false);
 
     /* Determine current architecture of thread PTID.
 
@@ -876,8 +876,8 @@ struct target_ops
 
     /* Return nonzero if the filesystem seen by the current inferior
        is the local filesystem, zero otherwise.  */
-    virtual int filesystem_is_local ()
-      TARGET_DEFAULT_RETURN (1);
+    virtual bool filesystem_is_local ()
+      TARGET_DEFAULT_RETURN (true);
 
     /* Open FILENAME on the target, in the filesystem as seen by INF,
        using FLAGS and MODE.  If INF is NULL, use the filesystem seen
@@ -944,8 +944,8 @@ struct target_ops
 
     /* Is the target able to download tracepoint locations in current
        state?  */
-    virtual int can_download_tracepoint ()
-      TARGET_DEFAULT_RETURN (0);
+    virtual bool can_download_tracepoint ()
+      TARGET_DEFAULT_RETURN (false);
 
     /* Send full details of a trace state variable to the target.  */
     virtual void download_trace_state_variable (const trace_state_variable &tsv)
@@ -993,8 +993,8 @@ struct target_ops
     /* Get the value of the trace state variable number TSV, returning
        1 if the value is known and writing the value itself into the
        location pointed to by VAL, else returning 0.  */
-    virtual int get_trace_state_variable_value (int tsv, LONGEST *val)
-      TARGET_DEFAULT_RETURN (0);
+    virtual bool get_trace_state_variable_value (int tsv, LONGEST *val)
+      TARGET_DEFAULT_RETURN (false);
 
     virtual int save_trace_data (const char *filename)
       TARGET_DEFAULT_NORETURN (tcomplain ());
@@ -1028,9 +1028,9 @@ struct target_ops
 
     /* Add/change textual notes about the trace run, returning 1 if
        successful, 0 otherwise.  */
-    virtual int set_trace_notes (const char *user, const char *notes,
-				 const char *stopnotes)
-      TARGET_DEFAULT_RETURN (0);
+    virtual bool set_trace_notes (const char *user, const char *notes,
+				  const char *stopnotes)
+      TARGET_DEFAULT_RETURN (false);
 
     /* Return the processor core that thread PTID was last seen on.
        This information is updated only when:
@@ -1052,7 +1052,7 @@ struct target_ops
 
     /* Return the address of the start of the Thread Information Block
        a Windows OS specific feature.  */
-    virtual int get_tib_address (ptid_t ptid, CORE_ADDR *addr)
+    virtual bool get_tib_address (ptid_t ptid, CORE_ADDR *addr)
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
     /* Send the new settings of write permission variables.  */
@@ -1078,14 +1078,14 @@ struct target_ops
     virtual traceframe_info_up traceframe_info ()
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
-    /* Ask the target to use or not to use agent according to USE.  Return 1
-       successful, 0 otherwise.  */
-    virtual int use_agent (int use)
+    /* Ask the target to use or not to use agent according to USE.
+       Return true if successful, false otherwise.  */
+    virtual bool use_agent (bool use)
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
     /* Is the target able to use agent in current state?  */
-    virtual int can_use_agent ()
-      TARGET_DEFAULT_RETURN (0);
+    virtual bool can_use_agent ()
+      TARGET_DEFAULT_RETURN (false);
 
     /* Enable branch tracing for PTID using CONF configuration.
        Return a branch trace target information struct for reading and for
@@ -1140,13 +1140,13 @@ struct target_ops
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
     /* Query if the record target is currently replaying PTID.  */
-    virtual int record_is_replaying (ptid_t ptid)
-      TARGET_DEFAULT_RETURN (0);
+    virtual bool record_is_replaying (ptid_t ptid)
+      TARGET_DEFAULT_RETURN (false);
 
     /* Query if the record target will replay PTID if it were resumed in
        execution direction DIR.  */
-    virtual int record_will_replay (ptid_t ptid, int dir)
-      TARGET_DEFAULT_RETURN (0);
+    virtual bool record_will_replay (ptid_t ptid, int dir)
+      TARGET_DEFAULT_RETURN (false);
 
     /* Stop replaying.  */
     virtual void record_stop_replaying ()
@@ -1203,10 +1203,10 @@ struct target_ops
     virtual void call_history_range (ULONGEST begin, ULONGEST end, record_print_flags flags)
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
-    /* Nonzero if TARGET_OBJECT_LIBRARIES_SVR4 may be read with a
+    /* True if TARGET_OBJECT_LIBRARIES_SVR4 may be read with a
        non-empty annex.  */
-    virtual int augmented_libraries_svr4_read ()
-      TARGET_DEFAULT_RETURN (0);
+    virtual bool augmented_libraries_svr4_read ()
+      TARGET_DEFAULT_RETURN (false);
 
     /* Those unwinders are tried before any other arch unwinders.  If
        SELF doesn't have unwinders, it should delegate to the
@@ -2481,19 +2481,19 @@ public:
     return NULL;
   }
 
-  int has_registers () override
+  bool has_registers () override
   {
-    return 1;
+    return true;
   }
 
-  int has_stack () override
+  bool has_stack () override
   {
-    return 1;
+    return true;
   }
 
-  int has_memory () override
+  bool has_memory () override
   {
-    return 1;
+    return true;
   }
 
   void prepare_to_store (regcache *regs) override
diff --git a/gdb/tracefile-tfile.c b/gdb/tracefile-tfile.c
index af8e3bd83b..d224ad9760 100644
--- a/gdb/tracefile-tfile.c
+++ b/gdb/tracefile-tfile.c
@@ -67,7 +67,7 @@ Use a trace file as a target.  Specify the filename of the trace file.");
   void files_info () override;
   int trace_find (enum trace_find_type type, int num,
 			  CORE_ADDR addr1, CORE_ADDR addr2, int *tpp) override;
-  int get_trace_state_variable_value (int tsv, LONGEST *val) override;
+  bool get_trace_state_variable_value (int tsv, LONGEST *val) override;
   traceframe_info_up traceframe_info () override;
 
   void get_tracepoint_status (struct breakpoint *tp,
@@ -1033,11 +1033,11 @@ tfile_target::xfer_partial (enum target_object object,
 /* Iterate through the blocks of a trace frame, looking for a 'V'
    block with a matching tsv number.  */
 
-int
+bool
 tfile_target::get_trace_state_variable_value (int tsvnum, LONGEST *val)
 {
   int pos;
-  int found = 0;
+  bool found = false;
 
   /* Iterate over blocks in current frame and find the last 'V'
      block in which tsv number is TSVNUM.  In one trace frame, there
@@ -1058,7 +1058,7 @@ tfile_target::get_trace_state_variable_value (int tsvnum, LONGEST *val)
 	  *val = extract_signed_integer ((gdb_byte *) val, 8,
 					 gdbarch_byte_order
 					 (target_gdbarch ()));
-	  found = 1;
+	  found = true;
 	}
       pos += (4 + 8);
     }
diff --git a/gdb/tracefile.c b/gdb/tracefile.c
index 9c9c75398e..f7e69f2df6 100644
--- a/gdb/tracefile.c
+++ b/gdb/tracefile.c
@@ -425,7 +425,7 @@ tracefile_fetch_registers (struct regcache *regcache, int regno)
 
 /* This is the implementation of target_ops method to_has_all_memory.  */
 
-int
+bool
 tracefile_target::has_all_memory ()
 {
   return 1;
@@ -433,7 +433,7 @@ tracefile_target::has_all_memory ()
 
 /* This is the implementation of target_ops method to_has_memory.  */
 
-int
+bool
 tracefile_target::has_memory ()
 {
   return 1;
@@ -443,7 +443,7 @@ tracefile_target::has_memory ()
    The target has a stack when GDB has already selected one trace
    frame.  */
 
-int
+bool
 tracefile_target::has_stack ()
 {
   return get_traceframe_number () != -1;
@@ -453,7 +453,7 @@ tracefile_target::has_stack ()
    The target has registers when GDB has already selected one trace
    frame.  */
 
-int
+bool
 tracefile_target::has_registers ()
 {
   return get_traceframe_number () != -1;
@@ -462,7 +462,7 @@ tracefile_target::has_registers ()
 /* This is the implementation of target_ops method to_thread_alive.
    tracefile has one thread faked by GDB.  */
 
-int
+bool
 tracefile_target::thread_alive (ptid_t ptid)
 {
   return 1;
diff --git a/gdb/tracefile.h b/gdb/tracefile.h
index accd038ebd..47f8bee8f2 100644
--- a/gdb/tracefile.h
+++ b/gdb/tracefile.h
@@ -122,11 +122,11 @@ public:
   tracefile_target ();
 
   int get_trace_status (trace_status *ts) override;
-  int has_all_memory () override;
-  int has_memory () override;
-  int has_stack () override;
-  int has_registers () override;
-  int thread_alive (ptid_t ptid) override;
+  bool has_all_memory () override;
+  bool has_memory () override;
+  bool has_stack () override;
+  bool has_registers () override;
+  bool thread_alive (ptid_t ptid) override;
 };
 
 extern void tracefile_fetch_registers (struct regcache *regcache, int regno);
diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index 589ef47c67..f5a66c1f1c 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -333,7 +333,7 @@ struct windows_nat_target final : public x86_nat_target<inf_child_target>
 
   void mourn_inferior () override;
 
-  int thread_alive (ptid_t ptid) override;
+  bool thread_alive (ptid_t ptid) override;
 
   const char *pid_to_str (ptid_t) override;
 
@@ -343,7 +343,7 @@ struct windows_nat_target final : public x86_nat_target<inf_child_target>
 
   ptid_t get_ada_task_ptid (long lwp, long thread) override;
 
-  int get_tib_address (ptid_t ptid, CORE_ADDR *addr) override;
+  bool get_tib_address (ptid_t ptid, CORE_ADDR *addr) override;
 
   const char *thread_name (struct thread_info *) override;
 };
@@ -2975,19 +2975,19 @@ windows_nat_target::xfer_partial (enum target_object object,
 /* Provide thread local base, i.e. Thread Information Block address.
    Returns 1 if ptid is found and sets *ADDR to thread_local_base.  */
 
-int
+bool
 windows_nat_target::get_tib_address (ptid_t ptid, CORE_ADDR *addr)
 {
   windows_thread_info *th;
 
   th = thread_rec (ptid_get_tid (ptid), 0);
   if (th == NULL)
-    return 0;
+    return false;
 
   if (addr != NULL)
     *addr = th->thread_local_base;
 
-  return 1;
+  return true;
 }
 
 ptid_t
@@ -3156,7 +3156,7 @@ cygwin_get_dr7 (void)
    by "polling" it.  If WaitForSingleObject returns WAIT_OBJECT_0
    it means that the thread has died.  Otherwise it is assumed to be alive.  */
 
-int
+bool
 windows_nat_target::thread_alive (ptid_t ptid)
 {
   int tid;
@@ -3164,8 +3164,7 @@ windows_nat_target::thread_alive (ptid_t ptid)
   gdb_assert (ptid_get_tid (ptid) != 0);
   tid = ptid_get_tid (ptid);
 
-  return WaitForSingleObject (thread_rec (tid, FALSE)->h, 0) == WAIT_OBJECT_0
-    ? FALSE : TRUE;
+  return WaitForSingleObject (thread_rec (tid, FALSE)->h, 0) != WAIT_OBJECT_0;
 }
 
 void
diff --git a/gdb/x86-linux-nat.h b/gdb/x86-linux-nat.h
index 0bafaaa71f..7cbb27184a 100644
--- a/gdb/x86-linux-nat.h
+++ b/gdb/x86-linux-nat.h
@@ -47,16 +47,16 @@ struct x86_linux_nat_target : public x86_nat_target<linux_nat_target>
      stopped-by-watchpoint info as soon as an lwp stops (via the low_
      methods) and caches the result, to be returned via the normal
      non-low methods.  */
-  int stopped_by_watchpoint () override
+  bool stopped_by_watchpoint () override
   { return linux_nat_target::stopped_by_watchpoint (); }
 
-  int stopped_data_address (CORE_ADDR *addr_p) override
+  bool stopped_data_address (CORE_ADDR *addr_p) override
   { return linux_nat_target::stopped_data_address (addr_p); }
 
-  int low_stopped_by_watchpoint () override
+  bool low_stopped_by_watchpoint () override
   { return x86_nat_target::stopped_by_watchpoint (); }
 
-  int low_stopped_data_address (CORE_ADDR *addr_p) override
+  bool low_stopped_data_address (CORE_ADDR *addr_p) override
   { return x86_nat_target::stopped_data_address (addr_p); }
 };
 
diff --git a/gdb/x86-nat.h b/gdb/x86-nat.h
index 8ad1821360..cc27fa43b4 100644
--- a/gdb/x86-nat.h
+++ b/gdb/x86-nat.h
@@ -103,16 +103,16 @@ struct x86_nat_target : public BaseTarget
 			    struct bp_target_info *bp_tgt) override
   { return x86_remove_hw_breakpoint (gdbarch, bp_tgt); }
 
-  int stopped_by_watchpoint () override
+  bool stopped_by_watchpoint () override
   { return x86_stopped_by_watchpoint (); }
 
-  int stopped_data_address (CORE_ADDR *addr_p) override
+  bool stopped_data_address (CORE_ADDR *addr_p) override
   { return x86_stopped_data_address (addr_p); }
 
   /* A target must provide an implementation of the
      "supports_stopped_by_hw_breakpoint" target method before this
      callback will be used.  */
-  int stopped_by_hw_breakpoint () override
+  bool stopped_by_hw_breakpoint () override
   { return x86_stopped_by_hw_breakpoint (); }
 };
 
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 19/40] target_ops/C++: AIX target
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (7 preceding siblings ...)
  2018-04-14 19:10 ` [PATCH 08/40] target_ops/C++: bsd-uthread Pedro Alves
@ 2018-04-14 19:10 ` Pedro Alves
  2018-04-14 19:10 ` [PATCH 40/40] target factories, target open and multiple instances of targets Pedro Alves
                   ` (32 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:10 UTC (permalink / raw)
  To: gdb-patches

Straighforward conversion.  Tested on AIX 7.2 on the compile farm.
---
 gdb/aix-thread.c | 161 +++++++++++++++++++++++++++++--------------------------
 gdb/rs6000-nat.c |  95 +++++++++++++++++---------------
 2 files changed, 138 insertions(+), 118 deletions(-)

diff --git a/gdb/aix-thread.c b/gdb/aix-thread.c
index d2b951d94d..3727336fcb 100644
--- a/gdb/aix-thread.c
+++ b/gdb/aix-thread.c
@@ -108,7 +108,45 @@ struct pd_thread {
 
 /* This module's target-specific operations, active while pd_able is true.  */
 
-static struct target_ops aix_thread_ops;
+class aix_thread_target final : public target_ops
+{
+public:
+  aix_thread_target ()
+  { to_stratum = thread_stratum; }
+
+  const char *shortname () override
+  { return "aix-threads"; }
+  const char *longname () override
+  { return _("AIX pthread support"); }
+  const char *doc () override
+  { return _("AIX pthread support"); }
+
+  void detach (inferior *, int) override;
+  void resume (ptid_t, int, enum gdb_signal) override;
+  ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
+
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+
+  enum target_xfer_status xfer_partial (enum target_object object,
+					const char *annex,
+					gdb_byte *readbuf,
+					const gdb_byte *writebuf,
+					ULONGEST offset, ULONGEST len,
+					ULONGEST *xfered_len) override;
+
+  void mourn_inferior () override;
+
+  int thread_alive (ptid_t ptid) override;
+
+  const char *pid_to_str (ptid_t) override;
+
+  const char *extra_thread_info (struct thread_info *) override;
+
+  ptid_t get_ada_task_ptid (long lwp, long thread) override;
+};
+
+static aix_thread_target aix_thread_ops;
 
 /* Address of the function that libpthread will call when libpthdebug
    is ready to be initialized.  */
@@ -980,21 +1018,20 @@ aix_thread_inferior_created (struct target_ops *ops, int from_tty)
 
 /* Detach from the process attached to by aix_thread_attach().  */
 
-static void
-aix_thread_detach (struct target_ops *ops, inferior *inf, int from_tty)
+void
+aix_thread_target::detach (inferior *inf, int from_tty)
 {
-  struct target_ops *beneath = find_target_beneath (ops);
+  struct target_ops *beneath = find_target_beneath (this);
 
   pd_disable ();
-  beneath->to_detach (beneath, inf, from_tty);
+  beneath->detach (inf, from_tty);
 }
 
 /* Tell the inferior process to continue running thread PID if != -1
    and all threads otherwise.  */
 
-static void
-aix_thread_resume (struct target_ops *ops,
-                   ptid_t ptid, int step, enum gdb_signal sig)
+void
+aix_thread_target::resume (ptid_t ptid, int step, enum gdb_signal sig)
 {
   struct thread_info *thread;
   pthdb_tid_t tid[2];
@@ -1002,10 +1039,10 @@ aix_thread_resume (struct target_ops *ops,
   if (!PD_TID (ptid))
     {
       scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
-      struct target_ops *beneath = find_target_beneath (ops);
+      struct target_ops *beneath = find_target_beneath (this);
       
       inferior_ptid = pid_to_ptid (ptid_get_pid (inferior_ptid));
-      beneath->to_resume (beneath, ptid, step, sig);
+      beneath->resume (ptid, step, sig);
     }
   else
     {
@@ -1035,11 +1072,11 @@ aix_thread_resume (struct target_ops *ops,
    If an error occurs, return -1, else return the pid of the stopped
    thread.  */
 
-static ptid_t
-aix_thread_wait (struct target_ops *ops,
-		 ptid_t ptid, struct target_waitstatus *status, int options)
+ptid_t
+aix_thread_target::wait (ptid_t ptid, struct target_waitstatus *status,
+			 int options)
 {
-  struct target_ops *beneath = find_target_beneath (ops);
+  struct target_ops *beneath = find_target_beneath (this);
 
   {
     scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
@@ -1047,7 +1084,7 @@ aix_thread_wait (struct target_ops *ops,
     pid_to_prc (&ptid);
 
     inferior_ptid = pid_to_ptid (ptid_get_pid (inferior_ptid));
-    ptid = beneath->to_wait (beneath, ptid, status, options);
+    ptid = beneath->wait (ptid, status, options);
   }
 
   if (ptid_get_pid (ptid) == -1)
@@ -1319,16 +1356,15 @@ fetch_regs_kernel_thread (struct regcache *regcache, int regno,
 /* Fetch register REGNO if != -1 or all registers otherwise from the
    thread/process connected to REGCACHE.  */
 
-static void
-aix_thread_fetch_registers (struct target_ops *ops,
-                            struct regcache *regcache, int regno)
+void
+aix_thread_target::fetch_registers (struct regcache *regcache, int regno)
 {
   struct thread_info *thread;
   pthdb_tid_t tid;
-  struct target_ops *beneath = find_target_beneath (ops);
+  struct target_ops *beneath = find_target_beneath (this);
 
   if (!PD_TID (regcache_get_ptid (regcache)))
-    beneath->to_fetch_registers (beneath, regcache, regno);
+    beneath->fetch_registers (regcache, regno);
   else
     {
       thread = find_thread_ptid (regcache_get_ptid (regcache));
@@ -1674,16 +1710,15 @@ store_regs_kernel_thread (const struct regcache *regcache, int regno,
 /* Store gdb's current view of the register set into the
    thread/process connected to REGCACHE.  */
 
-static void
-aix_thread_store_registers (struct target_ops *ops,
-                            struct regcache *regcache, int regno)
+void
+aix_thread_target::store_registers (struct regcache *regcache, int regno)
 {
   struct thread_info *thread;
   pthdb_tid_t tid;
-  struct target_ops *beneath = find_target_beneath (ops);
+  struct target_ops *beneath = find_target_beneath (this);
 
   if (!PD_TID (regcache_get_ptid (regcache)))
-    beneath->to_store_registers (beneath, regcache, regno);
+    beneath->store_registers (regcache, regno);
   else
     {
       thread = find_thread_ptid (regcache_get_ptid (regcache));
@@ -1699,40 +1734,41 @@ aix_thread_store_registers (struct target_ops *ops,
 
 /* Implement the to_xfer_partial target_ops method.  */
 
-static enum target_xfer_status
-aix_thread_xfer_partial (struct target_ops *ops, enum target_object object,
-			 const char *annex, gdb_byte *readbuf,
-			 const gdb_byte *writebuf,
-			 ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
+enum target_xfer_status
+aix_thread_target::xfer_partial (enum target_object object,
+				 const char *annex, gdb_byte *readbuf,
+				 const gdb_byte *writebuf,
+				 ULONGEST offset, ULONGEST len,
+				 ULONGEST *xfered_len)
 {
   scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
-  struct target_ops *beneath = find_target_beneath (ops);
+  struct target_ops *beneath = find_target_beneath (this);
 
   inferior_ptid = pid_to_ptid (ptid_get_pid (inferior_ptid));
-  return beneath->to_xfer_partial (beneath, object, annex, readbuf,
-				   writebuf, offset, len, xfered_len);
+  return beneath->xfer_partial (object, annex, readbuf,
+				writebuf, offset, len, xfered_len);
 }
 
 /* Clean up after the inferior exits.  */
 
-static void
-aix_thread_mourn_inferior (struct target_ops *ops)
+void
+aix_thread_target::mourn_inferior ()
 {
-  struct target_ops *beneath = find_target_beneath (ops);
+  struct target_ops *beneath = find_target_beneath (this);
 
   pd_deactivate ();
-  beneath->to_mourn_inferior (beneath);
+  beneath->mourn_inferior ();
 }
 
 /* Return whether thread PID is still valid.  */
 
-static int
-aix_thread_thread_alive (struct target_ops *ops, ptid_t ptid)
+int
+aix_thread_target::thread_alive (ptid_t ptid)
 {
-  struct target_ops *beneath = find_target_beneath (ops);
+  struct target_ops *beneath = find_target_beneath (this);
 
   if (!PD_TID (ptid))
-    return beneath->to_thread_alive (beneath, ptid);
+    return beneath->thread_alive (ptid);
 
   /* We update the thread list every time the child stops, so all
      valid threads should be in the thread list.  */
@@ -1742,14 +1778,14 @@ aix_thread_thread_alive (struct target_ops *ops, ptid_t ptid)
 /* Return a printable representation of composite PID for use in
    "info threads" output.  */
 
-static const char *
-aix_thread_pid_to_str (struct target_ops *ops, ptid_t ptid)
+const char *
+aix_thread_target::pid_to_str (ptid_t ptid)
 {
   static char *ret = NULL;
-  struct target_ops *beneath = find_target_beneath (ops);
+  struct target_ops *beneath = find_target_beneath (this);
 
   if (!PD_TID (ptid))
-    return beneath->to_pid_to_str (beneath, ptid);
+    return beneath->pid_to_str (ptid);
 
   /* Free previous return value; a new one will be allocated by
      xstrprintf().  */
@@ -1762,9 +1798,8 @@ aix_thread_pid_to_str (struct target_ops *ops, ptid_t ptid)
 /* Return a printable representation of extra information about
    THREAD, for use in "info threads" output.  */
 
-static const char *
-aix_thread_extra_thread_info (struct target_ops *self,
-			      struct thread_info *thread)
+const char *
+aix_thread_target::extra_thread_info (struct thread_info *thread)
 {
   int status;
   pthdb_pthread_t pdtid;
@@ -1819,35 +1854,12 @@ aix_thread_extra_thread_info (struct target_ops *self,
   return ret;
 }
 
-static ptid_t
-aix_thread_get_ada_task_ptid (struct target_ops *self, long lwp, long thread)
+ptid_t
+aix_thread_target::get_ada_task_ptid (long lwp, long thread)
 {
   return ptid_build (ptid_get_pid (inferior_ptid), 0, thread);
 }
 
-/* Initialize target aix_thread_ops.  */
-
-static void
-init_aix_thread_ops (void)
-{
-  aix_thread_ops.to_shortname = "aix-threads";
-  aix_thread_ops.to_longname = _("AIX pthread support");
-  aix_thread_ops.to_doc = _("AIX pthread support");
-
-  aix_thread_ops.to_detach = aix_thread_detach;
-  aix_thread_ops.to_resume = aix_thread_resume;
-  aix_thread_ops.to_wait = aix_thread_wait;
-  aix_thread_ops.to_fetch_registers = aix_thread_fetch_registers;
-  aix_thread_ops.to_store_registers = aix_thread_store_registers;
-  aix_thread_ops.to_xfer_partial = aix_thread_xfer_partial;
-  aix_thread_ops.to_mourn_inferior = aix_thread_mourn_inferior;
-  aix_thread_ops.to_thread_alive = aix_thread_thread_alive;
-  aix_thread_ops.to_pid_to_str = aix_thread_pid_to_str;
-  aix_thread_ops.to_extra_thread_info = aix_thread_extra_thread_info;
-  aix_thread_ops.to_get_ada_task_ptid = aix_thread_get_ada_task_ptid;
-  aix_thread_ops.to_stratum = thread_stratum;
-  aix_thread_ops.to_magic = OPS_MAGIC;
-}
 
 /* Module startup initialization function, automagically called by
    init.c.  */
@@ -1855,9 +1867,6 @@ init_aix_thread_ops (void)
 void
 _initialize_aix_thread (void)
 {
-  init_aix_thread_ops ();
-  complete_target_initialization (&aix_thread_ops);
-
   /* Notice when object files get loaded and unloaded.  */
   gdb::observers::new_objfile.attach (new_objfile);
 
diff --git a/gdb/rs6000-nat.c b/gdb/rs6000-nat.c
index d8c15f00ea..0880d3748e 100644
--- a/gdb/rs6000-nat.c
+++ b/gdb/rs6000-nat.c
@@ -74,7 +74,34 @@
 # define ARCH64() (register_size (target_gdbarch (), 0) == 8)
 #endif
 
-static target_xfer_partial_ftype rs6000_xfer_shared_libraries;
+class rs6000_nat_target final : public inf_ptrace_target
+{
+public:
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+
+  enum target_xfer_status xfer_partial (enum target_object object,
+					const char *annex,
+					gdb_byte *readbuf,
+					const gdb_byte *writebuf,
+					ULONGEST offset, ULONGEST len,
+					ULONGEST *xfered_len) override;
+
+  void create_inferior (const char *, const std::string &,
+			char **, int) override;
+
+  ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
+
+private:
+  enum target_xfer_status
+    xfer_shared_libraries (enum target_object object,
+			   const char *annex, gdb_byte *readbuf,
+			   const gdb_byte *writebuf,
+			   ULONGEST offset, ULONGEST len,
+			   ULONGEST *xfered_len);
+};
+
+static rs6000_nat_target the_rs6000_nat_target;
 
 /* Given REGNO, a gdb register number, return the corresponding
    number suitable for use as a ptrace() parameter.  Return -1 if
@@ -277,9 +304,8 @@ store_register (struct regcache *regcache, int regno)
 /* Read from the inferior all registers if REGNO == -1 and just register
    REGNO otherwise.  */
 
-static void
-rs6000_fetch_inferior_registers (struct target_ops *ops,
-				 struct regcache *regcache, int regno)
+void
+rs6000_nat_target::fetch_registers (struct regcache *regcache, int regno)
 {
   struct gdbarch *gdbarch = regcache->arch ();
   if (regno != -1)
@@ -320,9 +346,8 @@ rs6000_fetch_inferior_registers (struct target_ops *ops,
    If REGNO is -1, do this for all registers.
    Otherwise, REGNO specifies which register (so we can save time).  */
 
-static void
-rs6000_store_inferior_registers (struct target_ops *ops,
-				 struct regcache *regcache, int regno)
+void
+rs6000_nat_target::store_registers (struct regcache *regcache, int regno)
 {
   struct gdbarch *gdbarch = regcache->arch ();
   if (regno != -1)
@@ -361,11 +386,12 @@ rs6000_store_inferior_registers (struct target_ops *ops,
 
 /* Implement the to_xfer_partial target_ops method.  */
 
-static enum target_xfer_status
-rs6000_xfer_partial (struct target_ops *ops, enum target_object object,
-		     const char *annex, gdb_byte *readbuf,
-		     const gdb_byte *writebuf,
-		     ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
+enum target_xfer_status
+rs6000_nat_target::xfer_partial (enum target_object object,
+				 const char *annex, gdb_byte *readbuf,
+				 const gdb_byte *writebuf,
+				 ULONGEST offset, ULONGEST len,
+				 ULONGEST *xfered_len)
 {
   pid_t pid = ptid_get_pid (inferior_ptid);
   int arch64 = ARCH64 ();
@@ -373,9 +399,9 @@ rs6000_xfer_partial (struct target_ops *ops, enum target_object object,
   switch (object)
     {
     case TARGET_OBJECT_LIBRARIES_AIX:
-      return rs6000_xfer_shared_libraries (ops, object, annex,
-					   readbuf, writebuf,
-					   offset, len, xfered_len);
+      return xfer_shared_libraries (object, annex,
+				    readbuf, writebuf,
+				    offset, len, xfered_len);
     case TARGET_OBJECT_MEMORY:
       {
 	union
@@ -467,9 +493,9 @@ rs6000_xfer_partial (struct target_ops *ops, enum target_object object,
    process ID of the child, or MINUS_ONE_PTID in case of error; store
    the status in *OURSTATUS.  */
 
-static ptid_t
-rs6000_wait (struct target_ops *ops,
-	     ptid_t ptid, struct target_waitstatus *ourstatus, int options)
+ptid_t
+rs6000_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
+			 int options)
 {
   pid_t pid;
   int status, save_errno;
@@ -524,20 +550,17 @@ rs6000_wait (struct target_ops *ops,
 /* Set the current architecture from the host running GDB.  Called when
    starting a child process.  */
 
-static void (*super_create_inferior) (struct target_ops *,
-				      const char *exec_file,
-				      const std::string &allargs,
-				      char **env, int from_tty);
-static void
-rs6000_create_inferior (struct target_ops * ops, const char *exec_file,
-			const std::string &allargs, char **env, int from_tty)
+void
+rs6000_nat_target::create_inferior (const char *exec_file,
+				    const std::string &allargs,
+				    char **env, int from_tty)
 {
   enum bfd_architecture arch;
   unsigned long mach;
   bfd abfd;
   struct gdbarch_info info;
 
-  super_create_inferior (ops, exec_file, allargs, env, from_tty);
+  inf_ptrace_target::create_inferior (exec_file, allargs, env, from_tty);
 
   if (__power_rs ())
     {
@@ -617,9 +640,9 @@ rs6000_ptrace_ldinfo (ptid_t ptid)
 /* Implement the to_xfer_partial target_ops method for
    TARGET_OBJECT_LIBRARIES_AIX objects.  */
 
-static enum target_xfer_status
-rs6000_xfer_shared_libraries
-  (struct target_ops *ops, enum target_object object,
+enum target_xfer_status
+rs6000_nat_target::xfer_shared_libraries
+  (enum target_object object,
    const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf,
    ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
 {
@@ -648,17 +671,5 @@ rs6000_xfer_shared_libraries
 void
 _initialize_rs6000_nat (void)
 {
-  struct target_ops *t;
-
-  t = inf_ptrace_target ();
-  t->to_fetch_registers = rs6000_fetch_inferior_registers;
-  t->to_store_registers = rs6000_store_inferior_registers;
-  t->to_xfer_partial = rs6000_xfer_partial;
-
-  super_create_inferior = t->to_create_inferior;
-  t->to_create_inferior = rs6000_create_inferior;
-
-  t->to_wait = rs6000_wait;
-
-  add_target (t);
+  add_target (&the_rs6000_nat_target);
 }
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 27/40] target_ops/C++: SPARC GNU/Linux
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (9 preceding siblings ...)
  2018-04-14 19:10 ` [PATCH 40/40] target factories, target open and multiple instances of targets Pedro Alves
@ 2018-04-14 19:10 ` Pedro Alves
  2018-04-14 19:10 ` [PATCH 37/40] target_ops/C++: The Hurd Pedro Alves
                   ` (30 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:10 UTC (permalink / raw)
  To: gdb-patches

Straighforward conversion.
---
 gdb/sparc-linux-nat.c   | 24 ++++++++++++++----------
 gdb/sparc-nat.c         |  6 ++----
 gdb/sparc-nat.h         |  6 ++----
 gdb/sparc64-linux-nat.c | 24 +++++++++++++++---------
 4 files changed, 33 insertions(+), 27 deletions(-)

diff --git a/gdb/sparc-linux-nat.c b/gdb/sparc-linux-nat.c
index 3a5132c858..de7dda3d14 100644
--- a/gdb/sparc-linux-nat.c
+++ b/gdb/sparc-linux-nat.c
@@ -28,6 +28,19 @@
 #include "target.h"
 #include "linux-nat.h"
 
+class sparc_linux_nat_target final : public linux_nat_target
+{
+public:
+  /* Add our register access methods.  */
+  void fetch_registers (struct regcache *regcache, int regnum) override
+  { sparc_fetch_inferior_registers (regcache, regnum); }
+
+  void store_registers (struct regcache *regcache, int regnum) override;
+  { sparc_store_inferior_registers (regcache, regnum); }
+};
+
+static sparc_linux_nat_target the_sparc_linux_nat_target;
+
 void
 supply_gregset (struct regcache *regcache, const prgregset_t *gregs)
 {
@@ -56,17 +69,8 @@ fill_fpregset (const struct regcache *regcache,
 void
 _initialize_sparc_linux_nat (void)
 {
-  struct target_ops *t;
-
-  /* Fill in the generic GNU/Linux methods.  */
-  t = linux_target ();
-
   sparc_fpregmap = &sparc32_bsd_fpregmap;
 
-  /* Add our register access methods.  */
-  t->to_fetch_registers = sparc_fetch_inferior_registers;
-  t->to_store_registers = sparc_store_inferior_registers;
-
   /* Register the target.  */
-  linux_nat_add_target (t);
+  add_target (&the_sparc_linux_nat_target);
 }
diff --git a/gdb/sparc-nat.c b/gdb/sparc-nat.c
index 5dc17b3b64..9aeaf22c5d 100644
--- a/gdb/sparc-nat.c
+++ b/gdb/sparc-nat.c
@@ -134,8 +134,7 @@ sparc32_fpregset_supplies_p (struct gdbarch *gdbarch, int regnum)
    for all registers (including the floating-point registers).  */
 
 void
-sparc_fetch_inferior_registers (struct target_ops *ops,
-				struct regcache *regcache, int regnum)
+sparc_fetch_inferior_registers (struct regcache *regcache, int regnum)
 {
   struct gdbarch *gdbarch = regcache->arch ();
   pid_t pid;
@@ -187,8 +186,7 @@ sparc_fetch_inferior_registers (struct target_ops *ops,
 }
 
 void
-sparc_store_inferior_registers (struct target_ops *ops,
-				struct regcache *regcache, int regnum)
+sparc_store_inferior_registers (struct regcache *regcache, int regnum)
 {
   struct gdbarch *gdbarch = regcache->arch ();
   pid_t pid;
diff --git a/gdb/sparc-nat.h b/gdb/sparc-nat.h
index 6960d3dda8..f627fd33ed 100644
--- a/gdb/sparc-nat.h
+++ b/gdb/sparc-nat.h
@@ -44,9 +44,7 @@ extern int sparc32_fpregset_supplies_p (struct gdbarch *gdbarch, int regnum);
 
 extern struct target_ops *sparc_target (void);
 
-extern void sparc_fetch_inferior_registers (struct target_ops *,
-					    struct regcache *, int);
-extern void sparc_store_inferior_registers (struct target_ops *,
-					    struct regcache *, int);
+extern void sparc_fetch_inferior_registers (struct regcache *, int);
+extern void sparc_store_inferior_registers (struct regcache *, int);
 
 #endif /* sparc-nat.h */
diff --git a/gdb/sparc64-linux-nat.c b/gdb/sparc64-linux-nat.c
index 7f7c5de500..ea7cfb43f6 100644
--- a/gdb/sparc64-linux-nat.c
+++ b/gdb/sparc64-linux-nat.c
@@ -30,6 +30,19 @@
 #include "target.h"
 #include "linux-nat.h"
 
+class sparc64_linux_nat_target final : public linux_nat_target
+{
+public:
+  /* Add our register access methods.  */
+  void fetch_registers (struct regcache *regcache, int regnum) override
+  { sparc_fetch_inferior_registers (this, regcache, regnum); }
+
+  void store_registers (struct regcache *regcache, int regnum) override;
+  { sparc_store_inferior_registers (this, regcache, regnum); }
+};
+
+static sparc64_linux_nat_target the_sparc64_linux_nat_target;
+
 static const struct sparc_gregmap sparc64_linux_ptrace_gregmap =
 {
   16 * 8,			/* "tstate" */
@@ -72,19 +85,12 @@ fill_fpregset (const struct regcache *regcache,
 void
 _initialize_sparc64_linux_nat (void)
 {
-  struct target_ops *t;
-
-  /* Fill in the generic GNU/Linux methods.  */
-  t = linux_target ();
+  target_ops *t = &the_sparc64_linux_nat_target;
 
   sparc_fpregmap = &sparc64_bsd_fpregmap;
 
-  /* Add our register access methods.  */
-  t->to_fetch_registers = sparc_fetch_inferior_registers;
-  t->to_store_registers = sparc_store_inferior_registers;
-
   /* Register the target.  */
-  linux_nat_add_target (t);
+  add_target (t);
 
   /* ADI support */
   linux_nat_set_forget_process (t, sparc64_forget_process);
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 07/40] target_ops/C++: ravenscar-thread
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (2 preceding siblings ...)
  2018-04-14 19:10 ` [PATCH 03/40] target_ops/C++: exec target Pedro Alves
@ 2018-04-14 19:10 ` Pedro Alves
  2018-04-14 19:10 ` [PATCH 38/40] target_ops: Use bool throughout Pedro Alves
                   ` (37 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:10 UTC (permalink / raw)
  To: gdb-patches

Straighforward conversion.
---
 gdb/ravenscar-thread.c | 230 ++++++++++++++++++++++++-------------------------
 1 file changed, 115 insertions(+), 115 deletions(-)

diff --git a/gdb/ravenscar-thread.c b/gdb/ravenscar-thread.c
index 46e454a6a8..e850ef7507 100644
--- a/gdb/ravenscar-thread.c
+++ b/gdb/ravenscar-thread.c
@@ -60,9 +60,6 @@
 /* If non-null, ravenscar task support is enabled.  */
 static int ravenscar_task_support = 1;
 
-/* This module's target-specific operations.  */
-static struct target_ops ravenscar_ops;
-
 /* PTID of the last thread that received an event.
    This can be useful to determine the associated task that received
    the event, to make it the current task.  */
@@ -76,20 +73,62 @@ static const char first_task_name[] = "system__tasking__debug__first_task";
 static const char ravenscar_runtime_initializer[] =
   "system__bb__threads__initialize";
 
-static void ravenscar_update_thread_list (struct target_ops *ops);
+struct ravenscar_thread_target final : public target_ops
+{
+  ravenscar_thread_target ()
+  { to_stratum = thread_stratum; }
+
+  const char *shortname () override
+  { return "ravenscar"; }
+
+  const char *longname () override
+  { return _("Ravenscar tasks."); }
+
+  const char *doc () override
+  { return _("Ravenscar tasks support."); }
+
+  ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
+  void resume (ptid_t, int, enum gdb_signal) override;
+
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+
+  void prepare_to_store (struct regcache *) override;
+
+  int stopped_by_sw_breakpoint () override;
+
+  int stopped_by_hw_breakpoint () override;
+
+  int stopped_by_watchpoint () override;
+
+  int stopped_data_address (CORE_ADDR *) override;
+
+  int thread_alive (ptid_t ptid) override;
+
+  int core_of_thread (ptid_t ptid) override;
+
+  void update_thread_list () override;
+
+  const char *extra_thread_info (struct thread_info *) override;
+
+  const char *pid_to_str (ptid_t) override;
+
+  ptid_t get_ada_task_ptid (long lwp, long thread) override;
+
+  void mourn_inferior () override;
+
+  int has_all_memory ()  override { return default_child_has_all_memory (); }
+  int has_memory ()  override { return default_child_has_memory (); }
+  int has_stack ()  override { return default_child_has_stack (); }
+  int has_registers ()  override { return default_child_has_registers (); }
+  int has_execution (ptid_t ptid) override
+  { return default_child_has_execution (ptid); }
+};
+
+/* This module's target-specific operations.  */
+static ravenscar_thread_target ravenscar_ops;
+
 static ptid_t ravenscar_active_task (int cpu);
-static const char *ravenscar_extra_thread_info (struct target_ops *self,
-						struct thread_info *tp);
-static int ravenscar_thread_alive (struct target_ops *ops, ptid_t ptid);
-static void ravenscar_fetch_registers (struct target_ops *ops,
-                                       struct regcache *regcache, int regnum);
-static void ravenscar_store_registers (struct target_ops *ops,
-                                       struct regcache *regcache, int regnum);
-static void ravenscar_prepare_to_store (struct target_ops *self,
-					struct regcache *regcache);
-static void ravenscar_resume (struct target_ops *ops, ptid_t ptid, int step,
-			      enum gdb_signal siggnal);
-static void ravenscar_mourn_inferior (struct target_ops *ops);
 static void ravenscar_update_inferior_ptid (void);
 static int has_ravenscar_runtime (void);
 static int ravenscar_runtime_initialized (void);
@@ -281,26 +320,25 @@ get_running_thread_id (int cpu)
   return extract_typed_address (buf, builtin_type_void_data_ptr);
 }
 
-static void
-ravenscar_resume (struct target_ops *ops, ptid_t ptid, int step,
-		  enum gdb_signal siggnal)
+void
+ravenscar_thread_target::resume (ptid_t ptid, int step, enum gdb_signal siggnal)
 {
-  struct target_ops *beneath = find_target_beneath (ops);
+  struct target_ops *beneath = find_target_beneath (this);
 
   inferior_ptid = base_ptid;
-  beneath->to_resume (beneath, base_ptid, step, siggnal);
+  beneath->resume (base_ptid, step, siggnal);
 }
 
-static ptid_t
-ravenscar_wait (struct target_ops *ops, ptid_t ptid,
-                struct target_waitstatus *status,
-                int options)
+ptid_t
+ravenscar_thread_target::wait (ptid_t ptid,
+			       struct target_waitstatus *status,
+			       int options)
 {
-  struct target_ops *beneath = find_target_beneath (ops);
+  struct target_ops *beneath = find_target_beneath (this);
   ptid_t event_ptid;
 
   inferior_ptid = base_ptid;
-  event_ptid = beneath->to_wait (beneath, base_ptid, status, 0);
+  event_ptid = beneath->wait (base_ptid, status, 0);
   /* Find any new threads that might have been created, and update
      inferior_ptid to the active thread.
 
@@ -312,7 +350,7 @@ ravenscar_wait (struct target_ops *ops, ptid_t ptid,
       && status->kind != TARGET_WAITKIND_SIGNALLED)
     {
       inferior_ptid = event_ptid;
-      ravenscar_update_thread_list (ops);
+      this->update_thread_list ();
       ravenscar_update_inferior_ptid ();
     }
   return inferior_ptid;
@@ -328,8 +366,8 @@ ravenscar_add_thread (struct ada_task_info *task)
     add_thread (task->ptid);
 }
 
-static void
-ravenscar_update_thread_list (struct target_ops *ops)
+void
+ravenscar_thread_target::update_thread_list ()
 {
   ada_build_task_list ();
 
@@ -352,21 +390,21 @@ ravenscar_active_task (int cpu)
     return ptid_build (ptid_get_pid (base_ptid), 0, tid);
 }
 
-static const char *
-ravenscar_extra_thread_info (struct target_ops *self, struct thread_info *tp)
+const char *
+ravenscar_thread_target::extra_thread_info (thread_info *tp)
 {
   return "Ravenscar task";
 }
 
-static int
-ravenscar_thread_alive (struct target_ops *ops, ptid_t ptid)
+int
+ravenscar_thread_target::thread_alive (ptid_t ptid)
 {
   /* Ravenscar tasks are non-terminating.  */
   return 1;
 }
 
-static const char *
-ravenscar_pid_to_str (struct target_ops *ops, ptid_t ptid)
+const char *
+ravenscar_thread_target::pid_to_str (ptid_t ptid)
 {
   static char buf[30];
 
@@ -374,11 +412,10 @@ ravenscar_pid_to_str (struct target_ops *ops, ptid_t ptid)
   return buf;
 }
 
-static void
-ravenscar_fetch_registers (struct target_ops *ops,
-                           struct regcache *regcache, int regnum)
+void
+ravenscar_thread_target::fetch_registers (struct regcache *regcache, int regnum)
 {
-  struct target_ops *beneath = find_target_beneath (ops);
+  struct target_ops *beneath = find_target_beneath (this);
   ptid_t ptid = regcache_get_ptid (regcache);
 
   if (ravenscar_runtime_initialized ()
@@ -392,14 +429,14 @@ ravenscar_fetch_registers (struct target_ops *ops,
       arch_ops->to_fetch_registers (regcache, regnum);
     }
   else
-    beneath->to_fetch_registers (beneath, regcache, regnum);
+    beneath->fetch_registers (regcache, regnum);
 }
 
-static void
-ravenscar_store_registers (struct target_ops *ops,
-                           struct regcache *regcache, int regnum)
+void
+ravenscar_thread_target::store_registers (struct regcache *regcache,
+					  int regnum)
 {
-  struct target_ops *beneath = find_target_beneath (ops);
+  target_ops *beneath = find_target_beneath (this);
   ptid_t ptid = regcache_get_ptid (regcache);
 
   if (ravenscar_runtime_initialized ()
@@ -410,17 +447,16 @@ ravenscar_store_registers (struct target_ops *ops,
       struct ravenscar_arch_ops *arch_ops
 	= gdbarch_ravenscar_ops (gdbarch);
 
-      arch_ops->to_store_registers (regcache, regnum);
+      beneath->store_registers (regcache, regnum);
     }
   else
-    beneath->to_store_registers (beneath, regcache, regnum);
+    beneath->store_registers (regcache, regnum);
 }
 
-static void
-ravenscar_prepare_to_store (struct target_ops *self,
-			    struct regcache *regcache)
+void
+ravenscar_thread_target::prepare_to_store (struct regcache *regcache)
 {
-  struct target_ops *beneath = find_target_beneath (self);
+  target_ops *beneath = find_target_beneath (this);
   ptid_t ptid = regcache_get_ptid (regcache);
 
   if (ravenscar_runtime_initialized ()
@@ -431,93 +467,93 @@ ravenscar_prepare_to_store (struct target_ops *self,
       struct ravenscar_arch_ops *arch_ops
 	= gdbarch_ravenscar_ops (gdbarch);
 
-      arch_ops->to_prepare_to_store (regcache);
+      beneath->prepare_to_store (regcache);
     }
   else
-    beneath->to_prepare_to_store (beneath, regcache);
+    beneath->prepare_to_store (regcache);
 }
 
 /* Implement the to_stopped_by_sw_breakpoint target_ops "method".  */
 
-static int
-ravenscar_stopped_by_sw_breakpoint (struct target_ops *ops)
+int
+ravenscar_thread_target::stopped_by_sw_breakpoint ()
 {
   ptid_t saved_ptid = inferior_ptid;
-  struct target_ops *beneath = find_target_beneath (ops);
+  struct target_ops *beneath = find_target_beneath (this);
   int result;
 
   inferior_ptid = get_base_thread_from_ravenscar_task (saved_ptid);
-  result = beneath->to_stopped_by_sw_breakpoint (beneath);
+  result = beneath->stopped_by_sw_breakpoint ();
   inferior_ptid = saved_ptid;
   return result;
 }
 
 /* Implement the to_stopped_by_hw_breakpoint target_ops "method".  */
 
-static int
-ravenscar_stopped_by_hw_breakpoint (struct target_ops *ops)
+int
+ravenscar_thread_target::stopped_by_hw_breakpoint ()
 {
   ptid_t saved_ptid = inferior_ptid;
-  struct target_ops *beneath = find_target_beneath (ops);
+  struct target_ops *beneath = find_target_beneath (this);
   int result;
 
   inferior_ptid = get_base_thread_from_ravenscar_task (saved_ptid);
-  result = beneath->to_stopped_by_hw_breakpoint (beneath);
+  result = beneath->stopped_by_hw_breakpoint ();
   inferior_ptid = saved_ptid;
   return result;
 }
 
 /* Implement the to_stopped_by_watchpoint target_ops "method".  */
 
-static int
-ravenscar_stopped_by_watchpoint (struct target_ops *ops)
+int
+ravenscar_thread_target::stopped_by_watchpoint ()
 {
   ptid_t saved_ptid = inferior_ptid;
-  struct target_ops *beneath = find_target_beneath (ops);
+  struct target_ops *beneath = find_target_beneath (this);
   int result;
 
   inferior_ptid = get_base_thread_from_ravenscar_task (saved_ptid);
-  result = beneath->to_stopped_by_watchpoint (beneath);
+  result = beneath->stopped_by_watchpoint ();
   inferior_ptid = saved_ptid;
   return result;
 }
 
 /* Implement the to_stopped_data_address target_ops "method".  */
 
-static int
-ravenscar_stopped_data_address (struct target_ops *ops, CORE_ADDR *addr_p)
+int
+ravenscar_thread_target::stopped_data_address (CORE_ADDR *addr_p)
 {
   ptid_t saved_ptid = inferior_ptid;
-  struct target_ops *beneath = find_target_beneath (ops);
+  struct target_ops *beneath = find_target_beneath (this);
   int result;
 
   inferior_ptid = get_base_thread_from_ravenscar_task (saved_ptid);
-  result = beneath->to_stopped_data_address (beneath, addr_p);
+  result = beneath->stopped_data_address (addr_p);
   inferior_ptid = saved_ptid;
   return result;
 }
 
-static void
-ravenscar_mourn_inferior (struct target_ops *ops)
+void
+ravenscar_thread_target::mourn_inferior ()
 {
-  struct target_ops *beneath = find_target_beneath (ops);
+  struct target_ops *beneath = find_target_beneath (this);
 
   base_ptid = null_ptid;
-  beneath->to_mourn_inferior (beneath);
+  beneath->mourn_inferior ();
   unpush_target (&ravenscar_ops);
 }
 
 /* Implement the to_core_of_thread target_ops "method".  */
 
-static int
-ravenscar_core_of_thread (struct target_ops *ops, ptid_t ptid)
+int
+ravenscar_thread_target::core_of_thread (ptid_t ptid)
 {
   ptid_t saved_ptid = inferior_ptid;
-  struct target_ops *beneath = find_target_beneath (ops);
+  struct target_ops *beneath = find_target_beneath (this);
   int result;
 
   inferior_ptid = get_base_thread_from_ravenscar_task (saved_ptid);
-  result = beneath->to_core_of_thread (beneath, inferior_ptid);
+  result = beneath->core_of_thread (inferior_ptid);
   inferior_ptid = saved_ptid;
   return result;
 }
@@ -545,45 +581,12 @@ ravenscar_inferior_created (struct target_ops *target, int from_tty)
   push_target (&ravenscar_ops);
 }
 
-static ptid_t
-ravenscar_get_ada_task_ptid (struct target_ops *self, long lwp, long thread)
+ptid_t
+ravenscar_thread_target::get_ada_task_ptid (long lwp, long thread)
 {
   return ptid_build (ptid_get_pid (base_ptid), 0, thread);
 }
 
-static void
-init_ravenscar_thread_ops (void)
-{
-  ravenscar_ops.to_shortname = "ravenscar";
-  ravenscar_ops.to_longname = "Ravenscar tasks.";
-  ravenscar_ops.to_doc = "Ravenscar tasks support.";
-  ravenscar_ops.to_resume = ravenscar_resume;
-  ravenscar_ops.to_wait = ravenscar_wait;
-  ravenscar_ops.to_fetch_registers = ravenscar_fetch_registers;
-  ravenscar_ops.to_store_registers = ravenscar_store_registers;
-  ravenscar_ops.to_prepare_to_store = ravenscar_prepare_to_store;
-  ravenscar_ops.to_stopped_by_sw_breakpoint
-    = ravenscar_stopped_by_sw_breakpoint;
-  ravenscar_ops.to_stopped_by_hw_breakpoint
-    = ravenscar_stopped_by_hw_breakpoint;
-  ravenscar_ops.to_stopped_by_watchpoint = ravenscar_stopped_by_watchpoint;
-  ravenscar_ops.to_stopped_data_address = ravenscar_stopped_data_address;
-  ravenscar_ops.to_thread_alive = ravenscar_thread_alive;
-  ravenscar_ops.to_update_thread_list = ravenscar_update_thread_list;
-  ravenscar_ops.to_pid_to_str = ravenscar_pid_to_str;
-  ravenscar_ops.to_extra_thread_info = ravenscar_extra_thread_info;
-  ravenscar_ops.to_get_ada_task_ptid = ravenscar_get_ada_task_ptid;
-  ravenscar_ops.to_mourn_inferior = ravenscar_mourn_inferior;
-  ravenscar_ops.to_has_all_memory = default_child_has_all_memory;
-  ravenscar_ops.to_has_memory = default_child_has_memory;
-  ravenscar_ops.to_has_stack = default_child_has_stack;
-  ravenscar_ops.to_has_registers = default_child_has_registers;
-  ravenscar_ops.to_has_execution = default_child_has_execution;
-  ravenscar_ops.to_stratum = thread_stratum;
-  ravenscar_ops.to_core_of_thread = ravenscar_core_of_thread;
-  ravenscar_ops.to_magic = OPS_MAGIC;
-}
-
 /* Command-list for the "set/show ravenscar" prefix command.  */
 static struct cmd_list_element *set_ravenscar_list;
 static struct cmd_list_element *show_ravenscar_list;
@@ -627,15 +630,12 @@ Support for Ravenscar task/thread switching is disabled\n"));
 void
 _initialize_ravenscar (void)
 {
-  init_ravenscar_thread_ops ();
   base_ptid = null_ptid;
 
   /* Notice when the inferior is created in order to push the
      ravenscar ops if needed.  */
   gdb::observers::inferior_created.attach (ravenscar_inferior_created);
 
-  complete_target_initialization (&ravenscar_ops);
-
   add_prefix_cmd ("ravenscar", no_class, set_ravenscar_command,
                   _("Prefix command for changing Ravenscar-specific settings"),
                   &set_ravenscar_list, "set ravenscar ", 0, &setlist);
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 29/40] target_ops/C++: Tile-Gx GNU/Linux
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (5 preceding siblings ...)
  2018-04-14 19:10 ` [PATCH 32/40] target_ops/C++: Generic i386/AMD64 BSD targets Pedro Alves
@ 2018-04-14 19:10 ` Pedro Alves
  2018-04-14 19:10 ` [PATCH 08/40] target_ops/C++: bsd-uthread Pedro Alves
                   ` (34 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:10 UTC (permalink / raw)
  To: gdb-patches

Straighforward conversion.  Not tested.
---
 gdb/tilegx-linux-nat.c | 34 +++++++++++++++++-----------------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/gdb/tilegx-linux-nat.c b/gdb/tilegx-linux-nat.c
index d7c14f0565..0df98e6ffc 100644
--- a/gdb/tilegx-linux-nat.c
+++ b/gdb/tilegx-linux-nat.c
@@ -34,6 +34,16 @@
 /* Prototypes for supply_gregset etc.  */
 #include "gregset.h"
 
+class tilegx_linux_nat_target final : public linux_nat_target
+{
+public:
+  /* Add our register access methods.  */
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+};
+
+static tilegx_linux_nat_target the_tilegx_linux_nat_target;
+
 /* The register sets used in GNU/Linux ELF core-dumps are identical to
    the register sets in `struct user' that is used for a.out
    core-dumps, and is also used by `ptrace'.  The corresponding types
@@ -122,9 +132,9 @@ fill_fpregset (const struct regcache *regcache,
 /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
    for all registers.  */
 
-static void
-fetch_inferior_registers (struct target_ops *ops,
-			  struct regcache *regcache, int regnum)
+void
+tilegx_linux_nat_target::fetch_registers (struct regcache *regcache,
+					  int regnum)
 {
   elf_gregset_t regs;
   pid_t tid = get_ptrace_pid (regcache_get_ptid (regcache));
@@ -138,9 +148,9 @@ fetch_inferior_registers (struct target_ops *ops,
 /* Store register REGNUM back into the inferior.  If REGNUM is -1, do
    this for all registers.  */
 
-static void
-store_inferior_registers (struct target_ops *ops,
-			  struct regcache *regcache, int regnum)
+void
+tilegx_linux_nat_target::store_registers (struct regcache *regcache,
+					  int regnum)
 {
   elf_gregset_t regs;
   pid_t tid = get_ptrace_pid (regcache_get_ptid (regcache));
@@ -157,15 +167,5 @@ store_inferior_registers (struct target_ops *ops,
 void
 _initialize_tile_linux_nat (void)
 {
-  struct target_ops *t;
-
-  /* Fill in the generic GNU/Linux methods.  */
-  t = linux_target ();
-
-  /* Add our register access methods.  */
-  t->to_fetch_registers = fetch_inferior_registers;
-  t->to_store_registers = store_inferior_registers;
-
-  /* Register the target.  */
-  linux_nat_add_target (t);
+  add_target (&the_tilegx_linux_nat_target);
 }
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 34/40] target_ops/C++: bsd_kvm_add_target, BSD libkvm target
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (14 preceding siblings ...)
  2018-04-14 19:10 ` [PATCH 09/40] target_ops/C++: bfd-target Pedro Alves
@ 2018-04-14 19:10 ` Pedro Alves
  2018-04-14 19:10 ` [PATCH 23/40] target_ops/C++: IA-64 GNU/Linux Pedro Alves
                   ` (25 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:10 UTC (permalink / raw)
  To: gdb-patches

Straightforward conversion.

I considered making bsd_kvm_supply_pcb a virtual method, and then have
each port inherit bsd_kvm_target and override that method, but that
was resulting in lots of unjustified churn, so I left the function
pointer mechanism alone.
---
 gdb/bsd-kvm.c | 103 +++++++++++++++++++++++++++++++++-------------------------
 1 file changed, 59 insertions(+), 44 deletions(-)

diff --git a/gdb/bsd-kvm.c b/gdb/bsd-kvm.c
index 8edc026fd3..f6b7ad15db 100644
--- a/gdb/bsd-kvm.c
+++ b/gdb/bsd-kvm.c
@@ -56,16 +56,56 @@ static struct pcb *bsd_kvm_paddr;
    register state from PCB and supplies it to REGCACHE.  */
 static int (*bsd_kvm_supply_pcb)(struct regcache *regcache, struct pcb *pcb);
 
-/* Target ops for libkvm interface.  */
-static struct target_ops bsd_kvm_ops;
-
 /* This is the ptid we use while we're connected to kvm.  The kvm
    target currently doesn't export any view of the running processes,
    so this represents the kernel task.  */
 static ptid_t bsd_kvm_ptid;
 
+/* The libkvm target.  */
+
+class bsd_kvm_target : public target_ops
+{
+public:
+  bsd_kvm_target ()
+  { this->to_stratum = process_stratum; }
+
+  const char *shortname () override
+  { return "kvm"; }
+
+  const char *longname () override
+  { return _("Kernel memory interface"); }
+
+  const char *doc () override
+  {
+    return _("Use a kernel virtual memory image as a target.\n\
+Optionally specify the filename of a core dump.");
+  }
+
+  void open (const char *, int) override;
+  void close () override;
+
+  void fetch_registers (struct regcache *, int) override;
+  enum target_xfer_status xfer_partial (enum target_object object,
+					const char *annex,
+					gdb_byte *readbuf,
+					const gdb_byte *writebuf,
+					ULONGEST offset, ULONGEST len,
+					ULONGEST *xfered_len) override;
+
+  void files_info () override;
+  int thread_alive (ptid_t ptid) override;
+  const char *pid_to_str (ptid_t) override;
+
+  int has_memory () override { return 1; }
+  int has_stack () override { return 1; }
+  int has_registers () override { return 1; }
+};
+
+/* Target ops for libkvm interface.  */
+static bsd_kvm_target bsd_kvm_ops;
+
 static void
-bsd_kvm_open (const char *arg, int from_tty)
+bsd_kvm_target::open (const char *arg, int from_tty)
 {
   char errbuf[_POSIX2_LINE_MAX];
   char *execfile = NULL;
@@ -107,8 +147,8 @@ bsd_kvm_open (const char *arg, int from_tty)
   print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC, 1);
 }
 
-static void
-bsd_kvm_close (struct target_ops *self)
+void
+bsd_kvm_target::close ()
 {
   if (core_kd)
     {
@@ -134,11 +174,11 @@ bsd_kvm_xfer_memory (CORE_ADDR addr, ULONGEST len,
   return nbytes;
 }
 
-static enum target_xfer_status
-bsd_kvm_xfer_partial (struct target_ops *ops, enum target_object object,
-		      const char *annex, gdb_byte *readbuf,
-		      const gdb_byte *writebuf,
-		      ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
+enum target_xfer_status
+bsd_kvm_target::xfer_partial (enum target_object object,
+			      const char *annex, gdb_byte *readbuf,
+			      const gdb_byte *writebuf,
+			      ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
 {
   switch (object)
     {
@@ -162,8 +202,8 @@ bsd_kvm_xfer_partial (struct target_ops *ops, enum target_object object,
     }
 }
 
-static void
-bsd_kvm_files_info (struct target_ops *ops)
+void
+bsd_kvm_target::files_info ()
 {
   if (bsd_kvm_corefile && strcmp (bsd_kvm_corefile, _PATH_MEM) != 0)
     printf_filtered (_("\tUsing the kernel crash dump %s.\n"),
@@ -186,9 +226,8 @@ bsd_kvm_fetch_pcb (struct regcache *regcache, struct pcb *paddr)
   return bsd_kvm_supply_pcb (regcache, &pcb);
 }
 
-static void
-bsd_kvm_fetch_registers (struct target_ops *ops,
-			 struct regcache *regcache, int regnum)
+void
+bsd_kvm_target::fetch_registers (struct regcache *regcache, int regnum)
 {
   struct nlist nl[2];
 
@@ -325,27 +364,20 @@ bsd_kvm_pcb_cmd (const char *arg, int fromtty)
   print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC, 1);
 }
 
-static int
-bsd_kvm_thread_alive (struct target_ops *ops,
-		      ptid_t ptid)
+int
+bsd_kvm_target::thread_alive (ptid_t ptid)
 {
   return 1;
 }
 
-static const char *
-bsd_kvm_pid_to_str (struct target_ops *ops, ptid_t ptid)
+const char *
+bsd_kvm_target::pid_to_str (ptid_t ptid)
 {
   static char buf[64];
   xsnprintf (buf, sizeof buf, "<kvm>");
   return buf;
 }
 
-static int
-bsd_kvm_return_one (struct target_ops *ops)
-{
-  return 1;
-}
-
 /* Add the libkvm interface to the list of all possible targets and
    register CUPPLY_PCB as the architecture-specific process control
    block interpreter.  */
@@ -356,23 +388,6 @@ bsd_kvm_add_target (int (*supply_pcb)(struct regcache *, struct pcb *))
   gdb_assert (bsd_kvm_supply_pcb == NULL);
   bsd_kvm_supply_pcb = supply_pcb;
 
-  bsd_kvm_ops.to_shortname = "kvm";
-  bsd_kvm_ops.to_longname = _("Kernel memory interface");
-  bsd_kvm_ops.to_doc = _("Use a kernel virtual memory image as a target.\n\
-Optionally specify the filename of a core dump.");
-  bsd_kvm_ops.to_open = bsd_kvm_open;
-  bsd_kvm_ops.to_close = bsd_kvm_close;
-  bsd_kvm_ops.to_fetch_registers = bsd_kvm_fetch_registers;
-  bsd_kvm_ops.to_xfer_partial = bsd_kvm_xfer_partial;
-  bsd_kvm_ops.to_files_info = bsd_kvm_files_info;
-  bsd_kvm_ops.to_thread_alive = bsd_kvm_thread_alive;
-  bsd_kvm_ops.to_pid_to_str = bsd_kvm_pid_to_str;
-  bsd_kvm_ops.to_stratum = process_stratum;
-  bsd_kvm_ops.to_has_memory = bsd_kvm_return_one;
-  bsd_kvm_ops.to_has_stack = bsd_kvm_return_one;
-  bsd_kvm_ops.to_has_registers = bsd_kvm_return_one;
-  bsd_kvm_ops.to_magic = OPS_MAGIC;
-
   add_target (&bsd_kvm_ops);
   
   add_prefix_cmd ("kvm", class_obscure, bsd_kvm_cmd, _("\
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 40/40] target factories, target open and multiple instances of targets
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (8 preceding siblings ...)
  2018-04-14 19:10 ` [PATCH 19/40] target_ops/C++: AIX target Pedro Alves
@ 2018-04-14 19:10 ` Pedro Alves
  2018-04-14 19:10 ` [PATCH 27/40] target_ops/C++: SPARC GNU/Linux Pedro Alves
                   ` (31 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:10 UTC (permalink / raw)
  To: gdb-patches

Currently, to open a target, with "target TARGET_NAME", GDB finds the
target_ops instance with "TARGET_NAME" as short name, and then calls
its target_ops::open virtual method.  In reality, there's no actual
target/name lookup, a pointer to the target_ops object was associated
with the "target TARGET_NAME" command at add_target time (when GDB is
initialized), as the command's context.

This creates a chicken and egg situation.  Consider the case of
wanting to open multiple remote connections.  We want to be able to
have one remote target_ops instance per connection, but, if we're not
connected yet, so we don't yet have an instance to call target->open()
on...

This patch fixes this by separating out common info about a target_ops
to a separate structure (shortname, longname, doc), and changing the
add_target routine to take a reference to such an object instead of a
pointer to a target_ops, and a pointer to a factory function that is
responsible to open an instance of the corresponding target when the
user types "target TARGET_NAME".

 -extern void add_target (struct target_ops *);
 +extern void add_target (const target_info &info, target_open_ftype *func);

I.e. this factory function replaces the target_ops::open virtual
method.

For static/singleton targets, nothing changes, the target_open_ftype
function pushes the global target_ops instance on the target stack.
At target_close time, the connection is tor down, but the global
target_ops object remains live.

However, targets that support being open multiple times will make
their target_open_ftype routine allocate a new target_ops instance on
the heap [e.g., new remote_target()], and push that on the stack.  At
target_close time, the new object is destroyed (by the
target_ops::close virtual method).

Both the core target and the remote targets will support being open
multiple times (others could/should too, but those were my stopping
point), but not in this patch yet.  We need to get rid of more globals
first before that'd be useful.

Native targets are somewhat special, given find_default_run_target &
friends.  Those routines also expect to return a target_ops pointer,
even before we've open the target.  However, we'll never need more
than one instance of the native target, so we can assume/require that
native targets are global/simpletons, and have the backends register a
pointer to the native target_ops.  Since all native targets inherit
inf_child_target, we can centralize that registration.  See
add_inf_child_target, get_native_target/set_native_target and
find_default_run_target.

gdb/ChangeLog:
yyyy-mm-dd  Pedro Alves  <palves@redhat.com>

	* aarch64-fbsd-nat.c (_initialize_aarch64_fbsd_nat): Use
	add_inf_child_target.
	* aarch64-linux-nat.c (_initialize_aarch64_linux_nat): Use
	add_inf_child_target.
	* aix-thread.c (aix_thread_target_info): New.
	(aix_thread_target) <shortname, longname, doc>: Delete.
	<info>: New.
	* alpha-bsd-nat.c (_initialize_alphabsd_nat): Use
	add_inf_child_target.
	* alpha-linux-nat.c (_initialize_alpha_linux_nat): Use
	add_inf_child_target.
	* amd64-linux-nat.c (_initialize_amd64_linux_nat): Use
	add_inf_child_target.
	* amd64-nbsd-nat.c (_initialize_amd64nbsd_nat): Use
	add_inf_child_target.
	* amd64-obsd-nat.c (_initialize_amd64obsd_nat): Use
	add_inf_child_target.
	* arm-fbsd-nat.c (_initialize_arm_fbsd_nat): Use
	add_inf_child_target.
	* arm-linux-nat.c (_initialize_arm_linux_nat): Use
	add_inf_child_target.
	* arm-nbsd-nat.c (_initialize_arm_netbsd_nat): Use
	add_inf_child_target.
	* bfd-target.c (target_bfd_target_info): New.
	(target_bfd) <shortname, longname, doc>: Delete.
	<info>: New.
	* bsd-kvm.c (bsd_kvm_target_info): New.
	(bsd_kvm_target) <shortname, longname, doc>: Delete.
	<info>: New.
	(bsd_kvm_target::open): Rename to ...
	(bsd_kvm_target_open): ... this.  Adjust.
	* bsd-uthread.c (bsd_uthread_target_info): New.
	(bsd_uthread_target) <shortname, longname, doc>: Delete.
	<info>:	New.
	* corefile.c (core_file_command): Adjust.
	* corelow.c (core_target_info): New.
	(core_target) <shortname, longname, doc>: Delete.
	<info>: New.
	(core_target::open): Rename to ...
	(core_target_open): ... this.  Adjust.
	* ctf.c (ctf_target_info): New.
	(ctf_target) <shortname, longname, doc>: Delete.
	<info>:	New.
	(ctf_target::open): Rename to ...
	(ctf_target_open): ... this.
	(_initialize_ctf): Adjust.
	* exec.c (exec_target_info): New.
	(exec_target) <shortname, longname, doc>: Delete.
	<info>:	New.
	(exec_target::open): Rename to ...
	(exec_target_open): ... this.
	* gdbcore.h (core_target_open): Declare.
	* go32-nat.c (_initialize_go32_nat): Use add_inf_child_target.
	* hppa-linux-nat.c (_initialize_hppa_linux_nat): Use
	add_inf_child_target.
	* hppa-nbsd-nat.c (_initialize_hppanbsd_nat): Use
	add_inf_child_target.
	* hppa-obsd-nat.c (_initialize_hppaobsd_nat): Use
	add_inf_child_target.
	* i386-darwin-nat.c (_initialize_i386_darwin_nat): Use
	add_inf_child_target.
	* i386-fbsd-nat.c (_initialize_i386fbsd_nat): Use
	add_inf_child_target.
	* i386-gnu-nat.c (_initialize_i386gnu_nat): Use
	add_inf_child_target.
	* i386-linux-nat.c (_initialize_i386_linux_nat): Use
	add_inf_child_target.
	* i386-nbsd-nat.c (_initialize_i386nbsd_nat): Use
	add_inf_child_target.
	* i386-obsd-nat.c (_initialize_i386obsd_nat): Use
	add_inf_child_target.
	* ia64-linux-nat.c (_initialize_ia64_linux_nat): Use
	add_inf_child_target.
	* inf-child.c (inf_child_target_info): New.
	(inf_child_target::info): New.
	(inf_child_open_target): Remove 'target' parameter.  Use
	get_native_target instead.
	(inf_child_target::open): Delete.
	(add_inf_child_target): New.
	* inf-child.h (inf_child_target) <shortname, longname, doc, open>:
	Delete.
	<info>:	New.
	(add_inf_child_target): Declare.
	(inf_child_open_target): Declare.
	* linux-thread-db.c (thread_db_target_info): New.
	(thread_db_target) <shortname, longname, doc>: Delete.
	<info>:	New.
	* m32r-linux-nat.c (_initialize_m32r_linux_nat): Use
	add_inf_child_target.
	* m68k-bsd-nat.c (_initialize_m68kbsd_nat): Use
	add_inf_child_target.
	* m68k-linux-nat.c (_initialize_m68k_linux_nat): Use
	add_inf_child_target.
	* m88k-bsd-nat.c (_initialize_m88kbsd_nat): Use
	add_inf_child_target.
	* make-target-delegates (print_class): Adjust.
	* mips-fbsd-nat.c (_initialize_mips_fbsd_nat): Use
	add_inf_child_target.
	* mips-linux-nat.c (_initialize_mips_linux_nat): Use
	add_inf_child_target.
	* mips-nbsd-nat.c (_initialize_mipsnbsd_nat): Use
	add_inf_child_target.
	* mips64-obsd-nat.c (_initialize_mips64obsd_nat): Use
	add_inf_child_target.
	* nto-procfs.c (nto_native_target_info): New.
	(nto_procfs_target_native) <shortname, longname, doc>:
	Delete.
	<info>:	New.
	(nto_procfs_target_info): New.
	(nto_procfs_target_procfs) <shortname, longname, doc>:
	Delete.
	<info>:	New.
	(init_procfs_targets): Adjust.
	* ppc-fbsd-nat.c (_initialize_ppcfbsd_nat): Use
	add_inf_child_target.
	* ppc-linux-nat.c (_initialize_ppc_linux_nat): Use
	add_inf_child_target.
	* ppc-nbsd-nat.c (_initialize_ppcnbsd_nat): Use
	add_inf_child_target.
	* ppc-obsd-nat.c (_initialize_ppcobsd_nat): Use
	add_inf_child_target.
	* ravenscar-thread.c (ravenscar_target_info): New.
	(ravenscar_thread_target) <shortname, longname, doc>:
	Delete.
	<info>:	New.
	* record-btrace.c (record_btrace_target_info):
	(record_btrace_target) <shortname, longname, doc>: Delete.
	<info>: New.
	(record_btrace_target::open): Rename to ...
	(record_btrace_target_open): ... this.  Adjust.
	* record-full.c (record_longname, record_doc): New.
	(record_full_base_target) <shortname, longname, doc>: Delete.
	<info>: New.
	(record_full_target_info): New.
	(record_full_target): <shortname>: Delete.
	<info>: New.
	(record_full_core_open_1, record_full_open_1): Update comments.
	(record_full_base_target::open): Rename to ...
	(record_full_open): ... this.
	(cmd_record_full_restore): Update.
	(_initialize_record_full): Update.
	* remote-sim.c (remote_sim_target_info): New.
	(gdbsim_target) <shortname, longname, doc>: Delete.
	<info>: New.
	(gdbsim_target::open): Rename to ...
	(gdbsim_target_open): ... this.
	(_initialize_remote_sim): Adjust.
	* remote.c (remote_doc): New.
	(remote_target_info): New.
	(remote_target) <shortname, longname, doc>: Delete.
	<info>: New.
	(extended_remote_target_info): New.
	(extended_remote_target) <shortname, longname, doc>: Delete.
	<info>: New.
	(remote_target::open_1): Make static.  Adjust.
	* rs6000-nat.c (_initialize_rs6000_nat): Use add_inf_child_target.
	* s390-linux-nat.c (_initialize_s390_nat): Use
	add_inf_child_target.
	* sh-nbsd-nat.c (_initialize_shnbsd_nat): Use
	add_inf_child_target.
	* sol-thread.c (thread_db_target_info): New.
	(sol_thread_target) <shortname, longname, doc>: Delete.
	<info>: New.
	* sparc-linux-nat.c (_initialize_sparc_linux_nat): Use
	add_inf_child_target.
	* sparc-nbsd-nat.c (_initialize_sparcnbsd_nat): Use
	add_inf_child_target.
	* sparc64-fbsd-nat.c (_initialize_sparc64fbsd_nat): Use
	add_inf_child_target.
	* sparc64-linux-nat.c (_initialize_sparc64_linux_nat): Use
	add_inf_child_target.
	* sparc64-nbsd-nat.c (_initialize_sparc64nbsd_nat): Use
	add_inf_child_target.
	* sparc64-obsd-nat.c (_initialize_sparc64obsd_nat): Use
	add_inf_child_target.
	* spu-linux-nat.c (_initialize_spu_nat): Use
	add_inf_child_target.
	* spu-multiarch.c (spu_multiarch_target_info): New.
	(spu_multiarch_target) <shortname, longname, doc>: Delete.
	<info>: New.
	* target-delegates.c: Regenerate.
	* target.c: Include <unordered_map>.
	(target_ops_p): Delete.
	(DEF_VEC_P(target_ops_p)): Delete.
	(target_factories): New.
	(test_target_info): New.
	(test_target_ops::info): New.
	(open_target): Adjust to use target_factories.
	(add_target_with_completer): Rename to ...
	(add_target): ... this.  Change prototype.  Register target_info
	and open callback in target_factories.  Register target_info in
	command context instead of target_ops.
	(add_target): Delete old implementation.
	(add_deprecated_target_alias): Change prototype.  Adjust.
	(the_native_target): New.
	(set_native_target, get_native_target): New.
	(find_default_run_target): Use the_native_target.
	(find_attach_target, find_run_target): Simplify.
	(target_ops::open): Delete.
	(dummy_target_info): New.
	(dummy_target::shortname, dummy_target::longname)
	(dummy_target::doc): Delete.
	(dummy_target::info): New.
	(debug_target::shortname, debug_target::longname)
	(debug_target::doc): Delete.
	(debug_target::info): New.
	* target.h (struct target_info): New.
	(target_ops::~target_ops): Add comment.
	(target_ops::info): New.
	(target_ops::shortname, target_ops::longname, target_ops::doc): No
	longer virtual.  Implement in terms of target_info.
	(set_native_target, get_native_target): Declare.
	(target_open_ftype): New.
	(add_target, add_target_with_completer)
	(add_deprecated_target_alias): Change prototype.
	(test_target) <shortname, longname, doc>: Delete.
	<info>: New.
	* tilegx-linux-nat.c (_initialize_tile_linux_nat): Use
	add_inf_child_target.
	* tracefile-tfile.c (tfile_target_info): New.
	(tfile_target) <shortname, longname, doc>: Delete.
	<info>: New.
	(tfile_target::open): Rename to ...
	(tfile_target_open): ... this.
	(_initialize_tracefile_tfile): Adjust.
	* vax-bsd-nat.c (_initialize_vaxbsd_nat): Use
	add_inf_child_target.
	* windows-nat.c (_initialize_windows_nat): Use
	add_inf_child_target.
	* xtensa-linux-nat.c (_initialize_xtensa_linux_nat): Use
	add_inf_child_target.
---
 gdb/aarch64-fbsd-nat.c    |   2 +-
 gdb/aarch64-linux-nat.c   |   4 +-
 gdb/aix-thread.c          |  14 ++--
 gdb/alpha-bsd-nat.c       |   2 +-
 gdb/alpha-linux-nat.c     |   2 +-
 gdb/amd64-linux-nat.c     |   2 +-
 gdb/amd64-nbsd-nat.c      |   2 +-
 gdb/amd64-obsd-nat.c      |   2 +-
 gdb/arm-fbsd-nat.c        |   2 +-
 gdb/arm-linux-nat.c       |   4 +-
 gdb/arm-nbsd-nat.c        |   2 +-
 gdb/bfd-target.c          |  17 ++--
 gdb/bsd-kvm.c             |  25 +++---
 gdb/bsd-uthread.c         |  16 ++--
 gdb/corefile.c            |  10 ++-
 gdb/corelow.c             |  26 +++---
 gdb/ctf.c                 |  28 +++----
 gdb/exec.c                |  28 +++----
 gdb/gdbcore.h             |   4 +
 gdb/go32-nat.c            |   2 +-
 gdb/hppa-linux-nat.c      |   2 +-
 gdb/hppa-nbsd-nat.c       |   2 +-
 gdb/hppa-obsd-nat.c       |   2 +-
 gdb/i386-darwin-nat.c     |   2 +-
 gdb/i386-fbsd-nat.c       |   2 +-
 gdb/i386-gnu-nat.c        |   2 +-
 gdb/i386-linux-nat.c      |   2 +-
 gdb/i386-nbsd-nat.c       |   2 +-
 gdb/i386-obsd-nat.c       |   2 +-
 gdb/ia64-linux-nat.c      |   4 +-
 gdb/inf-child.c           |  36 +++++++--
 gdb/inf-child.h           |  19 ++---
 gdb/linux-thread-db.c     |  14 ++--
 gdb/m32r-linux-nat.c      |   2 +-
 gdb/m68k-bsd-nat.c        |   2 +-
 gdb/m68k-linux-nat.c      |   2 +-
 gdb/m88k-bsd-nat.c        |   2 +-
 gdb/make-target-delegates |   4 +-
 gdb/mips-fbsd-nat.c       |   2 +-
 gdb/mips-linux-nat.c      |   2 +-
 gdb/mips-nbsd-nat.c       |   2 +-
 gdb/mips64-obsd-nat.c     |   2 +-
 gdb/nto-procfs.c          |  38 +++++----
 gdb/ppc-fbsd-nat.c        |   2 +-
 gdb/ppc-linux-nat.c       |   2 +-
 gdb/ppc-nbsd-nat.c        |   2 +-
 gdb/ppc-obsd-nat.c        |   2 +-
 gdb/ravenscar-thread.c    |  16 ++--
 gdb/record-btrace.c       |  25 +++---
 gdb/record-full.c         |  52 +++++++-----
 gdb/remote-sim.c          |  23 +++---
 gdb/remote.c              |  59 ++++++++------
 gdb/rs6000-nat.c          |   2 +-
 gdb/s390-linux-nat.c      |   4 +-
 gdb/sh-nbsd-nat.c         |   2 +-
 gdb/sol-thread.c          |  14 ++--
 gdb/sparc-linux-nat.c     |   2 +-
 gdb/sparc-nbsd-nat.c      |   2 +-
 gdb/sparc64-fbsd-nat.c    |   4 +-
 gdb/sparc64-linux-nat.c   |   4 +-
 gdb/sparc64-nbsd-nat.c    |   2 +-
 gdb/sparc64-obsd-nat.c    |   2 +-
 gdb/spu-linux-nat.c       |   2 +-
 gdb/spu-multiarch.c       |  16 ++--
 gdb/target-delegates.c    |   8 +-
 gdb/target.c              | 202 +++++++++++++++++++++-------------------------
 gdb/target.h              |  89 ++++++++++++--------
 gdb/tilegx-linux-nat.c    |   2 +-
 gdb/tracefile-tfile.c     |  28 +++----
 gdb/vax-bsd-nat.c         |   2 +-
 gdb/windows-nat.c         |   2 +-
 gdb/xtensa-linux-nat.c    |   2 +-
 72 files changed, 470 insertions(+), 447 deletions(-)

diff --git a/gdb/aarch64-fbsd-nat.c b/gdb/aarch64-fbsd-nat.c
index 5ffbf1fdb1..a50656353c 100644
--- a/gdb/aarch64-fbsd-nat.c
+++ b/gdb/aarch64-fbsd-nat.c
@@ -128,5 +128,5 @@ aarch64_fbsd_nat_target::store_registers (struct regcache *regcache,
 void
 _initialize_aarch64_fbsd_nat (void)
 {
-  add_target (&the_aarch64_fbsd_nat_target);
+  add_inf_child_target (&the_aarch64_fbsd_nat_target);
 }
diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
index 724ca9c3ff..5d46ccc70e 100644
--- a/gdb/aarch64-linux-nat.c
+++ b/gdb/aarch64-linux-nat.c
@@ -837,10 +837,8 @@ triggers a breakpoint or watchpoint."),
 void
 _initialize_aarch64_linux_nat (void)
 {
-  struct target_ops *t = &the_aarch64_linux_nat_target;
-
   add_show_debug_regs_command ();
 
   /* Register the target.  */
-  add_target (t);
+  add_inf_child_target (&the_aarch64_linux_nat_target);
 }
diff --git a/gdb/aix-thread.c b/gdb/aix-thread.c
index 410fb55e72..d328bdd872 100644
--- a/gdb/aix-thread.c
+++ b/gdb/aix-thread.c
@@ -108,18 +108,20 @@ struct pd_thread {
 
 /* This module's target-specific operations, active while pd_able is true.  */
 
+static const target_info aix_thread_target_info = {
+  "aix-threads",
+  N_("AIX pthread support"),
+  N_("AIX pthread support")
+};
+
 class aix_thread_target final : public target_ops
 {
 public:
   aix_thread_target ()
   { to_stratum = thread_stratum; }
 
-  const char *shortname () override
-  { return "aix-threads"; }
-  const char *longname () override
-  { return _("AIX pthread support"); }
-  const char *doc () override
-  { return _("AIX pthread support"); }
+  const target_info &info () const override
+  { return aix_thread_target_info; }
 
   void detach (inferior *, int) override;
   void resume (ptid_t, int, enum gdb_signal) override;
diff --git a/gdb/alpha-bsd-nat.c b/gdb/alpha-bsd-nat.c
index 5dc7a32235..5acc74611d 100644
--- a/gdb/alpha-bsd-nat.c
+++ b/gdb/alpha-bsd-nat.c
@@ -196,7 +196,7 @@ alphabsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
 void
 _initialize_alphabsd_nat (void)
 {
-  add_target (&the_alpha_bsd_nat_target);
+  add_inf_child_target (&the_alpha_bsd_nat_target);
 
   /* Support debugging kernel virtual memory images.  */
   bsd_kvm_add_target (alphabsd_supply_pcb);
diff --git a/gdb/alpha-linux-nat.c b/gdb/alpha-linux-nat.c
index 70997e5f4a..4286db3318 100644
--- a/gdb/alpha-linux-nat.c
+++ b/gdb/alpha-linux-nat.c
@@ -103,5 +103,5 @@ alpha_linux_nat_target::register_u_offset (struct gdbarch *gdbarch,
 void
 _initialize_alpha_linux_nat (void)
 {
-  add_target (&the_alpha_linux_nat_target);
+  add_inf_child_target (&the_alpha_linux_nat_target);
 }
diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c
index 9177c3eec2..1cb4c2c627 100644
--- a/gdb/amd64-linux-nat.c
+++ b/gdb/amd64-linux-nat.c
@@ -421,5 +421,5 @@ _initialize_amd64_linux_nat (void)
   linux_target = &the_amd64_linux_nat_target;
 
   /* Add the target.  */
-  add_target (linux_target);
+  add_inf_child_target (linux_target);
 }
diff --git a/gdb/amd64-nbsd-nat.c b/gdb/amd64-nbsd-nat.c
index e1c07dfb4c..f92983b4f5 100644
--- a/gdb/amd64-nbsd-nat.c
+++ b/gdb/amd64-nbsd-nat.c
@@ -63,5 +63,5 @@ _initialize_amd64nbsd_nat (void)
   amd64_native_gregset32_num_regs = ARRAY_SIZE (amd64nbsd32_r_reg_offset);
   amd64_native_gregset64_reg_offset = amd64nbsd_r_reg_offset;
 
-  add_target (&the_amd64_nbsd_nat_target);
+  add_inf_child_target (&the_amd64_nbsd_nat_target);
 }
diff --git a/gdb/amd64-obsd-nat.c b/gdb/amd64-obsd-nat.c
index d6756d9463..0e89e3f574 100644
--- a/gdb/amd64-obsd-nat.c
+++ b/gdb/amd64-obsd-nat.c
@@ -135,7 +135,7 @@ _initialize_amd64obsd_nat (void)
   amd64_native_gregset32_num_regs = ARRAY_SIZE (amd64obsd32_r_reg_offset);
   amd64_native_gregset64_reg_offset = amd64obsd_r_reg_offset;
 
-  add_target (&the_amd64_obsd_nat_target);
+  add_inf_child_target (&the_amd64_obsd_nat_target);
 
   /* Support debugging kernel virtual memory images.  */
   bsd_kvm_add_target (amd64obsd_supply_pcb);
diff --git a/gdb/arm-fbsd-nat.c b/gdb/arm-fbsd-nat.c
index f31ee5fa1d..be733ff746 100644
--- a/gdb/arm-fbsd-nat.c
+++ b/gdb/arm-fbsd-nat.c
@@ -148,5 +148,5 @@ arm_fbsd_nat_target::read_description ()
 void
 _initialize_arm_fbsd_nat (void)
 {
-  add_target (&the_arm_fbsd_nat_target);
+  add_inf_child_target (&the_arm_fbsd_nat_target);
 }
diff --git a/gdb/arm-linux-nat.c b/gdb/arm-linux-nat.c
index aac90fd223..5df1ef1a86 100644
--- a/gdb/arm-linux-nat.c
+++ b/gdb/arm-linux-nat.c
@@ -1330,8 +1330,6 @@ arm_linux_nat_target::low_new_fork (struct lwp_info *parent, pid_t child_pid)
 void
 _initialize_arm_linux_nat (void)
 {
-  target_ops *t = &the_arm_linux_nat_target;
-
   /* Register the target.  */
-  add_target (t);
+  add_inf_child_target (&the_arm_linux_nat_target);
 }
diff --git a/gdb/arm-nbsd-nat.c b/gdb/arm-nbsd-nat.c
index 9d58b35a2a..3a1ddeaf4e 100644
--- a/gdb/arm-nbsd-nat.c
+++ b/gdb/arm-nbsd-nat.c
@@ -469,7 +469,7 @@ static struct core_fns arm_netbsd_elfcore_fns =
 void
 _initialize_arm_netbsd_nat (void)
 {
-  add_target (&the_arm_netbsd_nat_target);
+  add_inf_child_target (&the_arm_netbsd_nat_target);
 
   deprecated_add_core_fns (&arm_netbsd_elfcore_fns);
 }
diff --git a/gdb/bfd-target.c b/gdb/bfd-target.c
index 7ac8bc3c61..ba194d7b04 100644
--- a/gdb/bfd-target.c
+++ b/gdb/bfd-target.c
@@ -24,20 +24,21 @@
 #include "gdb_bfd.h"
 
 /* A target that wraps a BFD.  */
+
+static const target_info target_bfd_target_info = {
+  "bfd",
+  N_("BFD backed target"),
+  N_("You should never see this")
+};
+
 class target_bfd : public target_ops
 {
 public:
   explicit target_bfd (struct bfd *bfd);
   ~target_bfd () override;
 
-  const char *shortname () override
-  { return "bfd"; }
-
-  const char *longname () override
-  { return _("BFD backed target"); }
-
-  const char *doc () override
-  { return _("You should never see this"); }
+  const target_info &info () const override
+  { return target_bfd_target_info; }
 
   void close () override;
 
diff --git a/gdb/bsd-kvm.c b/gdb/bsd-kvm.c
index 804cddb927..7260799fac 100644
--- a/gdb/bsd-kvm.c
+++ b/gdb/bsd-kvm.c
@@ -63,25 +63,22 @@ static ptid_t bsd_kvm_ptid;
 
 /* The libkvm target.  */
 
+static const target_info bsd_kvm_target_info = {
+  "kvm",
+  N_("Kernel memory interface"),
+  N_("Use a kernel virtual memory image as a target.\n\
+Optionally specify the filename of a core dump.")
+};
+
 class bsd_kvm_target : public target_ops
 {
 public:
   bsd_kvm_target ()
   { this->to_stratum = process_stratum; }
 
-  const char *shortname () override
-  { return "kvm"; }
-
-  const char *longname () override
-  { return _("Kernel memory interface"); }
-
-  const char *doc () override
-  {
-    return _("Use a kernel virtual memory image as a target.\n\
-Optionally specify the filename of a core dump.");
-  }
+  const target_info &info () const override
+  { return bsd_kvm_target_info; }
 
-  void open (const char *, int) override;
   void close () override;
 
   void fetch_registers (struct regcache *, int) override;
@@ -105,7 +102,7 @@ Optionally specify the filename of a core dump.");
 static bsd_kvm_target bsd_kvm_ops;
 
 static void
-bsd_kvm_target::open (const char *arg, int from_tty)
+bsd_kvm_target_open (const char *arg, int from_tty)
 {
   char errbuf[_POSIX2_LINE_MAX];
   char *execfile = NULL;
@@ -388,7 +385,7 @@ bsd_kvm_add_target (int (*supply_pcb)(struct regcache *, struct pcb *))
   gdb_assert (bsd_kvm_supply_pcb == NULL);
   bsd_kvm_supply_pcb = supply_pcb;
 
-  add_target (&bsd_kvm_ops);
+  add_target (bsd_kvm_target_info, bsd_kvm_target_open);
   
   add_prefix_cmd ("kvm", class_obscure, bsd_kvm_cmd, _("\
 Generic command for manipulating the kernel memory interface."),
diff --git a/gdb/bsd-uthread.c b/gdb/bsd-uthread.c
index efcec1e396..1505cfede7 100644
--- a/gdb/bsd-uthread.c
+++ b/gdb/bsd-uthread.c
@@ -33,19 +33,19 @@
 
 #include "bsd-uthread.h"
 
+static const target_info bsd_uthread_target_info = {
+  "bsd-uthreads",
+  N_("BSD user-level threads"),
+  N_("BSD user-level threads")
+};
+
 struct bsd_uthread_target final : public target_ops
 {
   bsd_uthread_target ()
   { to_stratum = thread_stratum; }
 
-  const char *shortname () override
-  { return "bsd-uthreads"; }
-
-  const char *longname () override
-  { return _("BSD user-level threads"); }
-
-  const char *doc () override
-  { return _("BSD user-level threads"); }
+  const target_info &info () const override
+  { return bsd_uthread_target_info; }
 
   void close () override;
 
diff --git a/gdb/corefile.c b/gdb/corefile.c
index c849a10646..114de83640 100644
--- a/gdb/corefile.c
+++ b/gdb/corefile.c
@@ -62,12 +62,14 @@ core_file_command (const char *filename, int from_tty)
 {
   dont_repeat ();		/* Either way, seems bogus.  */
 
-  gdb_assert (the_core_target != NULL);
-
   if (!filename)
-    the_core_target->detach (current_inferior (), from_tty);
+    {
+      gdb_assert (the_core_target != NULL);
+
+      the_core_target->detach (current_inferior (), from_tty);
+    }
   else
-    the_core_target->open (filename, from_tty);
+    core_target_open (filename, from_tty);
 }
 \f
 
diff --git a/gdb/corelow.c b/gdb/corelow.c
index e7d9a7ed51..97a957c8fc 100644
--- a/gdb/corelow.c
+++ b/gdb/corelow.c
@@ -52,25 +52,21 @@
 
 /* The core file target.  */
 
+static const target_info core_target_info = {
+  "core",
+  N_("Local core dump file"),
+  N_("Use a core file as a target.  Specify the filename of the core file.")
+};
+
 class core_target final : public target_ops
 {
 public:
   core_target ()
   { to_stratum = process_stratum; }
 
-  const char *shortname () override
-  { return "core"; }
-
-  const char *longname () override
-  { return _("Local core dump file"); }
+  const target_info &info () const override
+  { return core_target_info; }
 
-  const char *doc () override
-  {
-    return _("\
-Use a core file as a target.  Specify the filename of the core file.");
-  }
-
-  void open (const char *, int) override;
   void close () override;
   void detach (inferior *, int) override;
   void fetch_registers (struct regcache *, int) override;
@@ -313,10 +309,10 @@ add_to_thread_list (bfd *abfd, asection *asect, void *reg_sect_arg)
     inferior_ptid = ptid;			/* Yes, make it current.  */
 }
 
-/* This routine opens and sets up the core file bfd.  */
+/* See gdbcore.h.  */
 
 void
-core_target::open (const char *arg, int from_tty)
+core_target_open (const char *arg, int from_tty)
 {
   const char *p;
   int siggy;
@@ -1031,5 +1027,5 @@ _initialize_corelow (void)
 		    the_core_target->longname ());
   the_core_target = &core_ops;
 
-  add_target_with_completer (&core_ops, filename_completer);
+  add_target (core_target_info, core_target_open, filename_completer);
 }
diff --git a/gdb/ctf.c b/gdb/ctf.c
index 90d6f6c025..cae5d221cb 100644
--- a/gdb/ctf.c
+++ b/gdb/ctf.c
@@ -34,23 +34,19 @@
 
 /* The CTF target.  */
 
+static const target_info ctf_target_info = {
+  "ctf",
+  N_("CTF file"),
+  N_("(Use a CTF directory as a target.\n\
+Specify the filename of the CTF directory.")
+};
+
 class ctf_target final : public tracefile_target
 {
 public:
-  const char *shortname () override
-  { return "ctf"; }
-
-  const char *longname () override
-  { return _("CTF file"); }
+  const target_info &info () const override
+  { return ctf_target_info; }
 
-  const char *doc () override
-  {
-    return _("\
-Use a CTF directory as a target.\n\
-Specify the filename of the CTF directory.");
-  }
-
-  void open (const char *, int) override;
   void close () override;
   void fetch_registers (struct regcache *, int) override;
   enum target_xfer_status xfer_partial (enum target_object object,
@@ -1108,8 +1104,8 @@ ctf_read_tp (struct uploaded_tp **uploaded_tps)
    definitions from the first packet.  Set the start position at the
    second packet which contains events on trace blocks.  */
 
-void
-ctf_target::open (const char *dirname, int from_tty)
+static void
+ctf_target_open (const char *dirname, int from_tty)
 {
   struct bt_ctf_event *event;
   uint32_t event_id;
@@ -1724,6 +1720,6 @@ void
 _initialize_ctf (void)
 {
 #if HAVE_LIBBABELTRACE
-  add_target_with_completer (&ctf_ops, filename_completer);
+  add_target (ctf_target_info, ctf_target_open, filename_completer);
 #endif
 }
diff --git a/gdb/exec.c b/gdb/exec.c
index 4c71abd35f..9a9d904f36 100644
--- a/gdb/exec.c
+++ b/gdb/exec.c
@@ -49,6 +49,13 @@
 
 void (*deprecated_file_changed_hook) (const char *);
 
+static const target_info exec_target_info = {
+  "exec",
+  N_("Local exec file"),
+  N_("Use an executable file as a target.\n\
+Specify the filename of the executable file.")
+};
+
 /* The target vector for executable files.  */
 
 struct exec_target final : public target_ops
@@ -56,20 +63,9 @@ struct exec_target final : public target_ops
   exec_target ()
   { to_stratum = file_stratum; }
 
-  const char *shortname () override
-  { return "exec"; }
-
-  const char *longname () override
-  { return _("Local exec file"); }
+  const target_info &info () const override
+  { return exec_target_info; }
 
-  const char *doc () override
-  {
-    return _("\
-Use an executable file as a target.\n\
-Specify the filename of the executable file.");
-  }
-
-  void open (const char *, int) override;
   void close () override;
   enum target_xfer_status xfer_partial (enum target_object object,
 					const char *annex,
@@ -99,8 +95,8 @@ show_write_files (struct ui_file *file, int from_tty,
 }
 
 
-void
-exec_target::open (const char *args, int from_tty)
+static void
+exec_target_open (const char *args, int from_tty)
 {
   target_preopen (from_tty);
   exec_file_attach (args, from_tty);
@@ -1090,5 +1086,5 @@ Show writing into executable and core files."), NULL,
 			   show_write_files,
 			   &setlist, &showlist);
 
-  add_target_with_completer (&exec_ops, filename_completer);
+  add_target (exec_target_info, exec_target_open, filename_completer);
 }
diff --git a/gdb/gdbcore.h b/gdb/gdbcore.h
index 04a235dd90..401c213d48 100644
--- a/gdb/gdbcore.h
+++ b/gdb/gdbcore.h
@@ -143,6 +143,10 @@ extern struct target_ops *the_core_target;
 
 extern int write_files;
 
+/* Open and set up the core file bfd.  */
+
+extern void core_target_open (const char *arg, int from_tty);
+
 extern void core_file_command (const char *filename, int from_tty);
 
 extern void exec_file_attach (const char *filename, int from_tty);
diff --git a/gdb/go32-nat.c b/gdb/go32-nat.c
index 6f6aedea7e..22da20a4a0 100644
--- a/gdb/go32-nat.c
+++ b/gdb/go32-nat.c
@@ -2090,7 +2090,7 @@ _initialize_go32_nat (void)
   x86_dr_low.get_addr = go32_get_dr;
   x86_set_debug_register_length (4);
 
-  add_target (&the_go32_nat_target);
+  add_inf_child_target (&the_go32_nat_target);
 
   /* Initialize child's cwd as empty to be initialized when starting
      the child.  */
diff --git a/gdb/hppa-linux-nat.c b/gdb/hppa-linux-nat.c
index 36f6a19e67..1ddc5aeb14 100644
--- a/gdb/hppa-linux-nat.c
+++ b/gdb/hppa-linux-nat.c
@@ -390,5 +390,5 @@ void
 _initialize_hppa_linux_nat (void)
 {
   /* Register the target.  */
-  add_target (&the_hppa_linux_nat_target);
+  add_inf_child_target (&the_hppa_linux_nat_target);
 }
diff --git a/gdb/hppa-nbsd-nat.c b/gdb/hppa-nbsd-nat.c
index 1497166145..3547d65543 100644
--- a/gdb/hppa-nbsd-nat.c
+++ b/gdb/hppa-nbsd-nat.c
@@ -231,5 +231,5 @@ hppa_nbsd_nat_target::store_registers (struct regcache *regcache, int regnum)
 void
 _initialize_hppanbsd_nat (void)
 {
-  add_target (&the_hppa_nbsd_nat_target);
+  add_inf_child_target (&the_hppa_nbsd_nat_target);
 }
diff --git a/gdb/hppa-obsd-nat.c b/gdb/hppa-obsd-nat.c
index 2bef638a31..3ca19adc75 100644
--- a/gdb/hppa-obsd-nat.c
+++ b/gdb/hppa-obsd-nat.c
@@ -255,5 +255,5 @@ hppa_obsd_nat_target::store_registers (struct regcache *regcache, int regnum)
 void
 _initialize_hppaobsd_nat (void)
 {
-  add_target (&the_hppa_obsd_nat_target);
+  add_inf_child_target (&the_hppa_obsd_nat_target);
 }
diff --git a/gdb/i386-darwin-nat.c b/gdb/i386-darwin-nat.c
index 48f1a7921d..e57b12693f 100644
--- a/gdb/i386-darwin-nat.c
+++ b/gdb/i386-darwin-nat.c
@@ -659,5 +659,5 @@ _initialize_i386_darwin_nat (void)
   x86_set_debug_register_length (4);
 #endif
 
-  add_target (&darwin_target);
+  add_inf_child_target (&darwin_target);
 }
diff --git a/gdb/i386-fbsd-nat.c b/gdb/i386-fbsd-nat.c
index f2bb82c4c0..6518b712c6 100644
--- a/gdb/i386-fbsd-nat.c
+++ b/gdb/i386-fbsd-nat.c
@@ -163,7 +163,7 @@ i386_fbsd_nat_traget::read_description ()
 void
 _initialize_i386fbsd_nat (void)
 {
-  add_target (&the_i386_fbsd_nat_target);
+  add_inf_child_target (&the_i386_fbsd_nat_target);
 
   /* Support debugging kernel virtual memory images.  */
   bsd_kvm_add_target (i386fbsd_supply_pcb);
diff --git a/gdb/i386-gnu-nat.c b/gdb/i386-gnu-nat.c
index de7d62a269..8bb036dac3 100644
--- a/gdb/i386-gnu-nat.c
+++ b/gdb/i386-gnu-nat.c
@@ -440,5 +440,5 @@ _initialize_i386gnu_nat (void)
 #endif /* i386_DEBUG_STATE */
 
   /* Register the target.  */
-  add_target (&the_i386_gnu_nat_target);
+  add_inf_child_target (&the_i386_gnu_nat_target);
 }
diff --git a/gdb/i386-linux-nat.c b/gdb/i386-linux-nat.c
index 786eec227f..6538324306 100644
--- a/gdb/i386-linux-nat.c
+++ b/gdb/i386-linux-nat.c
@@ -717,5 +717,5 @@ _initialize_i386_linux_nat (void)
   linux_target = &the_i386_linux_nat_target;
 
   /* Add the target.  */
-  add_target (linux_target);
+  add_inf_child_target (linux_target);
 }
diff --git a/gdb/i386-nbsd-nat.c b/gdb/i386-nbsd-nat.c
index 508abdc92e..bc875e07cd 100644
--- a/gdb/i386-nbsd-nat.c
+++ b/gdb/i386-nbsd-nat.c
@@ -76,7 +76,7 @@ static i386_bsd_nat_target<nbsd_nat_target> the_i386_nbsd_nat_target;
 void
 _initialize_i386nbsd_nat (void)
 {
-  add_target (&the_i386_nbsd_nat_target);
+  add_inf_child_target (&the_i386_nbsd_nat_target);
 
   /* Support debugging kernel virtual memory images.  */
   bsd_kvm_add_target (i386nbsd_supply_pcb);
diff --git a/gdb/i386-obsd-nat.c b/gdb/i386-obsd-nat.c
index 2a09f3e0d6..a3221edc85 100644
--- a/gdb/i386-obsd-nat.c
+++ b/gdb/i386-obsd-nat.c
@@ -93,7 +93,7 @@ static i386_bsd_nat_target<obsd_nat_target> the_i386_obsd_nat_target;
 void
 _initialize_i386obsd_nat (void)
 {
-  add_target (&i386_obsd_nat_target);
+  add_inf_child_target (&i386_obsd_nat_target);
 
   /* Support debugging kernel virtual memory images.  */
   bsd_kvm_add_target (i386obsd_supply_pcb);
diff --git a/gdb/ia64-linux-nat.c b/gdb/ia64-linux-nat.c
index 1e7ff6dcd5..315b3bbaef 100644
--- a/gdb/ia64-linux-nat.c
+++ b/gdb/ia64-linux-nat.c
@@ -929,8 +929,6 @@ ia64_linux_nat_target::low_status_is_event (int status)
 void
 _initialize_ia64_linux_nat (void)
 {
-  struct target_ops *t = &the_ia64_linux_nat_target;
-
   /* Register the target.  */
-  add_target (t);
+  add_inf_child_target (&the_ia64_linux_nat_target);
 }
diff --git a/gdb/inf-child.c b/gdb/inf-child.c
index 8e5ebfa2c2..2f5babebce 100644
--- a/gdb/inf-child.c
+++ b/gdb/inf-child.c
@@ -39,6 +39,18 @@
 #include <fcntl.h>
 #include <unistd.h>
 
+static const target_info inf_child_target_info = {
+  "native",
+  N_("Native process"),
+  N_("Native process (started by the \"run\" command).")
+};
+
+const target_info &
+inf_child_target::info () const
+{
+  return inf_child_target_info;
+}
+
 /* Helper function for child_wait and the derivatives of child_wait.
    HOSTSTATUS is the waitstatus from wait() or the equivalent; store our
    translation of that in OURSTATUS.  */
@@ -139,9 +151,14 @@ static int inf_child_explicitly_opened;
 /* See inf-child.h.  */
 
 void
-inf_child_open_target (struct target_ops *target, const char *arg,
-		       int from_tty)
+inf_child_open_target (const char *arg, int from_tty)
 {
+  target_ops *target = get_native_target ();
+
+  /* There's always only ever one native target, and if we get here,
+     it better be an inf-child target.  */
+  gdb_assert (dynamic_cast<inf_child_target *> (target) != NULL);
+
   target_preopen (from_tty);
   push_target (target);
   inf_child_explicitly_opened = 1;
@@ -149,12 +166,6 @@ inf_child_open_target (struct target_ops *target, const char *arg,
     printf_filtered ("Done.  Use the \"run\" command to start a process.\n");
 }
 
-void
-inf_child_target::open (const char *arg, int from_tty)
-{
-  inf_child_open_target (this, arg, from_tty);
-}
-
 /* Implement the to_disconnect target_ops method.  */
 
 void
@@ -426,3 +437,12 @@ inf_child_target::inf_child_target ()
 {
   this->to_stratum = process_stratum;
 }
+
+/* See inf-child.h.  */
+
+void
+add_inf_child_target (inf_child_target *target)
+{
+  set_native_target (target);
+  add_target (inf_child_target_info, inf_child_open_target);
+}
diff --git a/gdb/inf-child.h b/gdb/inf-child.h
index 755c462fb8..1b59fb5b7a 100644
--- a/gdb/inf-child.h
+++ b/gdb/inf-child.h
@@ -32,16 +32,8 @@ public:
   inf_child_target ();
   ~inf_child_target () override = 0;
 
-  const char *shortname () override
-  { return "native"; }
+  const target_info &info () const override;
 
-  const char *longname () override
-  { return _("Native process"); }
-
-  const char *doc () override
-  { return _("Native process (started by the \"run\" command)."); }
-
-  void open (const char *arg, int from_tty) override;
   void close () override;
 
   void disconnect (const char *, int) override;
@@ -123,4 +115,13 @@ protected:
 /* This is for native targets which use a unix/POSIX-style waitstatus.  */
 extern void store_waitstatus (struct target_waitstatus *, int);
 
+/* Register TARGET as native target and set it up to respond to the
+   "target native" command.  */
+extern void add_inf_child_target (inf_child_target *target);
+
+/* target_open_ftype callback for inf-child targets.  Used by targets
+   that want to register an alternative target_info object.  Most
+   targets use add_inf_child_target instead.  */
+extern void inf_child_open_target (const char *arg, int from_tty);
+
 #endif
diff --git a/gdb/linux-thread-db.c b/gdb/linux-thread-db.c
index a7b0772d45..324c59378c 100644
--- a/gdb/linux-thread-db.c
+++ b/gdb/linux-thread-db.c
@@ -75,17 +75,19 @@
    of the ptid_t prevents thread IDs changing when libpthread is
    loaded or unloaded.  */
 
+static const target_info thread_db_target_info = {
+  "multi-thread",
+  N_("multi-threaded child process."),
+  N_("Threads and pthreads support.")
+};
+
 class thread_db_target : public target_ops
 {
 public:
   thread_db_target ();
 
-  const char *shortname () override
-  { return "multi-thread"; }
-  const char *longname () override
-  { return _("multi-threaded child process."); }
-  const char *doc () override
-  { return _("Threads and pthreads support."); }
+  const target_info &info () const override
+  { return thread_db_target_info; }
 
   void detach (inferior *, int) override;
   ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
diff --git a/gdb/m32r-linux-nat.c b/gdb/m32r-linux-nat.c
index ccdea941e0..6bfef2303a 100644
--- a/gdb/m32r-linux-nat.c
+++ b/gdb/m32r-linux-nat.c
@@ -241,5 +241,5 @@ void
 _initialize_m32r_linux_nat (void)
 {
   /* Register the target.  */
-  add_target (&the_m32r_linux_nat_target);
+  add_inf_child_target (&the_m32r_linux_nat_target);
 }
diff --git a/gdb/m68k-bsd-nat.c b/gdb/m68k-bsd-nat.c
index 372ef2233a..c853ed6558 100644
--- a/gdb/m68k-bsd-nat.c
+++ b/gdb/m68k-bsd-nat.c
@@ -225,7 +225,7 @@ m68kbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
 void
 _initialize_m68kbsd_nat (void)
 {
-  add_target (&the_m68k_bsd_nat_target);
+  add_inf_child_target (&the_m68k_bsd_nat_target);
 
   /* Support debugging kernel virtual memory images.  */
   bsd_kvm_add_target (m68kbsd_supply_pcb);
diff --git a/gdb/m68k-linux-nat.c b/gdb/m68k-linux-nat.c
index 536361f60d..938c9cc27a 100644
--- a/gdb/m68k-linux-nat.c
+++ b/gdb/m68k-linux-nat.c
@@ -519,5 +519,5 @@ void
 _initialize_m68k_linux_nat (void)
 {
   /* Register the target.  */
-  add_target (&the_m68k_linux_nat_target);
+  add_inf_child_target (&the_m68k_linux_nat_target);
 }
diff --git a/gdb/m88k-bsd-nat.c b/gdb/m88k-bsd-nat.c
index 255d2ffba9..ed38124e91 100644
--- a/gdb/m88k-bsd-nat.c
+++ b/gdb/m88k-bsd-nat.c
@@ -104,5 +104,5 @@ m88k_bsd_nat_target::store_registers (struct regcache *regcache, int regnum)
 void
 _initialize_m88kbsd_nat (void)
 {
-  add_target (&the_m88k_bsd_nat_target);
+  add_inf_child_target (&the_m88k_bsd_nat_target);
 }
diff --git a/gdb/make-target-delegates b/gdb/make-target-delegates
index 83a1afcadf..b8cf63cd0b 100755
--- a/gdb/make-target-delegates
+++ b/gdb/make-target-delegates
@@ -392,9 +392,7 @@ sub print_class($) {
     print "{\n";
     print "  $name ();\n";
     print "\n";
-    print "  const char *shortname () override;\n";
-    print "  const char *longname () override;\n";
-    print "  const char *doc () override;\n";
+    print "  const target_info &info () const override;\n";
     print "\n";
 
     for $name (@delegators) {
diff --git a/gdb/mips-fbsd-nat.c b/gdb/mips-fbsd-nat.c
index 3b38b580a9..b67444b049 100644
--- a/gdb/mips-fbsd-nat.c
+++ b/gdb/mips-fbsd-nat.c
@@ -129,5 +129,5 @@ mips_fbsd_nat_target::store_registers (struct regcache *regcache, int regnum)
 void
 _initialize_mips_fbsd_nat (void)
 {
-  add_target (&the_mips_fbsd_nat_target);
+  add_inf_child_target (&the_mips_fbsd_nat_target);
 }
diff --git a/gdb/mips-linux-nat.c b/gdb/mips-linux-nat.c
index 8432171890..c697c57105 100644
--- a/gdb/mips-linux-nat.c
+++ b/gdb/mips-linux-nat.c
@@ -801,5 +801,5 @@ triggers a breakpoint or watchpoint."),
 			   &maintenance_set_cmdlist,
 			   &maintenance_show_cmdlist);
 
-  add_target (&the_mips_linux_nat_target);
+  add_inf_child_target (&the_mips_linux_nat_target);
 }
diff --git a/gdb/mips-nbsd-nat.c b/gdb/mips-nbsd-nat.c
index 74b2060c13..b9fc6279d0 100644
--- a/gdb/mips-nbsd-nat.c
+++ b/gdb/mips-nbsd-nat.c
@@ -116,5 +116,5 @@ mips_nbsd_nat_target::store_registers (struct regcache *regcache, int regno)
 void
 _initialize_mipsnbsd_nat (void)
 {
-  add_target (&the_mips_nbsd_nat_target);
+  add_inf_child_target (&the_mips_nbsd_nat_target);
 }
diff --git a/gdb/mips64-obsd-nat.c b/gdb/mips64-obsd-nat.c
index 2193972f07..bc411517b9 100644
--- a/gdb/mips64-obsd-nat.c
+++ b/gdb/mips64-obsd-nat.c
@@ -118,5 +118,5 @@ mips64_obsd_nat_target::store_registers (struct regcache *regcache, int regnum)
 void
 _initialize_mips64obsd_nat (void)
 {
-  add_target (&the_mips64_obsd_nat_target);
+  add_inf_child_target (&the_mips64_obsd_nat_target);
 }
diff --git a/gdb/nto-procfs.c b/gdb/nto-procfs.c
index f3ba877840..51559e6c3e 100644
--- a/gdb/nto-procfs.c
+++ b/gdb/nto-procfs.c
@@ -128,28 +128,31 @@ struct nto_procfs_target : public inf_child_target
 };
 
 /* For "target native".  */
-struct nto_procfs_target_native final : public nto_procfs_target
-{
-  /* Leave shortname as "native".  */
 
-  const char *longname () override
-  { return _("QNX Neutrino local process"); }
+static const target_info nto_native_target_info = {
+  "native",
+  N_("QNX Neutrino local process"),
+  N_("QNX Neutrino local process (started by the \"run\" command).")
+};
 
-  const char *doc () override
-  { return _("QNX Neutrino local process (started by the \"run\" command)."); }
+class nto_procfs_target_native final : public nto_procfs_target
+{
+  const target_info &info () const override
+  { return nto_native_target_info; }
 };
 
 /* For "target procfs <node>".  */
-struct nto_procfs_target_procfs final : public nto_procfs_target
-{
-  const char *shortname () override
-  { return "procfs"; }
 
-  const char *longname () override
-  { return _("QNX Neutrino local or remote process"); }
+static const target_info nto_procfs_target_info = {
+  "procfs",
+  N_("QNX Neutrino local or remote process"),
+  N_("QNX Neutrino process.  target procfs <node>")
+};
 
-  const char *doc () override
-  { return _("QNX Neutrino process.  target procfs <node>"); }
+struct nto_procfs_target_procfs final : public nto_procfs_target
+{
+  const target_info &info () const override
+  { return nto_procfs_target_info; }
 };
 
 static ptid_t do_attach (ptid_t ptid);
@@ -1519,10 +1522,11 @@ static void
 init_procfs_targets (void)
 {
   /* Register "target native".  This is the default run target.  */
-  add_target (&nto_native_ops);
+  add_target (nto_native_target_info, inf_child_open_target);
+  set_native_target (&nto_native_ops);
 
   /* Register "target procfs <node>".  */
-  add_target (&nto_procfs_ops);
+  add_target (nto_procfs_target_info, inf_child_open_target);
 }
 
 #define OSTYPE_NTO 1
diff --git a/gdb/ppc-fbsd-nat.c b/gdb/ppc-fbsd-nat.c
index e046fbb553..0329b024ee 100644
--- a/gdb/ppc-fbsd-nat.c
+++ b/gdb/ppc-fbsd-nat.c
@@ -204,7 +204,7 @@ ppcfbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
 void
 _initialize_ppcfbsd_nat (void)
 {
-  add_target (&the_ppc_fbsd_nat_target);
+  add_inf_child_target (&the_ppc_fbsd_nat_target);
 
   /* Support debugging kernel virtual memory images.  */
   bsd_kvm_add_target (ppcfbsd_supply_pcb);
diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c
index a1c3dc8fe3..1423339339 100644
--- a/gdb/ppc-linux-nat.c
+++ b/gdb/ppc-linux-nat.c
@@ -2509,5 +2509,5 @@ _initialize_ppc_linux_nat (void)
   gdb::observers::thread_exit.attach (ppc_linux_thread_exit);
 
   /* Register the target.  */
-  add_target (linux_target);
+  add_inf_child_target (linux_target);
 }
diff --git a/gdb/ppc-nbsd-nat.c b/gdb/ppc-nbsd-nat.c
index e2b8083ad0..6d468eef29 100644
--- a/gdb/ppc-nbsd-nat.c
+++ b/gdb/ppc-nbsd-nat.c
@@ -186,5 +186,5 @@ _initialize_ppcnbsd_nat (void)
   /* Support debugging kernel virtual memory images.  */
   bsd_kvm_add_target (ppcnbsd_supply_pcb);
 
-  add_target (&the_ppc_nbsd_nat_target);
+  add_inf_child_target (&the_ppc_nbsd_nat_target);
 }
diff --git a/gdb/ppc-obsd-nat.c b/gdb/ppc-obsd-nat.c
index 27c4e1f414..10da6367a9 100644
--- a/gdb/ppc-obsd-nat.c
+++ b/gdb/ppc-obsd-nat.c
@@ -190,7 +190,7 @@ ppcobsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
 void
 _initialize_ppcobsd_nat (void)
 {
-  add_target (&the_ppc_obsd_nat_target);
+  add_inf_child_target (&the_ppc_obsd_nat_target);
 
   /* General-purpose registers.  */
   ppcobsd_reg_offsets.r0_offset = offsetof (struct reg, gpr);
diff --git a/gdb/ravenscar-thread.c b/gdb/ravenscar-thread.c
index 03cbe3d9e7..5f3e179dec 100644
--- a/gdb/ravenscar-thread.c
+++ b/gdb/ravenscar-thread.c
@@ -73,19 +73,19 @@ static const char first_task_name[] = "system__tasking__debug__first_task";
 static const char ravenscar_runtime_initializer[] =
   "system__bb__threads__initialize";
 
+static const target_info ravenscar_target_info = {
+  "ravenscar",
+  N_("Ravenscar tasks."),
+  N_("Ravenscar tasks support.")
+};
+
 struct ravenscar_thread_target final : public target_ops
 {
   ravenscar_thread_target ()
   { to_stratum = thread_stratum; }
 
-  const char *shortname () override
-  { return "ravenscar"; }
-
-  const char *longname () override
-  { return _("Ravenscar tasks."); }
-
-  const char *doc () override
-  { return _("Ravenscar tasks support."); }
+  const target_info &info () const override
+  { return ravenscar_target_info; }
 
   ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
   void resume (ptid_t, int, enum gdb_signal) override;
diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
index 3c1cfb6601..a88c2cf3ae 100644
--- a/gdb/record-btrace.c
+++ b/gdb/record-btrace.c
@@ -41,6 +41,12 @@
 #include "vec.h"
 #include <algorithm>
 
+static const target_info record_btrace_target_info = {
+  "record-btrace",
+  N_("Branch tracing target"),
+  N_("Collect control-flow trace and provide the execution history.")
+};
+
 /* The target_ops of record-btrace.  */
 
 class record_btrace_target final : public target_ops
@@ -49,16 +55,9 @@ public:
   record_btrace_target ()
   { to_stratum = record_stratum; }
 
-  const char *shortname () override
-  { return "record-btrace"; }
-
-  const char *longname () override
-  { return _("Branch tracing target"); }
+  const target_info &info () const override
+  { return record_btrace_target_info; }
 
-  const char *doc () override
-  { return _("Collect control-flow trace and provide the execution history."); }
-
-  void open (const char *, int) override;
   void close () override;
   void async (int) override;
 
@@ -335,10 +334,10 @@ private:
   std::forward_list<thread_info *> m_threads;
 };
 
-/* The open method of target record-btrace.  */
+/* Open target record-btrace.  */
 
-void
-record_btrace_target::open (const char *args, int from_tty)
+static void
+record_btrace_target_open (const char *args, int from_tty)
 {
   /* If we fail to enable btrace for one thread, disable it for the threads for
      which it was successfully enabled.  */
@@ -3142,7 +3141,7 @@ to see the actual buffer size."), NULL, show_record_pt_buffer_size_value,
 			    &set_record_btrace_pt_cmdlist,
 			    &show_record_btrace_pt_cmdlist);
 
-  add_target (&record_btrace_ops);
+  add_target (record_btrace_target_info, record_btrace_target_open);
 
   bfcache = htab_create_alloc (50, bfcache_hash, bfcache_eq, NULL,
 			       xcalloc, xfree);
diff --git a/gdb/record-full.c b/gdb/record-full.c
index 58f4be4fea..79f5c0fa0a 100644
--- a/gdb/record-full.c
+++ b/gdb/record-full.c
@@ -206,6 +206,11 @@ static unsigned int record_full_insn_num = 0;
    than count of insns presently in execution log).  */
 static ULONGEST record_full_insn_count;
 
+static const char record_longname[]
+  = N_("Process record and replay target");
+static const char record_doc[]
+  = N_("Log program while executing and replay execution from log.");
+
 /* Base class implementing functionality common to both the
    "record-full" and "record-core" targets.  */
 
@@ -215,15 +220,8 @@ public:
   record_full_base_target ()
   { to_stratum = record_stratum; }
 
-  const char *shortname () override = 0;
-
-  const char *longname () override
-  { return _("Process record and replay target"); }
-
-  const char *doc () override
-  { return _("Log program while executing and replay execution from log."); }
+  const target_info &info () const override = 0;
 
-  void open (const char *, int) override;
   void close () override;
   void async (int) override;
   ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
@@ -257,11 +255,17 @@ public:
 
 /* The "record-full" target.  */
 
+static const target_info record_full_target_info = {
+  "record-full",
+  record_longname,
+  record_doc,
+};
+
 class record_full_target final : public record_full_base_target
 {
 public:
-  const char *shortname () override
-  { return "record-full"; }
+  const target_info &info () const override
+  { return record_full_target_info; }
 
   void commit_resume () override;
   void resume (ptid_t, int, enum gdb_signal) override;
@@ -285,11 +289,17 @@ public:
 
 /* The "record-core" target.  */
 
+static const target_info record_full_core_target_info = {
+  "record-core",
+  record_longname,
+  record_doc,
+};
+
 class record_full_core_target final : public record_full_base_target
 {
 public:
-  const char *shortname () override
-  { return "record-core"; }
+  const target_info &info () const override
+  { return record_full_core_target_info; }
 
   void resume (ptid_t, int, enum gdb_signal) override;
   void disconnect (const char *, int) override;
@@ -900,7 +910,7 @@ record_full_async_inferior_event_handler (gdb_client_data data)
   inferior_event_handler (INF_REG_EVENT, NULL);
 }
 
-/* Open the process record target.  */
+/* Open the process record target for 'core' files.  */
 
 static void
 record_full_core_open_1 (const char *name, int from_tty)
@@ -930,7 +940,7 @@ record_full_core_open_1 (const char *name, int from_tty)
   record_full_restore ();
 }
 
-/* "open" target method for 'live' processes.  */
+/* Open the process record target for 'live' processes.  */
 
 static void
 record_full_open_1 (const char *name, int from_tty)
@@ -954,10 +964,10 @@ record_full_open_1 (const char *name, int from_tty)
 
 static void record_full_init_record_breakpoints (void);
 
-/* "open" target method.  Open the process record target.  */
+/* Open the process record target.  */
 
-void
-record_full_base_target::open (const char *name, int from_tty)
+static void
+record_full_open (const char *name, int from_tty)
 {
   if (record_debug)
     fprintf_unfiltered (gdb_stdlog, "Process record: record_full_open\n");
@@ -2519,7 +2529,7 @@ static void
 cmd_record_full_restore (const char *args, int from_tty)
 {
   core_file_command (args, from_tty);
-  record_full_ops.open (args, from_tty);
+  record_full_open (args, from_tty);
 }
 
 /* Save the execution log to a file.  We use a modified elf corefile
@@ -2808,9 +2818,9 @@ _initialize_record_full (void)
   record_full_first.next = NULL;
   record_full_first.type = record_full_end;
 
-  add_target (&record_full_ops);
-  add_deprecated_target_alias (&record_full_ops, "record");
-  add_target (&record_full_core_ops);
+  add_target (record_full_target_info, record_full_open);
+  add_deprecated_target_alias (record_full_target_info, "record");
+  add_target (record_full_core_target_info, record_full_open);
 
   add_prefix_cmd ("full", class_obscure, cmd_record_full_start,
 		  _("Start full execution recording."), &record_full_cmdlist,
diff --git a/gdb/remote-sim.c b/gdb/remote-sim.c
index 91dbd7c7bb..d8ba0aa52d 100644
--- a/gdb/remote-sim.c
+++ b/gdb/remote-sim.c
@@ -75,22 +75,21 @@ void simulator_command (char *args, int from_tty);
    sim_* are the interface to the simulator (see remote-sim.h).
    gdbsim_* are stuff which is internal to gdb.  */
 
+static const target_info gdbsim_target_info = {
+  "sim",
+  N_("simulator"),
+  N_("Use the compiled-in simulator.")
+};
+
 struct gdbsim_target
   : public memory_breakpoint_target<target_ops>
 {
   gdbsim_target ()
   { to_stratum = process_stratum; }
 
-  const char *shortname () override
-  { return "sim"; }
-
-  const char *longname () override
-  { return _("simulator"); }
+  const target_info &info () const override
+  { return gdbsim_target_info; }
 
-  const char *doc () override
-  { return _("Use the compiled-in simulator."); }
-
-  void open (const char *, int) override;
   void close () override;
 
   void detach (inferior *inf, int) override;
@@ -701,8 +700,8 @@ gdbsim_target::create_inferior (const char *exec_file,
    Targets should supply this routine, if only to provide an error message.  */
 /* Called when selecting the simulator.  E.g. (gdb) target sim name.  */
 
-void
-gdbsim_target::open (const char *args, int from_tty)
+static void
+gdbsim_target_open (const char *args, int from_tty)
 {
   int len;
   char *arg_buf;
@@ -1344,7 +1343,7 @@ _initialize_remote_sim (void)
 {
   struct cmd_list_element *c;
 
-  add_target (&gdbsim_ops);
+  add_target (gdbsim_target_info, gdbsim_target_open);
 
   c = add_com ("sim", class_obscure, simulator_command,
 	       _("Send a command to the simulator."));
diff --git a/gdb/remote.c b/gdb/remote.c
index 4790bc7f5e..9e6a7f7f5a 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -78,6 +78,17 @@
 
 /* The remote target.  */
 
+static const char remote_doc[] = N_("\
+Use a remote computer via a serial line, using a gdb-specific protocol.\n\
+Specify the serial device it is connected to\n\
+(e.g. /dev/ttyS0, /dev/ttya, COM1, etc.).");
+
+static const target_info remote_target_info = {
+  "remote",
+  N_("Remote serial target in gdb-specific protocol"),
+  remote_doc
+};
+
 class remote_target : public target_ops
 {
 public:
@@ -86,24 +97,15 @@ public:
     to_stratum = process_stratum;
   }
 
-  const char *shortname () override
-  { return "remote"; }
-
-  const char *longname () override
-  { return _("Remote serial target in gdb-specific protocol"); }
-
-  const char *doc () override
-  {
-    return _("\
-Use a remote computer via a serial line, using a gdb-specific protocol.\n\
-Specify the serial device it is connected to\n\
-(e.g. /dev/ttyS0, /dev/ttya, COM1, etc.).");
-  }
+  const target_info &info () const override
+  { return remote_target_info; }
 
   thread_control_capabilities get_thread_control_capabilities () override
   { return tc_schedlock; }
 
-  void open (const char *, int) override;
+  /* Open a remote connection.  */
+  static void open (const char *, int);
+
   void close () override;
 
   void detach (inferior *, int) override;
@@ -376,23 +378,27 @@ Specify the serial device it is connected to\n\
   enum exec_direction_kind execution_direction () override;
 
 protected:
-  void open_1 (const char *name, int from_tty, int extended_p);
+  static void open_1 (const char *name, int from_tty, int extended_p);
   void start_remote (int from_tty, int extended_p);
 };
 
+static const target_info extended_remote_target_info = {
+  "extended-remote",
+  N_("Extended remote serial target in gdb-specific protocol"),
+  remote_doc
+};
+
 /* Set up the extended remote target by extending the standard remote
    target and adding to it.  */
 
 class extended_remote_target : public remote_target
 {
 public:
-  const char *shortname () override
-  { return "extended-remote"; }
+  const target_info &info () const override
+  { return extended_remote_target_info; }
 
-  const char *longname () override
-  { return _("Extended remote serial target in gdb-specific protocol"); }
-
-  void open (const char *, int) override;
+  /* Open an extended-remote connection.  */
+  static void open (const char *, int);
 
   bool can_create_inferior () override { return true; }
   void create_inferior (const char *, const std::string &,
@@ -5270,7 +5276,10 @@ remote_target::open_1 (const char *name, int from_tty, int extended_p)
       puts_filtered (name);
       puts_filtered ("\n");
     }
-  push_target (this);		/* Switch to using remote target now.  */
+
+  remote_target *target
+    = extended_p ? &extended_remote_ops : &remote_ops;
+  push_target (target);		/* Switch to using remote target now.  */
 
   /* Register extra event sources in the event loop.  */
   remote_async_inferior_event_token
@@ -5338,7 +5347,7 @@ remote_target::open_1 (const char *name, int from_tty, int extended_p)
 
     TRY
       {
-	start_remote (from_tty, extended_p);
+	target->start_remote (from_tty, extended_p);
       }
     CATCH (ex, RETURN_MASK_ALL)
       {
@@ -14009,8 +14018,8 @@ _initialize_remote (void)
      time.  */
   remote_state = new_remote_state ();
 
-  add_target (&remote_ops);
-  add_target (&extended_remote_ops);
+  add_target (remote_target_info, remote_target::open);
+  add_target (extended_remote_target_info, extended_remote_target::open);
 
   /* Hook into new objfile notification.  */
   gdb::observers::new_objfile.attach (remote_new_objfile);
diff --git a/gdb/rs6000-nat.c b/gdb/rs6000-nat.c
index 0880d3748e..e9f064710a 100644
--- a/gdb/rs6000-nat.c
+++ b/gdb/rs6000-nat.c
@@ -671,5 +671,5 @@ rs6000_nat_target::xfer_shared_libraries
 void
 _initialize_rs6000_nat (void)
 {
-  add_target (&the_rs6000_nat_target);
+  add_inf_child_target (&the_rs6000_nat_target);
 }
diff --git a/gdb/s390-linux-nat.c b/gdb/s390-linux-nat.c
index 637d12f4b2..5ac635a8a4 100644
--- a/gdb/s390-linux-nat.c
+++ b/gdb/s390-linux-nat.c
@@ -1065,10 +1065,8 @@ s390_linux_nat_target::read_description ()
 void
 _initialize_s390_nat (void)
 {
-  struct target_ops *t = &the_s390_linux_nat_target;
-
   /* Register the target.  */
-  add_target (t);
+  add_inf_child_target (&the_s390_linux_nat_target);
 
   /* A maintenance command to enable showing the PER state.  */
   add_setshow_boolean_cmd ("show-debug-regs", class_maintenance,
diff --git a/gdb/sh-nbsd-nat.c b/gdb/sh-nbsd-nat.c
index dad4381c9c..ed5dce204f 100644
--- a/gdb/sh-nbsd-nat.c
+++ b/gdb/sh-nbsd-nat.c
@@ -99,5 +99,5 @@ sh_nbsd_nat_target::store_registers (struct regcache *regcache, int regno)
 void
 _initialize_shnbsd_nat (void)
 {
-  add_target (&the_sh_nbsd_nat_target);
+  add_inf_child_target (&the_sh_nbsd_nat_target);
 }
diff --git a/gdb/sol-thread.c b/gdb/sol-thread.c
index 8f2ac3a6a3..d628416066 100644
--- a/gdb/sol-thread.c
+++ b/gdb/sol-thread.c
@@ -69,18 +69,20 @@
 #include "minsyms.h"
 #include "objfiles.h"
 
+static const target_info thread_db_target_info = {
+  "solaris-threads",
+  N_("Solaris threads and pthread."),
+  N_("Solaris threads and pthread support.")
+};
+
 class sol_thread_target : public target_ops
 {
 public:
   sol_thread_target ()
   { this->to_stratum = thread_stratum; }
 
-  const char *shortname () override
-  { return "solaris-threads"; }
-  const char *longname () override
-  { return _("Solaris threads and pthread."); }
-  const char *doc () override
-  { return _("Solaris threads and pthread support."); }
+  const target_info &info () const override
+  { return thread_db_target_info; }
 
   void detach (inferior *, int) override;
   ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
diff --git a/gdb/sparc-linux-nat.c b/gdb/sparc-linux-nat.c
index de7dda3d14..2154821b19 100644
--- a/gdb/sparc-linux-nat.c
+++ b/gdb/sparc-linux-nat.c
@@ -72,5 +72,5 @@ _initialize_sparc_linux_nat (void)
   sparc_fpregmap = &sparc32_bsd_fpregmap;
 
   /* Register the target.  */
-  add_target (&the_sparc_linux_nat_target);
+  add_inf_child_target (&the_sparc_linux_nat_target);
 }
diff --git a/gdb/sparc-nbsd-nat.c b/gdb/sparc-nbsd-nat.c
index 5ff723d342..e1ed44202c 100644
--- a/gdb/sparc-nbsd-nat.c
+++ b/gdb/sparc-nbsd-nat.c
@@ -63,7 +63,7 @@ _initialize_sparcnbsd_nat (void)
   sparc_gregmap = &sparc32nbsd_gregmap;
   sparc_fpregmap = &sparc32_bsd_fpregmap;
 
-  add_target (&sparc_nbsd_nat_target);
+  add_inf_child_target (&sparc_nbsd_nat_target);
 
   /* Support debugging kernel virtual memory images.  */
   bsd_kvm_add_target (sparc32nbsd_supply_pcb);
diff --git a/gdb/sparc64-fbsd-nat.c b/gdb/sparc64-fbsd-nat.c
index 00c1ece2db..20c6a28d18 100644
--- a/gdb/sparc64-fbsd-nat.c
+++ b/gdb/sparc64-fbsd-nat.c
@@ -65,9 +65,7 @@ static sparc_target<fbsd_nat_target> the_sparc64_fbsd_nat_target;
 void
 _initialize_sparc64fbsd_nat (void)
 {
-  struct target_ops *t;
-
-  add_target (&the_sparc64_fbsd_nat_target);
+  add_inf_child_target (&the_sparc64_fbsd_nat_target);
 
   sparc_gregmap = &sparc64fbsd_gregmap;
 
diff --git a/gdb/sparc64-linux-nat.c b/gdb/sparc64-linux-nat.c
index bc7855acfa..8406df0a24 100644
--- a/gdb/sparc64-linux-nat.c
+++ b/gdb/sparc64-linux-nat.c
@@ -91,12 +91,10 @@ fill_fpregset (const struct regcache *regcache,
 void
 _initialize_sparc64_linux_nat (void)
 {
-  target_ops *t = &the_sparc64_linux_nat_target;
-
   sparc_fpregmap = &sparc64_bsd_fpregmap;
 
   /* Register the target.  */
-  add_target (t);
+  add_inf_child_target (&the_sparc64_linux_nat_target);
 
   sparc_gregmap = &sparc64_linux_ptrace_gregmap;
 }
diff --git a/gdb/sparc64-nbsd-nat.c b/gdb/sparc64-nbsd-nat.c
index a0bfd8138e..ac760b341d 100644
--- a/gdb/sparc64-nbsd-nat.c
+++ b/gdb/sparc64-nbsd-nat.c
@@ -180,7 +180,7 @@ _initialize_sparc64nbsd_nat (void)
   sparc_gregset_supplies_p = sparc64nbsd_gregset_supplies_p;
   sparc_fpregset_supplies_p = sparc64nbsd_fpregset_supplies_p;
 
-  add_target (&the_sparc64_nbsd_nat_target);
+  add_inf_child_target (&the_sparc64_nbsd_nat_target);
 
   /* Support debugging kernel virtual memory images.  */
   bsd_kvm_add_target (sparc64nbsd_supply_pcb);
diff --git a/gdb/sparc64-obsd-nat.c b/gdb/sparc64-obsd-nat.c
index 67629aa05e..eeef363036 100644
--- a/gdb/sparc64-obsd-nat.c
+++ b/gdb/sparc64-obsd-nat.c
@@ -123,7 +123,7 @@ _initialize_sparc64obsd_nat (void)
   sparc_fpregmap = &sparc64_bsd_fpregmap;
 
   /* Add some extra features to the generic SPARC target.  */
-  add_target (&the_sparc64_obsd_nat_target);
+  add_inf_child_target (&the_sparc64_obsd_nat_target);
 
   /* Support debugging kernel virtual memory images.  */
   bsd_kvm_add_target (sparc64obsd_supply_pcb);
diff --git a/gdb/spu-linux-nat.c b/gdb/spu-linux-nat.c
index 8b4c643b2c..c289bb75fe 100644
--- a/gdb/spu-linux-nat.c
+++ b/gdb/spu-linux-nat.c
@@ -658,5 +658,5 @@ spu_linux_nat_target::can_use_hw_breakpoint (enum bptype type,
 void 
 _initialize_spu_nat (void)
 {
-  add_target (&the_spu_linux_nat_target);
+  add_inf_child_target (&the_spu_linux_nat_target);
 }
diff --git a/gdb/spu-multiarch.c b/gdb/spu-multiarch.c
index 1886807d37..5da5e4e7fc 100644
--- a/gdb/spu-multiarch.c
+++ b/gdb/spu-multiarch.c
@@ -36,19 +36,19 @@
 
 /* The SPU multi-architecture support target.  */
 
+static const target_info spu_multiarch_target_info = {
+  "spu",
+  N_("SPU multi-architecture support."),
+  N_("SPU multi-architecture support.")
+};
+
 struct spu_multiarch_target final : public target_ops
 {
   spu_multiarch_target ()
   { to_stratum = arch_stratum; };
 
-  const char *shortname () override
-  { return "spu"; }
-
-  const char *longname () override
-  { return _("SPU multi-architecture support."); }
-
-  const char *doc () override
-  { return _("SPU multi-architecture support."); }
+  const target_info &info () const override
+  { return spu_multiarch_target_info; }
 
   void mourn_inferior () override;
 
diff --git a/gdb/target-delegates.c b/gdb/target-delegates.c
index c06b700d6f..da74347122 100644
--- a/gdb/target-delegates.c
+++ b/gdb/target-delegates.c
@@ -8,9 +8,7 @@ struct dummy_target : public target_ops
 {
   dummy_target ();
 
-  const char *shortname () override;
-  const char *longname () override;
-  const char *doc () override;
+  const target_info &info () const override;
 
   void post_attach (int arg0) override;
   void detach (inferior *arg0, int arg1) override;
@@ -178,9 +176,7 @@ struct debug_target : public target_ops
 {
   debug_target ();
 
-  const char *shortname () override;
-  const char *longname () override;
-  const char *doc () override;
+  const target_info &info () const override;
 
   void post_attach (int arg0) override;
   void detach (inferior *arg0, int arg1) override;
diff --git a/gdb/target.c b/gdb/target.c
index 3ed5537e2d..b957769a3f 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -49,6 +49,7 @@
 #include "byte-vector.h"
 #include "terminal.h"
 #include <algorithm>
+#include <unordered_map>
 
 static void generic_tls_error (void) ATTRIBUTE_NORETURN;
 
@@ -103,10 +104,14 @@ static const char *default_pid_to_str (struct target_ops *ops, ptid_t ptid);
 static enum exec_direction_kind default_execution_direction
     (struct target_ops *self);
 
-/* Vector of existing target structures. */
-typedef struct target_ops *target_ops_p;
-DEF_VEC_P (target_ops_p);
-static VEC (target_ops_p) *target_structs;
+/* Mapping between target_info objects (which have address identity)
+   and corresponding open/factory function/callback.  Each add_target
+   call adds one entry to this map, and registers a "target
+   TARGET_NAME" command that when invoked calls the factory registered
+   here.  The target_info object is associated with the command via
+   the command's context.  */
+static std::unordered_map<const target_info *, target_open_ftype *>
+  target_factories;
 
 /* The initial current target, so that there is always a semi-valid
    current target.  */
@@ -179,6 +184,27 @@ target_command (const char *arg, int from_tty)
 		  gdb_stdout);
 }
 
+#if GDB_SELF_TEST
+namespace selftests {
+
+/* A mock process_stratum target_ops that doesn't read/write registers
+   anywhere.  */
+
+static const target_info test_target_info = {
+  "test",
+  N_("unit tests target"),
+  N_("You should never see this"),
+};
+
+const target_info &
+test_target_ops::info () const
+{
+  return test_target_info;
+}
+
+} /* namespace selftests */
+#endif /* GDB_SELF_TEST */
+
 /* Default target_has_* methods for process_stratum targets.  */
 
 int
@@ -304,30 +330,29 @@ target_has_execution_current (void)
 static void
 open_target (const char *args, int from_tty, struct cmd_list_element *command)
 {
-  struct target_ops *ops = (struct target_ops *) get_cmd_context (command);
+  auto *ti = static_cast<target_info *> (get_cmd_context (command));
+  target_open_ftype *func = target_factories[ti];
 
   if (targetdebug)
-    fprintf_unfiltered (gdb_stdlog, "-> %s->to_open (...)\n",
-			ops->shortname ());
+    fprintf_unfiltered (gdb_stdlog, "-> %s->open (...)\n",
+			ti->shortname);
 
-  ops->open (args, from_tty);
+  func (args, from_tty);
 
   if (targetdebug)
-    fprintf_unfiltered (gdb_stdlog, "<- %s->to_open (%s, %d)\n",
-			ops->shortname (), args, from_tty);
+    fprintf_unfiltered (gdb_stdlog, "<- %s->open (%s, %d)\n",
+			ti->shortname, args, from_tty);
 }
 
-/* Add possible target architecture T to the list and add a new
-   command 'target T->shortname ()'.  Set COMPLETER as the command's
-   completer if not NULL.  */
+/* See target.h.  */
 
 void
-add_target_with_completer (struct target_ops *t,
-			   completer_ftype *completer)
+add_target (const target_info &t, target_open_ftype *func,
+	    completer_ftype *completer)
 {
   struct cmd_list_element *c;
 
-  VEC_safe_push (target_ops_p, target_structs, t);
+  target_factories[&t] = func;
 
   if (targetlist == NULL)
     add_prefix_cmd ("target", class_run, target_command, _("\
@@ -337,35 +362,27 @@ Remaining arguments are interpreted by the target protocol.  For more\n\
 information on the arguments for a particular protocol, type\n\
 `help target ' followed by the protocol name."),
 		    &targetlist, "target ", 0, &cmdlist);
-  c = add_cmd (t->shortname (), no_class, t->doc (), &targetlist);
+  c = add_cmd (t.shortname, no_class, t.doc, &targetlist);
+  set_cmd_context (c, (void *) &t);
   set_cmd_sfunc (c, open_target);
-  set_cmd_context (c, t);
   if (completer != NULL)
     set_cmd_completer (c, completer);
 }
 
-/* Add a possible target architecture to the list.  */
-
-void
-add_target (struct target_ops *t)
-{
-  add_target_with_completer (t, NULL);
-}
-
 /* See target.h.  */
 
 void
-add_deprecated_target_alias (struct target_ops *t, const char *alias)
+add_deprecated_target_alias (const target_info &tinfo, const char *alias)
 {
   struct cmd_list_element *c;
   char *alt;
 
   /* If we use add_alias_cmd, here, we do not get the deprecated warning,
      see PR cli/15104.  */
-  c = add_cmd (alias, no_class, t->doc (), &targetlist);
+  c = add_cmd (alias, no_class, tinfo.doc, &targetlist);
   set_cmd_sfunc (c, open_target);
-  set_cmd_context (c, t);
-  alt = xstrprintf ("target %s", t->shortname ());
+  set_cmd_context (c, (void *) &tinfo);
+  alt = xstrprintf ("target %s", tinfo.shortname);
   deprecate_cmd (c, alt);
 }
 
@@ -2420,6 +2437,27 @@ show_auto_connect_native_target (struct ui_file *file, int from_tty,
 		    value);
 }
 
+/* A pointer to the target that can respond to "run" or "attach".
+   Native targets are always singletons and instantiated early at GDB
+   startup.  */
+static target_ops *the_native_target;
+
+/* See target.h.  */
+
+void
+set_native_target (target_ops *target)
+{
+  the_native_target = target;
+}
+
+/* See target.h.  */
+
+target_ops *
+get_native_target ()
+{
+  return the_native_target;
+}
+
 /* Look through the list of possible targets for a target that can
    execute a run or attach command without any other data.  This is
    used to locate the default process stratum.
@@ -2430,36 +2468,12 @@ show_auto_connect_native_target (struct ui_file *file, int from_tty,
 static struct target_ops *
 find_default_run_target (const char *do_mesg)
 {
-  struct target_ops *runable = NULL;
-
-  if (auto_connect_native_target)
-    {
-      struct target_ops *t;
-      int count = 0;
-      int i;
-
-      for (i = 0; VEC_iterate (target_ops_p, target_structs, i, t); ++i)
-	{
-	  if (t->can_run ())
-	    {
-	      runable = t;
-	      ++count;
-	    }
-	}
-
-      if (count != 1)
-	runable = NULL;
-    }
-
-  if (runable == NULL)
-    {
-      if (do_mesg)
-	error (_("Don't know how to %s.  Try \"help target\"."), do_mesg);
-      else
-	return NULL;
-    }
+  if (auto_connect_native_target && the_native_target != NULL)
+    return the_native_target;
 
-  return runable;
+  if (do_mesg != NULL)
+    error (_("Don't know how to %s.  Try \"help target\"."), do_mesg);
+  return NULL;
 }
 
 /* See target.h.  */
@@ -2467,20 +2481,15 @@ find_default_run_target (const char *do_mesg)
 struct target_ops *
 find_attach_target (void)
 {
-  struct target_ops *t;
-
   /* If a target on the current stack can attach, use it.  */
-  for (t = target_stack; t != NULL; t = t->beneath)
+  for (target_ops *t = target_stack; t != NULL; t = t->beneath)
     {
       if (t->can_attach ())
-	break;
+	return t;
     }
 
   /* Otherwise, use the default run target for attaching.  */
-  if (t == NULL)
-    t = find_default_run_target ("attach");
-
-  return t;
+  return find_default_run_target ("attach");
 }
 
 /* See target.h.  */
@@ -2488,20 +2497,15 @@ find_attach_target (void)
 struct target_ops *
 find_run_target (void)
 {
-  struct target_ops *t;
-
   /* If a target on the current stack can run, use it.  */
-  for (t = target_stack; t != NULL; t = t->beneath)
+  for (target_ops *t = target_stack; t != NULL; t = t->beneath)
     {
       if (t->can_create_inferior ())
-	break;
+	return t;
     }
 
   /* Otherwise, use the default run target.  */
-  if (t == NULL)
-    t = find_default_run_target ("run");
-
-  return t;
+  return find_default_run_target ("run");
 }
 
 bool
@@ -2614,12 +2618,6 @@ target_thread_address_space (ptid_t ptid)
   return aspace;
 }
 
-void
-target_ops::open (const char *, int)
-{
-  gdb_assert_not_reached ("target_ops::open called");
-}
-
 void
 target_ops::close ()
 {
@@ -3332,50 +3330,32 @@ dummy_make_corefile_notes (struct target_ops *self,
 #include "target-delegates.c"
 
 
+static const target_info dummy_target_info = {
+  "None",
+  N_("None"),
+  ""
+};
+
 dummy_target::dummy_target ()
 {
   to_stratum = dummy_stratum;
 }
 
-const char *
-dummy_target::shortname ()
-{
-  return "None";
-}
-
-const char *
-dummy_target::longname ()
-{
-  return _("None");
-}
-
-const char *
-dummy_target::doc ()
-{
-  return "";
-}
-
 debug_target::debug_target ()
 {
   to_stratum = debug_stratum;
 }
 
-const char *
-debug_target::shortname ()
+const target_info &
+dummy_target::info () const
 {
-  return beneath->shortname ();
+  return dummy_target_info;
 }
 
-const char *
-debug_target::longname ()
-{
-  return beneath->longname ();
-}
-
-const char *
-debug_target::doc ()
+const target_info &
+debug_target::info () const
 {
-  return beneath->doc ();
+  return beneath->info ();
 }
 
 \f
diff --git a/gdb/target.h b/gdb/target.h
index cd49fce92b..b37702b501 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -404,27 +404,44 @@ typedef void async_callback_ftype (enum inferior_event_type event_type,
 #define TARGET_DEFAULT_RETURN(ARG)
 #define TARGET_DEFAULT_FUNC(ARG)
 
+/* Each target that can be activated with "target TARGET_NAME" passes
+   the address of one of these objects to add_target, which uses the
+   object's address as unique identifier, and registers the "target
+   TARGET_NAME" command using SHORTNAME as target name.  */
+
+struct target_info
+{
+  /* Name of this target.  */
+  const char *shortname;
+
+  /* Name for printing.  */
+  const char *longname;
+
+  /* Documentation.  Does not include trailing newline, and starts
+     with a one-line description (probably similar to longname).  */
+  const char *doc;
+};
+
 struct target_ops
   {
     struct target_ops *beneath;	/* To the target under this one.  */
 
+    /* Free resources associated with the target.  Note that singleton
+       targets, like e.g., native targets, are global objects, not
+       heap allocated, and are thus only deleted on GDB exit.  The
+       main teardown entry point is the "close" method, below.  */
     virtual ~target_ops () {}
 
-    /* Name this target type.  */
-    virtual const char *shortname () = 0;
-
-    /* Name for printing.  */
-    virtual const char *longname () = 0;
+    /* Return a reference to this target's unique target_info
+       object.  */
+    virtual const target_info &info () const = 0;
 
-    /* Documentation.  Does not include trailing newline, and starts
-       ith a one-line description (probably similar to longname).  */
-    virtual const char *doc () = 0;
+    /* Name this target type.  */
+    const char *shortname ()
+    { return info ().shortname; }
 
-    /* The open routine takes the rest of the parameters from the
-       command, and (if successful) pushes a new target onto the
-       stack.  Targets should supply this routine, if only to provide
-       an error message.  */
-    virtual void open (const char *, int);
+    const char *longname ()
+    { return info ().longname; }
 
     /* Close the target.  This is where the target can handle
        teardown.  Heap-allocated targets should delete themselves
@@ -1226,6 +1243,15 @@ struct target_ops
       TARGET_DEFAULT_IGNORE ();
   };
 
+/* Native target backends call this once at initialization time to
+   inform the core about which is the target that can respond to "run"
+   or "attach".  Note: native targets are always singletons.  */
+extern void set_native_target (target_ops *target);
+
+/* Get the registered native target, if there's one.  Otherwise return
+   NULL.  */
+extern target_ops *get_native_target ();
+
 /* The ops structure for our "current" target process.  This should
    never be NULL.  If there is no target, it points to the dummy_target.  */
 
@@ -2207,15 +2233,25 @@ int target_verify_memory (const gdb_byte *data,
    no matter where it is on the list.  Returns 0 if no
    change, 1 if removed from stack.  */
 
-extern void add_target (struct target_ops *);
+/* Type of callback called when the user activates a target with
+   "target TARGET_NAME".  The callback routine takes the rest of the
+   parameters from the command, and (if successful) pushes a new
+   target onto the stack.  */
+typedef void target_open_ftype (const char *args, int from_tty);
+
+/* Add the target described by INFO to the list of possible targets
+   and add a new command 'target $(INFO->shortname)'.  Set COMPLETER
+   as the command's completer if not NULL.  */
 
-extern void add_target_with_completer (struct target_ops *t,
-				       completer_ftype *completer);
+extern void add_target (const target_info &info,
+			target_open_ftype *func,
+			completer_ftype *completer = NULL);
 
-/* Adds a command ALIAS for target T and marks it deprecated.  This is useful
-   for maintaining backwards compatibility when renaming targets.  */
+/* Adds a command ALIAS for the target described by INFO and marks it
+   deprecated.  This is useful for maintaining backwards compatibility
+   when renaming targets.  */
 
-extern void add_deprecated_target_alias (struct target_ops *t,
+extern void add_deprecated_target_alias (const target_info &info,
 					 const char *alias);
 
 extern void push_target (struct target_ops *);
@@ -2466,20 +2502,7 @@ public:
     to_stratum = process_stratum;
   }
 
-  const char *shortname () override
-  {
-    return NULL;
-  }
-
-  const char *longname () override
-  {
-    return NULL;
-  }
-
-  const char *doc () override
-  {
-    return NULL;
-  }
+  const target_info &info () const override;
 
   bool has_registers () override
   {
diff --git a/gdb/tilegx-linux-nat.c b/gdb/tilegx-linux-nat.c
index 0df98e6ffc..ad61ade520 100644
--- a/gdb/tilegx-linux-nat.c
+++ b/gdb/tilegx-linux-nat.c
@@ -167,5 +167,5 @@ tilegx_linux_nat_target::store_registers (struct regcache *regcache,
 void
 _initialize_tile_linux_nat (void)
 {
-  add_target (&the_tilegx_linux_nat_target);
+  add_inf_child_target (&the_tilegx_linux_nat_target);
 }
diff --git a/gdb/tracefile-tfile.c b/gdb/tracefile-tfile.c
index d224ad9760..f4fdd3674d 100644
--- a/gdb/tracefile-tfile.c
+++ b/gdb/tracefile-tfile.c
@@ -40,22 +40,18 @@
 
 /* The tfile target.  */
 
+static const target_info tfile_target_info = {
+  "tfile",
+  N_("Local trace dump file"),
+  N_("Use a trace file as a target.  Specify the filename of the trace file.")
+};
+
 class tfile_target final : public tracefile_target
 {
  public:
-  const char *shortname () override
-  { return "tfile"; }
-
-  const char *longname () override
-  { return _("Local trace dump file"); }
-
-  const char *doc () override
-  {
-    return _("\
-Use a trace file as a target.  Specify the filename of the trace file.");
-  }
+  const target_info &info () const override
+  { return tfile_target_info; }
 
-  void open (const char *, int) override;
   void close () override;
   void fetch_registers (struct regcache *, int) override;
   enum target_xfer_status xfer_partial (enum target_object object,
@@ -451,8 +447,10 @@ tfile_read (gdb_byte *readbuf, int size)
     error (_("Premature end of file while reading trace file"));
 }
 
-void
-tfile_target::open (const char *arg, int from_tty)
+/* Open the tfile target.  */
+
+static void
+tfile_target_open (const char *arg, int from_tty)
 {
   int flags;
   int scratch_chan;
@@ -1139,5 +1137,5 @@ tfile_append_tdesc_line (const char *line)
 void
 _initialize_tracefile_tfile (void)
 {
-  add_target_with_completer (&tfile_ops, filename_completer);
+  add_target (tfile_target_info, tfile_target_open, filename_completer);
 }
diff --git a/gdb/vax-bsd-nat.c b/gdb/vax-bsd-nat.c
index 19c7a33a8c..3fd16004b8 100644
--- a/gdb/vax-bsd-nat.c
+++ b/gdb/vax-bsd-nat.c
@@ -135,7 +135,7 @@ vaxbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
 void
 _initialize_vaxbsd_nat (void)
 {
-  add_target (&the_vax_bsd_nat_target);
+  add_inf_child_target (&the_vax_bsd_nat_target);
 
   /* Support debugging kernel virtual memory images.  */
   bsd_kvm_add_target (vaxbsd_supply_pcb);
diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index f5a66c1f1c..16ebd17607 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -3018,7 +3018,7 @@ _initialize_windows_nat (void)
      calling x86_set_debug_register_length function
      in processor windows specific native file.  */
 
-  add_target (&the_windows_nat_target);
+  add_inf_child_target (&the_windows_nat_target);
 
 #ifdef __CYGWIN__
   cygwin_internal (CW_SET_DOS_FILE_WARNING, 0);
diff --git a/gdb/xtensa-linux-nat.c b/gdb/xtensa-linux-nat.c
index 2acffbfbdf..f6ef6107fa 100644
--- a/gdb/xtensa-linux-nat.c
+++ b/gdb/xtensa-linux-nat.c
@@ -364,5 +364,5 @@ _initialize_xtensa_linux_nat (void)
 	xtreg_high = ptr->gdb_regnum;
     }
 
-  add_target (&the_xtensa_linux_nat_target);
+  add_inf_child_target (&the_xtensa_linux_nat_target);
 }
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 03/40] target_ops/C++: exec target
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
  2018-04-14 19:10 ` [PATCH 02/40] make-target-delegates: line break between return type and function name Pedro Alves
  2018-04-14 19:10 ` [PATCH 17/40] target_ops/C++: macOS/Darwin target Pedro Alves
@ 2018-04-14 19:10 ` Pedro Alves
  2018-04-14 19:10 ` [PATCH 07/40] target_ops/C++: ravenscar-thread Pedro Alves
                   ` (38 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:10 UTC (permalink / raw)
  To: gdb-patches

Straighforward conversion.
---
 gdb/exec.c    | 139 ++++++++++++++++++++++++----------------------------------
 gdb/gdbcore.h |   2 -
 2 files changed, 58 insertions(+), 83 deletions(-)

diff --git a/gdb/exec.c b/gdb/exec.c
index f94c15f1f5..14d0668591 100644
--- a/gdb/exec.c
+++ b/gdb/exec.c
@@ -49,15 +49,43 @@
 
 void (*deprecated_file_changed_hook) (const char *);
 
-/* Prototypes for local functions */
-
-static void exec_files_info (struct target_ops *);
-
-static void init_exec_ops (void);
-
 /* The target vector for executable files.  */
 
-static struct target_ops exec_ops;
+struct exec_target final : public target_ops
+{
+  exec_target ()
+  { to_stratum = file_stratum; }
+
+  const char *shortname () override
+  { return "exec"; }
+
+  const char *longname () override
+  { return _("Local exec file"); }
+
+  const char *doc () override
+  {
+    return _("\
+Use an executable file as a target.\n\
+Specify the filename of the executable file.");
+  }
+
+  void open (const char *, int) override;
+  void close () override;
+  enum target_xfer_status xfer_partial (enum target_object object,
+					const char *annex,
+					gdb_byte *readbuf,
+					const gdb_byte *writebuf,
+					ULONGEST offset, ULONGEST len,
+					ULONGEST *xfered_len) override;
+  struct target_section_table *get_section_table () override;
+  void files_info () override;
+
+  int has_memory () override;
+  char *make_corefile_notes (bfd *, int *) override;
+  int find_memory_regions (find_memory_region_ftype func, void *data) override;
+};
+
+static exec_target exec_ops;
 
 /* Whether to open exec and core files read-only or read-write.  */
 
@@ -71,8 +99,8 @@ show_write_files (struct ui_file *file, int from_tty,
 }
 
 
-static void
-exec_open (const char *args, int from_tty)
+void
+exec_target::open (const char *args, int from_tty)
 {
   target_preopen (from_tty);
   exec_file_attach (args, from_tty);
@@ -105,8 +133,8 @@ exec_close (void)
 /* This is the target_close implementation.  Clears all target
    sections and closes all executable bfds from all program spaces.  */
 
-static void
-exec_close_1 (struct target_ops *self)
+void
+exec_target::close ()
 {
   struct program_space *ss;
   scoped_restore_current_program_space restore_pspace;
@@ -119,17 +147,7 @@ exec_close_1 (struct target_ops *self)
     }
 }
 
-void
-exec_file_clear (int from_tty)
-{
-  /* Remove exec file.  */
-  exec_close ();
-
-  if (from_tty)
-    printf_unfiltered (_("No executable file now.\n"));
-}
-
-/* See exec.h.  */
+/* See gdbcore.h.  */
 
 void
 try_open_exec_file (const char *exec_file_host, struct inferior *inf,
@@ -846,19 +864,19 @@ section_table_xfer_memory_partial (gdb_byte *readbuf, const gdb_byte *writebuf,
   return TARGET_XFER_EOF;		/* We can't help.  */
 }
 
-static struct target_section_table *
-exec_get_section_table (struct target_ops *ops)
+struct target_section_table *
+exec_target::get_section_table ()
 {
   return current_target_sections;
 }
 
-static enum target_xfer_status
-exec_xfer_partial (struct target_ops *ops, enum target_object object,
-		   const char *annex, gdb_byte *readbuf,
-		   const gdb_byte *writebuf,
-		   ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
+enum target_xfer_status
+exec_target::xfer_partial (enum target_object object,
+			   const char *annex, gdb_byte *readbuf,
+			   const gdb_byte *writebuf,
+			   ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
 {
-  struct target_section_table *table = target_get_section_table (ops);
+  struct target_section_table *table = get_section_table ();
 
   if (object == TARGET_OBJECT_MEMORY)
     return section_table_xfer_memory_partial (readbuf, writebuf,
@@ -940,8 +958,8 @@ print_section_info (struct target_section_table *t, bfd *abfd)
     }
 }
 
-static void
-exec_files_info (struct target_ops *t)
+void
+exec_target::files_info ()
 {
   if (exec_bfd)
     print_section_info (current_target_sections, exec_bfd);
@@ -981,7 +999,7 @@ set_section_command (const char *args, int from_tty)
 	  p->addr += offset;
 	  p->endaddr += offset;
 	  if (from_tty)
-	    exec_files_info (&exec_ops);
+	    exec_ops.files_info ();
 	  return;
 	}
     }
@@ -1013,29 +1031,8 @@ exec_set_section_address (const char *filename, int index, CORE_ADDR address)
     }
 }
 
-/* If mourn is being called in all the right places, this could be say
-   `gdb internal error' (since generic_mourn calls
-   breakpoint_init_inferior).  */
-
-static int
-ignore (struct target_ops *ops, struct gdbarch *gdbarch,
-	struct bp_target_info *bp_tgt)
-{
-  return 0;
-}
-
-/* Implement the to_remove_breakpoint method.  */
-
-static int
-exec_remove_breakpoint (struct target_ops *ops, struct gdbarch *gdbarch,
-			struct bp_target_info *bp_tgt,
-			enum remove_bp_reason reason)
-{
-  return 0;
-}
-
-static int
-exec_has_memory (struct target_ops *ops)
+int
+exec_target::has_memory ()
 {
   /* We can provide memory if we have any file/target sections to read
      from.  */
@@ -1043,34 +1040,16 @@ exec_has_memory (struct target_ops *ops)
 	  != current_target_sections->sections_end);
 }
 
-static char *
-exec_make_note_section (struct target_ops *self, bfd *obfd, int *note_size)
+char *
+exec_target::make_corefile_notes (bfd *obfd, int *note_size)
 {
   error (_("Can't create a corefile"));
 }
 
-/* Fill in the exec file target vector.  Very few entries need to be
-   defined.  */
-
-static void
-init_exec_ops (void)
+int
+exec_target::find_memory_regions (find_memory_region_ftype func, void *data)
 {
-  exec_ops.to_shortname = "exec";
-  exec_ops.to_longname = "Local exec file";
-  exec_ops.to_doc = "Use an executable file as a target.\n\
-Specify the filename of the executable file.";
-  exec_ops.to_open = exec_open;
-  exec_ops.to_close = exec_close_1;
-  exec_ops.to_xfer_partial = exec_xfer_partial;
-  exec_ops.to_get_section_table = exec_get_section_table;
-  exec_ops.to_files_info = exec_files_info;
-  exec_ops.to_insert_breakpoint = ignore;
-  exec_ops.to_remove_breakpoint = exec_remove_breakpoint;
-  exec_ops.to_stratum = file_stratum;
-  exec_ops.to_has_memory = exec_has_memory;
-  exec_ops.to_make_corefile_notes = exec_make_note_section;
-  exec_ops.to_find_memory_regions = objfile_find_memory_regions;
-  exec_ops.to_magic = OPS_MAGIC;
+  return objfile_find_memory_regions (this, func, data);
 }
 
 void
@@ -1078,8 +1057,6 @@ _initialize_exec (void)
 {
   struct cmd_list_element *c;
 
-  init_exec_ops ();
-
   if (!dbx_commands)
     {
       c = add_cmd ("file", class_files, file_command, _("\
diff --git a/gdb/gdbcore.h b/gdb/gdbcore.h
index fef7879e99..5264eef4ee 100644
--- a/gdb/gdbcore.h
+++ b/gdb/gdbcore.h
@@ -153,8 +153,6 @@ extern void exec_file_attach (const char *filename, int from_tty);
 
 extern void exec_file_locate_attach (int pid, int defer_bp_reset, int from_tty);
 
-extern void exec_file_clear (int from_tty);
-
 extern void validate_files (void);
 
 /* The current default bfd target.  */
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 32/40] target_ops/C++: Generic i386/AMD64 BSD targets
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (4 preceding siblings ...)
  2018-04-14 19:10 ` [PATCH 38/40] target_ops: Use bool throughout Pedro Alves
@ 2018-04-14 19:10 ` Pedro Alves
  2018-04-14 19:10 ` [PATCH 29/40] target_ops/C++: Tile-Gx GNU/Linux Pedro Alves
                   ` (35 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:10 UTC (permalink / raw)
  To: gdb-patches

The

  $architecture x NetBSD/OpenBSD/FreeBSD

support matrix complicates things a bit.  There's common BSD target
code, and there's common architecture-specific code shared between the
different BSDs.  Current, all that is stiched together to form a final
target, via the i386bsd_target, x86bsd_target, fbsd_nat_add_target
functions etc.

Introduces generic i386/AMD64 BSD targets, to be used as template
mixin to build a final target.
---
 gdb/amd64-bsd-nat.c  | 24 ++++--------------------
 gdb/amd64-bsd-nat.h  | 44 ++++++++++++++++++++++++++++++++++++++++++++
 gdb/amd64-fbsd-nat.c | 26 +++++++++++++++-----------
 gdb/amd64-nat.h      |  5 -----
 gdb/i386-bsd-nat.c   | 24 ++++--------------------
 gdb/i386-bsd-nat.h   | 22 ++++++++++++++++++----
 gdb/i386-fbsd-nat.c  | 37 ++++++++++++++++++++-----------------
 gdb/x86-bsd-nat.c    | 27 ++-------------------------
 gdb/x86-bsd-nat.h    | 21 +++++++++++++++++----
 9 files changed, 124 insertions(+), 106 deletions(-)
 create mode 100644 gdb/amd64-bsd-nat.h

diff --git a/gdb/amd64-bsd-nat.c b/gdb/amd64-bsd-nat.c
index d3a516f875..74a1842de9 100644
--- a/gdb/amd64-bsd-nat.c
+++ b/gdb/amd64-bsd-nat.c
@@ -38,9 +38,8 @@
 /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
    for all registers (including the floating-point registers).  */
 
-static void
-amd64bsd_fetch_inferior_registers (struct target_ops *ops,
-				   struct regcache *regcache, int regnum)
+void
+amd64bsd_fetch_inferior_registers (struct regcache *regcache, int regnum)
 {
   struct gdbarch *gdbarch = regcache->arch ();
   pid_t pid = get_ptrace_pid (regcache_get_ptid (regcache));
@@ -112,9 +111,8 @@ amd64bsd_fetch_inferior_registers (struct target_ops *ops,
 /* Store register REGNUM back into the inferior.  If REGNUM is -1, do
    this for all registers (including the floating-point registers).  */
 
-static void
-amd64bsd_store_inferior_registers (struct target_ops *ops,
-				   struct regcache *regcache, int regnum)
+void
+amd64bsd_store_inferior_registers (struct regcache *regcache, int regnum)
 {
   struct gdbarch *gdbarch = regcache->arch ();
   pid_t pid = get_ptrace_pid (regcache_get_ptid (regcache));
@@ -193,17 +191,3 @@ amd64bsd_store_inferior_registers (struct target_ops *ops,
 	perror_with_name (_("Couldn't write floating point status"));
     }
 }
-
-/* Create a prototype *BSD/amd64 target.  The client can override it
-   with local methods.  */
-
-struct target_ops *
-amd64bsd_target (void)
-{
-  struct target_ops *t;
-
-  t = x86bsd_target ();
-  t->to_fetch_registers = amd64bsd_fetch_inferior_registers;
-  t->to_store_registers = amd64bsd_store_inferior_registers;
-  return t;
-}
diff --git a/gdb/amd64-bsd-nat.h b/gdb/amd64-bsd-nat.h
new file mode 100644
index 0000000000..84528ca625
--- /dev/null
+++ b/gdb/amd64-bsd-nat.h
@@ -0,0 +1,44 @@
+/* Native-dependent code for modern AMD64 BSD's.
+
+   Copyright (C) 2018 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef AMD64_BSD_NAT_H
+#define AMD64_BSD_NAT_H
+
+#include "x86-bsd-nat.h"
+
+/* Helper functions.  See definitions.  */
+extern void amd64bsd_fetch_inferior_registers (struct regcache *regcache,
+					       int regnum);
+extern void amd64bsd_store_inferior_registers (struct regcache *regcache,
+					       int regnum);
+
+/* A prototype *BSD/AMD64 target.  */
+
+template<typename BaseTarget>
+class amd64_bsd_nat_target : public x86bsd_nat_target<BaseTarget>
+{
+public:
+  void fetch_registers (struct regcache *regcache, int regnum) override
+  { amd64bsd_fetch_inferior_registers (regcache, regnum); }
+
+  void store_registers (struct regcache *regcache, int regnum) override
+  { amd64bsd_store_inferior_registers (regcache, regnum); }
+};
+
+#endif /* i386-bsd-nat.h */
diff --git a/gdb/amd64-fbsd-nat.c b/gdb/amd64-fbsd-nat.c
index 07963f508d..d1c62d79e8 100644
--- a/gdb/amd64-fbsd-nat.c
+++ b/gdb/amd64-fbsd-nat.c
@@ -32,11 +32,21 @@
 #include "fbsd-nat.h"
 #include "amd64-tdep.h"
 #include "amd64-nat.h"
-#include "x86-bsd-nat.h"
+#include "amd64-bsd-nat.h"
 #include "x86-nat.h"
 #include "x86-xstate.h"
 \f
 
+class amd64_fbsd_nat_target final
+  : public amd64_bsd_nat_target<fbsd_nat_target>
+{
+public:
+  /* Add some extra features to the common *BSD/i386 target.  */
+  const struct target_desc *read_description () override;
+};
+
+static amd64_fbsd_nat_target the_amd64_fbsd_nat_target;
+
 /* Offset in `struct reg' where MEMBER is stored.  */
 #define REG_OFFSET(member) offsetof (struct reg, member)
 
@@ -141,10 +151,10 @@ amd64fbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
 }
 \f
 
-/* Implement the to_read_description method.  */
+/* Implement the read_description method.  */
 
-static const struct target_desc *
-amd64fbsd_read_description (struct target_ops *ops)
+const struct target_desc *
+amd64_fbsd_nat_target::read_description (struct target_ops *ops)
 {
 #ifdef PT_GETXSTATE_INFO
   static int xsave_probed;
@@ -188,18 +198,12 @@ amd64fbsd_read_description (struct target_ops *ops)
 void
 _initialize_amd64fbsd_nat (void)
 {
-  struct target_ops *t;
+  struct target_ops *t = &the_amd64_fbsd_nat_target;
   int offset;
 
   amd64_native_gregset32_reg_offset = amd64fbsd32_r_reg_offset;
   amd64_native_gregset64_reg_offset = amd64fbsd64_r_reg_offset;
 
-  /* Add some extra features to the common *BSD/i386 target.  */
-  t = amd64bsd_target ();
-  t->to_read_description = amd64fbsd_read_description;
-
-  fbsd_nat_add_target (t);
-
   /* Support debugging kernel virtual memory images.  */
   bsd_kvm_add_target (amd64fbsd_supply_pcb);
 
diff --git a/gdb/amd64-nat.h b/gdb/amd64-nat.h
index c1a4a87cd4..11bddf5c9e 100644
--- a/gdb/amd64-nat.h
+++ b/gdb/amd64-nat.h
@@ -49,9 +49,4 @@ extern void amd64_supply_native_gregset (struct regcache *regcache,
 extern void amd64_collect_native_gregset (const struct regcache *regcache,
 					  void *gregs, int regnum);
 
-/* Create a prototype *BSD/amd64 target.  The client can override it
-   with local methods.  */
-
-extern struct target_ops *amd64bsd_target (void);
-
 #endif /* amd64-nat.h */
diff --git a/gdb/i386-bsd-nat.c b/gdb/i386-bsd-nat.c
index ef2b534129..f7f27ceba0 100644
--- a/gdb/i386-bsd-nat.c
+++ b/gdb/i386-bsd-nat.c
@@ -127,9 +127,8 @@ i386bsd_collect_gregset (const struct regcache *regcache,
 /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
    for all registers (including the floating point registers).  */
 
-static void
-i386bsd_fetch_inferior_registers (struct target_ops *ops,
-				  struct regcache *regcache, int regnum)
+void
+i386bsd_fetch_inferior_registers (struct regcache *regcache, int regnum)
 {
   pid_t pid = get_ptrace_pid (regcache_get_ptid (regcache));
 
@@ -191,9 +190,8 @@ i386bsd_fetch_inferior_registers (struct target_ops *ops,
 /* Store register REGNUM back into the inferior.  If REGNUM is -1, do
    this for all registers (including the floating point registers).  */
 
-static void
-i386bsd_store_inferior_registers (struct target_ops *ops,
-				  struct regcache *regcache, int regnum)
+void
+i386bsd_store_inferior_registers (struct regcache *regcache, int regnum)
 {
   pid_t pid = get_ptrace_pid (regcache_get_ptid (regcache));
 
@@ -267,20 +265,6 @@ i386bsd_store_inferior_registers (struct target_ops *ops,
     }
 }
 
-/* Create a prototype *BSD/i386 target.  The client can override it
-   with local methods.  */
-
-struct target_ops *
-i386bsd_target (void)
-{
-  struct target_ops *t;
-
-  t = x86bsd_target ();
-  t->to_fetch_registers = i386bsd_fetch_inferior_registers;
-  t->to_store_registers = i386bsd_store_inferior_registers;
-  return t;
-}
-
 void
 _initialize_i386bsd_nat (void)
 {
diff --git a/gdb/i386-bsd-nat.h b/gdb/i386-bsd-nat.h
index 72eec39274..b5acc70482 100644
--- a/gdb/i386-bsd-nat.h
+++ b/gdb/i386-bsd-nat.h
@@ -20,9 +20,23 @@
 #ifndef I386_BSD_NAT_H
 #define I386_BSD_NAT_H
 
-/* Create a prototype *BSD/i386 target.  The client can override it
-   with local methods.  */
-
-extern struct target_ops *i386bsd_target (void);
+/* Helper functions.  See definitions.  */
+extern void i386bsd_fetch_inferior_registers (struct regcache *regcache,
+					      int regnum);
+extern void i386bsd_store_inferior_registers (struct regcache *regcache,
+					      int regnum);
+
+/* A prototype *BSD/i386 target.  */
+
+template<typename BaseTarget>
+class i386_bsd_nat_target : public x86bsd_nat_target<BaseTarget>
+{
+public:
+  void fetch_registers (struct regcache *regcache, int regnum) override
+  { i386bsd_fetch_inferior_registers (regcache, regnum); }
+
+  void store_registers (struct regcache *, int) override
+  { i386bsd_store_inferior_registers (regcache, regnum); }
+};
 
 #endif /* i386-bsd-nat.h */
diff --git a/gdb/i386-fbsd-nat.c b/gdb/i386-fbsd-nat.c
index c7b8f9a1f9..f2bb82c4c0 100644
--- a/gdb/i386-fbsd-nat.c
+++ b/gdb/i386-fbsd-nat.c
@@ -34,12 +34,25 @@
 #include "x86-bsd-nat.h"
 #include "i386-bsd-nat.h"
 
+class i386_fbsd_nat_target final
+  : public i386_bsd_nat_target<fbsd_nat_target>
+{
+public:
+  /* Add some extra features to the common *BSD/i386 target.  */
+#ifdef PT_GETXSTATE_INFO
+  const struct target_desc *read_description () override;
+#endif
+
+  void resume (ptid_t, int, enum gdb_signal) override;
+};
+
+static i386_fbsd_nat_target the_i386_fbsd_nat_target;
+
 /* Resume execution of the inferior process.  If STEP is nonzero,
    single-step it.  If SIGNAL is nonzero, give it that signal.  */
 
-static void
-i386fbsd_resume (struct target_ops *ops,
-		 ptid_t ptid, int step, enum gdb_signal signal)
+void
+i386_fbsd_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signal)
 {
   pid_t pid = ptid_get_pid (ptid);
   int request = PT_STEP;
@@ -119,10 +132,10 @@ i386fbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
 \f
 
 #ifdef PT_GETXSTATE_INFO
-/* Implement the to_read_description method.  */
+/* Implement the read_description method.  */
 
-static const struct target_desc *
-i386fbsd_read_description (struct target_ops *ops)
+const struct target_desc *
+i386_fbsd_nat_traget::read_description ()
 {
   static int xsave_probed;
   static uint64_t xcr0;
@@ -150,17 +163,7 @@ i386fbsd_read_description (struct target_ops *ops)
 void
 _initialize_i386fbsd_nat (void)
 {
-  struct target_ops *t;
-
-  /* Add some extra features to the common *BSD/i386 target.  */
-  t = i386bsd_target ();
-
-#ifdef PT_GETXSTATE_INFO
-  t->to_read_description = i386fbsd_read_description;
-#endif
-
-  t->to_resume = i386fbsd_resume;
-  fbsd_nat_add_target (t);
+  add_target (&the_i386_fbsd_nat_target);
 
   /* Support debugging kernel virtual memory images.  */
   bsd_kvm_add_target (i386fbsd_supply_pcb);
diff --git a/gdb/x86-bsd-nat.c b/gdb/x86-bsd-nat.c
index dff2a004a5..542bcd0603 100644
--- a/gdb/x86-bsd-nat.c
+++ b/gdb/x86-bsd-nat.c
@@ -40,16 +40,6 @@ size_t x86bsd_xsave_len;
 /* Support for debug registers.  */
 
 #ifdef HAVE_PT_GETDBREGS
-static void (*super_mourn_inferior) (struct target_ops *ops);
-
-/* Implement the "to_mourn_inferior" target_ops method.  */
-
-static void
-x86bsd_mourn_inferior (struct target_ops *ops)
-{
-  x86_cleanup_dregs ();
-  super_mourn_inferior (ops);
-}
 
 /* Helper macro to access debug register X.  FreeBSD/amd64 and modern
    versions of FreeBSD/i386 provide this macro in system headers.  Define
@@ -134,28 +124,15 @@ x86bsd_dr_get_control (void)
 
 #endif /* PT_GETDBREGS */
 
-/* Create a prototype *BSD/x86 target.  The client can override it
-   with local methods.  */
-
-struct target_ops *
-x86bsd_target (void)
+void
+_initialize_x86_bsd_nat ()
 {
-  struct target_ops *t;
-
-  t = inf_ptrace_target ();
-
 #ifdef HAVE_PT_GETDBREGS
-  x86_use_watchpoints (t);
-
   x86_dr_low.set_control = x86bsd_dr_set_control;
   x86_dr_low.set_addr = x86bsd_dr_set_addr;
   x86_dr_low.get_addr = x86bsd_dr_get_addr;
   x86_dr_low.get_status = x86bsd_dr_get_status;
   x86_dr_low.get_control = x86bsd_dr_get_control;
   x86_set_debug_register_length (sizeof (void *));
-  super_mourn_inferior = t->to_mourn_inferior;
-  t->to_mourn_inferior = x86bsd_mourn_inferior;
 #endif /* HAVE_PT_GETDBREGS */
-
-  return t;
 }
diff --git a/gdb/x86-bsd-nat.h b/gdb/x86-bsd-nat.h
index ced33ac6aa..1aee5fbc46 100644
--- a/gdb/x86-bsd-nat.h
+++ b/gdb/x86-bsd-nat.h
@@ -20,12 +20,25 @@
 #ifndef X86_BSD_NAT_H
 #define X86_BSD_NAT_H
 
+#include "x86-nat.h"
+
 /* Low level x86 XSAVE info.  */
 extern size_t x86bsd_xsave_len;
 
-/* Create a prototype *BSD/x86 target.  The client can override it
-   with local methods.  */
-
-extern struct target_ops *x86bsd_target (void);
+/* A prototype *BSD/x86 target.  */
+
+template<typename BaseTarget>
+class x86bsd_nat_target : public x86_nat_target<BaseTarget>
+{
+  using base_class = x86_nat_target<BaseTarget>;
+public:
+#ifdef HAVE_PT_GETDBREGS
+  void mourn_inferior () override
+  {
+    x86_cleanup_dregs ();
+    base_class::mourn_inferior ();
+  }
+#endif /* HAVE_PT_GETDBREGS */
+};
 
 #endif /* x86-bsd-nat.h */
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 09/40] target_ops/C++: bfd-target
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (13 preceding siblings ...)
  2018-04-14 19:10 ` [PATCH 20/40] target_ops/C++: ARM GNU/Linux Pedro Alves
@ 2018-04-14 19:10 ` Pedro Alves
  2018-04-14 19:10 ` [PATCH 34/40] target_ops/C++: bsd_kvm_add_target, BSD libkvm target Pedro Alves
                   ` (26 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:10 UTC (permalink / raw)
  To: gdb-patches

Straighforward conversion.
---
 gdb/bfd-target.c | 104 +++++++++++++++++++++++++++++++------------------------
 1 file changed, 59 insertions(+), 45 deletions(-)

diff --git a/gdb/bfd-target.c b/gdb/bfd-target.c
index 99b49aad13..7ac8bc3c61 100644
--- a/gdb/bfd-target.c
+++ b/gdb/bfd-target.c
@@ -23,36 +23,58 @@
 #include "exec.h"
 #include "gdb_bfd.h"
 
-/* The object that is stored in the target_ops->to_data field has this
-   type.  */
-struct target_bfd_data
+/* A target that wraps a BFD.  */
+class target_bfd : public target_ops
 {
+public:
+  explicit target_bfd (struct bfd *bfd);
+  ~target_bfd () override;
+
+  const char *shortname () override
+  { return "bfd"; }
+
+  const char *longname () override
+  { return _("BFD backed target"); }
+
+  const char *doc () override
+  { return _("You should never see this"); }
+
+  void close () override;
+
+  target_xfer_status
+    xfer_partial (target_object object,
+		  const char *annex, gdb_byte *readbuf,
+		  const gdb_byte *writebuf,
+		  ULONGEST offset, ULONGEST len,
+		  ULONGEST *xfered_len) override;
+
+  target_section_table *get_section_table () override;
+
+private:
   /* The BFD we're wrapping.  */
-  struct bfd *bfd;
+  struct bfd *m_bfd;
 
   /* The section table build from the ALLOC sections in BFD.  Note
      that we can't rely on extracting the BFD from a random section in
      the table, since the table can be legitimately empty.  */
-  struct target_section_table table;
+  struct target_section_table m_table;
 };
 
-static enum target_xfer_status
-target_bfd_xfer_partial (struct target_ops *ops,
-			 enum target_object object,
-			 const char *annex, gdb_byte *readbuf,
-			 const gdb_byte *writebuf,
-			 ULONGEST offset, ULONGEST len,
-			 ULONGEST *xfered_len)
+target_xfer_status
+target_bfd::xfer_partial (target_object object,
+			  const char *annex, gdb_byte *readbuf,
+			  const gdb_byte *writebuf,
+			  ULONGEST offset, ULONGEST len,
+			  ULONGEST *xfered_len)
 {
   switch (object)
     {
     case TARGET_OBJECT_MEMORY:
       {
-	struct target_bfd_data *data = (struct target_bfd_data *) ops->to_data;
 	return section_table_xfer_memory_partial (readbuf, writebuf,
 						  offset, len, xfered_len,
-						  data->table.sections,
-						  data->table.sections_end,
+						  m_table.sections,
+						  m_table.sections_end,
 						  NULL);
       }
     default:
@@ -60,44 +82,36 @@ target_bfd_xfer_partial (struct target_ops *ops,
     }
 }
 
-static struct target_section_table *
-target_bfd_get_section_table (struct target_ops *ops)
+target_section_table *
+target_bfd::get_section_table ()
 {
-  struct target_bfd_data *data = (struct target_bfd_data *) ops->to_data;
-  return &data->table;
+  return &m_table;
 }
 
-static void
-target_bfd_close (struct target_ops *t)
+target_bfd::target_bfd (struct bfd *abfd)
 {
-  struct target_bfd_data *data = (struct target_bfd_data *) t->to_data;
+  this->to_stratum = file_stratum;
+  m_bfd = abfd;
+  gdb_bfd_ref (abfd);
+  m_table.sections = NULL;
+  m_table.sections_end = NULL;
+  build_section_table (abfd, &m_table.sections, &m_table.sections_end);
+}
 
-  gdb_bfd_unref (data->bfd);
-  xfree (data->table.sections);
-  xfree (data);
-  xfree (t);
+target_bfd::~target_bfd ()
+{
+  gdb_bfd_unref (m_bfd);
+  xfree (m_table.sections);
 }
 
-struct target_ops *
+target_ops *
 target_bfd_reopen (struct bfd *abfd)
 {
-  struct target_ops *t;
-  struct target_bfd_data *data;
+  return new target_bfd (abfd);
+}
 
-  data = XCNEW (struct target_bfd_data);
-  data->bfd = abfd;
-  gdb_bfd_ref (abfd);
-  build_section_table (abfd, &data->table.sections, &data->table.sections_end);
-
-  t = XCNEW (struct target_ops);
-  t->to_shortname = "bfd";
-  t->to_longname = _("BFD backed target");
-  t->to_doc = _("You should never see this");
-  t->to_get_section_table = target_bfd_get_section_table;
-  t->to_xfer_partial = target_bfd_xfer_partial;
-  t->to_close = target_bfd_close;
-  t->to_data = data;
-  t->to_magic = OPS_MAGIC;
-
-  return t;
+void
+target_bfd::close ()
+{
+  delete this;
 }
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 08/40] target_ops/C++: bsd-uthread
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (6 preceding siblings ...)
  2018-04-14 19:10 ` [PATCH 29/40] target_ops/C++: Tile-Gx GNU/Linux Pedro Alves
@ 2018-04-14 19:10 ` Pedro Alves
  2018-04-14 19:10 ` [PATCH 19/40] target_ops/C++: AIX target Pedro Alves
                   ` (33 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:10 UTC (permalink / raw)
  To: gdb-patches

Straighforward conversion.

The bsd_uthread_ops_hack hack is gone.  It's not needed because
nothing was extending a target created by bsd_uthread_target.
---
 gdb/bsd-uthread.c | 137 +++++++++++++++++++++++++++---------------------------
 1 file changed, 69 insertions(+), 68 deletions(-)

diff --git a/gdb/bsd-uthread.c b/gdb/bsd-uthread.c
index 6c9e3af77f..19d49c76f9 100644
--- a/gdb/bsd-uthread.c
+++ b/gdb/bsd-uthread.c
@@ -33,8 +33,40 @@
 
 #include "bsd-uthread.h"
 
-/* HACK: Save the bsd_uthreads ops returned by bsd_uthread_target.  */
-static struct target_ops *bsd_uthread_ops_hack;
+struct bsd_uthread_target final : public target_ops
+{
+  bsd_uthread_target ()
+  { to_stratum = thread_stratum; }
+
+  const char *shortname () override
+  { return "bsd-uthreads"; }
+
+  const char *longname () override
+  { return _("BSD user-level threads"); }
+
+  const char *doc () override
+  { return _("BSD user-level threads"); }
+
+  void close () override;
+
+  void mourn_inferior () override;
+
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+
+  ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
+  void resume (ptid_t, int, enum gdb_signal) override;
+
+  int thread_alive (ptid_t ptid) override;
+
+  void update_thread_list () override;
+
+  const char *extra_thread_info (struct thread_info *) override;
+
+  const char *pid_to_str (ptid_t) override;
+};
+
+static bsd_uthread_target bsd_uthread_ops;
 \f
 
 /* Architecture-specific operations.  */
@@ -200,15 +232,15 @@ bsd_uthread_activate (struct objfile *objfile)
   bsd_uthread_thread_ctx_offset =
     bsd_uthread_lookup_offset ("_thread_ctx_offset", objfile);
 
-  push_target (bsd_uthread_ops_hack);
+  push_target (&bsd_uthread_ops);
   bsd_uthread_active = 1;
   return 1;
 }
 
 /* Cleanup due to deactivation.  */
 
-static void
-bsd_uthread_close (struct target_ops *self)
+void
+bsd_uthread_target::close ()
 {
   bsd_uthread_active = 0;
   bsd_uthread_thread_run_addr = 0;
@@ -228,7 +260,7 @@ bsd_uthread_deactivate (void)
   if (!bsd_uthread_active)
     return;
 
-  unpush_target (bsd_uthread_ops_hack);
+  unpush_target (&bsd_uthread_ops);
 }
 
 static void
@@ -275,24 +307,23 @@ bsd_uthread_solib_unloaded (struct so_list *so)
     bsd_uthread_deactivate ();
 }
 
-static void
-bsd_uthread_mourn_inferior (struct target_ops *ops)
+void
+bsd_uthread_target::mourn_inferior ()
 {
-  struct target_ops *beneath = find_target_beneath (ops);
-  beneath->to_mourn_inferior (beneath);
+  struct target_ops *beneath = find_target_beneath (this);
+  beneath->mourn_inferior ();
   bsd_uthread_deactivate ();
 }
 
-static void
-bsd_uthread_fetch_registers (struct target_ops *ops,
-			     struct regcache *regcache, int regnum)
+void
+bsd_uthread_target::fetch_registers (struct regcache *regcache, int regnum)
 {
   struct gdbarch *gdbarch = regcache->arch ();
   struct bsd_uthread_ops *uthread_ops
     = (struct bsd_uthread_ops *) gdbarch_data (gdbarch, bsd_uthread_data);
   ptid_t ptid = regcache_get_ptid (regcache);
   CORE_ADDR addr = ptid_get_tid (ptid);
-  struct target_ops *beneath = find_target_beneath (ops);
+  struct target_ops *beneath = find_target_beneath (this);
   CORE_ADDR active_addr;
   scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
 
@@ -301,7 +332,7 @@ bsd_uthread_fetch_registers (struct target_ops *ops,
   inferior_ptid = ptid;
 
   /* Always fetch the appropriate registers from the layer beneath.  */
-  beneath->to_fetch_registers (beneath, regcache, regnum);
+  beneath->fetch_registers (regcache, regnum);
 
   /* FIXME: That might have gotten us more than we asked for.  Make
      sure we overwrite all relevant registers with values from the
@@ -317,14 +348,13 @@ bsd_uthread_fetch_registers (struct target_ops *ops,
     }
 }
 
-static void
-bsd_uthread_store_registers (struct target_ops *ops,
-			     struct regcache *regcache, int regnum)
+void
+bsd_uthread_target::store_registers (struct regcache *regcache, int regnum)
 {
   struct gdbarch *gdbarch = regcache->arch ();
   struct bsd_uthread_ops *uthread_ops
     = (struct bsd_uthread_ops *) gdbarch_data (gdbarch, bsd_uthread_data);
-  struct target_ops *beneath = find_target_beneath (ops);
+  struct target_ops *beneath = find_target_beneath (this);
   ptid_t ptid = regcache_get_ptid (regcache);
   CORE_ADDR addr = ptid_get_tid (ptid);
   CORE_ADDR active_addr;
@@ -345,20 +375,20 @@ bsd_uthread_store_registers (struct target_ops *ops,
     {
       /* Updating the thread that is currently running; pass the
          request to the layer beneath.  */
-      beneath->to_store_registers (beneath, regcache, regnum);
+      beneath->store_registers (regcache, regnum);
     }
 }
 
-static ptid_t
-bsd_uthread_wait (struct target_ops *ops,
-		  ptid_t ptid, struct target_waitstatus *status, int options)
+ptid_t
+bsd_uthread_target::wait (ptid_t ptid, struct target_waitstatus *status,
+			  int options)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
   CORE_ADDR addr;
-  struct target_ops *beneath = find_target_beneath (ops);
+  struct target_ops *beneath = find_target_beneath (this);
 
   /* Pass the request to the layer beneath.  */
-  ptid = beneath->to_wait (beneath, ptid, status, options);
+  ptid = beneath->wait (ptid, status, options);
 
   /* If the process is no longer alive, there's no point in figuring
      out the thread ID.  It will fail anyway.  */
@@ -399,20 +429,19 @@ bsd_uthread_wait (struct target_ops *ops,
   return ptid;
 }
 
-static void
-bsd_uthread_resume (struct target_ops *ops,
-		    ptid_t ptid, int step, enum gdb_signal sig)
+void
+bsd_uthread_target::resume (ptid_t ptid, int step, enum gdb_signal sig)
 {
   /* Pass the request to the layer beneath.  */
-  struct target_ops *beneath = find_target_beneath (ops);
-  beneath->to_resume (beneath, ptid, step, sig);
+  struct target_ops *beneath = find_target_beneath (this);
+  beneath->resume (ptid, step, sig);
 }
 
-static int
-bsd_uthread_thread_alive (struct target_ops *ops, ptid_t ptid)
+int
+bsd_uthread_target::thread_alive (ptid_t ptid)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
-  struct target_ops *beneath = find_target_beneath (ops);
+  struct target_ops *beneath = find_target_beneath (this);
   CORE_ADDR addr = ptid_get_tid (ptid);
 
   if (addr != 0)
@@ -427,11 +456,11 @@ bsd_uthread_thread_alive (struct target_ops *ops, ptid_t ptid)
 	return 0;
     }
 
-  return beneath->to_thread_alive (beneath, ptid);
+  return beneath->thread_alive (ptid);
 }
 
-static void
-bsd_uthread_update_thread_list (struct target_ops *ops)
+void
+bsd_uthread_target::update_thread_list ()
 {
   pid_t pid = ptid_get_pid (inferior_ptid);
   int offset = bsd_uthread_thread_next_offset;
@@ -487,9 +516,8 @@ static const char *bsd_uthread_state[] =
 /* Return a string describing th state of the thread specified by
    INFO.  */
 
-static const char *
-bsd_uthread_extra_thread_info (struct target_ops *self,
-			       struct thread_info *info)
+const char *
+bsd_uthread_target::extra_thread_info (thread_info *info)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
   CORE_ADDR addr = ptid_get_tid (info->ptid);
@@ -507,8 +535,8 @@ bsd_uthread_extra_thread_info (struct target_ops *self,
   return NULL;
 }
 
-static const char *
-bsd_uthread_pid_to_str (struct target_ops *ops, ptid_t ptid)
+const char *
+bsd_uthread_target::pid_to_str (ptid_t ptid)
 {
   if (ptid_get_tid (ptid) != 0)
     {
@@ -522,36 +550,9 @@ bsd_uthread_pid_to_str (struct target_ops *ops, ptid_t ptid)
   return normal_pid_to_str (ptid);
 }
 
-static struct target_ops *
-bsd_uthread_target (void)
-{
-  struct target_ops *t = XCNEW (struct target_ops);
-
-  t->to_shortname = "bsd-uthreads";
-  t->to_longname = "BSD user-level threads";
-  t->to_doc = "BSD user-level threads";
-  t->to_close = bsd_uthread_close;
-  t->to_mourn_inferior = bsd_uthread_mourn_inferior;
-  t->to_fetch_registers = bsd_uthread_fetch_registers;
-  t->to_store_registers = bsd_uthread_store_registers;
-  t->to_wait = bsd_uthread_wait;
-  t->to_resume = bsd_uthread_resume;
-  t->to_thread_alive = bsd_uthread_thread_alive;
-  t->to_update_thread_list = bsd_uthread_update_thread_list;
-  t->to_extra_thread_info = bsd_uthread_extra_thread_info;
-  t->to_pid_to_str = bsd_uthread_pid_to_str;
-  t->to_stratum = thread_stratum;
-  t->to_magic = OPS_MAGIC;
-  bsd_uthread_ops_hack = t;
-
-  return t;
-}
-
 void
 _initialize_bsd_uthread (void)
 {
-  complete_target_initialization (bsd_uthread_target ());
-
   bsd_uthread_data = gdbarch_data_register_pre_init (bsd_uthread_init);
 
   gdb::observers::inferior_created.attach (bsd_uthread_inferior_created);
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 23/40] target_ops/C++: IA-64 GNU/Linux
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (15 preceding siblings ...)
  2018-04-14 19:10 ` [PATCH 34/40] target_ops/C++: bsd_kvm_add_target, BSD libkvm target Pedro Alves
@ 2018-04-14 19:10 ` Pedro Alves
  2018-04-14 19:15 ` [PATCH 14/40] target_ops/C++: PPC/PPC64 GNU/Linux Pedro Alves
                   ` (24 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:10 UTC (permalink / raw)
  To: gdb-patches

Straighforward conversion.  Not tested.
---
 gdb/ia64-linux-nat.c | 133 ++++++++++++++++++++++++++-------------------------
 1 file changed, 68 insertions(+), 65 deletions(-)

diff --git a/gdb/ia64-linux-nat.c b/gdb/ia64-linux-nat.c
index f6492dcebb..2aa66a5682 100644
--- a/gdb/ia64-linux-nat.c
+++ b/gdb/ia64-linux-nat.c
@@ -43,6 +43,46 @@
 
 #include "inf-ptrace.h"
 
+class ia64_linux_nat_target final : public linux_nat_target
+{
+public:
+  /* Add our register access methods.  */
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+
+  enum target_xfer_status xfer_partial (enum target_object object,
+					const char *annex,
+					gdb_byte *readbuf,
+					const gdb_byte *writebuf,
+					ULONGEST offset, ULONGEST len,
+					ULONGEST *xfered_len) override;
+
+  const struct target_desc *read_description () override;
+
+  /* Override watchpoint routines.  */
+
+  /* The IA-64 architecture can step over a watch point (without
+     triggering it again) if the "dd" (data debug fault disable) bit
+     in the processor status word is set.
+
+     This PSR bit is set in
+     ia64_linux_nat_target::stopped_by_watchpoint when the code there
+     has determined that a hardware watchpoint has indeed been hit.
+     The CPU will then be able to execute one instruction without
+     triggering a watchpoint.  */
+  int have_steppable_watchpoint () { return 1; }
+
+  int can_use_hw_breakpoint (enum bptype, int, int) override;
+  int stopped_by_watchpoint () override;
+  int stopped_data_address (CORE_ADDR *) override;
+  int insert_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
+			 struct expression *) override;
+  int remove_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
+			 struct expression *) override;
+};
+
+static ia64_linux_nat_target the_ia64_linux_nat_target;
+
 /* These must match the order of the register names.
 
    Some sort of lookup table is needed because the offsets associated
@@ -542,11 +582,10 @@ is_power_of_2 (int val)
   return onecount <= 1;
 }
 
-static int
-ia64_linux_insert_watchpoint (struct target_ops *self,
-			      CORE_ADDR addr, int len,
-			      enum target_hw_bp_type type,
-			      struct expression *cond)
+int
+ia64_linux_nat_target::insert_watchpoint (CORE_ADDR addr, int len,
+					  enum target_hw_bp_type type,
+					  struct expression *cond)
 {
   struct lwp_info *lp;
   int idx;
@@ -598,11 +637,10 @@ ia64_linux_insert_watchpoint (struct target_ops *self,
   return 0;
 }
 
-static int
-ia64_linux_remove_watchpoint (struct target_ops *self,
-			      CORE_ADDR addr, int len,
-			      enum target_hw_bp_type type,
-			      struct expression *cond)
+int
+ia64_linux_nat_target::remove_watchpoint (CORE_ADDR addr, int len,
+					  enum target_hw_bp_type type,
+					  struct expression *cond)
 {
   int idx;
   long dbr_addr, dbr_mask;
@@ -650,8 +688,8 @@ ia64_linux_new_thread (struct lwp_info *lp)
     enable_watchpoints_in_psr (lp->ptid);
 }
 
-static int
-ia64_linux_stopped_data_address (struct target_ops *ops, CORE_ADDR *addr_p)
+int
+ia64_linux_nat_target::stopped_data_address (CORE_ADDR *addr_p)
 {
   CORE_ADDR psr;
   siginfo_t siginfo;
@@ -673,11 +711,11 @@ ia64_linux_stopped_data_address (struct target_ops *ops, CORE_ADDR *addr_p)
   return 1;
 }
 
-static int
-ia64_linux_stopped_by_watchpoint (struct target_ops *ops)
+int
+ia64_linux_nat_target::stopped_by_watchpoint ()
 {
   CORE_ADDR addr;
-  return ia64_linux_stopped_data_address (ops, &addr);
+  return stopped_data_address (&addr);
 }
 
 static int
@@ -765,9 +803,8 @@ ia64_linux_fetch_register (struct regcache *regcache, int regnum)
 /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
    for all registers.  */
 
-static void
-ia64_linux_fetch_registers (struct target_ops *ops,
-			    struct regcache *regcache, int regnum)
+void
+ia64_linux_nat_target::fetch_registers (struct regcache *regcache, int regnum)
 {
   if (regnum == -1)
     for (regnum = 0;
@@ -820,9 +857,8 @@ ia64_linux_store_register (const struct regcache *regcache, int regnum)
 /* Store register REGNUM back into the inferior.  If REGNUM is -1, do
    this for all registers.  */
 
-static void
-ia64_linux_store_registers (struct target_ops *ops,
-			    struct regcache *regcache, int regnum)
+void
+ia64_linux_nat_target::store_registers (struct regcache *regcache, int regnum)
 {
   if (regnum == -1)
     for (regnum = 0;
@@ -833,18 +869,14 @@ ia64_linux_store_registers (struct target_ops *ops,
     ia64_linux_store_register (regcache, regnum);
 }
 
+/* Implement the xfer_partial target_ops method.  */
 
-static target_xfer_partial_ftype *super_xfer_partial;
-
-/* Implement the to_xfer_partial target_ops method.  */
-
-static enum target_xfer_status
-ia64_linux_xfer_partial (struct target_ops *ops,
-			 enum target_object object,
-			 const char *annex,
-			 gdb_byte *readbuf, const gdb_byte *writebuf,
-			 ULONGEST offset, ULONGEST len,
-			 ULONGEST *xfered_len)
+enum target_xfer_status
+ia64_linux_nat_target::xfer_partial (enum target_object object,
+				     const char *annex,
+				     gdb_byte *readbuf, const gdb_byte *writebuf,
+				     ULONGEST offset, ULONGEST len,
+				     ULONGEST *xfered_len)
 {
   if (object == TARGET_OBJECT_UNWIND_TABLE && readbuf != NULL)
     {
@@ -875,8 +907,8 @@ ia64_linux_xfer_partial (struct target_ops *ops,
       return TARGET_XFER_OK;
     }
 
-  return super_xfer_partial (ops, object, annex, readbuf, writebuf,
-			     offset, len, xfered_len);
+  return linux_nat_target::xfer_partial (object, annex, readbuf, writebuf,
+					 offset, len, xfered_len);
 }
 
 /* For break.b instruction ia64 CPU forgets the immediate value and generates
@@ -894,39 +926,10 @@ ia64_linux_status_is_event (int status)
 void
 _initialize_ia64_linux_nat (void)
 {
-  struct target_ops *t;
-
-  /* Fill in the generic GNU/Linux methods.  */
-  t = linux_target ();
-
-  /* Override the default fetch/store register routines.  */
-  t->to_fetch_registers = ia64_linux_fetch_registers;
-  t->to_store_registers = ia64_linux_store_registers;
-
-  /* Override the default to_xfer_partial.  */
-  super_xfer_partial = t->to_xfer_partial;
-  t->to_xfer_partial = ia64_linux_xfer_partial;
-
-  /* Override watchpoint routines.  */
-
-  /* The IA-64 architecture can step over a watch point (without triggering
-     it again) if the "dd" (data debug fault disable) bit in the processor
-     status word is set.
-
-     This PSR bit is set in ia64_linux_stopped_by_watchpoint when the
-     code there has determined that a hardware watchpoint has indeed
-     been hit.  The CPU will then be able to execute one instruction
-     without triggering a watchpoint.  */
-
-  t->to_have_steppable_watchpoint = 1;
-  t->to_can_use_hw_breakpoint = ia64_linux_can_use_hw_breakpoint;
-  t->to_stopped_by_watchpoint = ia64_linux_stopped_by_watchpoint;
-  t->to_stopped_data_address = ia64_linux_stopped_data_address;
-  t->to_insert_watchpoint = ia64_linux_insert_watchpoint;
-  t->to_remove_watchpoint = ia64_linux_remove_watchpoint;
+  struct target_ops *t = &the_ia64_linux_nat_target;
 
   /* Register the target.  */
-  linux_nat_add_target (t);
+  add_target (t);
   linux_nat_set_new_thread (t, ia64_linux_new_thread);
   linux_nat_set_status_is_event (t, ia64_linux_status_is_event);
 }
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 22/40] target_ops/C++: HP-PA GNU/Linux
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (18 preceding siblings ...)
  2018-04-14 19:15 ` [PATCH 12/40] target_ops/C++: target remote-sim Pedro Alves
@ 2018-04-14 19:15 ` Pedro Alves
  2018-04-14 19:18 ` [PATCH 04/40] target_ops/C++: core target Pedro Alves
                   ` (21 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:15 UTC (permalink / raw)
  To: gdb-patches

Straighforward conversion.  Not tested.
---
 gdb/hppa-linux-nat.c | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/gdb/hppa-linux-nat.c b/gdb/hppa-linux-nat.c
index ddcee03cb4..36f6a19e67 100644
--- a/gdb/hppa-linux-nat.c
+++ b/gdb/hppa-linux-nat.c
@@ -34,6 +34,16 @@
 
 #include "hppa-tdep.h"
 
+class hppa_linux_nat_target final : public linux_nat_target
+{
+public:
+  /* Add our register access methods.  */
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+};
+
+static hppa_linux_nat_target the_hppa_linux_nat_target;
+
 /* Prototypes for supply_gregset etc.  */
 #include "gregset.h"
 
@@ -262,9 +272,9 @@ store_register (const struct regcache *regcache, int regno)
    regno == -1, otherwise fetch all general registers or all floating
    point registers depending upon the value of regno.  */
 
-static void
-hppa_linux_fetch_inferior_registers (struct target_ops *ops,
-				     struct regcache *regcache, int regno)
+void
+hppa_linux_nat_target::fetch_inferior_registers (struct regcache *regcache,
+						 int regno)
 {
   if (-1 == regno)
     {
@@ -283,9 +293,8 @@ hppa_linux_fetch_inferior_registers (struct target_ops *ops,
    regno == -1, otherwise store all general registers or all floating
    point registers depending upon the value of regno.  */
 
-static void
-hppa_linux_store_inferior_registers (struct target_ops *ops,
-				     struct regcache *regcache, int regno)
+void
+hppa_linux_nat_target::store_registers (struct regcache *regcache, int regno)
 {
   if (-1 == regno)
     {
@@ -380,15 +389,6 @@ fill_fpregset (const struct regcache *regcache,
 void
 _initialize_hppa_linux_nat (void)
 {
-  struct target_ops *t;
-
-  /* Fill in the generic GNU/Linux methods.  */
-  t = linux_target ();
-
-  /* Add our register access methods.  */
-  t->to_fetch_registers = hppa_linux_fetch_inferior_registers;
-  t->to_store_registers = hppa_linux_store_inferior_registers;
-
   /* Register the target.  */
-  linux_nat_add_target (t);
+  add_target (&the_hppa_linux_nat_target);
 }
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 12/40] target_ops/C++: target remote-sim
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (17 preceding siblings ...)
  2018-04-14 19:15 ` [PATCH 14/40] target_ops/C++: PPC/PPC64 GNU/Linux Pedro Alves
@ 2018-04-14 19:15 ` Pedro Alves
  2018-04-14 19:15 ` [PATCH 22/40] target_ops/C++: HP-PA GNU/Linux Pedro Alves
                   ` (22 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:15 UTC (permalink / raw)
  To: gdb-patches

Straighforward conversion.
---
 gdb/remote-sim.c | 220 ++++++++++++++++++++++++++++---------------------------
 1 file changed, 111 insertions(+), 109 deletions(-)

diff --git a/gdb/remote-sim.c b/gdb/remote-sim.c
index 456fa8a3fe..3d484bcd85 100644
--- a/gdb/remote-sim.c
+++ b/gdb/remote-sim.c
@@ -68,35 +68,79 @@ static void gdb_os_evprintf_filtered (host_callback *, const char *, va_list);
 static void gdb_os_error (host_callback *, const char *, ...)
      ATTRIBUTE_NORETURN;
 
-static void gdbsim_kill (struct target_ops *);
+void simulator_command (char *args, int from_tty);
 
-static void gdbsim_load (struct target_ops *self, const char *prog,
-			 int fromtty);
+/* Naming convention:
 
-static void gdbsim_open (const char *args, int from_tty);
+   sim_* are the interface to the simulator (see remote-sim.h).
+   gdbsim_* are stuff which is internal to gdb.  */
 
-static void gdbsim_close (struct target_ops *self);
+struct gdbsim_target
+  : public memory_breakpoint_target<target_ops>
+{
+  gdbsim_target ()
+  { to_stratum = process_stratum; }
 
-static void gdbsim_detach (struct target_ops *ops, inferior *inf, int from_tty);
+  const char *shortname () override
+  { return "sim"; }
 
-static void gdbsim_prepare_to_store (struct target_ops *self,
-				     struct regcache *regcache);
+  const char *longname () override
+  { return _("simulator"); }
 
-static void gdbsim_files_info (struct target_ops *target);
+  const char *doc () override
+  { return _("Use the compiled-in simulator."); }
 
-static void gdbsim_mourn_inferior (struct target_ops *target);
+  void open (const char *, int) override;
+  void close () override;
 
-static void gdbsim_interrupt (struct target_ops *self);
+  void detach (inferior *inf, int) override;
 
-void simulator_command (char *args, int from_tty);
+  void resume (ptid_t, int, enum gdb_signal) override;
+  ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
 
-/* Naming convention:
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+  void prepare_to_store (struct regcache *) override;
 
-   sim_* are the interface to the simulator (see remote-sim.h).
-   gdbsim_* are stuff which is internal to gdb.  */
+  enum target_xfer_status xfer_partial (enum target_object object,
+					const char *annex,
+					gdb_byte *readbuf,
+					const gdb_byte *writebuf,
+					ULONGEST offset, ULONGEST len,
+					ULONGEST *xfered_len) override;
+
+  void files_info () override;
+
+  void kill () override;
+
+  void load (const char *, int) override;
+
+  bool can_create_inferior () override { return true; }
+  void create_inferior (const char *, const std::string &,
+			char **, int) override;
+
+  void mourn_inferior () override;
+
+  void interrupt () override;
+
+  int thread_alive (ptid_t ptid) override;
 
-/* Forward data declarations */
-extern struct target_ops gdbsim_ops;
+  const char *pid_to_str (ptid_t) override;
+
+  int has_all_memory ()  override;
+  int has_memory ()  override;
+
+  int has_stack ()  override
+  { return default_child_has_stack (); }
+
+  int has_registers ()  override
+  { return default_child_has_registers (); }
+
+  int has_execution (ptid_t ptid) override
+  { return default_child_has_execution (ptid); }
+};
+
+static struct gdbsim_target gdbsim_ops;
 
 static const struct inferior_data *sim_inferior_data_key;
 
@@ -422,9 +466,8 @@ one2one_register_sim_regno (struct gdbarch *gdbarch, int regnum)
   return regnum;
 }
 
-static void
-gdbsim_fetch_register (struct target_ops *ops,
-		       struct regcache *regcache, int regno)
+void
+gdbsim_target::fetch_registers (struct regcache *regcache, int regno)
 {
   struct gdbarch *gdbarch = regcache->arch ();
   struct inferior *inf = find_inferior_ptid (regcache_get_ptid (regcache));
@@ -434,7 +477,7 @@ gdbsim_fetch_register (struct target_ops *ops,
   if (regno == -1)
     {
       for (regno = 0; regno < gdbarch_num_regs (gdbarch); regno++)
-	gdbsim_fetch_register (ops, regcache, regno);
+	fetch_registers (regcache, regno);
       return;
     }
 
@@ -492,9 +535,8 @@ gdbsim_fetch_register (struct target_ops *ops,
 }
 
 
-static void
-gdbsim_store_register (struct target_ops *ops,
-		       struct regcache *regcache, int regno)
+void
+gdbsim_target::store_registers (struct regcache *regcache, int regno)
 {
   struct gdbarch *gdbarch = regcache->arch ();
   struct inferior *inf = find_inferior_ptid (regcache_get_ptid (regcache));
@@ -504,7 +546,7 @@ gdbsim_store_register (struct target_ops *ops,
   if (regno == -1)
     {
       for (regno = 0; regno < gdbarch_num_regs (gdbarch); regno++)
-	gdbsim_store_register (ops, regcache, regno);
+	store_registers (regcache, regno);
       return;
     }
   else if (gdbarch_register_sim_regno (gdbarch, regno) >= 0)
@@ -541,8 +583,8 @@ gdbsim_store_register (struct target_ops *ops,
 /* Kill the running program.  This may involve closing any open files
    and releasing other resources acquired by the simulated program.  */
 
-static void
-gdbsim_kill (struct target_ops *ops)
+void
+gdbsim_target::kill ()
 {
   if (remote_debug)
     fprintf_unfiltered (gdb_stdlog, "gdbsim_kill\n");
@@ -556,8 +598,8 @@ gdbsim_kill (struct target_ops *ops)
    not only bring new code into the target process, but also to update
    GDB's symbol tables to match.  */
 
-static void
-gdbsim_load (struct target_ops *self, const char *args, int fromtty)
+void
+gdbsim_target::load (const char *args, int fromtty)
 {
   const char *prog;
   struct sim_inferior_data *sim_data
@@ -597,9 +639,10 @@ gdbsim_load (struct target_ops *self, const char *args, int fromtty)
 /* This is called not only when we first attach, but also when the
    user types "run" after having attached.  */
 
-static void
-gdbsim_create_inferior (struct target_ops *target, const char *exec_file,
-			const std::string &allargs, char **env, int from_tty)
+void
+gdbsim_target::create_inferior (const char *exec_file,
+				const std::string &allargs,
+				char **env, int from_tty)
 {
   struct sim_inferior_data *sim_data
     = get_sim_inferior_data (current_inferior (), SIM_INSTANCE_NEEDED);
@@ -619,7 +662,7 @@ gdbsim_create_inferior (struct target_ops *target, const char *exec_file,
 			args);
 
   if (ptid_equal (inferior_ptid, sim_data->remote_sim_ptid))
-    gdbsim_kill (target);
+    kill ();
   remove_breakpoints ();
   init_wait_for_inferior ();
 
@@ -658,8 +701,8 @@ gdbsim_create_inferior (struct target_ops *target, const char *exec_file,
    Targets should supply this routine, if only to provide an error message.  */
 /* Called when selecting the simulator.  E.g. (gdb) target sim name.  */
 
-static void
-gdbsim_open (const char *args, int from_tty)
+void
+gdbsim_target::open (const char *args, int from_tty)
 {
   int len;
   char *arg_buf;
@@ -789,8 +832,8 @@ gdbsim_close_inferior (struct inferior *inf, void *arg)
 
 /* Close out all files and local state before this target loses control.  */
 
-static void
-gdbsim_close (struct target_ops *self)
+void
+gdbsim_target::close ()
 {
   struct sim_inferior_data *sim_data
     = get_sim_inferior_data (current_inferior (), SIM_INSTANCE_NOT_NEEDED);
@@ -819,13 +862,13 @@ gdbsim_close (struct target_ops *self)
 /* Terminate the open connection to the remote debugger.
    Use this when you want to detach and do something else with your gdb.  */
 
-static void
-gdbsim_detach (struct target_ops *ops, inferior *inf, int from_tty)
+void
+gdbsim_target::detach (inferior *inf, int from_tty)
 {
   if (remote_debug)
     fprintf_unfiltered (gdb_stdlog, "gdbsim_detach\n");
 
-  unpush_target (ops);		/* calls gdbsim_close to do the real work */
+  unpush_target (this);		/* calls gdbsim_close to do the real work */
   if (from_tty)
     printf_filtered ("Ending simulator %s debugging\n", target_shortname);
 }
@@ -864,9 +907,8 @@ gdbsim_resume_inferior (struct inferior *inf, void *arg)
   return 0;
 }
 
-static void
-gdbsim_resume (struct target_ops *ops,
-	       ptid_t ptid, int step, enum gdb_signal siggnal)
+void
+gdbsim_target::resume (ptid_t ptid, int step, enum gdb_signal siggnal)
 {
   struct resume_data rd;
   struct sim_inferior_data *sim_data
@@ -919,8 +961,8 @@ gdbsim_interrupt_inferior (struct inferior *inf, void *arg)
   return 0;
 }
 
-static void
-gdbsim_interrupt (struct target_ops *self)
+void
+gdbsim_target::interrupt ()
 {
   iterate_over_inferiors (gdbsim_interrupt_inferior, NULL);
 }
@@ -946,12 +988,11 @@ gdb_os_poll_quit (host_callback *p)
 static void
 gdbsim_cntrl_c (int signo)
 {
-  gdbsim_interrupt (NULL);
+  gdbsim_ops.interrupt ();
 }
 
-static ptid_t
-gdbsim_wait (struct target_ops *ops,
-	     ptid_t ptid, struct target_waitstatus *status, int options)
+ptid_t
+gdbsim_target::wait (ptid_t ptid, struct target_waitstatus *status, int options)
 {
   struct sim_inferior_data *sim_data;
   static sighandler_t prev_sigint;
@@ -1035,8 +1076,8 @@ gdbsim_wait (struct target_ops *ops,
    that registers contains all the registers from the program being
    debugged.  */
 
-static void
-gdbsim_prepare_to_store (struct target_ops *self, struct regcache *regcache)
+void
+gdbsim_target::prepare_to_store (struct regcache *regcache)
 {
   /* Do nothing, since we can store individual regs.  */
 }
@@ -1056,7 +1097,7 @@ gdbsim_xfer_memory (struct target_ops *target,
   /* If this target doesn't have memory yet, return 0 causing the
      request to be passed to a lower target, hopefully an exec
      file.  */
-  if (!target->to_has_memory (target))
+  if (!target->has_memory ())
     return TARGET_XFER_EOF;
 
   if (!sim_data->program_loaded)
@@ -1104,16 +1145,16 @@ gdbsim_xfer_memory (struct target_ops *target,
 
 /* Target to_xfer_partial implementation.  */
 
-static enum target_xfer_status
-gdbsim_xfer_partial (struct target_ops *ops, enum target_object object,
-		     const char *annex, gdb_byte *readbuf,
-		     const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
-		     ULONGEST *xfered_len)
+enum target_xfer_status
+gdbsim_target::xfer_partial (enum target_object object,
+			     const char *annex, gdb_byte *readbuf,
+			     const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
+			     ULONGEST *xfered_len)
 {
   switch (object)
     {
     case TARGET_OBJECT_MEMORY:
-      return gdbsim_xfer_memory (ops, readbuf, writebuf, offset, len,
+      return gdbsim_xfer_memory (this, readbuf, writebuf, offset, len,
 				 xfered_len);
 
     default:
@@ -1121,8 +1162,8 @@ gdbsim_xfer_partial (struct target_ops *ops, enum target_object object,
     }
 }
 
-static void
-gdbsim_files_info (struct target_ops *target)
+void
+gdbsim_target::files_info ()
 {
   struct sim_inferior_data *sim_data
     = get_sim_inferior_data (current_inferior (), SIM_INSTANCE_NEEDED);
@@ -1144,8 +1185,8 @@ gdbsim_files_info (struct target_ops *target)
 
 /* Clear the simulator's notion of what the break points are.  */
 
-static void
-gdbsim_mourn_inferior (struct target_ops *target)
+void
+gdbsim_target::mourn_inferior ()
 {
   struct sim_inferior_data *sim_data
     = get_sim_inferior_data (current_inferior (), SIM_INSTANCE_NOT_NEEDED);
@@ -1247,8 +1288,8 @@ sim_command_completer (struct cmd_list_element *ignore,
 
 /* Check to see if a thread is still alive.  */
 
-static int
-gdbsim_thread_alive (struct target_ops *ops, ptid_t ptid)
+int
+gdbsim_target::thread_alive (ptid_t ptid)
 {
   struct sim_inferior_data *sim_data
     = get_sim_inferior_data_by_ptid (ptid, SIM_INSTANCE_NOT_NEEDED);
@@ -1266,16 +1307,16 @@ gdbsim_thread_alive (struct target_ops *ops, ptid_t ptid)
 /* Convert a thread ID to a string.  Returns the string in a static
    buffer.  */
 
-static const char *
-gdbsim_pid_to_str (struct target_ops *ops, ptid_t ptid)
+const char *
+gdbsim_target::pid_to_str (ptid_t ptid)
 {
   return normal_pid_to_str (ptid);
 }
 
 /* Simulator memory may be accessed after the program has been loaded.  */
 
-static int
-gdbsim_has_all_memory (struct target_ops *ops)
+int
+gdbsim_target::has_all_memory ()
 {
   struct sim_inferior_data *sim_data
     = get_sim_inferior_data (current_inferior (), SIM_INSTANCE_NOT_NEEDED);
@@ -1286,8 +1327,8 @@ gdbsim_has_all_memory (struct target_ops *ops)
   return 1;
 }
 
-static int
-gdbsim_has_memory (struct target_ops *ops)
+int
+gdbsim_target::has_memory ()
 {
   struct sim_inferior_data *sim_data
     = get_sim_inferior_data (current_inferior (), SIM_INSTANCE_NOT_NEEDED);
@@ -1298,50 +1339,11 @@ gdbsim_has_memory (struct target_ops *ops)
   return 1;
 }
 
-/* Define the target subroutine names.  */
-
-struct target_ops gdbsim_ops;
-
-static void
-init_gdbsim_ops (void)
-{
-  gdbsim_ops.to_shortname = "sim";
-  gdbsim_ops.to_longname = "simulator";
-  gdbsim_ops.to_doc = "Use the compiled-in simulator.";
-  gdbsim_ops.to_open = gdbsim_open;
-  gdbsim_ops.to_close = gdbsim_close;
-  gdbsim_ops.to_detach = gdbsim_detach;
-  gdbsim_ops.to_resume = gdbsim_resume;
-  gdbsim_ops.to_wait = gdbsim_wait;
-  gdbsim_ops.to_fetch_registers = gdbsim_fetch_register;
-  gdbsim_ops.to_store_registers = gdbsim_store_register;
-  gdbsim_ops.to_prepare_to_store = gdbsim_prepare_to_store;
-  gdbsim_ops.to_xfer_partial = gdbsim_xfer_partial;
-  gdbsim_ops.to_files_info = gdbsim_files_info;
-  gdbsim_ops.to_insert_breakpoint = memory_insert_breakpoint;
-  gdbsim_ops.to_remove_breakpoint = memory_remove_breakpoint;
-  gdbsim_ops.to_kill = gdbsim_kill;
-  gdbsim_ops.to_load = gdbsim_load;
-  gdbsim_ops.to_create_inferior = gdbsim_create_inferior;
-  gdbsim_ops.to_mourn_inferior = gdbsim_mourn_inferior;
-  gdbsim_ops.to_interrupt = gdbsim_interrupt;
-  gdbsim_ops.to_thread_alive = gdbsim_thread_alive;
-  gdbsim_ops.to_pid_to_str = gdbsim_pid_to_str;
-  gdbsim_ops.to_stratum = process_stratum;
-  gdbsim_ops.to_has_all_memory = gdbsim_has_all_memory;
-  gdbsim_ops.to_has_memory = gdbsim_has_memory;
-  gdbsim_ops.to_has_stack = default_child_has_stack;
-  gdbsim_ops.to_has_registers = default_child_has_registers;
-  gdbsim_ops.to_has_execution = default_child_has_execution;
-  gdbsim_ops.to_magic = OPS_MAGIC;
-}
-
 void
 _initialize_remote_sim (void)
 {
   struct cmd_list_element *c;
 
-  init_gdbsim_ops ();
   add_target (&gdbsim_ops);
 
   c = add_com ("sim", class_obscure, simulator_command,
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 14/40] target_ops/C++: PPC/PPC64 GNU/Linux
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (16 preceding siblings ...)
  2018-04-14 19:10 ` [PATCH 23/40] target_ops/C++: IA-64 GNU/Linux Pedro Alves
@ 2018-04-14 19:15 ` Pedro Alves
  2018-04-14 19:15 ` [PATCH 12/40] target_ops/C++: target remote-sim Pedro Alves
                   ` (23 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:15 UTC (permalink / raw)
  To: gdb-patches

Straighforward conversion.  I'd tested this on the GCC compile farm.
---
 gdb/ppc-linux-nat.c | 193 +++++++++++++++++++++++++++++-----------------------
 1 file changed, 106 insertions(+), 87 deletions(-)

diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c
index e1b728016c..c9f0f9d48d 100644
--- a/gdb/ppc-linux-nat.c
+++ b/gdb/ppc-linux-nat.c
@@ -267,6 +267,57 @@ int have_ptrace_getsetregs = 1;
    them and gotten an error.  */
 int have_ptrace_getsetfpregs = 1;
 
+struct ppc_linux_nat_target final : public linux_nat_target
+{
+  /* Add our register access methods.  */
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+
+  /* Add our breakpoint/watchpoint methods.  */
+  int can_use_hw_breakpoint (enum bptype, int, int) override;
+
+  int insert_hw_breakpoint (struct gdbarch *, struct bp_target_info *)
+    override;
+
+  int remove_hw_breakpoint (struct gdbarch *, struct bp_target_info *)
+    override;
+
+  int region_ok_for_hw_watchpoint (CORE_ADDR, int) override;
+
+  int insert_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
+			 struct expression *) override;
+
+  int remove_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
+			 struct expression *) override;
+
+  int insert_mask_watchpoint (CORE_ADDR, CORE_ADDR, enum target_hw_bp_type)
+    override;
+
+  int remove_mask_watchpoint (CORE_ADDR, CORE_ADDR, enum target_hw_bp_type)
+    override;
+
+  int stopped_by_watchpoint () override;
+
+  int stopped_data_address (CORE_ADDR *) override;
+
+  int watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, int) override;
+
+  int can_accel_watchpoint_condition (CORE_ADDR, int, int, struct expression *)
+    override;
+
+  int masked_watch_num_registers (CORE_ADDR, CORE_ADDR) override;
+
+  int ranged_break_num_registers () override;
+
+  const struct target_desc *read_description ()  override;
+
+  int auxv_parse (gdb_byte **readptr,
+		  gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
+    override;
+};
+
+static ppc_linux_nat_target the_ppc_linux_nat_target;
+
 /* *INDENT-OFF* */
 /* registers layout, as presented by the ptrace interface:
 PT_R0, PT_R1, PT_R2, PT_R3, PT_R4, PT_R5, PT_R6, PT_R7,
@@ -806,9 +857,8 @@ fetch_ppc_registers (struct regcache *regcache, int tid)
 /* Fetch registers from the child process.  Fetch all registers if
    regno == -1, otherwise fetch all general registers or all floating
    point registers depending upon the value of regno.  */
-static void
-ppc_linux_fetch_inferior_registers (struct target_ops *ops,
-				    struct regcache *regcache, int regno)
+void
+ppc_linux_nat_target::fetch_registers (struct regcache *regcache, int regno)
 {
   pid_t tid = get_ptrace_pid (regcache_get_ptid (regcache));
 
@@ -1385,9 +1435,8 @@ have_ptrace_hwdebug_interface (void)
   return have_ptrace_hwdebug_interface;
 }
 
-static int
-ppc_linux_can_use_hw_breakpoint (struct target_ops *self,
-				 enum bptype type, int cnt, int ot)
+int
+ppc_linux_nat_target::can_use_hw_breakpoint (enum bptype type, int cnt, int ot)
 {
   int total_hw_wp, total_hw_bp;
 
@@ -1443,9 +1492,8 @@ ppc_linux_can_use_hw_breakpoint (struct target_ops *self,
   return 1;
 }
 
-static int
-ppc_linux_region_ok_for_hw_watchpoint (struct target_ops *self,
-				       CORE_ADDR addr, int len)
+int
+ppc_linux_nat_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
 {
   /* Handle sub-8-byte quantities.  */
   if (len <= 0)
@@ -1603,8 +1651,8 @@ hwdebug_remove_point (struct ppc_hw_breakpoint *b, int tid)
 
 /* Return the number of registers needed for a ranged breakpoint.  */
 
-static int
-ppc_linux_ranged_break_num_registers (struct target_ops *target)
+int
+ppc_linux_nat_target::ranged_break_num_registers ()
 {
   return ((have_ptrace_hwdebug_interface ()
 	   && hwdebug_info.features & PPC_DEBUG_FEATURE_INSN_BP_RANGE)?
@@ -1614,10 +1662,9 @@ ppc_linux_ranged_break_num_registers (struct target_ops *target)
 /* Insert the hardware breakpoint described by BP_TGT.  Returns 0 for
    success, 1 if hardware breakpoints are not supported or -1 for failure.  */
 
-static int
-ppc_linux_insert_hw_breakpoint (struct target_ops *self,
-				struct gdbarch *gdbarch,
-				  struct bp_target_info *bp_tgt)
+int
+ppc_linux_nat_target::insert_hw_breakpoint (struct gdbarch *gdbarch,
+					    struct bp_target_info *bp_tgt)
 {
   struct lwp_info *lp;
   struct ppc_hw_breakpoint p;
@@ -1651,10 +1698,9 @@ ppc_linux_insert_hw_breakpoint (struct target_ops *self,
   return 0;
 }
 
-static int
-ppc_linux_remove_hw_breakpoint (struct target_ops *self,
-				struct gdbarch *gdbarch,
-				  struct bp_target_info *bp_tgt)
+int
+ppc_linux_nat_target::remove_hw_breakpoint (struct gdbarch *gdbarch,
+					    struct bp_target_info *bp_tgt)
 {
   struct lwp_info *lp;
   struct ppc_hw_breakpoint p;
@@ -1708,9 +1754,9 @@ get_trigger_type (enum target_hw_bp_type type)
    or hw_access for an access watchpoint.  Returns 0 on success and throws
    an error on failure.  */
 
-static int
-ppc_linux_insert_mask_watchpoint (struct target_ops *ops, CORE_ADDR addr,
-				  CORE_ADDR mask, enum target_hw_bp_type rw)
+int
+ppc_linux_nat_target::insert_mask_watchpoint (CORE_ADDR addr,  CORE_ADDR mask,
+					      target_hw_bp_type rw)
 {
   struct lwp_info *lp;
   struct ppc_hw_breakpoint p;
@@ -1736,9 +1782,9 @@ ppc_linux_insert_mask_watchpoint (struct target_ops *ops, CORE_ADDR addr,
    or hw_access for an access watchpoint.  Returns 0 on success and throws
    an error on failure.  */
 
-static int
-ppc_linux_remove_mask_watchpoint (struct target_ops *ops, CORE_ADDR addr,
-				  CORE_ADDR mask, enum target_hw_bp_type rw)
+int
+ppc_linux_nat_target::remove_mask_watchpoint (CORE_ADDR addr, CORE_ADDR mask,
+					      target_hw_bp_type rw)
 {
   struct lwp_info *lp;
   struct ppc_hw_breakpoint p;
@@ -1940,10 +1986,10 @@ check_condition (CORE_ADDR watch_addr, struct expression *cond,
 /* Return non-zero if the target is capable of using hardware to evaluate
    the condition expression, thus only triggering the watchpoint when it is
    true.  */
-static int
-ppc_linux_can_accel_watchpoint_condition (struct target_ops *self,
-					  CORE_ADDR addr, int len, int rw,
-					  struct expression *cond)
+int
+ppc_linux_nat_target::can_accel_watchpoint_condition (CORE_ADDR addr, int len,
+						      int rw,
+						      struct expression *cond)
 {
   CORE_ADDR data_value;
 
@@ -2003,10 +2049,10 @@ create_watchpoint_request (struct ppc_hw_breakpoint *p, CORE_ADDR addr,
   p->addr = (uint64_t) addr;
 }
 
-static int
-ppc_linux_insert_watchpoint (struct target_ops *self, CORE_ADDR addr, int len,
-			     enum target_hw_bp_type type,
-			     struct expression *cond)
+int
+ppc_linux_nat_target::insert_watchpoint (CORE_ADDR addr, int len,
+					 enum target_hw_bp_type type,
+					 struct expression *cond)
 {
   struct lwp_info *lp;
   int ret = -1;
@@ -2072,10 +2118,10 @@ ppc_linux_insert_watchpoint (struct target_ops *self, CORE_ADDR addr, int len,
   return ret;
 }
 
-static int
-ppc_linux_remove_watchpoint (struct target_ops *self, CORE_ADDR addr, int len,
-			     enum target_hw_bp_type type,
-			     struct expression *cond)
+int
+ppc_linux_nat_target::remove_watchpoint (CORE_ADDR addr, int len,
+					 enum target_hw_bp_type type,
+					 struct expression *cond)
 {
   struct lwp_info *lp;
   int ret = -1;
@@ -2176,8 +2222,8 @@ ppc_linux_thread_exit (struct thread_info *tp, int silent)
   xfree (t);
 }
 
-static int
-ppc_linux_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p)
+int
+ppc_linux_nat_target::stopped_data_address (CORE_ADDR *addr_p)
 {
   siginfo_t siginfo;
 
@@ -2215,17 +2261,17 @@ ppc_linux_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p)
   return 1;
 }
 
-static int
-ppc_linux_stopped_by_watchpoint (struct target_ops *ops)
+int
+ppc_linux_nat_target::stopped_by_watchpoint ()
 {
   CORE_ADDR addr;
-  return ppc_linux_stopped_data_address (ops, &addr);
+  return stopped_data_address (&addr);
 }
 
-static int
-ppc_linux_watchpoint_addr_within_range (struct target_ops *target,
-					CORE_ADDR addr,
-					CORE_ADDR start, int length)
+int
+ppc_linux_nat_target::watchpoint_addr_within_range (CORE_ADDR addr,
+						    CORE_ADDR start,
+						    int length)
 {
   int mask;
 
@@ -2245,9 +2291,8 @@ ppc_linux_watchpoint_addr_within_range (struct target_ops *target,
 
 /* Return the number of registers needed for a masked hardware watchpoint.  */
 
-static int
-ppc_linux_masked_watch_num_registers (struct target_ops *target,
-				      CORE_ADDR addr, CORE_ADDR mask)
+int
+ppc_linux_nat_target::masked_watch_num_registers (CORE_ADDR addr, CORE_ADDR mask)
 {
   if (!have_ptrace_hwdebug_interface ()
 	   || (hwdebug_info.features & PPC_DEBUG_FEATURE_DATA_BP_MASK) == 0)
@@ -2263,9 +2308,8 @@ ppc_linux_masked_watch_num_registers (struct target_ops *target,
     return 2;
 }
 
-static void
-ppc_linux_store_inferior_registers (struct target_ops *ops,
-				    struct regcache *regcache, int regno)
+void
+ppc_linux_nat_target::store_registers (struct regcache *regcache, int regno)
 {
   pid_t tid = get_ptrace_pid (regcache_get_ptid (regcache));
 
@@ -2342,9 +2386,10 @@ ppc_linux_target_wordsize (void)
   return wordsize;
 }
 
-static int
-ppc_linux_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
-                      gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
+int
+ppc_linux_nat_target::auxv_parse (gdb_byte **readptr,
+				  gdb_byte *endptr, CORE_ADDR *typep,
+				  CORE_ADDR *valp)
 {
   int sizeof_auxv_field = ppc_linux_target_wordsize ();
   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
@@ -2365,8 +2410,8 @@ ppc_linux_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
   return 1;
 }
 
-static const struct target_desc *
-ppc_linux_read_description (struct target_ops *ops)
+const struct target_desc *
+ppc_linux_nat_target::read_description ()
 {
   int altivec = 0;
   int vsx = 0;
@@ -2456,38 +2501,12 @@ ppc_linux_read_description (struct target_ops *ops)
 void
 _initialize_ppc_linux_nat (void)
 {
-  struct target_ops *t;
-
-  /* Fill in the generic GNU/Linux methods.  */
-  t = linux_target ();
-
-  /* Add our register access methods.  */
-  t->to_fetch_registers = ppc_linux_fetch_inferior_registers;
-  t->to_store_registers = ppc_linux_store_inferior_registers;
-
-  /* Add our breakpoint/watchpoint methods.  */
-  t->to_can_use_hw_breakpoint = ppc_linux_can_use_hw_breakpoint;
-  t->to_insert_hw_breakpoint = ppc_linux_insert_hw_breakpoint;
-  t->to_remove_hw_breakpoint = ppc_linux_remove_hw_breakpoint;
-  t->to_region_ok_for_hw_watchpoint = ppc_linux_region_ok_for_hw_watchpoint;
-  t->to_insert_watchpoint = ppc_linux_insert_watchpoint;
-  t->to_remove_watchpoint = ppc_linux_remove_watchpoint;
-  t->to_insert_mask_watchpoint = ppc_linux_insert_mask_watchpoint;
-  t->to_remove_mask_watchpoint = ppc_linux_remove_mask_watchpoint;
-  t->to_stopped_by_watchpoint = ppc_linux_stopped_by_watchpoint;
-  t->to_stopped_data_address = ppc_linux_stopped_data_address;
-  t->to_watchpoint_addr_within_range = ppc_linux_watchpoint_addr_within_range;
-  t->to_can_accel_watchpoint_condition
-    = ppc_linux_can_accel_watchpoint_condition;
-  t->to_masked_watch_num_registers = ppc_linux_masked_watch_num_registers;
-  t->to_ranged_break_num_registers = ppc_linux_ranged_break_num_registers;
-
-  t->to_read_description = ppc_linux_read_description;
-  t->to_auxv_parse = ppc_linux_auxv_parse;
+  linux_target = &the_ppc_linux_nat_target;
 
   gdb::observers::thread_exit.attach (ppc_linux_thread_exit);
 
   /* Register the target.  */
-  linux_nat_add_target (t);
-  linux_nat_set_new_thread (t, ppc_linux_new_thread);
+  add_target (linux_target);
+
+  linux_nat_set_new_thread (linux_target, ppc_linux_new_thread);
 }
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 24/40] target_ops/C++: m32r GNU/Linux
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (22 preceding siblings ...)
  2018-04-14 19:18 ` [PATCH 25/40] target_ops/C++: m68k GNU/Linux Pedro Alves
@ 2018-04-14 19:18 ` Pedro Alves
  2018-04-14 19:19 ` [PATCH 05/40] target_ops/C++: ctf/tfile targets Pedro Alves
                   ` (17 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:18 UTC (permalink / raw)
  To: gdb-patches

Straighforward conversion.  Not tested.
---
 gdb/m32r-linux-nat.c | 29 +++++++++++++----------------
 1 file changed, 13 insertions(+), 16 deletions(-)

diff --git a/gdb/m32r-linux-nat.c b/gdb/m32r-linux-nat.c
index e5dbfb9832..ccdea941e0 100644
--- a/gdb/m32r-linux-nat.c
+++ b/gdb/m32r-linux-nat.c
@@ -34,7 +34,15 @@
 #include "m32r-tdep.h"
 \f
 
+class m32r_linux_nat_target final : public linux_nat_target
+{
+public:
+  /* Add our register access methods.  */
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+};
 
+static m32r_linux_nat_target the_m32r_linux_nat_target;
 
 /* Since EVB register is not available for native debug, we reduce
    the number of registers.  */
@@ -191,9 +199,8 @@ fill_fpregset (const struct regcache *regcache,
    this for all registers (including the floating point and SSE
    registers).  */
 
-static void
-m32r_linux_fetch_inferior_registers (struct target_ops *ops,
-				     struct regcache *regcache, int regno)
+void
+m32r_linux_nat_target::fetch_registers (struct regcache *regcache, int regno)
 {
   pid_t tid = get_ptrace_pid (regcache_get_ptid (regcache));
 
@@ -213,9 +220,8 @@ m32r_linux_fetch_inferior_registers (struct target_ops *ops,
 /* Store register REGNO back into the child process.  If REGNO is -1,
    do this for all registers (including the floating point and SSE
    registers).  */
-static void
-m32r_linux_store_inferior_registers (struct target_ops *ops,
-				     struct regcache *regcache, int regno)
+void
+m32r_linux_nat_target::store_registers (struct regcache *regcache, int regno)
 {
   pid_t tid = get_ptrace_pid (regcache_get_ptid (regcache));
 
@@ -234,15 +240,6 @@ m32r_linux_store_inferior_registers (struct target_ops *ops,
 void
 _initialize_m32r_linux_nat (void)
 {
-  struct target_ops *t;
-
-  /* Fill in the generic GNU/Linux methods.  */
-  t = linux_target ();
-
-  /* Add our register access methods.  */
-  t->to_fetch_registers = m32r_linux_fetch_inferior_registers;
-  t->to_store_registers = m32r_linux_store_inferior_registers;
-
   /* Register the target.  */
-  linux_nat_add_target (t);
+  add_target (&the_m32r_linux_nat_target);
 }
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 36/40] target_ops/C++: go32/DJGPP
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (20 preceding siblings ...)
  2018-04-14 19:18 ` [PATCH 04/40] target_ops/C++: core target Pedro Alves
@ 2018-04-14 19:18 ` Pedro Alves
  2018-04-14 19:18 ` [PATCH 25/40] target_ops/C++: m68k GNU/Linux Pedro Alves
                   ` (19 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:18 UTC (permalink / raw)
  To: gdb-patches

Straightforward conversion.  Build tested with a cross compiler.
---
 gdb/go32-nat.c | 181 +++++++++++++++++++++++++++++++--------------------------
 1 file changed, 97 insertions(+), 84 deletions(-)

diff --git a/gdb/go32-nat.c b/gdb/go32-nat.c
index f9a52a7a77..dcf60cb3d2 100644
--- a/gdb/go32-nat.c
+++ b/gdb/go32-nat.c
@@ -232,7 +232,6 @@ static int dr_ref_count[4];
 #define SOME_PID 42
 
 static int prog_has_started = 0;
-static void go32_mourn_inferior (struct target_ops *ops);
 
 #define r_ofs(x) (offsetof(TSS,x))
 
@@ -335,8 +334,56 @@ static struct {
   {GDB_SIGNAL_LAST, -1}
 };
 
-static void
-go32_attach (struct target_ops *ops, const char *args, int from_tty)
+/* The go32 target.  */
+
+class go32_nat_target : public x86_nat_target<inf_child_target>
+{
+  void attach (const char *, int) override;
+
+  void resume (ptid_t, int, enum gdb_signal) override;
+
+  ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
+
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+
+  enum target_xfer_status xfer_partial (enum target_object object,
+					const char *annex,
+					gdb_byte *readbuf,
+					const gdb_byte *writebuf,
+					ULONGEST offset, ULONGEST len,
+					ULONGEST *xfered_len) override;
+
+  void files_info () override;
+
+  void terminal_init () override;
+
+  void terminal_inferior () override;
+
+  void terminal_ours_for_output () override;
+
+  void terminal_ours () override;
+
+  void terminal_info (const char *, int) override;
+
+  void pass_ctrlc () override;
+
+  void kill () override;
+
+  void create_inferior (const char *, const std::string &,
+			char **, int) override;
+
+  void mourn_inferior () override;
+
+  int thread_alive (ptid_t ptid) override;
+
+  const char *pid_to_str (ptid_t) override;
+};
+
+static go32_nat_target the_go32_nat_target;
+
+void
+go32_nat_target::attach (const char *args, int from_tty)
 {
   error (_("\
 You cannot attach to a running program on this platform.\n\
@@ -346,9 +393,8 @@ Use the `run' command to run DJGPP programs."));
 static int resume_is_step;
 static int resume_signal = -1;
 
-static void
-go32_resume (struct target_ops *ops,
-	     ptid_t ptid, int step, enum gdb_signal siggnal)
+void
+go32_nat_target::resume (ptid_t ptid, int step, enum gdb_signal siggnal)
 {
   int i;
 
@@ -371,9 +417,9 @@ go32_resume (struct target_ops *ops,
 
 static char child_cwd[FILENAME_MAX];
 
-static ptid_t
-go32_wait (struct target_ops *ops,
-	   ptid_t ptid, struct target_waitstatus *status, int options)
+ptid_t
+go32_nat_target::wait (ptid_t ptid, struct target_waitstatus *status,
+		       int options)
 {
   int i;
   unsigned char saved_opcode;
@@ -505,9 +551,8 @@ fetch_register (struct regcache *regcache, int regno)
 		    _("Invalid register no. %d in fetch_register."), regno);
 }
 
-static void
-go32_fetch_registers (struct target_ops *ops,
-		      struct regcache *regcache, int regno)
+void
+go32_nat_target::fetch_registers (struct regcache *regcache, int regno)
 {
   if (regno >= 0)
     fetch_register (regcache, regno);
@@ -536,9 +581,8 @@ store_register (const struct regcache *regcache, int regno)
 		    _("Invalid register no. %d in store_register."), regno);
 }
 
-static void
-go32_store_registers (struct target_ops *ops,
-		      struct regcache *regcache, int regno)
+void
+go32_nat_target::store_registers (struct regcache *regcache, int regno)
 {
   unsigned r;
 
@@ -598,11 +642,12 @@ go32_xfer_memory (gdb_byte *readbuf, const gdb_byte *writebuf,
 
 /* Target to_xfer_partial implementation.  */
 
-static enum target_xfer_status
-go32_xfer_partial (struct target_ops *ops, enum target_object object,
-		   const char *annex, gdb_byte *readbuf,
-		   const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
-		   ULONGEST *xfered_len)
+enum target_xfer_status
+go32_nat_target::xfer_partial (enum target_object object,
+			       const char *annex, gdb_byte *readbuf,
+			       const gdb_byte *writebuf, ULONGEST offset,
+			       ULONGEST len,
+			       ULONGEST *xfered_len)
 {
   switch (object)
     {
@@ -610,30 +655,30 @@ go32_xfer_partial (struct target_ops *ops, enum target_object object,
       return go32_xfer_memory (readbuf, writebuf, offset, len, xfered_len);
 
     default:
-      return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
-					    readbuf, writebuf, offset, len,
-					    xfered_len);
+      return this->beneath->xfer_partial (object, annex,
+					  readbuf, writebuf, offset, len,
+					  xfered_len);
     }
 }
 
 static cmdline_t child_cmd;	/* Parsed child's command line kept here.  */
 
-static void
-go32_files_info (struct target_ops *target)
+void
+go32_nat_target::files_info ()
 {
   printf_unfiltered ("You are running a DJGPP V2 program.\n");
 }
 
-static void
-go32_kill_inferior (struct target_ops *ops)
+void
+go32_nat_target::kill_inferior ()
 {
-  go32_mourn_inferior (ops);
+  mourn_inferior ();
 }
 
-static void
-go32_create_inferior (struct target_ops *ops,
-		      const char *exec_file,
-		      const std::string &allargs, char **env, int from_tty)
+void
+go32_nat_target::create_inferior (const char *exec_file,
+				  const std::string &allargs,
+				  char **env, int from_tty)
 {
   extern char **environ;
   jmp_buf start_state;
@@ -711,8 +756,8 @@ go32_create_inferior (struct target_ops *ops,
   inf = current_inferior ();
   inferior_appeared (inf, SOME_PID);
 
-  if (!target_is_pushed (ops))
-    push_target (ops);
+  if (!target_is_pushed (this))
+    push_target (this);
 
   add_thread_silent (inferior_ptid);
 
@@ -721,8 +766,8 @@ go32_create_inferior (struct target_ops *ops,
   prog_has_started = 1;
 }
 
-static void
-go32_mourn_inferior (struct target_ops *ops)
+void
+go32_nat_target::mourn_inferior ()
 {
   ptid_t ptid;
 
@@ -747,7 +792,7 @@ go32_mourn_inferior (struct target_ops *ops)
   prog_has_started = 0;
 
   generic_mourn_inferior ();
-  inf_child_maybe_unpush_target (ops);
+  maybe_unpush_target ();
 }
 
 /* Hardware watchpoint support.  */
@@ -852,15 +897,15 @@ static int inf_terminal_mode;
    second call will always see GDB's own cooked terminal.  */
 static int terminal_is_ours = 1;
 
-static void
-go32_terminal_init (struct target_ops *self)
+void
+go32_nat_target::terminal_init ()
 {
   inf_mode_valid = 0;	/* Reinitialize, in case they are restarting child.  */
   terminal_is_ours = 1;
 }
 
-static void
-go32_terminal_info (struct target_ops *self, const char *args, int from_tty)
+void
+go32_nat_target::terminal_info (const char *args, int from_tty)
 {
   printf_unfiltered ("Inferior's terminal is in %s mode.\n",
 		     !inf_mode_valid
@@ -889,8 +934,8 @@ go32_terminal_info (struct target_ops *self, const char *args, int from_tty)
 #endif
 }
 
-static void
-go32_terminal_inferior (struct target_ops *self)
+void
+go32_nat_target::terminal_inferior ()
 {
   /* Redirect standard handles as child wants them.  */
   errno = 0;
@@ -910,8 +955,8 @@ go32_terminal_inferior (struct target_ops *self)
   }
 }
 
-static void
-go32_terminal_ours (struct target_ops *self)
+void
+go32_nat_target::terminal_ours ()
 {
   /* Switch to cooked mode on the gdb terminal and save the inferior
      terminal mode to be restored when it is resumed.  */
@@ -937,52 +982,23 @@ go32_terminal_ours (struct target_ops *self)
   }
 }
 
-static void
-go32_pass_ctrlc (struct target_ops *self)
+void
+go32_nat_target::pass_ctrlc ()
 {
 }
 
-static int
-go32_thread_alive (struct target_ops *ops, ptid_t ptid)
+int
+go32_nat_target::thread_alive (ptid_t ptid)
 {
   return !ptid_equal (ptid, null_ptid);
 }
 
-static const char *
-go32_pid_to_str (struct target_ops *ops, ptid_t ptid)
+const char *
+go32_nat_target::pid_to_str (ptid_t ptid)
 {
   return normal_pid_to_str (ptid);
 }
 
-/* Create a go32 target.  */
-
-static struct target_ops *
-go32_target (void)
-{
-  struct target_ops *t = inf_child_target ();
-
-  t->to_attach = go32_attach;
-  t->to_resume = go32_resume;
-  t->to_wait = go32_wait;
-  t->to_fetch_registers = go32_fetch_registers;
-  t->to_store_registers = go32_store_registers;
-  t->to_xfer_partial = go32_xfer_partial;
-  t->to_files_info = go32_files_info;
-  t->to_terminal_init = go32_terminal_init;
-  t->to_terminal_inferior = go32_terminal_inferior;
-  t->to_terminal_ours_for_output = go32_terminal_ours;
-  t->to_terminal_ours = go32_terminal_ours;
-  t->to_terminal_info = go32_terminal_info;
-  t->to_pass_ctrlc = go32_pass_ctrlc;
-  t->to_kill = go32_kill_inferior;
-  t->to_create_inferior = go32_create_inferior;
-  t->to_mourn_inferior = go32_mourn_inferior;
-  t->to_thread_alive = go32_thread_alive;
-  t->to_pid_to_str = go32_pid_to_str;
-
-  return t;
-}
-
 /* Return the current DOS codepage number.  */
 static int
 dos_codepage (void)
@@ -2067,8 +2083,6 @@ go32_info_dos_command (const char *args, int from_tty)
 void
 _initialize_go32_nat (void)
 {
-  struct target_ops *t = go32_target ();
-
   x86_dr_low.set_control = go32_set_dr7;
   x86_dr_low.set_addr = go32_set_dr;
   x86_dr_low.get_status = go32_get_dr6;
@@ -2076,8 +2090,7 @@ _initialize_go32_nat (void)
   x86_dr_low.get_addr = go32_get_dr;
   x86_set_debug_register_length (4);
 
-  x86_use_watchpoints (t);
-  add_target (t);
+  add_target (&the_go32_nat_target);
 
   /* Initialize child's cwd as empty to be initialized when starting
      the child.  */
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 04/40] target_ops/C++: core target
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (19 preceding siblings ...)
  2018-04-14 19:15 ` [PATCH 22/40] target_ops/C++: HP-PA GNU/Linux Pedro Alves
@ 2018-04-14 19:18 ` Pedro Alves
  2018-04-14 19:18 ` [PATCH 36/40] target_ops/C++: go32/DJGPP Pedro Alves
                   ` (20 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:18 UTC (permalink / raw)
  To: gdb-patches

Straighforward conversion.

The core_target global is renamed to avoid conflict with the
"core_target" class.
---
 gdb/corefile.c |  12 ++--
 gdb/corelow.c  | 202 ++++++++++++++++++++++++++++-----------------------------
 gdb/gdbcore.h  |   4 +-
 3 files changed, 105 insertions(+), 113 deletions(-)

diff --git a/gdb/corefile.c b/gdb/corefile.c
index 5a735264ef..c849a10646 100644
--- a/gdb/corefile.c
+++ b/gdb/corefile.c
@@ -53,9 +53,6 @@ static int exec_file_hook_count = 0;		/* Size of array.  */
 
 bfd *core_bfd = NULL;
 
-/* corelow.c target.  It is never NULL after GDB initialization.  */
-
-struct target_ops *core_target;
 \f
 
 /* Backward compatability with old way of specifying core files.  */
@@ -65,12 +62,12 @@ core_file_command (const char *filename, int from_tty)
 {
   dont_repeat ();		/* Either way, seems bogus.  */
 
-  gdb_assert (core_target != NULL);
+  gdb_assert (the_core_target != NULL);
 
   if (!filename)
-    (core_target->to_detach) (core_target, current_inferior (), from_tty);
+    the_core_target->detach (current_inferior (), from_tty);
   else
-    (core_target->to_open) (filename, from_tty);
+    the_core_target->open (filename, from_tty);
 }
 \f
 
@@ -237,8 +234,7 @@ read_memory_object (enum target_object object, CORE_ADDR memaddr,
       enum target_xfer_status status;
       ULONGEST xfered_len;
 
-      status = target_xfer_partial (current_target.beneath,
-				    object, NULL,
+      status = target_xfer_partial (target_stack, object, NULL,
 				    myaddr + xfered, NULL,
 				    memaddr + xfered, len - xfered,
 				    &xfered_len);
diff --git a/gdb/corelow.c b/gdb/corelow.c
index 190f0162d9..f7202f75e3 100644
--- a/gdb/corelow.c
+++ b/gdb/corelow.c
@@ -50,6 +50,55 @@
 #define O_LARGEFILE 0
 #endif
 
+/* The core file target.  */
+
+class core_target final : public target_ops
+{
+public:
+  core_target ()
+  { to_stratum = process_stratum; }
+
+  const char *shortname () override
+  { return "core"; }
+
+  const char *longname () override
+  { return _("Local core dump file"); }
+
+  const char *doc () override
+  {
+    return _("\
+Use a core file as a target.  Specify the filename of the core file.");
+  }
+
+  void open (const char *, int) override;
+  void close () override;
+  void detach (inferior *, int) override;
+  void fetch_registers (struct regcache *, int) override;
+
+  enum target_xfer_status xfer_partial (enum target_object object,
+					const char *annex,
+					gdb_byte *readbuf,
+					const gdb_byte *writebuf,
+					ULONGEST offset, ULONGEST len,
+					ULONGEST *xfered_len) override;
+  void files_info () override;
+
+  int thread_alive (ptid_t ptid) override;
+  const struct target_desc *read_description () override;
+
+  const char *pid_to_str (ptid_t) override;
+
+  const char *thread_name (struct thread_info *) override;
+
+  int has_memory () override;
+  int has_stack () override;
+  int has_registers () override;
+  bool info_proc (const char *, enum info_proc_what) override;
+};
+
+/* See gdbcore.h.  */
+struct target_ops *the_core_target;
+
 /* List of all available core_fns.  On gdb startup, each core file
    register reader calls deprecated_add_core_fns() to register
    information on each core format it is prepared to read.  */
@@ -74,21 +123,15 @@ static struct gdbarch *core_gdbarch = NULL;
    unix child targets.  */
 static struct target_section_table *core_data;
 
-static void core_files_info (struct target_ops *);
-
 static struct core_fns *sniff_core_bfd (bfd *);
 
 static int gdb_check_format (bfd *);
 
-static void core_close (struct target_ops *self);
-
 static void core_close_cleanup (void *ignore);
 
 static void add_to_thread_list (bfd *, asection *, void *);
 
-static void init_core_ops (void);
-
-static struct target_ops core_ops;
+static core_target core_ops;
 
 /* An arbitrary identifier for the core inferior.  */
 #define CORELOW_PID 1
@@ -185,7 +228,7 @@ gdb_check_format (bfd *abfd)
    stack spaces as empty.  */
 
 static void
-core_close (struct target_ops *self)
+core_close ()
 {
   if (core_bfd)
     {
@@ -216,7 +259,13 @@ core_close (struct target_ops *self)
 static void
 core_close_cleanup (void *ignore)
 {
-  core_close (NULL);
+  core_close ();
+}
+
+void
+core_target::close ()
+{
+  core_close ();
 }
 
 /* Look for sections whose names start with `.reg/' so that we can
@@ -266,8 +315,8 @@ add_to_thread_list (bfd *abfd, asection *asect, void *reg_sect_arg)
 
 /* This routine opens and sets up the core file bfd.  */
 
-static void
-core_open (const char *arg, int from_tty)
+void
+core_target::open (const char *arg, int from_tty)
 {
   const char *p;
   int siggy;
@@ -463,10 +512,10 @@ core_open (const char *arg, int from_tty)
     }
 }
 
-static void
-core_detach (struct target_ops *ops, inferior *inf, int from_tty)
+void
+core_target::detach (inferior *inf, int from_tty)
 {
-  unpush_target (ops);
+  unpush_target (this);
   reinit_frame_cache ();
   if (from_tty)
     printf_filtered (_("No core file now.\n"));
@@ -585,9 +634,8 @@ get_core_registers_cb (const char *sect_name, int size,
 
 /* We just get all the registers, so we don't use regno.  */
 
-static void
-get_core_registers (struct target_ops *ops,
-		    struct regcache *regcache, int regno)
+void
+core_target::fetch_registers (struct regcache *regcache, int regno)
 {
   int i;
   struct gdbarch *gdbarch;
@@ -619,8 +667,8 @@ get_core_registers (struct target_ops *ops,
       regcache_raw_supply (regcache, i, NULL);
 }
 
-static void
-core_files_info (struct target_ops *t)
+void
+core_target::files_info ()
 {
   print_section_info (core_data, core_bfd);
 }
@@ -655,11 +703,10 @@ add_to_spuid_list (bfd *abfd, asection *asect, void *list_p)
   list->pos += 4;
 }
 
-static enum target_xfer_status
-core_xfer_partial (struct target_ops *ops, enum target_object object,
-		   const char *annex, gdb_byte *readbuf,
-		   const gdb_byte *writebuf, ULONGEST offset,
-		   ULONGEST len, ULONGEST *xfered_len)
+enum target_xfer_status
+core_target::xfer_partial (enum target_object object, const char *annex,
+			   gdb_byte *readbuf, const gdb_byte *writebuf,
+			   ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
 {
   switch (object)
     {
@@ -861,35 +908,13 @@ core_xfer_partial (struct target_ops *ops, enum target_object object,
       return TARGET_XFER_E_IO;
 
     default:
-      return ops->beneath->to_xfer_partial (ops->beneath, object,
-					    annex, readbuf,
-					    writebuf, offset, len,
-					    xfered_len);
+      return this->beneath->xfer_partial (object, annex, readbuf,
+					  writebuf, offset, len,
+					  xfered_len);
     }
 }
 
 \f
-/* If mourn is being called in all the right places, this could be say
-   `gdb internal error' (since generic_mourn calls
-   breakpoint_init_inferior).  */
-
-static int
-ignore (struct target_ops *ops, struct gdbarch *gdbarch,
-	struct bp_target_info *bp_tgt)
-{
-  return 0;
-}
-
-/* Implement the to_remove_breakpoint method.  */
-
-static int
-core_remove_breakpoint (struct target_ops *ops, struct gdbarch *gdbarch,
-			struct bp_target_info *bp_tgt,
-			enum remove_bp_reason reason)
-{
-  return 0;
-}
-
 
 /* Okay, let's be honest: threads gleaned from a core file aren't
    exactly lively, are they?  On the other hand, if we don't claim
@@ -897,8 +922,8 @@ core_remove_breakpoint (struct target_ops *ops, struct gdbarch *gdbarch,
    to appear in an "info thread" command, which is quite a useful
    behaviour.
  */
-static int
-core_thread_alive (struct target_ops *ops, ptid_t ptid)
+int
+core_target::thread_alive (ptid_t ptid)
 {
   return 1;
 }
@@ -908,24 +933,23 @@ core_thread_alive (struct target_ops *ops, ptid_t ptid)
    wrapper could be avoided if targets got a chance to specialize
    core_ops.  */
 
-static const struct target_desc *
-core_read_description (struct target_ops *target)
+const struct target_desc *
+core_target::read_description ()
 {
   if (core_gdbarch && gdbarch_core_read_description_p (core_gdbarch))
     {
       const struct target_desc *result;
 
-      result = gdbarch_core_read_description (core_gdbarch, 
-					      target, core_bfd);
+      result = gdbarch_core_read_description (core_gdbarch, this, core_bfd);
       if (result != NULL)
 	return result;
     }
 
-  return target->beneath->to_read_description (target->beneath);
+  return this->beneath->read_description ();
 }
 
-static const char *
-core_pid_to_str (struct target_ops *ops, ptid_t ptid)
+const char *
+core_target::pid_to_str (ptid_t ptid)
 {
   static char buf[64];
   struct inferior *inf;
@@ -956,8 +980,8 @@ core_pid_to_str (struct target_ops *ops, ptid_t ptid)
   return buf;
 }
 
-static const char *
-core_thread_name (struct target_ops *self, struct thread_info *thr)
+const char *
+core_target::thread_name (struct thread_info *thr)
 {
   if (core_gdbarch
       && gdbarch_core_thread_name_p (core_gdbarch))
@@ -965,29 +989,28 @@ core_thread_name (struct target_ops *self, struct thread_info *thr)
   return NULL;
 }
 
-static int
-core_has_memory (struct target_ops *ops)
+int
+core_target::has_memory ()
 {
   return (core_bfd != NULL);
 }
 
-static int
-core_has_stack (struct target_ops *ops)
+int
+core_target::has_stack ()
 {
   return (core_bfd != NULL);
 }
 
-static int
-core_has_registers (struct target_ops *ops)
+int
+core_target::has_registers ()
 {
   return (core_bfd != NULL);
 }
 
 /* Implement the to_info_proc method.  */
 
-static void
-core_info_proc (struct target_ops *ops, const char *args,
-		enum info_proc_what request)
+bool
+core_target::info_proc (const char *args, enum info_proc_what request)
 {
   struct gdbarch *gdbarch = get_current_arch ();
 
@@ -995,47 +1018,18 @@ core_info_proc (struct target_ops *ops, const char *args,
      method on gdbarch, not 'info_proc'.  */
   if (gdbarch_core_info_proc_p (gdbarch))
     gdbarch_core_info_proc (gdbarch, args, request);
-}
-
-/* Fill in core_ops with its defined operations and properties.  */
 
-static void
-init_core_ops (void)
-{
-  core_ops.to_shortname = "core";
-  core_ops.to_longname = "Local core dump file";
-  core_ops.to_doc =
-    "Use a core file as a target.  Specify the filename of the core file.";
-  core_ops.to_open = core_open;
-  core_ops.to_close = core_close;
-  core_ops.to_detach = core_detach;
-  core_ops.to_fetch_registers = get_core_registers;
-  core_ops.to_xfer_partial = core_xfer_partial;
-  core_ops.to_files_info = core_files_info;
-  core_ops.to_insert_breakpoint = ignore;
-  core_ops.to_remove_breakpoint = core_remove_breakpoint;
-  core_ops.to_thread_alive = core_thread_alive;
-  core_ops.to_read_description = core_read_description;
-  core_ops.to_pid_to_str = core_pid_to_str;
-  core_ops.to_thread_name = core_thread_name;
-  core_ops.to_stratum = process_stratum;
-  core_ops.to_has_memory = core_has_memory;
-  core_ops.to_has_stack = core_has_stack;
-  core_ops.to_has_registers = core_has_registers;
-  core_ops.to_info_proc = core_info_proc;
-  core_ops.to_magic = OPS_MAGIC;
-
-  if (core_target)
-    internal_error (__FILE__, __LINE__, 
-		    _("init_core_ops: core target already exists (\"%s\")."),
-		    core_target->to_longname);
-  core_target = &core_ops;
+  return true;
 }
 
 void
 _initialize_corelow (void)
 {
-  init_core_ops ();
+  if (the_core_target != NULL)
+    internal_error (__FILE__, __LINE__,
+		    _("core target already exists (\"%s\")."),
+		    the_core_target->longname ());
+  the_core_target = &core_ops;
 
   add_target_with_completer (&core_ops, filename_completer);
 }
diff --git a/gdb/gdbcore.h b/gdb/gdbcore.h
index 5264eef4ee..04a235dd90 100644
--- a/gdb/gdbcore.h
+++ b/gdb/gdbcore.h
@@ -135,7 +135,9 @@ extern void specify_exec_file_hook (void (*hook) (const char *filename));
 
 extern bfd *core_bfd;
 
-extern struct target_ops *core_target;
+/* corelow.c target.  It is never NULL after GDB initialization.  */
+
+extern struct target_ops *the_core_target;
 
 /* Whether to open exec and core files read-only or read-write.  */
 
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 25/40] target_ops/C++: m68k GNU/Linux
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (21 preceding siblings ...)
  2018-04-14 19:18 ` [PATCH 36/40] target_ops/C++: go32/DJGPP Pedro Alves
@ 2018-04-14 19:18 ` Pedro Alves
  2018-04-14 19:18 ` [PATCH 24/40] target_ops/C++: m32r GNU/Linux Pedro Alves
                   ` (18 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:18 UTC (permalink / raw)
  To: gdb-patches

Straighforward conversion.  Not tested.
---
 gdb/m68k-linux-nat.c | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/gdb/m68k-linux-nat.c b/gdb/m68k-linux-nat.c
index 754051bc4b..536361f60d 100644
--- a/gdb/m68k-linux-nat.c
+++ b/gdb/m68k-linux-nat.c
@@ -57,6 +57,17 @@
 #define PTRACE_GET_THREAD_AREA 25
 #endif
 \f
+
+class m68k_linux_nat_target final : public linux_nat_target
+{
+public:
+  /* Add our register access methods.  */
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+};
+
+static m68k_linux_nat_target the_m68k_linux_nat_target;
+
 /* This table must line up with gdbarch_register_name in "m68k-tdep.c".  */
 static const int regmap[] =
 {
@@ -392,9 +403,8 @@ static void store_fpregs (const struct regcache *regcache, int tid, int regno)
    this for all registers (including the floating point and SSE
    registers).  */
 
-static void
-m68k_linux_fetch_inferior_registers (struct target_ops *ops,
-				     struct regcache *regcache, int regno)
+void
+m68k_linux_nat_target::fetch_registers (struct regcache *regcache, int regno)
 {
   pid_t tid;
 
@@ -446,9 +456,8 @@ m68k_linux_fetch_inferior_registers (struct target_ops *ops,
 /* Store register REGNO back into the child process.  If REGNO is -1,
    do this for all registers (including the floating point and SSE
    registers).  */
-static void
-m68k_linux_store_inferior_registers (struct target_ops *ops,
-				     struct regcache *regcache, int regno)
+void
+m68k_linux_nat_target::store_registers (struct regcache *regcache, int regno)
 {
   pid_t tid;
 
@@ -509,15 +518,6 @@ ps_get_thread_area (struct ps_prochandle *ph,
 void
 _initialize_m68k_linux_nat (void)
 {
-  struct target_ops *t;
-
-  /* Fill in the generic GNU/Linux methods.  */
-  t = linux_target ();
-
-  /* Add our register access methods.  */
-  t->to_fetch_registers = m68k_linux_fetch_inferior_registers;
-  t->to_store_registers = m68k_linux_store_inferior_registers;
-
   /* Register the target.  */
-  linux_nat_add_target (t);
+  add_target (&the_m68k_linux_nat_target);
 }
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 15/40] target_ops/C++: Solaris/procfs
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (25 preceding siblings ...)
  2018-04-14 19:19 ` [PATCH 31/40] target_ops/C++: Base FreeBSD target Pedro Alves
@ 2018-04-14 19:19 ` Pedro Alves
  2018-04-14 19:19 ` [PATCH 30/40] target_ops/C++: Xtensa GNU/Linux Pedro Alves
                   ` (14 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:19 UTC (permalink / raw)
  To: gdb-patches

Straighforward conversion.  I'd tested this on a Solaris VM.
---
 gdb/procfs.c     | 304 ++++++++++++++++++++++++-------------------------------
 gdb/sol-thread.c | 165 +++++++++++++++---------------
 2 files changed, 220 insertions(+), 249 deletions(-)

diff --git a/gdb/procfs.c b/gdb/procfs.c
index 478770d0fe..abae358c44 100644
--- a/gdb/procfs.c
+++ b/gdb/procfs.c
@@ -86,69 +86,88 @@
 
 /* This module defines the GDB target vector and its methods.  */
 
-static void procfs_attach (struct target_ops *, const char *, int);
-static void procfs_detach (struct target_ops *, inferior *, int);
-static void procfs_resume (struct target_ops *,
-			   ptid_t, int, enum gdb_signal);
-static void procfs_files_info (struct target_ops *);
-static void procfs_fetch_registers (struct target_ops *,
-				    struct regcache *, int);
-static void procfs_store_registers (struct target_ops *,
-				    struct regcache *, int);
-static void procfs_pass_signals (struct target_ops *self,
-				 int, unsigned char *);
-static void procfs_kill_inferior (struct target_ops *ops);
-static void procfs_mourn_inferior (struct target_ops *ops);
-static void procfs_create_inferior (struct target_ops *, const char *,
-				    const std::string &, char **, int);
-static ptid_t procfs_wait (struct target_ops *,
-			   ptid_t, struct target_waitstatus *, int);
+
 static enum target_xfer_status procfs_xfer_memory (gdb_byte *,
 						   const gdb_byte *,
 						   ULONGEST, ULONGEST,
 						   ULONGEST *);
-static target_xfer_partial_ftype procfs_xfer_partial;
 
-static int procfs_thread_alive (struct target_ops *ops, ptid_t);
+class procfs_target final : public inf_child_target
+{
+public:
+  void create_inferior (const char *, const std::string &,
+			char **, int) override;
+
+  void kill () override;
+
+  void mourn_inferior () override;
+
+  void attach (const char *, int) override;
+  void detach (inferior *inf, int) override;
+
+  void resume (ptid_t, int, enum gdb_signal) override;
+  ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
+
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+
+  enum target_xfer_status xfer_partial (enum target_object object,
+					const char *annex,
+					gdb_byte *readbuf,
+					const gdb_byte *writebuf,
+					ULONGEST offset, ULONGEST len,
+					ULONGEST *xfered_len) override;
+
+  void pass_signals (int, unsigned char *) override;
 
-static void procfs_update_thread_list (struct target_ops *ops);
-static const char *procfs_pid_to_str (struct target_ops *, ptid_t);
+  void files_info () override;
 
-static int proc_find_memory_regions (struct target_ops *self,
-				     find_memory_region_ftype, void *);
+  void update_thread_list () override;
 
-static char *procfs_make_note_section (struct target_ops *self,
-				       bfd *, int *);
+  int thread_alive (ptid_t ptid) override;
 
-static int procfs_can_use_hw_breakpoint (struct target_ops *self,
-					 enum bptype, int, int);
+  const char *pid_to_str (ptid_t) override;
 
-static void procfs_info_proc (struct target_ops *, const char *,
-			      enum info_proc_what);
+  thread_control_capabilities get_thread_control_capabilities () override
+  { return tc_schedlock; }
 
-static int procfs_stopped_by_watchpoint (struct target_ops *);
+  /* find_memory_regions support method for gcore */
+  int find_memory_regions (find_memory_region_ftype func, void *data)
+    override;
 
-static int procfs_insert_watchpoint (struct target_ops *,
-				     CORE_ADDR, int,
-				     enum target_hw_bp_type,
-				     struct expression *);
+  char *make_corefile_notes (bfd *, int *) override;
 
-static int procfs_remove_watchpoint (struct target_ops *,
-				     CORE_ADDR, int,
-				     enum target_hw_bp_type,
-				     struct expression *);
+  bool info_proc (const char *, enum info_proc_what) override;
+
+#if defined(PR_MODEL_NATIVE) && (PR_MODEL_NATIVE == PR_MODEL_LP64)
+  int auxv_parse (gdb_byte **readptr,
+		  gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
+    override;
+#endif
+
+  int stopped_by_watchpoint () override;
+
+  int insert_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
+			 struct expression *) override;
+
+  int remove_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
+			 struct expression *) override;
+
+  int region_ok_for_hw_watchpoint (CORE_ADDR, int) override;
+
+  int can_use_hw_breakpoint (enum bptype, int, int) override;
+  int stopped_data_address (CORE_ADDR *) override;
+};
 
-static int procfs_region_ok_for_hw_watchpoint (struct target_ops *,
-					       CORE_ADDR, int);
-static int procfs_stopped_data_address (struct target_ops *, CORE_ADDR *);
+static procfs_target the_procfs_target;
 
 #if defined (PR_MODEL_NATIVE) && (PR_MODEL_NATIVE == PR_MODEL_LP64)
 /* When GDB is built as 64-bit application on Solaris, the auxv data
    is presented in 64-bit format.  We need to provide a custom parser
    to handle that.  */
-static int
-procfs_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
-		   gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
+int
+procfs_target::auxv_parse (gdb_byte **readptr,
+			   gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
   gdb_byte *ptr = *readptr;
@@ -171,51 +190,6 @@ procfs_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
 }
 #endif
 
-/* Create a procfs target.  */
-
-static struct target_ops *
-procfs_target (void)
-{
-  struct target_ops *t = inf_child_target ();
-
-  t->to_create_inferior = procfs_create_inferior;
-  t->to_kill = procfs_kill_inferior;
-  t->to_mourn_inferior = procfs_mourn_inferior;
-  t->to_attach = procfs_attach;
-  t->to_detach = procfs_detach;
-  t->to_wait = procfs_wait;
-  t->to_resume = procfs_resume;
-  t->to_fetch_registers = procfs_fetch_registers;
-  t->to_store_registers = procfs_store_registers;
-  t->to_xfer_partial = procfs_xfer_partial;
-  t->to_pass_signals = procfs_pass_signals;
-  t->to_files_info = procfs_files_info;
-
-  t->to_update_thread_list = procfs_update_thread_list;
-  t->to_thread_alive = procfs_thread_alive;
-  t->to_pid_to_str = procfs_pid_to_str;
-
-  t->to_has_thread_control = tc_schedlock;
-  t->to_find_memory_regions = proc_find_memory_regions;
-  t->to_make_corefile_notes = procfs_make_note_section;
-  t->to_info_proc = procfs_info_proc;
-
-#if defined(PR_MODEL_NATIVE) && (PR_MODEL_NATIVE == PR_MODEL_LP64)
-  t->to_auxv_parse = procfs_auxv_parse;
-#endif
-
-  t->to_stopped_by_watchpoint = procfs_stopped_by_watchpoint;
-  t->to_insert_watchpoint = procfs_insert_watchpoint;
-  t->to_remove_watchpoint = procfs_remove_watchpoint;
-  t->to_region_ok_for_hw_watchpoint = procfs_region_ok_for_hw_watchpoint;
-  t->to_can_use_hw_breakpoint = procfs_can_use_hw_breakpoint;
-  t->to_stopped_data_address = procfs_stopped_data_address;
-
-  t->to_magic = OPS_MAGIC;
-
-  return t;
-}
-
 /* =================== END, TARGET_OPS "MODULE" =================== */
 
 /* World Unification:
@@ -1912,8 +1886,8 @@ procfs_debug_inferior (procinfo *pi)
   return 0;
 }
 
-static void
-procfs_attach (struct target_ops *ops, const char *args, int from_tty)
+void
+procfs_target::attach (const char *args, int from_tty)
 {
   char *exec_file;
   int   pid;
@@ -1937,12 +1911,12 @@ procfs_attach (struct target_ops *ops, const char *args, int from_tty)
       fflush (stdout);
     }
   inferior_ptid = do_attach (pid_to_ptid (pid));
-  if (!target_is_pushed (ops))
-    push_target (ops);
+  if (!target_is_pushed (this))
+    push_target (this);
 }
 
-static void
-procfs_detach (struct target_ops *ops, inferior *inf, int from_tty)
+void
+procfs_target::detach (inferior *inf, int from_tty)
 {
   int pid = ptid_get_pid (inferior_ptid);
 
@@ -1963,7 +1937,7 @@ procfs_detach (struct target_ops *ops, inferior *inf, int from_tty)
 
   inferior_ptid = null_ptid;
   detach_inferior (pid);
-  inf_child_maybe_unpush_target (ops);
+  maybe_unpush_target ();
 }
 
 static ptid_t
@@ -2092,9 +2066,8 @@ do_detach ()
    registers.  So we cache the results, and mark the cache invalid
    when the process is resumed.  */
 
-static void
-procfs_fetch_registers (struct target_ops *ops,
-			struct regcache *regcache, int regnum)
+void
+procfs_target::fetch_registers (struct regcache *regcache, int regnum)
 {
   gdb_gregset_t *gregs;
   procinfo *pi;
@@ -2142,9 +2115,8 @@ procfs_fetch_registers (struct target_ops *ops,
    FIXME: is that a really bad idea?  Have to think about cases where
    writing one register might affect the value of others, etc.  */
 
-static void
-procfs_store_registers (struct target_ops *ops,
-			struct regcache *regcache, int regnum)
+void
+procfs_target::store_registers (struct regcache *regcache, int regnum)
 {
   gdb_gregset_t *gregs;
   procinfo *pi;
@@ -2228,9 +2200,9 @@ syscall_is_lwp_create (procinfo *pi, int scall)
    Returns the id of process (and possibly thread) that incurred the
    event.  Event codes are returned through a pointer parameter.  */
 
-static ptid_t
-procfs_wait (struct target_ops *ops,
-	     ptid_t ptid, struct target_waitstatus *status, int options)
+ptid_t
+procfs_target::wait (ptid_t ptid, struct target_waitstatus *status,
+		     int options)
 {
   /* First cut: loosely based on original version 2.1.  */
   procinfo *pi;
@@ -2271,7 +2243,7 @@ wait_again:
 	      int wait_retval;
 
 	      /* /proc file not found; presumably child has terminated.  */
-	      wait_retval = wait (&wstat); /* "wait" for the child's exit.  */
+	      wait_retval = ::wait (&wstat); /* "wait" for the child's exit.  */
 
 	      /* Wrong child?  */
 	      if (wait_retval != ptid_get_pid (inferior_ptid))
@@ -2364,7 +2336,7 @@ wait_again:
 		      }
 		    else
 		      {
-			int temp = wait (&wstat);
+			int temp = ::wait (&wstat);
 
 			/* FIXME: shouldn't I make sure I get the right
 			   event from the right process?  If (for
@@ -2594,11 +2566,11 @@ wait_again:
 /* Perform a partial transfer to/from the specified object.  For
    memory transfers, fall back to the old memory xfer functions.  */
 
-static enum target_xfer_status
-procfs_xfer_partial (struct target_ops *ops, enum target_object object,
-		     const char *annex, gdb_byte *readbuf,
-		     const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
-		     ULONGEST *xfered_len)
+enum target_xfer_status
+procfs_target::xfer_partial (enum target_object object,
+			     const char *annex, gdb_byte *readbuf,
+			     const gdb_byte *writebuf, ULONGEST offset,
+			     ULONGEST len, ULONGEST *xfered_len)
 {
   switch (object)
     {
@@ -2606,13 +2578,13 @@ procfs_xfer_partial (struct target_ops *ops, enum target_object object,
       return procfs_xfer_memory (readbuf, writebuf, offset, len, xfered_len);
 
     case TARGET_OBJECT_AUXV:
-      return memory_xfer_auxv (ops, object, annex, readbuf, writebuf,
+      return memory_xfer_auxv (this, object, annex, readbuf, writebuf,
 			       offset, len, xfered_len);
 
     default:
-      return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
-					    readbuf, writebuf, offset, len,
-					    xfered_len);
+      return this->beneath->xfer_partial (object, annex,
+					  readbuf, writebuf, offset, len,
+					  xfered_len);
     }
 }
 
@@ -2741,9 +2713,8 @@ make_signal_thread_runnable (procinfo *process, procinfo *pi, void *ptr)
    allow any child thread to run; if non-zero, then allow only the
    indicated thread to run.  (not implemented yet).  */
 
-static void
-procfs_resume (struct target_ops *ops,
-	       ptid_t ptid, int step, enum gdb_signal signo)
+void
+procfs_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
 {
   procinfo *pi, *thread;
   int native_signo;
@@ -2821,9 +2792,8 @@ procfs_resume (struct target_ops *ops,
 
 /* Set up to trace signals in the child process.  */
 
-static void
-procfs_pass_signals (struct target_ops *self,
-		     int numsigs, unsigned char *pass_signals)
+void
+procfs_target::pass_signals (int numsigs, unsigned char *pass_signals)
 {
   sigset_t signals;
   procinfo *pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0);
@@ -2844,8 +2814,8 @@ procfs_pass_signals (struct target_ops *self,
 
 /* Print status information about the child process.  */
 
-static void
-procfs_files_info (struct target_ops *ignore)
+void
+procfs_target::files_info ()
 {
   struct inferior *inf = current_inferior ();
 
@@ -2887,8 +2857,8 @@ unconditionally_kill_inferior (procinfo *pi)
 /* We're done debugging it, and we want it to go away.  Then we want
    GDB to forget all about it.  */
 
-static void
-procfs_kill_inferior (struct target_ops *ops)
+void
+procfs_target::kill ()
 {
   if (!ptid_equal (inferior_ptid, null_ptid)) /* ? */
     {
@@ -2903,8 +2873,8 @@ procfs_kill_inferior (struct target_ops *ops)
 
 /* Forget we ever debugged this thing!  */
 
-static void
-procfs_mourn_inferior (struct target_ops *ops)
+void
+procfs_target::mourn_inferior ()
 {
   procinfo *pi;
 
@@ -2918,7 +2888,7 @@ procfs_mourn_inferior (struct target_ops *ops)
 
   generic_mourn_inferior ();
 
-  inf_child_maybe_unpush_target (ops);
+  maybe_unpush_target ();
 }
 
 /* When GDB forks to create a runnable inferior process, this function
@@ -3081,9 +3051,10 @@ procfs_set_exec_trap (void)
    abstracted out and shared with other unix targets such as
    inf-ptrace?  */
 
-static void
-procfs_create_inferior (struct target_ops *ops, const char *exec_file,
-			const std::string &allargs, char **env, int from_tty)
+void
+procfs_target::create_inferior (const char *exec_file,
+				const std::string &allargs,
+				char **env, int from_tty)
 {
   char *shell_file = getenv ("SHELL");
   char *tryname;
@@ -3165,7 +3136,7 @@ procfs_create_inferior (struct target_ops *ops, const char *exec_file,
      pid shouldn't change.  */
   add_thread_silent (pid_to_ptid (pid));
 
-  procfs_init_inferior (ops, pid);
+  procfs_init_inferior (this, pid);
 }
 
 /* An observer for the "inferior_created" event.  */
@@ -3191,8 +3162,8 @@ procfs_notice_thread (procinfo *pi, procinfo *thread, void *ptr)
 /* Query all the threads that the target knows about, and give them
    back to GDB to add to its list.  */
 
-static void
-procfs_update_thread_list (struct target_ops *ops)
+void
+procfs_target::update_thread_list ()
 {
   procinfo *pi;
 
@@ -3208,8 +3179,8 @@ procfs_update_thread_list (struct target_ops *ops)
    really seem to be doing his job.  Got to investigate how to tell
    when a thread is really gone.  */
 
-static int
-procfs_thread_alive (struct target_ops *ops, ptid_t ptid)
+int
+procfs_target::thread_alive (ptid_t ptid)
 {
   int proc, thread;
   procinfo *pi;
@@ -3235,8 +3206,8 @@ procfs_thread_alive (struct target_ops *ops, ptid_t ptid)
 /* Convert PTID to a string.  Returns the string in a static
    buffer.  */
 
-static const char *
-procfs_pid_to_str (struct target_ops *ops, ptid_t ptid)
+const char *
+procfs_target::pid_to_str (ptid_t ptid)
 {
   static char buf[80];
 
@@ -3306,10 +3277,8 @@ procfs_set_watchpoint (ptid_t ptid, CORE_ADDR addr, int len, int rwflag,
    procfs.c targets due to the fact that some of them still define
    target_can_use_hardware_watchpoint.  */
 
-static int
-procfs_can_use_hw_breakpoint (struct target_ops *self,
-			      enum bptype type,
-			      int cnt, int othertype)
+int
+procfs_target::can_use_hw_breakpoint (enum bptype type, int cnt, int othertype)
 {
   /* Due to the way that proc_set_watchpoint() is implemented, host
      and target pointers must be of the same size.  If they are not,
@@ -3332,8 +3301,8 @@ procfs_can_use_hw_breakpoint (struct target_ops *self,
 /* Returns non-zero if process is stopped on a hardware watchpoint
    fault, else returns zero.  */
 
-static int
-procfs_stopped_by_watchpoint (struct target_ops *ops)
+int
+procfs_target::stopped_by_watchpoint ()
 {
   procinfo *pi;
 
@@ -3356,8 +3325,8 @@ procfs_stopped_by_watchpoint (struct target_ops *ops)
    procfs_stopped_by_watchpoint returned 1, thus no further checks are
    done.  The function also assumes that ADDR is not NULL.  */
 
-static int
-procfs_stopped_data_address (struct target_ops *targ, CORE_ADDR *addr)
+int
+procfs_target::stopped_data_address (CORE_ADDR *addr)
 {
   procinfo *pi;
 
@@ -3365,11 +3334,10 @@ procfs_stopped_data_address (struct target_ops *targ, CORE_ADDR *addr)
   return proc_watchpoint_address (pi, addr);
 }
 
-static int
-procfs_insert_watchpoint (struct target_ops *self,
-			  CORE_ADDR addr, int len,
-			  enum target_hw_bp_type type,
-			  struct expression *cond)
+int
+procfs_target::insert_watchpoint (CORE_ADDR addr, int len,
+				  enum target_hw_bp_type type,
+				  struct expression *cond)
 {
   if (!target_have_steppable_watchpoint
       && !gdbarch_have_nonsteppable_watchpoint (target_gdbarch ()))
@@ -3389,18 +3357,16 @@ procfs_insert_watchpoint (struct target_ops *self,
     }
 }
 
-static int
-procfs_remove_watchpoint (struct target_ops *self,
-			  CORE_ADDR addr, int len,
-			  enum target_hw_bp_type type,
-			  struct expression *cond)
+int
+procfs_target::remove_watchpoint (CORE_ADDR addr, int len,
+				  enum target_hw_bp_type type,
+				  struct expression *cond)
 {
   return procfs_set_watchpoint (inferior_ptid, addr, 0, 0, 0);
 }
 
-static int
-procfs_region_ok_for_hw_watchpoint (struct target_ops *self,
-				    CORE_ADDR addr, int len)
+int
+procfs_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
 {
   /* The man page for proc(4) on Solaris 2.6 and up says that the
      system can support "thousands" of hardware watchpoints, but gives
@@ -3494,9 +3460,8 @@ find_memory_regions_callback (struct prmap *map,
    Stops iterating and returns the first non-zero value returned by
    the callback.  */
 
-static int
-proc_find_memory_regions (struct target_ops *self,
-			  find_memory_region_ftype func, void *data)
+int
+procfs_target::find_memory_regions (find_memory_region_ftype func, void *data)
 {
   procinfo *pi = find_procinfo_or_die (ptid_get_pid (inferior_ptid), 0);
 
@@ -3586,9 +3551,8 @@ info_proc_mappings (procinfo *pi, int summary)
 
 /* Implement the "info proc" command.  */
 
-static void
-procfs_info_proc (struct target_ops *ops, const char *args,
-		  enum info_proc_what what)
+bool
+procfs_target::info_proc (const char *args, enum info_proc_what what)
 {
   struct cleanup *old_chain;
   procinfo *process  = NULL;
@@ -3673,6 +3637,8 @@ procfs_info_proc (struct target_ops *ops, const char *args,
     }
 
   do_cleanups (old_chain);
+
+  return true;
 }
 
 /* Modify the status of the system call identified by SYSCALLNUM in
@@ -3773,7 +3739,7 @@ _initialize_procfs (void)
   add_com ("proc-untrace-exit", no_class, proc_untrace_sysexit_cmd,
 	   _("Cancel a trace of exits from the syscall."));
 
-  add_target (procfs_target ());
+  add_target (&the_procfs_target);
 }
 
 /* =================== END, GDB  "MODULE" =================== */
@@ -3881,8 +3847,8 @@ find_stop_signal (void)
     return GDB_SIGNAL_0;
 }
 
-static char *
-procfs_make_note_section (struct target_ops *self, bfd *obfd, int *note_size)
+char *
+procfs_target::make_corefile_notes (bfd *obfd, int *note_size)
 {
   struct cleanup *old_chain;
   gdb_gregset_t gregs;
diff --git a/gdb/sol-thread.c b/gdb/sol-thread.c
index 62d839cd41..0572da30c0 100644
--- a/gdb/sol-thread.c
+++ b/gdb/sol-thread.c
@@ -69,7 +69,41 @@
 #include "minsyms.h"
 #include "objfiles.h"
 
-struct target_ops sol_thread_ops;
+class sol_thread_target : public target_ops
+{
+public:
+  sol_thread_target ()
+  { this->to_stratum = thread_stratum; }
+
+  const char *shortname () override
+  { return "solaris-threads"; }
+  const char *longname () override
+  { return _("Solaris threads and pthread."); }
+  const char *doc () override
+  { return _("Solaris threads and pthread support."); }
+
+  void detach (inferior *, int) override;
+  ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
+  void resume (ptid_t, int, enum gdb_signal) override;
+  void mourn_inferior () override;
+  const char *pid_to_str (ptid_t) override;
+  ptid_t get_ada_task_ptid (long lwp, long thread) override;
+
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+
+  enum target_xfer_status xfer_partial (enum target_object object,
+					const char *annex,
+					gdb_byte *readbuf,
+					const gdb_byte *writebuf,
+					ULONGEST offset, ULONGEST len,
+					ULONGEST *xfered_len) override;
+
+  int thread_alive (ptid_t ptid) override;
+  void update_thread_list () override;
+};
+
+static sol_thread_target sol_thread_ops;
 
 /* Prototypes for supply_gregset etc.  */
 #include "gregset.h"
@@ -93,8 +127,6 @@ static struct ps_prochandle main_ph;
 static td_thragent_t *main_ta;
 static int sol_thread_active = 0;
 
-static void init_sol_thread_ops (void);
-
 /* Default definitions: These must be defined in tm.h if they are to
    be shared with a process module such as procfs.  */
 
@@ -347,15 +379,15 @@ lwp_to_thread (ptid_t lwp)
    process to have been previously attached.  It *might* work if the
    program was started via the normal ptrace (PTRACE_TRACEME).  */
 
-static void
-sol_thread_detach (struct target_ops *ops, inferior *inf, int from_tty)
+void
+sol_thread_target::detach (inferior *inf, int from_tty)
 {
-  struct target_ops *beneath = find_target_beneath (ops);
+  struct target_ops *beneath = find_target_beneath (this);
 
   sol_thread_active = 0;
   inferior_ptid = pid_to_ptid (ptid_get_pid (main_ph.ptid));
-  unpush_target (ops);
-  beneath->to_detach (beneath, inf, from_tty);
+  unpush_target (this);
+  beneath->detach (inf, from_tty);
 }
 
 /* Resume execution of process PTID.  If STEP is nozero, then just
@@ -363,11 +395,10 @@ sol_thread_detach (struct target_ops *ops, inferior *inf, int from_tty)
    activated.  We may have to convert PTID from a thread ID to an LWP
    ID for procfs.  */
 
-static void
-sol_thread_resume (struct target_ops *ops,
-		   ptid_t ptid, int step, enum gdb_signal signo)
+void
+sol_thread_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
 {
-  struct target_ops *beneath = find_target_beneath (ops);
+  struct target_ops *beneath = find_target_beneath (this);
 
   scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
 
@@ -387,19 +418,19 @@ sol_thread_resume (struct target_ops *ops,
 		 ptid_get_tid (save_ptid));
     }
 
-  beneath->to_resume (beneath, ptid, step, signo);
+  beneath->resume (ptid, step, signo);
 }
 
 /* Wait for any threads to stop.  We may have to convert PTID from a
    thread ID to an LWP ID, and vice versa on the way out.  */
 
-static ptid_t
-sol_thread_wait (struct target_ops *ops,
-		 ptid_t ptid, struct target_waitstatus *ourstatus, int options)
+ptid_t
+sol_thread_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
+			 int options)
 {
   ptid_t rtnval;
   ptid_t save_ptid;
-  struct target_ops *beneath = find_target_beneath (ops);
+  struct target_ops *beneath = find_target_beneath (this);
 
   save_ptid = inferior_ptid;
   scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
@@ -420,7 +451,7 @@ sol_thread_wait (struct target_ops *ops,
 		 ptid_get_tid (save_ptid));
     }
 
-  rtnval = beneath->to_wait (beneath, ptid, ourstatus, options);
+  rtnval = beneath->wait (ptid, ourstatus, options);
 
   if (ourstatus->kind != TARGET_WAITKIND_EXITED)
     {
@@ -444,9 +475,8 @@ sol_thread_wait (struct target_ops *ops,
   return rtnval;
 }
 
-static void
-sol_thread_fetch_registers (struct target_ops *ops,
-			    struct regcache *regcache, int regnum)
+void
+sol_thread_target::fetch_registers (struct regcache *regcache, int regnum)
 {
   thread_t thread;
   td_thrhandle_t thandle;
@@ -455,13 +485,13 @@ sol_thread_fetch_registers (struct target_ops *ops,
   prfpregset_t fpregset;
   gdb_gregset_t *gregset_p = &gregset;
   gdb_fpregset_t *fpregset_p = &fpregset;
-  struct target_ops *beneath = find_target_beneath (ops);
+  struct target_ops *beneath = find_target_beneath (this);
   ptid_t ptid = regcache_get_ptid (regcache);
 
   if (!ptid_tid_p (ptid))
     {
       /* It's an LWP; pass the request on to the layer beneath.  */
-      beneath->to_fetch_registers (beneath, regcache, regnum);
+      beneath->fetch_registers (regcache, regnum);
       return;
     }
 
@@ -500,9 +530,8 @@ sol_thread_fetch_registers (struct target_ops *ops,
   supply_fpregset (regcache, (const gdb_fpregset_t *) fpregset_p);
 }
 
-static void
-sol_thread_store_registers (struct target_ops *ops,
-			    struct regcache *regcache, int regnum)
+void
+sol_thread_target::store_registers (struct regcache *regcache, int regnum)
 {
   thread_t thread;
   td_thrhandle_t thandle;
@@ -513,10 +542,10 @@ sol_thread_store_registers (struct target_ops *ops,
 
   if (!ptid_tid_p (ptid))
     {
-      struct target_ops *beneath = find_target_beneath (ops);
+      struct target_ops *beneath = find_target_beneath (this);
 
       /* It's an LWP; pass the request on to the layer beneath.  */
-      beneath->to_store_registers (beneath, regcache, regnum);
+      beneath->store_registers (regcache, regnum);
       return;
     }
 
@@ -557,13 +586,14 @@ sol_thread_store_registers (struct target_ops *ops,
    target_write_partial for details of each variant.  One, and only
    one, of readbuf or writebuf must be non-NULL.  */
 
-static enum target_xfer_status
-sol_thread_xfer_partial (struct target_ops *ops, enum target_object object,
-			  const char *annex, gdb_byte *readbuf,
-			  const gdb_byte *writebuf,
-			 ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
+enum target_xfer_status
+sol_thread_target::xfer_partial (enum target_object object,
+				 const char *annex, gdb_byte *readbuf,
+				 const gdb_byte *writebuf,
+				 ULONGEST offset, ULONGEST len,
+				 ULONGEST *xfered_len)
 {
-  struct target_ops *beneath = find_target_beneath (ops);
+  struct target_ops *beneath = find_target_beneath (this);
 
   scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
 
@@ -577,8 +607,8 @@ sol_thread_xfer_partial (struct target_ops *ops, enum target_object object,
       inferior_ptid = procfs_first_available ();
     }
 
-  return beneath->to_xfer_partial (beneath, object, annex, readbuf,
-				   writebuf, offset, len, xfered_len);
+  return beneath->xfer_partial (object, annex, readbuf,
+				writebuf, offset, len, xfered_len);
 }
 
 static void
@@ -588,7 +618,7 @@ check_for_thread_db (void)
   ptid_t ptid;
 
   /* Don't attempt to use thread_db for remote targets.  */
-  if (!(target_can_run (&current_target) || core_bfd))
+  if (!(target_can_run () || core_bfd))
     return;
 
   /* Do nothing if we couldn't load libthread_db.so.1.  */
@@ -656,22 +686,22 @@ sol_thread_new_objfile (struct objfile *objfile)
 
 /* Clean up after the inferior dies.  */
 
-static void
-sol_thread_mourn_inferior (struct target_ops *ops)
+void
+sol_thread_target::mourn_inferior ()
 {
-  struct target_ops *beneath = find_target_beneath (ops);
+  struct target_ops *beneath = find_target_beneath (this);
 
   sol_thread_active = 0;
 
-  unpush_target (ops);
+  unpush_target (this);
 
-  beneath->to_mourn_inferior (beneath);
+  beneath->mourn_inferior ();
 }
 
 /* Return true if PTID is still active in the inferior.  */
 
-static int
-sol_thread_alive (struct target_ops *ops, ptid_t ptid)
+int
+sol_thread_target::thread_alive (ptid_t ptid)
 {
   if (ptid_tid_p (ptid))
     {
@@ -689,10 +719,10 @@ sol_thread_alive (struct target_ops *ops, ptid_t ptid)
     }
   else
     {
-      struct target_ops *beneath = find_target_beneath (ops);
+      struct target_ops *beneath = find_target_beneath (this);
 
       /* It's an LPW; pass the request on to the layer below.  */
-      return beneath->to_thread_alive (beneath, ptid);
+      return beneath->thread_alive (ptid);
     }
 }
 
@@ -976,8 +1006,8 @@ ps_lgetLDT (struct ps_prochandle *ph, lwpid_t lwpid,
 
 /* Convert PTID to printable form.  */
 
-static const char *
-solaris_pid_to_str (struct target_ops *ops, ptid_t ptid)
+const char *
+sol_thread_target::pid_to_str (ptid_t ptid)
 {
   static char buf[100];
 
@@ -1027,16 +1057,16 @@ sol_update_thread_list_callback (const td_thrhandle_t *th, void *ignored)
   return 0;
 }
 
-static void
-sol_update_thread_list (struct target_ops *ops)
+void
+sol_thread_target::update_thread_list ()
 {
-  struct target_ops *beneath = find_target_beneath (ops);
+  struct target_ops *beneath = find_target_beneath (this);
 
   /* Delete dead threads.  */
   prune_threads ();
 
   /* Find any new LWP's.  */
-  beneath->to_update_thread_list (beneath);
+  beneath->update_thread_list ();
 
   /* Then find any new user-level threads.  */
   p_td_ta_thr_iter (main_ta, sol_update_thread_list_callback, (void *) 0,
@@ -1143,8 +1173,8 @@ thread_db_find_thread_from_tid (struct thread_info *thread, void *data)
   return 0;
 }
 
-static ptid_t
-sol_get_ada_task_ptid (struct target_ops *self, long lwp, long thread)
+ptid_t
+sol_thread_target::get_ada_task_ptid (long lwp, long thread)
 {
   struct thread_info *thread_info =
     iterate_over_threads (thread_db_find_thread_from_tid, &thread);
@@ -1153,7 +1183,7 @@ sol_get_ada_task_ptid (struct target_ops *self, long lwp, long thread)
     {
       /* The list of threads is probably not up to date.  Find any
          thread that is missing from the list, and try again.  */
-      sol_update_thread_list (&current_target);
+      update_thread_list ();
       thread_info = iterate_over_threads (thread_db_find_thread_from_tid,
                                           &thread);
     }
@@ -1163,34 +1193,11 @@ sol_get_ada_task_ptid (struct target_ops *self, long lwp, long thread)
   return (thread_info->ptid);
 }
 
-static void
-init_sol_thread_ops (void)
-{
-  sol_thread_ops.to_shortname = "solaris-threads";
-  sol_thread_ops.to_longname = "Solaris threads and pthread.";
-  sol_thread_ops.to_doc = "Solaris threads and pthread support.";
-  sol_thread_ops.to_detach = sol_thread_detach;
-  sol_thread_ops.to_resume = sol_thread_resume;
-  sol_thread_ops.to_wait = sol_thread_wait;
-  sol_thread_ops.to_fetch_registers = sol_thread_fetch_registers;
-  sol_thread_ops.to_store_registers = sol_thread_store_registers;
-  sol_thread_ops.to_xfer_partial = sol_thread_xfer_partial;
-  sol_thread_ops.to_mourn_inferior = sol_thread_mourn_inferior;
-  sol_thread_ops.to_thread_alive = sol_thread_alive;
-  sol_thread_ops.to_pid_to_str = solaris_pid_to_str;
-  sol_thread_ops.to_update_thread_list = sol_update_thread_list;
-  sol_thread_ops.to_stratum = thread_stratum;
-  sol_thread_ops.to_get_ada_task_ptid = sol_get_ada_task_ptid;
-  sol_thread_ops.to_magic = OPS_MAGIC;
-}
-
 void
 _initialize_sol_thread (void)
 {
   void *dlhandle;
 
-  init_sol_thread_ops ();
-
   dlhandle = dlopen ("libthread_db.so.1", RTLD_NOW);
   if (!dlhandle)
     goto die;
@@ -1223,8 +1230,6 @@ _initialize_sol_thread (void)
   resolve (td_thr_getgregs);
   resolve (td_thr_setgregs);
 
-  complete_target_initialization (&sol_thread_ops);
-
   add_cmd ("sol-threads", class_maintenance, info_solthreads,
 	   _("Show info on Solaris user threads."), &maintenanceinfolist);
 
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 35/40] target_ops/C++: NTO/QNX, nto-procfs.c
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (28 preceding siblings ...)
  2018-04-14 19:19 ` [PATCH 26/40] target_ops/C++: s390 GNU/Linux Pedro Alves
@ 2018-04-14 19:19 ` Pedro Alves
  2018-04-14 19:19 ` [PATCH 16/40] target_ops/C++: Windows targets Pedro Alves
                   ` (11 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:19 UTC (permalink / raw)
  To: gdb-patches

Straightforward conversion.  Not tested.
---
 gdb/nto-procfs.c | 332 +++++++++++++++++++++++++++++--------------------------
 1 file changed, 173 insertions(+), 159 deletions(-)

diff --git a/gdb/nto-procfs.c b/gdb/nto-procfs.c
index 5ff01560e0..1ca4bac336 100644
--- a/gdb/nto-procfs.c
+++ b/gdb/nto-procfs.c
@@ -55,22 +55,104 @@ static sighandler_t ofunc;
 
 static procfs_run run;
 
-static ptid_t do_attach (ptid_t ptid);
+/* Create the "native" and "procfs" targets.  */
+
+struct nto_procfs_target : public inf_child_target
+{
+  void open (const char *arg, int from_tty) override;
+
+  void attach (const char *, int) override = 0;
+
+  void post_attach (int);
+
+  void detach (inferior *, int) override;
+
+  void resume (ptid_t, int, enum gdb_signal) override;
+
+  ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
+
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+
+  enum target_xfer_status xfer_partial (enum target_object object,
+					const char *annex,
+					gdb_byte *readbuf,
+					const gdb_byte *writebuf,
+					ULONGEST offset, ULONGEST len,
+					ULONGEST *xfered_len) override;
+
+  void files_info () override;
+
+  int insert_breakpoint (struct gdbarch *, struct bp_target_info *) override;
+
+  int remove_breakpoint (struct gdbarch *, struct bp_target_info *,
+			 enum remove_bp_reason) override;
+
+  int can_use_hw_breakpoint (enum bptype, int, int) override;
+
+  int insert_hw_breakpoint (struct gdbarch *, struct bp_target_info *) override;
+
+  int remove_hw_breakpoint (struct gdbarch *, struct bp_target_info *) override;
+
+  int insert_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
+			 struct expression *) override;
+
+  int remove_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
+			 struct expression *) override;
+
+  int stopped_by_watchpoint () override;
+
+  void kill () override;
+
+  void create_inferior (const char *, const std::string &,
+			char **, int) override;
+
+  void mourn_inferior () override;
 
-static int procfs_can_use_hw_breakpoint (struct target_ops *self,
-					 enum bptype, int, int);
+  void pass_signals (int, unsigned char *) override;
 
-static int procfs_insert_hw_watchpoint (struct target_ops *self,
-					CORE_ADDR addr, int len,
-					enum target_hw_bp_type type,
-					struct expression *cond);
+  int thread_alive (ptid_t ptid) override;
 
-static int procfs_remove_hw_watchpoint (struct target_ops *self,
-					CORE_ADDR addr, int len,
-					enum target_hw_bp_type type,
-					struct expression *cond);
+  void update_thread_list () override;
 
-static int procfs_stopped_by_watchpoint (struct target_ops *ops);
+  const char *pid_to_str (ptid_t) override;
+
+  void interrupt () override;
+
+  bool have_continuable_watchpoint ()
+  { return true; }
+
+  const char *extra_thread_info (struct thread_info *) override;
+
+  char *pid_to_exec_file (int pid) override;
+};
+
+/* For "target native".  */
+struct nto_procfs_target_native final : public nto_procfs_target
+{
+  /* Leave shortname as "native".  */
+
+  const char *longname () override
+  { return _("QNX Neutrino local process"); }
+
+  const char *doc () override
+  { return _("QNX Neutrino local process (started by the \"run\" command)."); }
+};
+
+/* For "target procfs <node>".  */
+struct nto_procfs_target_procfs final : public nto_procfs_target
+{
+  const char *shortname () override
+  { return "procfs"; }
+
+  const char *longname () override
+  { return _("QNX Neutrino local or remote process"); }
+
+  const char *doc () override
+  { return _("QNX Neutrino process.  target procfs <node>"); }
+};
+
+static ptid_t do_attach (ptid_t ptid);
 
 /* These two globals are only ever set in procfs_open_1, but are
    referenced elsewhere.  'nto_procfs_node' is a flag used to say
@@ -109,8 +191,8 @@ procfs_is_nto_target (bfd *abfd)
    <arg>' from the (gdb) prompt.  For QNX6 (nto), the only valid arg
    will be a QNX node string, eg: "/net/some_node".  If arg is not a
    valid QNX node, we will default to local.  */
-static void
-procfs_open_1 (struct target_ops *ops, const char *arg, int from_tty)
+void
+nto_procfs_target::open (const char *arg, int from_tty)
 {
   char *endstr;
   char buffer[50];
@@ -202,7 +284,7 @@ procfs_open_1 (struct target_ops *ops, const char *arg, int from_tty)
 	}
     }
 
-  inf_child_open_target (ops, arg, from_tty);
+  inf_child_target::open (arg, from_tty);
   printf_filtered ("Debugging using %s\n", nto_procfs_path);
 }
 
@@ -216,8 +298,8 @@ procfs_set_thread (ptid_t ptid)
 }
 
 /*  Return nonzero if the thread TH is still alive.  */
-static int
-procfs_thread_alive (struct target_ops *ops, ptid_t ptid)
+int
+nto_procfs_target::thread_alive (ptid_t ptid)
 {
   pid_t tid;
   pid_t pid;
@@ -298,8 +380,8 @@ update_thread_private_data (struct thread_info *new_thread,
 #endif /* _NTO_VERSION */
 }
 
-static void
-procfs_update_thread_list (struct target_ops *ops)
+void
+nto_procfs_target::update_thread_list ()
 {
   procfs_status status;
   pid_t pid;
@@ -586,8 +668,8 @@ procfs_meminfo (const char *args, int from_tty)
 }
 
 /* Print status information about what we're accessing.  */
-static void
-procfs_files_info (struct target_ops *ignore)
+void
+nto_procfs_target::files_info ()
 {
   struct inferior *inf = current_inferior ();
 
@@ -599,8 +681,8 @@ procfs_files_info (struct target_ops *ignore)
 
 /* Target to_pid_to_exec_file implementation.  */
 
-static char *
-procfs_pid_to_exec_file (struct target_ops *ops, const int pid)
+char *
+nto_procfs_target::pid_to_exec_file (const int pid)
 {
   int proc_fd;
   static char proc_path[PATH_MAX];
@@ -625,8 +707,8 @@ procfs_pid_to_exec_file (struct target_ops *ops, const int pid)
 }
 
 /* Attach to process PID, then initialize for debugging it.  */
-static void
-procfs_attach (struct target_ops *ops, const char *args, int from_tty)
+void
+nto_procfs_target::attach (const char *args, int from_tty)
 {
   char *exec_file;
   int pid;
@@ -661,8 +743,8 @@ procfs_attach (struct target_ops *ops, const char *args, int from_tty)
   procfs_update_thread_list (ops);
 }
 
-static void
-procfs_post_attach (struct target_ops *self, pid_t pid)
+void
+nto_procfs_target::post_attach (pid_t pid)
 {
   if (exec_bfd)
     solib_create_inferior_hook (0);
@@ -729,9 +811,9 @@ nto_handle_sigint (int signo)
   target_interrupt ();
 }
 
-static ptid_t
-procfs_wait (struct target_ops *ops,
-	     ptid_t ptid, struct target_waitstatus *ourstatus, int options)
+sptid_t
+nto_procfs_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
+			 int options)
 {
   sigset_t set;
   siginfo_t info;
@@ -835,9 +917,8 @@ procfs_wait (struct target_ops *ops,
 /* Read the current values of the inferior's registers, both the
    general register set and floating point registers (if supported)
    and update gdb's idea of their current values.  */
-static void
-procfs_fetch_registers (struct target_ops *ops,
-			struct regcache *regcache, int regno)
+void
+nto_procfs_target::fetch_registers (struct regcache *regcache, int regno)
 {
   union
   {
@@ -883,11 +964,11 @@ procfs_xfer_memory (gdb_byte *readbuf, const gdb_byte *writebuf,
 
 /* Target to_xfer_partial implementation.  */
 
-static enum target_xfer_status
-procfs_xfer_partial (struct target_ops *ops, enum target_object object,
-		     const char *annex, gdb_byte *readbuf,
-		     const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
-		     ULONGEST *xfered_len)
+enum target_xfer_status
+nto_procfs_target::xfer_partial (enum target_object object,
+				 const char *annex, gdb_byte *readbuf,
+				 const gdb_byte *writebuf, ULONGEST offset,
+				 ULONGEST len, ULONGEST *xfered_len)
 {
   switch (object)
     {
@@ -926,9 +1007,9 @@ procfs_xfer_partial (struct target_ops *ops, enum target_object object,
 	}
 	/* Fallthru */
     default:
-      return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
-					    readbuf, writebuf, offset, len,
-					    xfered_len);
+      return this->beneath->xfer_partial (object, annex,
+					  readbuf, writebuf, offset, len,
+					  xfered_len);
     }
 }
 
@@ -936,8 +1017,8 @@ procfs_xfer_partial (struct target_ops *ops, enum target_object object,
    The program resumes execution and will no longer stop
    on signals, etc.  We'd better not have left any breakpoints
    in the program or it'll die when it hits one.  */
-static void
-procfs_detach (struct target_ops *ops, inferior *inf, int from_tty)
+void
+nto_procfs_target::detach (inferior *inf, int from_tty)
 {
   int pid;
 
@@ -970,43 +1051,41 @@ procfs_breakpoint (CORE_ADDR addr, int type, int size)
   return 0;
 }
 
-static int
-procfs_insert_breakpoint (struct target_ops *ops, struct gdbarch *gdbarch,
-			  struct bp_target_info *bp_tgt)
+int
+nto_procfs_target::insert_breakpoint (struct gdbarch *gdbarch,
+				      struct bp_target_info *bp_tgt)
 {
   bp_tgt->placed_address = bp_tgt->reqstd_address;
   return procfs_breakpoint (bp_tgt->placed_address, _DEBUG_BREAK_EXEC, 0);
 }
 
-static int
-procfs_remove_breakpoint (struct target_ops *ops, struct gdbarch *gdbarch,
-			  struct bp_target_info *bp_tgt,
-			  enum remove_bp_reason reason)
+int
+nto_procfs_target::remove_breakpoint (struct gdbarch *gdbarch,
+				      struct bp_target_info *bp_tgt,
+				      enum remove_bp_reason reason)
 {
   return procfs_breakpoint (bp_tgt->placed_address, _DEBUG_BREAK_EXEC, -1);
 }
 
-static int
-procfs_insert_hw_breakpoint (struct target_ops *self, struct gdbarch *gdbarch,
-			     struct bp_target_info *bp_tgt)
+int
+nto_procfs_target::insert_hw_breakpoint (struct gdbarch *gdbarch,
+					 struct bp_target_info *bp_tgt)
 {
   bp_tgt->placed_address = bp_tgt->reqstd_address;
   return procfs_breakpoint (bp_tgt->placed_address,
 			    _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, 0);
 }
 
-static int
-procfs_remove_hw_breakpoint (struct target_ops *self,
-			     struct gdbarch *gdbarch,
-			     struct bp_target_info *bp_tgt)
+int
+nto_procfs_target::remove_hw_breakpoint (struct gdbarch *gdbarch,
+					 struct bp_target_info *bp_tgt)
 {
   return procfs_breakpoint (bp_tgt->placed_address,
 			    _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, -1);
 }
 
-static void
-procfs_resume (struct target_ops *ops,
-	       ptid_t ptid, int step, enum gdb_signal signo)
+void
+nto_procfs_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
 {
   int signal_to_pass;
   procfs_status status;
@@ -1065,8 +1144,8 @@ procfs_resume (struct target_ops *ops,
     }
 }
 
-static void
-procfs_mourn_inferior (struct target_ops *ops)
+void
+nto_procfs_target::mourn_inferior ()
 {
   if (!ptid_equal (inferior_ptid, null_ptid))
     {
@@ -1138,10 +1217,10 @@ breakup_args (char *scratch, char **argv)
   *argv = NULL;
 }
 
-static void
-procfs_create_inferior (struct target_ops *ops, const char *exec_file,
-			const std::string &allargs,
-			char **env, int from_tty)
+void
+nto_procfs_target::create_inferior (const char *exec_file,
+				    const std::string &allargs,
+				    char **env, int from_tty)
 {
   struct inheritance inherit;
   pid_t pid;
@@ -1268,14 +1347,14 @@ procfs_create_inferior (struct target_ops *ops, const char *exec_file,
     solib_create_inferior_hook (0);
 }
 
-static void
-procfs_interrupt (struct target_ops *self)
+void
+nto_procfs_target::interrupt ()
 {
   devctl (ctl_fd, DCMD_PROC_STOP, NULL, 0, 0);
 }
 
-static void
-procfs_kill_inferior (struct target_ops *ops)
+void
+nto_procfs_target::kill ()
 {
   target_mourn_inferior (inferior_ptid);
 }
@@ -1313,9 +1392,8 @@ get_regset (int regset, char *buf, int bufsize, int *regsize)
   return dev_set;
 }
 
-static void
-procfs_store_registers (struct target_ops *ops,
-			struct regcache *regcache, int regno)
+void
+nto_procfs_target::store_registers (struct regcache *regcache, int regno)
 {
   union
   {
@@ -1380,9 +1458,8 @@ procfs_store_registers (struct target_ops *ops,
 
 /* Set list of signals to be handled in the target.  */
 
-static void
-procfs_pass_signals (struct target_ops *self,
-		     int numsigs, unsigned char *pass_signals)
+void
+nto_procfs_target::pass_signals (int numsigs, unsigned char *pass_signals)
 {
   int signo;
 
@@ -1396,8 +1473,8 @@ procfs_pass_signals (struct target_ops *self,
     }
 }
 
-static char *
-procfs_pid_to_str (struct target_ops *ops, ptid_t ptid)
+char *
+nto_procfs_target::pid_to_str (ptid_t ptid)
 {
   static char buf[1024];
   int pid, tid, n;
@@ -1423,87 +1500,27 @@ procfs_pid_to_str (struct target_ops *ops, ptid_t ptid)
   "target procfs <node>" wouldn't make sense as default run target, as
   it needs <node>.  */
 
-static int
-procfs_can_run (struct target_ops *self)
+int
+nto_procfs_target::can_run ()
 {
   return 0;
 }
 
 /* "target procfs".  */
-static struct target_ops nto_procfs_ops;
+static nto_procfs_target_procfs nto_procfs_ops;
 
 /* "target native".  */
-static struct target_ops *nto_native_ops;
-
-/* to_open implementation for "target procfs".  */
-
-static void
-procfs_open (const char *arg, int from_tty)
-{
-  procfs_open_1 (&nto_procfs_ops, arg, from_tty);
-}
-
-/* to_open implementation for "target native".  */
-
-static void
-procfs_native_open (const char *arg, int from_tty)
-{
-  procfs_open_1 (nto_native_ops, arg, from_tty);
-}
+static nto_procfs_target_native nto_native_ops;
 
 /* Create the "native" and "procfs" targets.  */
 
 static void
 init_procfs_targets (void)
 {
-  struct target_ops *t = inf_child_target ();
-
-  /* Leave to_shortname as "native".  */
-  t->to_longname = "QNX Neutrino local process";
-  t->to_doc = "QNX Neutrino local process (started by the \"run\" command).";
-  t->to_open = procfs_native_open;
-  t->to_attach = procfs_attach;
-  t->to_post_attach = procfs_post_attach;
-  t->to_detach = procfs_detach;
-  t->to_resume = procfs_resume;
-  t->to_wait = procfs_wait;
-  t->to_fetch_registers = procfs_fetch_registers;
-  t->to_store_registers = procfs_store_registers;
-  t->to_xfer_partial = procfs_xfer_partial;
-  t->to_files_info = procfs_files_info;
-  t->to_insert_breakpoint = procfs_insert_breakpoint;
-  t->to_remove_breakpoint = procfs_remove_breakpoint;
-  t->to_can_use_hw_breakpoint = procfs_can_use_hw_breakpoint;
-  t->to_insert_hw_breakpoint = procfs_insert_hw_breakpoint;
-  t->to_remove_hw_breakpoint = procfs_remove_hw_breakpoint;
-  t->to_insert_watchpoint = procfs_insert_hw_watchpoint;
-  t->to_remove_watchpoint = procfs_remove_hw_watchpoint;
-  t->to_stopped_by_watchpoint = procfs_stopped_by_watchpoint;
-  t->to_kill = procfs_kill_inferior;
-  t->to_create_inferior = procfs_create_inferior;
-  t->to_mourn_inferior = procfs_mourn_inferior;
-  t->to_pass_signals = procfs_pass_signals;
-  t->to_thread_alive = procfs_thread_alive;
-  t->to_update_thread_list = procfs_update_thread_list;
-  t->to_pid_to_str = procfs_pid_to_str;
-  t->to_interrupt = procfs_interrupt;
-  t->to_have_continuable_watchpoint = 1;
-  t->to_extra_thread_info = nto_extra_thread_info;
-  t->to_pid_to_exec_file = procfs_pid_to_exec_file;
-
-  nto_native_ops = t;
-
   /* Register "target native".  This is the default run target.  */
-  add_target (t);
+  add_target (&nto_native_ops);
 
   /* Register "target procfs <node>".  */
-  nto_procfs_ops = *t;
-  nto_procfs_ops.to_shortname = "procfs";
-  nto_procfs_ops.to_can_run = procfs_can_run;
-  t->to_longname = "QNX Neutrino local or remote process";
-  t->to_doc = "QNX Neutrino process.  target procfs <node>";
-  t->to_open = procfs_open;
-
   add_target (&nto_procfs_ops);
 }
 
@@ -1566,34 +1583,31 @@ procfs_hw_watchpoint (int addr, int len, enum target_hw_bp_type type)
   return 0;
 }
 
-static int
-procfs_can_use_hw_breakpoint (struct target_ops *self,
-			      enum bptype type,
-			      int cnt, int othertype)
+int
+nto_procfs_target::can_use_hw_breakpoint (enum bptype type,
+					  int cnt, int othertype)
 {
   return 1;
 }
 
-static int
-procfs_remove_hw_watchpoint (struct target_ops *self,
-			     CORE_ADDR addr, int len,
-			     enum target_hw_bp_type type,
-			     struct expression *cond)
+int
+nto_procfs_target::remove_hw_watchpoint (CORE_ADDR addr, int len,
+					 enum target_hw_bp_type type,
+					 struct expression *cond)
 {
   return procfs_hw_watchpoint (addr, -1, type);
 }
 
-static int
-procfs_insert_hw_watchpoint (struct target_ops *self,
-			     CORE_ADDR addr, int len,
-			     enum target_hw_bp_type type,
-			     struct expression *cond)
+int
+nto_procfs_target::insert_hw_watchpoint (CORE_ADDR addr, int len,
+					 enum target_hw_bp_type type,
+					 struct expression *cond)
 {
   return procfs_hw_watchpoint (addr, len, type);
 }
 
-static int
-procfs_stopped_by_watchpoint (struct target_ops *ops)
+int
+nto_procfs_target::stopped_by_watchpoint ()
 {
   /* NOTE: nto_stopped_by_watchpoint will be called ONLY while we are
      stopped due to a SIGTRAP.  This assumes gdb works in 'all-stop' mode;
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 05/40] target_ops/C++: ctf/tfile targets
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (23 preceding siblings ...)
  2018-04-14 19:18 ` [PATCH 24/40] target_ops/C++: m32r GNU/Linux Pedro Alves
@ 2018-04-14 19:19 ` Pedro Alves
  2018-04-14 19:19 ` [PATCH 31/40] target_ops/C++: Base FreeBSD target Pedro Alves
                   ` (16 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:19 UTC (permalink / raw)
  To: gdb-patches

init_tracefile_ops is replaced by a base class that is inherited by
both ctf and tfile.
---
 gdb/ctf.c             | 103 +++++++++++++++++++++++--------------------
 gdb/tracefile-tfile.c | 120 +++++++++++++++++++++++++++-----------------------
 gdb/tracefile.c       |  38 ++++++----------
 gdb/tracefile.h       |  16 ++++++-
 4 files changed, 149 insertions(+), 128 deletions(-)

diff --git a/gdb/ctf.c b/gdb/ctf.c
index 07ae93b999..b09cebbf07 100644
--- a/gdb/ctf.c
+++ b/gdb/ctf.c
@@ -32,6 +32,40 @@
 #include <ctype.h>
 #include <algorithm>
 
+/* The CTF target.  */
+
+class ctf_target final : public tracefile_target
+{
+public:
+  const char *shortname () override
+  { return "ctf"; }
+
+  const char *longname () override
+  { return _("CTF file"); }
+
+  const char *doc () override
+  {
+    return _("\
+Use a CTF directory as a target.\n\
+Specify the filename of the CTF directory.");
+  }
+
+  void open (const char *, int) override;
+  void close () override;
+  void fetch_registers (struct regcache *, int) override;
+  enum target_xfer_status xfer_partial (enum target_object object,
+						const char *annex,
+						gdb_byte *readbuf,
+						const gdb_byte *writebuf,
+						ULONGEST offset, ULONGEST len,
+						ULONGEST *xfered_len) override;
+  void files_info () override;
+  int trace_find (enum trace_find_type type, int num,
+			  CORE_ADDR addr1, CORE_ADDR addr2, int *tpp) override;
+  int get_trace_state_variable_value (int tsv, LONGEST *val) override;
+  traceframe_info_up traceframe_info () override;
+};
+
 /* GDB saves trace buffers and other information (such as trace
    status) got from the remote target into Common Trace Format (CTF).
    The following types of information are expected to save in CTF:
@@ -826,7 +860,7 @@ static struct bt_iter_pos *start_pos;
 /* The name of CTF directory.  */
 static char *trace_dirname;
 
-static struct target_ops ctf_ops;
+static ctf_target ctf_ops;
 
 /* Destroy ctf iterator and context.  */
 
@@ -1074,8 +1108,8 @@ ctf_read_tp (struct uploaded_tp **uploaded_tps)
    definitions from the first packet.  Set the start position at the
    second packet which contains events on trace blocks.  */
 
-static void
-ctf_open (const char *dirname, int from_tty)
+void
+ctf_target::open (const char *dirname, int from_tty)
 {
   struct bt_ctf_event *event;
   uint32_t event_id;
@@ -1142,8 +1176,8 @@ ctf_open (const char *dirname, int from_tty)
 /* This is the implementation of target_ops method to_close.  Destroy
    CTF iterator and context.  */
 
-static void
-ctf_close (struct target_ops *self)
+void
+ctf_target::close ()
 {
   int pid;
 
@@ -1161,8 +1195,8 @@ ctf_close (struct target_ops *self)
 /* This is the implementation of target_ops method to_files_info.
    Print the directory name of CTF trace data.  */
 
-static void
-ctf_files_info (struct target_ops *t)
+void
+ctf_target::files_info ()
 {
   printf_filtered ("\t`%s'\n", trace_dirname);
 }
@@ -1172,9 +1206,8 @@ ctf_files_info (struct target_ops *t)
    extract contents from events, and set REGCACHE with the contents.
    If no matched events are found, mark registers unavailable.  */
 
-static void
-ctf_fetch_registers (struct target_ops *ops,
-		     struct regcache *regcache, int regno)
+void
+ctf_target::fetch_registers (struct regcache *regcache, int regno)
 {
   struct gdbarch *gdbarch = regcache->arch ();
   struct bt_ctf_event *event = NULL;
@@ -1258,11 +1291,11 @@ ctf_fetch_registers (struct target_ops *ops,
    OFFSET is within the range, read the contents from events to
    READBUF.  */
 
-static enum target_xfer_status
-ctf_xfer_partial (struct target_ops *ops, enum target_object object,
-		  const char *annex, gdb_byte *readbuf,
-		  const gdb_byte *writebuf, ULONGEST offset,
-		  ULONGEST len, ULONGEST *xfered_len)
+enum target_xfer_status
+ctf_target::xfer_partial (enum target_object object,
+			  const char *annex, gdb_byte *readbuf,
+			  const gdb_byte *writebuf, ULONGEST offset,
+			  ULONGEST len, ULONGEST *xfered_len)
 {
   /* We're only doing regular memory for now.  */
   if (object != TARGET_OBJECT_MEMORY)
@@ -1397,9 +1430,8 @@ ctf_xfer_partial (struct target_ops *ops, enum target_object object,
    trace variable is found, set the value of it to *VAL and return
    true, otherwise return false.  */
 
-static int
-ctf_get_trace_state_variable_value (struct target_ops *self,
-				    int tsvnum, LONGEST *val)
+int
+ctf_target::get_trace_state_variable_value (int tsvnum, LONGEST *val)
 {
   struct bt_iter_pos *pos;
   int found = 0;
@@ -1515,9 +1547,9 @@ ctf_get_traceframe_address (void)
    Iterate the events whose name is "frame", extract the tracepoint
    number in it.  Return traceframe number when matched.  */
 
-static int
-ctf_trace_find (struct target_ops *self, enum trace_find_type type, int num,
-		CORE_ADDR addr1, CORE_ADDR addr2, int *tpp)
+int
+ctf_target::trace_find (enum trace_find_type type, int num,
+			CORE_ADDR addr1, CORE_ADDR addr2, int *tpp)
 {
   int tfnum = 0;
   int found = 0;
@@ -1617,10 +1649,10 @@ ctf_trace_find (struct target_ops *self, enum trace_find_type type, int num,
    frame, extract memory range information, and return them in
    traceframe_info.  */
 
-static traceframe_info_up
-ctf_traceframe_info (struct target_ops *self)
+traceframe_info_up
+ctf_target::traceframe_info ()
 {
-  traceframe_info_up info (new traceframe_info);
+  traceframe_info_up info (new struct traceframe_info);
   const char *name;
   struct bt_iter_pos *pos;
 
@@ -1684,27 +1716,6 @@ ctf_traceframe_info (struct target_ops *self)
   return info;
 }
 
-static void
-init_ctf_ops (void)
-{
-  memset (&ctf_ops, 0, sizeof (ctf_ops));
-
-  init_tracefile_ops (&ctf_ops);
-  ctf_ops.to_shortname = "ctf";
-  ctf_ops.to_longname = "CTF file";
-  ctf_ops.to_doc = "Use a CTF directory as a target.\n\
-Specify the filename of the CTF directory.";
-  ctf_ops.to_open = ctf_open;
-  ctf_ops.to_close = ctf_close;
-  ctf_ops.to_fetch_registers = ctf_fetch_registers;
-  ctf_ops.to_xfer_partial = ctf_xfer_partial;
-  ctf_ops.to_files_info = ctf_files_info;
-  ctf_ops.to_trace_find = ctf_trace_find;
-  ctf_ops.to_get_trace_state_variable_value
-    = ctf_get_trace_state_variable_value;
-  ctf_ops.to_traceframe_info = ctf_traceframe_info;
-}
-
 #endif
 
 /* module initialization */
@@ -1713,8 +1724,6 @@ void
 _initialize_ctf (void)
 {
 #if HAVE_LIBBABELTRACE
-  init_ctf_ops ();
-
   add_target_with_completer (&ctf_ops, filename_completer);
 #endif
 }
diff --git a/gdb/tracefile-tfile.c b/gdb/tracefile-tfile.c
index d7e934770a..af8e3bd83b 100644
--- a/gdb/tracefile-tfile.c
+++ b/gdb/tracefile-tfile.c
@@ -38,6 +38,42 @@
 #define O_LARGEFILE 0
 #endif
 
+/* The tfile target.  */
+
+class tfile_target final : public tracefile_target
+{
+ public:
+  const char *shortname () override
+  { return "tfile"; }
+
+  const char *longname () override
+  { return _("Local trace dump file"); }
+
+  const char *doc () override
+  {
+    return _("\
+Use a trace file as a target.  Specify the filename of the trace file.");
+  }
+
+  void open (const char *, int) override;
+  void close () override;
+  void fetch_registers (struct regcache *, int) override;
+  enum target_xfer_status xfer_partial (enum target_object object,
+						const char *annex,
+						gdb_byte *readbuf,
+						const gdb_byte *writebuf,
+						ULONGEST offset, ULONGEST len,
+						ULONGEST *xfered_len) override;
+  void files_info () override;
+  int trace_find (enum trace_find_type type, int num,
+			  CORE_ADDR addr1, CORE_ADDR addr2, int *tpp) override;
+  int get_trace_state_variable_value (int tsv, LONGEST *val) override;
+  traceframe_info_up traceframe_info () override;
+
+  void get_tracepoint_status (struct breakpoint *tp,
+			      struct uploaded_tp *utp) override;
+};
+
 /* TFILE trace writer.  */
 
 struct tfile_trace_file_writer
@@ -275,7 +311,7 @@ tfile_write_tdesc (struct trace_file_writer *self)
     = (struct tfile_trace_file_writer *) self;
 
   gdb::optional<std::string> tdesc
-    = target_fetch_description_xml (&current_target);
+    = target_fetch_description_xml (target_stack);
 
   if (!tdesc)
     return;
@@ -378,9 +414,7 @@ tfile_trace_file_writer_new (void)
 
 /* target tfile command */
 
-static struct target_ops tfile_ops;
-
-/* Fill in tfile_ops with its defined operations and properties.  */
+static tfile_target tfile_ops;
 
 #define TRACE_HEADER_SIZE 8
 
@@ -417,8 +451,8 @@ tfile_read (gdb_byte *readbuf, int size)
     error (_("Premature end of file while reading trace file"));
 }
 
-static void
-tfile_open (const char *arg, int from_tty)
+void
+tfile_target::open (const char *arg, int from_tty)
 {
   int flags;
   int scratch_chan;
@@ -580,8 +614,8 @@ tfile_interp_line (char *line, struct uploaded_tp **utpp,
 
 /* Close the trace file and generally clean up.  */
 
-static void
-tfile_close (struct target_ops *self)
+void
+tfile_target::close ()
 {
   int pid;
 
@@ -592,7 +626,7 @@ tfile_close (struct target_ops *self)
   inferior_ptid = null_ptid;	/* Avoid confusion from thread stuff.  */
   exit_inferior_silent (pid);
 
-  close (trace_fd);
+  ::close (trace_fd);
   trace_fd = -1;
   xfree (trace_filename);
   trace_filename = NULL;
@@ -601,15 +635,14 @@ tfile_close (struct target_ops *self)
   trace_reset_local_state ();
 }
 
-static void
-tfile_files_info (struct target_ops *t)
+void
+tfile_target::files_info ()
 {
   printf_filtered ("\t`%s'\n", trace_filename);
 }
 
-static void
-tfile_get_tracepoint_status (struct target_ops *self,
-			     struct breakpoint *tp, struct uploaded_tp *utp)
+void
+tfile_target::get_tracepoint_status (struct breakpoint *tp, struct uploaded_tp *utp)
 {
   /* Other bits of trace status were collected as part of opening the
      trace files, so nothing to do here.  */
@@ -653,9 +686,9 @@ tfile_get_traceframe_address (off_t tframe_offset)
    both the traceframe and tracepoint number, otherwise -1 for
    each.  */
 
-static int
-tfile_trace_find (struct target_ops *self, enum trace_find_type type, int num,
-		  CORE_ADDR addr1, CORE_ADDR addr2, int *tpp)
+int
+tfile_target::trace_find (enum trace_find_type type, int num,
+			  CORE_ADDR addr1, CORE_ADDR addr2, int *tpp)
 {
   short tpnum;
   int tfnum = 0, found = 0;
@@ -836,9 +869,8 @@ traceframe_find_block_type (char type_wanted, int pos)
 /* Look for a block of saved registers in the traceframe, and get the
    requested register from it.  */
 
-static void
-tfile_fetch_registers (struct target_ops *ops,
-		       struct regcache *regcache, int regno)
+void
+tfile_target::fetch_registers (struct regcache *regcache, int regno)
 {
   struct gdbarch *gdbarch = regcache->arch ();
   int offset, regn, regsize, dummy;
@@ -883,7 +915,7 @@ tfile_fetch_registers (struct target_ops *ops,
 }
 
 static enum target_xfer_status
-tfile_xfer_partial_features (struct target_ops *ops, const char *annex,
+tfile_xfer_partial_features (const char *annex,
 			     gdb_byte *readbuf, const gdb_byte *writebuf,
 			     ULONGEST offset, ULONGEST len,
 			     ULONGEST *xfered_len)
@@ -909,15 +941,15 @@ tfile_xfer_partial_features (struct target_ops *ops, const char *annex,
   return TARGET_XFER_OK;
 }
 
-static enum target_xfer_status
-tfile_xfer_partial (struct target_ops *ops, enum target_object object,
-		    const char *annex, gdb_byte *readbuf,
-		    const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
-		    ULONGEST *xfered_len)
+enum target_xfer_status
+tfile_target::xfer_partial (enum target_object object,
+			    const char *annex, gdb_byte *readbuf,
+			    const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
+			    ULONGEST *xfered_len)
 {
   /* We're only doing regular memory and tdesc for now.  */
   if (object == TARGET_OBJECT_AVAILABLE_FEATURES)
-    return tfile_xfer_partial_features (ops, annex, readbuf, writebuf,
+    return tfile_xfer_partial_features (annex, readbuf, writebuf,
 					offset, len, xfered_len);
   if (object != TARGET_OBJECT_MEMORY)
     return TARGET_XFER_E_IO;
@@ -1001,9 +1033,8 @@ tfile_xfer_partial (struct target_ops *ops, enum target_object object,
 /* Iterate through the blocks of a trace frame, looking for a 'V'
    block with a matching tsv number.  */
 
-static int
-tfile_get_trace_state_variable_value (struct target_ops *self,
-				      int tsvnum, LONGEST *val)
+int
+tfile_target::get_trace_state_variable_value (int tsvnum, LONGEST *val)
 {
   int pos;
   int found = 0;
@@ -1085,10 +1116,10 @@ build_traceframe_info (char blocktype, void *data)
   return 0;
 }
 
-static traceframe_info_up
-tfile_traceframe_info (struct target_ops *self)
+traceframe_info_up
+tfile_target::traceframe_info ()
 {
-  traceframe_info_up info (new traceframe_info);
+  traceframe_info_up info (new struct traceframe_info);
 
   traceframe_walk_blocks (build_traceframe_info, 0, info.get ());
 
@@ -1105,31 +1136,8 @@ tfile_append_tdesc_line (const char *line)
   buffer_grow_str (&trace_tdesc, "\n");
 }
 
-static void
-init_tfile_ops (void)
-{
-  init_tracefile_ops (&tfile_ops);
-
-  tfile_ops.to_shortname = "tfile";
-  tfile_ops.to_longname = "Local trace dump file";
-  tfile_ops.to_doc
-    = "Use a trace file as a target.  Specify the filename of the trace file.";
-  tfile_ops.to_open = tfile_open;
-  tfile_ops.to_close = tfile_close;
-  tfile_ops.to_fetch_registers = tfile_fetch_registers;
-  tfile_ops.to_xfer_partial = tfile_xfer_partial;
-  tfile_ops.to_files_info = tfile_files_info;
-  tfile_ops.to_get_tracepoint_status = tfile_get_tracepoint_status;
-  tfile_ops.to_trace_find = tfile_trace_find;
-  tfile_ops.to_get_trace_state_variable_value
-    = tfile_get_trace_state_variable_value;
-  tfile_ops.to_traceframe_info = tfile_traceframe_info;
-}
-
 void
 _initialize_tracefile_tfile (void)
 {
-  init_tfile_ops ();
-
   add_target_with_completer (&tfile_ops, filename_completer);
 }
diff --git a/gdb/tracefile.c b/gdb/tracefile.c
index 58d620c3af..9c9c75398e 100644
--- a/gdb/tracefile.c
+++ b/gdb/tracefile.c
@@ -425,16 +425,16 @@ tracefile_fetch_registers (struct regcache *regcache, int regno)
 
 /* This is the implementation of target_ops method to_has_all_memory.  */
 
-static int
-tracefile_has_all_memory (struct target_ops *ops)
+int
+tracefile_target::has_all_memory ()
 {
   return 1;
 }
 
 /* This is the implementation of target_ops method to_has_memory.  */
 
-static int
-tracefile_has_memory (struct target_ops *ops)
+int
+tracefile_target::has_memory ()
 {
   return 1;
 }
@@ -443,8 +443,8 @@ tracefile_has_memory (struct target_ops *ops)
    The target has a stack when GDB has already selected one trace
    frame.  */
 
-static int
-tracefile_has_stack (struct target_ops *ops)
+int
+tracefile_target::has_stack ()
 {
   return get_traceframe_number () != -1;
 }
@@ -453,8 +453,8 @@ tracefile_has_stack (struct target_ops *ops)
    The target has registers when GDB has already selected one trace
    frame.  */
 
-static int
-tracefile_has_registers (struct target_ops *ops)
+int
+tracefile_target::has_registers ()
 {
   return get_traceframe_number () != -1;
 }
@@ -462,8 +462,8 @@ tracefile_has_registers (struct target_ops *ops)
 /* This is the implementation of target_ops method to_thread_alive.
    tracefile has one thread faked by GDB.  */
 
-static int
-tracefile_thread_alive (struct target_ops *ops, ptid_t ptid)
+int
+tracefile_target::thread_alive (ptid_t ptid)
 {
   return 1;
 }
@@ -471,8 +471,8 @@ tracefile_thread_alive (struct target_ops *ops, ptid_t ptid)
 /* This is the implementation of target_ops method to_get_trace_status.
    The trace status for a file is that tracing can never be run.  */
 
-static int
-tracefile_get_trace_status (struct target_ops *self, struct trace_status *ts)
+int
+tracefile_target::get_trace_status (struct trace_status *ts)
 {
   /* Other bits of trace status were collected as part of opening the
      trace files, so nothing to do here.  */
@@ -480,19 +480,9 @@ tracefile_get_trace_status (struct target_ops *self, struct trace_status *ts)
   return -1;
 }
 
-/* Initialize OPS for tracefile related targets.  */
-
-void
-init_tracefile_ops (struct target_ops *ops)
+tracefile_target::tracefile_target ()
 {
-  ops->to_stratum = process_stratum;
-  ops->to_get_trace_status = tracefile_get_trace_status;
-  ops->to_has_all_memory = tracefile_has_all_memory;
-  ops->to_has_memory = tracefile_has_memory;
-  ops->to_has_stack = tracefile_has_stack;
-  ops->to_has_registers = tracefile_has_registers;
-  ops->to_thread_alive = tracefile_thread_alive;
-  ops->to_magic = OPS_MAGIC;
+  this->to_stratum = process_stratum;
 }
 
 void
diff --git a/gdb/tracefile.h b/gdb/tracefile.h
index e6d4460d3e..accd038ebd 100644
--- a/gdb/tracefile.h
+++ b/gdb/tracefile.h
@@ -2,6 +2,7 @@
 #define TRACEFILE_H 1
 
 #include "tracepoint.h"
+#include "target.h"
 
 struct trace_file_writer;
 
@@ -113,7 +114,20 @@ struct trace_file_writer
 
 extern struct trace_file_writer *tfile_trace_file_writer_new (void);
 
-extern void init_tracefile_ops (struct target_ops *ops);
+/* Base class for tracefile related targets.  */
+
+class tracefile_target : public target_ops
+{
+public:
+  tracefile_target ();
+
+  int get_trace_status (trace_status *ts) override;
+  int has_all_memory () override;
+  int has_memory () override;
+  int has_stack () override;
+  int has_registers () override;
+  int thread_alive (ptid_t ptid) override;
+};
 
 extern void tracefile_fetch_registers (struct regcache *regcache, int regno);
 
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 26/40] target_ops/C++: s390 GNU/Linux
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (27 preceding siblings ...)
  2018-04-14 19:19 ` [PATCH 30/40] target_ops/C++: Xtensa GNU/Linux Pedro Alves
@ 2018-04-14 19:19 ` Pedro Alves
  2018-04-14 19:19 ` [PATCH 35/40] target_ops/C++: NTO/QNX, nto-procfs.c Pedro Alves
                   ` (12 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:19 UTC (permalink / raw)
  To: gdb-patches

Straighforward conversion.
---
 gdb/s390-linux-nat.c | 121 +++++++++++++++++++++++++++------------------------
 1 file changed, 63 insertions(+), 58 deletions(-)

diff --git a/gdb/s390-linux-nat.c b/gdb/s390-linux-nat.c
index cc5e33340e..d3d98014ac 100644
--- a/gdb/s390-linux-nat.c
+++ b/gdb/s390-linux-nat.c
@@ -108,6 +108,36 @@ static const struct regset s390_64_gregset =
 #define PER_CONTROL_SUSPENSION		PER_BIT (41)
 #define PER_CONTROL_ALTERATION		PER_BIT (42)
 
+class s390_linux_nat_target final : public linux_nat_target
+{
+public:
+  /* Add our register access methods.  */
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+
+  /* Add our watchpoint methods.  */
+  int can_use_hw_breakpoint (enum bptype, int, int) override;
+  int insert_hw_breakpoint (struct gdbarch *, struct bp_target_info *)
+    override;
+  int remove_hw_breakpoint (struct gdbarch *, struct bp_target_info *)
+    override;
+  int region_ok_for_hw_watchpoint (CORE_ADDR, int) override;
+  int have_continuable_watchpoint () { return 1; }
+  int stopped_by_watchpoint () override;
+  int watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, int) override;
+  int insert_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
+			 struct expression *) override;
+  int remove_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
+			 struct expression *) override;
+
+  /* Detect target architecture.  */
+  const struct target_desc *read_description () override;
+  int auxv_parse (gdb_byte **readptr,
+		  gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
+    override;
+};
+
+static s390_linux_nat_target the_s390_linux_nat_target;
 
 /* Fill GDB's register array with the general-purpose register values
    in *REGP.
@@ -369,9 +399,8 @@ check_regset (int tid, int regset, int regsize)
 
 /* Fetch register REGNUM from the child process.  If REGNUM is -1, do
    this for all registers.  */
-static void
-s390_linux_fetch_inferior_registers (struct target_ops *ops,
-				     struct regcache *regcache, int regnum)
+void
+s390_linux_nat_target::fetch_registers (struct regcache *regcache, int regnum)
 {
   pid_t tid = get_ptrace_pid (regcache_get_ptid (regcache));
 
@@ -424,9 +453,8 @@ s390_linux_fetch_inferior_registers (struct target_ops *ops,
 
 /* Store register REGNUM back into the child process.  If REGNUM is
    -1, do this for all registers.  */
-static void
-s390_linux_store_inferior_registers (struct target_ops *ops,
-				     struct regcache *regcache, int regnum)
+void
+s390_linux_nat_target::store_registers (struct regcache *regcache, int regnum)
 {
   pid_t tid = get_ptrace_pid (regcache_get_ptid (regcache));
 
@@ -629,8 +657,8 @@ s390_show_debug_regs (int tid, const char *where)
 		per_info.lowcore.words.access_id);
 }
 
-static int
-s390_stopped_by_watchpoint (struct target_ops *ops)
+int
+s390_linux_nat_target::stopped_by_watchpoint ()
 {
   struct s390_debug_reg_state *state
     = s390_get_debug_reg_state (ptid_get_pid (inferior_ptid));
@@ -821,10 +849,10 @@ s390_refresh_per_info (void)
   return 0;
 }
 
-static int
-s390_insert_watchpoint (struct target_ops *self,
-			CORE_ADDR addr, int len, enum target_hw_bp_type type,
-			struct expression *cond)
+int
+s390_linux_nat_target::insert_watchpoint (CORE_ADDR addr, int len,
+					  enum target_hw_bp_type type,
+					  struct expression *cond)
 {
   s390_watch_area area;
   struct s390_debug_reg_state *state
@@ -837,10 +865,10 @@ s390_insert_watchpoint (struct target_ops *self,
   return s390_refresh_per_info ();
 }
 
-static int
-s390_remove_watchpoint (struct target_ops *self,
-			CORE_ADDR addr, int len, enum target_hw_bp_type type,
-			struct expression *cond)
+int
+s390_linux_nat_target::remove_watchpoint (CORE_ADDR addr, int len,
+					  enum target_hw_bp_type type,
+					  struct expression *cond)
 {
   unsigned ix;
   s390_watch_area *area;
@@ -865,9 +893,9 @@ s390_remove_watchpoint (struct target_ops *self,
 
 /* Implement the "can_use_hw_breakpoint" target_ops method. */
 
-static int
-s390_can_use_hw_breakpoint (struct target_ops *self,
-			    enum bptype type, int cnt, int othertype)
+int
+s390_linux_nat_target::can_use_hw_breakpoint (enum bptype type,
+					      int cnt, int othertype)
 {
   if (type == bp_hardware_watchpoint || type == bp_hardware_breakpoint)
     return 1;
@@ -876,10 +904,9 @@ s390_can_use_hw_breakpoint (struct target_ops *self,
 
 /* Implement the "insert_hw_breakpoint" target_ops method.  */
 
-static int
-s390_insert_hw_breakpoint (struct target_ops *self,
-			   struct gdbarch *gdbarch,
-			   struct bp_target_info *bp_tgt)
+int
+s390_linux_nat_target::insert_hw_breakpoint (struct gdbarch *gdbarch,
+					     struct bp_target_info *bp_tgt)
 {
   s390_watch_area area;
   struct s390_debug_reg_state *state;
@@ -894,10 +921,9 @@ s390_insert_hw_breakpoint (struct target_ops *self,
 
 /* Implement the "remove_hw_breakpoint" target_ops method.  */
 
-static int
-s390_remove_hw_breakpoint (struct target_ops *self,
-			   struct gdbarch *gdbarch,
-			   struct bp_target_info *bp_tgt)
+int
+s390_linux_nat_target::remove_hw_breakpoint (struct gdbarch *gdbarch,
+					     struct bp_target_info *bp_tgt)
 {
   unsigned ix;
   struct watch_area *area;
@@ -920,9 +946,8 @@ s390_remove_hw_breakpoint (struct target_ops *self,
   return -1;
 }
 
-static int
-s390_region_ok_for_hw_watchpoint (struct target_ops *self,
-				  CORE_ADDR addr, int cnt)
+int
+s390_linux_nat_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, int cnt)
 {
   return 1;
 }
@@ -946,9 +971,10 @@ s390_target_wordsize (void)
   return wordsize;
 }
 
-static int
-s390_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
-		 gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
+int
+s390_linux_nat_target::auxv_parse (gdb_byte **readptr,
+				   gdb_byte *endptr, CORE_ADDR *typep,
+				   CORE_ADDR *valp)
 {
   int sizeof_auxv_field = s390_target_wordsize ();
   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
@@ -969,8 +995,8 @@ s390_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
   return 1;
 }
 
-static const struct target_desc *
-s390_read_description (struct target_ops *ops)
+const struct target_desc *
+s390_linux_nat_target::read_description ()
 {
   int tid = s390_inferior_tid ();
 
@@ -1033,31 +1059,10 @@ s390_read_description (struct target_ops *ops)
 void
 _initialize_s390_nat (void)
 {
-  struct target_ops *t;
-
-  /* Fill in the generic GNU/Linux methods.  */
-  t = linux_target ();
-
-  /* Add our register access methods.  */
-  t->to_fetch_registers = s390_linux_fetch_inferior_registers;
-  t->to_store_registers = s390_linux_store_inferior_registers;
-
-  /* Add our watchpoint methods.  */
-  t->to_can_use_hw_breakpoint = s390_can_use_hw_breakpoint;
-  t->to_insert_hw_breakpoint = s390_insert_hw_breakpoint;
-  t->to_remove_hw_breakpoint = s390_remove_hw_breakpoint;
-  t->to_region_ok_for_hw_watchpoint = s390_region_ok_for_hw_watchpoint;
-  t->to_have_continuable_watchpoint = 1;
-  t->to_stopped_by_watchpoint = s390_stopped_by_watchpoint;
-  t->to_insert_watchpoint = s390_insert_watchpoint;
-  t->to_remove_watchpoint = s390_remove_watchpoint;
-
-  /* Detect target architecture.  */
-  t->to_read_description = s390_read_description;
-  t->to_auxv_parse = s390_auxv_parse;
+  struct target_ops *t = &the_s390_linux_nat_target;
 
   /* Register the target.  */
-  linux_nat_add_target (t);
+  add_target (t);
   linux_nat_set_new_thread (t, s390_new_thread);
   linux_nat_set_delete_thread (t, s390_delete_thread);
   linux_nat_set_prepare_to_resume (t, s390_prepare_to_resume);
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 31/40] target_ops/C++: Base FreeBSD target
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (24 preceding siblings ...)
  2018-04-14 19:19 ` [PATCH 05/40] target_ops/C++: ctf/tfile targets Pedro Alves
@ 2018-04-14 19:19 ` Pedro Alves
  2018-04-17 16:12   ` John Baldwin
  2018-04-14 19:19 ` [PATCH 15/40] target_ops/C++: Solaris/procfs Pedro Alves
                   ` (15 subsequent siblings)
  41 siblings, 1 reply; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:19 UTC (permalink / raw)
  To: gdb-patches

The

  $architecture x NetBSD/OpenBSD/FreeBSD

support matrix complicates things a bit.  There's common BSD target
code, and there's common architecture-specific code shared between the
different BSDs.  Current, all that is stiched together to form a final
target, via the i386bsd_target, x86bsd_target, fbsd_nat_add_target
functions etc.

Introduces a fbsd_nat_target base/prototype target.  To be used in
following patches.
---
 gdb/fbsd-nat.c | 208 ++++++++++++++++++---------------------------------------
 gdb/fbsd-nat.h |  70 ++++++++++++++++++-
 2 files changed, 132 insertions(+), 146 deletions(-)

diff --git a/gdb/fbsd-nat.c b/gdb/fbsd-nat.c
index bea7f42c7e..5324f8b07e 100644
--- a/gdb/fbsd-nat.c
+++ b/gdb/fbsd-nat.c
@@ -57,8 +57,8 @@
 /* Return the name of a file that can be opened to get the symbols for
    the child process identified by PID.  */
 
-static char *
-fbsd_pid_to_exec_file (struct target_ops *self, int pid)
+char *
+fbsd_nat_target::pid_to_exec_file (int pid)
 {
   ssize_t len;
   static char buf[PATH_MAX];
@@ -96,9 +96,9 @@ fbsd_pid_to_exec_file (struct target_ops *self, int pid)
    calling FUNC for each memory region.  OBFD is passed as the last
    argument to FUNC.  */
 
-static int
-fbsd_find_memory_regions (struct target_ops *self,
-			  find_memory_region_ftype func, void *obfd)
+int
+fbsd_nat_target::find_memory_regions (find_memory_region_ftype func,
+				      void *obfd)
 {
   pid_t pid = ptid_get_pid (inferior_ptid);
   struct kinfo_vmentry *kve;
@@ -170,9 +170,9 @@ fbsd_read_mapping (FILE *mapfile, unsigned long *start, unsigned long *end,
    calling FUNC for each memory region.  OBFD is passed as the last
    argument to FUNC.  */
 
-static int
-fbsd_find_memory_regions (struct target_ops *self,
-			  find_memory_region_ftype func, void *obfd)
+int
+fbsd_nat_target::find_memory_regions (find_memory_region_ftype func,
+				      void *obfd)
 {
   pid_t pid = ptid_get_pid (inferior_ptid);
   unsigned long start, end, size;
@@ -259,11 +259,10 @@ fbsd_fetch_kinfo_proc (pid_t pid, struct kinfo_proc *kp)
   return (sysctl (mib, 4, kp, &len, NULL, 0) == 0);
 }
 
-/* Implement the "to_info_proc target_ops" method.  */
+/* Implement the "info_proc" target_ops method.  */
 
-static void
-fbsd_info_proc (struct target_ops *ops, const char *args,
-		enum info_proc_what what)
+void
+fbsd_nat_target::info_proc (const char *args, enum info_proc_what what)
 {
 #ifdef HAVE_KINFO_GETFILE
   gdb::unique_xmalloc_ptr<struct kinfo_file> fdtbl;
@@ -542,14 +541,6 @@ fbsd_info_proc (struct target_ops *ops, const char *args,
 }
 
 #ifdef KERN_PROC_AUXV
-static enum target_xfer_status (*super_xfer_partial) (struct target_ops *ops,
-						      enum target_object object,
-						      const char *annex,
-						      gdb_byte *readbuf,
-						      const gdb_byte *writebuf,
-						      ULONGEST offset,
-						      ULONGEST len,
-						      ULONGEST *xfered_len);
 
 #ifdef PT_LWPINFO
 /* Return the size of siginfo for the current inferior.  */
@@ -680,13 +671,14 @@ fbsd_convert_siginfo (siginfo_t *si)
 }
 #endif
 
-/* Implement the "to_xfer_partial target_ops" method.  */
+/* Implement the "xfer_partial" target_ops method.  */
 
-static enum target_xfer_status
-fbsd_xfer_partial (struct target_ops *ops, enum target_object object,
-		   const char *annex, gdb_byte *readbuf,
-		   const gdb_byte *writebuf,
-		   ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
+enum target_xfer_status
+fbsd_nat_target::xfer_partial (enum target_object object,
+			       const char *annex, gdb_byte *readbuf,
+			       const gdb_byte *writebuf,
+			       ULONGEST offset, ULONGEST len,
+			       ULONGEST *xfered_len)
 {
   pid_t pid = ptid_get_pid (inferior_ptid);
 
@@ -766,8 +758,9 @@ fbsd_xfer_partial (struct target_ops *ops, enum target_object object,
 	return TARGET_XFER_E_IO;
       }
     default:
-      return super_xfer_partial (ops, object, annex, readbuf, writebuf, offset,
-				 len, xfered_len);
+      return inf_ptrace_target::xfer_partial (object, annex,
+					      readbuf, writebuf, offset,
+					      len, xfered_len);
     }
 }
 #endif
@@ -776,15 +769,6 @@ fbsd_xfer_partial (struct target_ops *ops, enum target_object object,
 static int debug_fbsd_lwp;
 static int debug_fbsd_nat;
 
-static void (*super_resume) (struct target_ops *,
-			     ptid_t,
-			     int,
-			     enum gdb_signal);
-static ptid_t (*super_wait) (struct target_ops *,
-			     ptid_t,
-			     struct target_waitstatus *,
-			     int);
-
 static void
 show_fbsd_lwp_debug (struct ui_file *file, int from_tty,
 		     struct cmd_list_element *c, const char *value)
@@ -829,8 +813,8 @@ show_fbsd_nat_debug (struct ui_file *file, int from_tty,
 
 /* Return true if PTID is still active in the inferior.  */
 
-static int
-fbsd_thread_alive (struct target_ops *ops, ptid_t ptid)
+int
+fbsd_nat_target::thread_alive (ptid_t ptid)
 {
   if (ptid_lwp_p (ptid))
     {
@@ -851,8 +835,8 @@ fbsd_thread_alive (struct target_ops *ops, ptid_t ptid)
 /* Convert PTID to a string.  Returns the string in a static
    buffer.  */
 
-static const char *
-fbsd_pid_to_str (struct target_ops *ops, ptid_t ptid)
+const char *
+fbsd_nat_target::pid_to_str (ptid_t ptid)
 {
   lwpid_t lwp;
 
@@ -873,8 +857,8 @@ fbsd_pid_to_str (struct target_ops *ops, ptid_t ptid)
 /* Return the name assigned to a thread by an application.  Returns
    the string in a static buffer.  */
 
-static const char *
-fbsd_thread_name (struct target_ops *self, struct thread_info *thr)
+const char *
+fbsd_nat_target::thread_name (struct thread_info *thr)
 {
   struct ptrace_lwpinfo pl;
   struct kinfo_proc kp;
@@ -984,10 +968,10 @@ fbsd_add_threads (pid_t pid)
     }
 }
 
-/* Implement the "to_update_thread_list" target_ops method.  */
+/* Implement the "update_thread_list" target_ops method.  */
 
-static void
-fbsd_update_thread_list (struct target_ops *ops)
+void
+fbsd_nat_target::update_thread_list ()
 {
 #ifdef PT_LWP_EVENTS
   /* With support for thread events, threads are added/deleted from the
@@ -1102,11 +1086,10 @@ fbsd_next_vfork_done (void)
 #endif
 #endif
 
-/* Implement the "to_resume" target_ops method.  */
+/* Implement the "resume" target_ops method.  */
 
-static void
-fbsd_resume (struct target_ops *ops,
-	     ptid_t ptid, int step, enum gdb_signal signo)
+void
+fbsd_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
 {
 #if defined(TDP_RFPPWAIT) && !defined(PTRACE_VFORK)
   pid_t pid;
@@ -1193,7 +1176,7 @@ fbsd_resume (struct target_ops *ops,
     }
   ptid = ptid_t (ptid.pid ());
 #endif
-  super_resume (ops, ptid, step, signo);
+  inf_ptrace_target::resume (ptid, step, signo);
 }
 
 #ifdef USE_SIGTRAP_SIGINFO
@@ -1202,8 +1185,7 @@ fbsd_resume (struct target_ops *ops,
    core, return true.  */
 
 static bool
-fbsd_handle_debug_trap (struct target_ops *ops, ptid_t ptid,
-			const struct ptrace_lwpinfo &pl)
+fbsd_handle_debug_trap (ptid_t ptid, const struct ptrace_lwpinfo &pl)
 {
 
   /* Ignore traps without valid siginfo or for signals other than
@@ -1250,10 +1232,9 @@ fbsd_handle_debug_trap (struct target_ops *ops, ptid_t ptid,
    process ID of the child, or MINUS_ONE_PTID in case of error; store
    the status in *OURSTATUS.  */
 
-static ptid_t
-fbsd_wait (struct target_ops *ops,
-	   ptid_t ptid, struct target_waitstatus *ourstatus,
-	   int target_options)
+ptid_t
+fbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
+		       int target_options)
 {
   ptid_t wptid;
 
@@ -1267,7 +1248,7 @@ fbsd_wait (struct target_ops *ops,
 	  return wptid;
 	}
 #endif
-      wptid = super_wait (ops, ptid, ourstatus, target_options);
+      wptid = inf_ptrace_target::wait (ptid, ourstatus, target_options);
       if (ourstatus->kind == TARGET_WAITKIND_STOPPED)
 	{
 	  struct ptrace_lwpinfo pl;
@@ -1432,7 +1413,7 @@ fbsd_wait (struct target_ops *ops,
 #endif
 
 #ifdef USE_SIGTRAP_SIGINFO
-	  if (fbsd_handle_debug_trap (ops, wptid, pl))
+	  if (fbsd_handle_debug_trap (wptid, pl))
 	    return wptid;
 #endif
 
@@ -1475,10 +1456,10 @@ fbsd_wait (struct target_ops *ops,
 }
 
 #ifdef USE_SIGTRAP_SIGINFO
-/* Implement the "to_stopped_by_sw_breakpoint" target_ops method.  */
+/* Implement the "stopped_by_sw_breakpoint" target_ops method.  */
 
-static int
-fbsd_stopped_by_sw_breakpoint (struct target_ops *ops)
+int
+fbsd_nat_target::stopped_by_sw_breakpoint ()
 {
   struct ptrace_lwpinfo pl;
 
@@ -1491,32 +1472,22 @@ fbsd_stopped_by_sw_breakpoint (struct target_ops *ops)
 	  && pl.pl_siginfo.si_code == TRAP_BRKPT);
 }
 
-/* Implement the "to_supports_stopped_by_sw_breakpoint" target_ops
+/* Implement the "supports_stopped_by_sw_breakpoint" target_ops
    method.  */
 
-static int
-fbsd_supports_stopped_by_sw_breakpoint (struct target_ops *ops)
+int
+fbsd_nat_target::supports_stopped_by_sw_breakpoint ()
 {
   return 1;
 }
-
-/* Implement the "to_supports_stopped_by_hw_breakpoint" target_ops
-   method.  */
-
-static int
-fbsd_supports_stopped_by_hw_breakpoint (struct target_ops *ops)
-{
-  return ops->to_stopped_by_hw_breakpoint != NULL;
-}
 #endif
 
 #ifdef TDP_RFPPWAIT
 /* Target hook for follow_fork.  On entry and at return inferior_ptid is
    the ptid of the followed inferior.  */
 
-static int
-fbsd_follow_fork (struct target_ops *ops, int follow_child,
-			int detach_fork)
+int
+fbsd_nat_target::follow_fork (int follow_child, int detach_fork)
 {
   if (!follow_child && detach_fork)
     {
@@ -1562,35 +1533,35 @@ fbsd_follow_fork (struct target_ops *ops, int follow_child,
   return 0;
 }
 
-static int
-fbsd_insert_fork_catchpoint (struct target_ops *self, int pid)
+int
+fbsd_nat_target::insert_fork_catchpoint (int pid)
 {
   return 0;
 }
 
-static int
-fbsd_remove_fork_catchpoint (struct target_ops *self, int pid)
+int
+fbsd_nat_target::remove_fork_catchpoint (int pid)
 {
   return 0;
 }
 
-static int
-fbsd_insert_vfork_catchpoint (struct target_ops *self, int pid)
+int
+fbsd_nat_target::insert_vfork_catchpoint (int pid)
 {
   return 0;
 }
 
-static int
-fbsd_remove_vfork_catchpoint (struct target_ops *self, int pid)
+int
+fbsd_nat_target::remove_vfork_catchpoint (int pid)
 {
   return 0;
 }
 #endif
 
-/* Implement the "to_post_startup_inferior" target_ops method.  */
+/* Implement the "post_startup_inferior" target_ops method.  */
 
 static void
-fbsd_post_startup_inferior (struct target_ops *self, ptid_t pid)
+fbsd_nat_target::post_startup_inferior (ptid_t pid)
 {
   fbsd_enable_proc_events (ptid_get_pid (pid));
 }
@@ -1608,24 +1579,24 @@ fbsd_post_attach (struct target_ops *self, int pid)
 /* If the FreeBSD kernel supports PL_FLAG_EXEC, then traced processes
    will always stop after exec.  */
 
-static int
-fbsd_insert_exec_catchpoint (struct target_ops *self, int pid)
+int
+fbsd_nat_target::insert_exec_catchpoint (int pid)
 {
   return 0;
 }
 
 static int
-fbsd_remove_exec_catchpoint (struct target_ops *self, int pid)
+fbsd_nat_target::remove_exec_catchpoint (int pid)
 {
   return 0;
 }
 #endif
 
 #ifdef HAVE_STRUCT_PTRACE_LWPINFO_PL_SYSCALL_CODE
-static int
-fbsd_set_syscall_catchpoint (struct target_ops *self, int pid, bool needed,
-			     int any_count,
-			     gdb::array_view<const int> syscall_counts)
+int
+fbsd_nat_target::set_syscall_catchpoint (int pid, bool needed,
+					 int any_count,
+					 gdb::array_view<const int> syscall_counts)
 {
 
   /* Ignore the arguments.  inf-ptrace.c will use PT_SYSCALL which
@@ -1636,55 +1607,6 @@ fbsd_set_syscall_catchpoint (struct target_ops *self, int pid, bool needed,
 #endif
 #endif
 
-void
-fbsd_nat_add_target (struct target_ops *t)
-{
-  t->to_pid_to_exec_file = fbsd_pid_to_exec_file;
-  t->to_find_memory_regions = fbsd_find_memory_regions;
-  t->to_info_proc = fbsd_info_proc;
-#ifdef KERN_PROC_AUXV
-  super_xfer_partial = t->to_xfer_partial;
-  t->to_xfer_partial = fbsd_xfer_partial;
-#endif
-#ifdef PT_LWPINFO
-  t->to_thread_alive = fbsd_thread_alive;
-  t->to_pid_to_str = fbsd_pid_to_str;
-#ifdef HAVE_STRUCT_PTRACE_LWPINFO_PL_TDNAME
-  t->to_thread_name = fbsd_thread_name;
-#endif
-  t->to_update_thread_list = fbsd_update_thread_list;
-  t->to_has_thread_control = tc_schedlock;
-  super_resume = t->to_resume;
-  t->to_resume = fbsd_resume;
-  super_wait = t->to_wait;
-  t->to_wait = fbsd_wait;
-  t->to_post_startup_inferior = fbsd_post_startup_inferior;
-  t->to_post_attach = fbsd_post_attach;
-#ifdef USE_SIGTRAP_SIGINFO
-  t->to_stopped_by_sw_breakpoint = fbsd_stopped_by_sw_breakpoint;
-  t->to_supports_stopped_by_sw_breakpoint
-    = fbsd_supports_stopped_by_sw_breakpoint;
-  t->to_supports_stopped_by_hw_breakpoint
-    = fbsd_supports_stopped_by_hw_breakpoint;
-#endif
-#ifdef TDP_RFPPWAIT
-  t->to_follow_fork = fbsd_follow_fork;
-  t->to_insert_fork_catchpoint = fbsd_insert_fork_catchpoint;
-  t->to_remove_fork_catchpoint = fbsd_remove_fork_catchpoint;
-  t->to_insert_vfork_catchpoint = fbsd_insert_vfork_catchpoint;
-  t->to_remove_vfork_catchpoint = fbsd_remove_vfork_catchpoint;
-#endif
-#ifdef PL_FLAG_EXEC
-  t->to_insert_exec_catchpoint = fbsd_insert_exec_catchpoint;
-  t->to_remove_exec_catchpoint = fbsd_remove_exec_catchpoint;
-#endif
-#ifdef HAVE_STRUCT_PTRACE_LWPINFO_PL_SYSCALL_CODE
-  t->to_set_syscall_catchpoint = fbsd_set_syscall_catchpoint;
-#endif
-#endif
-  add_target (t);
-}
-
 void
 _initialize_fbsd_nat (void)
 {
diff --git a/gdb/fbsd-nat.h b/gdb/fbsd-nat.h
index 8326b96db7..a4418bb8f8 100644
--- a/gdb/fbsd-nat.h
+++ b/gdb/fbsd-nat.h
@@ -20,8 +20,72 @@
 #ifndef FBSD_NAT_H
 #define FBSD_NAT_H
 
-/* Register the customized FreeBSD target.  This should be used
-   instead of calling add_target directly.  */
-extern void fbsd_nat_add_target (struct target_ops *);
+/* A prototype FreeBSD target.  */
+
+class fbsd_nat_target : public inf_ptrace_target
+{
+public:
+  char *pid_to_exec_file (int pid) override;
+
+  int find_memory_regions (find_memory_region_ftype func, void *data);
+
+  bool info_proc (const char *, enum info_proc_what);
+
+#ifdef KERN_PROC_AUXV
+  enum target_xfer_status xfer_partial (enum target_object object,
+					const char *annex,
+					gdb_byte *readbuf,
+					const gdb_byte *writebuf,
+					ULONGEST offset, ULONGEST len,
+					ULONGEST *xfered_len) override;
+#endif
+
+#ifdef PT_LWPINFO
+  int thread_alive (ptid_t ptid) override;
+  const char *pid_to_str (ptid_t) override;
+
+#ifdef HAVE_STRUCT_PTRACE_LWPINFO_PL_TDNAME
+  const char *thread_name (struct thread_info *) override;
+#endif
+
+  void update_thread_list () override;
+
+  thread_control_capabilities get_thread_control_capabilities () override
+  { return tc_schedlock; }
+
+  void resume (ptid_t, int, enum gdb_signal) override;
+
+  ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
+
+  void post_startup_inferior (ptid_t) override;
+  void post_attach (int) override;
+
+#ifdef USE_SIGTRAP_SIGINFO
+  int supports_stopped_by_sw_breakpoint () override;
+  int stopped_by_sw_breakpoint () override;
+#endif
+
+#ifdef TDP_RFPPWAIT
+  int follow_fork (int, int) override;
+
+  int insert_fork_catchpoint (int) override;
+  int remove_fork_catchpoint (int) override;
+
+  int insert_vfork_catchpoint (int) override;
+  int remove_vfork_catchpoint (int) override;
+#endif
+
+#ifdef PL_FLAG_EXEC
+  int insert_exec_catchpoint (int) override;
+  int remove_exec_catchpoint (int) override;
+#endif
+
+#ifdef HAVE_STRUCT_PTRACE_LWPINFO_PL_SYSCALL_CODE
+  int set_syscall_catchpoint (int, bool, int, gdb::array_view<const int>)
+    override;
+#endif /* HAVE_STRUCT_PTRACE_LWPINFO_PL_SYSCALL_CODE */
+
+#endif /* PT_LWPINFO */
+};
 
 #endif /* fbsd-nat.h */
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 16/40] target_ops/C++: Windows targets
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (29 preceding siblings ...)
  2018-04-14 19:19 ` [PATCH 35/40] target_ops/C++: NTO/QNX, nto-procfs.c Pedro Alves
@ 2018-04-14 19:19 ` Pedro Alves
  2018-04-14 19:20 ` [PATCH 10/40] target_ops/C++: record targets Pedro Alves
                   ` (10 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:19 UTC (permalink / raw)
  To: gdb-patches

Straighforward conversion.  I'd tested this with a cross compiler.
---
 gdb/windows-nat.c | 216 ++++++++++++++++++++++++++++--------------------------
 1 file changed, 114 insertions(+), 102 deletions(-)

diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c
index 95e3c5816b..589ef47c67 100644
--- a/gdb/windows-nat.c
+++ b/gdb/windows-nat.c
@@ -201,10 +201,6 @@ typedef enum
 #define DEBUG_MEM(x)	if (debug_memory)	printf_unfiltered x
 #define DEBUG_EXCEPT(x)	if (debug_exceptions)	printf_unfiltered x
 
-static void windows_interrupt (struct target_ops *self);
-static int windows_thread_alive (struct target_ops *, ptid_t);
-static void windows_kill_inferior (struct target_ops *);
-
 static void cygwin_set_dr (int i, CORE_ADDR addr);
 static void cygwin_set_dr7 (unsigned long val);
 static CORE_ADDR cygwin_get_dr (int i);
@@ -302,6 +298,58 @@ static const struct xlate_exception
   {STATUS_FLOAT_DIVIDE_BY_ZERO, GDB_SIGNAL_FPE},
   {-1, GDB_SIGNAL_UNKNOWN}};
 
+
+struct windows_nat_target final : public x86_nat_target<inf_child_target>
+{
+  void close () override;
+
+  void attach (const char *, int) override;
+
+  bool attach_no_wait () override
+  { return true; }
+
+  void detach (inferior *, int) override;
+
+  void resume (ptid_t, int , enum gdb_signal) override;
+
+  ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
+
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+
+  enum target_xfer_status xfer_partial (enum target_object object,
+					const char *annex,
+					gdb_byte *readbuf,
+					const gdb_byte *writebuf,
+					ULONGEST offset, ULONGEST len,
+					ULONGEST *xfered_len) override;
+
+  void files_info () override;
+
+  void kill () override;
+
+  void create_inferior (const char *, const std::string &,
+			char **, int) override;
+
+  void mourn_inferior () override;
+
+  int thread_alive (ptid_t ptid) override;
+
+  const char *pid_to_str (ptid_t) override;
+
+  void interrupt () override;
+
+  char *pid_to_exec_file (int pid) override;
+
+  ptid_t get_ada_task_ptid (long lwp, long thread) override;
+
+  int get_tib_address (ptid_t ptid, CORE_ADDR *addr) override;
+
+  const char *thread_name (struct thread_info *) override;
+};
+
+static windows_nat_target the_windows_nat_target;
+
 /* Set the MAPPINGS static global to OFFSETS.
    See the description of MAPPINGS for more details.  */
 
@@ -531,9 +579,8 @@ do_windows_fetch_inferior_registers (struct regcache *regcache,
     }
 }
 
-static void
-windows_fetch_inferior_registers (struct target_ops *ops,
-				  struct regcache *regcache, int r)
+void
+windows_nat_target::fetch_registers (struct regcache *regcache, int r)
 {
   DWORD pid = ptid_get_tid (regcache_get_ptid (regcache));
   windows_thread_info *th = thread_rec (pid, TRUE);
@@ -560,9 +607,9 @@ do_windows_store_inferior_registers (const struct regcache *regcache,
 
 /* Store a new register value into the context of the thread tied to
    REGCACHE.  */
-static void
-windows_store_inferior_registers (struct target_ops *ops,
-				  struct regcache *regcache, int r)
+
+void
+windows_nat_target::store_registers (struct regcache *regcache, int r)
 {
   DWORD pid = ptid_get_tid (regcache_get_ptid (regcache));
   windows_thread_info *th = thread_rec (pid, TRUE);
@@ -1310,9 +1357,8 @@ fake_create_process (void)
   return main_thread_id;
 }
 
-static void
-windows_resume (struct target_ops *ops,
-		ptid_t ptid, int step, enum gdb_signal sig)
+void
+windows_nat_target::resume (ptid_t ptid, int step, enum gdb_signal sig)
 {
   windows_thread_info *th;
   DWORD continue_status = DBG_CONTINUE;
@@ -1373,8 +1419,7 @@ windows_resume (struct target_ops *ops,
 	  /* Single step by setting t bit.  */
 	  struct regcache *regcache = get_current_regcache ();
 	  struct gdbarch *gdbarch = regcache->arch ();
-	  windows_fetch_inferior_registers (ops, regcache,
-					    gdbarch_ps_regnum (gdbarch));
+	  fetch_registers (regcache, gdbarch_ps_regnum (gdbarch));
 	  th->context.EFlags |= FLAG_TRACE_BIT;
 	}
 
@@ -1631,9 +1676,9 @@ out:
 }
 
 /* Wait for interesting events to occur in the target process.  */
-static ptid_t
-windows_wait (struct target_ops *ops,
-	      ptid_t ptid, struct target_waitstatus *ourstatus, int options)
+ptid_t
+windows_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
+			  int options)
 {
   int pid = -1;
 
@@ -1676,7 +1721,7 @@ windows_wait (struct target_ops *ops,
 	     the user tries to resume the execution in the inferior.
 	     This is a classic race that we should try to fix one day.  */
       SetConsoleCtrlHandler (&ctrl_c_handler, TRUE);
-      retval = get_windows_debug_event (ops, pid, ourstatus);
+      retval = get_windows_debug_event (this, pid, ourstatus);
       SetConsoleCtrlHandler (&ctrl_c_handler, FALSE);
 
       if (retval)
@@ -1689,7 +1734,7 @@ windows_wait (struct target_ops *ops,
 	    detach = deprecated_ui_loop_hook (0);
 
 	  if (detach)
-	    windows_kill_inferior (ops);
+	    kill ();
 	}
     }
 }
@@ -1791,7 +1836,7 @@ do_initial_windows_stuff (struct target_ops *ops, DWORD pid, int attaching)
     {
       struct target_waitstatus status;
 
-      windows_wait (ops, minus_one_ptid, &status, 0);
+      ops->wait (minus_one_ptid, &status, 0);
 
       /* Note windows_wait returns TARGET_WAITKIND_SPURIOUS for thread
 	 events.  */
@@ -1799,7 +1844,7 @@ do_initial_windows_stuff (struct target_ops *ops, DWORD pid, int attaching)
 	  && status.kind != TARGET_WAITKIND_SPURIOUS)
 	break;
 
-      windows_resume (ops, minus_one_ptid, 0, GDB_SIGNAL_0);
+      ops->resume (minus_one_ptid, 0, GDB_SIGNAL_0);
     }
 
   /* Now that the inferior has been started and all DLLs have been mapped,
@@ -1873,8 +1918,9 @@ out:
 }
 
 /* Attach to process PID, then initialize for debugging it.  */
-static void
-windows_attach (struct target_ops *ops, const char *args, int from_tty)
+
+void
+windows_nat_target::attach (const char *args, int from_tty)
 {
   BOOL ok;
   DWORD pid;
@@ -1922,17 +1968,17 @@ windows_attach (struct target_ops *ops, const char *args, int from_tty)
       gdb_flush (gdb_stdout);
     }
 
-  do_initial_windows_stuff (ops, pid, 1);
+  do_initial_windows_stuff (this, pid, 1);
   target_terminal::ours ();
 }
 
-static void
-windows_detach (struct target_ops *ops, inferior *inf, int from_tty)
+void
+windows_nat_target::detach (inferior *inf, int from_tty)
 {
   int detached = 1;
 
   ptid_t ptid = minus_one_ptid;
-  windows_resume (ops, ptid, 0, GDB_SIGNAL_0);
+  resume (ptid, 0, GDB_SIGNAL_0);
 
   if (!DebugActiveProcessStop (current_event.dwProcessId))
     {
@@ -1956,7 +2002,7 @@ windows_detach (struct target_ops *ops, inferior *inf, int from_tty)
   inferior_ptid = null_ptid;
   detach_inferior (current_event.dwProcessId);
 
-  inf_child_maybe_unpush_target (ops);
+  maybe_unpush_target ();
 }
 
 /* Try to determine the executable filename.
@@ -2013,8 +2059,8 @@ windows_get_exec_module_filename (char *exe_name_ret, size_t exe_name_max_len)
 
 /* The pid_to_exec_file target_ops method for this platform.  */
 
-static char *
-windows_pid_to_exec_file (struct target_ops *self, int pid)
+char *
+windows_nat_target::pid_to_exec_file (int pid)
 {
   static char path[__PMAX];
 #ifdef __CYGWIN__
@@ -2041,8 +2087,8 @@ windows_pid_to_exec_file (struct target_ops *self, int pid)
 
 /* Print status information about what we're accessing.  */
 
-static void
-windows_files_info (struct target_ops *ignore)
+void
+windows_nat_target::files_info ()
 {
   struct inferior *inf = current_inferior ();
 
@@ -2430,10 +2476,10 @@ redirect_inferior_handles (const char *cmd_orig, char *cmd,
    ALLARGS is a string containing the arguments to the program.
    ENV is the environment vector to pass.  Errors reported with error().  */
 
-static void
-windows_create_inferior (struct target_ops *ops, const char *exec_file,
-			 const std::string &origallargs, char **in_env,
-			 int from_tty)
+void
+windows_nat_target::create_inferior (const char *exec_file,
+				     const std::string &origallargs,
+				     char **in_env, int from_tty)
 {
   STARTUPINFO si;
 #ifdef __CYGWIN__
@@ -2751,13 +2797,13 @@ windows_create_inferior (struct target_ops *ops, const char *exec_file,
   else
     saw_create = 0;
 
-  do_initial_windows_stuff (ops, pi.dwProcessId, 0);
+  do_initial_windows_stuff (this, pi.dwProcessId, 0);
 
   /* windows_continue (DBG_CONTINUE, -1, 0); */
 }
 
-static void
-windows_mourn_inferior (struct target_ops *ops)
+void
+windows_nat_target::mourn_inferior ()
 {
   (void) windows_continue (DBG_CONTINUE, -1, 0);
   x86_cleanup_dregs();
@@ -2766,14 +2812,14 @@ windows_mourn_inferior (struct target_ops *ops)
       CHECK (CloseHandle (current_process_handle));
       open_process_used = 0;
     }
-  inf_child_mourn_inferior (ops);
+  inf_child_target::mourn_inferior ();
 }
 
 /* Send a SIGINT to the process group.  This acts just like the user typed a
    ^C on the controlling terminal.  */
 
-static void
-windows_interrupt (struct target_ops *self)
+void
+windows_nat_target::interrupt ()
 {
   DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
   CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId));
@@ -2820,8 +2866,8 @@ windows_xfer_memory (gdb_byte *readbuf, const gdb_byte *writebuf,
     return success ? TARGET_XFER_OK : TARGET_XFER_E_IO;
 }
 
-static void
-windows_kill_inferior (struct target_ops *ops)
+void
+windows_nat_target::kill ()
 {
   CHECK (TerminateProcess (current_process_handle, 0));
 
@@ -2838,16 +2884,16 @@ windows_kill_inferior (struct target_ops *ops)
   target_mourn_inferior (inferior_ptid);	/* Or just windows_mourn_inferior?  */
 }
 
-static void
-windows_close (struct target_ops *self)
+void
+windows_nat_target::close ()
 {
   DEBUG_EVENTS (("gdb: windows_close, inferior_ptid=%d\n",
 		ptid_get_pid (inferior_ptid)));
 }
 
 /* Convert pid to printable format.  */
-static const char *
-windows_pid_to_str (struct target_ops *ops, ptid_t ptid)
+const char *
+windows_nat_target::pid_to_str (ptid_t ptid)
 {
   static char buf[80];
 
@@ -2904,11 +2950,11 @@ windows_xfer_shared_libraries (struct target_ops *ops,
   return len != 0 ? TARGET_XFER_OK : TARGET_XFER_EOF;
 }
 
-static enum target_xfer_status
-windows_xfer_partial (struct target_ops *ops, enum target_object object,
-		      const char *annex, gdb_byte *readbuf,
-		      const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
-		      ULONGEST *xfered_len)
+enum target_xfer_status
+windows_nat_target::xfer_partial (enum target_object object,
+				  const char *annex, gdb_byte *readbuf,
+				  const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
+				  ULONGEST *xfered_len)
 {
   switch (object)
     {
@@ -2916,22 +2962,21 @@ windows_xfer_partial (struct target_ops *ops, enum target_object object,
       return windows_xfer_memory (readbuf, writebuf, offset, len, xfered_len);
 
     case TARGET_OBJECT_LIBRARIES:
-      return windows_xfer_shared_libraries (ops, object, annex, readbuf,
+      return windows_xfer_shared_libraries (this, object, annex, readbuf,
 					    writebuf, offset, len, xfered_len);
 
     default:
-      return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
-					    readbuf, writebuf, offset, len,
-					    xfered_len);
+      return beneath->xfer_partial (object, annex,
+				    readbuf, writebuf, offset, len,
+				    xfered_len);
     }
 }
 
 /* Provide thread local base, i.e. Thread Information Block address.
    Returns 1 if ptid is found and sets *ADDR to thread_local_base.  */
 
-static int
-windows_get_tib_address (struct target_ops *self,
-			 ptid_t ptid, CORE_ADDR *addr)
+int
+windows_nat_target::get_tib_address (ptid_t ptid, CORE_ADDR *addr)
 {
   windows_thread_info *th;
 
@@ -2945,58 +2990,24 @@ windows_get_tib_address (struct target_ops *self,
   return 1;
 }
 
-static ptid_t
-windows_get_ada_task_ptid (struct target_ops *self, long lwp, long thread)
+ptid_t
+windows_nat_target::get_ada_task_ptid (long lwp, long thread)
 {
   return ptid_build (ptid_get_pid (inferior_ptid), 0, lwp);
 }
 
 /* Implementation of the to_thread_name method.  */
 
-static const char *
-windows_thread_name (struct target_ops *self, struct thread_info *thr)
+const char *
+windows_nat_target::thread_name (struct thread_info *thr)
 {
   return thread_rec (ptid_get_tid (thr->ptid), 0)->name;
 }
 
-static struct target_ops *
-windows_target (void)
-{
-  struct target_ops *t = inf_child_target ();
-
-  t->to_close = windows_close;
-  t->to_attach = windows_attach;
-  t->to_attach_no_wait = 1;
-  t->to_detach = windows_detach;
-  t->to_resume = windows_resume;
-  t->to_wait = windows_wait;
-  t->to_fetch_registers = windows_fetch_inferior_registers;
-  t->to_store_registers = windows_store_inferior_registers;
-  t->to_xfer_partial = windows_xfer_partial;
-  t->to_files_info = windows_files_info;
-  t->to_kill = windows_kill_inferior;
-  t->to_create_inferior = windows_create_inferior;
-  t->to_mourn_inferior = windows_mourn_inferior;
-  t->to_thread_alive = windows_thread_alive;
-  t->to_pid_to_str = windows_pid_to_str;
-  t->to_interrupt = windows_interrupt;
-  t->to_pid_to_exec_file = windows_pid_to_exec_file;
-  t->to_get_ada_task_ptid = windows_get_ada_task_ptid;
-  t->to_get_tib_address = windows_get_tib_address;
-  t->to_thread_name = windows_thread_name;
-
-  return t;
-}
 
 void
 _initialize_windows_nat (void)
 {
-  struct target_ops *t;
-
-  t = windows_target ();
-
-  x86_use_watchpoints (t);
-
   x86_dr_low.set_control = cygwin_set_dr7;
   x86_dr_low.set_addr = cygwin_set_dr;
   x86_dr_low.get_addr = cygwin_get_dr;
@@ -3007,7 +3018,7 @@ _initialize_windows_nat (void)
      calling x86_set_debug_register_length function
      in processor windows specific native file.  */
 
-  add_target (t);
+  add_target (&the_windows_nat_target);
 
 #ifdef __CYGWIN__
   cygwin_internal (CW_SET_DOS_FILE_WARNING, 0);
@@ -3144,8 +3155,9 @@ cygwin_get_dr7 (void)
 /* Determine if the thread referenced by "ptid" is alive
    by "polling" it.  If WaitForSingleObject returns WAIT_OBJECT_0
    it means that the thread has died.  Otherwise it is assumed to be alive.  */
-static int
-windows_thread_alive (struct target_ops *ops, ptid_t ptid)
+
+int
+windows_nat_target::thread_alive (ptid_t ptid)
 {
   int tid;
 
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 30/40] target_ops/C++: Xtensa GNU/Linux
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (26 preceding siblings ...)
  2018-04-14 19:19 ` [PATCH 15/40] target_ops/C++: Solaris/procfs Pedro Alves
@ 2018-04-14 19:19 ` Pedro Alves
  2018-04-14 19:19 ` [PATCH 26/40] target_ops/C++: s390 GNU/Linux Pedro Alves
                   ` (13 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:19 UTC (permalink / raw)
  To: gdb-patches

Straighforward conversion.  Not tested.
---
 gdb/xtensa-linux-nat.c | 32 +++++++++++++++++---------------
 1 file changed, 17 insertions(+), 15 deletions(-)

diff --git a/gdb/xtensa-linux-nat.c b/gdb/xtensa-linux-nat.c
index eac68bbb26..2acffbfbdf 100644
--- a/gdb/xtensa-linux-nat.c
+++ b/gdb/xtensa-linux-nat.c
@@ -45,6 +45,16 @@
    hardware-specific overlays.  */
 #include "xtensa-xtregs.c"
 
+class xtensa_linux_nat_target final : public linux_nat_target
+{
+public:
+  /* Add our register access methods.  */
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+};
+
+static xtensa_linux_nat_target the_xtensa_linux_nat_target;
+
 void
 fill_gregset (const struct regcache *regcache,
 	      gdb_gregset_t *gregsetp, int regnum)
@@ -289,9 +299,9 @@ store_xtregs (struct regcache *regcache, int regnum)
     perror_with_name (_("Couldn't write extended registers"));
 }
 
-static void
-xtensa_linux_fetch_inferior_registers (struct target_ops *ops,
-				       struct regcache *regcache, int regnum)
+void
+xtensa_linux_nat_target::fetch_registers (struct regcache *regcache,
+					  int regnum)
 {
   if (regnum == -1)
     {
@@ -304,9 +314,9 @@ xtensa_linux_fetch_inferior_registers (struct target_ops *ops,
     fetch_xtregs (regcache, regnum);
 }
 
-static void
-xtensa_linux_store_inferior_registers (struct target_ops *ops,
-				       struct regcache *regcache, int regnum)
+void
+xtensa_linux_nat_target::store_registers (struct regcache *regcache,
+					  int regnum)
 {
   if (regnum == -1)
     {
@@ -341,7 +351,6 @@ ps_get_thread_area (struct ps_prochandle *ph,
 void
 _initialize_xtensa_linux_nat (void)
 {
-  struct target_ops *t;
   const xtensa_regtable_t *ptr;
 
   /* Calculate the number range for extended registers.  */
@@ -355,12 +364,5 @@ _initialize_xtensa_linux_nat (void)
 	xtreg_high = ptr->gdb_regnum;
     }
 
-  /* Fill in the generic GNU/Linux methods.  */
-  t = linux_target ();
-
-  /* Add our register access methods.  */
-  t->to_fetch_registers = xtensa_linux_fetch_inferior_registers;
-  t->to_store_registers = xtensa_linux_store_inferior_registers;
-
-  linux_nat_add_target (t);
+  add_target (&the_xtensa_linux_nat_target);
 }
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 11/40] target_ops/C++: remote/extended-remote targets
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (31 preceding siblings ...)
  2018-04-14 19:20 ` [PATCH 10/40] target_ops/C++: record targets Pedro Alves
@ 2018-04-14 19:20 ` Pedro Alves
  2018-04-14 19:20 ` [PATCH 33/40] target_ops/C++: The rest of the BSD targets Pedro Alves
                   ` (8 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:20 UTC (permalink / raw)
  To: gdb-patches

This is a first pass, just enough to C++ify target_ops.

A later pass will convert more free functions to methods, and make the
remote_state be truly per remote instance, allowing multiple
simultaneous instances of remote targets.
---
 gdb/remote.c | 1319 +++++++++++++++++++++++++++++++---------------------------
 1 file changed, 712 insertions(+), 607 deletions(-)

diff --git a/gdb/remote.c b/gdb/remote.c
index e6d07a620c..0b22b11c09 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -76,6 +76,337 @@
 #include "environ.h"
 #include "common/byte-vector.h"
 
+/* The remote target.  */
+
+class remote_target : public target_ops
+{
+public:
+  remote_target ()
+  {
+    to_stratum = process_stratum;
+  }
+
+  const char *shortname () override
+  { return "remote"; }
+
+  const char *longname () override
+  { return _("Remote serial target in gdb-specific protocol"); }
+
+  const char *doc () override
+  {
+    return _("\
+Use a remote computer via a serial line, using a gdb-specific protocol.\n\
+Specify the serial device it is connected to\n\
+(e.g. /dev/ttyS0, /dev/ttya, COM1, etc.).");
+  }
+
+  thread_control_capabilities get_thread_control_capabilities () override
+  { return tc_schedlock; }
+
+  void open (const char *, int) override;
+  void close () override;
+
+  void detach (inferior *, int) override;
+  void disconnect (const char *, int) override;
+
+  void commit_resume () override;
+  void resume (ptid_t, int, enum gdb_signal) override;
+  ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
+
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+  void prepare_to_store (struct regcache *) override;
+
+  void files_info () override;
+
+  int insert_breakpoint (struct gdbarch *, struct bp_target_info *) override;
+
+  int remove_breakpoint (struct gdbarch *, struct bp_target_info *,
+			 enum remove_bp_reason) override;
+
+
+  int stopped_by_sw_breakpoint () override;
+  int supports_stopped_by_sw_breakpoint () override;
+
+  int stopped_by_hw_breakpoint () override;
+
+  int supports_stopped_by_hw_breakpoint () override;
+
+  int stopped_by_watchpoint () override;
+
+  int stopped_data_address (CORE_ADDR *) override;
+
+  int watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, int) override;
+
+  int can_use_hw_breakpoint (enum bptype, int, int) override;
+
+  int insert_hw_breakpoint (struct gdbarch *, struct bp_target_info *) override;
+
+  int remove_hw_breakpoint (struct gdbarch *, struct bp_target_info *) override;
+
+  int region_ok_for_hw_watchpoint (CORE_ADDR, int) override;
+
+  int insert_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
+			 struct expression *) override;
+
+  int remove_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
+			 struct expression *) override;
+
+  void kill () override;
+
+  void load (const char *, int) override;
+
+  void mourn_inferior () override;
+
+  void pass_signals (int, unsigned char *) override;
+
+  int set_syscall_catchpoint (int, bool, int,
+			      gdb::array_view<const int>) override;
+
+  void program_signals (int, unsigned char *) override;
+
+  int thread_alive (ptid_t ptid) override;
+
+  const char *thread_name (struct thread_info *) override;
+
+  void update_thread_list () override;
+
+  const char *pid_to_str (ptid_t) override;
+
+  const char *extra_thread_info (struct thread_info *) override;
+
+  ptid_t get_ada_task_ptid (long lwp, long thread) override;
+
+  thread_info *thread_handle_to_thread_info (const gdb_byte *thread_handle,
+					     int handle_len,
+					     inferior *inf) override;
+
+  void stop (ptid_t) override;
+
+  void interrupt () override;
+
+  void pass_ctrlc () override;
+
+  enum target_xfer_status xfer_partial (enum target_object object,
+					const char *annex,
+					gdb_byte *readbuf,
+					const gdb_byte *writebuf,
+					ULONGEST offset, ULONGEST len,
+					ULONGEST *xfered_len) override;
+
+  ULONGEST get_memory_xfer_limit () override;
+
+  void rcmd (const char *command, struct ui_file *output) override;
+
+  char *pid_to_exec_file (int pid) override;
+
+  void log_command (const char *cmd) override
+  {
+    serial_log_command (this, cmd);
+  }
+
+  CORE_ADDR get_thread_local_address (ptid_t ptid,
+				      CORE_ADDR load_module_addr,
+				      CORE_ADDR offset) override;
+
+  int has_all_memory ()  override { return default_child_has_all_memory (); }
+  int has_memory ()  override { return default_child_has_memory (); }
+  int has_stack ()  override { return default_child_has_stack (); }
+  int has_registers ()  override { return default_child_has_registers (); }
+  int has_execution (ptid_t ptid)  override { return default_child_has_execution (ptid); }
+
+  int can_execute_reverse () override;
+
+  std::vector<mem_region> memory_map () override;
+
+  void flash_erase (ULONGEST address, LONGEST length) override;
+
+  void flash_done () override;
+
+  const struct target_desc *read_description () override;
+
+  int search_memory (CORE_ADDR start_addr, ULONGEST search_space_len,
+		     const gdb_byte *pattern, ULONGEST pattern_len,
+		     CORE_ADDR *found_addrp) override;
+
+  int can_async_p () override;
+
+  int is_async_p () override;
+
+  void async (int) override;
+
+  void thread_events (int) override;
+
+  int can_do_single_step () override;
+
+  void terminal_inferior () override;
+
+  void terminal_ours () override;
+
+  int supports_non_stop () override;
+
+  int supports_multi_process () override;
+
+  int supports_disable_randomization () override;
+
+  int filesystem_is_local () override;
+
+
+  int fileio_open (struct inferior *inf, const char *filename,
+		   int flags, int mode, int warn_if_slow,
+		   int *target_errno) override;
+
+  int fileio_pwrite (int fd, const gdb_byte *write_buf, int len,
+		     ULONGEST offset, int *target_errno) override;
+
+  int fileio_pread (int fd, gdb_byte *read_buf, int len,
+		    ULONGEST offset, int *target_errno) override;
+
+  int fileio_fstat (int fd, struct stat *sb, int *target_errno) override;
+
+  int fileio_close (int fd, int *target_errno) override;
+
+  int fileio_unlink (struct inferior *inf,
+		     const char *filename,
+		     int *target_errno) override;
+
+  gdb::optional<std::string>
+    fileio_readlink (struct inferior *inf,
+		     const char *filename,
+		     int *target_errno) override;
+
+  int supports_enable_disable_tracepoint () override;
+
+  int supports_string_tracing () override;
+
+  int supports_evaluation_of_breakpoint_conditions () override;
+
+  int can_run_breakpoint_commands () override;
+
+  void trace_init () override;
+
+  void download_tracepoint (struct bp_location *location) override;
+
+  int can_download_tracepoint () override;
+
+  void download_trace_state_variable (const trace_state_variable &tsv) override;
+
+  void enable_tracepoint (struct bp_location *location) override;
+
+  void disable_tracepoint (struct bp_location *location) override;
+
+  void trace_set_readonly_regions () override;
+
+  void trace_start () override;
+
+  int get_trace_status (struct trace_status *ts) override;
+
+  void get_tracepoint_status (struct breakpoint *tp, struct uploaded_tp *utp)
+    override;
+
+  void trace_stop () override;
+
+  int trace_find (enum trace_find_type type, int num,
+		  CORE_ADDR addr1, CORE_ADDR addr2, int *tpp) override;
+
+  int get_trace_state_variable_value (int tsv, LONGEST *val) override;
+
+  int save_trace_data (const char *filename) override;
+
+  int upload_tracepoints (struct uploaded_tp **utpp) override;
+
+  int upload_trace_state_variables (struct uploaded_tsv **utsvp) override;
+
+  LONGEST get_raw_trace_data (gdb_byte *buf, ULONGEST offset, LONGEST len) override;
+
+  int get_min_fast_tracepoint_insn_len () override;
+
+  void set_disconnected_tracing (int val) override;
+
+  void set_circular_trace_buffer (int val) override;
+
+  void set_trace_buffer_size (LONGEST val) override;
+
+  int set_trace_notes (const char *user, const char *notes,
+		       const char *stopnotes) override;
+
+  int core_of_thread (ptid_t ptid) override;
+
+  int verify_memory (const gdb_byte *data,
+		     CORE_ADDR memaddr, ULONGEST size) override;
+
+
+  int get_tib_address (ptid_t ptid, CORE_ADDR *addr) override;
+
+  void set_permissions () override;
+
+  bool static_tracepoint_marker_at (CORE_ADDR,
+				    struct static_tracepoint_marker *marker)
+    override;
+
+  std::vector<static_tracepoint_marker>
+    static_tracepoint_markers_by_strid (const char *id) override;
+
+  traceframe_info_up traceframe_info () override;
+
+  int use_agent (int use) override;
+  int can_use_agent () override;
+
+  struct btrace_target_info *enable_btrace (ptid_t ptid,
+					    const struct btrace_config *conf) override;
+
+  void disable_btrace (struct btrace_target_info *tinfo) override;
+
+  void teardown_btrace (struct btrace_target_info *tinfo) override;
+
+  enum btrace_error read_btrace (struct btrace_data *data,
+				 struct btrace_target_info *btinfo,
+				 enum btrace_read_type type) override;
+
+  const struct btrace_config *btrace_conf (const struct btrace_target_info *) override;
+  int augmented_libraries_svr4_read () override;
+  int follow_fork (int, int) override;
+  void follow_exec (struct inferior *, char *) override;
+  int insert_fork_catchpoint (int) override;
+  int remove_fork_catchpoint (int) override;
+  int insert_vfork_catchpoint (int) override;
+  int remove_vfork_catchpoint (int) override;
+  int insert_exec_catchpoint (int) override;
+  int remove_exec_catchpoint (int) override;
+  enum exec_direction_kind execution_direction () override;
+
+protected:
+  void open_1 (const char *name, int from_tty, int extended_p);
+  void start_remote (int from_tty, int extended_p);
+};
+
+/* Set up the extended remote target by extending the standard remote
+   target and adding to it.  */
+
+class extended_remote_target : public remote_target
+{
+public:
+  const char *shortname () override
+  { return "extended-remote"; }
+
+  const char *longname () override
+  { return _("Extended remote serial target in gdb-specific protocol"); }
+
+  void open (const char *, int) override;
+
+  bool can_create_inferior () override { return true; }
+  void create_inferior (const char *, const std::string &,
+			char **, int) override;
+
+  void detach (inferior *, int) override;
+
+  bool can_attach () override { return true; }
+  void attach (const char *, int) override;
+
+  void post_attach (int) override;
+  int supports_disable_randomization () override;
+};
+
 /* Per-program-space data key.  */
 static const struct program_space_data *remote_pspace_data;
 
@@ -102,42 +433,18 @@ static int getpkt_sane (char **buf, long *sizeof_buf, int forever);
 static int getpkt_or_notif_sane (char **buf, long *sizeof_buf,
 				 int forever, int *is_notif);
 
-static void remote_files_info (struct target_ops *ignore);
-
-static void remote_prepare_to_store (struct target_ops *self,
-				     struct regcache *regcache);
-
-static void remote_open_1 (const char *, int, struct target_ops *,
-			   int extended_p);
-
-static void remote_close (struct target_ops *self);
-
 struct remote_state;
 
 static int remote_vkill (int pid, struct remote_state *rs);
 
 static void remote_kill_k (void);
 
-static void remote_mourn (struct target_ops *ops);
-
-static void extended_remote_restart (void);
-
 static void remote_send (char **buf, long *sizeof_buf_p);
 
 static int readchar (int timeout);
 
 static void remote_serial_write (const char *str, int len);
 
-static void remote_kill (struct target_ops *ops);
-
-static int remote_can_async_p (struct target_ops *);
-
-static int remote_is_async_p (struct target_ops *);
-
-static void remote_async (struct target_ops *ops, int enable);
-
-static void remote_thread_events (struct target_ops *ops, int enable);
-
 static void interrupt_query (void);
 
 static void set_general_thread (ptid_t ptid);
@@ -151,12 +458,6 @@ static long read_frame (char **buf_p, long *sizeof_buf);
 
 static int hexnumlen (ULONGEST num);
 
-static void init_remote_ops (void);
-
-static void init_extended_remote_ops (void);
-
-static void remote_stop (struct target_ops *self, ptid_t);
-
 static int stubhex (int ch);
 
 static int hexnumstr (char *, ULONGEST);
@@ -187,17 +488,6 @@ static void show_remote_protocol_packet_cmd (struct ui_file *file,
 static char *write_ptid (char *buf, const char *endbuf, ptid_t ptid);
 static ptid_t read_ptid (const char *buf, const char **obuf);
 
-static void remote_set_permissions (struct target_ops *self);
-
-static int remote_get_trace_status (struct target_ops *self,
-				    struct trace_status *ts);
-
-static int remote_upload_tracepoints (struct target_ops *self,
-				      struct uploaded_tp **utpp);
-
-static int remote_upload_trace_state_variables (struct target_ops *self,
-						struct uploaded_tsv **utsvp);
-  
 static void remote_query_supported (void);
 
 static void remote_check_symbols (void);
@@ -214,16 +504,10 @@ static void remove_new_fork_children (struct threads_listing_context *);
 
 static void remote_async_inferior_event_handler (gdb_client_data);
 
-static void remote_terminal_ours (struct target_ops *self);
-
 static int remote_read_description_p (struct target_ops *target);
 
 static void remote_console_output (char *msg);
 
-static int remote_supports_cond_breakpoints (struct target_ops *self);
-
-static int remote_can_run_breakpoint_commands (struct target_ops *self);
-
 static void remote_btrace_reset (void);
 
 static void remote_btrace_maybe_reopen (void);
@@ -902,9 +1186,9 @@ packet_reg_from_pnum (struct gdbarch *gdbarch, struct remote_arch_state *rsa,
   return NULL;
 }
 
-static struct target_ops remote_ops;
+static remote_target remote_ops;
 
-static struct target_ops extended_remote_ops;
+static extended_remote_target extended_remote_ops;
 
 /* FIXME: cagney/1999-09-23: Even though getpkt was called with
    ``forever'' still use the normal timeout mechanism.  This is
@@ -1656,8 +1940,8 @@ remote_exec_event_p (struct remote_state *rs)
 /* Insert fork catchpoint target routine.  If fork events are enabled
    then return success, nothing more to do.  */
 
-static int
-remote_insert_fork_catchpoint (struct target_ops *ops, int pid)
+int
+remote_target::insert_fork_catchpoint (int pid)
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -1667,8 +1951,8 @@ remote_insert_fork_catchpoint (struct target_ops *ops, int pid)
 /* Remove fork catchpoint target routine.  Nothing to do, just
    return success.  */
 
-static int
-remote_remove_fork_catchpoint (struct target_ops *ops, int pid)
+int
+remote_target::remove_fork_catchpoint (int pid)
 {
   return 0;
 }
@@ -1676,8 +1960,8 @@ remote_remove_fork_catchpoint (struct target_ops *ops, int pid)
 /* Insert vfork catchpoint target routine.  If vfork events are enabled
    then return success, nothing more to do.  */
 
-static int
-remote_insert_vfork_catchpoint (struct target_ops *ops, int pid)
+int
+remote_target::insert_vfork_catchpoint (int pid)
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -1687,8 +1971,8 @@ remote_insert_vfork_catchpoint (struct target_ops *ops, int pid)
 /* Remove vfork catchpoint target routine.  Nothing to do, just
    return success.  */
 
-static int
-remote_remove_vfork_catchpoint (struct target_ops *ops, int pid)
+int
+remote_target::remove_vfork_catchpoint (int pid)
 {
   return 0;
 }
@@ -1696,8 +1980,8 @@ remote_remove_vfork_catchpoint (struct target_ops *ops, int pid)
 /* Insert exec catchpoint target routine.  If exec events are
    enabled, just return success.  */
 
-static int
-remote_insert_exec_catchpoint (struct target_ops *ops, int pid)
+int
+remote_target::insert_exec_catchpoint (int pid)
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -1707,8 +1991,8 @@ remote_insert_exec_catchpoint (struct target_ops *ops, int pid)
 /* Remove exec catchpoint target routine.  Nothing to do, just
    return success.  */
 
-static int
-remote_remove_exec_catchpoint (struct target_ops *ops, int pid)
+int
+remote_target::remove_exec_catchpoint (int pid)
 {
   return 0;
 }
@@ -1971,9 +2255,8 @@ record_currthread (struct remote_state *rs, ptid_t currthread)
 /* If 'QPassSignals' is supported, tell the remote stub what signals
    it can simply pass through to the inferior without reporting.  */
 
-static void
-remote_pass_signals (struct target_ops *self,
-		     int numsigs, unsigned char *pass_signals)
+void
+remote_target::pass_signals (int numsigs, unsigned char *pass_signals)
 {
   if (packet_support (PACKET_QPassSignals) != PACKET_DISABLE)
     {
@@ -2022,10 +2305,9 @@ remote_pass_signals (struct target_ops *self,
 /* If 'QCatchSyscalls' is supported, tell the remote stub
    to report syscalls to GDB.  */
 
-static int
-remote_set_syscall_catchpoint (struct target_ops *self,
-			       int pid, bool needed, int any_count,
-			       gdb::array_view<const int> syscall_counts)
+int
+remote_target::set_syscall_catchpoint (int pid, bool needed, int any_count,
+				       gdb::array_view<const int> syscall_counts)
 {
   const char *catch_packet;
   enum packet_result result;
@@ -2099,9 +2381,8 @@ remote_set_syscall_catchpoint (struct target_ops *self,
 /* If 'QProgramSignals' is supported, tell the remote stub what
    signals it should pass through to the inferior when detaching.  */
 
-static void
-remote_program_signals (struct target_ops *self,
-			int numsigs, unsigned char *signals)
+void
+remote_target::program_signals (int numsigs, unsigned char *signals)
 {
   if (packet_support (PACKET_QProgramSignals) != PACKET_DISABLE)
     {
@@ -2221,7 +2502,7 @@ set_general_process (void)
    to model non-threaded targets as single-threaded.  */
 
 static int
-remote_thread_always_alive (struct target_ops *ops, ptid_t ptid)
+remote_thread_always_alive (ptid_t ptid)
 {
   if (ptid_equal (ptid, magic_null_ptid))
     /* The main thread is always alive.  */
@@ -2239,15 +2520,15 @@ remote_thread_always_alive (struct target_ops *ops, ptid_t ptid)
 /* Return nonzero if the thread PTID is still alive on the remote
    system.  */
 
-static int
-remote_thread_alive (struct target_ops *ops, ptid_t ptid)
+int
+remote_target::thread_alive (ptid_t ptid)
 {
   struct remote_state *rs = get_remote_state ();
   char *p, *endp;
 
   /* Check if this is a thread that we made up ourselves to model
      non-threaded targets as single-threaded.  */
-  if (remote_thread_always_alive (ops, ptid))
+  if (remote_thread_always_alive (ptid))
     return 1;
 
   p = rs->buf;
@@ -2264,8 +2545,8 @@ remote_thread_alive (struct target_ops *ops, ptid_t ptid)
 /* Return a pointer to a thread name if we know it and NULL otherwise.
    The thread_info object owns the memory for the name.  */
 
-static const char *
-remote_thread_name (struct target_ops *ops, struct thread_info *info)
+const char *
+remote_target::thread_name (struct thread_info *info)
 {
   if (info->priv != NULL)
     {
@@ -3211,8 +3492,8 @@ remote_get_threads_with_qthreadinfo (struct target_ops *ops,
 /* Implement the to_update_thread_list function for the remote
    targets.  */
 
-static void
-remote_update_thread_list (struct target_ops *ops)
+void
+remote_target::update_thread_list ()
 {
   struct threads_listing_context context;
   int got_list = 0;
@@ -3220,16 +3501,16 @@ remote_update_thread_list (struct target_ops *ops)
   /* We have a few different mechanisms to fetch the thread list.  Try
      them all, starting with the most preferred one first, falling
      back to older methods.  */
-  if (remote_get_threads_with_qxfer (ops, &context)
-      || remote_get_threads_with_qthreadinfo (ops, &context)
-      || remote_get_threads_with_ql (ops, &context))
+  if (remote_get_threads_with_qxfer (this, &context)
+      || remote_get_threads_with_qthreadinfo (this, &context)
+      || remote_get_threads_with_ql (this, &context))
     {
       struct thread_info *tp, *tmp;
 
       got_list = 1;
 
       if (context.items.empty ()
-	  && remote_thread_always_alive (ops, inferior_ptid))
+	  && remote_thread_always_alive (inferior_ptid))
 	{
 	  /* Some targets don't really support threads, but still
 	     reply an (empty) thread list in response to the thread
@@ -3297,8 +3578,8 @@ remote_update_thread_list (struct target_ops *ops)
  * Optional: targets are not required to implement this function.
  */
 
-static const char *
-remote_threads_extra_info (struct target_ops *self, struct thread_info *tp)
+const char *
+remote_target::extra_thread_info (thread_info *tp)
 {
   struct remote_state *rs = get_remote_state ();
   int result;
@@ -3381,9 +3662,9 @@ remote_threads_extra_info (struct target_ops *self, struct thread_info *tp)
 }
 \f
 
-static bool
-remote_static_tracepoint_marker_at (struct target_ops *self, CORE_ADDR addr,
-				    struct static_tracepoint_marker *marker)
+bool
+remote_target::static_tracepoint_marker_at (CORE_ADDR addr,
+					    struct static_tracepoint_marker *marker)
 {
   struct remote_state *rs = get_remote_state ();
   char *p = rs->buf;
@@ -3407,9 +3688,8 @@ remote_static_tracepoint_marker_at (struct target_ops *self, CORE_ADDR addr,
   return false;
 }
 
-static std::vector<static_tracepoint_marker>
-remote_static_tracepoint_markers_by_strid (struct target_ops *self,
-					   const char *strid)
+std::vector<static_tracepoint_marker>
+remote_target::static_tracepoint_markers_by_strid (const char *strid)
 {
   struct remote_state *rs = get_remote_state ();
   std::vector<static_tracepoint_marker> markers;
@@ -3446,8 +3726,8 @@ remote_static_tracepoint_markers_by_strid (struct target_ops *self,
 \f
 /* Implement the to_get_ada_task_ptid function for the remote targets.  */
 
-static ptid_t
-remote_get_ada_task_ptid (struct target_ops *self, long lwp, long thread)
+ptid_t
+remote_target::get_ada_task_ptid (long lwp, long thread)
 {
   return ptid_build (ptid_get_pid (inferior_ptid), lwp, 0);
 }
@@ -3470,8 +3750,8 @@ extended_remote_restart (void)
 \f
 /* Clean up connection to a remote debugger.  */
 
-static void
-remote_close (struct target_ops *self)
+void
+remote_target::close ()
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -3479,7 +3759,7 @@ remote_close (struct target_ops *self)
     return; /* already closed */
 
   /* Make sure we leave stdin registered in the event loop.  */
-  remote_terminal_ours (self);
+  terminal_ours ();
 
   serial_close (rs->remote_desc);
   rs->remote_desc = NULL;
@@ -3977,8 +4257,8 @@ process_initial_stop_replies (int from_tty)
 
 /* Start the remote connection and sync state.  */
 
-static void
-remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
+void
+remote_target::start_remote (int from_tty, int extended_p)
 {
   struct remote_state *rs = get_remote_state ();
   struct packet_config *noack_config;
@@ -4007,7 +4287,7 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
 
   /* If the stub wants to get a QAllow, compose one and send it.  */
   if (packet_support (PACKET_QAllow) != PACKET_DISABLE)
-    remote_set_permissions (target);
+    set_permissions ();
 
   /* gdbserver < 7.7 (before its fix from 2013-12-11) did reply to any
      unknown 'v' packet with string "OK".  "OK" gets interpreted by GDB
@@ -4090,7 +4370,7 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
 	 controlling.  We default to adding them in the running state.
 	 The '?' query below will then tell us about which threads are
 	 stopped.  */
-      remote_update_thread_list (target);
+      this->update_thread_list ();
     }
   else if (packet_support (PACKET_QNonStop) == PACKET_ENABLE)
     {
@@ -4106,11 +4386,11 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
   /* Upload TSVs regardless of whether the target is running or not.  The
      remote stub, such as GDBserver, may have some predefined or builtin
      TSVs, even if the target is not running.  */
-  if (remote_get_trace_status (target, current_trace_status ()) != -1)
+  if (get_trace_status (current_trace_status ()) != -1)
     {
       struct uploaded_tsv *uploaded_tsvs = NULL;
 
-      remote_upload_trace_state_variables (target, &uploaded_tsvs);
+      upload_trace_state_variables (&uploaded_tsvs);
       merge_uploaded_trace_state_variables (&uploaded_tsvs);
     }
 
@@ -4190,7 +4470,7 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
 	 how to do it some other way, try again.  This is not
 	 supported for non-stop; it could be, but it is tricky if
 	 there are no stopped threads when we connect.  */
-      if (remote_read_description_p (target)
+      if (remote_read_description_p (this)
 	  && gdbarch_target_desc (target_gdbarch ()) == NULL)
 	{
 	  target_clear_description ();
@@ -4202,7 +4482,7 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
       strcpy (rs->buf, wait_status);
       rs->cached_wait_status = 1;
 
-      start_remote (from_tty); /* Initialize gdb process mechanisms.  */
+      ::start_remote (from_tty); /* Initialize gdb process mechanisms.  */
     }
   else
     {
@@ -4245,7 +4525,7 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
       gdb_assert (wait_status == NULL);
 
       /* Report all signals during attach/startup.  */
-      remote_pass_signals (target, 0, NULL);
+      pass_signals (0, NULL);
 
       /* If there are already stopped threads, mark them stopped and
 	 report their stops before giving the prompt to the user.  */
@@ -4264,14 +4544,14 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
 
   /* Possibly the target has been engaged in a trace run started
      previously; find out where things are at.  */
-  if (remote_get_trace_status (target, current_trace_status ()) != -1)
+  if (get_trace_status (current_trace_status ()) != -1)
     {
       struct uploaded_tp *uploaded_tps = NULL;
 
       if (current_trace_status ()->running)
 	printf_filtered (_("Trace is already running on the target.\n"));
 
-      remote_upload_tracepoints (target, &uploaded_tps);
+      upload_tracepoints (&uploaded_tps);
 
       merge_uploaded_tracepoints (&uploaded_tps);
     }
@@ -4294,19 +4574,19 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
 /* Open a connection to a remote debugger.
    NAME is the filename used for communication.  */
 
-static void
-remote_open (const char *name, int from_tty)
+void
+remote_target::open (const char *name, int from_tty)
 {
-  remote_open_1 (name, from_tty, &remote_ops, 0);
+  open_1 (name, from_tty, 0);
 }
 
 /* Open a connection to a remote debugger using the extended
    remote gdb protocol.  NAME is the filename used for communication.  */
 
-static void
-extended_remote_open (const char *name, int from_tty)
+void
+extended_remote_target::open (const char *name, int from_tty)
 {
-  remote_open_1 (name, from_tty, &extended_remote_ops, 1 /*extended_p */);
+  open_1 (name, from_tty, 1 /*extended_p */);
 }
 
 /* Reset all packets back to "unknown support".  Called when opening a
@@ -4436,7 +4716,7 @@ remote_serial_open (const char *name)
    permissions.  */
 
 void
-remote_set_permissions (struct target_ops *self)
+remote_target::set_permissions ()
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -4919,9 +5199,8 @@ remote_unpush_and_throw (void)
   throw_error (TARGET_CLOSE_ERROR, _("Disconnected from target."));
 }
 
-static void
-remote_open_1 (const char *name, int from_tty,
-	       struct target_ops *target, int extended_p)
+void
+remote_target::open_1 (const char *name, int from_tty, int extended_p)
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -4991,7 +5270,7 @@ remote_open_1 (const char *name, int from_tty,
       puts_filtered (name);
       puts_filtered ("\n");
     }
-  push_target (target);		/* Switch to using remote target now.  */
+  push_target (this);		/* Switch to using remote target now.  */
 
   /* Register extra event sources in the event loop.  */
   remote_async_inferior_event_token
@@ -5059,7 +5338,7 @@ remote_open_1 (const char *name, int from_tty,
 
     TRY
       {
-	remote_start_remote (from_tty, target, extended_p);
+	start_remote (from_tty, extended_p);
       }
     CATCH (ex, RETURN_MASK_ALL)
       {
@@ -5145,14 +5424,14 @@ remote_detach_1 (int from_tty, inferior *inf)
     }
 }
 
-static void
-remote_detach (struct target_ops *ops, inferior *inf, int from_tty)
+void
+remote_target::detach (inferior *inf, int from_tty)
 {
   remote_detach_1 (from_tty, inf);
 }
 
-static void
-extended_remote_detach (struct target_ops *ops, inferior *inf, int from_tty)
+void
+extended_remote_target::detach (inferior *inf, int from_tty)
 {
   remote_detach_1 (from_tty, inf);
 }
@@ -5164,9 +5443,8 @@ extended_remote_detach (struct target_ops *ops, inferior *inf, int from_tty)
    it is named remote_follow_fork in anticipation of using it for the
    remote target as well.  */
 
-static int
-remote_follow_fork (struct target_ops *ops, int follow_child,
-		    int detach_fork)
+int
+remote_target::follow_fork (int follow_child, int detach_fork)
 {
   struct remote_state *rs = get_remote_state ();
   enum target_waitkind kind = inferior_thread ()->pending_follow.kind;
@@ -5201,9 +5479,8 @@ remote_follow_fork (struct target_ops *ops, int follow_child,
    inferior, which may be the same as the exec'ing inferior unless
    follow-exec-mode is "new".  */
 
-static void
-remote_follow_exec (struct target_ops *ops,
-		    struct inferior *inf, char *execd_pathname)
+void
+remote_target::follow_exec (struct inferior *inf, char *execd_pathname)
 {
   /* We know that this is a target file name, so if it has the "target:"
      prefix we strip it off before saving it in the program space.  */
@@ -5215,8 +5492,8 @@ remote_follow_exec (struct target_ops *ops,
 
 /* Same as remote_detach, but don't send the "D" packet; just disconnect.  */
 
-static void
-remote_disconnect (struct target_ops *target, const char *args, int from_tty)
+void
+remote_target::disconnect (const char *args, int from_tty)
 {
   if (args)
     error (_("Argument given to \"disconnect\" when remotely debugging."));
@@ -5224,7 +5501,7 @@ remote_disconnect (struct target_ops *target, const char *args, int from_tty)
   /* Make sure we unpush even the extended remote targets.  Calling
      target_mourn_inferior won't unpush, and remote_mourn won't
      unpush if there is more than one inferior left.  */
-  unpush_target (target);
+  unpush_target (this);
   generic_mourn_inferior ();
 
   if (from_tty)
@@ -5234,9 +5511,8 @@ remote_disconnect (struct target_ops *target, const char *args, int from_tty)
 /* Attach to the process specified by ARGS.  If FROM_TTY is non-zero,
    be chatty about it.  */
 
-static void
-extended_remote_attach (struct target_ops *target, const char *args,
-			int from_tty)
+void
+extended_remote_target::attach (const char *args, int from_tty)
 {
   struct remote_state *rs = get_remote_state ();
   int pid;
@@ -5299,7 +5575,7 @@ extended_remote_attach (struct target_ops *target, const char *args,
       struct thread_info *thread;
 
       /* Get list of threads.  */
-      remote_update_thread_list (target);
+      update_thread_list ();
 
       thread = first_thread_of_process (pid);
       if (thread)
@@ -5350,8 +5626,8 @@ extended_remote_attach (struct target_ops *target, const char *args,
 
 /* Implementation of the to_post_attach method.  */
 
-static void
-extended_remote_post_attach (struct target_ops *ops, int pid)
+void
+extended_remote_target::post_attach (int pid)
 {
   /* Get text, data & bss offsets.  */
   get_offsets ();
@@ -5674,9 +5950,8 @@ remote_resume_with_vcont (ptid_t ptid, int step, enum gdb_signal siggnal)
 
 /* Tell the remote machine to resume.  */
 
-static void
-remote_resume (struct target_ops *ops,
-	       ptid_t ptid, int step, enum gdb_signal siggnal)
+void
+remote_target::resume (ptid_t ptid, int step, enum gdb_signal siggnal)
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -5687,7 +5962,7 @@ remote_resume (struct target_ops *ops,
      request; the actual remote resumption will be done in
      target_commit_resume / remote_commit_resume, where we'll be able
      to do vCont action coalescing.  */
-  if (target_is_non_stop_p () && execution_direction != EXEC_REVERSE)
+  if (target_is_non_stop_p () && ::execution_direction != EXEC_REVERSE)
     {
       remote_thread_info *remote_thr;
 
@@ -5710,11 +5985,11 @@ remote_resume (struct target_ops *ops,
   if (!target_is_non_stop_p ())
     remote_notif_process (rs->notif_state, &notif_client_stop);
 
-  rs->last_resume_exec_dir = execution_direction;
+  rs->last_resume_exec_dir = ::execution_direction;
 
   /* Prefer vCont, and fallback to s/c/S/C, which use Hc.  */
   if (!remote_resume_with_vcont (ptid, step, siggnal))
-    remote_resume_with_hc (ops, ptid, step, siggnal);
+    remote_resume_with_hc (this, ptid, step, siggnal);
 
   /* We are about to start executing the inferior, let's register it
      with the event loop.  NOTE: this is the one place where all the
@@ -5850,8 +6125,8 @@ vcont_builder_push_action (struct vcont_builder *builder,
 
 /* to_commit_resume implementation.  */
 
-static void
-remote_commit_resume (struct target_ops *ops)
+void
+remote_target::commit_resume ()
 {
   struct inferior *inf;
   struct thread_info *tp;
@@ -5863,7 +6138,7 @@ remote_commit_resume (struct target_ops *ops)
      request directly from remote_resume.  Likewise if
      reverse-debugging, as there are no defined vCont actions for
      reverse execution.  */
-  if (!target_is_non_stop_p () || execution_direction == EXEC_REVERSE)
+  if (!target_is_non_stop_p () || ::execution_direction == EXEC_REVERSE)
     return;
 
   /* Try to send wildcard actions ("vCont;c" or "vCont;c:pPID.-1")
@@ -6129,8 +6404,8 @@ remote_interrupt_ns (void)
 
 /* Implement the to_stop function for the remote targets.  */
 
-static void
-remote_stop (struct target_ops *self, ptid_t ptid)
+void
+remote_target::stop (ptid_t ptid)
 {
   if (remote_debug)
     fprintf_unfiltered (gdb_stdlog, "remote_stop called\n");
@@ -6147,8 +6422,8 @@ remote_stop (struct target_ops *self, ptid_t ptid)
 
 /* Implement the to_interrupt function for the remote targets.  */
 
-static void
-remote_interrupt (struct target_ops *self)
+void
+remote_target::interrupt ()
 {
   if (remote_debug)
     fprintf_unfiltered (gdb_stdlog, "remote_interrupt called\n");
@@ -6161,8 +6436,8 @@ remote_interrupt (struct target_ops *self)
 
 /* Implement the to_pass_ctrlc function for the remote targets.  */
 
-static void
-remote_pass_ctrlc (struct target_ops *self)
+void
+remote_target::pass_ctrlc ()
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -6209,16 +6484,16 @@ interrupt_query (void)
    different in that explicit transfer of ownership to/from GDB/target
    is required.  */
 
-static void
-remote_terminal_inferior (struct target_ops *self)
+void
+remote_target::terminal_inferior ()
 {
   /* NOTE: At this point we could also register our selves as the
      recipient of all input.  Any characters typed could then be
      passed on down to the target.  */
 }
 
-static void
-remote_terminal_ours (struct target_ops *self)
+void
+remote_target::terminal_ours ()
 {
 }
 
@@ -7420,9 +7695,8 @@ remote_wait_as (ptid_t ptid, struct target_waitstatus *status, int options)
 /* Wait until the remote machine stops, then return, storing status in
    STATUS just as `wait' would.  */
 
-static ptid_t
-remote_wait (struct target_ops *ops,
-	     ptid_t ptid, struct target_waitstatus *status, int options)
+ptid_t
+remote_target::wait (ptid_t ptid, struct target_waitstatus *status, int options)
 {
   ptid_t event_ptid;
 
@@ -7672,9 +7946,8 @@ set_remote_traceframe (void)
     warning (_("could not set remote traceframe"));
 }
 
-static void
-remote_fetch_registers (struct target_ops *ops,
-			struct regcache *regcache, int regnum)
+void
+remote_target::fetch_registers (struct regcache *regcache, int regnum)
 {
   struct gdbarch *gdbarch = regcache->arch ();
   remote_arch_state *rsa = get_remote_arch_state (gdbarch);
@@ -7724,8 +7997,8 @@ remote_fetch_registers (struct target_ops *ops,
    'G' request), we have to read out the ones we don't want to change
    first.  */
 
-static void
-remote_prepare_to_store (struct target_ops *self, struct regcache *regcache)
+void
+remote_target::prepare_to_store (struct regcache *regcache)
 {
   remote_arch_state *rsa = get_remote_arch_state (regcache->arch ());
   int i;
@@ -7828,9 +8101,8 @@ store_registers_using_G (const struct regcache *regcache)
 /* Store register REGNUM, or all registers if REGNUM == -1, from the contents
    of the register cache buffer.  FIXME: ignores errors.  */
 
-static void
-remote_store_registers (struct target_ops *ops,
-			struct regcache *regcache, int regnum)
+void
+remote_target::store_registers (struct regcache *regcache, int regnum)
 {
   struct gdbarch *gdbarch = regcache->arch ();
   remote_arch_state *rsa = get_remote_arch_state (gdbarch);
@@ -8440,9 +8712,8 @@ remote_send_printf (const char *format, ...)
    In future, we'll need to decide on a better approach.  */
 static const int remote_flash_timeout = 1000;
 
-static void
-remote_flash_erase (struct target_ops *ops,
-                    ULONGEST address, LONGEST length)
+void
+remote_target::flash_erase (ULONGEST address, LONGEST length)
 {
   int addr_size = gdbarch_addr_bit (target_gdbarch ()) / 8;
   enum packet_result ret;
@@ -8474,8 +8745,8 @@ remote_flash_write (struct target_ops *ops, ULONGEST address,
 				 xfered_len,'X', 0);
 }
 
-static void
-remote_flash_done (struct target_ops *ops)
+void
+remote_target::flash_done ()
 {
   int ret;
 
@@ -8495,8 +8766,8 @@ remote_flash_done (struct target_ops *ops)
     }
 }
 
-static void
-remote_files_info (struct target_ops *ignore)
+void
+remote_target::files_info ()
 {
   puts_filtered ("Debugging a target over a serial line.\n");
 }
@@ -9261,8 +9532,8 @@ kill_new_fork_children (int pid, struct remote_state *rs)
 \f
 /* Target hook to kill the current inferior.  */
 
-static void
-remote_kill (struct target_ops *ops)
+void
+remote_target::kill ()
 {
   int res = -1;
   int pid = ptid_get_pid (inferior_ptid);
@@ -9363,15 +9634,15 @@ remote_kill_k (void)
   END_CATCH
 }
 
-static void
-remote_mourn (struct target_ops *target)
+void
+remote_target::mourn_inferior ()
 {
   struct remote_state *rs = get_remote_state ();
 
   /* In 'target remote' mode with one inferior, we close the connection.  */
   if (!rs->extended && number_of_live_inferiors () <= 1)
     {
-      unpush_target (target);
+      unpush_target (this);
 
       /* remote_close takes care of doing most of the clean up.  */
       generic_mourn_inferior ();
@@ -9431,8 +9702,8 @@ remote_mourn (struct target_ops *target)
     }
 }
 
-static int
-extended_remote_supports_disable_randomization (struct target_ops *self)
+int
+extended_remote_target::supports_disable_randomization ()
 {
   return packet_support (PACKET_QDisableRandomization) == PACKET_ENABLE;
 }
@@ -9608,11 +9879,10 @@ directory: %s"),
    executable file and the command line arguments, but not the
    environment.  */
 
-static void
-extended_remote_create_inferior (struct target_ops *ops,
-				 const char *exec_file,
-				 const std::string &args,
-				 char **env, int from_tty)
+void
+extended_remote_target::create_inferior (const char *exec_file,
+					 const std::string &args,
+					 char **env, int from_tty)
 {
   int run_worked;
   char *stop_reply;
@@ -9625,7 +9895,7 @@ extended_remote_create_inferior (struct target_ops *ops,
     target_async (1);
 
   /* Disable address space randomization if requested (and supported).  */
-  if (extended_remote_supports_disable_randomization (ops))
+  if (supports_disable_randomization ())
     extended_remote_disable_randomization (disable_randomization);
 
   /* If startup-with-shell is on, we inform gdbserver to start the
@@ -9736,10 +10006,9 @@ remote_add_target_side_commands (struct gdbarch *gdbarch,
    support, we ask the remote target to do the work; on targets
    which don't, we insert a traditional memory breakpoint.  */
 
-static int
-remote_insert_breakpoint (struct target_ops *ops,
-			  struct gdbarch *gdbarch,
-			  struct bp_target_info *bp_tgt)
+int
+remote_target::insert_breakpoint (struct gdbarch *gdbarch,
+				  struct bp_target_info *bp_tgt)
 {
   /* Try the "Z" s/w breakpoint packet if it is not already disabled.
      If it succeeds, then set the support to PACKET_ENABLE.  If it
@@ -9768,10 +10037,10 @@ remote_insert_breakpoint (struct target_ops *ops,
       p += hexnumstr (p, addr);
       xsnprintf (p, endbuf - p, ",%d", bp_tgt->kind);
 
-      if (remote_supports_cond_breakpoints (ops))
+      if (supports_evaluation_of_breakpoint_conditions ())
 	remote_add_target_side_condition (gdbarch, bp_tgt, p, endbuf);
 
-      if (remote_can_run_breakpoint_commands (ops))
+      if (can_run_breakpoint_commands ())
 	remote_add_target_side_commands (gdbarch, bp_tgt, p);
 
       putpkt (rs->buf);
@@ -9794,14 +10063,13 @@ remote_insert_breakpoint (struct target_ops *ops,
     throw_error (NOT_SUPPORTED_ERROR, _("\
 Target doesn't support breakpoints that have target side commands."));
 
-  return memory_insert_breakpoint (ops, gdbarch, bp_tgt);
+  return memory_insert_breakpoint (this, gdbarch, bp_tgt);
 }
 
-static int
-remote_remove_breakpoint (struct target_ops *ops,
-			  struct gdbarch *gdbarch,
-			  struct bp_target_info *bp_tgt,
-			  enum remove_bp_reason reason)
+int
+remote_target::remove_breakpoint (struct gdbarch *gdbarch,
+				  struct bp_target_info *bp_tgt,
+				  enum remove_bp_reason reason)
 {
   CORE_ADDR addr = bp_tgt->placed_address;
   struct remote_state *rs = get_remote_state ();
@@ -9830,7 +10098,7 @@ remote_remove_breakpoint (struct target_ops *ops,
       return (rs->buf[0] == 'E');
     }
 
-  return memory_remove_breakpoint (ops, gdbarch, bp_tgt, reason);
+  return memory_remove_breakpoint (this, gdbarch, bp_tgt, reason);
 }
 
 static enum Z_packet_type
@@ -9853,9 +10121,9 @@ watchpoint_to_Z_packet (int type)
     }
 }
 
-static int
-remote_insert_watchpoint (struct target_ops *self, CORE_ADDR addr, int len,
-			  enum target_hw_bp_type type, struct expression *cond)
+int
+remote_target::insert_watchpoint (CORE_ADDR addr, int len,
+				  enum target_hw_bp_type type, struct expression *cond)
 {
   struct remote_state *rs = get_remote_state ();
   char *endbuf = rs->buf + get_remote_packet_size ();
@@ -9892,9 +10160,9 @@ remote_insert_watchpoint (struct target_ops *self, CORE_ADDR addr, int len,
 		  _("remote_insert_watchpoint: reached end of function"));
 }
 
-static int
-remote_watchpoint_addr_within_range (struct target_ops *target, CORE_ADDR addr,
-				     CORE_ADDR start, int length)
+int
+remote_target::watchpoint_addr_within_range (CORE_ADDR addr,
+					     CORE_ADDR start, int length)
 {
   CORE_ADDR diff = remote_address_masked (addr - start);
 
@@ -9902,9 +10170,9 @@ remote_watchpoint_addr_within_range (struct target_ops *target, CORE_ADDR addr,
 }
 
 
-static int
-remote_remove_watchpoint (struct target_ops *self, CORE_ADDR addr, int len,
-			  enum target_hw_bp_type type, struct expression *cond)
+int
+remote_target::remove_watchpoint (CORE_ADDR addr, int len,
+				  enum target_hw_bp_type type, struct expression *cond)
 {
   struct remote_state *rs = get_remote_state ();
   char *endbuf = rs->buf + get_remote_packet_size ();
@@ -9944,9 +10212,8 @@ int remote_hw_watchpoint_limit = -1;
 int remote_hw_watchpoint_length_limit = -1;
 int remote_hw_breakpoint_limit = -1;
 
-static int
-remote_region_ok_for_hw_watchpoint (struct target_ops *self,
-				    CORE_ADDR addr, int len)
+int
+remote_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
 {
   if (remote_hw_watchpoint_length_limit == 0)
     return 0;
@@ -9958,9 +10225,8 @@ remote_region_ok_for_hw_watchpoint (struct target_ops *self,
     return 0;
 }
 
-static int
-remote_check_watch_resources (struct target_ops *self,
-			      enum bptype type, int cnt, int ot)
+int
+remote_target::can_use_hw_breakpoint (enum bptype type, int cnt, int ot)
 {
   if (type == bp_hardware_breakpoint)
     {
@@ -9987,8 +10253,8 @@ remote_check_watch_resources (struct target_ops *self,
 
 /* The to_stopped_by_sw_breakpoint method of target remote.  */
 
-static int
-remote_stopped_by_sw_breakpoint (struct target_ops *ops)
+int
+remote_target::stopped_by_sw_breakpoint ()
 {
   struct thread_info *thread = inferior_thread ();
 
@@ -10000,16 +10266,16 @@ remote_stopped_by_sw_breakpoint (struct target_ops *ops)
 /* The to_supports_stopped_by_sw_breakpoint method of target
    remote.  */
 
-static int
-remote_supports_stopped_by_sw_breakpoint (struct target_ops *ops)
+int
+remote_target::supports_stopped_by_sw_breakpoint ()
 {
   return (packet_support (PACKET_swbreak_feature) == PACKET_ENABLE);
 }
 
 /* The to_stopped_by_hw_breakpoint method of target remote.  */
 
-static int
-remote_stopped_by_hw_breakpoint (struct target_ops *ops)
+int
+remote_target::stopped_by_hw_breakpoint ()
 {
   struct thread_info *thread = inferior_thread ();
 
@@ -10021,14 +10287,14 @@ remote_stopped_by_hw_breakpoint (struct target_ops *ops)
 /* The to_supports_stopped_by_hw_breakpoint method of target
    remote.  */
 
-static int
-remote_supports_stopped_by_hw_breakpoint (struct target_ops *ops)
+int
+remote_target::supports_stopped_by_hw_breakpoint ()
 {
   return (packet_support (PACKET_hwbreak_feature) == PACKET_ENABLE);
 }
 
-static int
-remote_stopped_by_watchpoint (struct target_ops *ops)
+int
+remote_target::stopped_by_watchpoint ()
 {
   struct thread_info *thread = inferior_thread ();
 
@@ -10037,8 +10303,8 @@ remote_stopped_by_watchpoint (struct target_ops *ops)
 	      == TARGET_STOPPED_BY_WATCHPOINT));
 }
 
-static int
-remote_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p)
+int
+remote_target::stopped_data_address (CORE_ADDR *addr_p)
 {
   struct thread_info *thread = inferior_thread ();
 
@@ -10054,9 +10320,9 @@ remote_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p)
 }
 
 
-static int
-remote_insert_hw_breakpoint (struct target_ops *self, struct gdbarch *gdbarch,
-			     struct bp_target_info *bp_tgt)
+int
+remote_target::insert_hw_breakpoint (struct gdbarch *gdbarch,
+				     struct bp_target_info *bp_tgt)
 {
   CORE_ADDR addr = bp_tgt->reqstd_address;
   struct remote_state *rs;
@@ -10083,10 +10349,10 @@ remote_insert_hw_breakpoint (struct target_ops *self, struct gdbarch *gdbarch,
   p += hexnumstr (p, (ULONGEST) addr);
   xsnprintf (p, endbuf - p, ",%x", bp_tgt->kind);
 
-  if (remote_supports_cond_breakpoints (self))
+  if (supports_evaluation_of_breakpoint_conditions ())
     remote_add_target_side_condition (gdbarch, bp_tgt, p, endbuf);
 
-  if (remote_can_run_breakpoint_commands (self))
+  if (can_run_breakpoint_commands ())
     remote_add_target_side_commands (gdbarch, bp_tgt, p);
 
   putpkt (rs->buf);
@@ -10112,9 +10378,9 @@ remote_insert_hw_breakpoint (struct target_ops *self, struct gdbarch *gdbarch,
 }
 
 
-static int
-remote_remove_hw_breakpoint (struct target_ops *self, struct gdbarch *gdbarch,
-			     struct bp_target_info *bp_tgt)
+int
+remote_target::remove_hw_breakpoint (struct gdbarch *gdbarch,
+				     struct bp_target_info *bp_tgt)
 {
   CORE_ADDR addr;
   struct remote_state *rs = get_remote_state ();
@@ -10154,9 +10420,8 @@ remote_remove_hw_breakpoint (struct target_ops *self, struct gdbarch *gdbarch,
 
 /* Verify memory using the "qCRC:" request.  */
 
-static int
-remote_verify_memory (struct target_ops *ops,
-		      const gdb_byte *data, CORE_ADDR lma, ULONGEST size)
+int
+remote_target::verify_memory (const gdb_byte *data, CORE_ADDR lma, ULONGEST size)
 {
   struct remote_state *rs = get_remote_state ();
   unsigned long host_crc, target_crc;
@@ -10195,7 +10460,7 @@ remote_verify_memory (struct target_ops *ops,
 	}
     }
 
-  return simple_verify_memory (ops, data, lma, size);
+  return simple_verify_memory (this, data, lma, size);
 }
 
 /* compare-sections command
@@ -10280,7 +10545,7 @@ the loaded file\n"));
    target is returned, or -1 for error.  */
 
 static enum target_xfer_status
-remote_write_qxfer (struct target_ops *ops, const char *object_name,
+remote_write_qxfer (const char *object_name,
                     const char *annex, const gdb_byte *writebuf, 
                     ULONGEST offset, LONGEST len, ULONGEST *xfered_len,
                     struct packet_config *packet)
@@ -10323,7 +10588,7 @@ remote_write_qxfer (struct target_ops *ops, const char *object_name,
    target supports this object.  */
 
 static enum target_xfer_status
-remote_read_qxfer (struct target_ops *ops, const char *object_name,
+remote_read_qxfer (const char *object_name,
 		   const char *annex,
 		   gdb_byte *readbuf, ULONGEST offset, LONGEST len,
 		   ULONGEST *xfered_len,
@@ -10403,11 +10668,11 @@ remote_read_qxfer (struct target_ops *ops, const char *object_name,
     }
 }
 
-static enum target_xfer_status
-remote_xfer_partial (struct target_ops *ops, enum target_object object,
-		     const char *annex, gdb_byte *readbuf,
-		     const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
-		     ULONGEST *xfered_len)
+enum target_xfer_status
+remote_target::xfer_partial (enum target_object object,
+			     const char *annex, gdb_byte *readbuf,
+			     const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
+			     ULONGEST *xfered_len)
 {
   struct remote_state *rs;
   int i;
@@ -10433,7 +10698,7 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
 	return remote_write_bytes (offset, writebuf, len, unit_size,
 				   xfered_len);
       else
-	return remote_read_bytes (ops, offset, readbuf, len, unit_size,
+	return remote_read_bytes (this, offset, readbuf, len, unit_size,
 				  xfered_len);
     }
 
@@ -10441,11 +10706,11 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
   if (object == TARGET_OBJECT_SPU)
     {
       if (readbuf)
-	return remote_read_qxfer (ops, "spu", annex, readbuf, offset, len,
+	return remote_read_qxfer ("spu", annex, readbuf, offset, len,
 				  xfered_len, &remote_protocol_packets
 				  [PACKET_qXfer_spu_read]);
       else
-	return remote_write_qxfer (ops, "spu", annex, writebuf, offset, len,
+	return remote_write_qxfer ("spu", annex, writebuf, offset, len,
 				   xfered_len, &remote_protocol_packets
 				   [PACKET_qXfer_spu_write]);
     }
@@ -10454,11 +10719,11 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
   if (object == TARGET_OBJECT_SIGNAL_INFO)
     {
       if (readbuf)
-	return remote_read_qxfer (ops, "siginfo", annex, readbuf, offset, len,
+	return remote_read_qxfer ("siginfo", annex, readbuf, offset, len,
 				  xfered_len, &remote_protocol_packets
 				  [PACKET_qXfer_siginfo_read]);
       else
-	return remote_write_qxfer (ops, "siginfo", annex,
+	return remote_write_qxfer ("siginfo", annex,
 				   writebuf, offset, len, xfered_len,
 				   &remote_protocol_packets
 				   [PACKET_qXfer_siginfo_write]);
@@ -10467,7 +10732,7 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
   if (object == TARGET_OBJECT_STATIC_TRACE_DATA)
     {
       if (readbuf)
-	return remote_read_qxfer (ops, "statictrace", annex,
+	return remote_read_qxfer ("statictrace", annex,
 				  readbuf, offset, len, xfered_len,
 				  &remote_protocol_packets
 				  [PACKET_qXfer_statictrace_read]);
@@ -10481,7 +10746,7 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
       switch (object)
 	{
 	case TARGET_OBJECT_FLASH:
-	  return remote_flash_write (ops, offset, len, xfered_len,
+	  return remote_flash_write (this, offset, len, xfered_len,
 				     writebuf);
 
 	default:
@@ -10499,28 +10764,28 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
 
     case TARGET_OBJECT_AUXV:
       gdb_assert (annex == NULL);
-      return remote_read_qxfer (ops, "auxv", annex, readbuf, offset, len,
+      return remote_read_qxfer ("auxv", annex, readbuf, offset, len,
 				xfered_len,
 				&remote_protocol_packets[PACKET_qXfer_auxv]);
 
     case TARGET_OBJECT_AVAILABLE_FEATURES:
       return remote_read_qxfer
-	(ops, "features", annex, readbuf, offset, len, xfered_len,
+	("features", annex, readbuf, offset, len, xfered_len,
 	 &remote_protocol_packets[PACKET_qXfer_features]);
 
     case TARGET_OBJECT_LIBRARIES:
       return remote_read_qxfer
-	(ops, "libraries", annex, readbuf, offset, len, xfered_len,
+	("libraries", annex, readbuf, offset, len, xfered_len,
 	 &remote_protocol_packets[PACKET_qXfer_libraries]);
 
     case TARGET_OBJECT_LIBRARIES_SVR4:
       return remote_read_qxfer
-	(ops, "libraries-svr4", annex, readbuf, offset, len, xfered_len,
+	("libraries-svr4", annex, readbuf, offset, len, xfered_len,
 	 &remote_protocol_packets[PACKET_qXfer_libraries_svr4]);
 
     case TARGET_OBJECT_MEMORY_MAP:
       gdb_assert (annex == NULL);
-      return remote_read_qxfer (ops, "memory-map", annex, readbuf, offset, len,
+      return remote_read_qxfer ("memory-map", annex, readbuf, offset, len,
 				 xfered_len,
 				&remote_protocol_packets[PACKET_qXfer_memory_map]);
 
@@ -10528,43 +10793,43 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
       /* Should only get here if we're connected.  */
       gdb_assert (rs->remote_desc);
       return remote_read_qxfer
-	(ops, "osdata", annex, readbuf, offset, len, xfered_len,
+	("osdata", annex, readbuf, offset, len, xfered_len,
         &remote_protocol_packets[PACKET_qXfer_osdata]);
 
     case TARGET_OBJECT_THREADS:
       gdb_assert (annex == NULL);
-      return remote_read_qxfer (ops, "threads", annex, readbuf, offset, len,
+      return remote_read_qxfer ("threads", annex, readbuf, offset, len,
 				xfered_len,
 				&remote_protocol_packets[PACKET_qXfer_threads]);
 
     case TARGET_OBJECT_TRACEFRAME_INFO:
       gdb_assert (annex == NULL);
       return remote_read_qxfer
-	(ops, "traceframe-info", annex, readbuf, offset, len, xfered_len,
+	("traceframe-info", annex, readbuf, offset, len, xfered_len,
 	 &remote_protocol_packets[PACKET_qXfer_traceframe_info]);
 
     case TARGET_OBJECT_FDPIC:
-      return remote_read_qxfer (ops, "fdpic", annex, readbuf, offset, len,
+      return remote_read_qxfer ("fdpic", annex, readbuf, offset, len,
 				xfered_len,
 				&remote_protocol_packets[PACKET_qXfer_fdpic]);
 
     case TARGET_OBJECT_OPENVMS_UIB:
-      return remote_read_qxfer (ops, "uib", annex, readbuf, offset, len,
+      return remote_read_qxfer ("uib", annex, readbuf, offset, len,
 				xfered_len,
 				&remote_protocol_packets[PACKET_qXfer_uib]);
 
     case TARGET_OBJECT_BTRACE:
-      return remote_read_qxfer (ops, "btrace", annex, readbuf, offset, len,
+      return remote_read_qxfer ("btrace", annex, readbuf, offset, len,
 				xfered_len,
         &remote_protocol_packets[PACKET_qXfer_btrace]);
 
     case TARGET_OBJECT_BTRACE_CONF:
-      return remote_read_qxfer (ops, "btrace-conf", annex, readbuf, offset,
+      return remote_read_qxfer ("btrace-conf", annex, readbuf, offset,
 				len, xfered_len,
 	&remote_protocol_packets[PACKET_qXfer_btrace_conf]);
 
     case TARGET_OBJECT_EXEC_FILE:
-      return remote_read_qxfer (ops, "exec-file", annex, readbuf, offset,
+      return remote_read_qxfer ("exec-file", annex, readbuf, offset,
 				len, xfered_len,
 	&remote_protocol_packets[PACKET_qXfer_exec_file]);
 
@@ -10618,17 +10883,16 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
 
 /* Implementation of to_get_memory_xfer_limit.  */
 
-static ULONGEST
-remote_get_memory_xfer_limit (struct target_ops *ops)
+ULONGEST
+remote_target::get_memory_xfer_limit ()
 {
   return get_memory_write_packet_size ();
 }
 
-static int
-remote_search_memory (struct target_ops* ops,
-		      CORE_ADDR start_addr, ULONGEST search_space_len,
-		      const gdb_byte *pattern, ULONGEST pattern_len,
-		      CORE_ADDR *found_addrp)
+int
+remote_target::search_memory (CORE_ADDR start_addr, ULONGEST search_space_len,
+			      const gdb_byte *pattern, ULONGEST pattern_len,
+			      CORE_ADDR *found_addrp)
 {
   int addr_size = gdbarch_addr_bit (target_gdbarch ()) / 8;
   struct remote_state *rs = get_remote_state ();
@@ -10663,7 +10927,7 @@ remote_search_memory (struct target_ops* ops,
     {
       /* Target doesn't provided special support, fall back and use the
 	 standard support (copy memory and do the search here).  */
-      return simple_search_memory (ops, start_addr, search_space_len,
+      return simple_search_memory (this, start_addr, search_space_len,
 				   pattern, pattern_len, found_addrp);
     }
 
@@ -10694,7 +10958,7 @@ remote_search_memory (struct target_ops* ops,
 	 supported.  If so, fall back to the simple way.  */
       if (packet_config_support (packet) == PACKET_DISABLE)
 	{
-	  return simple_search_memory (ops, start_addr, search_space_len,
+	  return simple_search_memory (this, start_addr, search_space_len,
 				       pattern, pattern_len, found_addrp);
 	}
       return -1;
@@ -10716,9 +10980,8 @@ remote_search_memory (struct target_ops* ops,
   return found;
 }
 
-static void
-remote_rcmd (struct target_ops *self, const char *command,
-	     struct ui_file *outbuf)
+void
+remote_target::rcmd (const char *command, struct ui_file *outbuf)
 {
   struct remote_state *rs = get_remote_state ();
   char *p = rs->buf;
@@ -10786,8 +11049,8 @@ remote_rcmd (struct target_ops *self, const char *command,
     }
 }
 
-static std::vector<mem_region>
-remote_memory_map (struct target_ops *ops)
+std::vector<mem_region>
+remote_target::memory_map ()
 {
   std::vector<mem_region> result;
   gdb::optional<gdb::char_vector> text
@@ -10972,8 +11235,8 @@ init_remote_threadtests (void)
 /* Convert a thread ID to a string.  Returns the string in a static
    buffer.  */
 
-static const char *
-remote_pid_to_str (struct target_ops *ops, ptid_t ptid)
+const char *
+remote_target::pid_to_str (ptid_t ptid)
 {
   static char buf[64];
   struct remote_state *rs = get_remote_state ();
@@ -11021,9 +11284,9 @@ remote_pid_to_str (struct target_ops *ops, ptid_t ptid)
 /* Get the address of the thread local variable in OBJFILE which is
    stored at OFFSET within the thread local storage for thread PTID.  */
 
-static CORE_ADDR
-remote_get_thread_local_address (struct target_ops *ops,
-				 ptid_t ptid, CORE_ADDR lm, CORE_ADDR offset)
+CORE_ADDR
+remote_target::get_thread_local_address (ptid_t ptid, CORE_ADDR lm,
+					 CORE_ADDR offset)
 {
   if (packet_support (PACKET_qGetTLSAddr) != PACKET_DISABLE)
     {
@@ -11069,8 +11332,8 @@ remote_get_thread_local_address (struct target_ops *ops,
 /* Provide thread local base, i.e. Thread Information Block address.
    Returns 1 if ptid is found and thread_local_base is non zero.  */
 
-static int
-remote_get_tib_address (struct target_ops *self, ptid_t ptid, CORE_ADDR *addr)
+int
+remote_target::get_tib_address (ptid_t ptid, CORE_ADDR *addr)
 {
   if (packet_support (PACKET_qGetTIBAddr) != PACKET_DISABLE)
     {
@@ -11176,8 +11439,8 @@ remote_read_description_p (struct target_ops *target)
   return 0;
 }
 
-static const struct target_desc *
-remote_read_description (struct target_ops *target)
+const struct target_desc *
+remote_target::read_description ()
 {
   struct remote_g_packet_data *data
     = ((struct remote_g_packet_data *)
@@ -11186,7 +11449,7 @@ remote_read_description (struct target_ops *target)
   /* Do not try this during initial connection, when we do not know
      whether there is a running but stopped thread.  */
   if (!target_has_execution || ptid_equal (inferior_ptid, null_ptid))
-    return target->beneath->to_read_description (target->beneath);
+    return beneath->read_description ();
 
   if (!VEC_empty (remote_g_packet_guess_s, data->guesses))
     {
@@ -11205,7 +11468,7 @@ remote_read_description (struct target_ops *target)
 	 an architecture, but it's too tricky to do safely.  */
     }
 
-  return target->beneath->to_read_description (target->beneath);
+  return beneath->read_description ();
 }
 
 /* Remote file transfer support.  This is host-initiated I/O, not
@@ -11509,6 +11772,15 @@ remote_hostio_open (struct target_ops *self,
 				     remote_errno, NULL, NULL);
 }
 
+int
+remote_target::fileio_open (struct inferior *inf, const char *filename,
+			    int flags, int mode, int warn_if_slow,
+			    int *remote_errno)
+{
+  return remote_hostio_open (this, inf, filename, flags, mode, warn_if_slow,
+			     remote_errno);
+}
+
 /* Implementation of to_fileio_pwrite.  */
 
 static int
@@ -11538,6 +11810,13 @@ remote_hostio_pwrite (struct target_ops *self,
 				     remote_errno, NULL, NULL);
 }
 
+int
+remote_target::fileio_pwrite (int fd, const gdb_byte *write_buf, int len,
+			      ULONGEST offset, int *remote_errno)
+{
+  return remote_hostio_pwrite (this, fd, write_buf, len, offset, remote_errno);
+}
+
 /* Helper for the implementation of to_fileio_pread.  Read the file
    from the remote side with vFile:pread.  */
 
@@ -11648,6 +11927,13 @@ remote_hostio_pread (struct target_ops *self,
   return remote_hostio_pread_from_cache (rs, fd, read_buf, len, offset);
 }
 
+int
+remote_target::fileio_pread (int fd, gdb_byte *read_buf, int len,
+			     ULONGEST offset, int *remote_errno)
+{
+  return remote_hostio_pread (this, fd, read_buf, len, offset, remote_errno);
+}
+
 /* Implementation of to_fileio_close.  */
 
 static int
@@ -11667,6 +11953,12 @@ remote_hostio_close (struct target_ops *self, int fd, int *remote_errno)
 				     remote_errno, NULL, NULL);
 }
 
+int
+remote_target::fileio_close (int fd, int *remote_errno)
+{
+  return remote_hostio_close (this, fd, remote_errno);
+}
+
 /* Implementation of to_fileio_unlink.  */
 
 static int
@@ -11690,12 +11982,18 @@ remote_hostio_unlink (struct target_ops *self,
 				     remote_errno, NULL, NULL);
 }
 
+int
+remote_target::fileio_unlink (struct inferior *inf, const char *filename,
+			      int *remote_errno)
+{
+  return remote_hostio_unlink (this, inf, filename, remote_errno);
+}
+
 /* Implementation of to_fileio_readlink.  */
 
-static gdb::optional<std::string>
-remote_hostio_readlink (struct target_ops *self,
-			struct inferior *inf, const char *filename,
-			int *remote_errno)
+gdb::optional<std::string>
+remote_target::fileio_readlink (struct inferior *inf, const char *filename,
+				int *remote_errno)
 {
   struct remote_state *rs = get_remote_state ();
   char *p = rs->buf;
@@ -11731,10 +12029,8 @@ remote_hostio_readlink (struct target_ops *self,
 
 /* Implementation of to_fileio_fstat.  */
 
-static int
-remote_hostio_fstat (struct target_ops *self,
-		     int fd, struct stat *st,
-		     int *remote_errno)
+int
+remote_target::fileio_fstat (int fd, struct stat *st, int *remote_errno)
 {
   struct remote_state *rs = get_remote_state ();
   char *p = rs->buf;
@@ -11791,8 +12087,8 @@ remote_hostio_fstat (struct target_ops *self,
 
 /* Implementation of to_filesystem_is_local.  */
 
-static int
-remote_filesystem_is_local (struct target_ops *self)
+int
+remote_target::filesystem_is_local ()
 {
   /* Valgrind GDB presents itself as a remote target but works
      on the local filesystem: it does not implement remote get
@@ -11811,12 +12107,12 @@ remote_filesystem_is_local (struct target_ops *self)
 	  /* Try opening a file to probe support.  The supplied
 	     filename is irrelevant, we only care about whether
 	     the stub recognizes the packet or not.  */
-	  fd = remote_hostio_open (self, NULL, "just probing",
+	  fd = remote_hostio_open (this, NULL, "just probing",
 				   FILEIO_O_RDONLY, 0700, 0,
 				   &remote_errno);
 
 	  if (fd >= 0)
-	    remote_hostio_close (self, fd, &remote_errno);
+	    remote_hostio_close (this, fd, &remote_errno);
 
 	  ps = packet_support (PACKET_vFile_open);
 	}
@@ -12122,8 +12418,8 @@ remote_command (const char *args, int from_tty)
   help_list (remote_cmdlist, "remote ", all_commands, gdb_stdout);
 }
 
-static int
-remote_can_execute_reverse (struct target_ops *self)
+int
+remote_target::can_execute_reverse ()
 {
   if (packet_support (PACKET_bs) == PACKET_ENABLE
       || packet_support (PACKET_bc) == PACKET_ENABLE)
@@ -12132,21 +12428,21 @@ remote_can_execute_reverse (struct target_ops *self)
     return 0;
 }
 
-static int
-remote_supports_non_stop (struct target_ops *self)
+int
+remote_target::supports_non_stop ()
 {
   return 1;
 }
 
-static int
-remote_supports_disable_randomization (struct target_ops *self)
+int
+remote_target::supports_disable_randomization ()
 {
   /* Only supported in extended mode.  */
   return 0;
 }
 
-static int
-remote_supports_multi_process (struct target_ops *self)
+int
+remote_target::supports_multi_process ()
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -12154,56 +12450,56 @@ remote_supports_multi_process (struct target_ops *self)
 }
 
 static int
-remote_supports_cond_tracepoints (void)
+remote_supports_cond_tracepoints ()
 {
   return packet_support (PACKET_ConditionalTracepoints) == PACKET_ENABLE;
 }
 
-static int
-remote_supports_cond_breakpoints (struct target_ops *self)
+int
+remote_target::supports_evaluation_of_breakpoint_conditions ()
 {
   return packet_support (PACKET_ConditionalBreakpoints) == PACKET_ENABLE;
 }
 
 static int
-remote_supports_fast_tracepoints (void)
+remote_supports_fast_tracepoints ()
 {
   return packet_support (PACKET_FastTracepoints) == PACKET_ENABLE;
 }
 
 static int
-remote_supports_static_tracepoints (void)
+remote_supports_static_tracepoints ()
 {
   return packet_support (PACKET_StaticTracepoints) == PACKET_ENABLE;
 }
 
 static int
-remote_supports_install_in_trace (void)
+remote_supports_install_in_trace ()
 {
   return packet_support (PACKET_InstallInTrace) == PACKET_ENABLE;
 }
 
-static int
-remote_supports_enable_disable_tracepoint (struct target_ops *self)
+int
+remote_target::supports_enable_disable_tracepoint ()
 {
   return (packet_support (PACKET_EnableDisableTracepoints_feature)
 	  == PACKET_ENABLE);
 }
 
-static int
-remote_supports_string_tracing (struct target_ops *self)
+int
+remote_target::supports_string_tracing ()
 {
   return packet_support (PACKET_tracenz_feature) == PACKET_ENABLE;
 }
 
-static int
-remote_can_run_breakpoint_commands (struct target_ops *self)
+int
+remote_target::can_run_breakpoint_commands ()
 {
   return packet_support (PACKET_BreakpointCommands) == PACKET_ENABLE;
 }
 
-static void
-remote_trace_init (struct target_ops *self)
+void
+remote_target::trace_init ()
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -12253,8 +12549,8 @@ remote_download_command_source (int num, ULONGEST addr,
     }
 }
 
-static void
-remote_download_tracepoint (struct target_ops *self, struct bp_location *loc)
+void
+remote_target::download_tracepoint (struct bp_location *loc)
 {
 #define BUF_SIZE 2048
 
@@ -12417,8 +12713,8 @@ remote_download_tracepoint (struct target_ops *self, struct bp_location *loc)
     }
 }
 
-static int
-remote_can_download_tracepoint (struct target_ops *self)
+int
+remote_target::can_download_tracepoint ()
 {
   struct remote_state *rs = get_remote_state ();
   struct trace_status *ts;
@@ -12431,7 +12727,7 @@ remote_can_download_tracepoint (struct target_ops *self)
     return 0;
 
   ts = current_trace_status ();
-  status = remote_get_trace_status (self, ts);
+  status = get_trace_status (ts);
 
   if (status == -1 || !ts->running_known || !ts->running)
     return 0;
@@ -12445,9 +12741,8 @@ remote_can_download_tracepoint (struct target_ops *self)
 }
 
 
-static void
-remote_download_trace_state_variable (struct target_ops *self,
-				      const trace_state_variable &tsv)
+void
+remote_target::download_trace_state_variable (const trace_state_variable &tsv)
 {
   struct remote_state *rs = get_remote_state ();
   char *p;
@@ -12468,9 +12763,8 @@ remote_download_trace_state_variable (struct target_ops *self,
     error (_("Error on target while downloading trace state variable."));
 }
 
-static void
-remote_enable_tracepoint (struct target_ops *self,
-			  struct bp_location *location)
+void
+remote_target::enable_tracepoint (struct bp_location *location)
 {
   struct remote_state *rs = get_remote_state ();
   char addr_buf[40];
@@ -12486,9 +12780,8 @@ remote_enable_tracepoint (struct target_ops *self,
     error (_("Error on target while enabling tracepoint."));
 }
 
-static void
-remote_disable_tracepoint (struct target_ops *self,
-			   struct bp_location *location)
+void
+remote_target::disable_tracepoint (struct bp_location *location)
 {
   struct remote_state *rs = get_remote_state ();
   char addr_buf[40];
@@ -12504,8 +12797,8 @@ remote_disable_tracepoint (struct target_ops *self,
     error (_("Error on target while disabling tracepoint."));
 }
 
-static void
-remote_trace_set_readonly_regions (struct target_ops *self)
+void
+remote_target::trace_set_readonly_regions ()
 {
   asection *s;
   bfd *abfd = NULL;
@@ -12555,8 +12848,8 @@ Too many sections for read-only sections definition packet."));
     }
 }
 
-static void
-remote_trace_start (struct target_ops *self)
+void
+remote_target::trace_start ()
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -12568,8 +12861,8 @@ remote_trace_start (struct target_ops *self)
     error (_("Bogus reply from target: %s"), rs->buf);
 }
 
-static int
-remote_get_trace_status (struct target_ops *self, struct trace_status *ts)
+int
+remote_target::get_trace_status (struct trace_status *ts)
 {
   /* Initialize it just to avoid a GCC false warning.  */
   char *p = NULL;
@@ -12620,9 +12913,9 @@ remote_get_trace_status (struct target_ops *self, struct trace_status *ts)
   return ts->running;
 }
 
-static void
-remote_get_tracepoint_status (struct target_ops *self, struct breakpoint *bp,
-			      struct uploaded_tp *utp)
+void
+remote_target::get_tracepoint_status (struct breakpoint *bp,
+				      struct uploaded_tp *utp)
 {
   struct remote_state *rs = get_remote_state ();
   char *reply;
@@ -12667,8 +12960,8 @@ remote_get_tracepoint_status (struct target_ops *self, struct breakpoint *bp,
     }
 }
 
-static void
-remote_trace_stop (struct target_ops *self)
+void
+remote_target::trace_stop ()
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -12680,11 +12973,10 @@ remote_trace_stop (struct target_ops *self)
     error (_("Bogus reply from target: %s"), rs->buf);
 }
 
-static int
-remote_trace_find (struct target_ops *self,
-		   enum trace_find_type type, int num,
-		   CORE_ADDR addr1, CORE_ADDR addr2,
-		   int *tpp)
+int
+remote_target::trace_find (enum trace_find_type type, int num,
+			   CORE_ADDR addr1, CORE_ADDR addr2,
+			   int *tpp)
 {
   struct remote_state *rs = get_remote_state ();
   char *endbuf = rs->buf + get_remote_packet_size ();
@@ -12763,9 +13055,8 @@ remote_trace_find (struct target_ops *self,
   return target_frameno;
 }
 
-static int
-remote_get_trace_state_variable_value (struct target_ops *self,
-				       int tsvnum, LONGEST *val)
+int
+remote_target::get_trace_state_variable_value (int tsvnum, LONGEST *val)
 {
   struct remote_state *rs = get_remote_state ();
   char *reply;
@@ -12788,8 +13079,8 @@ remote_get_trace_state_variable_value (struct target_ops *self,
   return 0;
 }
 
-static int
-remote_save_trace_data (struct target_ops *self, const char *filename)
+int
+remote_target::save_trace_data (const char *filename)
 {
   struct remote_state *rs = get_remote_state ();
   char *p, *reply;
@@ -12815,9 +13106,8 @@ remote_save_trace_data (struct target_ops *self, const char *filename)
    memory, plus we want to be able to ask for as much as possible, but
    not be unhappy if we don't get as much as we ask for.  */
 
-static LONGEST
-remote_get_raw_trace_data (struct target_ops *self,
-			   gdb_byte *buf, ULONGEST offset, LONGEST len)
+LONGEST
+remote_target::get_raw_trace_data (gdb_byte *buf, ULONGEST offset, LONGEST len)
 {
   struct remote_state *rs = get_remote_state ();
   char *reply;
@@ -12854,8 +13144,8 @@ remote_get_raw_trace_data (struct target_ops *self,
   return -1;
 }
 
-static void
-remote_set_disconnected_tracing (struct target_ops *self, int val)
+void
+remote_target::set_disconnected_tracing (int val)
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -12875,8 +13165,8 @@ remote_set_disconnected_tracing (struct target_ops *self, int val)
     warning (_("Target does not support disconnected tracing."));
 }
 
-static int
-remote_core_of_thread (struct target_ops *ops, ptid_t ptid)
+int
+remote_target::core_of_thread (ptid_t ptid)
 {
   struct thread_info *info = find_thread_ptid (ptid);
 
@@ -12886,8 +13176,8 @@ remote_core_of_thread (struct target_ops *ops, ptid_t ptid)
   return -1;
 }
 
-static void
-remote_set_circular_trace_buffer (struct target_ops *self, int val)
+void
+remote_target::set_circular_trace_buffer (int val)
 {
   struct remote_state *rs = get_remote_state ();
   char *reply;
@@ -12901,8 +13191,8 @@ remote_set_circular_trace_buffer (struct target_ops *self, int val)
     error (_("Bogus reply from target: %s"), reply);
 }
 
-static traceframe_info_up
-remote_traceframe_info (struct target_ops *self)
+traceframe_info_up
+remote_target::traceframe_info ()
 {
   gdb::optional<gdb::char_vector> text
     = target_read_stralloc (target_stack, TARGET_OBJECT_TRACEFRAME_INFO,
@@ -12918,8 +13208,8 @@ remote_traceframe_info (struct target_ops *self)
    if the packet is not supported, and 0 if the minimum instruction
    length is unknown.  */
 
-static int
-remote_get_min_fast_tracepoint_insn_len (struct target_ops *self)
+int
+remote_target::get_min_fast_tracepoint_insn_len ()
 {
   struct remote_state *rs = get_remote_state ();
   char *reply;
@@ -12947,8 +13237,8 @@ remote_get_min_fast_tracepoint_insn_len (struct target_ops *self)
     }
 }
 
-static void
-remote_set_trace_buffer_size (struct target_ops *self, LONGEST val)
+void
+remote_target::set_trace_buffer_size (LONGEST val)
 {
   if (packet_support (PACKET_QTBuffer_size) != PACKET_DISABLE)
     {
@@ -12978,10 +13268,9 @@ remote_set_trace_buffer_size (struct target_ops *self, LONGEST val)
     }
 }
 
-static int
-remote_set_trace_notes (struct target_ops *self,
-			const char *user, const char *notes,
-			const char *stop_notes)
+int
+remote_target::set_trace_notes (const char *user, const char *notes,
+				const char *stop_notes)
 {
   struct remote_state *rs = get_remote_state ();
   char *reply;
@@ -13025,8 +13314,8 @@ remote_set_trace_notes (struct target_ops *self,
   return 1;
 }
 
-static int
-remote_use_agent (struct target_ops *self, int use)
+int
+remote_target::use_agent (int use)
 {
   if (packet_support (PACKET_QAgent) != PACKET_DISABLE)
     {
@@ -13039,7 +13328,7 @@ remote_use_agent (struct target_ops *self, int use)
 
       if (strcmp (rs->buf, "OK") == 0)
 	{
-	  use_agent = use;
+	  ::use_agent = use;
 	  return 1;
 	}
     }
@@ -13047,8 +13336,8 @@ remote_use_agent (struct target_ops *self, int use)
   return 0;
 }
 
-static int
-remote_can_use_agent (struct target_ops *self)
+int
+remote_target::can_use_agent ()
 {
   return (packet_support (PACKET_QAgent) != PACKET_DISABLE);
 }
@@ -13197,9 +13486,8 @@ remote_btrace_maybe_reopen (void)
 
 /* Enable branch tracing.  */
 
-static struct btrace_target_info *
-remote_enable_btrace (struct target_ops *self, ptid_t ptid,
-		      const struct btrace_config *conf)
+struct btrace_target_info *
+remote_target::enable_btrace (ptid_t ptid, const struct btrace_config *conf)
 {
   struct btrace_target_info *tinfo = NULL;
   struct packet_config *packet = NULL;
@@ -13260,9 +13548,8 @@ remote_enable_btrace (struct target_ops *self, ptid_t ptid,
 
 /* Disable branch tracing.  */
 
-static void
-remote_disable_btrace (struct target_ops *self,
-		       struct btrace_target_info *tinfo)
+void
+remote_target::disable_btrace (struct btrace_target_info *tinfo)
 {
   struct packet_config *packet = &remote_protocol_packets[PACKET_Qbtrace_off];
   struct remote_state *rs = get_remote_state ();
@@ -13293,9 +13580,8 @@ remote_disable_btrace (struct target_ops *self,
 
 /* Teardown branch tracing.  */
 
-static void
-remote_teardown_btrace (struct target_ops *self,
-			struct btrace_target_info *tinfo)
+void
+remote_target::teardown_btrace (struct btrace_target_info *tinfo)
 {
   /* We must not talk to the target during teardown.  */
   xfree (tinfo);
@@ -13303,11 +13589,10 @@ remote_teardown_btrace (struct target_ops *self,
 
 /* Read the branch trace.  */
 
-static enum btrace_error
-remote_read_btrace (struct target_ops *self,
-		    struct btrace_data *btrace,
-		    struct btrace_target_info *tinfo,
-		    enum btrace_read_type type)
+enum btrace_error
+remote_target::read_btrace (struct btrace_data *btrace,
+			    struct btrace_target_info *tinfo,
+			    enum btrace_read_type type)
 {
   struct packet_config *packet = &remote_protocol_packets[PACKET_qXfer_btrace];
   const char *annex;
@@ -13346,15 +13631,14 @@ remote_read_btrace (struct target_ops *self,
   return BTRACE_ERR_NONE;
 }
 
-static const struct btrace_config *
-remote_btrace_conf (struct target_ops *self,
-		    const struct btrace_target_info *tinfo)
+const struct btrace_config *
+remote_target::btrace_conf (const struct btrace_target_info *tinfo)
 {
   return &tinfo->conf;
 }
 
-static int
-remote_augmented_libraries_svr4_read (struct target_ops *self)
+int
+remote_target::augmented_libraries_svr4_read ()
 {
   return (packet_support (PACKET_augmented_libraries_svr4_read_feature)
 	  == PACKET_ENABLE);
@@ -13362,8 +13646,8 @@ remote_augmented_libraries_svr4_read (struct target_ops *self)
 
 /* Implementation of to_load.  */
 
-static void
-remote_load (struct target_ops *self, const char *name, int from_tty)
+void
+remote_target::load (const char *name, int from_tty)
 {
   generic_load (name, from_tty);
 }
@@ -13372,8 +13656,8 @@ remote_load (struct target_ops *self, const char *name, int from_tty)
    can be opened on the remote side to get the symbols for the child
    process.  Returns NULL if the operation is not supported.  */
 
-static char *
-remote_pid_to_exec_file (struct target_ops *self, int pid)
+char *
+remote_target::pid_to_exec_file (int pid)
 {
   static gdb::optional<gdb::char_vector> filename;
   struct inferior *inf;
@@ -13403,8 +13687,8 @@ remote_pid_to_exec_file (struct target_ops *self, int pid)
 
 /* Implement the to_can_do_single_step target_ops method.  */
 
-static int
-remote_can_do_single_step (struct target_ops *ops)
+int
+remote_target::can_do_single_step ()
 {
   /* We can only tell whether target supports single step or not by
      supported s and S vCont actions if the stub supports vContSupported
@@ -13427,8 +13711,8 @@ remote_can_do_single_step (struct target_ops *ops)
 /* Implementation of the to_execution_direction method for the remote
    target.  */
 
-static enum exec_direction_kind
-remote_execution_direction (struct target_ops *self)
+enum exec_direction_kind
+remote_target::execution_direction ()
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -13438,11 +13722,10 @@ remote_execution_direction (struct target_ops *self)
 /* Return pointer to the thread_info struct which corresponds to
    THREAD_HANDLE (having length HANDLE_LEN).  */
 
-static struct thread_info *
-remote_thread_handle_to_thread_info (struct target_ops *ops,
-				     const gdb_byte *thread_handle,
-				     int handle_len,
-				     struct inferior *inf)
+thread_info *
+remote_target::thread_handle_to_thread_info (const gdb_byte *thread_handle,
+					     int handle_len,
+					     inferior *inf)
 {
   struct thread_info *tp;
 
@@ -13464,182 +13747,8 @@ remote_thread_handle_to_thread_info (struct target_ops *ops,
   return NULL;
 }
 
-static void
-init_remote_ops (void)
-{
-  remote_ops.to_shortname = "remote";
-  remote_ops.to_longname = "Remote serial target in gdb-specific protocol";
-  remote_ops.to_doc =
-    "Use a remote computer via a serial line, using a gdb-specific protocol.\n\
-Specify the serial device it is connected to\n\
-(e.g. /dev/ttyS0, /dev/ttya, COM1, etc.).";
-  remote_ops.to_open = remote_open;
-  remote_ops.to_close = remote_close;
-  remote_ops.to_detach = remote_detach;
-  remote_ops.to_disconnect = remote_disconnect;
-  remote_ops.to_resume = remote_resume;
-  remote_ops.to_commit_resume = remote_commit_resume;
-  remote_ops.to_wait = remote_wait;
-  remote_ops.to_fetch_registers = remote_fetch_registers;
-  remote_ops.to_store_registers = remote_store_registers;
-  remote_ops.to_prepare_to_store = remote_prepare_to_store;
-  remote_ops.to_files_info = remote_files_info;
-  remote_ops.to_insert_breakpoint = remote_insert_breakpoint;
-  remote_ops.to_remove_breakpoint = remote_remove_breakpoint;
-  remote_ops.to_stopped_by_sw_breakpoint = remote_stopped_by_sw_breakpoint;
-  remote_ops.to_supports_stopped_by_sw_breakpoint = remote_supports_stopped_by_sw_breakpoint;
-  remote_ops.to_stopped_by_hw_breakpoint = remote_stopped_by_hw_breakpoint;
-  remote_ops.to_supports_stopped_by_hw_breakpoint = remote_supports_stopped_by_hw_breakpoint;
-  remote_ops.to_stopped_by_watchpoint = remote_stopped_by_watchpoint;
-  remote_ops.to_stopped_data_address = remote_stopped_data_address;
-  remote_ops.to_watchpoint_addr_within_range =
-    remote_watchpoint_addr_within_range;
-  remote_ops.to_can_use_hw_breakpoint = remote_check_watch_resources;
-  remote_ops.to_insert_hw_breakpoint = remote_insert_hw_breakpoint;
-  remote_ops.to_remove_hw_breakpoint = remote_remove_hw_breakpoint;
-  remote_ops.to_region_ok_for_hw_watchpoint
-     = remote_region_ok_for_hw_watchpoint;
-  remote_ops.to_insert_watchpoint = remote_insert_watchpoint;
-  remote_ops.to_remove_watchpoint = remote_remove_watchpoint;
-  remote_ops.to_kill = remote_kill;
-  remote_ops.to_load = remote_load;
-  remote_ops.to_mourn_inferior = remote_mourn;
-  remote_ops.to_pass_signals = remote_pass_signals;
-  remote_ops.to_set_syscall_catchpoint = remote_set_syscall_catchpoint;
-  remote_ops.to_program_signals = remote_program_signals;
-  remote_ops.to_thread_alive = remote_thread_alive;
-  remote_ops.to_thread_name = remote_thread_name;
-  remote_ops.to_update_thread_list = remote_update_thread_list;
-  remote_ops.to_pid_to_str = remote_pid_to_str;
-  remote_ops.to_extra_thread_info = remote_threads_extra_info;
-  remote_ops.to_get_ada_task_ptid = remote_get_ada_task_ptid;
-  remote_ops.to_stop = remote_stop;
-  remote_ops.to_interrupt = remote_interrupt;
-  remote_ops.to_pass_ctrlc = remote_pass_ctrlc;
-  remote_ops.to_xfer_partial = remote_xfer_partial;
-  remote_ops.to_get_memory_xfer_limit = remote_get_memory_xfer_limit;
-  remote_ops.to_rcmd = remote_rcmd;
-  remote_ops.to_pid_to_exec_file = remote_pid_to_exec_file;
-  remote_ops.to_log_command = serial_log_command;
-  remote_ops.to_get_thread_local_address = remote_get_thread_local_address;
-  remote_ops.to_stratum = process_stratum;
-  remote_ops.to_has_all_memory = default_child_has_all_memory;
-  remote_ops.to_has_memory = default_child_has_memory;
-  remote_ops.to_has_stack = default_child_has_stack;
-  remote_ops.to_has_registers = default_child_has_registers;
-  remote_ops.to_has_execution = default_child_has_execution;
-  remote_ops.to_has_thread_control = tc_schedlock;    /* can lock scheduler */
-  remote_ops.to_can_execute_reverse = remote_can_execute_reverse;
-  remote_ops.to_magic = OPS_MAGIC;
-  remote_ops.to_memory_map = remote_memory_map;
-  remote_ops.to_flash_erase = remote_flash_erase;
-  remote_ops.to_flash_done = remote_flash_done;
-  remote_ops.to_read_description = remote_read_description;
-  remote_ops.to_search_memory = remote_search_memory;
-  remote_ops.to_can_async_p = remote_can_async_p;
-  remote_ops.to_is_async_p = remote_is_async_p;
-  remote_ops.to_async = remote_async;
-  remote_ops.to_thread_events = remote_thread_events;
-  remote_ops.to_can_do_single_step = remote_can_do_single_step;
-  remote_ops.to_terminal_inferior = remote_terminal_inferior;
-  remote_ops.to_terminal_ours = remote_terminal_ours;
-  remote_ops.to_supports_non_stop = remote_supports_non_stop;
-  remote_ops.to_supports_multi_process = remote_supports_multi_process;
-  remote_ops.to_supports_disable_randomization
-    = remote_supports_disable_randomization;
-  remote_ops.to_filesystem_is_local = remote_filesystem_is_local;
-  remote_ops.to_fileio_open = remote_hostio_open;
-  remote_ops.to_fileio_pwrite = remote_hostio_pwrite;
-  remote_ops.to_fileio_pread = remote_hostio_pread;
-  remote_ops.to_fileio_fstat = remote_hostio_fstat;
-  remote_ops.to_fileio_close = remote_hostio_close;
-  remote_ops.to_fileio_unlink = remote_hostio_unlink;
-  remote_ops.to_fileio_readlink = remote_hostio_readlink;
-  remote_ops.to_supports_enable_disable_tracepoint = remote_supports_enable_disable_tracepoint;
-  remote_ops.to_supports_string_tracing = remote_supports_string_tracing;
-  remote_ops.to_supports_evaluation_of_breakpoint_conditions = remote_supports_cond_breakpoints;
-  remote_ops.to_can_run_breakpoint_commands = remote_can_run_breakpoint_commands;
-  remote_ops.to_trace_init = remote_trace_init;
-  remote_ops.to_download_tracepoint = remote_download_tracepoint;
-  remote_ops.to_can_download_tracepoint = remote_can_download_tracepoint;
-  remote_ops.to_download_trace_state_variable
-    = remote_download_trace_state_variable;
-  remote_ops.to_enable_tracepoint = remote_enable_tracepoint;
-  remote_ops.to_disable_tracepoint = remote_disable_tracepoint;
-  remote_ops.to_trace_set_readonly_regions = remote_trace_set_readonly_regions;
-  remote_ops.to_trace_start = remote_trace_start;
-  remote_ops.to_get_trace_status = remote_get_trace_status;
-  remote_ops.to_get_tracepoint_status = remote_get_tracepoint_status;
-  remote_ops.to_trace_stop = remote_trace_stop;
-  remote_ops.to_trace_find = remote_trace_find;
-  remote_ops.to_get_trace_state_variable_value
-    = remote_get_trace_state_variable_value;
-  remote_ops.to_save_trace_data = remote_save_trace_data;
-  remote_ops.to_upload_tracepoints = remote_upload_tracepoints;
-  remote_ops.to_upload_trace_state_variables
-    = remote_upload_trace_state_variables;
-  remote_ops.to_get_raw_trace_data = remote_get_raw_trace_data;
-  remote_ops.to_get_min_fast_tracepoint_insn_len = remote_get_min_fast_tracepoint_insn_len;
-  remote_ops.to_set_disconnected_tracing = remote_set_disconnected_tracing;
-  remote_ops.to_set_circular_trace_buffer = remote_set_circular_trace_buffer;
-  remote_ops.to_set_trace_buffer_size = remote_set_trace_buffer_size;
-  remote_ops.to_set_trace_notes = remote_set_trace_notes;
-  remote_ops.to_core_of_thread = remote_core_of_thread;
-  remote_ops.to_verify_memory = remote_verify_memory;
-  remote_ops.to_get_tib_address = remote_get_tib_address;
-  remote_ops.to_set_permissions = remote_set_permissions;
-  remote_ops.to_static_tracepoint_marker_at
-    = remote_static_tracepoint_marker_at;
-  remote_ops.to_static_tracepoint_markers_by_strid
-    = remote_static_tracepoint_markers_by_strid;
-  remote_ops.to_traceframe_info = remote_traceframe_info;
-  remote_ops.to_use_agent = remote_use_agent;
-  remote_ops.to_can_use_agent = remote_can_use_agent;
-  remote_ops.to_enable_btrace = remote_enable_btrace;
-  remote_ops.to_disable_btrace = remote_disable_btrace;
-  remote_ops.to_teardown_btrace = remote_teardown_btrace;
-  remote_ops.to_read_btrace = remote_read_btrace;
-  remote_ops.to_btrace_conf = remote_btrace_conf;
-  remote_ops.to_augmented_libraries_svr4_read =
-    remote_augmented_libraries_svr4_read;
-  remote_ops.to_follow_fork = remote_follow_fork;
-  remote_ops.to_follow_exec = remote_follow_exec;
-  remote_ops.to_insert_fork_catchpoint = remote_insert_fork_catchpoint;
-  remote_ops.to_remove_fork_catchpoint = remote_remove_fork_catchpoint;
-  remote_ops.to_insert_vfork_catchpoint = remote_insert_vfork_catchpoint;
-  remote_ops.to_remove_vfork_catchpoint = remote_remove_vfork_catchpoint;
-  remote_ops.to_insert_exec_catchpoint = remote_insert_exec_catchpoint;
-  remote_ops.to_remove_exec_catchpoint = remote_remove_exec_catchpoint;
-  remote_ops.to_execution_direction = remote_execution_direction;
-  remote_ops.to_thread_handle_to_thread_info =
-    remote_thread_handle_to_thread_info;
-}
-
-/* Set up the extended remote vector by making a copy of the standard
-   remote vector and adding to it.  */
-
-static void
-init_extended_remote_ops (void)
-{
-  extended_remote_ops = remote_ops;
-
-  extended_remote_ops.to_shortname = "extended-remote";
-  extended_remote_ops.to_longname =
-    "Extended remote serial target in gdb-specific protocol";
-  extended_remote_ops.to_doc =
-    "Use a remote computer via a serial line, using a gdb-specific protocol.\n\
-Specify the serial device it is connected to (e.g. /dev/ttya).";
-  extended_remote_ops.to_open = extended_remote_open;
-  extended_remote_ops.to_create_inferior = extended_remote_create_inferior;
-  extended_remote_ops.to_detach = extended_remote_detach;
-  extended_remote_ops.to_attach = extended_remote_attach;
-  extended_remote_ops.to_post_attach = extended_remote_post_attach;
-  extended_remote_ops.to_supports_disable_randomization
-    = extended_remote_supports_disable_randomization;
-}
-
-static int
-remote_can_async_p (struct target_ops *ops)
+int
+remote_target::can_async_p ()
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -13652,8 +13761,8 @@ remote_can_async_p (struct target_ops *ops)
   return serial_can_async_p (rs->remote_desc);
 }
 
-static int
-remote_is_async_p (struct target_ops *ops)
+int
+remote_target::is_async_p ()
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -13685,8 +13794,8 @@ remote_async_inferior_event_handler (gdb_client_data data)
   inferior_event_handler (INF_REG_EVENT, NULL);
 }
 
-static void
-remote_async (struct target_ops *ops, int enable)
+void
+remote_target::async (int enable)
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -13720,8 +13829,8 @@ remote_async (struct target_ops *ops, int enable)
 
 /* Implementation of the to_thread_events method.  */
 
-static void
-remote_thread_events (struct target_ops *ops, int enable)
+void
+remote_target::thread_events (int enable)
 {
   struct remote_state *rs = get_remote_state ();
   size_t size = get_remote_packet_size ();
@@ -13799,8 +13908,8 @@ remote_new_objfile (struct objfile *objfile)
    tracepoints yet, we don't want to mess up the user's existing
    collection.  */
   
-static int
-remote_upload_tracepoints (struct target_ops *self, struct uploaded_tp **utpp)
+int
+remote_target::upload_tracepoints (struct uploaded_tp **utpp)
 {
   struct remote_state *rs = get_remote_state ();
   char *p;
@@ -13820,9 +13929,8 @@ remote_upload_tracepoints (struct target_ops *self, struct uploaded_tp **utpp)
   return 0;
 }
 
-static int
-remote_upload_trace_state_variables (struct target_ops *self,
-				     struct uploaded_tsv **utsvp)
+int
+remote_target::upload_trace_state_variables (struct uploaded_tsv **utsvp)
 {
   struct remote_state *rs = get_remote_state ();
   char *p;
@@ -13901,10 +14009,7 @@ _initialize_remote (void)
      time.  */
   remote_state = new_remote_state ();
 
-  init_remote_ops ();
   add_target (&remote_ops);
-
-  init_extended_remote_ops ();
   add_target (&extended_remote_ops);
 
   /* Hook into new objfile notification.  */
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 10/40] target_ops/C++: record targets
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (30 preceding siblings ...)
  2018-04-14 19:19 ` [PATCH 16/40] target_ops/C++: Windows targets Pedro Alves
@ 2018-04-14 19:20 ` Pedro Alves
  2018-04-14 19:20 ` [PATCH 11/40] target_ops/C++: remote/extended-remote targets Pedro Alves
                   ` (9 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:20 UTC (permalink / raw)
  To: gdb-patches

Straighforward conversion.
---
 gdb/record-btrace.c | 557 ++++++++++++++++++++++++------------------------
 gdb/record-full.c   | 596 +++++++++++++++++++++++++++-------------------------
 gdb/record.c        |  18 +-
 3 files changed, 598 insertions(+), 573 deletions(-)

diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
index 7264b8ed2b..cce188e71a 100644
--- a/gdb/record-btrace.c
+++ b/gdb/record-btrace.c
@@ -42,7 +42,105 @@
 #include <algorithm>
 
 /* The target_ops of record-btrace.  */
-static struct target_ops record_btrace_ops;
+
+class record_btrace_target final : public target_ops
+{
+public:
+  record_btrace_target ()
+  { to_stratum = record_stratum; }
+
+  const char *shortname () override
+  { return "record-btrace"; }
+
+  const char *longname () override
+  { return _("Branch tracing target"); }
+
+  const char *doc () override
+  { return _("Collect control-flow trace and provide the execution history."); }
+
+  void open (const char *, int) override;
+  void close () override;
+  void async (int) override;
+
+  void detach (inferior *inf, int from_tty) override
+  { record_detach (this, inf, from_tty); }
+
+  void disconnect (const char *, int) override;
+
+  void mourn_inferior () override
+  { record_mourn_inferior (this); }
+
+  void kill () override
+  { record_kill (this); }
+
+  enum record_method record_method (ptid_t ptid) override;
+
+  void stop_recording () override;
+  void info_record () override;
+
+  void insn_history (int size, gdb_disassembly_flags flags) override;
+  void insn_history_from (ULONGEST from, int size,
+			  gdb_disassembly_flags flags) override;
+  void insn_history_range (ULONGEST begin, ULONGEST end,
+			   gdb_disassembly_flags flags) override;
+  void call_history (int size, record_print_flags flags) override;
+  void call_history_from (ULONGEST begin, int size, record_print_flags flags)
+    override;
+  void call_history_range (ULONGEST begin, ULONGEST end, record_print_flags flags)
+    override;
+
+  int record_is_replaying (ptid_t ptid) override;
+  int record_will_replay (ptid_t ptid, int dir) override;
+  void record_stop_replaying () override;
+
+  enum target_xfer_status xfer_partial (enum target_object object,
+					const char *annex,
+					gdb_byte *readbuf,
+					const gdb_byte *writebuf,
+					ULONGEST offset, ULONGEST len,
+					ULONGEST *xfered_len) override;
+
+  int insert_breakpoint (struct gdbarch *,
+			 struct bp_target_info *) override;
+  int remove_breakpoint (struct gdbarch *, struct bp_target_info *,
+			 enum remove_bp_reason) override;
+
+  void fetch_registers (struct regcache *, int) override;
+
+  void store_registers (struct regcache *, int) override;
+  void prepare_to_store (struct regcache *) override;
+
+  const struct frame_unwind *get_unwinder () override;
+
+  const struct frame_unwind *get_tailcall_unwinder () override;
+
+  void commit_resume () override;
+  void resume (ptid_t, int, enum gdb_signal) override;
+  ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
+
+  void stop (ptid_t) override;
+  void update_thread_list () override;
+  int thread_alive (ptid_t ptid) override;
+  void goto_record_begin () override;
+  void goto_record_end () override;
+  void goto_record (ULONGEST insn) override;
+
+  int can_execute_reverse () override;
+
+  int stopped_by_sw_breakpoint () override;
+  int supports_stopped_by_sw_breakpoint () override;
+
+  int stopped_by_hw_breakpoint () override;
+  int supports_stopped_by_hw_breakpoint () override;
+
+  enum exec_direction_kind execution_direction () override;
+  void prepare_to_generate_core () override;
+  void done_generating_core () override;
+};
+
+static record_btrace_target record_btrace_ops;
+
+/* Initialize the record-btrace target ops.  */
 
 /* Token associated with a new-thread observer enabling branch tracing
    for the new thread.  */
@@ -237,10 +335,10 @@ private:
   std::forward_list<thread_info *> m_threads;
 };
 
-/* The to_open method of target record-btrace.  */
+/* The open method of target record-btrace.  */
 
-static void
-record_btrace_open (const char *args, int from_tty)
+void
+record_btrace_target::open (const char *args, int from_tty)
 {
   /* If we fail to enable btrace for one thread, disable it for the threads for
      which it was successfully enabled.  */
@@ -267,10 +365,10 @@ record_btrace_open (const char *args, int from_tty)
   btrace_disable.discard ();
 }
 
-/* The to_stop_recording method of target record-btrace.  */
+/* The stop_recording method of target record-btrace.  */
 
-static void
-record_btrace_stop_recording (struct target_ops *self)
+void
+record_btrace_target::stop_recording ()
 {
   struct thread_info *tp;
 
@@ -283,25 +381,25 @@ record_btrace_stop_recording (struct target_ops *self)
       btrace_disable (tp);
 }
 
-/* The to_disconnect method of target record-btrace.  */
+/* The disconnect method of target record-btrace.  */
 
-static void
-record_btrace_disconnect (struct target_ops *self, const char *args,
-			  int from_tty)
+void
+record_btrace_target::disconnect (const char *args,
+				  int from_tty)
 {
-  struct target_ops *beneath = self->beneath;
+  struct target_ops *beneath = this->beneath;
 
   /* Do not stop recording, just clean up GDB side.  */
-  unpush_target (self);
+  unpush_target (this);
 
   /* Forward disconnect.  */
-  beneath->to_disconnect (beneath, args, from_tty);
+  beneath->disconnect (args, from_tty);
 }
 
-/* The to_close method of target record-btrace.  */
+/* The close method of target record-btrace.  */
 
-static void
-record_btrace_close (struct target_ops *self)
+void
+record_btrace_target::close ()
 {
   struct thread_info *tp;
 
@@ -318,17 +416,17 @@ record_btrace_close (struct target_ops *self)
     btrace_teardown (tp);
 }
 
-/* The to_async method of target record-btrace.  */
+/* The async method of target record-btrace.  */
 
-static void
-record_btrace_async (struct target_ops *ops, int enable)
+void
+record_btrace_target::async (int enable)
 {
   if (enable)
     mark_async_event_handler (record_btrace_async_inferior_event_handler);
   else
     clear_async_event_handler (record_btrace_async_inferior_event_handler);
 
-  ops->beneath->to_async (ops->beneath, enable);
+  this->beneath->async (enable);
 }
 
 /* Adjusts the size and returns a human readable size suffix.  */
@@ -416,10 +514,10 @@ record_btrace_print_conf (const struct btrace_config *conf)
   internal_error (__FILE__, __LINE__, _("Unkown branch trace format."));
 }
 
-/* The to_info_record method of target record-btrace.  */
+/* The info_record method of target record-btrace.  */
 
-static void
-record_btrace_info (struct target_ops *self)
+void
+record_btrace_target::info_record ()
 {
   struct btrace_thread_info *btinfo;
   const struct btrace_config *conf;
@@ -436,7 +534,7 @@ record_btrace_info (struct target_ops *self)
 
   btinfo = &tp->btrace;
 
-  conf = btrace_conf (btinfo);
+  conf = ::btrace_conf (btinfo);
   if (conf != NULL)
     record_btrace_print_conf (conf);
 
@@ -725,11 +823,10 @@ btrace_insn_history (struct ui_out *uiout,
     }
 }
 
-/* The to_insn_history method of target record-btrace.  */
+/* The insn_history method of target record-btrace.  */
 
-static void
-record_btrace_insn_history (struct target_ops *self, int size,
-			    gdb_disassembly_flags flags)
+void
+record_btrace_target::insn_history (int size, gdb_disassembly_flags flags)
 {
   struct btrace_thread_info *btinfo;
   struct btrace_insn_history *history;
@@ -809,12 +906,11 @@ record_btrace_insn_history (struct target_ops *self, int size,
   btrace_set_insn_history (btinfo, &begin, &end);
 }
 
-/* The to_insn_history_range method of target record-btrace.  */
+/* The insn_history_range method of target record-btrace.  */
 
-static void
-record_btrace_insn_history_range (struct target_ops *self,
-				  ULONGEST from, ULONGEST to,
-				  gdb_disassembly_flags flags)
+void
+record_btrace_target::insn_history_range (ULONGEST from, ULONGEST to,
+					  gdb_disassembly_flags flags)
 {
   struct btrace_thread_info *btinfo;
   struct btrace_insn_iterator begin, end;
@@ -858,12 +954,11 @@ record_btrace_insn_history_range (struct target_ops *self,
   btrace_set_insn_history (btinfo, &begin, &end);
 }
 
-/* The to_insn_history_from method of target record-btrace.  */
+/* The insn_history_from method of target record-btrace.  */
 
-static void
-record_btrace_insn_history_from (struct target_ops *self,
-				 ULONGEST from, int size,
-				 gdb_disassembly_flags flags)
+void
+record_btrace_target::insn_history_from (ULONGEST from, int size,
+					 gdb_disassembly_flags flags)
 {
   ULONGEST begin, end, context;
 
@@ -890,7 +985,7 @@ record_btrace_insn_history_from (struct target_ops *self,
 	end = ULONGEST_MAX;
     }
 
-  record_btrace_insn_history_range (self, begin, end, flags);
+  insn_history_range (begin, end, flags);
 }
 
 /* Print the instruction number range for a function call history line.  */
@@ -1078,11 +1173,10 @@ btrace_call_history (struct ui_out *uiout,
     }
 }
 
-/* The to_call_history method of target record-btrace.  */
+/* The call_history method of target record-btrace.  */
 
-static void
-record_btrace_call_history (struct target_ops *self, int size,
-			    record_print_flags flags)
+void
+record_btrace_target::call_history (int size, record_print_flags flags)
 {
   struct btrace_thread_info *btinfo;
   struct btrace_call_history *history;
@@ -1165,12 +1259,11 @@ record_btrace_call_history (struct target_ops *self, int size,
   btrace_set_call_history (btinfo, &begin, &end);
 }
 
-/* The to_call_history_range method of target record-btrace.  */
+/* The call_history_range method of target record-btrace.  */
 
-static void
-record_btrace_call_history_range (struct target_ops *self,
-				  ULONGEST from, ULONGEST to,
-				  record_print_flags flags)
+void
+record_btrace_target::call_history_range (ULONGEST from, ULONGEST to,
+					  record_print_flags flags)
 {
   struct btrace_thread_info *btinfo;
   struct btrace_call_iterator begin, end;
@@ -1214,12 +1307,11 @@ record_btrace_call_history_range (struct target_ops *self,
   btrace_set_call_history (btinfo, &begin, &end);
 }
 
-/* The to_call_history_from method of target record-btrace.  */
+/* The call_history_from method of target record-btrace.  */
 
-static void
-record_btrace_call_history_from (struct target_ops *self,
-				 ULONGEST from, int size,
-				 record_print_flags flags)
+void
+record_btrace_target::call_history_from (ULONGEST from, int size,
+					 record_print_flags flags)
 {
   ULONGEST begin, end, context;
 
@@ -1246,13 +1338,13 @@ record_btrace_call_history_from (struct target_ops *self,
 	end = ULONGEST_MAX;
     }
 
-  record_btrace_call_history_range (self, begin, end, flags);
+  call_history_range ( begin, end, flags);
 }
 
-/* The to_record_method method of target record-btrace.  */
+/* The record_method method of target record-btrace.  */
 
-static enum record_method
-record_btrace_record_method (struct target_ops *self, ptid_t ptid)
+enum record_method
+record_btrace_target::record_method (ptid_t ptid)
 {
   struct thread_info * const tp = find_thread_ptid (ptid);
 
@@ -1265,10 +1357,10 @@ record_btrace_record_method (struct target_ops *self, ptid_t ptid)
   return RECORD_METHOD_BTRACE;
 }
 
-/* The to_record_is_replaying method of target record-btrace.  */
+/* The record_is_replaying method of target record-btrace.  */
 
-static int
-record_btrace_is_replaying (struct target_ops *self, ptid_t ptid)
+int
+record_btrace_target::record_is_replaying (ptid_t ptid)
 {
   struct thread_info *tp;
 
@@ -1279,26 +1371,26 @@ record_btrace_is_replaying (struct target_ops *self, ptid_t ptid)
   return 0;
 }
 
-/* The to_record_will_replay method of target record-btrace.  */
+/* The record_will_replay method of target record-btrace.  */
 
-static int
-record_btrace_will_replay (struct target_ops *self, ptid_t ptid, int dir)
+int
+record_btrace_target::record_will_replay (ptid_t ptid, int dir)
 {
-  return dir == EXEC_REVERSE || record_btrace_is_replaying (self, ptid);
+  return dir == EXEC_REVERSE || record_is_replaying (ptid);
 }
 
-/* The to_xfer_partial method of target record-btrace.  */
+/* The xfer_partial method of target record-btrace.  */
 
-static enum target_xfer_status
-record_btrace_xfer_partial (struct target_ops *ops, enum target_object object,
-			    const char *annex, gdb_byte *readbuf,
-			    const gdb_byte *writebuf, ULONGEST offset,
-			    ULONGEST len, ULONGEST *xfered_len)
+enum target_xfer_status
+record_btrace_target::xfer_partial (enum target_object object,
+				    const char *annex, gdb_byte *readbuf,
+				    const gdb_byte *writebuf, ULONGEST offset,
+				    ULONGEST len, ULONGEST *xfered_len)
 {
   /* Filter out requests that don't make sense during replay.  */
   if (replay_memory_access == replay_memory_access_read_only
       && !record_btrace_generating_corefile
-      && record_btrace_is_replaying (ops, inferior_ptid))
+      && record_is_replaying (inferior_ptid))
     {
       switch (object)
 	{
@@ -1314,7 +1406,7 @@ record_btrace_xfer_partial (struct target_ops *ops, enum target_object object,
 	      }
 
 	    /* We allow reading readonly memory.  */
-	    section = target_section_by_addr (ops, offset);
+	    section = target_section_by_addr (this, offset);
 	    if (section != NULL)
 	      {
 		/* Check if the section we found is readonly.  */
@@ -1335,17 +1427,15 @@ record_btrace_xfer_partial (struct target_ops *ops, enum target_object object,
     }
 
   /* Forward the request.  */
-  ops = ops->beneath;
-  return ops->to_xfer_partial (ops, object, annex, readbuf, writebuf,
-			       offset, len, xfered_len);
+  return this->beneath->xfer_partial (object, annex, readbuf, writebuf,
+				      offset, len, xfered_len);
 }
 
-/* The to_insert_breakpoint method of target record-btrace.  */
+/* The insert_breakpoint method of target record-btrace.  */
 
-static int
-record_btrace_insert_breakpoint (struct target_ops *ops,
-				 struct gdbarch *gdbarch,
-				 struct bp_target_info *bp_tgt)
+int
+record_btrace_target::insert_breakpoint (struct gdbarch *gdbarch,
+					 struct bp_target_info *bp_tgt)
 {
   const char *old;
   int ret;
@@ -1358,7 +1448,7 @@ record_btrace_insert_breakpoint (struct target_ops *ops,
   ret = 0;
   TRY
     {
-      ret = ops->beneath->to_insert_breakpoint (ops->beneath, gdbarch, bp_tgt);
+      ret = this->beneath->insert_breakpoint (gdbarch, bp_tgt);
     }
   CATCH (except, RETURN_MASK_ALL)
     {
@@ -1371,13 +1461,12 @@ record_btrace_insert_breakpoint (struct target_ops *ops,
   return ret;
 }
 
-/* The to_remove_breakpoint method of target record-btrace.  */
+/* The remove_breakpoint method of target record-btrace.  */
 
-static int
-record_btrace_remove_breakpoint (struct target_ops *ops,
-				 struct gdbarch *gdbarch,
-				 struct bp_target_info *bp_tgt,
-				 enum remove_bp_reason reason)
+int
+record_btrace_target::remove_breakpoint (struct gdbarch *gdbarch,
+					 struct bp_target_info *bp_tgt,
+					 enum remove_bp_reason reason)
 {
   const char *old;
   int ret;
@@ -1390,8 +1479,7 @@ record_btrace_remove_breakpoint (struct target_ops *ops,
   ret = 0;
   TRY
     {
-      ret = ops->beneath->to_remove_breakpoint (ops->beneath, gdbarch, bp_tgt,
-						reason);
+      ret = this->beneath->remove_breakpoint (gdbarch, bp_tgt, reason);
     }
   CATCH (except, RETURN_MASK_ALL)
     {
@@ -1404,11 +1492,10 @@ record_btrace_remove_breakpoint (struct target_ops *ops,
   return ret;
 }
 
-/* The to_fetch_registers method of target record-btrace.  */
+/* The fetch_registers method of target record-btrace.  */
 
-static void
-record_btrace_fetch_registers (struct target_ops *ops,
-			       struct regcache *regcache, int regno)
+void
+record_btrace_target::fetch_registers (struct regcache *regcache, int regno)
 {
   struct btrace_insn_iterator *replay;
   struct thread_info *tp;
@@ -1438,45 +1525,35 @@ record_btrace_fetch_registers (struct target_ops *ops,
       regcache_raw_supply (regcache, regno, &insn->pc);
     }
   else
-    {
-      struct target_ops *t = ops->beneath;
-
-      t->to_fetch_registers (t, regcache, regno);
-    }
+    this->beneath->fetch_registers (regcache, regno);
 }
 
-/* The to_store_registers method of target record-btrace.  */
+/* The store_registers method of target record-btrace.  */
 
-static void
-record_btrace_store_registers (struct target_ops *ops,
-			       struct regcache *regcache, int regno)
+void
+record_btrace_target::store_registers (struct regcache *regcache, int regno)
 {
   struct target_ops *t;
 
   if (!record_btrace_generating_corefile
-      && record_btrace_is_replaying (ops, regcache_get_ptid (regcache)))
+      && record_is_replaying (regcache_get_ptid (regcache)))
     error (_("Cannot write registers while replaying."));
 
   gdb_assert (may_write_registers != 0);
 
-  t = ops->beneath;
-  t->to_store_registers (t, regcache, regno);
+  this->beneath->store_registers (regcache, regno);
 }
 
-/* The to_prepare_to_store method of target record-btrace.  */
+/* The prepare_to_store method of target record-btrace.  */
 
-static void
-record_btrace_prepare_to_store (struct target_ops *ops,
-				struct regcache *regcache)
+void
+record_btrace_target::prepare_to_store (struct regcache *regcache)
 {
-  struct target_ops *t;
-
   if (!record_btrace_generating_corefile
-      && record_btrace_is_replaying (ops, regcache_get_ptid (regcache)))
+      && record_is_replaying (regcache_get_ptid (regcache)))
     return;
 
-  t = ops->beneath;
-  t->to_prepare_to_store (t, regcache);
+  this->beneath->prepare_to_store (regcache);
 }
 
 /* The branch trace frame cache.  */
@@ -1792,18 +1869,18 @@ const struct frame_unwind record_btrace_tailcall_frame_unwind =
   record_btrace_frame_dealloc_cache
 };
 
-/* Implement the to_get_unwinder method.  */
+/* Implement the get_unwinder method.  */
 
-static const struct frame_unwind *
-record_btrace_to_get_unwinder (struct target_ops *self)
+const struct frame_unwind *
+record_btrace_target::get_unwinder ()
 {
   return &record_btrace_frame_unwind;
 }
 
-/* Implement the to_get_tailcall_unwinder method.  */
+/* Implement the get_tailcall_unwinder method.  */
 
-static const struct frame_unwind *
-record_btrace_to_get_tailcall_unwinder (struct target_ops *self)
+const struct frame_unwind *
+record_btrace_target::get_tailcall_unwinder ()
 {
   return &record_btrace_tailcall_frame_unwind;
 }
@@ -1872,7 +1949,7 @@ get_thread_current_frame (struct thread_info *tp)
      We are not actually running, yet.  We just started a reverse execution
      command or a record goto command.
      For the latter, EXECUTING is false and this has no effect.
-     For the former, EXECUTING is true and we're in to_wait, about to
+     For the former, EXECUTING is true and we're in wait, about to
      move the thread.  Since we need to recompute the stack, we temporarily
      set EXECUTING to flase.  */
   executing = is_executing (inferior_ptid);
@@ -2022,40 +2099,38 @@ record_btrace_stop_replaying_at_end (struct thread_info *tp)
     record_btrace_stop_replaying (tp);
 }
 
-/* The to_resume method of target record-btrace.  */
+/* The resume method of target record-btrace.  */
 
-static void
-record_btrace_resume (struct target_ops *ops, ptid_t ptid, int step,
-		      enum gdb_signal signal)
+void
+record_btrace_target::resume (ptid_t ptid, int step, enum gdb_signal signal)
 {
   struct thread_info *tp;
   enum btrace_thread_flag flag, cflag;
 
   DEBUG ("resume %s: %s%s", target_pid_to_str (ptid),
-	 execution_direction == EXEC_REVERSE ? "reverse-" : "",
+	 ::execution_direction == EXEC_REVERSE ? "reverse-" : "",
 	 step ? "step" : "cont");
 
   /* Store the execution direction of the last resume.
 
-     If there is more than one to_resume call, we have to rely on infrun
+     If there is more than one resume call, we have to rely on infrun
      to not change the execution direction in-between.  */
-  record_btrace_resume_exec_dir = execution_direction;
+  record_btrace_resume_exec_dir = ::execution_direction;
 
   /* As long as we're not replaying, just forward the request.
 
      For non-stop targets this means that no thread is replaying.  In order to
      make progress, we may need to explicitly move replaying threads to the end
      of their execution history.  */
-  if ((execution_direction != EXEC_REVERSE)
-      && !record_btrace_is_replaying (ops, minus_one_ptid))
+  if ((::execution_direction != EXEC_REVERSE)
+      && !record_is_replaying (minus_one_ptid))
     {
-      ops = ops->beneath;
-      ops->to_resume (ops, ptid, step, signal);
+      this->beneath->resume (ptid, step, signal);
       return;
     }
 
   /* Compute the btrace thread flag for the requested move.  */
-  if (execution_direction == EXEC_REVERSE)
+  if (::execution_direction == EXEC_REVERSE)
     {
       flag = step == 0 ? BTHR_RCONT : BTHR_RSTEP;
       cflag = BTHR_RCONT;
@@ -2098,14 +2173,14 @@ record_btrace_resume (struct target_ops *ops, ptid_t ptid, int step,
     }
 }
 
-/* The to_commit_resume method of target record-btrace.  */
+/* The commit_resume method of target record-btrace.  */
 
-static void
-record_btrace_commit_resume (struct target_ops *ops)
+void
+record_btrace_target::commit_resume ()
 {
-  if ((execution_direction != EXEC_REVERSE)
-      && !record_btrace_is_replaying (ops, minus_one_ptid))
-    ops->beneath->to_commit_resume (ops->beneath);
+  if ((::execution_direction != EXEC_REVERSE)
+      && !record_is_replaying (minus_one_ptid))
+    beneath->commit_resume ();
 }
 
 /* Cancel resuming TP.  */
@@ -2400,7 +2475,7 @@ record_btrace_step_thread (struct thread_info *tp)
       return btrace_step_again ();
     }
 
-  /* We keep threads moving at the end of their execution history.  The to_wait
+  /* We keep threads moving at the end of their execution history.  The wait
      method will stop the thread for whom the event is reported.  */
   if (status.kind == TARGET_WAITKIND_NO_HISTORY)
     btinfo->flags |= flags;
@@ -2435,11 +2510,11 @@ record_btrace_maybe_mark_async_event
   mark_async_event_handler (record_btrace_async_inferior_event_handler);
 }
 
-/* The to_wait method of target record-btrace.  */
+/* The wait method of target record-btrace.  */
 
-static ptid_t
-record_btrace_wait (struct target_ops *ops, ptid_t ptid,
-		    struct target_waitstatus *status, int options)
+ptid_t
+record_btrace_target::wait (ptid_t ptid, struct target_waitstatus *status,
+			    int options)
 {
   std::vector<thread_info *> moving;
   std::vector<thread_info *> no_history;
@@ -2447,11 +2522,10 @@ record_btrace_wait (struct target_ops *ops, ptid_t ptid,
   DEBUG ("wait %s (0x%x)", target_pid_to_str (ptid), options);
 
   /* As long as we're not replaying, just forward the request.  */
-  if ((execution_direction != EXEC_REVERSE)
-      && !record_btrace_is_replaying (ops, minus_one_ptid))
+  if ((::execution_direction != EXEC_REVERSE)
+      && !record_is_replaying (minus_one_ptid))
     {
-      ops = ops->beneath;
-      return ops->to_wait (ops, ptid, status, options);
+      return this->beneath->wait (ptid, status, options);
     }
 
   /* Keep a work list of moving threads.  */
@@ -2569,19 +2643,18 @@ record_btrace_wait (struct target_ops *ops, ptid_t ptid,
   return eventing->ptid;
 }
 
-/* The to_stop method of target record-btrace.  */
+/* The stop method of target record-btrace.  */
 
-static void
-record_btrace_stop (struct target_ops *ops, ptid_t ptid)
+void
+record_btrace_target::stop (ptid_t ptid)
 {
   DEBUG ("stop %s", target_pid_to_str (ptid));
 
   /* As long as we're not replaying, just forward the request.  */
-  if ((execution_direction != EXEC_REVERSE)
-      && !record_btrace_is_replaying (ops, minus_one_ptid))
+  if ((::execution_direction != EXEC_REVERSE)
+      && !record_is_replaying (minus_one_ptid))
     {
-      ops = ops->beneath;
-      ops->to_stop (ops, ptid);
+      this->beneath->stop (ptid);
     }
   else
     {
@@ -2596,94 +2669,92 @@ record_btrace_stop (struct target_ops *ops, ptid_t ptid)
     }
  }
 
-/* The to_can_execute_reverse method of target record-btrace.  */
+/* The can_execute_reverse method of target record-btrace.  */
 
-static int
-record_btrace_can_execute_reverse (struct target_ops *self)
+int
+record_btrace_target::can_execute_reverse ()
 {
   return 1;
 }
 
-/* The to_stopped_by_sw_breakpoint method of target record-btrace.  */
+/* The stopped_by_sw_breakpoint method of target record-btrace.  */
 
-static int
-record_btrace_stopped_by_sw_breakpoint (struct target_ops *ops)
+int
+record_btrace_target::stopped_by_sw_breakpoint ()
 {
-  if (record_btrace_is_replaying (ops, minus_one_ptid))
+  if (record_is_replaying (minus_one_ptid))
     {
       struct thread_info *tp = inferior_thread ();
 
       return tp->btrace.stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT;
     }
 
-  return ops->beneath->to_stopped_by_sw_breakpoint (ops->beneath);
+  return this->beneath->stopped_by_sw_breakpoint ();
 }
 
-/* The to_supports_stopped_by_sw_breakpoint method of target
+/* The supports_stopped_by_sw_breakpoint method of target
    record-btrace.  */
 
-static int
-record_btrace_supports_stopped_by_sw_breakpoint (struct target_ops *ops)
+int
+record_btrace_target::supports_stopped_by_sw_breakpoint ()
 {
-  if (record_btrace_is_replaying (ops, minus_one_ptid))
+  if (record_is_replaying (minus_one_ptid))
     return 1;
 
-  return ops->beneath->to_supports_stopped_by_sw_breakpoint (ops->beneath);
+  return this->beneath->supports_stopped_by_sw_breakpoint ();
 }
 
-/* The to_stopped_by_sw_breakpoint method of target record-btrace.  */
+/* The stopped_by_sw_breakpoint method of target record-btrace.  */
 
-static int
-record_btrace_stopped_by_hw_breakpoint (struct target_ops *ops)
+int
+record_btrace_target::stopped_by_hw_breakpoint ()
 {
-  if (record_btrace_is_replaying (ops, minus_one_ptid))
+  if (record_is_replaying (minus_one_ptid))
     {
       struct thread_info *tp = inferior_thread ();
 
       return tp->btrace.stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT;
     }
 
-  return ops->beneath->to_stopped_by_hw_breakpoint (ops->beneath);
+  return this->beneath->stopped_by_hw_breakpoint ();
 }
 
-/* The to_supports_stopped_by_hw_breakpoint method of target
+/* The supports_stopped_by_hw_breakpoint method of target
    record-btrace.  */
 
-static int
-record_btrace_supports_stopped_by_hw_breakpoint (struct target_ops *ops)
+int
+record_btrace_target::supports_stopped_by_hw_breakpoint ()
 {
-  if (record_btrace_is_replaying (ops, minus_one_ptid))
+  if (record_is_replaying (minus_one_ptid))
     return 1;
 
-  return ops->beneath->to_supports_stopped_by_hw_breakpoint (ops->beneath);
+  return this->beneath->supports_stopped_by_hw_breakpoint ();
 }
 
-/* The to_update_thread_list method of target record-btrace.  */
+/* The update_thread_list method of target record-btrace.  */
 
-static void
-record_btrace_update_thread_list (struct target_ops *ops)
+void
+record_btrace_target::update_thread_list ()
 {
   /* We don't add or remove threads during replay.  */
-  if (record_btrace_is_replaying (ops, minus_one_ptid))
+  if (record_is_replaying (minus_one_ptid))
     return;
 
   /* Forward the request.  */
-  ops = ops->beneath;
-  ops->to_update_thread_list (ops);
+  this->beneath->update_thread_list ();
 }
 
-/* The to_thread_alive method of target record-btrace.  */
+/* The thread_alive method of target record-btrace.  */
 
-static int
-record_btrace_thread_alive (struct target_ops *ops, ptid_t ptid)
+int
+record_btrace_target::thread_alive (ptid_t ptid)
 {
   /* We don't add or remove threads during replay.  */
-  if (record_btrace_is_replaying (ops, minus_one_ptid))
+  if (record_is_replaying (minus_one_ptid))
     return find_thread_ptid (ptid) != NULL;
 
   /* Forward the request.  */
-  ops = ops->beneath;
-  return ops->to_thread_alive (ops, ptid);
+  return this->beneath->thread_alive (ptid);
 }
 
 /* Set the replay branch trace instruction iterator.  If IT is NULL, replay
@@ -2717,10 +2788,10 @@ record_btrace_set_replay (struct thread_info *tp,
   print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);
 }
 
-/* The to_goto_record_begin method of target record-btrace.  */
+/* The goto_record_begin method of target record-btrace.  */
 
-static void
-record_btrace_goto_begin (struct target_ops *self)
+void
+record_btrace_target::goto_record_begin ()
 {
   struct thread_info *tp;
   struct btrace_insn_iterator begin;
@@ -2742,10 +2813,10 @@ record_btrace_goto_begin (struct target_ops *self)
   record_btrace_set_replay (tp, &begin);
 }
 
-/* The to_goto_record_end method of target record-btrace.  */
+/* The goto_record_end method of target record-btrace.  */
 
-static void
-record_btrace_goto_end (struct target_ops *ops)
+void
+record_btrace_target::goto_record_end ()
 {
   struct thread_info *tp;
 
@@ -2754,10 +2825,10 @@ record_btrace_goto_end (struct target_ops *ops)
   record_btrace_set_replay (tp, NULL);
 }
 
-/* The to_goto_record method of target record-btrace.  */
+/* The goto_record method of target record-btrace.  */
 
-static void
-record_btrace_goto (struct target_ops *self, ULONGEST insn)
+void
+record_btrace_target::goto_record (ULONGEST insn)
 {
   struct thread_info *tp;
   struct btrace_insn_iterator it;
@@ -2781,10 +2852,10 @@ record_btrace_goto (struct target_ops *self, ULONGEST insn)
   record_btrace_set_replay (tp, &it);
 }
 
-/* The to_record_stop_replaying method of target record-btrace.  */
+/* The record_stop_replaying method of target record-btrace.  */
 
-static void
-record_btrace_stop_replaying_all (struct target_ops *self)
+void
+record_btrace_target::record_stop_replaying ()
 {
   struct thread_info *tp;
 
@@ -2792,91 +2863,30 @@ record_btrace_stop_replaying_all (struct target_ops *self)
     record_btrace_stop_replaying (tp);
 }
 
-/* The to_execution_direction target method.  */
+/* The execution_direction target method.  */
 
-static enum exec_direction_kind
-record_btrace_execution_direction (struct target_ops *self)
+enum exec_direction_kind
+record_btrace_target::execution_direction ()
 {
   return record_btrace_resume_exec_dir;
 }
 
-/* The to_prepare_to_generate_core target method.  */
+/* The prepare_to_generate_core target method.  */
 
-static void
-record_btrace_prepare_to_generate_core (struct target_ops *self)
+void
+record_btrace_target::prepare_to_generate_core ()
 {
   record_btrace_generating_corefile = 1;
 }
 
-/* The to_done_generating_core target method.  */
+/* The done_generating_core target method.  */
 
-static void
-record_btrace_done_generating_core (struct target_ops *self)
+void
+record_btrace_target::done_generating_core ()
 {
   record_btrace_generating_corefile = 0;
 }
 
-/* Initialize the record-btrace target ops.  */
-
-static void
-init_record_btrace_ops (void)
-{
-  struct target_ops *ops;
-
-  ops = &record_btrace_ops;
-  ops->to_shortname = "record-btrace";
-  ops->to_longname = "Branch tracing target";
-  ops->to_doc = "Collect control-flow trace and provide the execution history.";
-  ops->to_open = record_btrace_open;
-  ops->to_close = record_btrace_close;
-  ops->to_async = record_btrace_async;
-  ops->to_detach = record_detach;
-  ops->to_disconnect = record_btrace_disconnect;
-  ops->to_mourn_inferior = record_mourn_inferior;
-  ops->to_kill = record_kill;
-  ops->to_stop_recording = record_btrace_stop_recording;
-  ops->to_info_record = record_btrace_info;
-  ops->to_insn_history = record_btrace_insn_history;
-  ops->to_insn_history_from = record_btrace_insn_history_from;
-  ops->to_insn_history_range = record_btrace_insn_history_range;
-  ops->to_call_history = record_btrace_call_history;
-  ops->to_call_history_from = record_btrace_call_history_from;
-  ops->to_call_history_range = record_btrace_call_history_range;
-  ops->to_record_method = record_btrace_record_method;
-  ops->to_record_is_replaying = record_btrace_is_replaying;
-  ops->to_record_will_replay = record_btrace_will_replay;
-  ops->to_record_stop_replaying = record_btrace_stop_replaying_all;
-  ops->to_xfer_partial = record_btrace_xfer_partial;
-  ops->to_remove_breakpoint = record_btrace_remove_breakpoint;
-  ops->to_insert_breakpoint = record_btrace_insert_breakpoint;
-  ops->to_fetch_registers = record_btrace_fetch_registers;
-  ops->to_store_registers = record_btrace_store_registers;
-  ops->to_prepare_to_store = record_btrace_prepare_to_store;
-  ops->to_get_unwinder = &record_btrace_to_get_unwinder;
-  ops->to_get_tailcall_unwinder = &record_btrace_to_get_tailcall_unwinder;
-  ops->to_resume = record_btrace_resume;
-  ops->to_commit_resume = record_btrace_commit_resume;
-  ops->to_wait = record_btrace_wait;
-  ops->to_stop = record_btrace_stop;
-  ops->to_update_thread_list = record_btrace_update_thread_list;
-  ops->to_thread_alive = record_btrace_thread_alive;
-  ops->to_goto_record_begin = record_btrace_goto_begin;
-  ops->to_goto_record_end = record_btrace_goto_end;
-  ops->to_goto_record = record_btrace_goto;
-  ops->to_can_execute_reverse = record_btrace_can_execute_reverse;
-  ops->to_stopped_by_sw_breakpoint = record_btrace_stopped_by_sw_breakpoint;
-  ops->to_supports_stopped_by_sw_breakpoint
-    = record_btrace_supports_stopped_by_sw_breakpoint;
-  ops->to_stopped_by_hw_breakpoint = record_btrace_stopped_by_hw_breakpoint;
-  ops->to_supports_stopped_by_hw_breakpoint
-    = record_btrace_supports_stopped_by_hw_breakpoint;
-  ops->to_execution_direction = record_btrace_execution_direction;
-  ops->to_prepare_to_generate_core = record_btrace_prepare_to_generate_core;
-  ops->to_done_generating_core = record_btrace_done_generating_core;
-  ops->to_stratum = record_stratum;
-  ops->to_magic = OPS_MAGIC;
-}
-
 /* Start recording in BTS format.  */
 
 static void
@@ -3132,7 +3142,6 @@ to see the actual buffer size."), NULL, show_record_pt_buffer_size_value,
 			    &set_record_btrace_pt_cmdlist,
 			    &show_record_btrace_pt_cmdlist);
 
-  init_record_btrace_ops ();
   add_target (&record_btrace_ops);
 
   bfcache = htab_create_alloc (50, bfcache_hash, bfcache_eq, NULL,
diff --git a/gdb/record-full.c b/gdb/record-full.c
index 4d8dd61bca..de96574baf 100644
--- a/gdb/record-full.c
+++ b/gdb/record-full.c
@@ -47,7 +47,7 @@
 
    Target record has two modes: recording, and replaying.
 
-   In record mode, we intercept the to_resume and to_wait methods.
+   In record mode, we intercept the resume and wait methods.
    Whenever gdb resumes the target, we run the target in single step
    mode, and we build up an execution log in which, for each executed
    instruction, we record all changes in memory and register state.
@@ -63,7 +63,7 @@
 #define DEFAULT_RECORD_FULL_INSN_MAX_NUM	200000
 
 #define RECORD_FULL_IS_REPLAY \
-     (record_full_list->next || execution_direction == EXEC_REVERSE)
+  (record_full_list->next || ::execution_direction == EXEC_REVERSE)
 
 #define RECORD_FULL_FILE_MAGIC	netorder32(0x20091016)
 
@@ -206,9 +206,144 @@ static unsigned int record_full_insn_num = 0;
    than count of insns presently in execution log).  */
 static ULONGEST record_full_insn_count;
 
-/* The target_ops of process record.  */
-static struct target_ops record_full_ops;
-static struct target_ops record_full_core_ops;
+/* Base class implementing functionality common to both the
+   "record-full" and "record-core" targets.  */
+
+class record_full_base_target : public target_ops
+{
+public:
+  record_full_base_target ()
+  { to_stratum = record_stratum; }
+
+  const char *shortname () override = 0;
+
+  const char *longname () override
+  { return _("Process record and replay target"); }
+
+  const char *doc () override
+  { return _("Log program while executing and replay execution from log."); }
+
+  void open (const char *, int) override;
+  void close () override;
+  void async (int) override;
+  ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
+  int stopped_by_watchpoint () override;
+  int stopped_data_address (CORE_ADDR *) override;
+
+  int stopped_by_sw_breakpoint () override;
+  int supports_stopped_by_sw_breakpoint () override;
+
+  int stopped_by_hw_breakpoint () override;
+  int supports_stopped_by_hw_breakpoint () override;
+
+  int can_execute_reverse () override;
+
+  /* Add bookmark target methods.  */
+  gdb_byte *get_bookmark (const char *, int) override;
+  void goto_bookmark (const gdb_byte *, int) override;
+  enum exec_direction_kind execution_direction () override;
+  enum record_method record_method (ptid_t ptid) override;
+  void info_record () override;
+  void save_record (const char *filename) override;
+  bool supports_delete_record () override;
+  void delete_record () override;
+  int record_is_replaying (ptid_t ptid) override;
+  int record_will_replay (ptid_t ptid, int dir) override;
+  void record_stop_replaying () override;
+  void goto_record_begin () override;
+  void goto_record_end () override;
+  void goto_record (ULONGEST insn) override;
+};
+
+/* The "record-full" target.  */
+
+class record_full_target final : public record_full_base_target
+{
+public:
+  const char *shortname () override
+  { return "record-full"; }
+
+  void commit_resume () override;
+  void resume (ptid_t, int, enum gdb_signal) override;
+  void disconnect (const char *, int) override;
+  void detach (inferior *, int) override;
+  void mourn_inferior () override;
+  void kill () override;
+  void store_registers (struct regcache *, int) override;
+  enum target_xfer_status xfer_partial (enum target_object object,
+					const char *annex,
+					gdb_byte *readbuf,
+					const gdb_byte *writebuf,
+					ULONGEST offset, ULONGEST len,
+					ULONGEST *xfered_len) override;
+  int insert_breakpoint (struct gdbarch *,
+			 struct bp_target_info *) override;
+  int remove_breakpoint (struct gdbarch *,
+			 struct bp_target_info *,
+			 enum remove_bp_reason) override;
+};
+
+/* The "record-core" target.  */
+
+class record_full_core_target final : public record_full_base_target
+{
+public:
+  const char *shortname () override
+  { return "record-core"; }
+
+  void resume (ptid_t, int, enum gdb_signal) override;
+  void disconnect (const char *, int) override;
+  void kill () override;
+  void fetch_registers (struct regcache *regcache, int regno) override;
+  void prepare_to_store (struct regcache *regcache) override;
+  void store_registers (struct regcache *, int) override;
+  enum target_xfer_status xfer_partial (enum target_object object,
+					const char *annex,
+					gdb_byte *readbuf,
+					const gdb_byte *writebuf,
+					ULONGEST offset, ULONGEST len,
+					ULONGEST *xfered_len) override;
+  int insert_breakpoint (struct gdbarch *,
+			 struct bp_target_info *) override;
+  int remove_breakpoint (struct gdbarch *,
+			 struct bp_target_info *,
+			 enum remove_bp_reason) override;
+
+  int has_execution (ptid_t) override;
+};
+
+static record_full_target record_full_ops;
+static record_full_core_target record_full_core_ops;
+
+void
+record_full_target::detach (inferior *inf, int from_tty)
+{
+  record_detach (this, inf, from_tty);
+}
+
+void
+record_full_target::disconnect (const char *args, int from_tty)
+{
+  record_disconnect (this, args, from_tty);
+}
+
+void
+record_full_core_target::disconnect (const char *args, int from_tty)
+{
+  record_disconnect (this, args, from_tty);
+}
+
+void
+record_full_target::mourn_inferior ()
+{
+  record_mourn_inferior (this);
+}
+
+void
+record_full_target::kill ()
+{
+  record_kill (this);
+}
 
 /* See record-full.h.  */
 
@@ -232,8 +367,6 @@ static struct cmd_list_element *record_full_cmdlist;
 
 static void record_full_goto_insn (struct record_full_entry *entry,
 				   enum exec_direction_kind dir);
-static void record_full_save (struct target_ops *self,
-			      const char *recfilename);
 
 /* Alloc and free functions for record_full_reg, record_full_mem, and
    record_full_end entries.  */
@@ -797,7 +930,7 @@ record_full_core_open_1 (const char *name, int from_tty)
   record_full_restore ();
 }
 
-/* "to_open" target method for 'live' processes.  */
+/* "open" target method for 'live' processes.  */
 
 static void
 record_full_open_1 (const char *name, int from_tty)
@@ -821,10 +954,10 @@ record_full_open_1 (const char *name, int from_tty)
 
 static void record_full_init_record_breakpoints (void);
 
-/* "to_open" target method.  Open the process record target.  */
+/* "open" target method.  Open the process record target.  */
 
-static void
-record_full_open (const char *name, int from_tty)
+void
+record_full_base_target::open (const char *name, int from_tty)
 {
   if (record_debug)
     fprintf_unfiltered (gdb_stdlog, "Process record: record_full_open\n");
@@ -852,10 +985,10 @@ record_full_open (const char *name, int from_tty)
   gdb::observers::record_changed.notify (current_inferior (),  1, "full", NULL);
 }
 
-/* "to_close" target method.  Close the process record target.  */
+/* "close" target method.  Close the process record target.  */
 
-static void
-record_full_close (struct target_ops *self)
+void
+record_full_base_target::close ()
 {
   struct record_full_core_buf_entry *entry;
 
@@ -887,17 +1020,17 @@ record_full_close (struct target_ops *self)
     delete_async_event_handler (&record_full_async_inferior_event_token);
 }
 
-/* "to_async" target method.  */
+/* "async" target method.  */
 
-static void
-record_full_async (struct target_ops *ops, int enable)
+void
+record_full_base_target::async (int enable)
 {
   if (enable)
     mark_async_event_handler (record_full_async_inferior_event_token);
   else
     clear_async_event_handler (record_full_async_inferior_event_token);
 
-  ops->beneath->to_async (ops->beneath, enable);
+  beneath->async (enable);
 }
 
 static int record_full_resume_step = 0;
@@ -923,15 +1056,14 @@ static int record_full_resumed = 0;
 */
 static enum exec_direction_kind record_full_execution_dir = EXEC_FORWARD;
 
-/* "to_resume" target method.  Resume the process record target.  */
+/* "resume" target method.  Resume the process record target.  */
 
-static void
-record_full_resume (struct target_ops *ops, ptid_t ptid, int step,
-		    enum gdb_signal signal)
+void
+record_full_target::resume (ptid_t ptid, int step, enum gdb_signal signal)
 {
   record_full_resume_step = step;
   record_full_resumed = 1;
-  record_full_execution_dir = execution_direction;
+  record_full_execution_dir = ::execution_direction;
 
   if (!RECORD_FULL_IS_REPLAY)
     {
@@ -963,7 +1095,7 @@ record_full_resume (struct target_ops *ops, ptid_t ptid, int step,
       /* Make sure the target beneath reports all signals.  */
       target_pass_signals (0, NULL);
 
-      ops->beneath->to_resume (ops->beneath, ptid, step, signal);
+      this->beneath->resume (ptid, step, signal);
     }
 
   /* We are about to start executing the inferior (or simulate it),
@@ -972,18 +1104,18 @@ record_full_resume (struct target_ops *ops, ptid_t ptid, int step,
     target_async (1);
 }
 
-/* "to_commit_resume" method for process record target.  */
+/* "commit_resume" method for process record target.  */
 
-static void
-record_full_commit_resume (struct target_ops *ops)
+void
+record_full_target::commit_resume ()
 {
   if (!RECORD_FULL_IS_REPLAY)
-    ops->beneath->to_commit_resume (ops->beneath);
+    beneath->commit_resume ();
 }
 
 static int record_full_get_sig = 0;
 
-/* SIGINT signal handler, registered by "to_wait" method.  */
+/* SIGINT signal handler, registered by "wait" method.  */
 
 static void
 record_full_sig_handler (int signo)
@@ -1011,13 +1143,13 @@ record_full_wait_cleanups (void *ignore)
     record_full_list = record_full_list->prev;
 }
 
-/* "to_wait" target method for process record target.
+/* "wait" target method for process record target.
 
    In record mode, the target is always run in singlestep mode
-   (even when gdb says to continue).  The to_wait method intercepts
+   (even when gdb says to continue).  The wait method intercepts
    the stop events and determines which ones are to be passed on to
    gdb.  Most stop events are just singlestep events that gdb is not
-   to know about, so the to_wait method just records them and keeps
+   to know about, so the wait method just records them and keeps
    singlestepping.
 
    In replay mode, this function emulates the recorded execution log, 
@@ -1060,7 +1192,7 @@ record_full_wait_1 (struct target_ops *ops,
       if (record_full_resume_step)
 	{
 	  /* This is a single step.  */
-	  return ops->beneath->to_wait (ops->beneath, ptid, status, options);
+	  return ops->beneath->wait (ptid, status, options);
 	}
       else
 	{
@@ -1073,7 +1205,7 @@ record_full_wait_1 (struct target_ops *ops,
 	    {
 	      struct thread_info *tp;
 
-	      ret = ops->beneath->to_wait (ops->beneath, ptid, status, options);
+	      ret = ops->beneath->wait (ptid, status, options);
 	      if (status->kind == TARGET_WAITKIND_IGNORE)
 		{
 		  if (record_debug)
@@ -1149,9 +1281,8 @@ record_full_wait_1 (struct target_ops *ops,
 					    "Process record: record_full_wait "
 					    "issuing one more step in the "
 					    "target beneath\n");
-		      ops->beneath->to_resume (ops->beneath, ptid, step,
-					       GDB_SIGNAL_0);
-		      ops->beneath->to_commit_resume (ops->beneath);
+		      ops->beneath->resume (ptid, step, GDB_SIGNAL_0);
+		      ops->beneath->commit_resume ();
 		      continue;
 		    }
 		}
@@ -1315,14 +1446,13 @@ replay_out:
   return inferior_ptid;
 }
 
-static ptid_t
-record_full_wait (struct target_ops *ops,
-		  ptid_t ptid, struct target_waitstatus *status,
-		  int options)
+ptid_t
+record_full_base_target::wait (ptid_t ptid, struct target_waitstatus *status,
+			       int options)
 {
   ptid_t return_ptid;
 
-  return_ptid = record_full_wait_1 (ops, ptid, status, options);
+  return_ptid = record_full_wait_1 (this, ptid, status, options);
   if (status->kind != TARGET_WAITKIND_IGNORE)
     {
       /* We're reporting a stop.  Make sure any spurious
@@ -1333,54 +1463,54 @@ record_full_wait (struct target_ops *ops,
   return return_ptid;
 }
 
-static int
-record_full_stopped_by_watchpoint (struct target_ops *ops)
+int
+record_full_base_target::stopped_by_watchpoint ()
 {
   if (RECORD_FULL_IS_REPLAY)
     return record_full_stop_reason == TARGET_STOPPED_BY_WATCHPOINT;
   else
-    return ops->beneath->to_stopped_by_watchpoint (ops->beneath);
+    return beneath->stopped_by_watchpoint ();
 }
 
-static int
-record_full_stopped_data_address (struct target_ops *ops, CORE_ADDR *addr_p)
+int
+record_full_base_target::stopped_data_address (CORE_ADDR *addr_p)
 {
   if (RECORD_FULL_IS_REPLAY)
     return 0;
   else
-    return ops->beneath->to_stopped_data_address (ops->beneath, addr_p);
+    return this->beneath->stopped_data_address (addr_p);
 }
 
-/* The to_stopped_by_sw_breakpoint method of target record-full.  */
+/* The stopped_by_sw_breakpoint method of target record-full.  */
 
-static int
-record_full_stopped_by_sw_breakpoint (struct target_ops *ops)
+int
+record_full_base_target::stopped_by_sw_breakpoint ()
 {
   return record_full_stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT;
 }
 
-/* The to_supports_stopped_by_sw_breakpoint method of target
+/* The supports_stopped_by_sw_breakpoint method of target
    record-full.  */
 
-static int
-record_full_supports_stopped_by_sw_breakpoint (struct target_ops *ops)
+int
+record_full_base_target::supports_stopped_by_sw_breakpoint ()
 {
   return 1;
 }
 
-/* The to_stopped_by_hw_breakpoint method of target record-full.  */
+/* The stopped_by_hw_breakpoint method of target record-full.  */
 
-static int
-record_full_stopped_by_hw_breakpoint (struct target_ops *ops)
+int
+record_full_base_target::stopped_by_hw_breakpoint ()
 {
   return record_full_stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT;
 }
 
-/* The to_supports_stopped_by_sw_breakpoint method of target
+/* The supports_stopped_by_sw_breakpoint method of target
    record-full.  */
 
-static int
-record_full_supports_stopped_by_hw_breakpoint (struct target_ops *ops)
+int
+record_full_base_target::supports_stopped_by_hw_breakpoint ()
 {
   return 1;
 }
@@ -1432,12 +1562,10 @@ record_full_registers_change (struct regcache *regcache, int regnum)
     record_full_insn_num++;
 }
 
-/* "to_store_registers" method for process record target.  */
+/* "store_registers" method for process record target.  */
 
-static void
-record_full_store_registers (struct target_ops *ops,
-			     struct regcache *regcache,
-			     int regno)
+void
+record_full_target::store_registers (struct regcache *regcache, int regno)
 {
   if (!record_full_gdb_operation_disable)
     {
@@ -1485,19 +1613,19 @@ record_full_store_registers (struct target_ops *ops,
 
       record_full_registers_change (regcache, regno);
     }
-  ops->beneath->to_store_registers (ops->beneath, regcache, regno);
+  this->beneath->store_registers (regcache, regno);
 }
 
-/* "to_xfer_partial" method.  Behavior is conditional on
+/* "xfer_partial" method.  Behavior is conditional on
    RECORD_FULL_IS_REPLAY.
    In replay mode, we cannot write memory unles we are willing to
    invalidate the record/replay log from this point forward.  */
 
-static enum target_xfer_status
-record_full_xfer_partial (struct target_ops *ops, enum target_object object,
-			  const char *annex, gdb_byte *readbuf,
-			  const gdb_byte *writebuf, ULONGEST offset,
-			  ULONGEST len, ULONGEST *xfered_len)
+enum target_xfer_status
+record_full_target::xfer_partial (enum target_object object,
+				  const char *annex, gdb_byte *readbuf,
+				  const gdb_byte *writebuf, ULONGEST offset,
+				  ULONGEST len, ULONGEST *xfered_len)
 {
   if (!record_full_gdb_operation_disable
       && (object == TARGET_OBJECT_MEMORY
@@ -1550,9 +1678,8 @@ record_full_xfer_partial (struct target_ops *ops, enum target_object object,
 	record_full_insn_num++;
     }
 
-  return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
-					readbuf, writebuf, offset,
-					len, xfered_len);
+  return this->beneath->xfer_partial (object, annex, readbuf, writebuf, offset,
+				      len, xfered_len);
 }
 
 /* This structure represents a breakpoint inserted while the record
@@ -1614,10 +1741,9 @@ record_full_init_record_breakpoints (void)
    insert or remove breakpoints in the real target when replaying, nor
    when recording.  */
 
-static int
-record_full_insert_breakpoint (struct target_ops *ops,
-			       struct gdbarch *gdbarch,
-			       struct bp_target_info *bp_tgt)
+int
+record_full_target::insert_breakpoint (struct gdbarch *gdbarch,
+				       struct bp_target_info *bp_tgt)
 {
   struct record_full_breakpoint *bp;
   int in_target_beneath = 0;
@@ -1630,12 +1756,11 @@ record_full_insert_breakpoint (struct target_ops *ops,
 	 However, we do have to insert software single-step
 	 breakpoints, in case the target can't hardware step.  To keep
 	 things simple, we always insert.  */
-      int ret;
 
       scoped_restore restore_operation_disable
 	= record_full_gdb_operation_disable_set ();
-      ret = ops->beneath->to_insert_breakpoint (ops->beneath, gdbarch, bp_tgt);
 
+      int ret = this->beneath->insert_breakpoint (gdbarch, bp_tgt);
       if (ret != 0)
 	return ret;
 
@@ -1666,13 +1791,12 @@ record_full_insert_breakpoint (struct target_ops *ops,
   return 0;
 }
 
-/* "to_remove_breakpoint" method for process record target.  */
+/* "remove_breakpoint" method for process record target.  */
 
-static int
-record_full_remove_breakpoint (struct target_ops *ops,
-			       struct gdbarch *gdbarch,
-			       struct bp_target_info *bp_tgt,
-			       enum remove_bp_reason reason)
+int
+record_full_target::remove_breakpoint (struct gdbarch *gdbarch,
+				       struct bp_target_info *bp_tgt,
+				       enum remove_bp_reason reason)
 {
   struct record_full_breakpoint *bp;
   int ix;
@@ -1687,12 +1811,11 @@ record_full_remove_breakpoint (struct target_ops *ops,
 	{
 	  if (bp->in_target_beneath)
 	    {
-	      int ret;
-
 	      scoped_restore restore_operation_disable
 		= record_full_gdb_operation_disable_set ();
-	      ret = ops->beneath->to_remove_breakpoint (ops->beneath, gdbarch,
-							bp_tgt, reason);
+
+	      int ret = this->beneath->remove_breakpoint (gdbarch, bp_tgt,
+							  reason);
 	      if (ret != 0)
 		return ret;
 	    }
@@ -1709,19 +1832,18 @@ record_full_remove_breakpoint (struct target_ops *ops,
   gdb_assert_not_reached ("removing unknown breakpoint");
 }
 
-/* "to_can_execute_reverse" method for process record target.  */
+/* "can_execute_reverse" method for process record target.  */
 
-static int
-record_full_can_execute_reverse (struct target_ops *self)
+int
+record_full_base_target::can_execute_reverse ()
 {
   return 1;
 }
 
-/* "to_get_bookmark" method for process record and prec over core.  */
+/* "get_bookmark" method for process record and prec over core.  */
 
-static gdb_byte *
-record_full_get_bookmark (struct target_ops *self, const char *args,
-			  int from_tty)
+gdb_byte *
+record_full_base_target::get_bookmark (const char *args, int from_tty)
 {
   char *ret = NULL;
 
@@ -1741,11 +1863,11 @@ record_full_get_bookmark (struct target_ops *self, const char *args,
   return (gdb_byte *) ret;
 }
 
-/* "to_goto_bookmark" method for process record and prec over core.  */
+/* "goto_bookmark" method for process record and prec over core.  */
 
-static void
-record_full_goto_bookmark (struct target_ops *self,
-			   const gdb_byte *raw_bookmark, int from_tty)
+void
+record_full_base_target::goto_bookmark (const gdb_byte *raw_bookmark,
+					int from_tty)
 {
   const char *bookmark = (const char *) raw_bookmark;
 
@@ -1766,22 +1888,22 @@ record_full_goto_bookmark (struct target_ops *self,
   record_goto (bookmark);
 }
 
-static enum exec_direction_kind
-record_full_execution_direction (struct target_ops *self)
+enum exec_direction_kind
+record_full_base_target::execution_direction ()
 {
   return record_full_execution_dir;
 }
 
-/* The to_record_method method of target record-full.  */
+/* The record_method method of target record-full.  */
 
 enum record_method
-record_full_record_method (struct target_ops *self, ptid_t ptid)
+record_full_base_target::record_method (ptid_t ptid)
 {
   return RECORD_METHOD_FULL;
 }
 
-static void
-record_full_info (struct target_ops *self)
+void
+record_full_base_target::info_record ()
 {
   struct record_full_entry *p;
 
@@ -1824,26 +1946,32 @@ record_full_info (struct target_ops *self)
 		   record_full_insn_max_num);
 }
 
-/* The "to_record_delete" target method.  */
+bool
+record_full_base_target::supports_delete_record ()
+{
+  return true;
+}
 
-static void
-record_full_delete (struct target_ops *self)
+/* The "delete_record" target method.  */
+
+void
+record_full_base_target::delete_record ()
 {
   record_full_list_release_following (record_full_list);
 }
 
-/* The "to_record_is_replaying" target method.  */
+/* The "record_is_replaying" target method.  */
 
-static int
-record_full_is_replaying (struct target_ops *self, ptid_t ptid)
+int
+record_full_base_target::record_is_replaying (ptid_t ptid)
 {
   return RECORD_FULL_IS_REPLAY;
 }
 
-/* The "to_record_will_replay" target method.  */
+/* The "record_will_replay" target method.  */
 
-static int
-record_full_will_replay (struct target_ops *self, ptid_t ptid, int dir)
+int
+record_full_base_target::record_will_replay (ptid_t ptid, int dir)
 {
   /* We can currently only record when executing forwards.  Should we be able
      to record when executing backwards on targets that support reverse
@@ -1880,10 +2008,10 @@ record_full_goto_entry (struct record_full_entry *p)
   print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC, 1);
 }
 
-/* The "to_goto_record_begin" target method.  */
+/* The "goto_record_begin" target method.  */
 
-static void
-record_full_goto_begin (struct target_ops *self)
+void
+record_full_base_target::goto_record_begin ()
 {
   struct record_full_entry *p = NULL;
 
@@ -1894,10 +2022,10 @@ record_full_goto_begin (struct target_ops *self)
   record_full_goto_entry (p);
 }
 
-/* The "to_goto_record_end" target method.  */
+/* The "goto_record_end" target method.  */
 
-static void
-record_full_goto_end (struct target_ops *self)
+void
+record_full_base_target::goto_record_end ()
 {
   struct record_full_entry *p = NULL;
 
@@ -1910,10 +2038,10 @@ record_full_goto_end (struct target_ops *self)
   record_full_goto_entry (p);
 }
 
-/* The "to_goto_record" target method.  */
+/* The "goto_record" target method.  */
 
-static void
-record_full_goto (struct target_ops *self, ULONGEST target_insn)
+void
+record_full_base_target::goto_record (ULONGEST target_insn)
 {
   struct record_full_entry *p = NULL;
 
@@ -1924,73 +2052,23 @@ record_full_goto (struct target_ops *self, ULONGEST target_insn)
   record_full_goto_entry (p);
 }
 
-/* The "to_record_stop_replaying" target method.  */
+/* The "record_stop_replaying" target method.  */
 
-static void
-record_full_stop_replaying (struct target_ops *self)
+void
+record_full_base_target::record_stop_replaying ()
 {
-  record_full_goto_end (self);
+  goto_record_end ();
 }
 
-static void
-init_record_full_ops (void)
-{
-  record_full_ops.to_shortname = "record-full";
-  record_full_ops.to_longname = "Process record and replay target";
-  record_full_ops.to_doc =
-    "Log program while executing and replay execution from log.";
-  record_full_ops.to_open = record_full_open;
-  record_full_ops.to_close = record_full_close;
-  record_full_ops.to_async = record_full_async;
-  record_full_ops.to_resume = record_full_resume;
-  record_full_ops.to_commit_resume = record_full_commit_resume;
-  record_full_ops.to_wait = record_full_wait;
-  record_full_ops.to_disconnect = record_disconnect;
-  record_full_ops.to_detach = record_detach;
-  record_full_ops.to_mourn_inferior = record_mourn_inferior;
-  record_full_ops.to_kill = record_kill;
-  record_full_ops.to_store_registers = record_full_store_registers;
-  record_full_ops.to_xfer_partial = record_full_xfer_partial;
-  record_full_ops.to_insert_breakpoint = record_full_insert_breakpoint;
-  record_full_ops.to_remove_breakpoint = record_full_remove_breakpoint;
-  record_full_ops.to_stopped_by_watchpoint = record_full_stopped_by_watchpoint;
-  record_full_ops.to_stopped_data_address = record_full_stopped_data_address;
-  record_full_ops.to_stopped_by_sw_breakpoint
-    = record_full_stopped_by_sw_breakpoint;
-  record_full_ops.to_supports_stopped_by_sw_breakpoint
-    = record_full_supports_stopped_by_sw_breakpoint;
-  record_full_ops.to_stopped_by_hw_breakpoint
-    = record_full_stopped_by_hw_breakpoint;
-  record_full_ops.to_supports_stopped_by_hw_breakpoint
-    = record_full_supports_stopped_by_hw_breakpoint;
-  record_full_ops.to_can_execute_reverse = record_full_can_execute_reverse;
-  record_full_ops.to_stratum = record_stratum;
-  /* Add bookmark target methods.  */
-  record_full_ops.to_get_bookmark = record_full_get_bookmark;
-  record_full_ops.to_goto_bookmark = record_full_goto_bookmark;
-  record_full_ops.to_execution_direction = record_full_execution_direction;
-  record_full_ops.to_record_method = record_full_record_method;
-  record_full_ops.to_info_record = record_full_info;
-  record_full_ops.to_save_record = record_full_save;
-  record_full_ops.to_delete_record = record_full_delete;
-  record_full_ops.to_record_is_replaying = record_full_is_replaying;
-  record_full_ops.to_record_will_replay = record_full_will_replay;
-  record_full_ops.to_record_stop_replaying = record_full_stop_replaying;
-  record_full_ops.to_goto_record_begin = record_full_goto_begin;
-  record_full_ops.to_goto_record_end = record_full_goto_end;
-  record_full_ops.to_goto_record = record_full_goto;
-  record_full_ops.to_magic = OPS_MAGIC;
-}
-
-/* "to_resume" method for prec over corefile.  */
+/* "resume" method for prec over corefile.  */
 
-static void
-record_full_core_resume (struct target_ops *ops, ptid_t ptid, int step,
-			 enum gdb_signal signal)
+void
+record_full_core_target::resume (ptid_t ptid, int step,
+				 enum gdb_signal signal)
 {
   record_full_resume_step = step;
   record_full_resumed = 1;
-  record_full_execution_dir = execution_direction;
+  record_full_execution_dir = ::execution_direction;
 
   /* We are about to start executing the inferior (or simulate it),
      let's register it with the event loop.  */
@@ -1998,23 +2076,22 @@ record_full_core_resume (struct target_ops *ops, ptid_t ptid, int step,
     target_async (1);
 }
 
-/* "to_kill" method for prec over corefile.  */
+/* "kill" method for prec over corefile.  */
 
-static void
-record_full_core_kill (struct target_ops *ops)
+void
+record_full_core_target::kill ()
 {
   if (record_debug)
     fprintf_unfiltered (gdb_stdlog, "Process record: record_full_core_kill\n");
 
-  unpush_target (&record_full_core_ops);
+  unpush_target (this);
 }
 
-/* "to_fetch_registers" method for prec over corefile.  */
+/* "fetch_registers" method for prec over corefile.  */
 
-static void
-record_full_core_fetch_registers (struct target_ops *ops,
-				  struct regcache *regcache,
-				  int regno)
+void
+record_full_core_target::fetch_registers (struct regcache *regcache,
+					  int regno)
 {
   if (regno < 0)
     {
@@ -2028,20 +2105,18 @@ record_full_core_fetch_registers (struct target_ops *ops,
     regcache->raw_supply (regno, *record_full_core_regbuf);
 }
 
-/* "to_prepare_to_store" method for prec over corefile.  */
+/* "prepare_to_store" method for prec over corefile.  */
 
-static void
-record_full_core_prepare_to_store (struct target_ops *self,
-				   struct regcache *regcache)
+void
+record_full_core_target::prepare_to_store (struct regcache *regcache)
 {
 }
 
-/* "to_store_registers" method for prec over corefile.  */
+/* "store_registers" method for prec over corefile.  */
 
-static void
-record_full_core_store_registers (struct target_ops *ops,
-                             struct regcache *regcache,
-                             int regno)
+void
+record_full_core_target::store_registers (struct regcache *regcache,
+					  int regno)
 {
   if (record_full_gdb_operation_disable)
     record_full_core_regbuf->raw_supply (regno, *regcache);
@@ -2049,14 +2124,13 @@ record_full_core_store_registers (struct target_ops *ops,
     error (_("You can't do that without a process to debug."));
 }
 
-/* "to_xfer_partial" method for prec over corefile.  */
+/* "xfer_partial" method for prec over corefile.  */
 
-static enum target_xfer_status
-record_full_core_xfer_partial (struct target_ops *ops,
-			       enum target_object object,
-			       const char *annex, gdb_byte *readbuf,
-			       const gdb_byte *writebuf, ULONGEST offset,
-			       ULONGEST len, ULONGEST *xfered_len)
+enum target_xfer_status
+record_full_core_target::xfer_partial (enum target_object object,
+				       const char *annex, gdb_byte *readbuf,
+				       const gdb_byte *writebuf, ULONGEST offset,
+				       ULONGEST len, ULONGEST *xfered_len)
 {
   if (object == TARGET_OBJECT_MEMORY)
     {
@@ -2120,11 +2194,10 @@ record_full_core_xfer_partial (struct target_ops *ops,
 		  else
 		    {
 		      if (!entry)
-			return ops->beneath->to_xfer_partial (ops->beneath,
-							      object, annex,
-							      readbuf, writebuf,
-							      offset, len,
-							      xfered_len);
+			return this->beneath->xfer_partial (object, annex,
+							    readbuf, writebuf,
+							    offset, len,
+							    xfered_len);
 
 		      memcpy (readbuf, entry->buf + sec_offset,
 			      (size_t) len);
@@ -2141,93 +2214,38 @@ record_full_core_xfer_partial (struct target_ops *ops,
 	error (_("You can't do that without a process to debug."));
     }
 
-  return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
-					readbuf, writebuf, offset, len,
-					xfered_len);
+  return this->beneath->xfer_partial (object, annex,
+				      readbuf, writebuf, offset, len,
+				      xfered_len);
 }
 
-/* "to_insert_breakpoint" method for prec over corefile.  */
+/* "insert_breakpoint" method for prec over corefile.  */
 
-static int
-record_full_core_insert_breakpoint (struct target_ops *ops,
-				    struct gdbarch *gdbarch,
-				    struct bp_target_info *bp_tgt)
+int
+record_full_core_target::insert_breakpoint (struct gdbarch *gdbarch,
+					    struct bp_target_info *bp_tgt)
 {
   return 0;
 }
 
-/* "to_remove_breakpoint" method for prec over corefile.  */
+/* "remove_breakpoint" method for prec over corefile.  */
 
-static int
-record_full_core_remove_breakpoint (struct target_ops *ops,
-				    struct gdbarch *gdbarch,
-				    struct bp_target_info *bp_tgt,
-				    enum remove_bp_reason reason)
+int
+record_full_core_target::remove_breakpoint (struct gdbarch *gdbarch,
+					    struct bp_target_info *bp_tgt,
+					    enum remove_bp_reason reason)
 {
   return 0;
 }
 
-/* "to_has_execution" method for prec over corefile.  */
+/* "has_execution" method for prec over corefile.  */
 
-static int
-record_full_core_has_execution (struct target_ops *ops, ptid_t the_ptid)
+int
+record_full_core_target::has_execution (ptid_t the_ptid)
 {
   return 1;
 }
 
-static void
-init_record_full_core_ops (void)
-{
-  record_full_core_ops.to_shortname = "record-core";
-  record_full_core_ops.to_longname = "Process record and replay target";
-  record_full_core_ops.to_doc =
-    "Log program while executing and replay execution from log.";
-  record_full_core_ops.to_open = record_full_open;
-  record_full_core_ops.to_close = record_full_close;
-  record_full_core_ops.to_async = record_full_async;
-  record_full_core_ops.to_resume = record_full_core_resume;
-  record_full_core_ops.to_wait = record_full_wait;
-  record_full_core_ops.to_kill = record_full_core_kill;
-  record_full_core_ops.to_fetch_registers = record_full_core_fetch_registers;
-  record_full_core_ops.to_prepare_to_store = record_full_core_prepare_to_store;
-  record_full_core_ops.to_store_registers = record_full_core_store_registers;
-  record_full_core_ops.to_xfer_partial = record_full_core_xfer_partial;
-  record_full_core_ops.to_insert_breakpoint
-    = record_full_core_insert_breakpoint;
-  record_full_core_ops.to_remove_breakpoint
-    = record_full_core_remove_breakpoint;
-  record_full_core_ops.to_stopped_by_watchpoint
-    = record_full_stopped_by_watchpoint;
-  record_full_core_ops.to_stopped_data_address
-    = record_full_stopped_data_address;
-  record_full_core_ops.to_stopped_by_sw_breakpoint
-    = record_full_stopped_by_sw_breakpoint;
-  record_full_core_ops.to_supports_stopped_by_sw_breakpoint
-    = record_full_supports_stopped_by_sw_breakpoint;
-  record_full_core_ops.to_stopped_by_hw_breakpoint
-    = record_full_stopped_by_hw_breakpoint;
-  record_full_core_ops.to_supports_stopped_by_hw_breakpoint
-    = record_full_supports_stopped_by_hw_breakpoint;
-  record_full_core_ops.to_can_execute_reverse
-    = record_full_can_execute_reverse;
-  record_full_core_ops.to_has_execution = record_full_core_has_execution;
-  record_full_core_ops.to_stratum = record_stratum;
-  /* Add bookmark target methods.  */
-  record_full_core_ops.to_get_bookmark = record_full_get_bookmark;
-  record_full_core_ops.to_goto_bookmark = record_full_goto_bookmark;
-  record_full_core_ops.to_execution_direction
-    = record_full_execution_direction;
-  record_full_core_ops.to_record_method = record_full_record_method;
-  record_full_core_ops.to_info_record = record_full_info;
-  record_full_core_ops.to_delete_record = record_full_delete;
-  record_full_core_ops.to_record_is_replaying = record_full_is_replaying;
-  record_full_core_ops.to_record_will_replay = record_full_will_replay;
-  record_full_core_ops.to_goto_record_begin = record_full_goto_begin;
-  record_full_core_ops.to_goto_record_end = record_full_goto_end;
-  record_full_core_ops.to_goto_record = record_full_goto;
-  record_full_core_ops.to_magic = OPS_MAGIC;
-}
-
 /* Record log save-file format
    Version 1 (never released)
 
@@ -2501,14 +2519,14 @@ static void
 cmd_record_full_restore (const char *args, int from_tty)
 {
   core_file_command (args, from_tty);
-  record_full_open (args, from_tty);
+  record_full_ops.open (args, from_tty);
 }
 
 /* Save the execution log to a file.  We use a modified elf corefile
    format, with an extra section for our data.  */
 
-static void
-record_full_save (struct target_ops *self, const char *recfilename)
+void
+record_full_base_target::save_record (const char *recfilename)
 {
   struct record_full_entry *cur_record_full_list;
   uint32_t magic;
@@ -2790,10 +2808,8 @@ _initialize_record_full (void)
   record_full_first.next = NULL;
   record_full_first.type = record_full_end;
 
-  init_record_full_ops ();
   add_target (&record_full_ops);
   add_deprecated_target_alias (&record_full_ops, "record");
-  init_record_full_core_ops ();
   add_target (&record_full_core_ops);
 
   add_prefix_cmd ("full", class_obscure, cmd_record_full_start,
diff --git a/gdb/record.c b/gdb/record.c
index 7c35dc8989..492d516ea2 100644
--- a/gdb/record.c
+++ b/gdb/record.c
@@ -154,9 +154,9 @@ record_read_memory (struct gdbarch *gdbarch,
 static void
 record_stop (struct target_ops *t)
 {
-  DEBUG ("stop %s", t->to_shortname);
+  DEBUG ("stop %s", t->shortname ());
 
-  t->to_stop_recording (t);
+  t->stop_recording ();
 }
 
 /* Unpush the record target.  */
@@ -164,7 +164,7 @@ record_stop (struct target_ops *t)
 static void
 record_unpush (struct target_ops *t)
 {
-  DEBUG ("unpush %s", t->to_shortname);
+  DEBUG ("unpush %s", t->shortname ());
 
   unpush_target (t);
 }
@@ -176,7 +176,7 @@ record_disconnect (struct target_ops *t, const char *args, int from_tty)
 {
   gdb_assert (t->to_stratum == record_stratum);
 
-  DEBUG ("disconnect %s", t->to_shortname);
+  DEBUG ("disconnect %s", t->shortname ());
 
   record_stop (t);
   record_unpush (t);
@@ -191,7 +191,7 @@ record_detach (struct target_ops *t, inferior *inf, int from_tty)
 {
   gdb_assert (t->to_stratum == record_stratum);
 
-  DEBUG ("detach %s", t->to_shortname);
+  DEBUG ("detach %s", t->shortname ());
 
   record_stop (t);
   record_unpush (t);
@@ -206,7 +206,7 @@ record_mourn_inferior (struct target_ops *t)
 {
   gdb_assert (t->to_stratum == record_stratum);
 
-  DEBUG ("mourn inferior %s", t->to_shortname);
+  DEBUG ("mourn inferior %s", t->shortname ());
 
   /* It is safer to not stop recording.  Resources will be freed when
      threads are discarded.  */
@@ -222,7 +222,7 @@ record_kill (struct target_ops *t)
 {
   gdb_assert (t->to_stratum == record_stratum);
 
-  DEBUG ("kill %s", t->to_shortname);
+  DEBUG ("kill %s", t->shortname ());
 
   /* It is safer to not stop recording.  Resources will be freed when
      threads are discarded.  */
@@ -346,8 +346,8 @@ info_record_command (const char *args, int from_tty)
       return;
     }
 
-  printf_filtered (_("Active record target: %s\n"), t->to_shortname);
-  t->to_info_record (t);
+  printf_filtered (_("Active record target: %s\n"), t->shortname ());
+  t->info_record ();
 }
 
 /* The "record save" command.  */
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 33/40] target_ops/C++: The rest of the BSD targets
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (32 preceding siblings ...)
  2018-04-14 19:20 ` [PATCH 11/40] target_ops/C++: remote/extended-remote targets Pedro Alves
@ 2018-04-14 19:20 ` Pedro Alves
  2018-04-14 19:20 ` [PATCH 06/40] target_ops/C++: spu-multiarch Pedro Alves
                   ` (7 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:20 UTC (permalink / raw)
  To: gdb-patches

The

  $architecture x NetBSD/OpenBSD/FreeBSD

support matrix complicates things a bit.  There's common BSD target
code, and there's common architecture-specific code shared between the
different BSDs.  Current, all that is stiched together to form a final
target, via the i386bsd_target, x86bsd_target, fbsd_nat_add_target
functions etc.

This patch converts the rest of the BSD targets to C++ified target_ops.

Adds new obsd_nat_target and nbsd_nat_target targets similar to
fbsd_nat_target introduced a couple patches ago, a sparc_target mixin
similar to the one introduced in the previous patch for x86, and then
stiches everything together into final targets.

Unfortunately, I'm not able to test most of this.  I was able to build
GDB for AMD64 NetBSD on the compile farm, but that's it.
---
 gdb/aarch64-fbsd-nat.c | 27 +++++++++++++++------------
 gdb/alpha-bsd-nat.c    | 25 +++++++++++++------------
 gdb/amd64-nbsd-nat.c   | 10 ++++------
 gdb/amd64-obsd-nat.c   |  6 ++++--
 gdb/arm-fbsd-nat.c     | 35 ++++++++++++++++++-----------------
 gdb/arm-nbsd-nat.c     | 27 +++++++++++++++------------
 gdb/hppa-nbsd-nat.c    | 30 +++++++++++++-----------------
 gdb/hppa-obsd-nat.c    | 25 +++++++++++++------------
 gdb/i386-nbsd-nat.c    |  9 +++------
 gdb/i386-obsd-nat.c    |  5 +++--
 gdb/m68k-bsd-nat.c     | 25 +++++++++++++------------
 gdb/m88k-bsd-nat.c     | 25 +++++++++++++------------
 gdb/mips-fbsd-nat.c    | 25 +++++++++++++------------
 gdb/mips-nbsd-nat.c    | 25 +++++++++++++------------
 gdb/mips64-obsd-nat.c  | 23 ++++++++++++-----------
 gdb/nbsd-nat.c         |  2 +-
 gdb/nbsd-nat.h         | 10 +++++++---
 gdb/obsd-nat.c         | 32 +++++++-------------------------
 gdb/obsd-nat.h         | 10 +++++++++-
 gdb/ppc-fbsd-nat.c     | 26 +++++++++++++-------------
 gdb/ppc-nbsd-nat.c     | 26 +++++++++++++-------------
 gdb/ppc-obsd-nat.c     | 26 +++++++++++++-------------
 gdb/sh-nbsd-nat.c      | 24 ++++++++++++------------
 gdb/sparc-nat.c        | 33 +--------------------------------
 gdb/sparc-nat.h        | 39 +++++++++++++++++++++++++++++++++++----
 gdb/sparc-nbsd-nat.c   |  5 +++--
 gdb/sparc64-fbsd-nat.c |  7 ++++---
 gdb/sparc64-nbsd-nat.c |  6 ++++--
 gdb/sparc64-obsd-nat.c |  5 ++++-
 gdb/vax-bsd-nat.c      | 25 +++++++++++++------------
 30 files changed, 304 insertions(+), 294 deletions(-)

diff --git a/gdb/aarch64-fbsd-nat.c b/gdb/aarch64-fbsd-nat.c
index 4f4eb8990e..5ffbf1fdb1 100644
--- a/gdb/aarch64-fbsd-nat.c
+++ b/gdb/aarch64-fbsd-nat.c
@@ -29,6 +29,14 @@
 #include "aarch64-fbsd-tdep.h"
 #include "inf-ptrace.h"
 
+struct aarch64_fbsd_nat_target final : public fbsd_nat_target
+{
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+};
+
+static aarch64_fbsd_nat_target the_aarch64_fbsd_nat_target;
+
 /* Determine if PT_GETREGS fetches REGNUM.  */
 
 static bool
@@ -48,9 +56,9 @@ getfpregs_supplies (struct gdbarch *gdbarch, int regnum)
 /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
    for all registers.  */
 
-static void
-aarch64_fbsd_fetch_inferior_registers (struct target_ops *ops,
-				    struct regcache *regcache, int regnum)
+void
+aarch64_fbsd_nat_target::fetch_registers (struct regcache *regcache,
+					  int regnum)
 {
   pid_t pid = get_ptrace_pid (regcache_get_ptid (regcache));
 
@@ -81,9 +89,9 @@ aarch64_fbsd_fetch_inferior_registers (struct target_ops *ops,
 /* Store register REGNUM back into the inferior.  If REGNUM is -1, do
    this for all registers.  */
 
-static void
-aarch64_fbsd_store_inferior_registers (struct target_ops *ops,
-				    struct regcache *regcache, int regnum)
+void
+aarch64_fbsd_nat_target::store_registers (struct regcache *regcache,
+					  int regnum)
 {
   pid_t pid = get_ptrace_pid (regcache_get_ptid (regcache));
 
@@ -120,10 +128,5 @@ aarch64_fbsd_store_inferior_registers (struct target_ops *ops,
 void
 _initialize_aarch64_fbsd_nat (void)
 {
-  struct target_ops *t;
-
-  t = inf_ptrace_target ();
-  t->to_fetch_registers = aarch64_fbsd_fetch_inferior_registers;
-  t->to_store_registers = aarch64_fbsd_store_inferior_registers;
-  fbsd_nat_add_target (t);
+  add_target (&the_aarch64_fbsd_nat_target);
 }
diff --git a/gdb/alpha-bsd-nat.c b/gdb/alpha-bsd-nat.c
index 80139b66e4..5dc7a32235 100644
--- a/gdb/alpha-bsd-nat.c
+++ b/gdb/alpha-bsd-nat.c
@@ -43,6 +43,14 @@ typedef struct fpreg fpregset_t;
 
 #include "gregset.h"
 
+struct alpha_bsd_nat_target : public inf_ptrace_target
+{
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+};
+
+static alpha_bsd_nat_target the_alpha_bsd_nat_target;
+
 /* Provide *regset() wrappers around the generic Alpha BSD register
    supply/fill routines.  */
 
@@ -83,9 +91,8 @@ getregs_supplies (int regno)
 /* Fetch register REGNO from the inferior.  If REGNO is -1, do this
    for all registers (including the floating point registers).  */
 
-static void
-alphabsd_fetch_inferior_registers (struct target_ops *ops,
-				   struct regcache *regcache, int regno)
+void
+alpha_bsd_nat_target::fetch_registers (struct regcache *regcache, int regno)
 {
   if (regno == -1 || getregs_supplies (regno))
     {
@@ -116,9 +123,8 @@ alphabsd_fetch_inferior_registers (struct target_ops *ops,
 /* Store register REGNO back into the inferior.  If REGNO is -1, do
    this for all registers (including the floating point registers).  */
 
-static void
-alphabsd_store_inferior_registers (struct target_ops *ops,
-				   struct regcache *regcache, int regno)
+void
+alpha_bsd_nat_target::store_registers (struct regcache *regcache, int regno)
 {
   if (regno == -1 || getregs_supplies (regno))
     {
@@ -190,12 +196,7 @@ alphabsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
 void
 _initialize_alphabsd_nat (void)
 {
-  struct target_ops *t;
-
-  t = inf_ptrace_target ();
-  t->to_fetch_registers = alphabsd_fetch_inferior_registers;
-  t->to_store_registers = alphabsd_store_inferior_registers;
-  add_target (t);
+  add_target (&the_alpha_bsd_nat_target);
 
   /* Support debugging kernel virtual memory images.  */
   bsd_kvm_add_target (alphabsd_supply_pcb);
diff --git a/gdb/amd64-nbsd-nat.c b/gdb/amd64-nbsd-nat.c
index cd8478342b..e1c07dfb4c 100644
--- a/gdb/amd64-nbsd-nat.c
+++ b/gdb/amd64-nbsd-nat.c
@@ -22,6 +22,7 @@
 
 #include "nbsd-nat.h"
 #include "amd64-tdep.h"
+#include "amd64-bsd-nat.h"
 #include "amd64-nat.h"
 
 /* Mapping between the general-purpose registers in NetBSD/amd64
@@ -53,17 +54,14 @@ static int amd64nbsd32_r_reg_offset[] =
   15 * 8			/* %gs */
 };
 
+static amd64_bsd_nat_target<nbsd_nat_target> the_amd64_nbsd_nat_target;
+
 void
 _initialize_amd64nbsd_nat (void)
 {
-  struct target_ops *t;
-
   amd64_native_gregset32_reg_offset = amd64nbsd32_r_reg_offset;
   amd64_native_gregset32_num_regs = ARRAY_SIZE (amd64nbsd32_r_reg_offset);
   amd64_native_gregset64_reg_offset = amd64nbsd_r_reg_offset;
 
-  /* Add some extra features to the common *BSD/amd64 target.  */
-  t = amd64bsd_target ();
-  t->to_pid_to_exec_file = nbsd_pid_to_exec_file;
-  add_target (t);
+  add_target (&the_amd64_nbsd_nat_target);
 }
diff --git a/gdb/amd64-obsd-nat.c b/gdb/amd64-obsd-nat.c
index 76ea48048e..d6756d9463 100644
--- a/gdb/amd64-obsd-nat.c
+++ b/gdb/amd64-obsd-nat.c
@@ -23,6 +23,7 @@
 #include "target.h"
 
 #include "amd64-tdep.h"
+#include "amd64-bsd-nat.h"
 #include "amd64-nat.h"
 #include "obsd-nat.h"
 
@@ -125,6 +126,8 @@ amd64obsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
   return 1;
 }
 
+static amd64_bsd_nat_target<obsd_nat_target> the_amd64_obsd_nat_target;
+
 void
 _initialize_amd64obsd_nat (void)
 {
@@ -132,8 +135,7 @@ _initialize_amd64obsd_nat (void)
   amd64_native_gregset32_num_regs = ARRAY_SIZE (amd64obsd32_r_reg_offset);
   amd64_native_gregset64_reg_offset = amd64obsd_r_reg_offset;
 
-  /* Add some extra features to the common *BSD/amd64 target.  */
-  obsd_add_target (amd64bsd_target ());
+  add_target (&the_amd64_obsd_nat_target);
 
   /* Support debugging kernel virtual memory images.  */
   bsd_kvm_add_target (amd64obsd_supply_pcb);
diff --git a/gdb/arm-fbsd-nat.c b/gdb/arm-fbsd-nat.c
index 5b9fcc0a26..f31ee5fa1d 100644
--- a/gdb/arm-fbsd-nat.c
+++ b/gdb/arm-fbsd-nat.c
@@ -29,6 +29,15 @@
 #include "arm-fbsd-tdep.h"
 #include "inf-ptrace.h"
 
+struct arm_fbsd_nat_target : public fbsd_nat_target
+{
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+  const struct target_desc *read_description () override;
+};
+
+static arm_fbsd_nat_target the_arm_fbsd_nat_target;
+
 /* Determine if PT_GETREGS fetches REGNUM.  */
 
 static bool
@@ -52,9 +61,8 @@ getvfpregs_supplies (struct gdbarch *gdbarch, int regnum)
 /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
    for all registers.  */
 
-static void
-arm_fbsd_fetch_inferior_registers (struct target_ops *ops,
-				    struct regcache *regcache, int regnum)
+void
+arm_fbsd_nat_target::fetch_registers (struct regcache *regcache, int regnum)
 {
   pid_t pid = get_ptrace_pid (regcache_get_ptid (regcache));
 
@@ -87,9 +95,8 @@ arm_fbsd_fetch_inferior_registers (struct target_ops *ops,
 /* Store register REGNUM back into the inferior.  If REGNUM is -1, do
    this for all registers.  */
 
-static void
-arm_fbsd_store_inferior_registers (struct target_ops *ops,
-				    struct regcache *regcache, int regnum)
+void
+arm_fbsd_nat_target::store_registers (struct regcache *regcache, int regnum)
 {
   pid_t pid = get_ptrace_pid (regcache_get_ptid (regcache));
 
@@ -127,25 +134,19 @@ arm_fbsd_store_inferior_registers (struct target_ops *ops,
 
 /* Implement the to_read_description method.  */
 
-static const struct target_desc *
-arm_fbsd_read_description (struct target_ops *ops)
+const struct target_desc *
+arm_fbsd_nat_target::read_description ()
 {
   const struct target_desc *desc;
 
-  desc = arm_fbsd_read_description_auxv (ops);
+  desc = arm_fbsd_read_description_auxv (this);
   if (desc == NULL)
-    desc = ops->beneath->to_read_description (ops->beneath);
+    desc = this->beneath->read_description ();
   return desc;
 }
 
 void
 _initialize_arm_fbsd_nat (void)
 {
-  struct target_ops *t;
-
-  t = inf_ptrace_target ();
-  t->to_fetch_registers = arm_fbsd_fetch_inferior_registers;
-  t->to_store_registers = arm_fbsd_store_inferior_registers;
-  t->to_read_description = arm_fbsd_read_description;
-  fbsd_nat_add_target (t);
+  add_target (&the_arm_fbsd_nat_target);
 }
diff --git a/gdb/arm-nbsd-nat.c b/gdb/arm-nbsd-nat.c
index 9d603b1e0e..9d58b35a2a 100644
--- a/gdb/arm-nbsd-nat.c
+++ b/gdb/arm-nbsd-nat.c
@@ -30,6 +30,16 @@
 #include "arm-tdep.h"
 #include "inf-ptrace.h"
 
+class arm_netbsd_nat_target final : public inf_ptrace_target
+{
+public:
+  /* Add our register access methods.  */
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+};
+
+static arm_netbsd_nat_target the_arm_netbsd_nat_target;
+
 extern int arm_apcs_32;
 
 static void
@@ -190,9 +200,8 @@ fetch_fp_regs (struct regcache *regcache)
   arm_supply_fparegset (regcache, &inferior_fp_registers);
 }
 
-static void
-armnbsd_fetch_registers (struct target_ops *ops,
-			 struct regcache *regcache, int regno)
+void
+arm_nbsd_nat_target::fetch_registers (struct regcache *regcache, int regno)
 {
   if (regno >= 0)
     {
@@ -391,9 +400,8 @@ store_fp_regs (const struct regcache *regcache)
     warning (_("unable to store floating-point registers"));
 }
 
-static void
-armnbsd_store_registers (struct target_ops *ops,
-			 struct regcache *regcache, int regno)
+void
+arm_nbsd_nat_target::store_registers (struct regcache *regcache, int regno)
 {
   if (regno >= 0)
     {
@@ -461,12 +469,7 @@ static struct core_fns arm_netbsd_elfcore_fns =
 void
 _initialize_arm_netbsd_nat (void)
 {
-  struct target_ops *t;
-
-  t = inf_ptrace_target ();
-  t->to_fetch_registers = armnbsd_fetch_registers;
-  t->to_store_registers = armnbsd_store_registers;
-  add_target (t);
+  add_target (&the_arm_netbsd_nat_target);
 
   deprecated_add_core_fns (&arm_netbsd_elfcore_fns);
 }
diff --git a/gdb/hppa-nbsd-nat.c b/gdb/hppa-nbsd-nat.c
index c74ec34f32..1497166145 100644
--- a/gdb/hppa-nbsd-nat.c
+++ b/gdb/hppa-nbsd-nat.c
@@ -30,6 +30,14 @@
 
 #include "nbsd-nat.h"
 
+class hppa_nbsd_nat_target final : public nbsd_nat_target
+{
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+};
+
+static hppa_nbsd_nat_target the_hppa_nbsd_nat_target;
+
 static int
 hppanbsd_gregset_supplies_p (int regnum)
 {
@@ -158,9 +166,8 @@ hppanbsd_collect_fpregset (struct regcache *regcache,
 /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
    for all registers (including the floating-point registers).  */
 
-static void
-hppanbsd_fetch_registers (struct target_ops *ops,
-			  struct regcache *regcache, int regnum)
+void
+hppa_nbsd_nat_target::fetch_registers (struct regcache *regcache, int regnum)
 
 {
   pid_t pid = ptid_get_pid (regcache_get_ptid (regcache));
@@ -189,9 +196,8 @@ hppanbsd_fetch_registers (struct target_ops *ops,
 /* Store register REGNUM back into the inferior.  If REGNUM is -1, do
    this for all registers (including the floating-point registers).  */
 
-static void
-hppanbsd_store_registers (struct target_ops *ops,
-			  struct regcache *regcache, int regnum)
+void
+hppa_nbsd_nat_target::store_registers (struct regcache *regcache, int regnum)
 {
   pid_t pid = ptid_get_pid (regcache_get_ptid (regcache));
 
@@ -225,15 +231,5 @@ hppanbsd_store_registers (struct target_ops *ops,
 void
 _initialize_hppanbsd_nat (void)
 {
-  struct target_ops *t;
-
-  /* Add some extra features to the ptrace target.  */
-  t = inf_ptrace_target ();
-
-  t->to_fetch_registers = hppanbsd_fetch_registers;
-  t->to_store_registers = hppanbsd_store_registers;
-
-  t->to_pid_to_exec_file = nbsd_pid_to_exec_file;
-
-  add_target (t);
+  add_target (&the_hppa_nbsd_nat_target);
 }
diff --git a/gdb/hppa-obsd-nat.c b/gdb/hppa-obsd-nat.c
index 340b30eeb3..2bef638a31 100644
--- a/gdb/hppa-obsd-nat.c
+++ b/gdb/hppa-obsd-nat.c
@@ -31,6 +31,14 @@
 
 #include "obsd-nat.h"
 
+struct hppa_obsd_nat_target : public obsd_nat_target
+{
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+};
+
+static hppa_obsd_nat_target the_hppa_obsd_nat_target;
+
 static int
 hppaobsd_gregset_supplies_p (int regnum)
 {
@@ -185,9 +193,8 @@ hppaobsd_collect_fpregset (struct regcache *regcache,
 /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
    for all registers (including the floating-point registers).  */
 
-static void
-hppaobsd_fetch_registers (struct target_ops *ops,
-			  struct regcache *regcache, int regnum)
+void
+hppa_obsd_nat_target::fetch_registers (struct regcache *regcache, int regnum)
 {
   pid_t pid = ptid_get_pid (regcache_get_ptid (regcache));
 
@@ -215,9 +222,8 @@ hppaobsd_fetch_registers (struct target_ops *ops,
 /* Store register REGNUM back into the inferior.  If REGNUM is -1, do
    this for all registers (including the floating-point registers).  */
 
-static void
-hppaobsd_store_registers (struct target_ops *ops,
-			  struct regcache *regcache, int regnum)
+void
+hppa_obsd_nat_target::store_registers (struct regcache *regcache, int regnum)
 {
   if (regnum == -1 || hppaobsd_gregset_supplies_p (regnum))
     {
@@ -249,10 +255,5 @@ hppaobsd_store_registers (struct target_ops *ops,
 void
 _initialize_hppaobsd_nat (void)
 {
-  struct target_ops *t;
-
-  t = inf_ptrace_target ();
-  t->to_fetch_registers = hppaobsd_fetch_registers;
-  t->to_store_registers = hppaobsd_store_registers;
-  obsd_add_target (t);
+  add_target (&the_hppa_obsd_nat_target);
 }
diff --git a/gdb/i386-nbsd-nat.c b/gdb/i386-nbsd-nat.c
index 6b0bcc9269..508abdc92e 100644
--- a/gdb/i386-nbsd-nat.c
+++ b/gdb/i386-nbsd-nat.c
@@ -71,16 +71,13 @@ i386nbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
   return 1;
 }
 
+static i386_bsd_nat_target<nbsd_nat_target> the_i386_nbsd_nat_target;
+
 void
 _initialize_i386nbsd_nat (void)
 {
-  struct target_ops *t;
+  add_target (&the_i386_nbsd_nat_target);
 
-  /* Add some extra features to the common *BSD/i386 target.  */
-  t = i386bsd_target ();
-  t->to_pid_to_exec_file = nbsd_pid_to_exec_file;
-  add_target (t);
- 
   /* Support debugging kernel virtual memory images.  */
   bsd_kvm_add_target (i386nbsd_supply_pcb);
 }
diff --git a/gdb/i386-obsd-nat.c b/gdb/i386-obsd-nat.c
index bc3a2edde6..2a09f3e0d6 100644
--- a/gdb/i386-obsd-nat.c
+++ b/gdb/i386-obsd-nat.c
@@ -88,11 +88,12 @@ i386obsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
   return 1;
 }
 
+static i386_bsd_nat_target<obsd_nat_target> the_i386_obsd_nat_target;
+
 void
 _initialize_i386obsd_nat (void)
 {
-  /* Add some extra features to the common *BSD/i386 target.  */
-  obsd_add_target (i386bsd_target ());
+  add_target (&i386_obsd_nat_target);
 
   /* Support debugging kernel virtual memory images.  */
   bsd_kvm_add_target (i386obsd_supply_pcb);
diff --git a/gdb/m68k-bsd-nat.c b/gdb/m68k-bsd-nat.c
index 2d96b23cf6..372ef2233a 100644
--- a/gdb/m68k-bsd-nat.c
+++ b/gdb/m68k-bsd-nat.c
@@ -29,6 +29,14 @@
 #include "m68k-tdep.h"
 #include "inf-ptrace.h"
 
+struct m68k_bsd_nat_target : public inf_ptrace_target
+{
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+};
+
+static m68k_bsd_nat_target the_m68k_bsd_nat_target;
+
 static int
 m68kbsd_gregset_supplies_p (int regnum)
 {
@@ -107,9 +115,8 @@ m68kbsd_collect_fpregset (struct regcache *regcache,
 /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
    for all registers (including the floating-point registers).  */
 
-static void
-m68kbsd_fetch_inferior_registers (struct target_ops *ops,
-				  struct regcache *regcache, int regnum)
+void
+m68k_bsd_nat_target::fetch_registers (struct regcache *regcache, int regnum)
 {
   pid_t pid = ptid_get_pid (regcache_get_ptid (regcache));
 
@@ -137,9 +144,8 @@ m68kbsd_fetch_inferior_registers (struct target_ops *ops,
 /* Store register REGNUM back into the inferior.  If REGNUM is -1, do
    this for all registers (including the floating-point registers).  */
 
-static void
-m68kbsd_store_inferior_registers (struct target_ops *ops,
-				  struct regcache *regcache, int regnum)
+void
+m68k_bsd_nat_target::store_registers (struct regcache *regcache, int regnum)
 {
   pid_t pid = ptid_get_pid (regcache_get_ptid (regcache));
 
@@ -219,12 +225,7 @@ m68kbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
 void
 _initialize_m68kbsd_nat (void)
 {
-  struct target_ops *t;
-
-  t = inf_ptrace_target ();
-  t->to_fetch_registers = m68kbsd_fetch_inferior_registers;
-  t->to_store_registers = m68kbsd_store_inferior_registers;
-  add_target (t);
+  add_target (&the_m68k_bsd_nat_target);
 
   /* Support debugging kernel virtual memory images.  */
   bsd_kvm_add_target (m68kbsd_supply_pcb);
diff --git a/gdb/m88k-bsd-nat.c b/gdb/m88k-bsd-nat.c
index ff9c5a241b..255d2ffba9 100644
--- a/gdb/m88k-bsd-nat.c
+++ b/gdb/m88k-bsd-nat.c
@@ -29,6 +29,14 @@
 #include "m88k-tdep.h"
 #include "inf-ptrace.h"
 
+struct m88k_bsd_nat_target : public inf_ptrace_target
+{
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+};
+
+static m88k_bsd_nat_target the_m88k_bsd_nat_target;
+
 /* Supply the general-purpose registers stored in GREGS to REGCACHE.  */
 
 static void
@@ -62,9 +70,8 @@ m88kbsd_collect_gregset (const struct regcache *regcache,
 /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
    for all registers.  */
 
-static void
-m88kbsd_fetch_inferior_registers (struct target_ops *ops,
-				  struct regcache *regcache, int regnum)
+void
+m88k_bsd_nat_target::fetch_registers (struct regcache *regcache, int regnum)
 {
   struct reg regs;
 
@@ -78,9 +85,8 @@ m88kbsd_fetch_inferior_registers (struct target_ops *ops,
 /* Store register REGNUM back into the inferior.  If REGNUM is -1, do
    this for all registers.  */
 
-static void
-m88kbsd_store_inferior_registers (struct target_ops *ops,
-				  struct regcache *regcache, int regnum)
+void
+m88k_bsd_nat_target::store_registers (struct regcache *regcache, int regnum)
 {
   struct reg regs;
 
@@ -98,10 +104,5 @@ m88kbsd_store_inferior_registers (struct target_ops *ops,
 void
 _initialize_m88kbsd_nat (void)
 {
-  struct target_ops *t;
-
-  t = inf_ptrace_target ();
-  t->to_fetch_registers = m88kbsd_fetch_inferior_registers;
-  t->to_store_registers = m88kbsd_store_inferior_registers;
-  add_target (t);
+  add_target (&the_m88k_bsd_nat_target);
 }
diff --git a/gdb/mips-fbsd-nat.c b/gdb/mips-fbsd-nat.c
index 6c559b0545..3b38b580a9 100644
--- a/gdb/mips-fbsd-nat.c
+++ b/gdb/mips-fbsd-nat.c
@@ -31,6 +31,14 @@
 #include "mips-fbsd-tdep.h"
 #include "inf-ptrace.h"
 
+struct mips_fbsd_nat_target : public fbsd_nat_target
+{
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+};
+
+static mips_fbsd_nat_target the_mips_fbsd_nat_target;
+
 /* Determine if PT_GETREGS fetches REGNUM.  */
 
 static bool
@@ -52,9 +60,8 @@ getfpregs_supplies (struct gdbarch *gdbarch, int regnum)
 /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
    for all registers.  */
 
-static void
-mips_fbsd_fetch_inferior_registers (struct target_ops *ops,
-				    struct regcache *regcache, int regnum)
+void
+mips_fbsd_nat_target::fetch_registers (struct regcache *regcache, int regnum)
 {
   pid_t pid = get_ptrace_pid (regcache_get_ptid (regcache));
 
@@ -84,9 +91,8 @@ mips_fbsd_fetch_inferior_registers (struct target_ops *ops,
 /* Store register REGNUM back into the inferior.  If REGNUM is -1, do
    this for all registers.  */
 
-static void
-mips_fbsd_store_inferior_registers (struct target_ops *ops,
-				    struct regcache *regcache, int regnum)
+void
+mips_fbsd_nat_target::store_registers (struct regcache *regcache, int regnum)
 {
   pid_t pid = get_ptrace_pid (regcache_get_ptid (regcache));
 
@@ -123,10 +129,5 @@ mips_fbsd_store_inferior_registers (struct target_ops *ops,
 void
 _initialize_mips_fbsd_nat (void)
 {
-  struct target_ops *t;
-
-  t = inf_ptrace_target ();
-  t->to_fetch_registers = mips_fbsd_fetch_inferior_registers;
-  t->to_store_registers = mips_fbsd_store_inferior_registers;
-  fbsd_nat_add_target (t);
+  add_target (&the_mips_fbsd_nat_target);
 }
diff --git a/gdb/mips-nbsd-nat.c b/gdb/mips-nbsd-nat.c
index 3dc61ff33e..74b2060c13 100644
--- a/gdb/mips-nbsd-nat.c
+++ b/gdb/mips-nbsd-nat.c
@@ -30,6 +30,14 @@
 #include "mips-nbsd-tdep.h"
 #include "inf-ptrace.h"
 
+class mips_nbsd_nat_target final : public inf_ptrace_target
+{
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+};
+
+static mips_nbsd_nat_target the_mips_nbsd_nat_target;
+
 /* Determine if PT_GETREGS fetches this register.  */
 static int
 getregs_supplies (struct gdbarch *gdbarch, int regno)
@@ -38,9 +46,8 @@ getregs_supplies (struct gdbarch *gdbarch, int regno)
 	  && (regno) <= gdbarch_pc_regnum (gdbarch));
 }
 
-static void
-mipsnbsd_fetch_inferior_registers (struct target_ops *ops,
-				   struct regcache *regcache, int regno)
+void
+mips_nbsd_nat_target::fetch_registers (struct regcache *regcache, int regno)
 {
   pid_t pid = ptid_get_pid (regcache_get_ptid (regcache));
 
@@ -69,9 +76,8 @@ mipsnbsd_fetch_inferior_registers (struct target_ops *ops,
     }
 }
 
-static void
-mipsnbsd_store_inferior_registers (struct target_ops *ops,
-				   struct regcache *regcache, int regno)
+void
+mips_nbsd_nat_target::store_registers (struct regcache *regcache, int regno)
 {
   pid_t pid = ptid_get_pid (regcache_get_ptid (regcache));
 
@@ -110,10 +116,5 @@ mipsnbsd_store_inferior_registers (struct target_ops *ops,
 void
 _initialize_mipsnbsd_nat (void)
 {
-  struct target_ops *t;
-
-  t = inf_ptrace_target ();
-  t->to_fetch_registers = mipsnbsd_fetch_inferior_registers;
-  t->to_store_registers = mipsnbsd_store_inferior_registers;
-  add_target (t);
+  add_target (&the_mips_nbsd_nat_target);
 }
diff --git a/gdb/mips64-obsd-nat.c b/gdb/mips64-obsd-nat.c
index d616418da1..2193972f07 100644
--- a/gdb/mips64-obsd-nat.c
+++ b/gdb/mips64-obsd-nat.c
@@ -35,6 +35,14 @@
 #define MIPS_FP0_REGNUM	MIPS_EMBED_FP0_REGNUM
 #define MIPS_FSR_REGNUM MIPS_EMBED_FP0_REGNUM + 32
 
+struct mips64_obsd_nat_target : public obsd_nat_target
+{
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+};
+
+static mips64_obsd_nat_target the_mips64_obsd_nat_target;
+
 /* Supply the general-purpose registers stored in GREGS to REGCACHE.  */
 
 static void
@@ -77,9 +85,8 @@ mips64obsd_collect_gregset (const struct regcache *regcache,
 /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
    for all registers.  */
 
-static void
-mips64obsd_fetch_inferior_registers (struct target_ops *ops,
-				     struct regcache *regcache, int regnum)
+void
+mips64_obsd_nat_target::fetch_registers (struct regcache *regcache, int regnum)
 {
   struct reg regs;
   pid_t pid = ptid_get_pid (regcache_get_ptid (regcache));
@@ -94,8 +101,7 @@ mips64obsd_fetch_inferior_registers (struct target_ops *ops,
    this for all registers.  */
 
 static void
-mips64obsd_store_inferior_registers (struct target_ops *ops,
-				     struct regcache *regcache, int regnum)
+mips64_obsd_nat_target::store_registers (struct regcache *regcache, int regnum)
 {
   struct reg regs;
   pid_t pid = ptid_get_pid (regcache_get_ptid (regcache));
@@ -112,10 +118,5 @@ mips64obsd_store_inferior_registers (struct target_ops *ops,
 void
 _initialize_mips64obsd_nat (void)
 {
-  struct target_ops *t;
-
-  t = inf_ptrace_target ();
-  t->to_fetch_registers = mips64obsd_fetch_inferior_registers;
-  t->to_store_registers = mips64obsd_store_inferior_registers;
-  obsd_add_target (t);
+  add_target (&the_mips64_obsd_nat_target);
 }
diff --git a/gdb/nbsd-nat.c b/gdb/nbsd-nat.c
index 72c3c0618d..d10d1ebe38 100644
--- a/gdb/nbsd-nat.c
+++ b/gdb/nbsd-nat.c
@@ -25,7 +25,7 @@
    the child process identified by PID.  */
 
 char *
-nbsd_pid_to_exec_file (struct target_ops *self, int pid)
+nbsd_nat_target::pid_to_exec_file (int pid)
 {
   ssize_t len;
   static char buf[PATH_MAX];
diff --git a/gdb/nbsd-nat.h b/gdb/nbsd-nat.h
index 99732f064b..33d5802d0d 100644
--- a/gdb/nbsd-nat.h
+++ b/gdb/nbsd-nat.h
@@ -20,9 +20,13 @@
 #ifndef NBSD_NAT_H
 #define NBSD_NAT_H
 
-/* Return the name of a file that can be opened to get the symbols for
-   the child process identified by PID.  */
+#include "inf-ptrace.h"
 
-extern char *nbsd_pid_to_exec_file (struct target_ops *self, int pid);
+/* A prototype NetBSD target.  */
+
+struct nbsd_nat_target : public inf_ptrace_target
+{
+  char *pid_to_exec_file (int pid) override;
+};
 
 #endif /* nbsd-nat.h */
diff --git a/gdb/obsd-nat.c b/gdb/obsd-nat.c
index c3cd2958b4..91bed717a5 100644
--- a/gdb/obsd-nat.c
+++ b/gdb/obsd-nat.c
@@ -35,8 +35,8 @@
 
 #ifdef PT_GET_THREAD_FIRST
 
-static const char *
-obsd_pid_to_str (struct target_ops *ops, ptid_t ptid)
+const char *
+obsd_nat_target::pid_to_str (ptid_t ptid)
 {
   if (ptid_get_lwp (ptid) != 0)
     {
@@ -49,8 +49,8 @@ obsd_pid_to_str (struct target_ops *ops, ptid_t ptid)
   return normal_pid_to_str (ptid);
 }
 
-static void
-obsd_update_thread_list (struct target_ops *ops)
+void
+obsd_nat_target::update_thread_list ()
 {
   pid_t pid = ptid_get_pid (inferior_ptid);
   struct ptrace_thread_state pts;
@@ -77,9 +77,9 @@ obsd_update_thread_list (struct target_ops *ops)
     }
 }
 
-static ptid_t
-obsd_wait (struct target_ops *ops,
-	   ptid_t ptid, struct target_waitstatus *ourstatus, int options)
+ptid_t
+obsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
+		       int options)
 {
   pid_t pid;
   int status, save_errno;
@@ -165,22 +165,4 @@ obsd_wait (struct target_ops *ops,
   return ptid;
 }
 
-void
-obsd_add_target (struct target_ops *t)
-{
-  /* Override some methods to support threads.  */
-  t->to_pid_to_str = obsd_pid_to_str;
-  t->to_update_thread_list = obsd_update_thread_list;
-  t->to_wait = obsd_wait;
-  add_target (t);
-}
-
-#else
-
-void
-obsd_add_target (struct target_ops *t)
-{
-  add_target (t);
-}
-
 #endif /* PT_GET_THREAD_FIRST */
diff --git a/gdb/obsd-nat.h b/gdb/obsd-nat.h
index fb98c9ac8a..365ba5efa1 100644
--- a/gdb/obsd-nat.h
+++ b/gdb/obsd-nat.h
@@ -20,6 +20,14 @@
 #ifndef OBSD_NAT_H
 #define OBSD_NAT_H
 
-extern void obsd_add_target (struct target_ops *);
+#include "inf-ptrace.h"
+
+class obsd_nat_target : public inf_ptrace_target
+{
+  /* Override some methods to support threads.  */
+  const char *pid_to_str (ptid_t) override;
+  void update_thread_list () override;
+  ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
+};
 
 #endif /* obsd-nat.h */
diff --git a/gdb/ppc-fbsd-nat.c b/gdb/ppc-fbsd-nat.c
index 3afd3e61bb..e046fbb553 100644
--- a/gdb/ppc-fbsd-nat.c
+++ b/gdb/ppc-fbsd-nat.c
@@ -37,6 +37,14 @@
 #include "inf-ptrace.h"
 #include "bsd-kvm.h"
 
+struct ppc_fbsd_nat_target : public fbsd_nat_target
+{
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+};
+
+static ppc_fbsd_nat_target the_ppc_fbsd_nat_target;
+
 /* Fill GDB's register array with the general-purpose register values
    in *GREGSETP.  */
 
@@ -115,9 +123,8 @@ getfpregs_supplies (struct gdbarch *gdbarch, int regno)
 /* Fetch register REGNO from the child process. If REGNO is -1, do it
    for all registers.  */
 
-static void
-ppcfbsd_fetch_inferior_registers (struct target_ops *ops,
-				  struct regcache *regcache, int regno)
+void
+ppc_fbsd_nat_target::fetch_registers (struct regcache *regcache, int regno)
 {
   gdb_gregset_t regs;
   pid_t pid = ptid_get_lwp (regcache_get_ptid (regcache));
@@ -142,9 +149,8 @@ ppcfbsd_fetch_inferior_registers (struct target_ops *ops,
 /* Store register REGNO back into the child process. If REGNO is -1,
    do this for all registers.  */
 
-static void
-ppcfbsd_store_inferior_registers (struct target_ops *ops,
-				  struct regcache *regcache, int regno)
+void
+ppc_fbsd_nat_target::store_registers (struct regcache *regcache, int regno)
 {
   gdb_gregset_t regs;
   pid_t pid = ptid_get_lwp (regcache_get_ptid (regcache));
@@ -198,13 +204,7 @@ ppcfbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
 void
 _initialize_ppcfbsd_nat (void)
 {
-  struct target_ops *t;
-
-  /* Add in local overrides.  */
-  t = inf_ptrace_target ();
-  t->to_fetch_registers = ppcfbsd_fetch_inferior_registers;
-  t->to_store_registers = ppcfbsd_store_inferior_registers;
-  fbsd_nat_add_target (t);
+  add_target (&the_ppc_fbsd_nat_target);
 
   /* Support debugging kernel virtual memory images.  */
   bsd_kvm_add_target (ppcfbsd_supply_pcb);
diff --git a/gdb/ppc-nbsd-nat.c b/gdb/ppc-nbsd-nat.c
index 3fd679befa..e2b8083ad0 100644
--- a/gdb/ppc-nbsd-nat.c
+++ b/gdb/ppc-nbsd-nat.c
@@ -36,6 +36,14 @@
 #include "bsd-kvm.h"
 #include "inf-ptrace.h"
 
+class ppc_nbsd_nat_target final : public inf_ptrace_target
+{
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+};
+
+static ppc_nbsd_nat_target the_ppc_nbsd_nat_target;
+
 /* Returns true if PT_GETREGS fetches this register.  */
 
 static int
@@ -76,9 +84,8 @@ getfpregs_supplies (struct gdbarch *gdbarch, int regnum)
 	  || regnum == tdep->ppc_fpscr_regnum);
 }
 
-static void
-ppcnbsd_fetch_inferior_registers (struct target_ops *ops,
-				  struct regcache *regcache, int regnum)
+void
+ppc_nbsd_nat_target::fetch_registers (struct regcache *regcache, int regnum)
 {
   struct gdbarch *gdbarch = regcache->arch ();
   pid_t pid = ptid_get_pid (regcache_get_ptid (regcache));
@@ -106,9 +113,8 @@ ppcnbsd_fetch_inferior_registers (struct target_ops *ops,
     }
 }
 
-static void
-ppcnbsd_store_inferior_registers (struct target_ops *ops,
-				  struct regcache *regcache, int regnum)
+void
+ppc_nbsd_nat_target::store_registers (struct regcache *regcache, int regnum)
 {
   struct gdbarch *gdbarch = regcache->arch ();
   pid_t pid = ptid_get_pid (regcache_get_ptid (regcache));
@@ -177,14 +183,8 @@ ppcnbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
 void
 _initialize_ppcnbsd_nat (void)
 {
-  struct target_ops *t;
-
   /* Support debugging kernel virtual memory images.  */
   bsd_kvm_add_target (ppcnbsd_supply_pcb);
 
-  /* Add in local overrides.  */
-  t = inf_ptrace_target ();
-  t->to_fetch_registers = ppcnbsd_fetch_inferior_registers;
-  t->to_store_registers = ppcnbsd_store_inferior_registers;
-  add_target (t);
+  add_target (&the_ppc_nbsd_nat_target);
 }
diff --git a/gdb/ppc-obsd-nat.c b/gdb/ppc-obsd-nat.c
index 17dbd9e75c..27c4e1f414 100644
--- a/gdb/ppc-obsd-nat.c
+++ b/gdb/ppc-obsd-nat.c
@@ -35,6 +35,14 @@
 #include "obsd-nat.h"
 #include "bsd-kvm.h"
 
+struct ppc_obsd_nat_target : public obsd_nat_target
+{
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+};
+
+static ppc_obsd_nat_target the_ppc_obsd_nat_target;
+
 /* OpenBSD/powerpc didn't have PT_GETFPREGS/PT_SETFPREGS until release
    4.0.  On older releases the floating-point registers are handled by
    PT_GETREGS/PT_SETREGS, but fpscr wasn't available..  */
@@ -70,9 +78,8 @@ getfpregs_supplies (struct gdbarch *gdbarch, int regnum)
 /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
    for all registers.  */
 
-static void
-ppcobsd_fetch_registers (struct target_ops *ops,
-			 struct regcache *regcache, int regnum)
+void
+ppc_obsd_nat_target::fetch_registers (struct regcache *regcache, int regnum)
 {
   struct reg regs;
   pid_t pid = ptid_get_pid (regcache_get_ptid (regcache));
@@ -105,9 +112,8 @@ ppcobsd_fetch_registers (struct target_ops *ops,
 /* Store register REGNUM back into the inferior.  If REGNUM is -1, do
    this for all registers.  */
 
-static void
-ppcobsd_store_registers (struct target_ops *ops,
-			 struct regcache *regcache, int regnum)
+void
+ppc_obsd_nat_target::store_registers (struct regcache *regcache, int regnum)
 {
   struct reg regs;
   pid_t pid = ptid_get_pid (regcache_get_ptid (regcache));
@@ -184,13 +190,7 @@ ppcobsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
 void
 _initialize_ppcobsd_nat (void)
 {
-  struct target_ops *t;
-
-  /* Add in local overrides.  */
-  t = inf_ptrace_target ();
-  t->to_fetch_registers = ppcobsd_fetch_registers;
-  t->to_store_registers = ppcobsd_store_registers;
-  obsd_add_target (t);
+  add_target (&the_ppc_obsd_nat_target);
 
   /* General-purpose registers.  */
   ppcobsd_reg_offsets.r0_offset = offsetof (struct reg, gpr);
diff --git a/gdb/sh-nbsd-nat.c b/gdb/sh-nbsd-nat.c
index d923e19799..dad4381c9c 100644
--- a/gdb/sh-nbsd-nat.c
+++ b/gdb/sh-nbsd-nat.c
@@ -30,6 +30,13 @@
 #include "inf-ptrace.h"
 #include "regcache.h"
 
+class sh_nbsd_nat_target final : public inf_ptrace_target
+{
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+};
+
+static sh_nbsd_nat_target the_sh_nbsd_nat_target;
 
 /* Determine if PT_GETREGS fetches this register.  */
 #define GETREGS_SUPPLIES(gdbarch, regno) \
@@ -41,9 +48,8 @@
 /* Sizeof `struct reg' in <machine/reg.h>.  */
 #define SHNBSD_SIZEOF_GREGS	(21 * 4)
 
-static void
-shnbsd_fetch_inferior_registers (struct target_ops *ops,
-				 struct regcache *regcache, int regno)
+void
+sh_nbsd_nat_target::fetch_registers (struct regcache *regcache, int regno)
 {
   pid_t pid = ptid_get_pid (regcache_get_ptid (regcache));
 
@@ -64,9 +70,8 @@ shnbsd_fetch_inferior_registers (struct target_ops *ops,
     }
 }
 
-static void
-shnbsd_store_inferior_registers (struct target_ops *ops,
-				 struct regcache *regcache, int regno)
+void
+sh_nbsd_nat_target::store_registers (struct regcache *regcache, int regno)
 {
   pid_t pid = ptid_get_pid (regcache_get_ptid (regcache));
 
@@ -94,10 +99,5 @@ shnbsd_store_inferior_registers (struct target_ops *ops,
 void
 _initialize_shnbsd_nat (void)
 {
-  struct target_ops *t;
-
-  t = inf_ptrace_target ();
-  t->to_fetch_registers = shnbsd_fetch_inferior_registers;
-  t->to_store_registers = shnbsd_store_inferior_registers;
-  add_target (t);
+  add_target (&the_sh_nbsd_nat_target);
 }
diff --git a/gdb/sparc-nat.c b/gdb/sparc-nat.c
index 9aeaf22c5d..8b5c68619d 100644
--- a/gdb/sparc-nat.c
+++ b/gdb/sparc-nat.c
@@ -251,7 +251,7 @@ sparc_store_inferior_registers (struct regcache *regcache, int regnum)
 /* Implement the to_xfer_partial target_ops method for
    TARGET_OBJECT_WCOOKIE.  Fetch StackGhost Per-Process XOR cookie.  */
 
-static enum target_xfer_status
+enum target_xfer_status
 sparc_xfer_wcookie (struct target_ops *ops, enum target_object object,
 		    const char *annex, gdb_byte *readbuf,
 		    const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
@@ -303,38 +303,7 @@ sparc_xfer_wcookie (struct target_ops *ops, enum target_object object,
   *xfered_len = (ULONGEST) len;
   return TARGET_XFER_OK;
 }
-
-target_xfer_partial_ftype *inf_ptrace_xfer_partial;
-
-static enum target_xfer_status
-sparc_xfer_partial (struct target_ops *ops, enum target_object object,
-		    const char *annex, gdb_byte *readbuf,
-		    const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
-		    ULONGEST *xfered_len)
-{
-  if (object == TARGET_OBJECT_WCOOKIE)
-    return sparc_xfer_wcookie (ops, object, annex, readbuf, writebuf, 
-			       offset, len, xfered_len);
-
-  return inf_ptrace_xfer_partial (ops, object, annex, readbuf, writebuf,
-				  offset, len, xfered_len);
-}
 \f
-/* Create a prototype generic SPARC target.  The client can override
-   it with local methods.  */
-
-struct target_ops *
-sparc_target (void)
-{
-  struct target_ops *t;
-
-  t = inf_ptrace_target ();
-  t->to_fetch_registers = sparc_fetch_inferior_registers;
-  t->to_store_registers = sparc_store_inferior_registers;
-  inf_ptrace_xfer_partial = t->to_xfer_partial;
-  t->to_xfer_partial = sparc_xfer_partial;
-  return t;
-}
 
 void
 _initialize_sparc_nat (void)
diff --git a/gdb/sparc-nat.h b/gdb/sparc-nat.h
index f627fd33ed..b564c01fed 100644
--- a/gdb/sparc-nat.h
+++ b/gdb/sparc-nat.h
@@ -39,12 +39,43 @@ extern int (*sparc_fpregset_supplies_p) (struct gdbarch *gdbarch, int);
 extern int sparc32_gregset_supplies_p (struct gdbarch *gdbarch, int regnum);
 extern int sparc32_fpregset_supplies_p (struct gdbarch *gdbarch, int regnum);
 
-/* Create a prototype generic SPARC target.  The client can override
+extern void sparc_fetch_inferior_registers (struct regcache *, int);
+extern void sparc_store_inferior_registers (struct regcache *, int);
+
+extern target_xfer_status sparc_xfer_wcookie (enum target_object object,
+					      const char *annex,
+					      gdb_byte *readbuf,
+					      const gdb_byte *writebuf,
+					      ULONGEST offset,
+					      ULONGEST len,
+					      ULONGEST *xfered_len);
+
+/* A prototype generic SPARC target.  The client can override
    it with local methods.  */
 
-extern struct target_ops *sparc_target (void);
+template<typename BaseTarget>
+struct sparc_target : public BaseTarget
+{
+  void fetch_registers (struct regcache *regcache, int regnum) override
+  { sparc_fetch_inferior_registers (regcache, regnum); }
 
-extern void sparc_fetch_inferior_registers (struct regcache *, int);
-extern void sparc_store_inferior_registers (struct regcache *, int);
+  void store_registers (struct regcache *regcache, int regnum) override
+  { sparc_store_inferior_registers (regcache, regnum); }
+
+  enum target_xfer_status xfer_partial (enum target_object object,
+					const char *annex,
+					gdb_byte *readbuf,
+					const gdb_byte *writebuf,
+					ULONGEST offset, ULONGEST len,
+					ULONGEST *xfered_len) override
+  {
+    if (object == TARGET_OBJECT_WCOOKIE)
+      return sparc_xfer_wcookie (object, annex, readbuf, writebuf,
+				 offset, len, xfered_len);
+
+    return BaseTarget (object, annex, readbuf, writebuf,
+		       offset, len, xfered_len);
+  }
+};
 
 #endif /* sparc-nat.h */
diff --git a/gdb/sparc-nbsd-nat.c b/gdb/sparc-nbsd-nat.c
index fd76d0e51f..5ff723d342 100644
--- a/gdb/sparc-nbsd-nat.c
+++ b/gdb/sparc-nbsd-nat.c
@@ -55,14 +55,15 @@ sparc32nbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
   return 1;
 }
 
+static sparc_target<inf_ptrace_target> the_sparc_nbsd_nat_target;
+
 void
 _initialize_sparcnbsd_nat (void)
 {
   sparc_gregmap = &sparc32nbsd_gregmap;
   sparc_fpregmap = &sparc32_bsd_fpregmap;
 
-  /* We've got nothing to add to the generic SPARC target.  */
-  add_target (sparc_target ());
+  add_target (&sparc_nbsd_nat_target);
 
   /* Support debugging kernel virtual memory images.  */
   bsd_kvm_add_target (sparc32nbsd_supply_pcb);
diff --git a/gdb/sparc64-fbsd-nat.c b/gdb/sparc64-fbsd-nat.c
index ec577d7e58..00c1ece2db 100644
--- a/gdb/sparc64-fbsd-nat.c
+++ b/gdb/sparc64-fbsd-nat.c
@@ -59,14 +59,15 @@ sparc64fbsd_kvm_supply_pcb (struct regcache *regcache, struct pcb *pcb)
   return 1;
 }
 
+/* Add some extra features to the generic SPARC target.  */
+static sparc_target<fbsd_nat_target> the_sparc64_fbsd_nat_target;
+
 void
 _initialize_sparc64fbsd_nat (void)
 {
   struct target_ops *t;
 
-  /* Add some extra features to the generic SPARC target.  */
-  t = sparc_target ();
-  fbsd_nat_add_target (t);
+  add_target (&the_sparc64_fbsd_nat_target);
 
   sparc_gregmap = &sparc64fbsd_gregmap;
 
diff --git a/gdb/sparc64-nbsd-nat.c b/gdb/sparc64-nbsd-nat.c
index ef46df034f..a0bfd8138e 100644
--- a/gdb/sparc64-nbsd-nat.c
+++ b/gdb/sparc64-nbsd-nat.c
@@ -167,6 +167,9 @@ sparc64nbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
   return 1;
 }
 
+/* We've got nothing to add to the generic SPARC target.  */
+static sparc_target<inf_ptrace_target> the_sparc64_nbsd_nat_target;
+
 void
 _initialize_sparc64nbsd_nat (void)
 {
@@ -177,8 +180,7 @@ _initialize_sparc64nbsd_nat (void)
   sparc_gregset_supplies_p = sparc64nbsd_gregset_supplies_p;
   sparc_fpregset_supplies_p = sparc64nbsd_fpregset_supplies_p;
 
-  /* We've got nothing to add to the generic SPARC target.  */
-  add_target (sparc_target ());
+  add_target (&the_sparc64_nbsd_nat_target);
 
   /* Support debugging kernel virtual memory images.  */
   bsd_kvm_add_target (sparc64nbsd_supply_pcb);
diff --git a/gdb/sparc64-obsd-nat.c b/gdb/sparc64-obsd-nat.c
index a851cad091..67629aa05e 100644
--- a/gdb/sparc64-obsd-nat.c
+++ b/gdb/sparc64-obsd-nat.c
@@ -106,6 +106,9 @@ sparc64obsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
   return 1;
 }
 
+/* Add some extra features to the generic SPARC target.  */
+static sparc_target<obsd_nat_target> the_sparc64_obsd_nat_target;
+
 void
 _initialize_sparc64obsd_nat (void)
 {
@@ -120,7 +123,7 @@ _initialize_sparc64obsd_nat (void)
   sparc_fpregmap = &sparc64_bsd_fpregmap;
 
   /* Add some extra features to the generic SPARC target.  */
-  obsd_add_target (sparc_target ());
+  add_target (&the_sparc64_obsd_nat_target);
 
   /* Support debugging kernel virtual memory images.  */
   bsd_kvm_add_target (sparc64obsd_supply_pcb);
diff --git a/gdb/vax-bsd-nat.c b/gdb/vax-bsd-nat.c
index 38106653f4..19c7a33a8c 100644
--- a/gdb/vax-bsd-nat.c
+++ b/gdb/vax-bsd-nat.c
@@ -29,6 +29,14 @@
 #include "vax-tdep.h"
 #include "inf-ptrace.h"
 
+struct vax_bsd_nat_target : public inf_ptrace_target
+{
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+};
+
+static vax_bsd_nat_target the_vax_bsd_nat_target;
+
 /* Supply the general-purpose registers stored in GREGS to REGCACHE.  */
 
 static void
@@ -62,9 +70,8 @@ vaxbsd_collect_gregset (const struct regcache *regcache,
 /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
    for all registers.  */
 
-static void
-vaxbsd_fetch_inferior_registers (struct target_ops *ops,
-				 struct regcache *regcache, int regnum)
+void
+vax_bsd_nat_target::fetch_registers (struct regcache *regcache, int regnum)
 {
   struct reg regs;
   pid_t pid = ptid_get_pid (regcache_get_ptid (regcache));
@@ -78,9 +85,8 @@ vaxbsd_fetch_inferior_registers (struct target_ops *ops,
 /* Store register REGNUM back into the inferior.  If REGNUM is -1, do
    this for all registers.  */
 
-static void
-vaxbsd_store_inferior_registers (struct target_ops *ops,
-				 struct regcache *regcache, int regnum)
+void
+vax_bsd_nat_target::store_registers (struct regcache *regcache, int regnum)
 {
   struct reg regs;
   pid_t pid = ptid_get_pid (regcache_get_ptid (regcache));
@@ -129,12 +135,7 @@ vaxbsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
 void
 _initialize_vaxbsd_nat (void)
 {
-  struct target_ops *t;
-
-  t = inf_ptrace_target ();
-  t->to_fetch_registers = vaxbsd_fetch_inferior_registers;
-  t->to_store_registers = vaxbsd_store_inferior_registers;
-  add_target (t);
+  add_target (&the_vax_bsd_nat_target);
 
   /* Support debugging kernel virtual memory images.  */
   bsd_kvm_add_target (vaxbsd_supply_pcb);
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 06/40] target_ops/C++: spu-multiarch
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (33 preceding siblings ...)
  2018-04-14 19:20 ` [PATCH 33/40] target_ops/C++: The rest of the BSD targets Pedro Alves
@ 2018-04-14 19:20 ` Pedro Alves
  2018-04-14 19:28 ` [PATCH 28/40] target_ops/C++: SPU/Linux Pedro Alves
                   ` (6 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:20 UTC (permalink / raw)
  To: gdb-patches

Straighforward conversion.
---
 gdb/spu-multiarch.c | 163 +++++++++++++++++++++++++++-------------------------
 1 file changed, 86 insertions(+), 77 deletions(-)

diff --git a/gdb/spu-multiarch.c b/gdb/spu-multiarch.c
index 86782abc8b..4e3397fdfe 100644
--- a/gdb/spu-multiarch.c
+++ b/gdb/spu-multiarch.c
@@ -34,8 +34,44 @@
 #include "ppc-linux-tdep.h"
 #include "spu-tdep.h"
 
-/* This module's target vector.  */
-static struct target_ops spu_ops;
+/* The SPU multi-architecture support target.  */
+
+struct spu_multiarch_target final : public target_ops
+{
+  spu_multiarch_target ()
+  { to_stratum = arch_stratum; };
+
+  const char *shortname () override
+  { return "spu"; }
+
+  const char *longname () override
+  { return _("SPU multi-architecture support."); }
+
+  const char *doc () override
+  { return _("SPU multi-architecture support."); }
+
+  void mourn_inferior () override;
+
+    void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+
+  enum target_xfer_status xfer_partial (enum target_object object,
+					const char *annex,
+					gdb_byte *readbuf,
+					const gdb_byte *writebuf,
+					ULONGEST offset, ULONGEST len,
+					ULONGEST *xfered_len) override;
+
+  int search_memory (CORE_ADDR start_addr, ULONGEST search_space_len,
+		     const gdb_byte *pattern, ULONGEST pattern_len,
+		     CORE_ADDR *found_addrp) override;
+
+  int region_ok_for_hw_watchpoint (CORE_ADDR, int) override;
+
+  struct gdbarch *thread_architecture (ptid_t) override;
+};
+
+static spu_multiarch_target spu_ops;
 
 /* Number of SPE objects loaded into the current inferior.  */
 static int spu_nr_solib;
@@ -112,8 +148,8 @@ spu_gdbarch (int spufs_fd)
 }
 
 /* Override the to_thread_architecture routine.  */
-static struct gdbarch *
-spu_thread_architecture (struct target_ops *ops, ptid_t ptid)
+struct gdbarch *
+spu_multiarch_target::thread_architecture (ptid_t ptid)
 {
   int spufs_fd;
   CORE_ADDR spufs_addr;
@@ -121,32 +157,31 @@ spu_thread_architecture (struct target_ops *ops, ptid_t ptid)
   if (parse_spufs_run (ptid, &spufs_fd, &spufs_addr))
     return spu_gdbarch (spufs_fd);
 
-  target_ops *beneath = find_target_beneath (ops);
-  return beneath->to_thread_architecture (beneath, ptid);
+  target_ops *beneath = find_target_beneath (this);
+  return beneath->thread_architecture (ptid);
 }
 
 /* Override the to_region_ok_for_hw_watchpoint routine.  */
-static int
-spu_region_ok_for_hw_watchpoint (struct target_ops *self,
-				 CORE_ADDR addr, int len)
+int
+spu_multiarch_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
 {
-  struct target_ops *ops_beneath = find_target_beneath (self);
+  struct target_ops *ops_beneath = find_target_beneath (this);
 
   /* We cannot watch SPU local store.  */
   if (SPUADDR_SPU (addr) != -1)
     return 0;
 
-  return ops_beneath->to_region_ok_for_hw_watchpoint (ops_beneath, addr, len);
+  return ops_beneath->region_ok_for_hw_watchpoint (addr, len);
 }
 
 /* Override the to_fetch_registers routine.  */
-static void
-spu_fetch_registers (struct target_ops *ops,
-		     struct regcache *regcache, int regno)
+
+void
+spu_multiarch_target::fetch_registers (struct regcache *regcache, int regno)
 {
   struct gdbarch *gdbarch = regcache->arch ();
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-  struct target_ops *ops_beneath = find_target_beneath (ops);
+  struct target_ops *ops_beneath = find_target_beneath (this);
   int spufs_fd;
   CORE_ADDR spufs_addr;
 
@@ -158,7 +193,7 @@ spu_fetch_registers (struct target_ops *ops,
   /* This version applies only if we're currently in spu_run.  */
   if (gdbarch_bfd_arch_info (gdbarch)->arch != bfd_arch_spu)
     {
-      ops_beneath->to_fetch_registers (ops_beneath, regcache, regno);
+      ops_beneath->fetch_registers (regcache, regno);
       return;
     }
 
@@ -200,12 +235,12 @@ spu_fetch_registers (struct target_ops *ops,
 }
 
 /* Override the to_store_registers routine.  */
-static void
-spu_store_registers (struct target_ops *ops,
-		     struct regcache *regcache, int regno)
+
+void
+spu_multiarch_target::store_registers (struct regcache *regcache, int regno)
 {
   struct gdbarch *gdbarch = regcache->arch ();
-  struct target_ops *ops_beneath = find_target_beneath (ops);
+  struct target_ops *ops_beneath = find_target_beneath (this);
   int spufs_fd;
   CORE_ADDR spufs_addr;
 
@@ -217,7 +252,7 @@ spu_store_registers (struct target_ops *ops,
   /* This version applies only if we're currently in spu_run.  */
   if (gdbarch_bfd_arch_info (gdbarch)->arch != bfd_arch_spu)
     {
-      ops_beneath->to_store_registers (ops_beneath, regcache, regno);
+      ops_beneath->store_registers (regcache, regno);
       return;
     }
 
@@ -252,13 +287,14 @@ spu_store_registers (struct target_ops *ops,
 }
 
 /* Override the to_xfer_partial routine.  */
-static enum target_xfer_status
-spu_xfer_partial (struct target_ops *ops, enum target_object object,
-		  const char *annex, gdb_byte *readbuf,
-		  const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
-		  ULONGEST *xfered_len)
+
+enum target_xfer_status
+spu_multiarch_target::xfer_partial (enum target_object object,
+				    const char *annex, gdb_byte *readbuf,
+				    const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
+				    ULONGEST *xfered_len)
 {
-  struct target_ops *ops_beneath = find_target_beneath (ops);
+  struct target_ops *ops_beneath = find_target_beneath (this);
 
   /* Use the "mem" spufs file to access SPU local store.  */
   if (object == TARGET_OBJECT_MEMORY)
@@ -273,9 +309,9 @@ spu_xfer_partial (struct target_ops *ops, enum target_object object,
       if (fd >= 0)
 	{
 	  xsnprintf (mem_annex, sizeof mem_annex, "%d/mem", fd);
-	  ret = ops_beneath->to_xfer_partial (ops_beneath, TARGET_OBJECT_SPU,
-					      mem_annex, readbuf, writebuf,
-					      addr, len, xfered_len);
+	  ret = ops_beneath->xfer_partial (TARGET_OBJECT_SPU,
+					   mem_annex, readbuf, writebuf,
+					   addr, len, xfered_len);
 	  if (ret == TARGET_XFER_OK)
 	    return ret;
 
@@ -285,41 +321,38 @@ spu_xfer_partial (struct target_ops *ops, enum target_object object,
 	     trying the original address first, and getting end-of-file.  */
 	  xsnprintf (lslr_annex, sizeof lslr_annex, "%d/lslr", fd);
 	  memset (buf, 0, sizeof buf);
-	  if (ops_beneath->to_xfer_partial (ops_beneath, TARGET_OBJECT_SPU,
-					    lslr_annex, buf, NULL,
-					    0, sizeof buf, xfered_len)
+	  if (ops_beneath->xfer_partial (TARGET_OBJECT_SPU,
+					 lslr_annex, buf, NULL,
+					 0, sizeof buf, xfered_len)
 	      != TARGET_XFER_OK)
 	    return ret;
 
 	  lslr = strtoulst ((char *) buf, NULL, 16);
-	  return ops_beneath->to_xfer_partial (ops_beneath, TARGET_OBJECT_SPU,
-					       mem_annex, readbuf, writebuf,
-					       addr & lslr, len, xfered_len);
+	  return ops_beneath->xfer_partial (TARGET_OBJECT_SPU,
+					    mem_annex, readbuf, writebuf,
+					    addr & lslr, len, xfered_len);
 	}
     }
 
-  return ops_beneath->to_xfer_partial (ops_beneath, object, annex,
-				       readbuf, writebuf, offset, len, xfered_len);
+  return ops_beneath->xfer_partial (object, annex,
+				    readbuf, writebuf, offset, len, xfered_len);
 }
 
 /* Override the to_search_memory routine.  */
-static int
-spu_search_memory (struct target_ops* ops,
-		   CORE_ADDR start_addr, ULONGEST search_space_len,
-		   const gdb_byte *pattern, ULONGEST pattern_len,
-		   CORE_ADDR *found_addrp)
+int
+spu_multiarch_target::search_memory (CORE_ADDR start_addr, ULONGEST search_space_len,
+				     const gdb_byte *pattern, ULONGEST pattern_len,
+				     CORE_ADDR *found_addrp)
 {
-  struct target_ops *ops_beneath = find_target_beneath (ops);
+  struct target_ops *ops_beneath = find_target_beneath (this);
 
   /* For SPU local store, always fall back to the simple method.  */
   if (SPUADDR_SPU (start_addr) >= 0)
-    return simple_search_memory (ops,
-				 start_addr, search_space_len,
+    return simple_search_memory (this, start_addr, search_space_len,
 				 pattern, pattern_len, found_addrp);
 
-  return ops_beneath->to_search_memory (ops_beneath,
-					start_addr, search_space_len,
-					pattern, pattern_len, found_addrp);
+  return ops_beneath->search_memory (start_addr, search_space_len,
+				     pattern, pattern_len, found_addrp);
 }
 
 
@@ -373,42 +406,18 @@ spu_multiarch_solib_unloaded (struct so_list *so)
 	spu_multiarch_deactivate ();
 }
 
-static void
-spu_mourn_inferior (struct target_ops *ops)
+void
+spu_multiarch_target::mourn_inferior ()
 {
-  struct target_ops *ops_beneath = find_target_beneath (ops);
+  struct target_ops *ops_beneath = find_target_beneath (this);
 
-  ops_beneath->to_mourn_inferior (ops_beneath);
+  ops_beneath->mourn_inferior ();
   spu_multiarch_deactivate ();
 }
 
-
-/* Initialize the SPU multi-architecture support target.  */
-
-static void
-init_spu_ops (void)
-{
-  spu_ops.to_shortname = "spu";
-  spu_ops.to_longname = "SPU multi-architecture support.";
-  spu_ops.to_doc = "SPU multi-architecture support.";
-  spu_ops.to_mourn_inferior = spu_mourn_inferior;
-  spu_ops.to_fetch_registers = spu_fetch_registers;
-  spu_ops.to_store_registers = spu_store_registers;
-  spu_ops.to_xfer_partial = spu_xfer_partial;
-  spu_ops.to_search_memory = spu_search_memory;
-  spu_ops.to_region_ok_for_hw_watchpoint = spu_region_ok_for_hw_watchpoint;
-  spu_ops.to_thread_architecture = spu_thread_architecture;
-  spu_ops.to_stratum = arch_stratum;
-  spu_ops.to_magic = OPS_MAGIC;
-}
-
 void
 _initialize_spu_multiarch (void)
 {
-  /* Install ourselves on the target stack.  */
-  init_spu_ops ();
-  complete_target_initialization (&spu_ops);
-
   /* Install observers to watch for SPU objects.  */
   gdb::observers::inferior_created.attach (spu_multiarch_inferior_created);
   gdb::observers::solib_loaded.attach (spu_multiarch_solib_loaded);
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 28/40] target_ops/C++: SPU/Linux
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (34 preceding siblings ...)
  2018-04-14 19:20 ` [PATCH 06/40] target_ops/C++: spu-multiarch Pedro Alves
@ 2018-04-14 19:28 ` Pedro Alves
  2018-05-04 17:09   ` Ulrich Weigand
  2018-04-14 19:28 ` [PATCH 21/40] target_ops/C++: Aarch64 GNU/Linux Pedro Alves
                   ` (5 subsequent siblings)
  41 siblings, 1 reply; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:28 UTC (permalink / raw)
  To: gdb-patches

Straighforward conversion.
---
 gdb/spu-linux-nat.c | 78 ++++++++++++++++++++++++++++-------------------------
 1 file changed, 42 insertions(+), 36 deletions(-)

diff --git a/gdb/spu-linux-nat.c b/gdb/spu-linux-nat.c
index 6c6bd026ea..8b4c643b2c 100644
--- a/gdb/spu-linux-nat.c
+++ b/gdb/spu-linux-nat.c
@@ -40,6 +40,28 @@
 #define INSTR_SC	0x44000002
 #define NR_spu_run	0x0116
 
+class spu_linux_nat_target final : public inf_ptrace_target
+{
+public:
+  void fetch_registers (struct regcache *regcache, int regnum) override;
+  void store_registers (struct regcache *regcache, int regnum) override;
+
+  void post_attach (int) override;
+  void post_startup_inferior (ptid_t) override;
+
+  ptid_t wait (ptid_t, struct target_waitstatus *, int options) override;
+
+  enum target_xfer_status xfer_partial (enum target_object object,
+					const char *annex,
+					gdb_byte *readbuf,
+					const gdb_byte *writebuf,
+					ULONGEST offset, ULONGEST len,
+					ULONGEST *xfered_len) override;
+
+  int can_use_hw_breakpoint (enum bptype, int, int) override;
+};
+
+static spu_linux_nat_target the_spu_linux_nat_target;
 
 /* Fetch PPU register REGNO.  */
 static ULONGEST
@@ -394,8 +416,8 @@ spu_symbol_file_add_from_memory (int inferior_fd)
 
 /* Override the post_startup_inferior routine to continue running
    the inferior until the first spu_run system call.  */
-static void
-spu_child_post_startup_inferior (struct target_ops *self, ptid_t ptid)
+void
+spu_linux_nat_target::post_startup_inferior (ptid_t ptid)
 {
   int fd;
   ULONGEST addr;
@@ -413,8 +435,8 @@ spu_child_post_startup_inferior (struct target_ops *self, ptid_t ptid)
 
 /* Override the post_attach routine to try load the SPE executable
    file image from its copy inside the target process.  */
-static void
-spu_child_post_attach (struct target_ops *self, int pid)
+void
+spu_linux_nat_target::post_attach (int pid)
 {
   int fd;
   ULONGEST addr;
@@ -436,9 +458,9 @@ spu_child_post_attach (struct target_ops *self, int pid)
 
 /* Wait for child PTID to do something.  Return id of the child,
    minus_one_ptid in case of error; store status into *OURSTATUS.  */
-static ptid_t
-spu_child_wait (struct target_ops *ops,
-		ptid_t ptid, struct target_waitstatus *ourstatus, int options)
+ptid_t
+spu_linux_nat_target:::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
+			     int options)
 {
   int save_errno;
   int status;
@@ -485,9 +507,8 @@ spu_child_wait (struct target_ops *ops,
 }
 
 /* Override the fetch_inferior_register routine.  */
-static void
-spu_fetch_inferior_registers (struct target_ops *ops,
-			      struct regcache *regcache, int regno)
+void
+spu_linux_nat_target::fetch_registers (struct regcache *regcache, int regno)
 {
   int fd;
   ULONGEST addr;
@@ -537,9 +558,8 @@ spu_fetch_inferior_registers (struct target_ops *ops,
 }
 
 /* Override the store_inferior_register routine.  */
-static void
-spu_store_inferior_registers (struct target_ops *ops,
-			      struct regcache *regcache, int regno)
+void
+spu_linux_nat_target::store_registers (struct regcache *regcache, int regno)
 {
   int fd;
   ULONGEST addr;
@@ -578,11 +598,11 @@ spu_store_inferior_registers (struct target_ops *ops,
 }
 
 /* Override the to_xfer_partial routine.  */
-static enum target_xfer_status
-spu_xfer_partial (struct target_ops *ops,
-		  enum target_object object, const char *annex,
-		  gdb_byte *readbuf, const gdb_byte *writebuf,
-		  ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
+enum target_xfer_status
+spu_linux_nat_target::xfer_partial (enum target_object object, const char *annex,
+				    gdb_byte *readbuf, const gdb_byte *writebuf,
+				    ULONGEST offset, ULONGEST len,
+				    ULONGEST *xfered_len)
 {
   if (object == TARGET_OBJECT_SPU)
     return spu_proc_xfer_spu (annex, readbuf, writebuf, offset, len,
@@ -627,9 +647,9 @@ spu_xfer_partial (struct target_ops *ops,
 }
 
 /* Override the to_can_use_hw_breakpoint routine.  */
-static int
-spu_can_use_hw_breakpoint (struct target_ops *self,
-			   enum bptype type, int cnt, int othertype)
+int
+spu_linux_nat_target::can_use_hw_breakpoint (enum bptype type,
+					     int cnt, int othertype)
 {
   return 0;
 }
@@ -638,19 +658,5 @@ spu_can_use_hw_breakpoint (struct target_ops *self,
 void 
 _initialize_spu_nat (void)
 {
-  /* Generic ptrace methods.  */
-  struct target_ops *t;
-  t = inf_ptrace_target ();
-
-  /* Add SPU methods.  */
-  t->to_post_attach = spu_child_post_attach;  
-  t->to_post_startup_inferior = spu_child_post_startup_inferior;
-  t->to_wait = spu_child_wait;
-  t->to_fetch_registers = spu_fetch_inferior_registers;
-  t->to_store_registers = spu_store_inferior_registers;
-  t->to_xfer_partial = spu_xfer_partial;
-  t->to_can_use_hw_breakpoint = spu_can_use_hw_breakpoint;
-
-  /* Register SPU target.  */
-  add_target (t);
+  add_target (&the_spu_linux_nat_target);
 }
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 21/40] target_ops/C++: Aarch64 GNU/Linux
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (35 preceding siblings ...)
  2018-04-14 19:28 ` [PATCH 28/40] target_ops/C++: SPU/Linux Pedro Alves
@ 2018-04-14 19:28 ` Pedro Alves
  2018-04-14 19:29 ` [PATCH 13/40] target_ops/C++: GNU/Linux + x86/AMD64 Pedro Alves
                   ` (4 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:28 UTC (permalink / raw)
  To: gdb-patches

Straighforward conversion.  Smoke tested on the compile farm.
---
 gdb/aarch64-linux-nat.c | 176 +++++++++++++++++++++++-------------------------
 1 file changed, 83 insertions(+), 93 deletions(-)

diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
index 9385659f14..1919241466 100644
--- a/gdb/aarch64-linux-nat.c
+++ b/gdb/aarch64-linux-nat.c
@@ -49,6 +49,36 @@
 #define TRAP_HWBKPT 0x0004
 #endif
 
+class aarch64_linux_nat_target final : public linux_nat_target
+{
+public:
+  /* Add our register access methods.  */
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+
+  const struct target_desc *read_description () override;
+
+  /* Add our hardware breakpoint and watchpoint implementation.  */
+  int can_use_hw_breakpoint (enum bptype, int, int) override;
+  int insert_hw_breakpoint (struct gdbarch *, struct bp_target_info *) override;
+  int remove_hw_breakpoint (struct gdbarch *, struct bp_target_info *) override;
+  int region_ok_for_hw_watchpoint (CORE_ADDR, int) override;
+  int insert_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
+			 struct expression *) override;
+  int remove_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
+			 struct expression *) override;
+  int stopped_by_watchpoint () override;
+  int stopped_data_address (CORE_ADDR *) override;
+  int watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, int) override;
+
+  int can_do_single_step () override;
+
+  /* Override the GNU/Linux inferior startup hook.  */
+  void post_startup_inferior (ptid_t) override;
+};
+
+static aarch64_linux_nat_target the_aarch64_linux_nat_target;
+
 /* Per-process data.  We don't bind this to a per-inferior registry
    because of targets like x86 GNU/Linux that need to keep track of
    processes that aren't bound to any inferior (e.g., fork children,
@@ -342,12 +372,11 @@ store_fpregs_to_thread (const struct regcache *regcache)
     }
 }
 
-/* Implement the "to_fetch_register" target_ops method.  */
+/* Implement the "fetch_registers" target_ops method.  */
 
-static void
-aarch64_linux_fetch_inferior_registers (struct target_ops *ops,
-					struct regcache *regcache,
-					int regno)
+void
+aarch64_linux_nat_target::fetch_registers (struct regcache *regcache,
+					   int regno)
 {
   if (regno == -1)
     {
@@ -360,12 +389,11 @@ aarch64_linux_fetch_inferior_registers (struct target_ops *ops,
     fetch_fpregs_from_thread (regcache);
 }
 
-/* Implement the "to_store_register" target_ops method.  */
+/* Implement the "store_registers" target_ops method.  */
 
-static void
-aarch64_linux_store_inferior_registers (struct target_ops *ops,
-					struct regcache *regcache,
-					int regno)
+void
+aarch64_linux_nat_target::store_registers (struct regcache *regcache,
+					   int regno)
 {
   if (regno == -1)
     {
@@ -467,26 +495,22 @@ ps_get_thread_area (struct ps_prochandle *ph,
 }
 \f
 
-static void (*super_post_startup_inferior) (struct target_ops *self,
-					    ptid_t ptid);
-
-/* Implement the "to_post_startup_inferior" target_ops method.  */
+/* Implement the "post_startup_inferior" target_ops method.  */
 
-static void
-aarch64_linux_child_post_startup_inferior (struct target_ops *self,
-					   ptid_t ptid)
+void
+aarch64_linux_nat_target::post_startup_inferior (ptid_t ptid)
 {
   aarch64_forget_process (ptid_get_pid (ptid));
   aarch64_linux_get_debug_reg_capacity (ptid_get_pid (ptid));
-  super_post_startup_inferior (self, ptid);
+  linux_nat_target::post_startup_inferior (ptid);
 }
 
 extern struct target_desc *tdesc_arm_with_neon;
 
-/* Implement the "to_read_description" target_ops method.  */
+/* Implement the "read_description" target_ops method.  */
 
-static const struct target_desc *
-aarch64_linux_read_description (struct target_ops *ops)
+const struct target_desc *
+aarch64_linux_nat_target::read_description ()
 {
   int ret, tid;
   gdb_byte regbuf[VFP_REGS_SIZE];
@@ -542,10 +566,9 @@ aarch64_linux_siginfo_fixup (siginfo_t *native, gdb_byte *inf, int direction)
    one).  OTHERTYPE is non-zero if other types of watchpoints are
    currently enabled.  */
 
-static int
-aarch64_linux_can_use_hw_breakpoint (struct target_ops *self,
-				     enum bptype type,
-				     int cnt, int othertype)
+int
+aarch64_linux_nat_target::can_use_hw_breakpoint (enum bptype type,
+						 int cnt, int othertype)
 {
   if (type == bp_hardware_watchpoint || type == bp_read_watchpoint
       || type == bp_access_watchpoint || type == bp_watchpoint)
@@ -573,10 +596,9 @@ aarch64_linux_can_use_hw_breakpoint (struct target_ops *self,
 /* Insert a hardware-assisted breakpoint at BP_TGT->reqstd_address.
    Return 0 on success, -1 on failure.  */
 
-static int
-aarch64_linux_insert_hw_breakpoint (struct target_ops *self,
-				    struct gdbarch *gdbarch,
-				    struct bp_target_info *bp_tgt)
+int
+aarch64_linux_nat_target::insert_hw_breakpoint (struct gdbarch *gdbarch,
+						struct bp_target_info *bp_tgt)
 {
   int ret;
   CORE_ADDR addr = bp_tgt->placed_address = bp_tgt->reqstd_address;
@@ -607,10 +629,9 @@ aarch64_linux_insert_hw_breakpoint (struct target_ops *self,
 /* Remove a hardware-assisted breakpoint at BP_TGT->placed_address.
    Return 0 on success, -1 on failure.  */
 
-static int
-aarch64_linux_remove_hw_breakpoint (struct target_ops *self,
-				    struct gdbarch *gdbarch,
-				    struct bp_target_info *bp_tgt)
+int
+aarch64_linux_nat_target::remove_hw_breakpoint (struct gdbarch *gdbarch,
+						struct bp_target_info *bp_tgt)
 {
   int ret;
   CORE_ADDR addr = bp_tgt->placed_address;
@@ -637,17 +658,16 @@ aarch64_linux_remove_hw_breakpoint (struct target_ops *self,
   return ret;
 }
 
-/* Implement the "to_insert_watchpoint" target_ops method.
+/* Implement the "insert_watchpoint" target_ops method.
 
    Insert a watchpoint to watch a memory region which starts at
    address ADDR and whose length is LEN bytes.  Watch memory accesses
    of the type TYPE.  Return 0 on success, -1 on failure.  */
 
-static int
-aarch64_linux_insert_watchpoint (struct target_ops *self,
-				 CORE_ADDR addr, int len,
-				 enum target_hw_bp_type type,
-				 struct expression *cond)
+int
+aarch64_linux_nat_target::insert_watchpoint (CORE_ADDR addr, int len,
+					     enum target_hw_bp_type type,
+					     struct expression *cond)
 {
   int ret;
   struct aarch64_debug_reg_state *state
@@ -671,16 +691,15 @@ aarch64_linux_insert_watchpoint (struct target_ops *self,
   return ret;
 }
 
-/* Implement the "to_remove_watchpoint" target_ops method.
+/* Implement the "remove_watchpoint" target_ops method.
    Remove a watchpoint that watched the memory region which starts at
    address ADDR, whose length is LEN bytes, and for accesses of the
    type TYPE.  Return 0 on success, -1 on failure.  */
 
-static int
-aarch64_linux_remove_watchpoint (struct target_ops *self,
-				 CORE_ADDR addr, int len,
-				 enum target_hw_bp_type type,
-				 struct expression *cond)
+int
+aarch64_linux_nat_target::remove_watchpoint (CORE_ADDR addr, int len,
+					     enum target_hw_bp_type type,
+					     struct expression *cond)
 {
   int ret;
   struct aarch64_debug_reg_state *state
@@ -704,20 +723,18 @@ aarch64_linux_remove_watchpoint (struct target_ops *self,
   return ret;
 }
 
-/* Implement the "to_region_ok_for_hw_watchpoint" target_ops method.  */
+/* Implement the "region_ok_for_hw_watchpoint" target_ops method.  */
 
-static int
-aarch64_linux_region_ok_for_hw_watchpoint (struct target_ops *self,
-					   CORE_ADDR addr, int len)
+int
+aarch64_linux_nat_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
 {
   return aarch64_linux_region_ok_for_watchpoint (addr, len);
 }
 
-/* Implement the "to_stopped_data_address" target_ops method.  */
+/* Implement the "stopped_data_address" target_ops method.  */
 
-static int
-aarch64_linux_stopped_data_address (struct target_ops *target,
-				    CORE_ADDR *addr_p)
+int
+aarch64_linux_nat_target::stopped_data_address (CORE_ADDR *addr_p)
 {
   siginfo_t siginfo;
   int i, tid;
@@ -752,30 +769,29 @@ aarch64_linux_stopped_data_address (struct target_ops *target,
   return 0;
 }
 
-/* Implement the "to_stopped_by_watchpoint" target_ops method.  */
+/* Implement the "stopped_by_watchpoint" target_ops method.  */
 
-static int
-aarch64_linux_stopped_by_watchpoint (struct target_ops *ops)
+int
+aarch64_linux_nat_target::stopped_by_watchpoint ()
 {
   CORE_ADDR addr;
 
-  return aarch64_linux_stopped_data_address (ops, &addr);
+  return stopped_data_address (&addr);
 }
 
-/* Implement the "to_watchpoint_addr_within_range" target_ops method.  */
+/* Implement the "watchpoint_addr_within_range" target_ops method.  */
 
-static int
-aarch64_linux_watchpoint_addr_within_range (struct target_ops *target,
-					    CORE_ADDR addr,
-					    CORE_ADDR start, int length)
+int
+aarch64_linux_nat_target::watchpoint_addr_within_range (CORE_ADDR addr,
+							CORE_ADDR start, int length)
 {
   return start <= addr && start + length - 1 >= addr;
 }
 
-/* Implement the "to_can_do_single_step" target_ops method.  */
+/* Implement the "can_do_single_step" target_ops method.  */
 
-static int
-aarch64_linux_can_do_single_step (struct target_ops *target)
+int
+aarch64_linux_nat_target::can_do_single_step ()
 {
   return 1;
 }
@@ -804,38 +820,12 @@ triggers a breakpoint or watchpoint."),
 void
 _initialize_aarch64_linux_nat (void)
 {
-  struct target_ops *t;
-
-  /* Fill in the generic GNU/Linux methods.  */
-  t = linux_target ();
+  struct target_ops *t = &the_aarch64_linux_nat_target;
 
   add_show_debug_regs_command ();
 
-  /* Add our register access methods.  */
-  t->to_fetch_registers = aarch64_linux_fetch_inferior_registers;
-  t->to_store_registers = aarch64_linux_store_inferior_registers;
-
-  t->to_read_description = aarch64_linux_read_description;
-
-  t->to_can_use_hw_breakpoint = aarch64_linux_can_use_hw_breakpoint;
-  t->to_insert_hw_breakpoint = aarch64_linux_insert_hw_breakpoint;
-  t->to_remove_hw_breakpoint = aarch64_linux_remove_hw_breakpoint;
-  t->to_region_ok_for_hw_watchpoint =
-    aarch64_linux_region_ok_for_hw_watchpoint;
-  t->to_insert_watchpoint = aarch64_linux_insert_watchpoint;
-  t->to_remove_watchpoint = aarch64_linux_remove_watchpoint;
-  t->to_stopped_by_watchpoint = aarch64_linux_stopped_by_watchpoint;
-  t->to_stopped_data_address = aarch64_linux_stopped_data_address;
-  t->to_watchpoint_addr_within_range =
-    aarch64_linux_watchpoint_addr_within_range;
-  t->to_can_do_single_step = aarch64_linux_can_do_single_step;
-
-  /* Override the GNU/Linux inferior startup hook.  */
-  super_post_startup_inferior = t->to_post_startup_inferior;
-  t->to_post_startup_inferior = aarch64_linux_child_post_startup_inferior;
-
   /* Register the target.  */
-  linux_nat_add_target (t);
+  add_target (t);
   linux_nat_set_new_thread (t, aarch64_linux_new_thread);
   linux_nat_set_delete_thread (t, aarch64_linux_delete_thread);
   linux_nat_set_new_fork (t, aarch64_linux_new_fork);
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 13/40] target_ops/C++: GNU/Linux + x86/AMD64
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (36 preceding siblings ...)
  2018-04-14 19:28 ` [PATCH 21/40] target_ops/C++: Aarch64 GNU/Linux Pedro Alves
@ 2018-04-14 19:29 ` Pedro Alves
  2018-04-14 19:30 ` [PATCH 18/40] target_ops/C++: linux_trad_target, MIPS and Alpha GNU/Linux Pedro Alves
                   ` (3 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:29 UTC (permalink / raw)
  To: gdb-patches

This converts the x86/AMD64 GNU/Linux ports to C++ified target_ops.

- inf-child/"native" is converted to an actual base class
  (inf_child_target), that is inherited by the linux-nat target.
  inf_child_target will be inherited by all other native targets too,
  of course, in the following patches.

- The old weird double-target linux_ops mechanism in linux-nat.c, is
  gone, replaced by adding a few virtual methods to linux-nat.h's
  target_ops, called low_XXX, that the concrete linux-nat
  implementations override.  Sort of like gdbserver's
  linux_target_ops, but simpler, for requiring only one
  target_ops-like hierarchy, which spares implementing the same method
  twice when we need to forward the method to a low implementation.
  The low target simply reimplements the target_ops method directly in
  that case.

  There are a few remaining linux-nat.c hooks that would be better
  converted to low_ methods like above too.  E.g.:

   linux_nat_set_new_thread (t, x86_linux_new_thread);
   linux_nat_set_new_fork (t, x86_linux_new_fork);
   linux_nat_set_forget_process

  That'll be done in a follow up patch.

- We can no longer use functions like x86_use_watchpoints to install
  custom methods on an arbitrary base target.  The patch replaces that
  with a template mixin.  See x86_nat_target in x86-nat.h.  That will
  be used by other non-Linux x86 targets in following patches.

- linux-thread-db is converted here too.
---
 gdb/amd64-linux-nat.c |  33 ++--
 gdb/i386-linux-nat.c  |  42 ++---
 gdb/inf-child.c       | 295 +++++++++++++++----------------
 gdb/inf-child.h       | 112 ++++++++++--
 gdb/inf-ptrace.c      | 142 ++++++---------
 gdb/inf-ptrace.h      |  67 +++++--
 gdb/linux-nat.c       | 480 +++++++++++++++++++-------------------------------
 gdb/linux-nat.h       | 141 +++++++++++++--
 gdb/linux-thread-db.c | 155 ++++++++--------
 gdb/x86-linux-nat.c   |  80 +++------
 gdb/x86-linux-nat.h   |  44 ++++-
 gdb/x86-nat.c         |  64 ++-----
 gdb/x86-nat.h         |  79 ++++++++-
 13 files changed, 926 insertions(+), 808 deletions(-)

diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c
index ad942435b8..cee364476c 100644
--- a/gdb/amd64-linux-nat.c
+++ b/gdb/amd64-linux-nat.c
@@ -30,7 +30,6 @@
 #include "gdb_proc_service.h"
 
 #include "amd64-nat.h"
-#include "linux-nat.h"
 #include "amd64-tdep.h"
 #include "amd64-linux-tdep.h"
 #include "i386-linux-tdep.h"
@@ -46,6 +45,15 @@
 #define PTRACE_ARCH_PRCTL      30
 #endif
 
+struct amd64_linux_nat_target final : public x86_linux_nat_target
+{
+  /* Add our register access methods.  */
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+};
+
+static amd64_linux_nat_target the_amd64_linux_nat_target;
+
 /* Mapping between the general-purpose registers in GNU/Linux x86-64
    `struct user' format and GDB's register cache layout for GNU/Linux
    i386.
@@ -130,9 +138,8 @@ fill_fpregset (const struct regcache *regcache,
    this for all registers (including the floating point and SSE
    registers).  */
 
-static void
-amd64_linux_fetch_inferior_registers (struct target_ops *ops,
-				      struct regcache *regcache, int regnum)
+void
+amd64_linux_nat_target::fetch_registers (struct regcache *regcache, int regnum)
 {
   struct gdbarch *gdbarch = regcache->arch ();
   int tid;
@@ -209,9 +216,8 @@ amd64_linux_fetch_inferior_registers (struct target_ops *ops,
    -1, do this for all registers (including the floating-point and SSE
    registers).  */
 
-static void
-amd64_linux_store_inferior_registers (struct target_ops *ops,
-				      struct regcache *regcache, int regnum)
+void
+amd64_linux_nat_target::store_registers (struct regcache *regcache, int regnum)
 {
   struct gdbarch *gdbarch = regcache->arch ();
   int tid;
@@ -399,8 +405,6 @@ amd64_linux_siginfo_fixup (siginfo_t *ptrace, gdb_byte *inf, int direction)
 void
 _initialize_amd64_linux_nat (void)
 {
-  struct target_ops *t;
-
   amd64_native_gregset32_reg_offset = amd64_linux_gregset32_reg_offset;
   amd64_native_gregset32_num_regs = I386_LINUX_NUM_REGS;
   amd64_native_gregset64_reg_offset = amd64_linux_gregset_reg_offset;
@@ -409,16 +413,11 @@ _initialize_amd64_linux_nat (void)
   gdb_assert (ARRAY_SIZE (amd64_linux_gregset32_reg_offset)
 	      == amd64_native_gregset32_num_regs);
 
-  /* Create a generic x86 GNU/Linux target.  */
-  t = x86_linux_create_target ();
-
-  /* Add our register access methods.  */
-  t->to_fetch_registers = amd64_linux_fetch_inferior_registers;
-  t->to_store_registers = amd64_linux_store_inferior_registers;
+  linux_target = &the_amd64_linux_nat_target;
 
   /* Add the target.  */
-  x86_linux_add_target (t);
+  x86_linux_add_target (linux_target);
 
   /* Add our siginfo layout converter.  */
-  linux_nat_set_siginfo_fixup (t, amd64_linux_siginfo_fixup);
+  linux_nat_set_siginfo_fixup (linux_target, amd64_linux_siginfo_fixup);
 }
diff --git a/gdb/i386-linux-nat.c b/gdb/i386-linux-nat.c
index d1d32e1b20..b923e65712 100644
--- a/gdb/i386-linux-nat.c
+++ b/gdb/i386-linux-nat.c
@@ -33,11 +33,22 @@
 #include "i386-linux-tdep.h"
 #include "x86-xstate.h"
 
-#include "linux-nat.h"
 #include "x86-linux-nat.h"
 #include "nat/linux-ptrace.h"
 #include "inf-ptrace.h"
 
+struct i386_linux_nat_target final : public x86_linux_nat_target
+{
+  /* Add our register access methods.  */
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+
+  /* Override the default ptrace resume method.  */
+  void low_resume (ptid_t ptid, int step, enum gdb_signal sig) override;
+};
+
+static i386_linux_nat_target the_i386_linux_nat_target;
+
 /* The register sets used in GNU/Linux ELF core-dumps are identical to
    the register sets in `struct user' that is used for a.out
    core-dumps, and is also used by `ptrace'.  The corresponding types
@@ -446,9 +457,8 @@ store_fpxregs (const struct regcache *regcache, int tid, int regno)
    this for all registers (including the floating point and SSE
    registers).  */
 
-static void
-i386_linux_fetch_inferior_registers (struct target_ops *ops,
-				     struct regcache *regcache, int regno)
+void
+i386_linux_nat_target::fetch_registers (struct regcache *regcache, int regno)
 {
   pid_t tid;
 
@@ -478,7 +488,7 @@ i386_linux_fetch_inferior_registers (struct target_ops *ops,
       /* The call above might reset `have_ptrace_getregs'.  */
       if (!have_ptrace_getregs)
 	{
-	  i386_linux_fetch_inferior_registers (ops, regcache, regno);
+	  fetch_registers (regcache, regno);
 	  return;
 	}
 
@@ -524,9 +534,8 @@ i386_linux_fetch_inferior_registers (struct target_ops *ops,
 /* Store register REGNO back into the child process.  If REGNO is -1,
    do this for all registers (including the floating point and SSE
    registers).  */
-static void
-i386_linux_store_inferior_registers (struct target_ops *ops,
-				     struct regcache *regcache, int regno)
+void
+i386_linux_nat_target::store_registers (struct regcache *regcache, int regno)
 {
   pid_t tid;
 
@@ -635,9 +644,8 @@ static const unsigned char linux_syscall[] = { 0xcd, 0x80 };
    If STEP is nonzero, single-step it.
    If SIGNAL is nonzero, give it that signal.  */
 
-static void
-i386_linux_resume (struct target_ops *ops,
-		   ptid_t ptid, int step, enum gdb_signal signal)
+void
+i386_linux_nat_target::low_resume (ptid_t ptid, int step, enum gdb_signal signal)
 {
   int pid = ptid_get_lwp (ptid);
   int request;
@@ -706,16 +714,8 @@ i386_linux_resume (struct target_ops *ops,
 void
 _initialize_i386_linux_nat (void)
 {
-  /* Create a generic x86 GNU/Linux target.  */
-  struct target_ops *t = x86_linux_create_target ();
-
-  /* Override the default ptrace resume method.  */
-  t->to_resume = i386_linux_resume;
-
-  /* Add our register access methods.  */
-  t->to_fetch_registers = i386_linux_fetch_inferior_registers;
-  t->to_store_registers = i386_linux_store_inferior_registers;
+  linux_target = &the_i386_linux_nat_target;
 
   /* Add the target.  */
-  x86_linux_add_target (t);
+  x86_linux_add_target (linux_target);
 }
diff --git a/gdb/inf-child.c b/gdb/inf-child.c
index c7c45530b6..7b2f2a25a2 100644
--- a/gdb/inf-child.c
+++ b/gdb/inf-child.c
@@ -39,11 +39,6 @@
 #include <fcntl.h>
 #include <unistd.h>
 
-/* A pointer to what is returned by inf_child_target.  Used by
-   inf_child_open to push the most-derived target in reaction to
-   "target native".  */
-static struct target_ops *inf_child_ops = NULL;
-
 /* Helper function for child_wait and the derivatives of child_wait.
    HOSTSTATUS is the waitstatus from wait() or the equivalent; store our
    translation of that in OURSTATUS.  */
@@ -67,35 +62,11 @@ store_waitstatus (struct target_waitstatus *ourstatus, int hoststatus)
     }
 }
 
-/* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
-   for all registers.  */
-
-static void
-inf_child_fetch_inferior_registers (struct target_ops *ops,
-				    struct regcache *regcache, int regnum)
-{
-  if (regnum == -1)
-    {
-      for (regnum = 0;
-	   regnum < gdbarch_num_regs (regcache->arch ());
-	   regnum++)
-	regcache_raw_supply (regcache, regnum, NULL);
-    }
-  else
-    regcache_raw_supply (regcache, regnum, NULL);
-}
-
-/* Store register REGNUM back into the inferior.  If REGNUM is -1, do
-   this for all registers (including the floating point registers).  */
-
-static void
-inf_child_store_inferior_registers (struct target_ops *ops,
-				    struct regcache *regcache, int regnum)
-{
-}
+inf_child_target::~inf_child_target ()
+{}
 
-static void
-inf_child_post_attach (struct target_ops *self, int pid)
+void
+inf_child_target::post_attach (int pid)
 {
   /* This target doesn't require a meaningful "post attach" operation
      by a debugger.  */
@@ -107,12 +78,59 @@ inf_child_post_attach (struct target_ops *self, int pid)
    makes sure that registers contains all the registers from the
    program being debugged.  */
 
-static void
-inf_child_prepare_to_store (struct target_ops *self,
-			    struct regcache *regcache)
+void
+inf_child_target::prepare_to_store (struct regcache *regcache)
 {
 }
 
+bool
+inf_child_target::supports_terminal_ours ()
+{
+  return true;
+}
+
+void
+inf_child_target::terminal_init ()
+{
+  child_terminal_init (this);
+}
+
+void
+inf_child_target::terminal_inferior ()
+{
+  child_terminal_inferior (this);
+}
+
+void
+inf_child_target::terminal_ours_for_output ()
+{
+  child_terminal_ours_for_output (this);
+}
+
+void
+inf_child_target::terminal_ours ()
+{
+  child_terminal_ours (this);
+}
+
+void
+inf_child_target::interrupt ()
+{
+  child_interrupt (this);
+}
+
+void
+inf_child_target::pass_ctrlc ()
+{
+  child_pass_ctrlc (this);
+}
+
+void
+inf_child_target::terminal_info (const char *args, int from_tty)
+{
+  child_terminal_info (this, args, from_tty);
+}
+
 /* True if the user did "target native".  In that case, we won't
    unpush the child target automatically when the last inferior is
    gone.  */
@@ -131,16 +149,16 @@ inf_child_open_target (struct target_ops *target, const char *arg,
     printf_filtered ("Done.  Use the \"run\" command to start a process.\n");
 }
 
-static void
-inf_child_open (const char *arg, int from_tty)
+void
+inf_child_target::open (const char *arg, int from_tty)
 {
-  inf_child_open_target (inf_child_ops, arg, from_tty);
+  inf_child_open_target (this, arg, from_tty);
 }
 
 /* Implement the to_disconnect target_ops method.  */
 
-static void
-inf_child_disconnect (struct target_ops *target, const char *args, int from_tty)
+void
+inf_child_target::disconnect (const char *args, int from_tty)
 {
   if (args != NULL)
     error (_("Argument given to \"disconnect\"."));
@@ -152,65 +170,98 @@ inf_child_disconnect (struct target_ops *target, const char *args, int from_tty)
 
 /* Implement the to_close target_ops method.  */
 
-static void
-inf_child_close (struct target_ops *target)
+void
+inf_child_target::close ()
 {
   /* In case we were forcibly closed.  */
   inf_child_explicitly_opened = 0;
 }
 
 void
-inf_child_mourn_inferior (struct target_ops *ops)
+inf_child_target::mourn_inferior ()
 {
   generic_mourn_inferior ();
-  inf_child_maybe_unpush_target (ops);
+  maybe_unpush_target ();
 }
 
 /* See inf-child.h.  */
 
 void
-inf_child_maybe_unpush_target (struct target_ops *ops)
+inf_child_target::maybe_unpush_target ()
 {
   if (!inf_child_explicitly_opened && !have_inferiors ())
-    unpush_target (ops);
+    unpush_target (this);
 }
 
-static void
-inf_child_post_startup_inferior (struct target_ops *self, ptid_t ptid)
+void
+inf_child_target::post_startup_inferior (ptid_t ptid)
 {
   /* This target doesn't require a meaningful "post startup inferior"
      operation by a debugger.  */
 }
 
-static int
-inf_child_follow_fork (struct target_ops *ops, int follow_child,
-		       int detach_fork)
+int
+inf_child_target::can_run ()
 {
-  /* This target doesn't support following fork or vfork events.  */
-  return 0;
+  return 1;
 }
 
-static int
-inf_child_can_run (struct target_ops *self)
+bool
+inf_child_target::can_create_inferior ()
 {
-  return 1;
+  return true;
+}
+
+bool
+inf_child_target::can_attach ()
+{
+  return true;
 }
 
-static char *
-inf_child_pid_to_exec_file (struct target_ops *self, int pid)
+char *
+inf_child_target::pid_to_exec_file (int pid)
 {
   /* This target doesn't support translation of a process ID to the
      filename of the executable file.  */
   return NULL;
 }
 
+int
+inf_child_target::has_all_memory ()
+{
+  return default_child_has_all_memory ();
+}
+
+int
+inf_child_target::has_memory ()
+{
+  return default_child_has_memory ();
+}
+
+int
+inf_child_target::has_stack ()
+{
+  return default_child_has_stack ();
+}
+
+int
+inf_child_target::has_registers ()
+{
+  return default_child_has_registers ();
+}
+
+int
+inf_child_target::has_execution (ptid_t ptid)
+{
+  return default_child_has_execution (ptid);
+}
+
 /* Implementation of to_fileio_open.  */
 
-static int
-inf_child_fileio_open (struct target_ops *self,
-		       struct inferior *inf, const char *filename,
-		       int flags, int mode, int warn_if_slow,
-		       int *target_errno)
+int
+inf_child_target::fileio_open (struct inferior *inf, const char *filename,
+			       int flags, int mode, int warn_if_slow,
+			       int *target_errno)
 {
   int nat_flags;
   mode_t nat_mode;
@@ -232,10 +283,9 @@ inf_child_fileio_open (struct target_ops *self,
 
 /* Implementation of to_fileio_pwrite.  */
 
-static int
-inf_child_fileio_pwrite (struct target_ops *self,
-			 int fd, const gdb_byte *write_buf, int len,
-			 ULONGEST offset, int *target_errno)
+int
+inf_child_target::fileio_pwrite (int fd, const gdb_byte *write_buf, int len,
+				 ULONGEST offset, int *target_errno)
 {
   int ret;
 
@@ -260,10 +310,9 @@ inf_child_fileio_pwrite (struct target_ops *self,
 
 /* Implementation of to_fileio_pread.  */
 
-static int
-inf_child_fileio_pread (struct target_ops *self,
-			int fd, gdb_byte *read_buf, int len,
-			ULONGEST offset, int *target_errno)
+int
+inf_child_target::fileio_pread (int fd, gdb_byte *read_buf, int len,
+				ULONGEST offset, int *target_errno)
 {
   int ret;
 
@@ -288,9 +337,8 @@ inf_child_fileio_pread (struct target_ops *self,
 
 /* Implementation of to_fileio_fstat.  */
 
-static int
-inf_child_fileio_fstat (struct target_ops *self, int fd,
-			struct stat *sb, int *target_errno)
+int
+inf_child_target::fileio_fstat (int fd, struct stat *sb, int *target_errno)
 {
   int ret;
 
@@ -303,12 +351,12 @@ inf_child_fileio_fstat (struct target_ops *self, int fd,
 
 /* Implementation of to_fileio_close.  */
 
-static int
-inf_child_fileio_close (struct target_ops *self, int fd, int *target_errno)
+int
+inf_child_target::fileio_close (int fd, int *target_errno)
 {
   int ret;
 
-  ret = close (fd);
+  ret = ::close (fd);
   if (ret == -1)
     *target_errno = host_to_fileio_error (errno);
 
@@ -317,10 +365,9 @@ inf_child_fileio_close (struct target_ops *self, int fd, int *target_errno)
 
 /* Implementation of to_fileio_unlink.  */
 
-static int
-inf_child_fileio_unlink (struct target_ops *self,
-			 struct inferior *inf, const char *filename,
-			 int *target_errno)
+int
+inf_child_target::fileio_unlink (struct inferior *inf, const char *filename,
+				 int *target_errno)
 {
   int ret;
 
@@ -333,10 +380,9 @@ inf_child_fileio_unlink (struct target_ops *self,
 
 /* Implementation of to_fileio_readlink.  */
 
-static gdb::optional<std::string>
-inf_child_fileio_readlink (struct target_ops *self,
-			   struct inferior *inf, const char *filename,
-			   int *target_errno)
+gdb::optional<std::string>
+inf_child_target::fileio_readlink (struct inferior *inf, const char *filename,
+				   int *target_errno)
 {
   /* We support readlink only on systems that also provide a compile-time
      maximum path length (PATH_MAX), at least for now.  */
@@ -358,86 +404,25 @@ inf_child_fileio_readlink (struct target_ops *self,
 #endif
 }
 
-static int
-inf_child_use_agent (struct target_ops *self, int use)
+int
+inf_child_target::use_agent (int use)
 {
   if (agent_loaded_p ())
     {
-      use_agent = use;
+      ::use_agent = use;
       return 1;
     }
   else
     return 0;
 }
 
-static int
-inf_child_can_use_agent (struct target_ops *self)
+int
+inf_child_target::can_use_agent ()
 {
   return agent_loaded_p ();
 }
 
-/* Default implementation of the to_can_async_p and
-   to_supports_non_stop methods.  */
-
-static int
-return_zero (struct target_ops *ignore)
-{
-  return 0;
-}
-
-struct target_ops *
-inf_child_target (void)
-{
-  struct target_ops *t = XCNEW (struct target_ops);
-
-  t->to_shortname = "native";
-  t->to_longname = "Native process";
-  t->to_doc = "Native process (started by the \"run\" command).";
-  t->to_open = inf_child_open;
-  t->to_close = inf_child_close;
-  t->to_disconnect = inf_child_disconnect;
-  t->to_post_attach = inf_child_post_attach;
-  t->to_fetch_registers = inf_child_fetch_inferior_registers;
-  t->to_store_registers = inf_child_store_inferior_registers;
-  t->to_prepare_to_store = inf_child_prepare_to_store;
-  t->to_insert_breakpoint = memory_insert_breakpoint;
-  t->to_remove_breakpoint = memory_remove_breakpoint;
-  t->to_terminal_init = child_terminal_init;
-  t->to_terminal_inferior = child_terminal_inferior;
-  t->to_terminal_save_inferior = child_terminal_save_inferior;
-  t->to_terminal_ours_for_output = child_terminal_ours_for_output;
-  t->to_terminal_ours = child_terminal_ours;
-  t->to_terminal_info = child_terminal_info;
-  t->to_pass_ctrlc = child_pass_ctrlc;
-  t->to_interrupt = child_interrupt;
-  t->to_post_startup_inferior = inf_child_post_startup_inferior;
-  t->to_follow_fork = inf_child_follow_fork;
-  t->to_can_run = inf_child_can_run;
-  /* We must default these because they must be implemented by any
-     target that can run.  */
-  t->to_can_async_p = return_zero;
-  t->to_supports_non_stop = return_zero;
-  t->to_pid_to_exec_file = inf_child_pid_to_exec_file;
-  t->to_stratum = process_stratum;
-  t->to_has_all_memory = default_child_has_all_memory;
-  t->to_has_memory = default_child_has_memory;
-  t->to_has_stack = default_child_has_stack;
-  t->to_has_registers = default_child_has_registers;
-  t->to_has_execution = default_child_has_execution;
-  t->to_fileio_open = inf_child_fileio_open;
-  t->to_fileio_pwrite = inf_child_fileio_pwrite;
-  t->to_fileio_pread = inf_child_fileio_pread;
-  t->to_fileio_fstat = inf_child_fileio_fstat;
-  t->to_fileio_close = inf_child_fileio_close;
-  t->to_fileio_unlink = inf_child_fileio_unlink;
-  t->to_fileio_readlink = inf_child_fileio_readlink;
-  t->to_magic = OPS_MAGIC;
-  t->to_use_agent = inf_child_use_agent;
-  t->to_can_use_agent = inf_child_can_use_agent;
-
-  /* Store a pointer so we can push the most-derived target from
-     inf_child_open.  */
-  inf_child_ops = t;
-
-  return t;
+inf_child_target::inf_child_target ()
+{
+  this->to_stratum = process_stratum;
 }
diff --git a/gdb/inf-child.h b/gdb/inf-child.h
index 5fb966d506..1b9c8c53ae 100644
--- a/gdb/inf-child.h
+++ b/gdb/inf-child.h
@@ -20,33 +20,107 @@
 #ifndef INF_CHILD_H
 #define INF_CHILD_H
 
-/* Create a prototype child target.  The client can override it with
-   local methods.  */
+#include "target.h"
 
-extern struct target_ops *inf_child_target (void);
+/* A prototype child target.  The client can override it with local
+   methods.  */
 
-/* Functions for helping to write a native target.  */
+class inf_child_target
+  : public memory_breakpoint_target<target_ops>
+{
+public:
+  inf_child_target ();
+  ~inf_child_target () override = 0;
 
-/* This is for native targets which use a unix/POSIX-style waitstatus.  */
-extern void store_waitstatus (struct target_waitstatus *, int);
+  const char *shortname () override
+  { return "native"; }
+
+  const char *longname () override
+  { return _("Native process"); }
+
+  const char *doc () override
+  { return _("Native process (started by the \"run\" command)."); }
+
+  void open (const char *arg, int from_tty) override;
+  void close () override;
+
+  void disconnect (const char *, int) override;
+
+  void fetch_registers (struct regcache *, int) override = 0;
+  void store_registers (struct regcache *, int) override = 0;
+
+  void prepare_to_store (struct regcache *) override;
+
+  bool supports_terminal_ours () override;
+  void terminal_init () override;
+  void terminal_inferior () override;
+  void terminal_ours_for_output () override;
+  void terminal_ours () override;
+  void terminal_info (const char *, int) override;
+
+  void interrupt () override;
+  void pass_ctrlc () override;
 
-/* This is to be called by the native target's open routine to push
-   the target, in case it need to override to_open.  */
+  void post_startup_inferior (ptid_t) override;
 
-extern void inf_child_open_target (struct target_ops *target,
-				   const char *arg, int from_tty);
+  void mourn_inferior () override;
 
-/* To be called by the native target's to_mourn_inferior routine.  */
+  int can_run () override;
 
-extern void inf_child_mourn_inferior (struct target_ops *ops);
+  bool can_create_inferior () override;
+  void create_inferior (const char *, const std::string &,
+			char **, int) = 0;
 
-/* Unpush the target if it wasn't explicitly open with "target native"
-   and there are no live inferiors left.  Note: if calling this as a
-   result of a mourn or detach, the current inferior shall already
-   have its PID cleared, so it isn't counted as live.  That's usually
-   done by calling either generic_mourn_inferior or
-   detach_inferior.  */
+  bool can_attach () override;
+  void attach (const char *, int) override = 0;
 
-extern void inf_child_maybe_unpush_target (struct target_ops *ops);
+  void post_attach (int);
+
+  /* We must default these because they must be implemented by any
+     target that can run.  */
+  int can_async_p ()  override { return 0; }
+  int supports_non_stop ()  override { return 0; }
+
+  char *pid_to_exec_file (int pid) override;
+
+  int has_all_memory () override;
+  int has_memory () override;
+  int has_stack () override;
+  int has_registers () override;
+  int has_execution (ptid_t) override;
+
+  int fileio_open (struct inferior *inf, const char *filename,
+		   int flags, int mode, int warn_if_slow,
+		   int *target_errno) override;
+  int fileio_pwrite (int fd, const gdb_byte *write_buf, int len,
+		     ULONGEST offset, int *target_errno) override;
+  int fileio_pread (int fd, gdb_byte *read_buf, int len,
+		    ULONGEST offset, int *target_errno) override;
+  int fileio_fstat (int fd, struct stat *sb, int *target_errno) override;
+  int fileio_close (int fd, int *target_errno) override;
+  int fileio_unlink (struct inferior *inf,
+		     const char *filename,
+		     int *target_errno) override;
+  gdb::optional<std::string> fileio_readlink (struct inferior *inf,
+					      const char *filename,
+					      int *target_errno) override;
+  int use_agent (int use) override;
+
+  int can_use_agent () override;
+
+protected:
+  /* Unpush the target if it wasn't explicitly open with "target native"
+     and there are no live inferiors left.  Note: if calling this as a
+     result of a mourn or detach, the current inferior shall already
+     have its PID cleared, so it isn't counted as live.  That's usually
+     done by calling either generic_mourn_inferior or
+     detach_inferior.  */
+  void maybe_unpush_target ();
+};
+
+/* Functions for helping to write a native target.  */
+
+/* This is for native targets which use a unix/POSIX-style waitstatus.  */
+extern void store_waitstatus (struct target_waitstatus *, int);
 
 #endif
diff --git a/gdb/inf-ptrace.c b/gdb/inf-ptrace.c
index 7c4d597be9..8f5a378353 100644
--- a/gdb/inf-ptrace.c
+++ b/gdb/inf-ptrace.c
@@ -52,14 +52,16 @@ typedef std::unique_ptr<struct target_ops, target_unpusher> target_unpush_up;
 
 \f
 
+inf_ptrace_target::~inf_ptrace_target ()
+{}
+
 #ifdef PT_GET_PROCESS_STATE
 
 /* Target hook for follow_fork.  On entry and at return inferior_ptid is
    the ptid of the followed inferior.  */
 
-static int
-inf_ptrace_follow_fork (struct target_ops *ops, int follow_child,
-			int detach_fork)
+int
+inf_ptrace_target::follow_fork (int follow_child, int detach_fork)
 {
   if (!follow_child)
     {
@@ -76,14 +78,14 @@ inf_ptrace_follow_fork (struct target_ops *ops, int follow_child,
   return 0;
 }
 
-static int
-inf_ptrace_insert_fork_catchpoint (struct target_ops *self, int pid)
+int
+inf_ptrace_target::insert_fork_catchpoint (int pid)
 {
   return 0;
 }
 
-static int
-inf_ptrace_remove_fork_catchpoint (struct target_ops *self, int pid)
+int
+inf_ptrace_target::remove_fork_catchpoint (int pid)
 {
   return 0;
 }
@@ -106,24 +108,24 @@ inf_ptrace_me (void)
    ENV is the environment vector to pass.  If FROM_TTY is non-zero, be
    chatty about it.  */
 
-static void
-inf_ptrace_create_inferior (struct target_ops *ops,
-			    const char *exec_file, const std::string &allargs,
-			    char **env, int from_tty)
+void
+inf_ptrace_target::create_inferior (const char *exec_file,
+				    const std::string &allargs,
+				    char **env, int from_tty)
 {
   pid_t pid;
   ptid_t ptid;
 
   /* Do not change either targets above or the same target if already present.
      The reason is the target stack is shared across multiple inferiors.  */
-  int ops_already_pushed = target_is_pushed (ops);
+  int ops_already_pushed = target_is_pushed (this);
 
   target_unpush_up unpusher;
   if (! ops_already_pushed)
     {
       /* Clear possible core file with its process_stratum.  */
-      push_target (ops);
-      unpusher.reset (ops);
+      push_target (this);
+      unpusher.reset (this);
     }
 
   pid = fork_inferior (exec_file, allargs, env, inf_ptrace_me, NULL,
@@ -146,8 +148,8 @@ inf_ptrace_create_inferior (struct target_ops *ops,
 
 #ifdef PT_GET_PROCESS_STATE
 
-static void
-inf_ptrace_post_startup_inferior (struct target_ops *self, ptid_t pid)
+void
+inf_ptrace_target::post_startup_inferior (ptid_t pid)
 {
   ptrace_event_t pe;
 
@@ -163,8 +165,8 @@ inf_ptrace_post_startup_inferior (struct target_ops *self, ptid_t pid)
 
 /* Clean up a rotting corpse of an inferior after it died.  */
 
-static void
-inf_ptrace_mourn_inferior (struct target_ops *ops)
+void
+inf_ptrace_target::mourn_inferior ()
 {
   int status;
 
@@ -174,14 +176,14 @@ inf_ptrace_mourn_inferior (struct target_ops *ops)
      only report its exit status to its original parent.  */
   waitpid (ptid_get_pid (inferior_ptid), &status, 0);
 
-  inf_child_mourn_inferior (ops);
+  inf_child_target::mourn_inferior ();
 }
 
 /* Attach to the process specified by ARGS.  If FROM_TTY is non-zero,
    be chatty about it.  */
 
-static void
-inf_ptrace_attach (struct target_ops *ops, const char *args, int from_tty)
+void
+inf_ptrace_target::attach (const char *args, int from_tty)
 {
   char *exec_file;
   pid_t pid;
@@ -189,7 +191,7 @@ inf_ptrace_attach (struct target_ops *ops, const char *args, int from_tty)
 
   /* Do not change either targets above or the same target if already present.
      The reason is the target stack is shared across multiple inferiors.  */
-  int ops_already_pushed = target_is_pushed (ops);
+  int ops_already_pushed = target_is_pushed (this);
 
   pid = parse_pid_to_attach (args);
 
@@ -201,8 +203,8 @@ inf_ptrace_attach (struct target_ops *ops, const char *args, int from_tty)
     {
       /* target_pid_to_str already uses the target.  Also clear possible core
 	 file with its process_stratum.  */
-      push_target (ops);
-      unpusher.reset (ops);
+      push_target (this);
+      unpusher.reset (this);
     }
 
   if (from_tty)
@@ -242,8 +244,8 @@ inf_ptrace_attach (struct target_ops *ops, const char *args, int from_tty)
 
 #ifdef PT_GET_PROCESS_STATE
 
-static void
-inf_ptrace_post_attach (struct target_ops *self, int pid)
+void
+inf_ptrace_target::post_attach (int pid)
 {
   ptrace_event_t pe;
 
@@ -259,8 +261,8 @@ inf_ptrace_post_attach (struct target_ops *self, int pid)
 
 /* Detach from the inferior.  If FROM_TTY is non-zero, be chatty about it.  */
 
-static void
-inf_ptrace_detach (struct target_ops *ops, inferior *inf, int from_tty)
+void
+inf_ptrace_target::detach (inferior *inf, int from_tty)
 {
   pid_t pid = ptid_get_pid (inferior_ptid);
 
@@ -279,24 +281,24 @@ inf_ptrace_detach (struct target_ops *ops, inferior *inf, int from_tty)
   error (_("This system does not support detaching from a process"));
 #endif
 
-  inf_ptrace_detach_success (ops, inf);
+  detach_success (inf);
 }
 
 /* See inf-ptrace.h.  */
 
 void
-inf_ptrace_detach_success (struct target_ops *ops, inferior *inf)
+inf_ptrace_target::detach_success (inferior *inf)
 {
   inferior_ptid = null_ptid;
   detach_inferior (inf);
 
-  inf_child_maybe_unpush_target (ops);
+  maybe_unpush_target ();
 }
 
 /* Kill the inferior.  */
 
-static void
-inf_ptrace_kill (struct target_ops *ops)
+void
+inf_ptrace_target::kill ()
 {
   pid_t pid = ptid_get_pid (inferior_ptid);
   int status;
@@ -330,9 +332,8 @@ get_ptrace_pid (ptid_t ptid)
    STEP is nonzero, single-step it.  If SIGNAL is nonzero, give it
    that signal.  */
 
-static void
-inf_ptrace_resume (struct target_ops *ops,
-		   ptid_t ptid, int step, enum gdb_signal signal)
+void
+inf_ptrace_target::resume (ptid_t ptid, int step, enum gdb_signal signal)
 {
   pid_t pid;
   int request;
@@ -372,9 +373,9 @@ inf_ptrace_resume (struct target_ops *ops,
    process ID of the child, or MINUS_ONE_PTID in case of error; store
    the status in *OURSTATUS.  */
 
-static ptid_t
-inf_ptrace_wait (struct target_ops *ops,
-		 ptid_t ptid, struct target_waitstatus *ourstatus, int options)
+ptid_t
+inf_ptrace_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
+			 int options)
 {
   pid_t pid;
   int status, save_errno;
@@ -520,11 +521,11 @@ inf_ptrace_peek_poke (pid_t pid, gdb_byte *readbuf,
 
 /* Implement the to_xfer_partial target_ops method.  */
 
-static enum target_xfer_status
-inf_ptrace_xfer_partial (struct target_ops *ops, enum target_object object,
-			 const char *annex, gdb_byte *readbuf,
-			 const gdb_byte *writebuf,
-			 ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
+enum target_xfer_status
+inf_ptrace_target::xfer_partial (enum target_object object,
+				 const char *annex, gdb_byte *readbuf,
+				 const gdb_byte *writebuf,
+				 ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
 {
   pid_t pid = get_ptrace_pid (inferior_ptid);
 
@@ -606,17 +607,17 @@ inf_ptrace_xfer_partial (struct target_ops *ops, enum target_object object,
 
 /* Return non-zero if the thread specified by PTID is alive.  */
 
-static int
-inf_ptrace_thread_alive (struct target_ops *ops, ptid_t ptid)
+int
+inf_ptrace_target::thread_alive (ptid_t ptid)
 {
   /* ??? Is kill the right way to do this?  */
-  return (kill (ptid_get_pid (ptid), 0) != -1);
+  return (::kill (ptid_get_pid (ptid), 0) != -1);
 }
 
 /* Print status information about what we're accessing.  */
 
-static void
-inf_ptrace_files_info (struct target_ops *ignore)
+void
+inf_ptrace_target::files_info ()
 {
   struct inferior *inf = current_inferior ();
 
@@ -625,8 +626,8 @@ inf_ptrace_files_info (struct target_ops *ignore)
 		   target_pid_to_str (inferior_ptid));
 }
 
-static const char *
-inf_ptrace_pid_to_str (struct target_ops *ops, ptid_t ptid)
+const char *
+inf_ptrace_target::pid_to_str (ptid_t ptid)
 {
   return normal_pid_to_str (ptid);
 }
@@ -638,9 +639,9 @@ inf_ptrace_pid_to_str (struct target_ops *ops, ptid_t ptid)
    Return -1 if there is insufficient buffer for a whole entry.
    Return 1 if an entry was read into *TYPEP and *VALP.  */
 
-static int
-inf_ptrace_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
-		       gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
+int
+inf_ptrace_target::auxv_parse (gdb_byte **readptr, gdb_byte *endptr,
+			       CORE_ADDR *typep, CORE_ADDR *valp)
 {
   struct type *int_type = builtin_type (target_gdbarch ())->builtin_int;
   struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
@@ -665,37 +666,4 @@ inf_ptrace_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
 }
 
 #endif
-
-/* Create a prototype ptrace target.  The client can override it with
-   local methods.  */
-
-struct target_ops *
-inf_ptrace_target (void)
-{
-  struct target_ops *t = inf_child_target ();
-
-  t->to_attach = inf_ptrace_attach;
-  t->to_detach = inf_ptrace_detach;
-  t->to_resume = inf_ptrace_resume;
-  t->to_wait = inf_ptrace_wait;
-  t->to_files_info = inf_ptrace_files_info;
-  t->to_kill = inf_ptrace_kill;
-  t->to_create_inferior = inf_ptrace_create_inferior;
-#ifdef PT_GET_PROCESS_STATE
-  t->to_follow_fork = inf_ptrace_follow_fork;
-  t->to_insert_fork_catchpoint = inf_ptrace_insert_fork_catchpoint;
-  t->to_remove_fork_catchpoint = inf_ptrace_remove_fork_catchpoint;
-  t->to_post_startup_inferior = inf_ptrace_post_startup_inferior;
-  t->to_post_attach = inf_ptrace_post_attach;
-#endif
-  t->to_mourn_inferior = inf_ptrace_mourn_inferior;
-  t->to_thread_alive = inf_ptrace_thread_alive;
-  t->to_pid_to_str = inf_ptrace_pid_to_str;
-  t->to_xfer_partial = inf_ptrace_xfer_partial;
-#if defined (PT_IO) && defined (PIOD_READ_AUXV)
-  t->to_auxv_parse = inf_ptrace_auxv_parse;
-#endif
-
-  return t;
-}
 \f
diff --git a/gdb/inf-ptrace.h b/gdb/inf-ptrace.h
index d10f64ae56..bd9b609ab4 100644
--- a/gdb/inf-ptrace.h
+++ b/gdb/inf-ptrace.h
@@ -20,26 +20,67 @@
 #ifndef INF_PTRACE_H
 #define INF_PTRACE_H
 
-/* Create a prototype ptrace target.  The client can override it with
-   local methods.  */
+#include "inf-child.h"
 
-extern struct target_ops *inf_ptrace_target (void);
+/* An abstract prototype ptrace target.  The client can override it
+   with local methods.  */
 
-/* Create a "traditional" ptrace target.  REGISTER_U_OFFSET should be
-   a function returning the offset within the user area where a
-   particular register is stored.  */
+struct inf_ptrace_target : public inf_child_target
+{
+  ~inf_ptrace_target () override = 0;
 
-extern struct target_ops *
-  inf_ptrace_trad_target (CORE_ADDR (*register_u_offset)
-					(struct gdbarch *, int, int));
+  void attach (const char *, int) override;
+
+  void detach (inferior *inf, int) override;
+
+  void resume (ptid_t, int, enum gdb_signal) override;
+
+  ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
+
+  void files_info () override;
+
+  void kill () override;
+
+  void create_inferior (const char *, const std::string &,
+			char **, int) override;
+#ifdef PT_GET_PROCESS_STATE
+  int follow_fork (int, int) override;
+
+  int insert_fork_catchpoint (int) override;
+
+  int remove_fork_catchpoint (int) override;
+
+  void post_startup_inferior (ptid_t) override;
+
+  void post_attach (int) override;
+#endif
+
+  void mourn_inferior () override;
+
+  int thread_alive (ptid_t ptid) override;
+
+  const char *pid_to_str (ptid_t) override;
+
+  enum target_xfer_status xfer_partial (enum target_object object,
+					const char *annex,
+					gdb_byte *readbuf,
+					const gdb_byte *writebuf,
+					ULONGEST offset, ULONGEST len,
+					ULONGEST *xfered_len) override;
+
+#if defined (PT_IO) && defined (PIOD_READ_AUXV)
+  int auxv_parse (gdb_byte **readptr,
+		  gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp) override;
+#endif
+
+protected:
+  /* Cleanup the inferior after a successful ptrace detach.  */
+  void detach_success (inferior *inf);
+};
 
 /* Return which PID to pass to ptrace in order to observe/control the
    tracee identified by PTID.  */
 
 extern pid_t get_ptrace_pid (ptid_t);
 
-
-/* Cleanup the inferior after a successful ptrace detach.  */
-extern void inf_ptrace_detach_success (struct target_ops *ops, inferior *inf);
-
 #endif
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index c23f83e057..bfc2e46ed6 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -186,14 +186,11 @@ leader.  */
 #define O_LARGEFILE 0
 #endif
 
+struct linux_nat_target *linux_target;
+
 /* Does the current host support PTRACE_GETREGSET?  */
 enum tribool have_ptrace_getregset = TRIBOOL_UNKNOWN;
 
-/* The single-threaded native GNU/Linux target_ops.  We save a pointer for
-   the use of the multi-threaded target.  */
-static struct target_ops *linux_ops;
-static struct target_ops linux_ops_saved;
-
 /* The method to call, if any, when a new thread is attached.  */
 static void (*linux_nat_new_thread) (struct lwp_info *);
 
@@ -217,10 +214,6 @@ static int (*linux_nat_siginfo_fixup) (siginfo_t *,
 				       gdb_byte *,
 				       int);
 
-/* The saved to_xfer_partial method, inherited from inf-ptrace.c.
-   Called by our to_xfer_partial.  */
-static target_xfer_partial_ftype *super_xfer_partial;
-
 /* The saved to_close method, inherited from inf-ptrace.c.
    Called by our to_close.  */
 static void (*super_close) (struct target_ops *);
@@ -431,14 +424,17 @@ linux_init_ptrace (pid_t pid, int attached)
   linux_ptrace_init_warnings ();
 }
 
-static void
-linux_child_post_attach (struct target_ops *self, int pid)
+linux_nat_target::~linux_nat_target ()
+{}
+
+void
+linux_nat_target::post_attach (int pid)
 {
   linux_init_ptrace (pid, 1);
 }
 
-static void
-linux_child_post_startup_inferior (struct target_ops *self, ptid_t ptid)
+void
+linux_nat_target::post_startup_inferior (ptid_t ptid)
 {
   linux_init_ptrace (ptid_get_pid (ptid), 0);
 }
@@ -472,9 +468,8 @@ delete_lwp_cleanup (void *lp_voidp)
    ptid of the followed inferior.  At return, inferior_ptid will be
    unchanged.  */
 
-static int
-linux_child_follow_fork (struct target_ops *ops, int follow_child,
-			 int detach_fork)
+int
+linux_nat_target::follow_fork (int follow_child, int detach_fork)
 {
   if (!follow_child)
     {
@@ -638,46 +633,45 @@ linux_child_follow_fork (struct target_ops *ops, int follow_child,
 }
 
 \f
-static int
-linux_child_insert_fork_catchpoint (struct target_ops *self, int pid)
+int
+linux_nat_target::insert_fork_catchpoint (int pid)
 {
   return !linux_supports_tracefork ();
 }
 
-static int
-linux_child_remove_fork_catchpoint (struct target_ops *self, int pid)
+int
+linux_nat_target::remove_fork_catchpoint (int pid)
 {
   return 0;
 }
 
-static int
-linux_child_insert_vfork_catchpoint (struct target_ops *self, int pid)
+int
+linux_nat_target::insert_vfork_catchpoint (int pid)
 {
   return !linux_supports_tracefork ();
 }
 
-static int
-linux_child_remove_vfork_catchpoint (struct target_ops *self, int pid)
+int
+linux_nat_target::remove_vfork_catchpoint (int pid)
 {
   return 0;
 }
 
-static int
-linux_child_insert_exec_catchpoint (struct target_ops *self, int pid)
+int
+linux_nat_target::insert_exec_catchpoint (int pid)
 {
   return !linux_supports_tracefork ();
 }
 
-static int
-linux_child_remove_exec_catchpoint (struct target_ops *self, int pid)
+int
+linux_nat_target::remove_exec_catchpoint (int pid)
 {
   return 0;
 }
 
-static int
-linux_child_set_syscall_catchpoint (struct target_ops *self,
-				    int pid, bool needed, int any_count,
-				    gdb::array_view<const int> syscall_counts)
+int
+linux_nat_target::set_syscall_catchpoint (int pid, bool needed, int any_count,
+					  gdb::array_view<const int> syscall_counts)
 {
   if (!linux_supports_tracesysgood ())
     return 1;
@@ -811,9 +805,8 @@ restore_child_signals_mask (sigset_t *prev_mask)
 static sigset_t pass_mask;
 
 /* Update signals to pass to the inferior.  */
-static void
-linux_nat_pass_signals (struct target_ops *self,
-			int numsigs, unsigned char *pass_signals)
+void
+linux_nat_target::pass_signals (int numsigs, unsigned char *pass_signals)
 {
   int signo;
 
@@ -831,7 +824,6 @@ linux_nat_pass_signals (struct target_ops *self,
 
 /* Prototypes for local functions.  */
 static int stop_wait_callback (struct lwp_info *lp, void *data);
-static char *linux_child_pid_to_exec_file (struct target_ops *self, int pid);
 static int resume_stopped_resumed_lwps (struct lwp_info *lp, void *data);
 static int check_ptrace_stopped_lwp_gone (struct lwp_info *lp);
 
@@ -1113,10 +1105,10 @@ linux_nat_post_attach_wait (ptid_t ptid, int *signalled)
   return status;
 }
 
-static void
-linux_nat_create_inferior (struct target_ops *ops, 
-			   const char *exec_file, const std::string &allargs,
-			   char **env, int from_tty)
+void
+linux_nat_target::create_inferior (const char *exec_file,
+				   const std::string &allargs,
+				   char **env, int from_tty)
 {
   maybe_disable_address_space_randomization restore_personality
     (disable_randomization);
@@ -1125,9 +1117,9 @@ linux_nat_create_inferior (struct target_ops *ops,
      we have to mask the async mode.  */
 
   /* Make sure we report all signals during startup.  */
-  linux_nat_pass_signals (ops, 0, NULL);
+  pass_signals (0, NULL);
 
-  linux_ops->to_create_inferior (ops, exec_file, allargs, env, from_tty);
+  inf_ptrace_target::create_inferior (exec_file, allargs, env, from_tty);
 }
 
 /* Callback for linux_proc_attach_tgid_threads.  Attach to PTID if not
@@ -1207,19 +1199,19 @@ attach_proc_task_lwp_callback (ptid_t ptid)
   return 0;
 }
 
-static void
-linux_nat_attach (struct target_ops *ops, const char *args, int from_tty)
+void
+linux_nat_target::attach (const char *args, int from_tty)
 {
   struct lwp_info *lp;
   int status;
   ptid_t ptid;
 
   /* Make sure we report all signals during attach.  */
-  linux_nat_pass_signals (ops, 0, NULL);
+  pass_signals (0, NULL);
 
   TRY
     {
-      linux_ops->to_attach (ops, args, from_tty);
+      inf_ptrace_target::attach (args, from_tty);
     }
   CATCH (ex, RETURN_MASK_ERROR)
     {
@@ -1496,8 +1488,8 @@ detach_callback (struct lwp_info *lp, void *data)
   return 0;
 }
 
-static void
-linux_nat_detach (struct target_ops *ops, inferior *inf, int from_tty)
+void
+linux_nat_target::detach (inferior *inf, int from_tty)
 {
   struct lwp_info *main_lwp;
   int pid = inf->pid;
@@ -1536,7 +1528,7 @@ linux_nat_detach (struct target_ops *ops, inferior *inf, int from_tty)
 
       detach_one_lwp (main_lwp, &signo);
 
-      inf_ptrace_detach_success (ops, inf);
+      detach_success (inf);
     }
 }
 
@@ -1563,7 +1555,7 @@ linux_resume_one_lwp_throw (struct lwp_info *lp, int step,
 
   if (linux_nat_prepare_to_resume != NULL)
     linux_nat_prepare_to_resume (lp);
-  linux_ops->to_resume (linux_ops, lp->ptid, step, signo);
+  linux_target->low_resume (lp->ptid, step, signo);
 
   /* Successfully resumed.  Clear state that no longer makes sense,
      and mark the LWP as running.  Must not do this before resuming
@@ -1716,9 +1708,8 @@ resume_set_callback (struct lwp_info *lp, void *data)
   return 0;
 }
 
-static void
-linux_nat_resume (struct target_ops *ops,
-		  ptid_t ptid, int step, enum gdb_signal signo)
+void
+linux_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
 {
   struct lwp_info *lp;
   int resume_many;
@@ -2117,7 +2108,7 @@ linux_handle_extended_wait (struct lwp_info *lp, int status)
 
       ourstatus->kind = TARGET_WAITKIND_EXECD;
       ourstatus->value.execd_pathname
-	= xstrdup (linux_child_pid_to_exec_file (NULL, pid));
+	= xstrdup (linux_proc_pid_to_exec_file (pid));
 
       /* The thread that execed must have been resumed, but, when a
 	 thread execs, it changes its tid to the tgid, and the old
@@ -2468,22 +2459,14 @@ maybe_clear_ignore_sigint (struct lwp_info *lp)
 static int
 check_stopped_by_watchpoint (struct lwp_info *lp)
 {
-  if (linux_ops->to_stopped_by_watchpoint == NULL)
-    return 0;
-
   scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
   inferior_ptid = lp->ptid;
 
-  if (linux_ops->to_stopped_by_watchpoint (linux_ops))
+  if (linux_target->low_stopped_by_watchpoint ())
     {
       lp->stop_reason = TARGET_STOPPED_BY_WATCHPOINT;
-
-      if (linux_ops->to_stopped_data_address != NULL)
-	lp->stopped_data_address_p =
-	  linux_ops->to_stopped_data_address (&current_target,
-					      &lp->stopped_data_address);
-      else
-	lp->stopped_data_address_p = 0;
+      lp->stopped_data_address_p
+	= linux_target->low_stopped_data_address (&lp->stopped_data_address);
     }
 
   return lp->stop_reason == TARGET_STOPPED_BY_WATCHPOINT;
@@ -2491,8 +2474,8 @@ check_stopped_by_watchpoint (struct lwp_info *lp)
 
 /* Returns true if the LWP had stopped for a watchpoint.  */
 
-static int
-linux_nat_stopped_by_watchpoint (struct target_ops *ops)
+int
+linux_nat_target::stopped_by_watchpoint ()
 {
   struct lwp_info *lp = find_lwp_pid (inferior_ptid);
 
@@ -2501,8 +2484,8 @@ linux_nat_stopped_by_watchpoint (struct target_ops *ops)
   return lp->stop_reason == TARGET_STOPPED_BY_WATCHPOINT;
 }
 
-static int
-linux_nat_stopped_data_address (struct target_ops *ops, CORE_ADDR *addr_p)
+int
+linux_nat_target::stopped_data_address (CORE_ADDR *addr_p)
 {
   struct lwp_info *lp = find_lwp_pid (inferior_ptid);
 
@@ -2852,8 +2835,8 @@ save_stop_reason (struct lwp_info *lp)
 
 /* Returns true if the LWP had stopped for a software breakpoint.  */
 
-static int
-linux_nat_stopped_by_sw_breakpoint (struct target_ops *ops)
+int
+linux_nat_target::stopped_by_sw_breakpoint ()
 {
   struct lwp_info *lp = find_lwp_pid (inferior_ptid);
 
@@ -2864,8 +2847,8 @@ linux_nat_stopped_by_sw_breakpoint (struct target_ops *ops)
 
 /* Implement the supports_stopped_by_sw_breakpoint method.  */
 
-static int
-linux_nat_supports_stopped_by_sw_breakpoint (struct target_ops *ops)
+int
+linux_nat_target::supports_stopped_by_sw_breakpoint ()
 {
   return USE_SIGTRAP_SIGINFO;
 }
@@ -2873,8 +2856,8 @@ linux_nat_supports_stopped_by_sw_breakpoint (struct target_ops *ops)
 /* Returns true if the LWP had stopped for a hardware
    breakpoint/watchpoint.  */
 
-static int
-linux_nat_stopped_by_hw_breakpoint (struct target_ops *ops)
+int
+linux_nat_target::stopped_by_hw_breakpoint ()
 {
   struct lwp_info *lp = find_lwp_pid (inferior_ptid);
 
@@ -2885,8 +2868,8 @@ linux_nat_stopped_by_hw_breakpoint (struct target_ops *ops)
 
 /* Implement the supports_stopped_by_hw_breakpoint method.  */
 
-static int
-linux_nat_supports_stopped_by_hw_breakpoint (struct target_ops *ops)
+int
+linux_nat_target::supports_stopped_by_hw_breakpoint ()
 {
   return USE_SIGTRAP_SIGINFO;
 }
@@ -3297,8 +3280,7 @@ filter_exit_event (struct lwp_info *event_child,
 }
 
 static ptid_t
-linux_nat_wait_1 (struct target_ops *ops,
-		  ptid_t ptid, struct target_waitstatus *ourstatus,
+linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus,
 		  int target_options)
 {
   sigset_t prev_mask;
@@ -3600,10 +3582,9 @@ resume_stopped_resumed_lwps (struct lwp_info *lp, void *data)
   return 0;
 }
 
-static ptid_t
-linux_nat_wait (struct target_ops *ops,
-		ptid_t ptid, struct target_waitstatus *ourstatus,
-		int target_options)
+ptid_t
+linux_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
+			int target_options)
 {
   ptid_t event_ptid;
 
@@ -3633,7 +3614,7 @@ linux_nat_wait (struct target_ops *ops,
   if (target_is_non_stop_p ())
     iterate_over_lwps (minus_one_ptid, resume_stopped_resumed_lwps, &ptid);
 
-  event_ptid = linux_nat_wait_1 (ops, ptid, ourstatus, target_options);
+  event_ptid = linux_nat_wait_1 (ptid, ourstatus, target_options);
 
   /* If we requested any event, and something came out, assume there
      may be more.  If we requested a specific lwp or process, also
@@ -3759,8 +3740,8 @@ kill_unfollowed_fork_children (struct inferior *inf)
       }
 }
 
-static void
-linux_nat_kill (struct target_ops *ops)
+void
+linux_nat_target::kill ()
 {
   /* If we're stopped while forking and we haven't followed yet,
      kill the other task.  We need to do this first because the
@@ -3790,8 +3771,8 @@ linux_nat_kill (struct target_ops *ops)
   target_mourn_inferior (inferior_ptid);
 }
 
-static void
-linux_nat_mourn_inferior (struct target_ops *ops)
+void
+linux_nat_target::mourn_inferior ()
 {
   int pid = ptid_get_pid (inferior_ptid);
 
@@ -3799,7 +3780,7 @@ linux_nat_mourn_inferior (struct target_ops *ops)
 
   if (! forks_exist_p ())
     /* Normal case, no other forks available.  */
-    linux_ops->to_mourn_inferior (ops);
+    inf_ptrace_target::mourn_inferior ();
   else
     /* Multi-fork case.  The current inferior_ptid has exited, but
        there are other viable forks to debug.  Delete the exiting
@@ -3833,7 +3814,7 @@ siginfo_fixup (siginfo_t *siginfo, gdb_byte *inf_siginfo, int direction)
 }
 
 static enum target_xfer_status
-linux_xfer_siginfo (struct target_ops *ops, enum target_object object,
+linux_xfer_siginfo (enum target_object object,
                     const char *annex, gdb_byte *readbuf,
 		    const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
 		    ULONGEST *xfered_len)
@@ -3888,15 +3869,33 @@ linux_xfer_siginfo (struct target_ops *ops, enum target_object object,
 }
 
 static enum target_xfer_status
-linux_nat_xfer_partial (struct target_ops *ops, enum target_object object,
-			const char *annex, gdb_byte *readbuf,
-			const gdb_byte *writebuf,
-			ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
+linux_nat_xfer_osdata (enum target_object object,
+		       const char *annex, gdb_byte *readbuf,
+		       const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
+		       ULONGEST *xfered_len);
+
+static enum target_xfer_status
+linux_proc_xfer_spu (enum target_object object,
+		     const char *annex, gdb_byte *readbuf,
+		     const gdb_byte *writebuf,
+		     ULONGEST offset, ULONGEST len, ULONGEST *xfered_len);
+
+static enum target_xfer_status
+linux_proc_xfer_partial (enum target_object object,
+			 const char *annex, gdb_byte *readbuf,
+			 const gdb_byte *writebuf,
+			 ULONGEST offset, LONGEST len, ULONGEST *xfered_len);
+
+enum target_xfer_status
+linux_nat_target::xfer_partial (enum target_object object,
+				const char *annex, gdb_byte *readbuf,
+				const gdb_byte *writebuf,
+				ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
 {
   enum target_xfer_status xfer;
 
   if (object == TARGET_OBJECT_SIGNAL_INFO)
-    return linux_xfer_siginfo (ops, object, annex, readbuf, writebuf,
+    return linux_xfer_siginfo (object, annex, readbuf, writebuf,
 			       offset, len, xfered_len);
 
   /* The target is connected but no live inferior is selected.  Pass
@@ -3905,14 +3904,44 @@ linux_nat_xfer_partial (struct target_ops *ops, enum target_object object,
   if (object == TARGET_OBJECT_MEMORY && ptid_equal (inferior_ptid, null_ptid))
     return TARGET_XFER_EOF;
 
-  xfer = linux_ops->to_xfer_partial (ops, object, annex, readbuf, writebuf,
-				     offset, len, xfered_len);
+  if (object == TARGET_OBJECT_AUXV)
+    return memory_xfer_auxv (this, object, annex, readbuf, writebuf,
+			     offset, len, xfered_len);
+
+  if (object == TARGET_OBJECT_OSDATA)
+    return linux_nat_xfer_osdata (object, annex, readbuf, writebuf,
+				  offset, len, xfered_len);
 
-  return xfer;
+  if (object == TARGET_OBJECT_SPU)
+    return linux_proc_xfer_spu (object, annex, readbuf, writebuf,
+				offset, len, xfered_len);
+
+  /* GDB calculates all addresses in the largest possible address
+     width.
+     The address width must be masked before its final use - either by
+     linux_proc_xfer_partial or inf_ptrace_target::xfer_partial.
+
+     Compare ADDR_BIT first to avoid a compiler warning on shift overflow.  */
+
+  if (object == TARGET_OBJECT_MEMORY)
+    {
+      int addr_bit = gdbarch_addr_bit (target_gdbarch ());
+
+      if (addr_bit < (sizeof (ULONGEST) * HOST_CHAR_BIT))
+	offset &= ((ULONGEST) 1 << addr_bit) - 1;
+    }
+
+  xfer = linux_proc_xfer_partial (object, annex, readbuf, writebuf,
+				  offset, len, xfered_len);
+  if (xfer != TARGET_XFER_EOF)
+    return xfer;
+
+  return inf_ptrace_target::xfer_partial (object, annex, readbuf, writebuf,
+					  offset, len, xfered_len);
 }
 
-static int
-linux_nat_thread_alive (struct target_ops *ops, ptid_t ptid)
+int
+linux_nat_target::thread_alive (ptid_t ptid)
 {
   /* As long as a PTID is in lwp list, consider it alive.  */
   return find_lwp_pid (ptid) != NULL;
@@ -3921,8 +3950,8 @@ linux_nat_thread_alive (struct target_ops *ops, ptid_t ptid)
 /* Implement the to_update_thread_list target method for this
    target.  */
 
-static void
-linux_nat_update_thread_list (struct target_ops *ops)
+void
+linux_nat_target::update_thread_list ()
 {
   struct lwp_info *lwp;
 
@@ -3943,8 +3972,8 @@ linux_nat_update_thread_list (struct target_ops *ops)
     }
 }
 
-static const char *
-linux_nat_pid_to_str (struct target_ops *ops, ptid_t ptid)
+const char *
+linux_nat_target::pid_to_str (ptid_t ptid)
 {
   static char buf[64];
 
@@ -3959,8 +3988,8 @@ linux_nat_pid_to_str (struct target_ops *ops, ptid_t ptid)
   return normal_pid_to_str (ptid);
 }
 
-static const char *
-linux_nat_thread_name (struct target_ops *self, struct thread_info *thr)
+const char *
+linux_nat_target::thread_name (struct thread_info *thr)
 {
   return linux_proc_tid_get_name (thr->ptid);
 }
@@ -3968,8 +3997,8 @@ linux_nat_thread_name (struct target_ops *self, struct thread_info *thr)
 /* Accepts an integer PID; Returns a string representing a file that
    can be opened to get the symbols for the child process.  */
 
-static char *
-linux_child_pid_to_exec_file (struct target_ops *self, int pid)
+char *
+linux_nat_target::pid_to_exec_file (int pid)
 {
   return linux_proc_pid_to_exec_file (pid);
 }
@@ -3979,7 +4008,7 @@ linux_child_pid_to_exec_file (struct target_ops *self, int pid)
    efficient than banging away at PTRACE_PEEKTEXT.  */
 
 static enum target_xfer_status
-linux_proc_xfer_partial (struct target_ops *ops, enum target_object object,
+linux_proc_xfer_partial (enum target_object object,
 			 const char *annex, gdb_byte *readbuf,
 			 const gdb_byte *writebuf,
 			 ULONGEST offset, LONGEST len, ULONGEST *xfered_len)
@@ -4083,7 +4112,7 @@ spu_enumerate_spu_ids (int pid, gdb_byte *buf, ULONGEST offset, ULONGEST len)
    object type, using the /proc file system.  */
 
 static enum target_xfer_status
-linux_proc_xfer_spu (struct target_ops *ops, enum target_object object,
+linux_proc_xfer_spu (enum target_object object,
 		     const char *annex, gdb_byte *readbuf,
 		     const gdb_byte *writebuf,
 		     ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
@@ -4223,7 +4252,7 @@ linux_proc_pending_signals (int pid, sigset_t *pending,
 }
 
 static enum target_xfer_status
-linux_nat_xfer_osdata (struct target_ops *ops, enum target_object object,
+linux_nat_xfer_osdata (enum target_object object,
 		       const char *annex, gdb_byte *readbuf,
 		       const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
 		       ULONGEST *xfered_len)
@@ -4237,49 +4266,6 @@ linux_nat_xfer_osdata (struct target_ops *ops, enum target_object object,
     return TARGET_XFER_OK;
 }
 
-static enum target_xfer_status
-linux_xfer_partial (struct target_ops *ops, enum target_object object,
-                    const char *annex, gdb_byte *readbuf,
-		    const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
-		    ULONGEST *xfered_len)
-{
-  enum target_xfer_status xfer;
-
-  if (object == TARGET_OBJECT_AUXV)
-    return memory_xfer_auxv (ops, object, annex, readbuf, writebuf,
-			     offset, len, xfered_len);
-
-  if (object == TARGET_OBJECT_OSDATA)
-    return linux_nat_xfer_osdata (ops, object, annex, readbuf, writebuf,
-				  offset, len, xfered_len);
-
-  if (object == TARGET_OBJECT_SPU)
-    return linux_proc_xfer_spu (ops, object, annex, readbuf, writebuf,
-				offset, len, xfered_len);
-
-  /* GDB calculates all the addresses in possibly larget width of the address.
-     Address width needs to be masked before its final use - either by
-     linux_proc_xfer_partial or inf_ptrace_xfer_partial.
-
-     Compare ADDR_BIT first to avoid a compiler warning on shift overflow.  */
-
-  if (object == TARGET_OBJECT_MEMORY)
-    {
-      int addr_bit = gdbarch_addr_bit (target_gdbarch ());
-
-      if (addr_bit < (sizeof (ULONGEST) * HOST_CHAR_BIT))
-	offset &= ((ULONGEST) 1 << addr_bit) - 1;
-    }
-
-  xfer = linux_proc_xfer_partial (ops, object, annex, readbuf, writebuf,
-				  offset, len, xfered_len);
-  if (xfer != TARGET_XFER_EOF)
-    return xfer;
-
-  return super_xfer_partial (ops, object, annex, readbuf, writebuf,
-			     offset, len, xfered_len);
-}
-
 static void
 cleanup_target_stop (void *arg)
 {
@@ -4291,9 +4277,8 @@ cleanup_target_stop (void *arg)
   target_continue_no_signal (*ptid);
 }
 
-static std::vector<static_tracepoint_marker>
-linux_child_static_tracepoint_markers_by_strid (struct target_ops *self,
-						const char *strid)
+std::vector<static_tracepoint_marker>
+linux_nat_target::static_tracepoint_markers_by_strid (const char *strid)
 {
   char s[IPA_CMD_BUF_SIZE];
   struct cleanup *old_chain;
@@ -4335,70 +4320,34 @@ linux_child_static_tracepoint_markers_by_strid (struct target_ops *self,
   return markers;
 }
 
-/* Create a prototype generic GNU/Linux target.  The client can override
-   it with local methods.  */
-
-void
-linux_target_install_ops (struct target_ops *t)
-{
-  t->to_insert_fork_catchpoint = linux_child_insert_fork_catchpoint;
-  t->to_remove_fork_catchpoint = linux_child_remove_fork_catchpoint;
-  t->to_insert_vfork_catchpoint = linux_child_insert_vfork_catchpoint;
-  t->to_remove_vfork_catchpoint = linux_child_remove_vfork_catchpoint;
-  t->to_insert_exec_catchpoint = linux_child_insert_exec_catchpoint;
-  t->to_remove_exec_catchpoint = linux_child_remove_exec_catchpoint;
-  t->to_set_syscall_catchpoint = linux_child_set_syscall_catchpoint;
-  t->to_pid_to_exec_file = linux_child_pid_to_exec_file;
-  t->to_post_startup_inferior = linux_child_post_startup_inferior;
-  t->to_post_attach = linux_child_post_attach;
-  t->to_follow_fork = linux_child_follow_fork;
-
-  super_xfer_partial = t->to_xfer_partial;
-  t->to_xfer_partial = linux_xfer_partial;
-
-  t->to_static_tracepoint_markers_by_strid
-    = linux_child_static_tracepoint_markers_by_strid;
-}
-
-struct target_ops *
-linux_target (void)
-{
-  struct target_ops *t;
-
-  t = inf_ptrace_target ();
-  linux_target_install_ops (t);
-
-  return t;
-}
-
 /* target_is_async_p implementation.  */
 
-static int
-linux_nat_is_async_p (struct target_ops *ops)
+int
+linux_nat_target::is_async_p ()
 {
   return linux_is_async_p ();
 }
 
 /* target_can_async_p implementation.  */
 
-static int
-linux_nat_can_async_p (struct target_ops *ops)
+int
+linux_nat_target::can_async_p ()
 {
   /* We're always async, unless the user explicitly prevented it with the
      "maint set target-async" command.  */
   return target_async_permitted;
 }
 
-static int
-linux_nat_supports_non_stop (struct target_ops *self)
+int
+linux_nat_target::supports_non_stop ()
 {
   return 1;
 }
 
 /* to_always_non_stop_p implementation.  */
 
-static int
-linux_nat_always_non_stop_p (struct target_ops *self)
+int
+linux_nat_target::always_non_stop_p ()
 {
   return 1;
 }
@@ -4408,14 +4357,14 @@ linux_nat_always_non_stop_p (struct target_ops *self)
 
 int linux_multi_process = 1;
 
-static int
-linux_nat_supports_multi_process (struct target_ops *self)
+int
+linux_nat_target::supports_multi_process ()
 {
   return linux_multi_process;
 }
 
-static int
-linux_nat_supports_disable_randomization (struct target_ops *self)
+int
+linux_nat_target::supports_disable_randomization ()
 {
 #ifdef HAVE_PERSONALITY
   return 1;
@@ -4494,8 +4443,8 @@ linux_async_pipe (int enable)
 
 /* target_async implementation.  */
 
-static void
-linux_nat_async (struct target_ops *ops, int enable)
+void
+linux_nat_target::async (int enable)
 {
   if (enable)
     {
@@ -4563,23 +4512,20 @@ linux_nat_stop_lwp (struct lwp_info *lwp, void *data)
   return 0;
 }
 
-static void
-linux_nat_stop (struct target_ops *self, ptid_t ptid)
+void
+linux_nat_target::stop (ptid_t ptid)
 {
   iterate_over_lwps (ptid, linux_nat_stop_lwp, NULL);
 }
 
-static void
-linux_nat_close (struct target_ops *self)
+void
+linux_nat_target::close ()
 {
   /* Unregister from the event loop.  */
-  if (linux_nat_is_async_p (self))
-    linux_nat_async (self, 0);
+  if (is_async_p ())
+    async (0);
 
-  if (linux_ops->to_close)
-    linux_ops->to_close (linux_ops);
-
-  super_close (self);
+  inf_ptrace_target::close ();
 }
 
 /* When requests are passed down from the linux-nat layer to the
@@ -4589,8 +4535,8 @@ linux_nat_close (struct target_ops *self)
    lwpid is a "main" process id or not (it assumes so).  We reverse
    look up the "main" process id from the lwp here.  */
 
-static struct address_space *
-linux_nat_thread_address_space (struct target_ops *t, ptid_t ptid)
+struct address_space *
+linux_nat_target::thread_address_space (ptid_t ptid)
 {
   struct lwp_info *lwp;
   struct inferior *inf;
@@ -4616,8 +4562,8 @@ linux_nat_thread_address_space (struct target_ops *t, ptid_t ptid)
 
 /* Return the cached value of the processor core for thread PTID.  */
 
-static int
-linux_nat_core_of_thread (struct target_ops *ops, ptid_t ptid)
+int
+linux_nat_target::core_of_thread (ptid_t ptid)
 {
   struct lwp_info *info = find_lwp_pid (ptid);
 
@@ -4628,8 +4574,8 @@ linux_nat_core_of_thread (struct target_ops *ops, ptid_t ptid)
 
 /* Implementation of to_filesystem_is_local.  */
 
-static int
-linux_nat_filesystem_is_local (struct target_ops *ops)
+int
+linux_nat_target::filesystem_is_local ()
 {
   struct inferior *inf = current_inferior ();
 
@@ -4658,11 +4604,10 @@ linux_nat_fileio_pid_of (struct inferior *inf)
 
 /* Implementation of to_fileio_open.  */
 
-static int
-linux_nat_fileio_open (struct target_ops *self,
-		       struct inferior *inf, const char *filename,
-		       int flags, int mode, int warn_if_slow,
-		       int *target_errno)
+int
+linux_nat_target::fileio_open (struct inferior *inf, const char *filename,
+			       int flags, int mode, int warn_if_slow,
+			       int *target_errno)
 {
   int nat_flags;
   mode_t nat_mode;
@@ -4685,10 +4630,9 @@ linux_nat_fileio_open (struct target_ops *self,
 
 /* Implementation of to_fileio_readlink.  */
 
-static gdb::optional<std::string>
-linux_nat_fileio_readlink (struct target_ops *self,
-			   struct inferior *inf, const char *filename,
-			   int *target_errno)
+gdb::optional<std::string>
+linux_nat_target::fileio_readlink (struct inferior *inf, const char *filename,
+				   int *target_errno)
 {
   char buf[PATH_MAX];
   int len;
@@ -4706,10 +4650,9 @@ linux_nat_fileio_readlink (struct target_ops *self,
 
 /* Implementation of to_fileio_unlink.  */
 
-static int
-linux_nat_fileio_unlink (struct target_ops *self,
-			 struct inferior *inf, const char *filename,
-			 int *target_errno)
+int
+linux_nat_target::fileio_unlink (struct inferior *inf, const char *filename,
+				 int *target_errno)
 {
   int ret;
 
@@ -4723,76 +4666,19 @@ linux_nat_fileio_unlink (struct target_ops *self,
 
 /* Implementation of the to_thread_events method.  */
 
-static void
-linux_nat_thread_events (struct target_ops *ops, int enable)
+void
+linux_nat_target::thread_events (int enable)
 {
   report_thread_events = enable;
 }
 
-void
-linux_nat_add_target (struct target_ops *t)
-{
-  /* Save the provided single-threaded target.  We save this in a separate
-     variable because another target we've inherited from (e.g. inf-ptrace)
-     may have saved a pointer to T; we want to use it for the final
-     process stratum target.  */
-  linux_ops_saved = *t;
-  linux_ops = &linux_ops_saved;
-
-  /* Override some methods for multithreading.  */
-  t->to_create_inferior = linux_nat_create_inferior;
-  t->to_attach = linux_nat_attach;
-  t->to_detach = linux_nat_detach;
-  t->to_resume = linux_nat_resume;
-  t->to_wait = linux_nat_wait;
-  t->to_pass_signals = linux_nat_pass_signals;
-  t->to_xfer_partial = linux_nat_xfer_partial;
-  t->to_kill = linux_nat_kill;
-  t->to_mourn_inferior = linux_nat_mourn_inferior;
-  t->to_thread_alive = linux_nat_thread_alive;
-  t->to_update_thread_list = linux_nat_update_thread_list;
-  t->to_pid_to_str = linux_nat_pid_to_str;
-  t->to_thread_name = linux_nat_thread_name;
-  t->to_has_thread_control = tc_schedlock;
-  t->to_thread_address_space = linux_nat_thread_address_space;
-  t->to_stopped_by_watchpoint = linux_nat_stopped_by_watchpoint;
-  t->to_stopped_data_address = linux_nat_stopped_data_address;
-  t->to_stopped_by_sw_breakpoint = linux_nat_stopped_by_sw_breakpoint;
-  t->to_supports_stopped_by_sw_breakpoint = linux_nat_supports_stopped_by_sw_breakpoint;
-  t->to_stopped_by_hw_breakpoint = linux_nat_stopped_by_hw_breakpoint;
-  t->to_supports_stopped_by_hw_breakpoint = linux_nat_supports_stopped_by_hw_breakpoint;
-  t->to_thread_events = linux_nat_thread_events;
-
-  t->to_can_async_p = linux_nat_can_async_p;
-  t->to_is_async_p = linux_nat_is_async_p;
-  t->to_supports_non_stop = linux_nat_supports_non_stop;
-  t->to_always_non_stop_p = linux_nat_always_non_stop_p;
-  t->to_async = linux_nat_async;
-
-  super_close = t->to_close;
-  t->to_close = linux_nat_close;
-
-  t->to_stop = linux_nat_stop;
-
-  t->to_supports_multi_process = linux_nat_supports_multi_process;
-
-  t->to_supports_disable_randomization
-    = linux_nat_supports_disable_randomization;
-
-  t->to_core_of_thread = linux_nat_core_of_thread;
-
-  t->to_filesystem_is_local = linux_nat_filesystem_is_local;
-  t->to_fileio_open = linux_nat_fileio_open;
-  t->to_fileio_readlink = linux_nat_fileio_readlink;
-  t->to_fileio_unlink = linux_nat_fileio_unlink;
-
+linux_nat_target::linux_nat_target ()
+{
   /* We don't change the stratum; this target will sit at
      process_stratum and thread_db will set at thread_stratum.  This
      is a little strange, since this is a multi-threaded-capable
      target, but we want to be on the stack below thread_db, and we
      also want to be used for single-threaded processes.  */
-
-  add_target (t);
 }
 
 /* Register a method to call whenever a new thread is attached.  */
diff --git a/gdb/linux-nat.h b/gdb/linux-nat.h
index 03c2021911..da5357a21e 100644
--- a/gdb/linux-nat.h
+++ b/gdb/linux-nat.h
@@ -18,9 +18,138 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "nat/linux-nat.h"
+#include "inf-ptrace.h"
 #include "target.h"
 #include <signal.h>
 
+/* A prototype generic GNU/Linux target.  A concrete instance should
+   override it with local methods.  */
+
+class linux_nat_target : public inf_ptrace_target
+{
+public:
+  linux_nat_target ();
+  ~linux_nat_target () override = 0;
+
+  thread_control_capabilities get_thread_control_capabilities () override
+  { return tc_schedlock; }
+
+  void create_inferior (const char *, const std::string &,
+			char **, int) override;
+
+  void attach (const char *, int) override;
+
+  void detach (inferior *, int) override;
+
+  void resume (ptid_t, int, enum gdb_signal) override;
+
+  ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
+
+  void pass_signals (int, unsigned char *) override;
+
+  enum target_xfer_status xfer_partial (enum target_object object,
+					const char *annex,
+					gdb_byte *readbuf,
+					const gdb_byte *writebuf,
+					ULONGEST offset, ULONGEST len,
+					ULONGEST *xfered_len) override;
+
+  void kill () override;
+
+  void mourn_inferior () override;
+  int thread_alive (ptid_t ptid) override;
+
+  void update_thread_list () override;
+
+  const char *pid_to_str (ptid_t) override;
+
+  const char *thread_name (struct thread_info *) override;
+
+  struct address_space *thread_address_space (ptid_t) override;
+
+  int stopped_by_watchpoint () override;
+
+  int stopped_data_address (CORE_ADDR *) override;
+
+  int stopped_by_sw_breakpoint () override;
+  int supports_stopped_by_sw_breakpoint () override;
+
+  int stopped_by_hw_breakpoint () override;
+  int supports_stopped_by_hw_breakpoint () override;
+
+  void thread_events (int) override;
+
+  int can_async_p () override;
+  int is_async_p () override;
+
+  int supports_non_stop () override;
+  int always_non_stop_p () override;
+
+  void async (int) override;
+
+  void close () override;
+
+  void stop (ptid_t) override;
+
+  int supports_multi_process () override;
+
+  int supports_disable_randomization () override;
+
+  int core_of_thread (ptid_t ptid) override;
+
+  int filesystem_is_local () override;
+
+  int fileio_open (struct inferior *inf, const char *filename,
+		   int flags, int mode, int warn_if_slow,
+		   int *target_errno) override;
+
+  gdb::optional<std::string>
+    fileio_readlink (struct inferior *inf,
+		     const char *filename,
+		     int *target_errno) override;
+
+  int fileio_unlink (struct inferior *inf,
+		     const char *filename,
+		     int *target_errno) override;
+
+  int insert_fork_catchpoint (int) override;
+  int remove_fork_catchpoint (int) override;
+  int insert_vfork_catchpoint (int) override;
+  int remove_vfork_catchpoint (int) override;
+
+  int insert_exec_catchpoint (int) override;
+  int remove_exec_catchpoint (int) override;
+
+  int set_syscall_catchpoint (int pid, bool needed, int any_count,
+			      gdb::array_view<const int> syscall_counts) override;
+
+  char *pid_to_exec_file (int pid) override;
+
+  void post_startup_inferior (ptid_t) override;
+
+  void post_attach (int) override;
+
+  int follow_fork (int, int) override;
+
+  std::vector<static_tracepoint_marker>
+    static_tracepoint_markers_by_strid (const char *id) override;
+
+  /* Methods that are meant to overridden by the concrete
+     arch-specific target instance.  */
+
+  virtual void low_resume (ptid_t ptid, int step, enum gdb_signal sig)
+  { inf_ptrace_target::resume (ptid, step, sig); }
+
+  virtual int low_stopped_by_watchpoint ()
+  { return 0; }
+
+  virtual int low_stopped_data_address (CORE_ADDR *addr_p)
+  { return 0; }
+};
+
+/* The final/concrete instance.  */
+extern linux_nat_target *linux_target;
+
 struct arch_lwp_info;
 
 /* Structure describing an LWP.  This is public only for the purposes
@@ -149,18 +278,6 @@ extern void linux_stop_and_wait_all_lwps (void);
    left stopped.)  */
 extern void linux_unstop_all_lwps (void);
 
-/* Create a prototype generic GNU/Linux target.  The client can
-   override it with local methods.  */
-struct target_ops * linux_target (void);
-
-/* Make a prototype generic GNU/Linux target.  The client can override
-   it with local methods.  */
-void linux_target_install_ops (struct target_ops *t);
-
-/* Register the customized GNU/Linux target.  This should be used
-   instead of calling add_target directly.  */
-void linux_nat_add_target (struct target_ops *);
-
 /* Register a method to call whenever a new thread is attached.  */
 void linux_nat_set_new_thread (struct target_ops *, void (*) (struct lwp_info *));
 
diff --git a/gdb/linux-thread-db.c b/gdb/linux-thread-db.c
index 08e3cfbc8b..a7b0772d45 100644
--- a/gdb/linux-thread-db.c
+++ b/gdb/linux-thread-db.c
@@ -75,6 +75,40 @@
    of the ptid_t prevents thread IDs changing when libpthread is
    loaded or unloaded.  */
 
+class thread_db_target : public target_ops
+{
+public:
+  thread_db_target ();
+
+  const char *shortname () override
+  { return "multi-thread"; }
+  const char *longname () override
+  { return _("multi-threaded child process."); }
+  const char *doc () override
+  { return _("Threads and pthreads support."); }
+
+  void detach (inferior *, int) override;
+  ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
+  void resume (ptid_t, int, enum gdb_signal) override;
+  void mourn_inferior () override;
+  void update_thread_list () override;
+  const char *pid_to_str (ptid_t) override;
+  CORE_ADDR get_thread_local_address (ptid_t ptid,
+				      CORE_ADDR load_module_addr,
+				      CORE_ADDR offset) override;
+  const char *extra_thread_info (struct thread_info *) override;
+  ptid_t get_ada_task_ptid (long lwp, long thread) override;
+
+  thread_info *thread_handle_to_thread_info (const gdb_byte *thread_handle,
+					     int handle_len,
+					     inferior *inf) override;
+};
+
+thread_db_target::thread_db_target()
+{
+  this->to_stratum = thread_stratum;
+}
+
 static char *libthread_db_search_path;
 
 /* Set to non-zero if thread_db auto-loading is enabled
@@ -118,7 +152,7 @@ show_libthread_db_debug (struct ui_file *file, int from_tty,
    threads.  */
 
 /* This module's target vector.  */
-static struct target_ops thread_db_ops;
+static thread_db_target the_thread_db_target;
 
 /* Non-zero if we have determined the signals used by the threads
    library.  */
@@ -635,7 +669,7 @@ try_thread_db_load_1 (struct thread_db_info *info)
   /* The thread library was detected.  Activate the thread_db target
      if this is the first process using it.  */
   if (thread_db_list->next == NULL)
-    push_target (&thread_db_ops);
+    push_target (&the_thread_db_target);
 
   return 1;
 }
@@ -889,7 +923,7 @@ thread_db_load (void)
     return 0;
 
   /* Don't attempt to use thread_db for remote targets.  */
-  if (!(target_can_run (&current_target) || core_bfd))
+  if (!(target_can_run () || core_bfd))
     return 0;
 
   if (thread_db_load_search ())
@@ -980,7 +1014,7 @@ static void
 check_pid_namespace_match (void)
 {
   /* Check is only relevant for local targets targets.  */
-  if (target_can_run (&current_target))
+  if (target_can_run ())
     {
       /* If the child is in a different PID namespace, its idea of its
 	 PID will differ from our idea of its PID.  When we scan the
@@ -1055,32 +1089,31 @@ record_thread (struct thread_db_info *info,
   return tp;
 }
 
-static void
-thread_db_detach (struct target_ops *ops, inferior *inf, int from_tty)
+void
+thread_db_target::detach (inferior *inf, int from_tty)
 {
-  struct target_ops *target_beneath = find_target_beneath (ops);
+  struct target_ops *target_beneath = find_target_beneath (this);
 
   delete_thread_db_info (inf->pid);
 
-  target_beneath->to_detach (target_beneath, inf, from_tty);
+  target_beneath->detach (inf, from_tty);
 
   /* NOTE: From this point on, inferior_ptid is null_ptid.  */
 
   /* If there are no more processes using libpthread, detach the
      thread_db target ops.  */
   if (!thread_db_list)
-    unpush_target (&thread_db_ops);
+    unpush_target (this);
 }
 
-static ptid_t
-thread_db_wait (struct target_ops *ops,
-		ptid_t ptid, struct target_waitstatus *ourstatus,
-		int options)
+ptid_t
+thread_db_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
+			int options)
 {
   struct thread_db_info *info;
-  struct target_ops *beneath = find_target_beneath (ops);
+  struct target_ops *beneath = find_target_beneath (this);
 
-  ptid = beneath->to_wait (beneath, ptid, ourstatus, options);
+  ptid = beneath->wait (ptid, ourstatus, options);
 
   switch (ourstatus->kind)
     {
@@ -1103,7 +1136,7 @@ thread_db_wait (struct target_ops *ops,
 	 not unless we find otherwise.  */
       delete_thread_db_info (ptid_get_pid (ptid));
       if (!thread_db_list)
- 	unpush_target (&thread_db_ops);
+	unpush_target (&the_thread_db_target);
 
       return ptid;
     }
@@ -1114,18 +1147,18 @@ thread_db_wait (struct target_ops *ops,
   return ptid;
 }
 
-static void
-thread_db_mourn_inferior (struct target_ops *ops)
+void
+thread_db_target::mourn_inferior ()
 {
-  struct target_ops *target_beneath = find_target_beneath (ops);
+  struct target_ops *target_beneath = find_target_beneath (this);
 
   delete_thread_db_info (ptid_get_pid (inferior_ptid));
 
-  target_beneath->to_mourn_inferior (target_beneath);
+  target_beneath->mourn_inferior ();
 
   /* Detach thread_db target ops.  */
   if (!thread_db_list)
-    unpush_target (ops);
+    unpush_target (&the_thread_db_target);
 }
 
 struct callback_data
@@ -1293,8 +1326,8 @@ thread_db_find_new_threads_1 (ptid_t ptid)
 /* Implement the to_update_thread_list target method for this
    target.  */
 
-static void
-thread_db_update_thread_list (struct target_ops *ops)
+void
+thread_db_target::update_thread_list ()
 {
   struct thread_db_info *info;
   struct inferior *inf;
@@ -1334,11 +1367,11 @@ thread_db_update_thread_list (struct target_ops *ops)
     }
 
   /* Give the beneath target a chance to do extra processing.  */
-  ops->beneath->to_update_thread_list (ops->beneath);
+  this->beneath->update_thread_list ();
 }
 
-static const char *
-thread_db_pid_to_str (struct target_ops *ops, ptid_t ptid)
+const char *
+thread_db_target::pid_to_str (ptid_t ptid)
 {
   struct thread_info *thread_info = find_thread_ptid (ptid);
   struct target_ops *beneath;
@@ -1354,16 +1387,15 @@ thread_db_pid_to_str (struct target_ops *ops, ptid_t ptid)
       return buf;
     }
 
-  beneath = find_target_beneath (ops);
-  return beneath->to_pid_to_str (beneath, ptid);
+  beneath = find_target_beneath (this);
+  return beneath->pid_to_str (ptid);
 }
 
 /* Return a string describing the state of the thread specified by
    INFO.  */
 
-static const char *
-thread_db_extra_thread_info (struct target_ops *self,
-			     struct thread_info *info)
+const char *
+thread_db_target::extra_thread_info (thread_info *info)
 {
   if (info->priv == NULL)
     return NULL;
@@ -1379,11 +1411,10 @@ thread_db_extra_thread_info (struct target_ops *self,
 /* Return pointer to the thread_info struct which corresponds to
    THREAD_HANDLE (having length HANDLE_LEN).  */
 
-static struct thread_info *
-thread_db_thread_handle_to_thread_info (struct target_ops *ops,
-					const gdb_byte *thread_handle,
-					int handle_len,
-					struct inferior *inf)
+thread_info *
+thread_db_target::thread_handle_to_thread_info (const gdb_byte *thread_handle,
+						int handle_len,
+						inferior *inf)
 {
   struct thread_info *tp;
   thread_t handle_tid;
@@ -1412,11 +1443,10 @@ thread_db_thread_handle_to_thread_info (struct target_ops *ops,
 /* Get the address of the thread local variable in load module LM which
    is stored at OFFSET within the thread local storage for thread PTID.  */
 
-static CORE_ADDR
-thread_db_get_thread_local_address (struct target_ops *ops,
-				    ptid_t ptid,
-				    CORE_ADDR lm,
-				    CORE_ADDR offset)
+CORE_ADDR
+thread_db_target::get_thread_local_address (ptid_t ptid,
+					    CORE_ADDR lm,
+					    CORE_ADDR offset)
 {
   struct thread_info *thread_info;
   struct target_ops *beneath;
@@ -1491,24 +1521,23 @@ thread_db_get_thread_local_address (struct target_ops *ops,
 	      : (CORE_ADDR) (uintptr_t) address);
     }
 
-  beneath = find_target_beneath (ops);
-  return beneath->to_get_thread_local_address (beneath, ptid, lm, offset);
+  beneath = find_target_beneath (this);
+  return beneath->get_thread_local_address (ptid, lm, offset);
 }
 
 /* Implement the to_get_ada_task_ptid target method for this target.  */
 
-static ptid_t
-thread_db_get_ada_task_ptid (struct target_ops *self, long lwp, long thread)
+ptid_t
+thread_db_target::get_ada_task_ptid (long lwp, long thread)
 {
   /* NPTL uses a 1:1 model, so the LWP id suffices.  */
   return ptid_build (ptid_get_pid (inferior_ptid), lwp, 0);
 }
 
-static void
-thread_db_resume (struct target_ops *ops,
-		  ptid_t ptid, int step, enum gdb_signal signo)
+void
+thread_db_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
 {
-  struct target_ops *beneath = find_target_beneath (ops);
+  struct target_ops *beneath = find_target_beneath (this);
   struct thread_db_info *info;
 
   if (ptid_equal (ptid, minus_one_ptid))
@@ -1522,7 +1551,7 @@ thread_db_resume (struct target_ops *ops,
   if (info)
     info->need_stale_parent_threads_check = 0;
 
-  beneath->to_resume (beneath, ptid, step, signo);
+  beneath->resume (ptid, step, signo);
 }
 
 /* std::sort helper function for info_auto_load_libthread_db, sort the
@@ -1637,35 +1666,9 @@ info_auto_load_libthread_db (const char *args, int from_tty)
     uiout->message (_("No auto-loaded libthread-db.\n"));
 }
 
-static void
-init_thread_db_ops (void)
-{
-  thread_db_ops.to_shortname = "multi-thread";
-  thread_db_ops.to_longname = "multi-threaded child process.";
-  thread_db_ops.to_doc = "Threads and pthreads support.";
-  thread_db_ops.to_detach = thread_db_detach;
-  thread_db_ops.to_wait = thread_db_wait;
-  thread_db_ops.to_resume = thread_db_resume;
-  thread_db_ops.to_mourn_inferior = thread_db_mourn_inferior;
-  thread_db_ops.to_update_thread_list = thread_db_update_thread_list;
-  thread_db_ops.to_pid_to_str = thread_db_pid_to_str;
-  thread_db_ops.to_stratum = thread_stratum;
-  thread_db_ops.to_has_thread_control = tc_schedlock;
-  thread_db_ops.to_get_thread_local_address
-    = thread_db_get_thread_local_address;
-  thread_db_ops.to_extra_thread_info = thread_db_extra_thread_info;
-  thread_db_ops.to_get_ada_task_ptid = thread_db_get_ada_task_ptid;
-  thread_db_ops.to_thread_handle_to_thread_info = thread_db_thread_handle_to_thread_info;
-  thread_db_ops.to_magic = OPS_MAGIC;
-
-  complete_target_initialization (&thread_db_ops);
-}
-
 void
 _initialize_thread_db (void)
 {
-  init_thread_db_ops ();
-
   /* Defer loading of libthread_db.so until inferior is running.
      This allows gdb to load correct libthread_db for a given
      executable -- there could be multiple versions of glibc,
diff --git a/gdb/x86-linux-nat.c b/gdb/x86-linux-nat.c
index a3bdafffa2..0910d0047e 100644
--- a/gdb/x86-linux-nat.c
+++ b/gdb/x86-linux-nat.c
@@ -27,7 +27,6 @@
 #include <sys/uio.h>
 
 #include "x86-nat.h"
-#include "linux-nat.h"
 #ifndef __x86_64__
 #include "i386-linux-nat.h"
 #endif
@@ -78,14 +77,15 @@ x86_linux_new_fork (struct lwp_info *parent, pid_t child_pid)
 }
 \f
 
-static void (*super_post_startup_inferior) (struct target_ops *self,
-					    ptid_t ptid);
+x86_linux_nat_target::~x86_linux_nat_target ()
+{
+}
 
-static void
-x86_linux_child_post_startup_inferior (struct target_ops *self, ptid_t ptid)
+void
+x86_linux_nat_target::post_startup_inferior (ptid_t ptid)
 {
   x86_cleanup_dregs ();
-  super_post_startup_inferior (self, ptid);
+  linux_nat_target::post_startup_inferior (ptid);
 }
 
 #ifdef __x86_64__
@@ -102,8 +102,8 @@ x86_linux_child_post_startup_inferior (struct target_ops *self, ptid_t ptid)
 
 /* Get Linux/x86 target description from running target.  */
 
-static const struct target_desc *
-x86_linux_read_description (struct target_ops *ops)
+const struct target_desc *
+x86_linux_nat_target::read_description ()
 {
   int tid;
   int is_64bit = 0;
@@ -212,9 +212,9 @@ x86_linux_read_description (struct target_ops *ops)
 
 /* Enable branch tracing.  */
 
-static struct btrace_target_info *
-x86_linux_enable_btrace (struct target_ops *self, ptid_t ptid,
-			 const struct btrace_config *conf)
+struct btrace_target_info *
+x86_linux_nat_target::enable_btrace (ptid_t ptid,
+				     const struct btrace_config *conf)
 {
   struct btrace_target_info *tinfo = nullptr;
   TRY
@@ -233,9 +233,8 @@ x86_linux_enable_btrace (struct target_ops *self, ptid_t ptid,
 
 /* Disable branch tracing.  */
 
-static void
-x86_linux_disable_btrace (struct target_ops *self,
-			  struct btrace_target_info *tinfo)
+void
+x86_linux_nat_target::disable_btrace (struct btrace_target_info *tinfo)
 {
   enum btrace_error errcode = linux_disable_btrace (tinfo);
 
@@ -245,28 +244,25 @@ x86_linux_disable_btrace (struct target_ops *self,
 
 /* Teardown branch tracing.  */
 
-static void
-x86_linux_teardown_btrace (struct target_ops *self,
-			   struct btrace_target_info *tinfo)
+void
+x86_linux_nat_target::teardown_btrace (struct btrace_target_info *tinfo)
 {
   /* Ignore errors.  */
   linux_disable_btrace (tinfo);
 }
 
-static enum btrace_error
-x86_linux_read_btrace (struct target_ops *self,
-		       struct btrace_data *data,
-		       struct btrace_target_info *btinfo,
-		       enum btrace_read_type type)
+enum btrace_error
+x86_linux_nat_target::read_btrace (struct btrace_data *data,
+				   struct btrace_target_info *btinfo,
+				   enum btrace_read_type type)
 {
   return linux_read_btrace (data, btinfo, type);
 }
 
 /* See to_btrace_conf in target.h.  */
 
-static const struct btrace_config *
-x86_linux_btrace_conf (struct target_ops *self,
-		       const struct btrace_target_info *btinfo)
+const struct btrace_config *
+x86_linux_nat_target::btrace_conf (const struct btrace_target_info *btinfo)
 {
   return linux_btrace_conf (btinfo);
 }
@@ -315,16 +311,12 @@ x86_linux_get_thread_area (pid_t pid, void *addr, unsigned int *base_addr)
 }
 \f
 
-/* Create an x86 GNU/Linux target.  */
+/* Add an x86 GNU/Linux target.  */
 
-struct target_ops *
-x86_linux_create_target (void)
+void
+x86_linux_add_target (linux_nat_target *t)
 {
-  /* Fill in the generic GNU/Linux methods.  */
-  struct target_ops *t = linux_target ();
-
   /* Initialize the debug register function vectors.  */
-  x86_use_watchpoints (t);
   x86_dr_low.set_control = x86_linux_dr_set_control;
   x86_dr_low.set_addr = x86_linux_dr_set_addr;
   x86_dr_low.get_addr = x86_linux_dr_get_addr;
@@ -332,29 +324,7 @@ x86_linux_create_target (void)
   x86_dr_low.get_control = x86_linux_dr_get_control;
   x86_set_debug_register_length (sizeof (void *));
 
-  /* Override the GNU/Linux inferior startup hook.  */
-  super_post_startup_inferior = t->to_post_startup_inferior;
-  t->to_post_startup_inferior = x86_linux_child_post_startup_inferior;
-
-  /* Add the description reader.  */
-  t->to_read_description = x86_linux_read_description;
-
-  /* Add btrace methods.  */
-  t->to_enable_btrace = x86_linux_enable_btrace;
-  t->to_disable_btrace = x86_linux_disable_btrace;
-  t->to_teardown_btrace = x86_linux_teardown_btrace;
-  t->to_read_btrace = x86_linux_read_btrace;
-  t->to_btrace_conf = x86_linux_btrace_conf;
-
-  return t;
-}
-
-/* Add an x86 GNU/Linux target.  */
-
-void
-x86_linux_add_target (struct target_ops *t)
-{
-  linux_nat_add_target (t);
+  add_target (t);
   linux_nat_set_new_thread (t, x86_linux_new_thread);
   linux_nat_set_delete_thread (t, x86_linux_delete_thread);
   linux_nat_set_new_fork (t, x86_linux_new_fork);
diff --git a/gdb/x86-linux-nat.h b/gdb/x86-linux-nat.h
index 383bfd5314..0bafaaa71f 100644
--- a/gdb/x86-linux-nat.h
+++ b/gdb/x86-linux-nat.h
@@ -21,6 +21,44 @@
 #define X86_LINUX_NAT_H 1
 
 #include "gdb_proc_service.h"  /* For ps_err_e.  */
+#include "linux-nat.h"
+#include "x86-nat.h"
+
+struct x86_linux_nat_target : public x86_nat_target<linux_nat_target>
+{
+  virtual ~x86_linux_nat_target () override = 0;
+
+  /* Override the GNU/Linux inferior startup hook.  */
+  void post_startup_inferior (ptid_t) override;
+
+  /* Add the description reader.  */
+  const struct target_desc *read_description () override;
+
+  struct btrace_target_info *enable_btrace (ptid_t ptid,
+					    const struct btrace_config *conf) override;
+  void disable_btrace (struct btrace_target_info *tinfo) override;
+  void teardown_btrace (struct btrace_target_info *tinfo) override;
+  enum btrace_error read_btrace (struct btrace_data *data,
+				 struct btrace_target_info *btinfo,
+				 enum btrace_read_type type) override;
+  const struct btrace_config *btrace_conf (const struct btrace_target_info *) override;
+
+  /* These two are rewired to low_ versions.  linux-nat.c queries
+     stopped-by-watchpoint info as soon as an lwp stops (via the low_
+     methods) and caches the result, to be returned via the normal
+     non-low methods.  */
+  int stopped_by_watchpoint () override
+  { return linux_nat_target::stopped_by_watchpoint (); }
+
+  int stopped_data_address (CORE_ADDR *addr_p) override
+  { return linux_nat_target::stopped_data_address (addr_p); }
+
+  int low_stopped_by_watchpoint () override
+  { return x86_nat_target::stopped_by_watchpoint (); }
+
+  int low_stopped_data_address (CORE_ADDR *addr_p) override
+  { return x86_nat_target::stopped_data_address (addr_p); }
+};
 
 \f
 
@@ -32,12 +70,8 @@ extern ps_err_e x86_linux_get_thread_area (pid_t pid, void *addr,
 					   unsigned int *base_addr);
 \f
 
-/* Create an x86 GNU/Linux target.  */
-
-extern struct target_ops *x86_linux_create_target (void);
-
 /* Add an x86 GNU/Linux target.  */
 
-extern void x86_linux_add_target (struct target_ops *t);
+extern void x86_linux_add_target (linux_nat_target *t);
 
 #endif
diff --git a/gdb/x86-nat.c b/gdb/x86-nat.c
index bec51373a6..cfd293c17f 100644
--- a/gdb/x86-nat.c
+++ b/gdb/x86-nat.c
@@ -146,8 +146,8 @@ x86_cleanup_dregs (void)
    address ADDR and whose length is LEN bytes.  Watch memory accesses
    of the type TYPE.  Return 0 on success, -1 on failure.  */
 
-static int
-x86_insert_watchpoint (struct target_ops *self, CORE_ADDR addr, int len,
+int
+x86_insert_watchpoint (CORE_ADDR addr, int len,
 		       enum target_hw_bp_type type, struct expression *cond)
 {
   struct x86_debug_reg_state *state
@@ -159,8 +159,8 @@ x86_insert_watchpoint (struct target_ops *self, CORE_ADDR addr, int len,
 /* Remove a watchpoint that watched the memory region which starts at
    address ADDR, whose length is LEN bytes, and for accesses of the
    type TYPE.  Return 0 on success, -1 on failure.  */
-static int
-x86_remove_watchpoint (struct target_ops *self, CORE_ADDR addr, int len,
+int
+x86_remove_watchpoint (CORE_ADDR addr, int len,
 		       enum target_hw_bp_type type, struct expression *cond)
 {
   struct x86_debug_reg_state *state
@@ -172,9 +172,8 @@ x86_remove_watchpoint (struct target_ops *self, CORE_ADDR addr, int len,
 /* Return non-zero if we can watch a memory region that starts at
    address ADDR and whose length is LEN bytes.  */
 
-static int
-x86_region_ok_for_watchpoint (struct target_ops *self,
-			      CORE_ADDR addr, int len)
+int
+x86_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
 {
   struct x86_debug_reg_state *state
     = x86_debug_reg_state (ptid_get_pid (inferior_ptid));
@@ -186,8 +185,8 @@ x86_region_ok_for_watchpoint (struct target_ops *self,
    address associated with that break/watchpoint and return non-zero.
    Otherwise, return zero.  */
 
-static int
-x86_stopped_data_address (struct target_ops *ops, CORE_ADDR *addr_p)
+int
+x86_stopped_data_address (CORE_ADDR *addr_p)
 {
   struct x86_debug_reg_state *state
     = x86_debug_reg_state (ptid_get_pid (inferior_ptid));
@@ -198,8 +197,8 @@ x86_stopped_data_address (struct target_ops *ops, CORE_ADDR *addr_p)
 /* Return non-zero if the inferior has some watchpoint that triggered.
    Otherwise return zero.  */
 
-static int
-x86_stopped_by_watchpoint (struct target_ops *ops)
+int
+x86_stopped_by_watchpoint ()
 {
   struct x86_debug_reg_state *state
     = x86_debug_reg_state (ptid_get_pid (inferior_ptid));
@@ -210,9 +209,8 @@ x86_stopped_by_watchpoint (struct target_ops *ops)
 /* Insert a hardware-assisted breakpoint at BP_TGT->reqstd_address.
    Return 0 on success, EBUSY on failure.  */
 
-static int
-x86_insert_hw_breakpoint (struct target_ops *self, struct gdbarch *gdbarch,
-			  struct bp_target_info *bp_tgt)
+int
+x86_insert_hw_breakpoint (struct gdbarch *gdbarch, struct bp_target_info *bp_tgt)
 {
   struct x86_debug_reg_state *state
     = x86_debug_reg_state (ptid_get_pid (inferior_ptid));
@@ -225,8 +223,8 @@ x86_insert_hw_breakpoint (struct target_ops *self, struct gdbarch *gdbarch,
 /* Remove a hardware-assisted breakpoint at BP_TGT->placed_address.
    Return 0 on success, -1 on failure.  */
 
-static int
-x86_remove_hw_breakpoint (struct target_ops *self, struct gdbarch *gdbarch,
+int
+x86_remove_hw_breakpoint (struct gdbarch *gdbarch,
 			  struct bp_target_info *bp_tgt)
 {
   struct x86_debug_reg_state *state
@@ -253,9 +251,8 @@ x86_remove_hw_breakpoint (struct target_ops *self, struct gdbarch *gdbarch,
    virtually unlimited number of watchpoints, due to debug register
    sharing implemented via reference counts in x86-nat.c.  */
 
-static int
-x86_can_use_hw_breakpoint (struct target_ops *self,
-			   enum bptype type, int cnt, int othertype)
+int
+x86_can_use_hw_breakpoint (enum bptype type, int cnt, int othertype)
 {
   return 1;
 }
@@ -263,8 +260,8 @@ x86_can_use_hw_breakpoint (struct target_ops *self,
 /* Return non-zero if the inferior has some breakpoint that triggered.
    Otherwise return zero.  */
 
-static int
-x86_stopped_by_hw_breakpoint (struct target_ops *ops)
+int
+x86_stopped_by_hw_breakpoint ()
 {
   struct x86_debug_reg_state *state
     = x86_debug_reg_state (ptid_get_pid (inferior_ptid));
@@ -291,30 +288,7 @@ triggers a breakpoint or watchpoint."),
 			   &maintenance_show_cmdlist);
 }
 
-/* There are only two global functions left.  */
-
-void
-x86_use_watchpoints (struct target_ops *t)
-{
-  /* After a watchpoint trap, the PC points to the instruction after the
-     one that caused the trap.  Therefore we don't need to step over it.
-     But we do need to reset the status register to avoid another trap.  */
-  t->to_have_continuable_watchpoint = 1;
-
-  t->to_can_use_hw_breakpoint = x86_can_use_hw_breakpoint;
-  t->to_region_ok_for_hw_watchpoint = x86_region_ok_for_watchpoint;
-  t->to_stopped_by_watchpoint = x86_stopped_by_watchpoint;
-  t->to_stopped_data_address = x86_stopped_data_address;
-  t->to_insert_watchpoint = x86_insert_watchpoint;
-  t->to_remove_watchpoint = x86_remove_watchpoint;
-  t->to_insert_hw_breakpoint = x86_insert_hw_breakpoint;
-  t->to_remove_hw_breakpoint = x86_remove_hw_breakpoint;
-
-  /* A target must provide an implementation of the
-     "to_supports_stopped_by_hw_breakpoint" target method before this
-     callback will be used.  */
-  t->to_stopped_by_hw_breakpoint = x86_stopped_by_hw_breakpoint;
-}
+/* See x86-nat.h.  */
 
 void
 x86_set_debug_register_length (int len)
diff --git a/gdb/x86-nat.h b/gdb/x86-nat.h
index 80c7fdfa80..8ad1821360 100644
--- a/gdb/x86-nat.h
+++ b/gdb/x86-nat.h
@@ -23,16 +23,12 @@
 #ifndef X86_NAT_H
 #define X86_NAT_H 1
 
+#include "breakpoint.h"
 #include "nat/x86-dregs.h"
+#include "target.h"
 
 /* Hardware-assisted breakpoints and watchpoints.  */
 
-/* Add watchpoint methods to the provided target_ops.  
-   Targets using x86 family debug registers for watchpoints should call
-   this.  */
-struct target_ops;
-extern void x86_use_watchpoints (struct target_ops *);
-
 /* Use this function to set x86_dr_low debug_register_length field
    rather than setting it directly to check that the length is only
    set once.  It also enables the 'maint set/show show-debug-regs' 
@@ -49,4 +45,75 @@ extern void x86_cleanup_dregs (void);
 
 extern void x86_forget_process (pid_t pid);
 
+/* Helper functions used by x86_nat_target below.  See their
+   definitions.  */
+
+extern int x86_can_use_hw_breakpoint (enum bptype type, int cnt, int othertype);
+extern int x86_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len);
+extern int x86_stopped_by_watchpoint ();
+extern int x86_stopped_data_address (CORE_ADDR *addr_p);
+extern int x86_insert_watchpoint (CORE_ADDR addr, int len,
+			   enum target_hw_bp_type type,
+			   struct expression *cond);
+extern int x86_remove_watchpoint (CORE_ADDR addr, int len,
+			   enum target_hw_bp_type type,
+			   struct expression *cond);
+extern int x86_insert_hw_breakpoint (struct gdbarch *gdbarch,
+			      struct bp_target_info *bp_tgt);
+extern int x86_remove_hw_breakpoint (struct gdbarch *gdbarch,
+				     struct bp_target_info *bp_tgt);
+extern int x86_stopped_by_hw_breakpoint ();
+
+/* Convenience template mixin used to add x86 watchpoints support to a
+   target.  */
+
+template <typename BaseTarget>
+struct x86_nat_target : public BaseTarget
+{
+  /* Hook in the x86 hardware watchpoints/breakpoints support.  */
+
+  /* After a watchpoint trap, the PC points to the instruction after
+     the one that caused the trap.  Therefore we don't need to step
+     over it.  But we do need to reset the status register to avoid
+     another trap.  */
+  bool have_continuable_watchpoint () override
+  { return true; }
+
+  int can_use_hw_breakpoint (enum bptype type, int cnt, int othertype) override
+  { return x86_can_use_hw_breakpoint (type, cnt, othertype); }
+
+  int region_ok_for_hw_watchpoint (CORE_ADDR addr, int len) override
+  { return x86_region_ok_for_hw_watchpoint (addr, len); }
+
+  int insert_watchpoint (CORE_ADDR addr, int len,
+			 enum target_hw_bp_type type,
+			 struct expression *cond) override
+  { return x86_insert_watchpoint (addr, len, type, cond); }
+
+  int remove_watchpoint (CORE_ADDR addr, int len,
+			 enum target_hw_bp_type type,
+			 struct expression *cond) override
+  { return x86_remove_watchpoint (addr, len, type, cond); }
+
+  int insert_hw_breakpoint (struct gdbarch *gdbarch,
+			    struct bp_target_info *bp_tgt) override
+  { return x86_insert_hw_breakpoint (gdbarch, bp_tgt); }
+
+  int remove_hw_breakpoint (struct gdbarch *gdbarch,
+			    struct bp_target_info *bp_tgt) override
+  { return x86_remove_hw_breakpoint (gdbarch, bp_tgt); }
+
+  int stopped_by_watchpoint () override
+  { return x86_stopped_by_watchpoint (); }
+
+  int stopped_data_address (CORE_ADDR *addr_p) override
+  { return x86_stopped_data_address (addr_p); }
+
+  /* A target must provide an implementation of the
+     "supports_stopped_by_hw_breakpoint" target method before this
+     callback will be used.  */
+  int stopped_by_hw_breakpoint () override
+  { return x86_stopped_by_hw_breakpoint (); }
+};
+
 #endif /* X86_NAT_H */
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [PATCH 18/40] target_ops/C++: linux_trad_target, MIPS and Alpha GNU/Linux
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (37 preceding siblings ...)
  2018-04-14 19:29 ` [PATCH 13/40] target_ops/C++: GNU/Linux + x86/AMD64 Pedro Alves
@ 2018-04-14 19:30 ` Pedro Alves
  2018-04-16 15:15 ` [RESEND][PATCH 01/40] Convert struct target_ops to C++ Pedro Alves
                   ` (2 subsequent siblings)
  41 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-14 19:30 UTC (permalink / raw)
  To: gdb-patches

This converts the code in the new linux-nat-trad.h/c files, that was
split off of inf-ptrace.h/c recently, to a C++ base class, and makes
the MIPS and Alpha GNU/Linux ports use it.

Otherwise, it's a straighforward conversion.

I'd checked with a cross compiler that the MIPS port builds.  I don't
have an Alpha compiler handy.
---
 gdb/alpha-linux-nat.c |  17 +++--
 gdb/linux-nat-trad.c  |  54 +++++-----------
 gdb/linux-nat-trad.h  |  24 +++++--
 gdb/mips-linux-nat.c  | 175 ++++++++++++++++++++++++++------------------------
 4 files changed, 138 insertions(+), 132 deletions(-)

diff --git a/gdb/alpha-linux-nat.c b/gdb/alpha-linux-nat.c
index 8d46af4176..70997e5f4a 100644
--- a/gdb/alpha-linux-nat.c
+++ b/gdb/alpha-linux-nat.c
@@ -32,6 +32,15 @@
 /* The address of UNIQUE for ptrace.  */
 #define ALPHA_UNIQUE_PTRACE_ADDR 65
 
+class alpha_linux_nat_target final : public linux_nat_trad_target
+{
+protected:
+  /* Override linux_nat_trad_target methods.  */
+  CORE_ADDR register_u_offset (struct gdbarch *gdbarch,
+			       int regno, int store_p) override;
+};
+
+static alpha_linux_nat_target the_alpha_linux_nat_target;
 
 /* See the comment in m68k-tdep.c regarding the utility of these
    functions.  */
@@ -77,9 +86,9 @@ fill_fpregset (const struct regcache *regcache,
   alpha_fill_fp_regs (regcache, regno, regp, regp + 31);
 }
 
-
-static CORE_ADDR
-alpha_linux_register_u_offset (struct gdbarch *gdbarch, int regno, int store_p)
+CORE_ADDR
+alpha_linux_nat_target::register_u_offset (struct gdbarch *gdbarch,
+					   int regno, int store_p)
 {
   if (regno == gdbarch_pc_regnum (gdbarch))
     return PC;
@@ -94,5 +103,5 @@ alpha_linux_register_u_offset (struct gdbarch *gdbarch, int regno, int store_p)
 void
 _initialize_alpha_linux_nat (void)
 {
-  linux_nat_add_target (linux_trad_target (alpha_linux_register_u_offset));
+  add_target (&the_alpha_linux_nat_target);
 }
diff --git a/gdb/linux-nat-trad.c b/gdb/linux-nat-trad.c
index 75130be0f4..066d15a352 100644
--- a/gdb/linux-nat-trad.c
+++ b/gdb/linux-nat-trad.c
@@ -23,14 +23,10 @@
 #include "nat/gdb_ptrace.h"
 #include "inf-ptrace.h"
 
-/* Pointer to a function that returns the offset within the user area
-   where a particular register is stored.  */
-static CORE_ADDR (*inf_ptrace_register_u_offset)(struct gdbarch *, int, int);
-
 /* Fetch register REGNUM from the inferior.  */
 
-static void
-inf_ptrace_fetch_register (struct regcache *regcache, int regnum)
+void
+linux_nat_trad_target::fetch_register (struct regcache *regcache, int regnum)
 {
   struct gdbarch *gdbarch = regcache->arch ();
   CORE_ADDR addr;
@@ -40,7 +36,7 @@ inf_ptrace_fetch_register (struct regcache *regcache, int regnum)
   int i;
 
   /* This isn't really an address, but ptrace thinks of it as one.  */
-  addr = inf_ptrace_register_u_offset (gdbarch, regnum, 0);
+  addr = register_u_offset (gdbarch, regnum, 0);
   if (addr == (CORE_ADDR)-1
       || gdbarch_cannot_fetch_register (gdbarch, regnum))
     {
@@ -72,23 +68,23 @@ inf_ptrace_fetch_register (struct regcache *regcache, int regnum)
 /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
    for all registers.  */
 
-static void
-inf_ptrace_fetch_registers (struct target_ops *ops,
-			    struct regcache *regcache, int regnum)
+void
+linux_nat_trad_target::fetch_registers (struct regcache *regcache, int regnum)
 {
   if (regnum == -1)
     for (regnum = 0;
 	 regnum < gdbarch_num_regs (regcache->arch ());
 	 regnum++)
-      inf_ptrace_fetch_register (regcache, regnum);
+      fetch_register (regcache, regnum);
   else
-    inf_ptrace_fetch_register (regcache, regnum);
+    fetch_register (regcache, regnum);
 }
 
 /* Store register REGNUM into the inferior.  */
 
-static void
-inf_ptrace_store_register (const struct regcache *regcache, int regnum)
+void
+linux_nat_trad_target::store_register (const struct regcache *regcache,
+				       int regnum)
 {
   struct gdbarch *gdbarch = regcache->arch ();
   CORE_ADDR addr;
@@ -98,7 +94,7 @@ inf_ptrace_store_register (const struct regcache *regcache, int regnum)
   int i;
 
   /* This isn't really an address, but ptrace thinks of it as one.  */
-  addr = inf_ptrace_register_u_offset (gdbarch, regnum, 1);
+  addr = register_u_offset (gdbarch, regnum, 1);
   if (addr == (CORE_ADDR)-1
       || gdbarch_cannot_store_register (gdbarch, regnum))
     return;
@@ -127,34 +123,14 @@ inf_ptrace_store_register (const struct regcache *regcache, int regnum)
 /* Store register REGNUM back into the inferior.  If REGNUM is -1, do
    this for all registers.  */
 
-static void
-inf_ptrace_store_registers (struct target_ops *ops,
-			    struct regcache *regcache, int regnum)
+void
+linux_nat_trad_target::store_registers (struct regcache *regcache, int regnum)
 {
   if (regnum == -1)
     for (regnum = 0;
 	 regnum < gdbarch_num_regs (regcache->arch ());
 	 regnum++)
-      inf_ptrace_store_register (regcache, regnum);
+      store_register (regcache, regnum);
   else
-    inf_ptrace_store_register (regcache, regnum);
-}
-
-/* Create a "traditional" Linux/ptrace target.  REGISTER_U_OFFSET
-   should be a function returning the offset within the user area
-   where a particular register is stored.  */
-
-struct target_ops *
-linux_trad_target (CORE_ADDR (*register_u_offset)(struct gdbarch *, int, int))
-{
-  struct target_ops *t = inf_ptrace_target();
-
-  gdb_assert (register_u_offset);
-  inf_ptrace_register_u_offset = register_u_offset;
-  t->to_fetch_registers = inf_ptrace_fetch_registers;
-  t->to_store_registers = inf_ptrace_store_registers;
-
-  linux_target_install_ops (t);
-
-  return t;
+    store_register (regcache, regnum);
 }
diff --git a/gdb/linux-nat-trad.h b/gdb/linux-nat-trad.h
index 3b4a6c8595..240a95139c 100644
--- a/gdb/linux-nat-trad.h
+++ b/gdb/linux-nat-trad.h
@@ -22,9 +22,25 @@
 
 #include "linux-nat.h"
 
-/* Create a generic GNU/Linux target using traditional
-   ptrace register access.  */
-struct target_ops *linux_trad_target
-  (CORE_ADDR (*register_u_offset)(struct gdbarch *, int, int));
+/* A prototype GNU/Linux target using traditional ptrace register
+   access.  A concrete type should override REGISTER_U_OFFSET.  */
+
+class linux_nat_trad_target : public linux_nat_target
+{
+public:
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+
+protected:
+  /* Return the offset within the user area where a particular
+     register is stored.  */
+  virtual CORE_ADDR register_u_offset (struct gdbarch *gdbarch,
+				       int regnum, int store) = 0;
+
+private:
+  /* Helpers.  See definition.  */
+  void fetch_register (struct regcache *regcache, int regnum);
+  void store_register (const struct regcache *regcache, int regnum);
+};
 
 #endif /* LINUX_NAT_TRAD_H */
diff --git a/gdb/mips-linux-nat.c b/gdb/mips-linux-nat.c
index 17e70b603b..1cd97d53c7 100644
--- a/gdb/mips-linux-nat.c
+++ b/gdb/mips-linux-nat.c
@@ -42,19 +42,49 @@
 #define PTRACE_GET_THREAD_AREA 25
 #endif
 
-/* Assume that we have PTRACE_GETREGS et al. support.  If we do not,
-   we'll clear this and use PTRACE_PEEKUSER instead.  */
-static int have_ptrace_regsets = 1;
+class mips_linux_nat_target final : public linux_nat_trad_target
+{
+public:
+  /* Add our register access methods.  */
+  void fetch_registers (struct regcache *, int) override;
+  void store_registers (struct regcache *, int) override;
+
+  void close () override;
+
+  int can_use_hw_breakpoint (enum bptype, int, int) override;
+
+  int remove_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
+			 struct expression *) override;
+
+  int insert_watchpoint (CORE_ADDR, int, enum target_hw_bp_type,
+			 struct expression *) override;
+
+  int stopped_by_watchpoint () override;
+
+  int stopped_data_address (CORE_ADDR *) override;
 
-/* Saved function pointers to fetch and store a single register using
-   PTRACE_PEEKUSER and PTRACE_POKEUSER.  */
+  int region_ok_for_hw_watchpoint (CORE_ADDR, int) override;
 
-static void (*super_fetch_registers) (struct target_ops *,
-				      struct regcache *, int);
-static void (*super_store_registers) (struct target_ops *,
-				      struct regcache *, int);
+  const struct target_desc *read_description () override;
 
-static void (*super_close) (struct target_ops *);
+protected:
+  /* Override linux_nat_trad_target methods.  */
+  CORE_ADDR register_u_offset (struct gdbarch *gdbarch,
+			       int regno, int store_p) override;
+
+private:
+  /* Helpers.  See definitions.  */
+  void mips64_regsets_store_registers (struct regcache *regcache,
+				       int regno);
+  void mips64_regsets_fetch_registers (struct regcache *regcache,
+				       int regno);
+};
+
+static mips_linux_nat_target the_mips_linux_nat_target;
+
+/* Assume that we have PTRACE_GETREGS et al. support.  If we do not,
+   we'll clear this and use PTRACE_PEEKUSER instead.  */
+static int have_ptrace_regsets = 1;
 
 /* Map gdb internal register number to ptrace ``address''.
    These ``addresses'' are normally defined in <asm/ptrace.h>. 
@@ -208,9 +238,9 @@ fill_fpregset (const struct regcache *regcache,
 /* Fetch REGNO (or all registers if REGNO == -1) from the target
    using PTRACE_GETREGS et al.  */
 
-static void
-mips64_linux_regsets_fetch_registers (struct target_ops *ops,
-				      struct regcache *regcache, int regno)
+void
+mips_linux_nat_target::mips64_regsets_fetch_registers
+  (struct regcache *regcache, int regno)
 {
   struct gdbarch *gdbarch = regcache->arch ();
   int is_fp, is_dsp;
@@ -280,23 +310,24 @@ mips64_linux_regsets_fetch_registers (struct target_ops *ops,
     }
 
   if (is_dsp)
-    super_fetch_registers (ops, regcache, regno);
+    linux_nat_trad_target::fetch_registers (regcache, regno);
   else if (regno == -1 && have_dsp)
     {
       for (regi = mips_regnum (gdbarch)->dspacc;
 	   regi < mips_regnum (gdbarch)->dspacc + 6;
 	   regi++)
-	super_fetch_registers (ops, regcache, regi);
-      super_fetch_registers (ops, regcache, mips_regnum (gdbarch)->dspctl);
+	linux_nat_trad_target::fetch_registers (regcache, regi);
+      linux_nat_trad_target::fetch_registers (regcache,
+					      mips_regnum (gdbarch)->dspctl);
     }
 }
 
 /* Store REGNO (or all registers if REGNO == -1) to the target
    using PTRACE_SETREGS et al.  */
 
-static void
-mips64_linux_regsets_store_registers (struct target_ops *ops,
-				      struct regcache *regcache, int regno)
+void
+mips_linux_nat_target::mips64_regsets_store_registers
+  (struct regcache *regcache, int regno)
 {
   struct gdbarch *gdbarch = regcache->arch ();
   int is_fp, is_dsp;
@@ -357,56 +388,56 @@ mips64_linux_regsets_store_registers (struct target_ops *ops,
     }
 
   if (is_dsp)
-    super_store_registers (ops, regcache, regno);
+    linux_nat_trad_target::store_registers (regcache, regno);
   else if (regno == -1 && have_dsp)
     {
       for (regi = mips_regnum (gdbarch)->dspacc;
 	   regi < mips_regnum (gdbarch)->dspacc + 6;
 	   regi++)
-	super_store_registers (ops, regcache, regi);
-      super_store_registers (ops, regcache, mips_regnum (gdbarch)->dspctl);
+	linux_nat_trad_target::store_registers (regcache, regi);
+      linux_nat_trad_target::store_registers (regcache,
+					      mips_regnum (gdbarch)->dspctl);
     }
 }
 
 /* Fetch REGNO (or all registers if REGNO == -1) from the target
    using any working method.  */
 
-static void
-mips64_linux_fetch_registers (struct target_ops *ops,
-			      struct regcache *regcache, int regnum)
+void
+mips_linux_nat_target::fetch_registers (struct regcache *regcache, int regnum)
 {
   /* Unless we already know that PTRACE_GETREGS does not work, try it.  */
   if (have_ptrace_regsets)
-    mips64_linux_regsets_fetch_registers (ops, regcache, regnum);
+    mips64_regsets_fetch_registers (regcache, regnum);
 
   /* If we know, or just found out, that PTRACE_GETREGS does not work, fall
      back to PTRACE_PEEKUSER.  */
   if (!have_ptrace_regsets)
-    super_fetch_registers (ops, regcache, regnum);
+    linux_nat_trad_target::fetch_registers (regcache, regnum);
 }
 
 /* Store REGNO (or all registers if REGNO == -1) to the target
    using any working method.  */
 
-static void
-mips64_linux_store_registers (struct target_ops *ops,
-			      struct regcache *regcache, int regnum)
+void
+mips_linux_nat_target::store_registers (struct regcache *regcache, int regnum)
 {
   /* Unless we already know that PTRACE_GETREGS does not work, try it.  */
   if (have_ptrace_regsets)
-    mips64_linux_regsets_store_registers (ops, regcache, regnum);
+    mips64_regsets_store_registers (regcache, regnum);
 
   /* If we know, or just found out, that PTRACE_GETREGS does not work, fall
      back to PTRACE_PEEKUSER.  */
   if (!have_ptrace_regsets)
-    super_store_registers (ops, regcache, regnum);
+    linux_nat_trad_target::store_registers (regcache, regnum);
 }
 
 /* Return the address in the core dump or inferior of register
    REGNO.  */
 
-static CORE_ADDR
-mips_linux_register_u_offset (struct gdbarch *gdbarch, int regno, int store_p)
+CORE_ADDR
+mips_linux_nat_target::register_u_offset (struct gdbarch *gdbarch,
+					  int regno, int store_p)
 {
   if (mips_abi_regsize (gdbarch) == 8)
     return mips64_linux_register_addr (gdbarch, regno, store_p);
@@ -414,8 +445,8 @@ mips_linux_register_u_offset (struct gdbarch *gdbarch, int regno, int store_p)
     return mips_linux_register_addr (gdbarch, regno, store_p);
 }
 
-static const struct target_desc *
-mips_linux_read_description (struct target_ops *ops)
+const struct target_desc *
+mips_linux_nat_target::read_description ()
 {
   static int have_dsp = -1;
 
@@ -499,10 +530,9 @@ mips_show_dr (const char *func, CORE_ADDR addr,
 /* Target to_can_use_hw_breakpoint implementation.  Return 1 if we can
    handle the specified watch type.  */
 
-static int
-mips_linux_can_use_hw_breakpoint (struct target_ops *self,
-				  enum bptype type,
-				  int cnt, int ot)
+int
+mips_linux_nat_target::can_use_hw_breakpoint (enum bptype type,
+					      int cnt, int ot)
 {
   int i;
   uint32_t wanted_mask, irw_mask;
@@ -542,8 +572,8 @@ mips_linux_can_use_hw_breakpoint (struct target_ops *self,
    stopped by watchpoint.  The watchhi R and W bits indicate the watch
    register triggered.  */
 
-static int
-mips_linux_stopped_by_watchpoint (struct target_ops *ops)
+int
+mips_linux_nat_target::stopped_by_watchpoint ()
 {
   int n;
   int num_valid;
@@ -566,8 +596,8 @@ mips_linux_stopped_by_watchpoint (struct target_ops *ops)
    where the watch triggered (if known).  Return 1 if the address was
    known.  */
 
-static int
-mips_linux_stopped_data_address (struct target_ops *t, CORE_ADDR *paddr)
+int
+mips_linux_nat_target::stopped_data_address (CORE_ADDR *paddr)
 {
   /* On mips we don't know the low order 3 bits of the data address,
      so we must return false.  */
@@ -577,9 +607,8 @@ mips_linux_stopped_data_address (struct target_ops *t, CORE_ADDR *paddr)
 /* Target to_region_ok_for_hw_watchpoint implementation.  Return 1 if
    the specified region can be covered by the watch registers.  */
 
-static int
-mips_linux_region_ok_for_hw_watchpoint (struct target_ops *self,
-					CORE_ADDR addr, int len)
+int
+mips_linux_nat_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
 {
   struct pt_watch_regs dummy_regs;
   int i;
@@ -633,11 +662,10 @@ mips_linux_new_thread (struct lwp_info *lp)
 /* Target to_insert_watchpoint implementation.  Try to insert a new
    watch.  Return zero on success.  */
 
-static int
-mips_linux_insert_watchpoint (struct target_ops *self,
-			      CORE_ADDR addr, int len,
-			      enum target_hw_bp_type type,
-			      struct expression *cond)
+int
+mips_linux_nat_target::insert_watchpoint (CORE_ADDR addr, int len,
+					  enum target_hw_bp_type type,
+					  struct expression *cond)
 {
   struct pt_watch_regs regs;
   struct mips_watchpoint *new_watch;
@@ -687,11 +715,10 @@ mips_linux_insert_watchpoint (struct target_ops *self,
 /* Target to_remove_watchpoint implementation.  Try to remove a watch.
    Return zero on success.  */
 
-static int
-mips_linux_remove_watchpoint (struct target_ops *self,
-			      CORE_ADDR addr, int len,
-			      enum target_hw_bp_type type,
-			      struct expression *cond)
+int
+mips_linux_nat_target::remove_watchpoint (CORE_ADDR addr, int len,
+					  enum target_hw_bp_type type,
+					  struct expression *cond)
 {
   int retval;
   int deleted_one;
@@ -736,8 +763,8 @@ mips_linux_remove_watchpoint (struct target_ops *self,
 /* Target to_close implementation.  Free any watches and call the
    super implementation.  */
 
-static void
-mips_linux_close (struct target_ops *self)
+void
+mips_linux_nat_target::close ()
 {
   struct mips_watchpoint *w;
   struct mips_watchpoint *nw;
@@ -752,15 +779,12 @@ mips_linux_close (struct target_ops *self)
     }
   current_watches = NULL;
 
-  if (super_close)
-    super_close (self);
+  linux_nat_trad_target::close ();
 }
 
 void
 _initialize_mips_linux_nat (void)
 {
-  struct target_ops *t;
-
   add_setshow_boolean_cmd ("show-debug-regs", class_maintenance,
 			   &show_debug_regs, _("\
 Set whether to show variables that mirror the mips debug registers."), _("\
@@ -774,26 +798,7 @@ triggers a breakpoint or watchpoint."),
 			   &maintenance_set_cmdlist,
 			   &maintenance_show_cmdlist);
 
-  t = linux_trad_target (mips_linux_register_u_offset);
-
-  super_close = t->to_close;
-  t->to_close = mips_linux_close;
-
-  super_fetch_registers = t->to_fetch_registers;
-  super_store_registers = t->to_store_registers;
-
-  t->to_fetch_registers = mips64_linux_fetch_registers;
-  t->to_store_registers = mips64_linux_store_registers;
-
-  t->to_can_use_hw_breakpoint = mips_linux_can_use_hw_breakpoint;
-  t->to_remove_watchpoint = mips_linux_remove_watchpoint;
-  t->to_insert_watchpoint = mips_linux_insert_watchpoint;
-  t->to_stopped_by_watchpoint = mips_linux_stopped_by_watchpoint;
-  t->to_stopped_data_address = mips_linux_stopped_data_address;
-  t->to_region_ok_for_hw_watchpoint = mips_linux_region_ok_for_hw_watchpoint;
-
-  t->to_read_description = mips_linux_read_description;
-
-  linux_nat_add_target (t);
-  linux_nat_set_new_thread (t, mips_linux_new_thread);
+  add_target (&the_mips_linux_nat_target);
+  linux_nat_set_new_thread (&the_mips_linux_nat_target,
+			    mips_linux_new_thread);
 }
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* [RESEND][PATCH 01/40] Convert struct target_ops to C++
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (38 preceding siblings ...)
  2018-04-14 19:30 ` [PATCH 18/40] target_ops/C++: linux_trad_target, MIPS and Alpha GNU/Linux Pedro Alves
@ 2018-04-16 15:15 ` Pedro Alves
  2018-05-03  0:06   ` Pedro Alves
  2018-04-27 15:47 ` [PATCH 00/40] C++ify target_ops, toward multi-target Tom Tromey
  2018-04-29 15:22 ` Simon Marchi
  41 siblings, 1 reply; 65+ messages in thread
From: Pedro Alves @ 2018-04-16 15:15 UTC (permalink / raw)
  To: gdb-patches

I'm not sure why, but PATCH 01/40 never made it to the list.
Maybe because it's too large (the patch file is 477K).

Here's the same patch, but without the (generated)
target-delegates.c hunk.

You can still see the generated code in the branch, here, of course:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=blobdiff;f=gdb/target-delegates.c;h=3aea00ea9d92c61ea009b3641cc7d2a64082fe9b;hp=6ff3e06cc83e00b737922e3fb16fd271aceb2183;hb=8c60ef81bb3076d86a10e5fdf2ab60dac64ec0fd;hpb=f1dd326b642d1aa7d7497264642bce06aab7135c

From 8c60ef81bb3076d86a10e5fdf2ab60dac64ec0fd Mon Sep 17 00:00:00 2001
From: Pedro Alves <palves@redhat.com>
Date: Fri, 6 Apr 2018 23:51:22 +0100
Subject: [PATCH 01/40] Convert struct target_ops to C++

I.e., use C++ virtual methods and inheritance instead of tables of
function pointers.

Unfortunately, there's no way to do a smooth transition.  ALL native
targets in the tree must be converted at the same time.  I've tested
all I could with cross compilers and with help from GCC compile farm,
but naturally I haven't been able to test many of the ports.  Still, I
made a best effort to port everything over, and while I expect some
build problems due to typos and such, which should be trivial to fix,
I don't expect any design problems.  Since the patch would be too big
to review and manage as a single unit, I split it in many chunks.
This patch contains the core changes.  The following patches that have
"target_ops/C++:" in their subject line each converts some target or
targets over.  For pushing, all the "target_ops/C++:" patches must be
squashed into this patch and pushed together, to avoid breaking the
build (as much as possible).  I also haven't written ChangeLog entries
for this part of the series yet, because it's going to be very
mechanical, and I'd rather send this out sooner than later, in order
to hopefuly get some help with testing on native ports that I don't
have access to.

* Implementation notes:

- The flattened current_target is gone.  References to current_target
  or current_target.beneath are replaced to references to target_stack
  (the top of the stack) directly.

- To keep "set debug target" working, This adds a new debug_stratum
  layer that sits on top of the stack, prints the debug, and delegates
  to the target beneath.

  In addition, this makes the shortname and longname properties of
  target_ops be virtual methods instead of data fields, and makes the
  debug target defer those to the target beneath.  This is so that
  debug code sprinkled around that does "if (debugtarget) ..."  can
  transparently print the name of the target beneath.

  A patch later in the series actually splits out the
  shortname/longname methods to a separate structure, but I preferred
  to keep that chance separate as it is associated with changing a bit
  the design of how targets are registered and open.

- Since you can't check whether a C++ virtual method is overriden, the
  old method of checking whether a target_ops implements a method by
  comparing the function pointer must be replaced with something else.
  This is fixed by adding a parallel "can_do_foo" target_ops methods.
  E.g.,:

    +  for (t = target_stack; t != NULL; t = t->beneath)
	 {
    -      if (t->to_create_inferior != NULL)
    +      if (t->can_create_inferior ())
	    break;
	 }

- make-target-delegates was adjusted to generate C++ classes and
  methods.

  It needed tweaks to grok "virtual" in front of the target method
  name, and for the fact that methods are no longer function pointers.
  (In particular, the current code parsing the return type was simple
  because it could simply parse up until the '(' in '(*to_foo)'.

  It now generates a couple C++ classes that inherit target_ops:
  dummy_target and debug_target.

  Since we need to generate the class declarations as well, i.e., we
  need to emit methods twice, we now generate the code in two passes.

- We can no longer use functions like x86_use_watchpoints to install
  custom methods on an arbitrary base target.

  The patch (actually patches until it's all squashed before pushing)
  replaces instances of such a pattern with template mixins.  A case
  seen in this patch in isolation is memory_breakpoint_target defined
  in target.h.
---
 gdb/auxv.c                                         |   13 +-
 gdb/auxv.h                                         |    3 +-
 gdb/avr-tdep.c                                     |    4 +-
 gdb/breakpoint.c                                   |    7 +-
 gdb/elfread.c                                      |   10 +-
 gdb/eval.c                                         |    2 +-
 gdb/exceptions.c                                   |    6 +-
 gdb/frame.c                                        |    2 +-
 gdb/gdbarch-selftests.c                            |    4 +-
 gdb/gnu-v3-abi.c                                   |    2 +-
 gdb/ia64-tdep.c                                    |    2 +-
 gdb/ia64-vms-tdep.c                                |    2 +-
 gdb/infcall.c                                      |    4 +-
 gdb/infcmd.c                                       |   36 +-
 gdb/infrun.c                                       |   12 +-
 gdb/linux-tdep.c                                   |   18 +-
 gdb/make-target-delegates                          |  205 +-
 gdb/mi/mi-main.c                                   |   13 +-
 gdb/minsyms.c                                      |    4 +-
 gdb/parse.c                                        |    2 +-
 gdb/ppc-linux-nat.c                                |    2 +-
 gdb/ppc-linux-tdep.c                               |   10 +-
 gdb/procfs.c                                       |    2 +-
 gdb/regcache.c                                     |   64 +-
 gdb/remote.c                                       |   12 +-
 gdb/rs6000-tdep.c                                  |    2 +-
 gdb/s390-linux-nat.c                               |    2 +-
 gdb/s390-tdep.c                                    |    2 +-
 gdb/solib-aix.c                                    |    2 +-
 gdb/solib-darwin.c                                 |    2 +-
 gdb/solib-dsbt.c                                   |    4 +-
 gdb/solib-spu.c                                    |    6 +-
 gdb/solib-svr4.c                                   |   18 +-
 gdb/solib-target.c                                 |    2 +-
 gdb/sparc-tdep.c                                   |    2 +-
 gdb/sparc64-tdep.c                                 |    4 +-
 gdb/spu-tdep.c                                     |   30 +-
 gdb/symfile.c                                      |    2 +-
 gdb/target-debug.h                                 |    6 +
 gdb/target-delegates.c                             | 5036 +++++++++-----------
 gdb/target-descriptions.c                          |    4 +-
 gdb/target-memory.c                                |    4 +-
 gdb/target.c                                       |  846 ++--
 gdb/target.h                                       |  830 ++--
 gdb/testsuite/gdb.base/breakpoint-in-ro-region.exp |    4 +-
 gdb/testsuite/gdb.base/sss-bp-on-user-bp-2.exp     |    4 +-
 gdb/tracepoint.c                                   |    2 +-
 gdb/valops.c                                       |    4 +-
 gdb/valprint.c                                     |    2 +-
 gdb/value.c                                        |    2 +-
 gdb/windows-tdep.c                                 |    2 +-
 51 files changed, 3389 insertions(+), 3876 deletions(-)

diff --git a/gdb/auxv.c b/gdb/auxv.c
index ce7a63b894..86a1ba88a6 100644
--- a/gdb/auxv.c
+++ b/gdb/auxv.c
@@ -283,16 +283,15 @@ default_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
    Return -1 if there is insufficient buffer for a whole entry.
    Return 1 if an entry was read into *TYPEP and *VALP.  */
 int
-target_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
-                  gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
+target_auxv_parse (gdb_byte **readptr,
+		   gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
 {
   struct gdbarch *gdbarch = target_gdbarch();
 
   if (gdbarch_auxv_parse_p (gdbarch))
     return gdbarch_auxv_parse (gdbarch, readptr, endptr, typep, valp);
 
-  return current_target.to_auxv_parse (&current_target, readptr, endptr,
-				       typep, valp);
+  return target_stack->auxv_parse (readptr, endptr, typep, valp);
 }
 
 
@@ -382,7 +381,7 @@ target_auxv_search (struct target_ops *ops, CORE_ADDR match, CORE_ADDR *valp)
   size_t len = info->data->size ();
 
   while (1)
-    switch (target_auxv_parse (ops, &ptr, data + len, &type, &val))
+    switch (target_auxv_parse (&ptr, data + len, &type, &val))
       {
       case 1:			/* Here's an entry, check it.  */
 	if (type == match)
@@ -532,7 +531,7 @@ fprint_target_auxv (struct ui_file *file, struct target_ops *ops)
   gdb_byte *ptr = data;
   size_t len = info->data->size ();
 
-  while (target_auxv_parse (ops, &ptr, data + len, &type, &val) > 0)
+  while (target_auxv_parse (&ptr, data + len, &type, &val) > 0)
     {
       gdbarch_print_auxv_entry (gdbarch, file, type, val);
       ++ents;
@@ -550,7 +549,7 @@ info_auxv_command (const char *cmd, int from_tty)
     error (_("The program has no auxiliary information now."));
   else
     {
-      int ents = fprint_target_auxv (gdb_stdout, &current_target);
+      int ents = fprint_target_auxv (gdb_stdout, target_stack);
 
       if (ents < 0)
 	error (_("No auxiliary vector found, or failed reading it."));
diff --git a/gdb/auxv.h b/gdb/auxv.h
index 4a1a95e692..29c75fbfe8 100644
--- a/gdb/auxv.h
+++ b/gdb/auxv.h
@@ -35,8 +35,7 @@ extern int default_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
    Return 0 if *READPTR is already at the end of the buffer.
    Return -1 if there is insufficient buffer for a whole entry.
    Return 1 if an entry was read into *TYPEP and *VALP.  */
-extern int target_auxv_parse (struct target_ops *ops,
-			      gdb_byte **readptr, gdb_byte *endptr,
+extern int target_auxv_parse (gdb_byte **readptr, gdb_byte *endptr,
 			      CORE_ADDR *typep, CORE_ADDR *valp);
 
 /* Extract the auxiliary vector entry with a_type matching MATCH.
diff --git a/gdb/avr-tdep.c b/gdb/avr-tdep.c
index 2b9be5e313..5aa61ba2d9 100644
--- a/gdb/avr-tdep.c
+++ b/gdb/avr-tdep.c
@@ -1555,7 +1555,7 @@ avr_io_reg_read_command (const char *args, int from_tty)
 
   /* Find out how many io registers the target has.  */
   gdb::optional<gdb::byte_vector> buf
-    = target_read_alloc (&current_target, TARGET_OBJECT_AVR, "avr.io_reg");
+    = target_read_alloc (target_stack, TARGET_OBJECT_AVR, "avr.io_reg");
 
   if (!buf)
     {
@@ -1589,7 +1589,7 @@ avr_io_reg_read_command (const char *args, int from_tty)
         j = nreg - i;           /* last block is less than 8 registers */
 
       snprintf (query, sizeof (query) - 1, "avr.io_reg:%x,%x", i, j);
-      buf = target_read_alloc (&current_target, TARGET_OBJECT_AVR, query);
+      buf = target_read_alloc (target_stack, TARGET_OBJECT_AVR, query);
 
       if (!buf)
         {
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 11b89bcf88..a5287128d0 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -3493,8 +3493,7 @@ create_exception_master_breakpoint (void)
 	}
 
       addr = BMSYMBOL_VALUE_ADDRESS (bp_objfile_data->exception_msym);
-      addr = gdbarch_convert_from_func_ptr_addr (gdbarch, addr,
-						 &current_target);
+      addr = gdbarch_convert_from_func_ptr_addr (gdbarch, addr, target_stack);
       b = create_internal_breakpoint (gdbarch, addr, bp_exception_master,
 				      &internal_breakpoint_ops);
       initialize_explicit_location (&explicit_loc);
@@ -4753,7 +4752,7 @@ watchpoints_triggered (struct target_waitstatus *ws)
       return 0;
     }
 
-  if (!target_stopped_data_address (&current_target, &addr))
+  if (!target_stopped_data_address (target_stack, &addr))
     {
       /* We were stopped by a watchpoint, but we don't know where.
 	 Mark all watchpoints as unknown.  */
@@ -4793,7 +4792,7 @@ watchpoints_triggered (struct target_waitstatus *ws)
 		  }
 	      }
 	    /* Exact match not required.  Within range is sufficient.  */
-	    else if (target_watchpoint_addr_within_range (&current_target,
+	    else if (target_watchpoint_addr_within_range (target_stack,
 							 addr, loc->address,
 							 loc->length))
 	      {
diff --git a/gdb/elfread.c b/gdb/elfread.c
index 260789062d..48404e111c 100644
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -806,8 +806,7 @@ elf_gnu_ifunc_resolve_by_got (const char *name, CORE_ADDR *addr_p)
       if (target_read_memory (pointer_address, buf, ptr_size) != 0)
 	continue;
       addr = extract_typed_address (buf, ptr_type);
-      addr = gdbarch_convert_from_func_ptr_addr (gdbarch, addr,
-						 &current_target);
+      addr = gdbarch_convert_from_func_ptr_addr (gdbarch, addr, target_stack);
       addr = gdbarch_addr_bits_remove (gdbarch, addr);
 
       if (addr_p)
@@ -872,13 +871,12 @@ elf_gnu_ifunc_resolve_addr (struct gdbarch *gdbarch, CORE_ADDR pc)
      parameter.  FUNCTION is the function entry address.  ADDRESS may be a
      function descriptor.  */
 
-  target_auxv_search (&current_target, AT_HWCAP, &hwcap);
+  target_auxv_search (target_stack, AT_HWCAP, &hwcap);
   hwcap_val = value_from_longest (builtin_type (gdbarch)
 				  ->builtin_unsigned_long, hwcap);
   address_val = call_function_by_hand (function, NULL, 1, &hwcap_val);
   address = value_as_address (address_val);
-  address = gdbarch_convert_from_func_ptr_addr (gdbarch, address,
-						&current_target);
+  address = gdbarch_convert_from_func_ptr_addr (gdbarch, address, target_stack);
   address = gdbarch_addr_bits_remove (gdbarch, address);
 
   if (name_at_pc)
@@ -985,7 +983,7 @@ elf_gnu_ifunc_resolver_return_stop (struct breakpoint *b)
   resolved_address = value_as_address (value);
   resolved_pc = gdbarch_convert_from_func_ptr_addr (gdbarch,
 						    resolved_address,
-						    &current_target);
+						    target_stack);
   resolved_pc = gdbarch_addr_bits_remove (gdbarch, resolved_pc);
 
   gdb_assert (current_program_space == b->pspace || b->pspace == NULL);
diff --git a/gdb/eval.c b/gdb/eval.c
index b6fbfcf6c9..26dc58d761 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -1742,7 +1742,7 @@ evaluate_subexp_standard (struct type *expect_type,
 	    /* The address might point to a function descriptor;
 	       resolve it to the actual code address instead.  */
 	    addr = gdbarch_convert_from_func_ptr_addr (exp->gdbarch, addr,
-						       &current_target);
+						       target_stack);
 
 	    /* Is it a high_level symbol?  */
 	    sym = find_pc_function (addr);
diff --git a/gdb/exceptions.c b/gdb/exceptions.c
index 49af8a2985..5abbaf2137 100644
--- a/gdb/exceptions.c
+++ b/gdb/exceptions.c
@@ -39,7 +39,11 @@ print_flush (void)
     deprecated_error_begin_hook ();
 
   gdb::optional<target_terminal::scoped_restore_terminal_state> term_state;
-  if (target_supports_terminal_ours ())
+  /* While normally there's always something pushed on the target
+     stack, the NULL check is needed here because we can get here very
+     early during startup, before the target stack is first
+     initialized.  */
+  if (target_stack != NULL && target_supports_terminal_ours ())
     {
       term_state.emplace ();
       target_terminal::ours_for_output ();
diff --git a/gdb/frame.c b/gdb/frame.c
index 90d0ac7b87..07fa2bc77d 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -2217,7 +2217,7 @@ inside_main_func (struct frame_info *this_frame)
      returned.  */
   maddr = gdbarch_convert_from_func_ptr_addr (get_frame_arch (this_frame),
 					      BMSYMBOL_VALUE_ADDRESS (msymbol),
-					      &current_target);
+					      target_stack);
   return maddr == get_frame_func (this_frame);
 }
 
diff --git a/gdb/gdbarch-selftests.c b/gdb/gdbarch-selftests.c
index 1655f13b0e..23afe3d75e 100644
--- a/gdb/gdbarch-selftests.c
+++ b/gdb/gdbarch-selftests.c
@@ -71,8 +71,8 @@ register_to_value_test (struct gdbarch *gdbarch)
 
   /* Error out if debugging something, because we're going to push the
      test target, which would pop any existing target.  */
-  if (current_target.to_stratum >= process_stratum)
-    error (_("target already pushed"));
+  if (target_stack->to_stratum >= process_stratum)
+   error (_("target already pushed"));
 
   /* Create a mock environment.  An inferior with a thread, with a
      process_stratum target pushed.  */
diff --git a/gdb/gnu-v3-abi.c b/gdb/gnu-v3-abi.c
index 859187f2e9..ddbec13891 100644
--- a/gdb/gnu-v3-abi.c
+++ b/gdb/gnu-v3-abi.c
@@ -1217,7 +1217,7 @@ gnuv3_skip_trampoline (struct frame_info *frame, CORE_ADDR stop_pc)
      of the real function from the function descriptor before passing on
      the address to other layers of GDB.  */
   func_addr = gdbarch_convert_from_func_ptr_addr (gdbarch, method_stop_pc,
-                                                  &current_target);
+						  target_stack);
   if (func_addr != 0)
     method_stop_pc = func_addr;
 
diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c
index 4f02f05375..26e112e7bc 100644
--- a/gdb/ia64-tdep.c
+++ b/gdb/ia64-tdep.c
@@ -2660,7 +2660,7 @@ getunwind_table (gdb_byte **buf_p)
      we should find a way to override the corefile layer's
      xfer_partial method.  */
 
-  x = target_read_alloc (&current_target, TARGET_OBJECT_UNWIND_TABLE,
+  x = target_read_alloc (target_stack, TARGET_OBJECT_UNWIND_TABLE,
 			 NULL, buf_p);
 
   return x;
diff --git a/gdb/ia64-vms-tdep.c b/gdb/ia64-vms-tdep.c
index c9565ce298..9b78576608 100644
--- a/gdb/ia64-vms-tdep.c
+++ b/gdb/ia64-vms-tdep.c
@@ -42,7 +42,7 @@ ia64_vms_find_proc_info_x (unw_addr_space_t as, unw_word_t ip,
   CORE_ADDR table_addr;
   unsigned int info_len;
 
-  res = target_read (&current_target, TARGET_OBJECT_OPENVMS_UIB,
+  res = target_read (target_stack, TARGET_OBJECT_OPENVMS_UIB,
                      annex + 2, buf, 0, sizeof (buf));
 
   if (res != sizeof (buf))
diff --git a/gdb/infcall.c b/gdb/infcall.c
index 9f02674bdf..d5a60eb55c 100644
--- a/gdb/infcall.c
+++ b/gdb/infcall.c
@@ -270,7 +270,7 @@ find_function_addr (struct value *function, struct type **retval_type)
       if (TYPE_CODE (ftype) == TYPE_CODE_FUNC
 	  || TYPE_CODE (ftype) == TYPE_CODE_METHOD)
 	funaddr = gdbarch_convert_from_func_ptr_addr (gdbarch, funaddr,
-						      &current_target);
+						      target_stack);
     }
   if (TYPE_CODE (ftype) == TYPE_CODE_FUNC
       || TYPE_CODE (ftype) == TYPE_CODE_METHOD)
@@ -306,7 +306,7 @@ find_function_addr (struct value *function, struct type **retval_type)
 	      funaddr = value_as_address (value_addr (function));
 	      nfunaddr = funaddr;
 	      funaddr = gdbarch_convert_from_func_ptr_addr (gdbarch, funaddr,
-							    &current_target);
+							    target_stack);
 	      if (funaddr != nfunaddr)
 		found_descriptor = 1;
 	    }
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index d43e7f202d..1a84ea817a 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -531,7 +531,7 @@ prepare_execution_command (struct target_ops *target, int background)
 {
   /* If we get a request for running in the bg but the target
      doesn't support it, error out.  */
-  if (background && !target->to_can_async_p (target))
+  if (background && !target->can_async_p ())
     error (_("Asynchronous execution not supported on this target."));
 
   if (!background)
@@ -600,7 +600,7 @@ run_command_1 (const char *args, int from_tty, enum run_how run_how)
 
   prepare_execution_command (run_target, async_exec);
 
-  if (non_stop && !run_target->to_supports_non_stop (run_target))
+  if (non_stop && !run_target->supports_non_stop ())
     error (_("The target does not support running in non-stop mode."));
 
   /* Done.  Can now set breakpoints, change inferior args, etc.  */
@@ -639,10 +639,10 @@ run_command_1 (const char *args, int from_tty, enum run_how run_how)
 
   /* We call get_inferior_args() because we might need to compute
      the value now.  */
-  run_target->to_create_inferior (run_target, exec_file,
-				  std::string (get_inferior_args ()),
-				  current_inferior ()->environment.envp (),
-				  from_tty);
+  run_target->create_inferior (exec_file,
+			       std::string (get_inferior_args ()),
+			       current_inferior ()->environment.envp (),
+			       from_tty);
   /* to_create_inferior should push the target, so after this point we
      shouldn't refer to run_target again.  */
   run_target = NULL;
@@ -660,7 +660,7 @@ run_command_1 (const char *args, int from_tty, enum run_how run_how)
 
   /* Pass zero for FROM_TTY, because at this point the "run" command
      has done its thing; now we are setting up the running program.  */
-  post_create_inferior (&current_target, 0);
+  post_create_inferior (target_stack, 0);
 
   /* Queue a pending event so that the program stops immediately.  */
   if (run_how == RUN_STOP_AT_FIRST_INSN)
@@ -896,7 +896,7 @@ continue_command (const char *args, int from_tty)
       ensure_not_running ();
     }
 
-  prepare_execution_command (&current_target, async_exec);
+  prepare_execution_command (target_stack, async_exec);
 
   if (from_tty)
     printf_filtered (_("Continuing.\n"));
@@ -1043,7 +1043,7 @@ step_1 (int skip_subroutines, int single_inst, const char *count_string)
     = strip_bg_char (count_string, &async_exec);
   count_string = stripped.get ();
 
-  prepare_execution_command (&current_target, async_exec);
+  prepare_execution_command (target_stack, async_exec);
 
   count = count_string ? parse_and_eval_long (count_string) : 1;
 
@@ -1232,7 +1232,7 @@ jump_command (const char *arg, int from_tty)
   gdb::unique_xmalloc_ptr<char> stripped = strip_bg_char (arg, &async_exec);
   arg = stripped.get ();
 
-  prepare_execution_command (&current_target, async_exec);
+  prepare_execution_command (target_stack, async_exec);
 
   if (!arg)
     error_no_arg (_("starting address"));
@@ -1312,7 +1312,7 @@ signal_command (const char *signum_exp, int from_tty)
     = strip_bg_char (signum_exp, &async_exec);
   signum_exp = stripped.get ();
 
-  prepare_execution_command (&current_target, async_exec);
+  prepare_execution_command (target_stack, async_exec);
 
   if (!signum_exp)
     error_no_arg (_("signal number"));
@@ -1585,7 +1585,7 @@ until_command (const char *arg, int from_tty)
   gdb::unique_xmalloc_ptr<char> stripped = strip_bg_char (arg, &async_exec);
   arg = stripped.get ();
 
-  prepare_execution_command (&current_target, async_exec);
+  prepare_execution_command (target_stack, async_exec);
 
   if (arg)
     until_break_command (arg, from_tty, 0);
@@ -1610,7 +1610,7 @@ advance_command (const char *arg, int from_tty)
   gdb::unique_xmalloc_ptr<char> stripped = strip_bg_char (arg, &async_exec);
   arg = stripped.get ();
 
-  prepare_execution_command (&current_target, async_exec);
+  prepare_execution_command (target_stack, async_exec);
 
   until_break_command (arg, from_tty, 1);
 }
@@ -1990,7 +1990,7 @@ finish_command (const char *arg, int from_tty)
   gdb::unique_xmalloc_ptr<char> stripped = strip_bg_char (arg, &async_exec);
   arg = stripped.get ();
 
-  prepare_execution_command (&current_target, async_exec);
+  prepare_execution_command (target_stack, async_exec);
 
   if (arg)
     error (_("The \"finish\" command does not take any arguments."));
@@ -2675,7 +2675,7 @@ setup_inferior (int from_tty)
   /* Take any necessary post-attaching actions for this platform.  */
   target_post_attach (ptid_get_pid (inferior_ptid));
 
-  post_create_inferior (&current_target, from_tty);
+  post_create_inferior (target_stack, from_tty);
 }
 
 /* What to do after the first program stops after attaching.  */
@@ -2838,10 +2838,10 @@ attach_command (const char *args, int from_tty)
 
   prepare_execution_command (attach_target, async_exec);
 
-  if (non_stop && !attach_target->to_supports_non_stop (attach_target))
+  if (non_stop && !attach_target->supports_non_stop ())
     error (_("Cannot attach to this target in non-stop mode"));
 
-  attach_target->to_attach (attach_target, args, from_tty);
+  attach_target->attach (args, from_tty);
   /* to_attach should push the target, so after this point we
      shouldn't refer to attach_target again.  */
   attach_target = NULL;
@@ -2892,7 +2892,7 @@ attach_command (const char *args, int from_tty)
 
   /* Some system don't generate traps when attaching to inferior.
      E.g. Mach 3 or GNU hurd.  */
-  if (!target_attach_no_wait)
+  if (!target_attach_no_wait ())
     {
       struct attach_command_continuation_args *a;
 
diff --git a/gdb/infrun.c b/gdb/infrun.c
index c1db689c1c..c51626d7df 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -3236,7 +3236,7 @@ start_remote (int from_tty)
   /* Now that the inferior has stopped, do any bookkeeping like
      loading shared libraries.  We want to do this before normal_stop,
      so that the displayed frame is up to date.  */
-  post_create_inferior (&current_target, from_tty);
+  post_create_inferior (target_stack, from_tty);
 
   normal_stop ();
 }
@@ -5693,7 +5693,7 @@ handle_signal_stop (struct execution_control_state *ecs)
 
 	  fprintf_unfiltered (gdb_stdlog, "infrun: stopped by watchpoint\n");
 
-          if (target_stopped_data_address (&current_target, &addr))
+	  if (target_stopped_data_address (target_stack, &addr))
             fprintf_unfiltered (gdb_stdlog,
                                 "infrun: stopped data address = %s\n",
                                 paddress (gdbarch, addr));
@@ -8727,7 +8727,7 @@ siginfo_value_read (struct value *v)
   validate_registers_access ();
 
   transferred =
-    target_read (&current_target, TARGET_OBJECT_SIGNAL_INFO,
+    target_read (target_stack, TARGET_OBJECT_SIGNAL_INFO,
 		 NULL,
 		 value_contents_all_raw (v),
 		 value_offset (v),
@@ -8749,7 +8749,7 @@ siginfo_value_write (struct value *v, struct value *fromval)
      vice versa.  */
   validate_registers_access ();
 
-  transferred = target_write (&current_target,
+  transferred = target_write (target_stack,
 			      TARGET_OBJECT_SIGNAL_INFO,
 			      NULL,
 			      value_contents_all_raw (fromval),
@@ -8828,7 +8828,7 @@ save_infcall_suspend_state (void)
       siginfo_data = (gdb_byte *) xmalloc (len);
       back_to = make_cleanup (xfree, siginfo_data);
 
-      if (target_read (&current_target, TARGET_OBJECT_SIGNAL_INFO, NULL,
+      if (target_read (target_stack, TARGET_OBJECT_SIGNAL_INFO, NULL,
 		       siginfo_data, 0, len) == len)
 	discard_cleanups (back_to);
       else
@@ -8878,7 +8878,7 @@ restore_infcall_suspend_state (struct infcall_suspend_state *inf_state)
       struct type *type = gdbarch_get_siginfo_type (gdbarch);
 
       /* Errors ignored.  */
-      target_write (&current_target, TARGET_OBJECT_SIGNAL_INFO, NULL,
+      target_write (target_stack, TARGET_OBJECT_SIGNAL_INFO, NULL,
 		    inf_state->siginfo_data, 0, TYPE_LENGTH (type));
     }
 
diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c
index 552a2a495b..145d05d923 100644
--- a/gdb/linux-tdep.c
+++ b/gdb/linux-tdep.c
@@ -402,8 +402,8 @@ linux_is_uclinux (void)
 {
   CORE_ADDR dummy;
 
-  return (target_auxv_search (&current_target, AT_NULL, &dummy) > 0
-	  && target_auxv_search (&current_target, AT_PAGESZ, &dummy) == 0);
+  return (target_auxv_search (target_stack, AT_NULL, &dummy) > 0
+	  && target_auxv_search (target_stack, AT_PAGESZ, &dummy) == 0);
 }
 
 static int
@@ -1423,7 +1423,7 @@ linux_spu_make_corefile_notes (bfd *obfd, char *note_data, int *note_size)
 
   /* Determine list of SPU ids.  */
   gdb::optional<gdb::byte_vector>
-    spu_ids = target_read_alloc (&current_target, TARGET_OBJECT_SPU, NULL);
+    spu_ids = target_read_alloc (target_stack, TARGET_OBJECT_SPU, NULL);
 
   if (!spu_ids)
     return nullptr;
@@ -1439,7 +1439,7 @@ linux_spu_make_corefile_notes (bfd *obfd, char *note_data, int *note_size)
 
 	  xsnprintf (annex, sizeof annex, "%d/%s", fd, spu_files[j]);
 	  gdb::optional<gdb::byte_vector> spu_data
-	    = target_read_alloc (&current_target, TARGET_OBJECT_SPU, annex);
+	    = target_read_alloc (target_stack, TARGET_OBJECT_SPU, annex);
 
 	  if (spu_data && !spu_data->empty ())
 	    {
@@ -1661,7 +1661,7 @@ linux_get_siginfo_data (thread_info *thread, struct gdbarch *gdbarch)
 
   gdb::byte_vector buf (TYPE_LENGTH (siginfo_type));
 
-  bytes_read = target_read (&current_target, TARGET_OBJECT_SIGNAL_INFO, NULL,
+  bytes_read = target_read (target_stack, TARGET_OBJECT_SIGNAL_INFO, NULL,
 			    buf.data (), 0, TYPE_LENGTH (siginfo_type));
   if (bytes_read != TYPE_LENGTH (siginfo_type))
     buf.clear ();
@@ -1970,7 +1970,7 @@ linux_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
 
   /* Auxillary vector.  */
   gdb::optional<gdb::byte_vector> auxv =
-    target_read_alloc (&current_target, TARGET_OBJECT_AUXV, NULL);
+    target_read_alloc (target_stack, TARGET_OBJECT_AUXV, NULL);
   if (auxv && !auxv->empty ())
     {
       note_data = elfcore_write_note (obfd, note_data, note_size,
@@ -2253,7 +2253,7 @@ linux_vsyscall_range_raw (struct gdbarch *gdbarch, struct mem_range *range)
   char filename[100];
   long pid;
 
-  if (target_auxv_search (&current_target, AT_SYSINFO_EHDR, &range->start) <= 0)
+  if (target_auxv_search (target_stack, AT_SYSINFO_EHDR, &range->start) <= 0)
     return 0;
 
   /* It doesn't make sense to access the host's /proc when debugging a
@@ -2443,14 +2443,14 @@ linux_displaced_step_location (struct gdbarch *gdbarch)
      local-store address and is thus not usable as displaced stepping
      location.  The auxiliary vector gets us the PowerPC-side entry
      point address instead.  */
-  if (target_auxv_search (&current_target, AT_ENTRY, &addr) <= 0)
+  if (target_auxv_search (target_stack, AT_ENTRY, &addr) <= 0)
     throw_error (NOT_SUPPORTED_ERROR,
 		 _("Cannot find AT_ENTRY auxiliary vector entry."));
 
   /* Make certain that the address points at real code, and not a
      function descriptor.  */
   addr = gdbarch_convert_from_func_ptr_addr (gdbarch, addr,
-					     &current_target);
+					     target_stack);
 
   /* Inferior calls also use the entry point as a breakpoint location.
      We don't want displaced stepping to interfere with those
diff --git a/gdb/make-target-delegates b/gdb/make-target-delegates
index bf91ddc17c..10853e3e20 100755
--- a/gdb/make-target-delegates
+++ b/gdb/make-target-delegates
@@ -30,16 +30,27 @@ $ENDER = qr,^\s*};$,;
 # Match a C symbol.
 $SYMBOL = qr,[a-zA-Z_][a-zA-Z0-9_]*,;
 # Match the name part of a method in struct target_ops.
-$NAME_PART = qr,\(\*(?<name>${SYMBOL}+)\)\s,;
+$NAME_PART = qr,(?<name>${SYMBOL}+)\s,;
 # Match the arguments to a method.
 $ARGS_PART = qr,(?<args>\(.*\)),;
 # We strip the indentation so here we only need the caret.
 $INTRO_PART = qr,^,;
 
+$POINTER_PART = qr,\s*(\*)?\s*,;
+
+# Match a C++ symbol, including scope operators and template
+# parameters.  E.g., 'std::vector<something>'.
+$CP_SYMBOL = qr,[a-zA-Z_][a-zA-Z0-9_<>:]*,;
 # Match the return type when it is "ordinary".
-$SIMPLE_RETURN_PART = qr,[^\(]+,;
+$SIMPLE_RETURN_PART = qr,((struct|class|enum|union)\s+)?${CP_SYMBOL}+,;
 # Match the return type when it is a VEC.
-$VEC_RETURN_PART = qr,VEC\s*\([^\)]+\)[^\(]*,;
+$VEC_RETURN_PART = qr,VEC\s*\([^\)]+\),;
+
+# Match a return type.
+$RETURN_PART = qr,((const|volatile)\s+)?(${SIMPLE_RETURN_PART}|${VEC_RETURN_PART})${POINTER_PART},;
+
+# Match "virtual".
+$VIRTUAL_PART = qr,virtual\s,;
 
 # Match the TARGET_DEFAULT_* attribute for a method.
 $TARGET_DEFAULT_PART = qr,TARGET_DEFAULT_(?<style>[A-Z_]+)\s*\((?<default_arg>.*)\),;
@@ -49,8 +60,7 @@ $TARGET_DEFAULT_PART = qr,TARGET_DEFAULT_(?<style>[A-Z_]+)\s*\((?<default_arg>.*
 $METHOD_TRAILER = qr,\s*${TARGET_DEFAULT_PART}$,;
 
 # Match an entire method definition.
-$METHOD = ($INTRO_PART . "(?<return_type>" . $SIMPLE_RETURN_PART
-	   . "|" . $VEC_RETURN_PART . ")"
+$METHOD = ($INTRO_PART . $VIRTUAL_PART . "(?<return_type>" . $RETURN_PART . ")"
 	   . $NAME_PART . $ARGS_PART
 	   . $METHOD_TRAILER);
 
@@ -90,7 +100,7 @@ sub scan_target_h() {
 	next if /{/;
 	last if m/$ENDER/;
 
-	# Just in case somebody ever uses C99.
+	# Strip // comments.
 	$_ =~ s,//.*$,,;
 	$_ = trim ($_);
 
@@ -130,16 +140,24 @@ sub parse_argtypes($) {
 
 sub dname($) {
     my ($name) = @_;
-    $name =~ s/to_/delegate_/;
-    return $name;
+    return "target_ops::" . $name;
 }
 
 # Write function header given name, return type, and argtypes.
 # Returns a list of actual argument names.
-sub write_function_header($$@) {
-    my ($name, $return_type, @argtypes) = @_;
+sub write_function_header($$$@) {
+    my ($decl, $name, $return_type, @argtypes) = @_;
+
+    print $return_type;
+
+    if ($decl) {
+	if ($return_type !~ m,\*$,) {
+	    print " ";
+	}
+    } else {
+	print "\n";
+    }
 
-    print "static " . $return_type . "\n";
     print $name . ' (';
 
     my $iter;
@@ -156,12 +174,7 @@ sub write_function_header($$@) {
 	}
 
 	my $vname;
-	if ($i == 0) {
-	    # Just a random nicety.
-	    $vname = 'self';
-	} else {
-	    $vname .= "arg$i";
-	}
+	$vname .= "arg$i";
 	$val .= $vname;
 
 	push @argdecls, $val;
@@ -169,25 +182,36 @@ sub write_function_header($$@) {
 	++$i;
     }
 
-    print join (', ', @argdecls) . ")\n";
-    print "{\n";
+    print join (', ', @argdecls) . ")";
+
+    if ($decl) {
+	print " override;\n";
+    } else {
+	print "\n{\n";
+    }
 
     return @actuals;
 }
 
+# Write out a declaration.
+sub write_declaration($$@) {
+    my ($name, $return_type, @argtypes) = @_;
+
+    write_function_header (1, $name, $return_type, @argtypes);
+}
+
 # Write out a delegation function.
 sub write_delegator($$@) {
     my ($name, $return_type, @argtypes) = @_;
 
-    my (@names) = write_function_header (dname ($name), $return_type,
-					 @argtypes);
+    my (@names) = write_function_header (0, dname ($name),
+					 $return_type, @argtypes);
 
-    print "  $names[0] = $names[0]->beneath;\n";
     print "  ";
     if ($return_type ne 'void') {
 	print "return ";
     }
-    print "$names[0]->" . $name . " (";
+    print "this->beneath->" . $name . " (";
     print join (', ', @names);
     print ");\n";
     print "}\n\n";
@@ -195,21 +219,28 @@ sub write_delegator($$@) {
 
 sub tdname ($) {
     my ($name) = @_;
-    $name =~ s/to_/tdefault_/;
-    return $name;
+    return "dummy_target::" . $name;
 }
 
 # Write out a default function.
 sub write_tdefault($$$$@) {
     my ($content, $style, $name, $return_type, @argtypes) = @_;
 
-    if ($style eq 'FUNC') {
-	return $content;
-    }
+    my (@names) = write_function_header (0, tdname ($name),
+					 $return_type, @argtypes);
 
-    write_function_header (tdname ($name), $return_type, @argtypes);
-
-    if ($style eq 'RETURN') {
+    if ($style eq 'FUNC') {
+	print "  ";
+	if ($return_type ne 'void') {
+	    print "return ";
+	}
+	print $content . " (this";
+	if (@names) {
+	    print ", ";
+	}
+	print join (', ', @names);
+	print ");\n";
+    } elsif ($style eq 'RETURN') {
 	print "  return $content;\n";
     } elsif ($style eq 'NORETURN') {
 	print "  $content;\n";
@@ -252,39 +283,37 @@ sub munge_type($) {
 }
 
 # Write out a debug method.
-sub write_debugmethod($$$$@) {
-    my ($content, $style, $name, $return_type, @argtypes) = @_;
+sub write_debugmethod($$$@) {
+    my ($content, $name, $return_type, @argtypes) = @_;
 
-    my ($debugname) = $name;
-    $debugname =~ s/to_/debug_/;
+    my ($debugname) = "debug_target::" . $name;
     my ($targetname) = $name;
-    $targetname =~ s/to_/target_/;
 
-    my (@names) = write_function_header ($debugname, $return_type, @argtypes);
+    my (@names) = write_function_header (0, $debugname, $return_type, @argtypes);
 
     if ($return_type ne 'void') {
 	print "  $return_type result;\n";
     }
 
-    print "  fprintf_unfiltered (gdb_stdlog, \"-> %s->$name (...)\\n\", debug_target.to_shortname);\n";
+    print "  fprintf_unfiltered (gdb_stdlog, \"-> %s->$name (...)\\n\", this->beneath->shortname ());\n";
 
     # Delegate to the beneath target.
     print "  ";
     if ($return_type ne 'void') {
 	print "result = ";
     }
-    print "debug_target." . $name . " (";
-    my @names2 = @names;
-    @names2[0] = "&debug_target";
-    print join (', ', @names2);
+    print "this->beneath->" . $name . " (";
+    print join (', ', @names);
     print ");\n";
 
     # Now print the arguments.
-    print "  fprintf_unfiltered (gdb_stdlog, \"<- %s->$name (\", debug_target.to_shortname);\n";
+    print "  fprintf_unfiltered (gdb_stdlog, \"<- %s->$name (\", this->beneath->shortname ());\n";
     for my $i (0 .. $#argtypes) {
-	print "  fputs_unfiltered (\", \", gdb_stdlog);\n" if $i > 0;
+	if ($i > 0) {
+	    print "  fputs_unfiltered (\", \", gdb_stdlog);\n"
+	}
 	my $printer = munge_type ($argtypes[$i]);
-	print "  $printer ($names2[$i]);\n";
+	print "  $printer ($names[$i]);\n";
     }
     if ($return_type ne 'void') {
 	print "  fputs_unfiltered (\") = \", gdb_stdlog);\n";
@@ -308,61 +337,71 @@ print "/* THIS FILE IS GENERATED -*- buffer-read-only: t -*- */\n";
 print "/* vi:set ro: */\n\n";
 print "/* To regenerate this file, run:*/\n";
 print "/*      make-target-delegates target.h > target-delegates.c */\n";
+print "\n";
 
 @lines = scan_target_h();
 
-
-%tdefault_names = ();
-%debug_names = ();
 @delegators = ();
+@return_types = ();
+@tdefaults = ();
+@styles = ();
+@argtypes_array = ();
+
 foreach $current_line (@lines) {
     next unless $current_line =~ m/$METHOD/;
 
-    $name = $+{name};
-    $current_line = $+{args};
-    $return_type = trim ($+{return_type});
-    $current_args = $+{args};
-    $tdefault = $+{default_arg};
-    $style = $+{style};
+    my $name = $+{name};
+    my $current_line = $+{args};
+    my $return_type = trim ($+{return_type});
+    my $current_args = $+{args};
+    my $tdefault = $+{default_arg};
+    my $style = $+{style};
 
-    @argtypes = parse_argtypes ($current_args);
+    my @argtypes = parse_argtypes ($current_args);
 
-    # The first argument must be "this" to be delegatable.
-    if ($argtypes[0] =~ /\s*struct\s+target_ops\s*\*\s*/) {
-	write_delegator ($name, $return_type, @argtypes);
+    push @delegators, $name;
 
-	push @delegators, $name;
+    $return_types{$name} = $return_type;
+    $tdefaults{$name} = $tdefault;
+    $styles{$name} = $style;
+    $argtypes_array{$name} = \@argtypes;
+}
 
-	$tdefault_names{$name} = write_tdefault ($tdefault, $style,
-						 $name, $return_type,
-						 @argtypes);
+sub print_class($) {
+    my ($name) = @_;
 
-	$debug_names{$name} = write_debugmethod ($tdefault, $style,
-						 $name, $return_type,
-						 @argtypes);
+    print "struct " . $name . " : public target_ops\n";
+    print "{\n";
+    print "  $name ();\n";
+    print "\n";
+    print "  const char *shortname () override;\n";
+    print "  const char *longname () override;\n";
+    print "  const char *doc () override;\n";
+    print "\n";
+
+    for $name (@delegators) {
+	my $return_type = $return_types{$name};
+	my @argtypes = @{$argtypes_array{$name}};
+
+	print "  ";
+	write_declaration ($name, $return_type, @argtypes);
     }
+
+    print "};\n\n";
 }
 
-# Now the delegation code.
-print "static void\ninstall_delegators (struct target_ops *ops)\n{\n";
+print_class ("dummy_target");
+print_class ("debug_target");
 
-for $iter (@delegators) {
-    print "  if (ops->" . $iter . " == NULL)\n";
-    print "    ops->" . $iter . " = " . dname ($iter) . ";\n";
-}
-print "}\n\n";
+for $name (@delegators) {
+    my $tdefault = $tdefaults{$name};
+    my $return_type = $return_types{$name};
+    my $style = $styles{$name};
+    my @argtypes = @{$argtypes_array{$name}};
 
-# Now the default method code.
-print "static void\ninstall_dummy_methods (struct target_ops *ops)\n{\n";
+    write_delegator ($name, $return_type, @argtypes);
 
-for $iter (@delegators) {
-    print "  ops->" . $iter . " = " . $tdefault_names{$iter} . ";\n";
-}
-print "}\n\n";
+    write_tdefault ($tdefault, $style, $name, $return_type, @argtypes);
 
-# The debug method code.
-print "static void\ninit_debug_target (struct target_ops *ops)\n{\n";
-for $iter (@delegators) {
-    print "  ops->" . $iter . " = " . $debug_names{$iter} . ";\n";
+    write_debugmethod ($tdefault, $name, $return_type, @argtypes);
 }
-print "}\n";
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index d7354606b5..51d0a268c9 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -266,7 +266,7 @@ proceed_thread_callback (struct thread_info *thread, void *arg)
 static void
 exec_continue (char **argv, int argc)
 {
-  prepare_execution_command (&current_target, mi_async_p ());
+  prepare_execution_command (target_stack, mi_async_p ());
 
   if (non_stop)
     {
@@ -405,7 +405,7 @@ run_one_inferior (struct inferior *inf, void *arg)
   int start_p = *(int *) arg;
   const char *run_cmd = start_p ? "start" : "run";
   struct target_ops *run_target = find_run_target ();
-  int async_p = mi_async && run_target->to_can_async_p (run_target);
+  int async_p = mi_async && run_target->can_async_p ();
 
   if (inf->pid != 0)
     {
@@ -479,7 +479,7 @@ mi_cmd_exec_run (const char *command, char **argv, int argc)
     {
       const char *run_cmd = start_p ? "start" : "run";
       struct target_ops *run_target = find_run_target ();
-      int async_p = mi_async && run_target->to_can_async_p (run_target);
+      int async_p = mi_async && run_target->can_async_p ();
 
       mi_execute_cli_command (run_cmd, async_p,
 			      async_p ? "&" : NULL);
@@ -1353,10 +1353,7 @@ mi_cmd_data_read_memory (const char *command, char **argv, int argc)
 
   gdb::byte_vector mbuf (total_bytes);
 
-  /* Dispatch memory reads to the topmost target, not the flattened
-     current_target.  */
-  nr_bytes = target_read (current_target.beneath,
-			  TARGET_OBJECT_MEMORY, NULL, mbuf.data (),
+  nr_bytes = target_read (target_stack, TARGET_OBJECT_MEMORY, NULL, mbuf.data (),
 			  addr, total_bytes);
   if (nr_bytes <= 0)
     error (_("Unable to read memory."));
@@ -1476,7 +1473,7 @@ mi_cmd_data_read_memory_bytes (const char *command, char **argv, int argc)
   length = atol (argv[1]);
 
   std::vector<memory_read_result> result
-    = read_memory_robust (current_target.beneath, addr, length);
+    = read_memory_robust (target_stack, addr, length);
 
   if (result.size () == 0)
     error (_("Unable to read memory."));
diff --git a/gdb/minsyms.c b/gdb/minsyms.c
index 9d23c4fd4f..625d5e4260 100644
--- a/gdb/minsyms.c
+++ b/gdb/minsyms.c
@@ -73,7 +73,7 @@ msymbol_is_function (struct objfile *objfile, minimal_symbol *minsym,
       {
 	struct gdbarch *gdbarch = get_objfile_arch (objfile);
 	CORE_ADDR pc = gdbarch_convert_from_func_ptr_addr (gdbarch, msym_addr,
-							   &current_target);
+							   target_stack);
 	if (pc != msym_addr)
 	  {
 	    if (func_address_p != NULL)
@@ -1501,7 +1501,7 @@ find_solib_trampoline_target (struct frame_info *frame, CORE_ADDR pc)
 	    func = gdbarch_convert_from_func_ptr_addr
 		    (get_objfile_arch (objfile),
 		     MSYMBOL_VALUE_ADDRESS (objfile, msymbol),
-		     &current_target);
+		     target_stack);
 
 	    /* Ignore data symbols that are not function descriptors.  */
 	    if (func != MSYMBOL_VALUE_ADDRESS (objfile, msymbol))
diff --git a/gdb/parse.c b/gdb/parse.c
index 3abb9d4219..6f82d37fe2 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -474,7 +474,7 @@ find_minsym_type_and_address (minimal_symbol *msymbol,
 
   /* The minimal symbol might point to a function descriptor;
      resolve it to the actual code address instead.  */
-  pc = gdbarch_convert_from_func_ptr_addr (gdbarch, addr, &current_target);
+  pc = gdbarch_convert_from_func_ptr_addr (gdbarch, addr, target_stack);
   if (pc != addr)
     {
       struct bound_minimal_symbol ifunc_msym = lookup_minimal_symbol_by_pc (pc);
diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c
index 2cd8792d30..e1b728016c 100644
--- a/gdb/ppc-linux-nat.c
+++ b/gdb/ppc-linux-nat.c
@@ -1300,7 +1300,7 @@ ppc_linux_get_hwcap (void)
 {
   CORE_ADDR field;
 
-  if (target_auxv_search (&current_target, AT_HWCAP, &field))
+  if (target_auxv_search (target_stack, AT_HWCAP, &field))
     return (unsigned long) field;
 
   return 0;
diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c
index 04487e7b15..6d3a64c4f0 100644
--- a/gdb/ppc-linux-tdep.c
+++ b/gdb/ppc-linux-tdep.c
@@ -1203,7 +1203,7 @@ ppc_linux_spe_context (int wordsize, enum bfd_endian byte_order,
   /* Look up cached address of thread-local variable.  */
   if (!ptid_equal (spe_context_cache_ptid, inferior_ptid))
     {
-      struct target_ops *target = &current_target;
+      struct target_ops *target = target_stack;
 
       TRY
 	{
@@ -1214,9 +1214,9 @@ ppc_linux_spe_context (int wordsize, enum bfd_endian byte_order,
 	     Instead, we have cached the lm_addr value, and use that to
 	     directly call the target's to_get_thread_local_address.  */
 	  spe_context_cache_address
-	    = target->to_get_thread_local_address (target, inferior_ptid,
-						   spe_context_lm_addr,
-						   spe_context_offset);
+	    = target->get_thread_local_address (inferior_ptid,
+						spe_context_lm_addr,
+						spe_context_offset);
 	  spe_context_cache_ptid = inferior_ptid;
 	}
 
@@ -1363,7 +1363,7 @@ ppu2spu_sniffer (const struct frame_unwind *self,
 	return 0;
 
       xsnprintf (annex, sizeof annex, "%d/regs", data.id);
-      if (target_read (&current_target, TARGET_OBJECT_SPU, annex,
+      if (target_read (target_stack, TARGET_OBJECT_SPU, annex,
 		       data.gprs, 0, sizeof data.gprs)
 	  == sizeof data.gprs)
 	{
diff --git a/gdb/procfs.c b/gdb/procfs.c
index 51c9ae8f00..478770d0fe 100644
--- a/gdb/procfs.c
+++ b/gdb/procfs.c
@@ -3936,7 +3936,7 @@ procfs_make_note_section (struct target_ops *self, bfd *obfd, int *note_size)
 			     &thread_args);
   note_data = thread_args.note_data;
 
-  auxv_len = target_read_alloc (&current_target, TARGET_OBJECT_AUXV,
+  auxv_len = target_read_alloc (target_stack, TARGET_OBJECT_AUXV,
 				NULL, &auxv);
   if (auxv_len > 0)
     {
diff --git a/gdb/regcache.c b/gdb/regcache.c
index 3af8ca9699..f8e0c49a7c 100644
--- a/gdb/regcache.c
+++ b/gdb/regcache.c
@@ -1488,30 +1488,12 @@ current_regcache_test (void)
   SELF_CHECK (regcache_access::current_regcache_size () == 2);
 }
 
-static void test_target_fetch_registers (target_ops *self, regcache *regs,
-					 int regno);
-static void test_target_store_registers (target_ops *self, regcache *regs,
-					 int regno);
-static enum target_xfer_status
-  test_target_xfer_partial (struct target_ops *ops,
-			    enum target_object object,
-			    const char *annex, gdb_byte *readbuf,
-			    const gdb_byte *writebuf,
-			    ULONGEST offset, ULONGEST len,
-			    ULONGEST *xfered_len);
-
 class target_ops_no_register : public test_target_ops
 {
 public:
   target_ops_no_register ()
     : test_target_ops {}
-  {
-    to_fetch_registers = test_target_fetch_registers;
-    to_store_registers = test_target_store_registers;
-    to_xfer_partial = test_target_xfer_partial;
-
-    to_data = this;
-  }
+  {}
 
   void reset ()
   {
@@ -1520,38 +1502,42 @@ public:
     xfer_partial_called = 0;
   }
 
+  void fetch_registers (regcache *regs, int regno) override;
+  void store_registers (regcache *regs, int regno) override;
+
+  enum target_xfer_status xfer_partial (enum target_object object,
+					const char *annex, gdb_byte *readbuf,
+					const gdb_byte *writebuf,
+					ULONGEST offset, ULONGEST len,
+					ULONGEST *xfered_len) override;
+
   unsigned int fetch_registers_called = 0;
   unsigned int store_registers_called = 0;
   unsigned int xfer_partial_called = 0;
 };
 
-static void
-test_target_fetch_registers (target_ops *self, regcache *regs, int regno)
+void
+target_ops_no_register::fetch_registers (regcache *regs, int regno)
 {
-  auto ops = static_cast<target_ops_no_register *> (self->to_data);
-
   /* Mark register available.  */
   regs->raw_supply_zeroed (regno);
-  ops->fetch_registers_called++;
+  this->fetch_registers_called++;
 }
 
-static void
-test_target_store_registers (target_ops *self, regcache *regs, int regno)
+void
+target_ops_no_register::store_registers (regcache *regs, int regno)
 {
-  auto ops = static_cast<target_ops_no_register *> (self->to_data);
-
-  ops->store_registers_called++;
+  this->store_registers_called++;
 }
 
-static enum target_xfer_status
-test_target_xfer_partial (struct target_ops *self, enum target_object object,
-			  const char *annex, gdb_byte *readbuf,
-			  const gdb_byte *writebuf,
-			  ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
+enum target_xfer_status
+target_ops_no_register::xfer_partial (enum target_object object,
+				      const char *annex, gdb_byte *readbuf,
+				      const gdb_byte *writebuf,
+				      ULONGEST offset, ULONGEST len,
+				      ULONGEST *xfered_len)
 {
-  auto ops = static_cast<target_ops_no_register *> (self->to_data);
-
-  ops->xfer_partial_called++;
+  this->xfer_partial_called++;
 
   *xfered_len = len;
   return TARGET_XFER_OK;
@@ -1573,7 +1559,7 @@ cooked_read_test (struct gdbarch *gdbarch)
 {
   /* Error out if debugging something, because we're going to push the
      test target, which would pop any existing target.  */
-  if (current_target.to_stratum >= process_stratum)
+  if (target_stack->to_stratum >= process_stratum)
     error (_("target already pushed"));
 
   /* Create a mock environment.  An inferior with a thread, with a
@@ -1747,7 +1733,7 @@ cooked_write_test (struct gdbarch *gdbarch)
 {
   /* Error out if debugging something, because we're going to push the
      test target, which would pop any existing target.  */
-  if (current_target.to_stratum >= process_stratum)
+  if (target_stack->to_stratum >= process_stratum)
     error (_("target already pushed"));
 
   /* Create a mock environment.  A process_stratum target pushed.  */
diff --git a/gdb/remote.c b/gdb/remote.c
index f54a38833b..e6d07a620c 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -4393,7 +4393,7 @@ remote_check_symbols (void)
 	     instead of any data function descriptor.  */
 	  sym_addr = gdbarch_convert_from_func_ptr_addr (target_gdbarch (),
 							 sym_addr,
-							 &current_target);
+							 target_stack);
 
 	  xsnprintf (msg, get_remote_packet_size (), "qSymbol:%s:%s",
 		     phex_nz (sym_addr, addr_size), &reply[8]);
@@ -10791,7 +10791,7 @@ remote_memory_map (struct target_ops *ops)
 {
   std::vector<mem_region> result;
   gdb::optional<gdb::char_vector> text
-    = target_read_stralloc (&current_target, TARGET_OBJECT_MEMORY_MAP, NULL);
+    = target_read_stralloc (target_stack, TARGET_OBJECT_MEMORY_MAP, NULL);
 
   if (text)
     result = parse_memory_map (text->data ());
@@ -12905,7 +12905,7 @@ static traceframe_info_up
 remote_traceframe_info (struct target_ops *self)
 {
   gdb::optional<gdb::char_vector> text
-    = target_read_stralloc (&current_target, TARGET_OBJECT_TRACEFRAME_INFO,
+    = target_read_stralloc (target_stack, TARGET_OBJECT_TRACEFRAME_INFO,
 			    NULL);
   if (text)
     return parse_traceframe_info (text->data ());
@@ -13137,7 +13137,7 @@ static void
 btrace_read_config (struct btrace_config *conf)
 {
   gdb::optional<gdb::char_vector> xml
-    = target_read_stralloc (&current_target, TARGET_OBJECT_BTRACE_CONF, "");
+    = target_read_stralloc (target_stack, TARGET_OBJECT_BTRACE_CONF, "");
   if (xml)
     parse_xml_btrace_conf (conf, xml->data ());
 }
@@ -13337,7 +13337,7 @@ remote_read_btrace (struct target_ops *self,
     }
 
   gdb::optional<gdb::char_vector> xml
-    = target_read_stralloc (&current_target, TARGET_OBJECT_BTRACE, annex);
+    = target_read_stralloc (target_stack, TARGET_OBJECT_BTRACE, annex);
   if (!xml)
     return BTRACE_ERR_UNKNOWN;
 
@@ -13395,7 +13395,7 @@ remote_pid_to_exec_file (struct target_ops *self, int pid)
       xsnprintf (annex, annex_size, "%x", pid);
     }
 
-  filename = target_read_stralloc (&current_target,
+  filename = target_read_stralloc (target_stack,
 				   TARGET_OBJECT_EXEC_FILE, annex);
 
   return filename ? filename->data () : nullptr;
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index 37cbcb672b..425c41df24 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -4885,7 +4885,7 @@ ppc_process_record_op31 (struct gdbarch *gdbarch, struct regcache *regcache,
       return 0;
 
     case 1014:		/* Data Cache Block set to Zero */
-      if (target_auxv_search (&current_target, AT_DCACHEBSIZE, &at_dcsz) <= 0
+      if (target_auxv_search (target_stack, AT_DCACHEBSIZE, &at_dcsz) <= 0
 	  || at_dcsz == 0)
 	at_dcsz = 128; /* Assume 128-byte cache line size (POWER8)  */
 
diff --git a/gdb/s390-linux-nat.c b/gdb/s390-linux-nat.c
index 14086faaa0..cc5e33340e 100644
--- a/gdb/s390-linux-nat.c
+++ b/gdb/s390-linux-nat.c
@@ -988,7 +988,7 @@ s390_read_description (struct target_ops *ops)
   {
     CORE_ADDR hwcap = 0;
 
-    target_auxv_search (&current_target, AT_HWCAP, &hwcap);
+    target_auxv_search (target_stack, AT_HWCAP, &hwcap);
     have_regset_tdb = (hwcap & HWCAP_S390_TE)
       && check_regset (tid, NT_S390_TDB, s390_sizeof_tdbregset);
 
diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c
index 408bb875d2..227c70909e 100644
--- a/gdb/s390-tdep.c
+++ b/gdb/s390-tdep.c
@@ -661,7 +661,7 @@ s390_load (struct s390_prologue_data *data,
   if (pv_is_constant (addr))
     {
       struct target_section *secp;
-      secp = target_section_by_addr (&current_target, addr.k);
+      secp = target_section_by_addr (target_stack, addr.k);
       if (secp != NULL
 	  && (bfd_get_section_flags (secp->the_bfd_section->owner,
 				     secp->the_bfd_section)
diff --git a/gdb/solib-aix.c b/gdb/solib-aix.c
index 608a702a9c..f3dfdb577c 100644
--- a/gdb/solib-aix.c
+++ b/gdb/solib-aix.c
@@ -280,7 +280,7 @@ solib_aix_get_library_list (struct inferior *inf, const char *warning_msg)
     return data->library_list;
 
   gdb::optional<gdb::char_vector> library_document
-    = target_read_stralloc (&current_target, TARGET_OBJECT_LIBRARIES_AIX,
+    = target_read_stralloc (target_stack, TARGET_OBJECT_LIBRARIES_AIX,
 			    NULL);
   if (!library_document && warning_msg != NULL)
     {
diff --git a/gdb/solib-darwin.c b/gdb/solib-darwin.c
index d66938fb90..557fb156b2 100644
--- a/gdb/solib-darwin.c
+++ b/gdb/solib-darwin.c
@@ -497,7 +497,7 @@ darwin_solib_read_all_image_info_addr (struct darwin_info *info)
   if (TYPE_LENGTH (ptr_type) > sizeof (buf))
     return;
 
-  len = target_read (&current_target, TARGET_OBJECT_DARWIN_DYLD_INFO, NULL,
+  len = target_read (target_stack, TARGET_OBJECT_DARWIN_DYLD_INFO, NULL,
 		     buf, 0, TYPE_LENGTH (ptr_type));
   if (len <= 0)
     return;
diff --git a/gdb/solib-dsbt.c b/gdb/solib-dsbt.c
index 7a9b75480a..9868606249 100644
--- a/gdb/solib-dsbt.c
+++ b/gdb/solib-dsbt.c
@@ -293,7 +293,7 @@ dsbt_get_initial_loadmaps (void)
 {
   struct dsbt_info *info = get_dsbt_info ();
   gdb::optional<gdb::byte_vector> buf
-    = target_read_alloc (&current_target, TARGET_OBJECT_FDPIC, "exec");
+    = target_read_alloc (target_stack, TARGET_OBJECT_FDPIC, "exec");
 
   if (!buf || buf->empty ())
     {
@@ -304,7 +304,7 @@ dsbt_get_initial_loadmaps (void)
   if (solib_dsbt_debug)
     dsbt_print_loadmap (info->exec_loadmap);
 
-  buf = target_read_alloc (&current_target, TARGET_OBJECT_FDPIC, "exec");
+  buf = target_read_alloc (target_stack, TARGET_OBJECT_FDPIC, "exec");
   if (!buf || buf->empty ())
     {
       info->interp_loadmap = NULL;
diff --git a/gdb/solib-spu.c b/gdb/solib-spu.c
index cb735fd451..a0fe8965bf 100644
--- a/gdb/solib-spu.c
+++ b/gdb/solib-spu.c
@@ -171,7 +171,7 @@ spu_current_sos (void)
     ;
 
   /* Determine list of SPU ids.  */
-  size = target_read (&current_target, TARGET_OBJECT_SPU, NULL,
+  size = target_read (target_stack, TARGET_OBJECT_SPU, NULL,
 		      buf, 0, sizeof buf);
 
   /* Do not add stand-alone SPE executable context as shared library,
@@ -206,7 +206,7 @@ spu_current_sos (void)
 	 already created the SPE context, but not installed the object-id
 	 yet.  Skip such entries; we'll be back for them later.  */
       xsnprintf (annex, sizeof annex, "%d/object-id", fd);
-      len = target_read (&current_target, TARGET_OBJECT_SPU, annex,
+      len = target_read (target_stack, TARGET_OBJECT_SPU, annex,
 			 (gdb_byte *) id, 0, sizeof id);
       if (len <= 0 || len >= sizeof id)
 	continue;
@@ -418,7 +418,7 @@ spu_enable_break (struct objfile *objfile)
       CORE_ADDR addr = BMSYMBOL_VALUE_ADDRESS (spe_event_sym);
 
       addr = gdbarch_convert_from_func_ptr_addr (target_gdbarch (), addr,
-                                                 &current_target);
+						 target_stack);
       create_solib_event_breakpoint (target_gdbarch (), addr);
       return 1;
     }
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index 3b0af668bd..f9936b36de 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -432,11 +432,11 @@ read_program_header (int type, int *p_sect_size, int *p_arch_size,
   int pt_phdr_p = 0;
 
   /* Get required auxv elements from target.  */
-  if (target_auxv_search (&current_target, AT_PHDR, &at_phdr) <= 0)
+  if (target_auxv_search (target_stack, AT_PHDR, &at_phdr) <= 0)
     return 0;
-  if (target_auxv_search (&current_target, AT_PHENT, &at_phent) <= 0)
+  if (target_auxv_search (target_stack, AT_PHENT, &at_phent) <= 0)
     return 0;
-  if (target_auxv_search (&current_target, AT_PHNUM, &at_phnum) <= 0)
+  if (target_auxv_search (target_stack, AT_PHNUM, &at_phnum) <= 0)
     return 0;
   if (!at_phdr || !at_phnum)
     return 0;
@@ -1244,7 +1244,7 @@ svr4_current_sos_via_xfer_libraries (struct svr4_library_list *list,
 
   /* Fetch the list of shared libraries.  */
   gdb::optional<gdb::char_vector> svr4_library_document
-    = target_read_stralloc (&current_target, TARGET_OBJECT_LIBRARIES_SVR4,
+    = target_read_stralloc (target_stack, TARGET_OBJECT_LIBRARIES_SVR4,
 			    annex);
   if (!svr4_library_document)
     return 0;
@@ -2219,7 +2219,7 @@ enable_break (struct svr4_info *info, int from_tty)
       sym_addr = gdbarch_addr_bits_remove
 	(target_gdbarch (), gdbarch_convert_from_func_ptr_addr (target_gdbarch (),
 							     sym_addr,
-							     &current_target));
+							     target_stack));
 
       /* On at least some versions of Solaris there's a dynamic relocation
 	 on _r_debug.r_brk and SYM_ADDR may not be relocated yet, e.g., if
@@ -2334,7 +2334,7 @@ enable_break (struct svr4_info *info, int from_tty)
       /* If we were not able to find the base address of the loader
          from our so_list, then try using the AT_BASE auxilliary entry.  */
       if (!load_addr_found)
-        if (target_auxv_search (&current_target, AT_BASE, &load_addr) > 0)
+	if (target_auxv_search (target_stack, AT_BASE, &load_addr) > 0)
 	  {
 	    int addr_bit = gdbarch_addr_bit (target_gdbarch ());
 
@@ -2459,7 +2459,7 @@ enable_break (struct svr4_info *info, int from_tty)
 	  sym_addr = BMSYMBOL_VALUE_ADDRESS (msymbol);
 	  sym_addr = gdbarch_convert_from_func_ptr_addr (target_gdbarch (),
 							 sym_addr,
-							 &current_target);
+							 target_stack);
 	  svr4_create_solib_event_breakpoints (target_gdbarch (), sym_addr);
 	  return 1;
 	}
@@ -2476,7 +2476,7 @@ enable_break (struct svr4_info *info, int from_tty)
 	      sym_addr = BMSYMBOL_VALUE_ADDRESS (msymbol);
 	      sym_addr = gdbarch_convert_from_func_ptr_addr (target_gdbarch (),
 							     sym_addr,
-							     &current_target);
+							     target_stack);
 	      svr4_create_solib_event_breakpoints (target_gdbarch (), sym_addr);
 	      return 1;
 	    }
@@ -2571,7 +2571,7 @@ svr4_exec_displacement (CORE_ADDR *displacementp)
   if ((bfd_get_file_flags (exec_bfd) & DYNAMIC) == 0)
     return 0;
 
-  if (target_auxv_search (&current_target, AT_ENTRY, &entry_point) <= 0)
+  if (target_auxv_search (target_stack, AT_ENTRY, &entry_point) <= 0)
     return 0;
 
   exec_displacement = entry_point - bfd_get_start_address (exec_bfd);
diff --git a/gdb/solib-target.c b/gdb/solib-target.c
index 7f96e80e1b..adbab7ea32 100644
--- a/gdb/solib-target.c
+++ b/gdb/solib-target.c
@@ -258,7 +258,7 @@ solib_target_current_sos (void)
 
   /* Fetch the list of shared libraries.  */
   gdb::optional<gdb::char_vector> library_document
-    = target_read_stralloc (&current_target, TARGET_OBJECT_LIBRARIES, NULL);
+    = target_read_stralloc (target_stack, TARGET_OBJECT_LIBRARIES, NULL);
   if (!library_document)
     return NULL;
 
diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c
index 633bd685bc..a4d5a7b27b 100644
--- a/gdb/sparc-tdep.c
+++ b/gdb/sparc-tdep.c
@@ -189,7 +189,7 @@ ULONGEST
 sparc_fetch_wcookie (struct gdbarch *gdbarch)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-  struct target_ops *ops = &current_target;
+  struct target_ops *ops = target_stack;
   gdb_byte buf[8];
   int len;
 
diff --git a/gdb/sparc64-tdep.c b/gdb/sparc64-tdep.c
index 6f3ca198b3..9fd6a66199 100644
--- a/gdb/sparc64-tdep.c
+++ b/gdb/sparc64-tdep.c
@@ -222,10 +222,10 @@ adi_available (void)
     return proc->stat.is_avail;
 
   proc->stat.checked_avail = true;
-  if (target_auxv_search (&current_target, AT_ADI_BLKSZ, &value) <= 0)
+  if (target_auxv_search (target_stack, AT_ADI_BLKSZ, &value) <= 0)
     return false;
   proc->stat.blksize = value;
-  target_auxv_search (&current_target, AT_ADI_NBITS, &value);
+  target_auxv_search (target_stack, AT_ADI_NBITS, &value);
   proc->stat.nbits = value;
   proc->stat.max_version = (1 << proc->stat.nbits) - 2;
   proc->stat.is_avail = true;
diff --git a/gdb/spu-tdep.c b/gdb/spu-tdep.c
index 783ef5b247..60b04aed73 100644
--- a/gdb/spu-tdep.c
+++ b/gdb/spu-tdep.c
@@ -198,7 +198,7 @@ spu_pseudo_register_read_spu (readable_regcache *regcache, const char *regname,
     return status;
   xsnprintf (annex, sizeof annex, "%d/%s", (int) id, regname);
   memset (reg, 0, sizeof reg);
-  target_read (&current_target, TARGET_OBJECT_SPU, annex,
+  target_read (target_stack, TARGET_OBJECT_SPU, annex,
 	       reg, 0, sizeof reg);
 
   ul = strtoulst ((char *) reg, NULL, 16);
@@ -229,7 +229,7 @@ spu_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache,
       if (status != REG_VALID)
 	return status;
       xsnprintf (annex, sizeof annex, "%d/fpcr", (int) id);
-      target_read (&current_target, TARGET_OBJECT_SPU, annex, buf, 0, 16);
+      target_read (target_stack, TARGET_OBJECT_SPU, annex, buf, 0, 16);
       return status;
 
     case SPU_SRR0_REGNUM:
@@ -263,7 +263,7 @@ spu_pseudo_register_write_spu (struct regcache *regcache, const char *regname,
   xsnprintf (annex, sizeof annex, "%d/%s", (int) id, regname);
   xsnprintf (reg, sizeof reg, "0x%s",
 	     phex_nz (extract_unsigned_integer (buf, 4, byte_order), 4));
-  target_write (&current_target, TARGET_OBJECT_SPU, annex,
+  target_write (target_stack, TARGET_OBJECT_SPU, annex,
 		(gdb_byte *) reg, 0, strlen (reg));
 }
 
@@ -286,7 +286,7 @@ spu_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
     case SPU_FPSCR_REGNUM:
       regcache_raw_read_unsigned (regcache, SPU_ID_REGNUM, &id);
       xsnprintf (annex, sizeof annex, "%d/fpcr", (int) id);
-      target_write (&current_target, TARGET_OBJECT_SPU, annex, buf, 0, 16);
+      target_write (target_stack, TARGET_OBJECT_SPU, annex, buf, 0, 16);
       break;
 
     case SPU_SRR0_REGNUM:
@@ -2079,7 +2079,7 @@ info_spu_event_command (const char *args, int from_tty)
   id = get_frame_register_unsigned (frame, SPU_ID_REGNUM);
 
   xsnprintf (annex, sizeof annex, "%d/event_status", id);
-  len = target_read (&current_target, TARGET_OBJECT_SPU, annex,
+  len = target_read (target_stack, TARGET_OBJECT_SPU, annex,
 		     buf, 0, (sizeof (buf) - 1));
   if (len <= 0)
     error (_("Could not read event_status."));
@@ -2087,7 +2087,7 @@ info_spu_event_command (const char *args, int from_tty)
   event_status = strtoulst ((char *) buf, NULL, 16);
  
   xsnprintf (annex, sizeof annex, "%d/event_mask", id);
-  len = target_read (&current_target, TARGET_OBJECT_SPU, annex,
+  len = target_read (target_stack, TARGET_OBJECT_SPU, annex,
 		     buf, 0, (sizeof (buf) - 1));
   if (len <= 0)
     error (_("Could not read event_mask."));
@@ -2133,7 +2133,7 @@ info_spu_signal_command (const char *args, int from_tty)
   id = get_frame_register_unsigned (frame, SPU_ID_REGNUM);
 
   xsnprintf (annex, sizeof annex, "%d/signal1", id);
-  len = target_read (&current_target, TARGET_OBJECT_SPU, annex, buf, 0, 4);
+  len = target_read (target_stack, TARGET_OBJECT_SPU, annex, buf, 0, 4);
   if (len < 0)
     error (_("Could not read signal1."));
   else if (len == 4)
@@ -2143,7 +2143,7 @@ info_spu_signal_command (const char *args, int from_tty)
     }
     
   xsnprintf (annex, sizeof annex, "%d/signal1_type", id);
-  len = target_read (&current_target, TARGET_OBJECT_SPU, annex,
+  len = target_read (target_stack, TARGET_OBJECT_SPU, annex,
 		     buf, 0, (sizeof (buf) - 1));
   if (len <= 0)
     error (_("Could not read signal1_type."));
@@ -2151,7 +2151,7 @@ info_spu_signal_command (const char *args, int from_tty)
   signal1_type = strtoulst ((char *) buf, NULL, 16);
 
   xsnprintf (annex, sizeof annex, "%d/signal2", id);
-  len = target_read (&current_target, TARGET_OBJECT_SPU, annex, buf, 0, 4);
+  len = target_read (target_stack, TARGET_OBJECT_SPU, annex, buf, 0, 4);
   if (len < 0)
     error (_("Could not read signal2."));
   else if (len == 4)
@@ -2161,7 +2161,7 @@ info_spu_signal_command (const char *args, int from_tty)
     }
     
   xsnprintf (annex, sizeof annex, "%d/signal2_type", id);
-  len = target_read (&current_target, TARGET_OBJECT_SPU, annex,
+  len = target_read (target_stack, TARGET_OBJECT_SPU, annex,
 		     buf, 0, (sizeof (buf) - 1));
   if (len <= 0)
     error (_("Could not read signal2_type."));
@@ -2250,7 +2250,7 @@ info_spu_mailbox_command (const char *args, int from_tty)
   ui_out_emit_tuple tuple_emitter (current_uiout, "SPUInfoMailbox");
 
   xsnprintf (annex, sizeof annex, "%d/mbox_info", id);
-  len = target_read (&current_target, TARGET_OBJECT_SPU, annex,
+  len = target_read (target_stack, TARGET_OBJECT_SPU, annex,
 		     buf, 0, sizeof buf);
   if (len < 0)
     error (_("Could not read mbox_info."));
@@ -2259,7 +2259,7 @@ info_spu_mailbox_command (const char *args, int from_tty)
 			 "mbox", "SPU Outbound Mailbox");
 
   xsnprintf (annex, sizeof annex, "%d/ibox_info", id);
-  len = target_read (&current_target, TARGET_OBJECT_SPU, annex,
+  len = target_read (target_stack, TARGET_OBJECT_SPU, annex,
 		     buf, 0, sizeof buf);
   if (len < 0)
     error (_("Could not read ibox_info."));
@@ -2268,7 +2268,7 @@ info_spu_mailbox_command (const char *args, int from_tty)
 			 "ibox", "SPU Outbound Interrupt Mailbox");
 
   xsnprintf (annex, sizeof annex, "%d/wbox_info", id);
-  len = target_read (&current_target, TARGET_OBJECT_SPU, annex,
+  len = target_read (target_stack, TARGET_OBJECT_SPU, annex,
 		     buf, 0, sizeof buf);
   if (len < 0)
     error (_("Could not read wbox_info."));
@@ -2481,7 +2481,7 @@ info_spu_dma_command (const char *args, int from_tty)
   id = get_frame_register_unsigned (frame, SPU_ID_REGNUM);
 
   xsnprintf (annex, sizeof annex, "%d/dma_info", id);
-  len = target_read (&current_target, TARGET_OBJECT_SPU, annex,
+  len = target_read (target_stack, TARGET_OBJECT_SPU, annex,
 		     buf, 0, 40 + 16 * 32);
   if (len <= 0)
     error (_("Could not read dma_info."));
@@ -2558,7 +2558,7 @@ info_spu_proxydma_command (const char *args, int from_tty)
   id = get_frame_register_unsigned (frame, SPU_ID_REGNUM);
 
   xsnprintf (annex, sizeof annex, "%d/proxydma_info", id);
-  len = target_read (&current_target, TARGET_OBJECT_SPU, annex,
+  len = target_read (target_stack, TARGET_OBJECT_SPU, annex,
 		     buf, 0, 24 + 8 * 32);
   if (len <= 0)
     error (_("Could not read proxydma_info."));
diff --git a/gdb/symfile.c b/gdb/symfile.c
index 1e5297ee29..1122db672e 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -863,7 +863,7 @@ init_entry_point_info (struct objfile *objfile)
       entry_point
 	= gdbarch_convert_from_func_ptr_addr (get_objfile_arch (objfile),
 					      entry_point,
-					      &current_target);
+					      target_stack);
 
       /* Remove any ISA markers, so that this matches entries in the
 	 symbol table.  */
diff --git a/gdb/target-debug.h b/gdb/target-debug.h
index 233e4baf19..5f3001b89f 100644
--- a/gdb/target-debug.h
+++ b/gdb/target-debug.h
@@ -176,6 +176,12 @@
   target_debug_do_print (host_address_to_string (inf))
 #define target_debug_print_record_print_flags(X) \
   target_debug_do_print (plongest (X))
+#define target_debug_print_enum_info_proc_what(X) \
+  target_debug_do_print (plongest (X))
+#define target_debug_print_thread_control_capabilities(X) \
+  target_debug_do_print (plongest (X))
+#define target_debug_print_thread_info_p(X)	\
+  target_debug_do_print (host_address_to_string (X))
 
 static void
 target_debug_print_struct_target_waitstatus_p (struct target_waitstatus *status)
diff --git a/gdb/target-descriptions.c b/gdb/target-descriptions.c
index 5d34e29a86..a5c9c6b67d 100644
--- a/gdb/target-descriptions.c
+++ b/gdb/target-descriptions.c
@@ -833,11 +833,11 @@ target_find_description (void)
   /* Next try to read the description from the current target using
      target objects.  */
   if (current_target_desc == NULL)
-    current_target_desc = target_read_description_xml (&current_target);
+    current_target_desc = target_read_description_xml (target_stack);
 
   /* If that failed try a target-specific hook.  */
   if (current_target_desc == NULL)
-    current_target_desc = target_read_description (&current_target);
+    current_target_desc = target_read_description (target_stack);
 
   /* If a non-NULL description was returned, then update the current
      architecture.  */
diff --git a/gdb/target-memory.c b/gdb/target-memory.c
index 395bf0bae9..8db64d7284 100644
--- a/gdb/target-memory.c
+++ b/gdb/target-memory.c
@@ -338,7 +338,7 @@ target_write_memory_blocks (const std::vector<memory_write_request> &requests,
     {
       LONGEST len;
 
-      len = target_write_with_progress (current_target.beneath,
+      len = target_write_with_progress (target_stack,
 					TARGET_OBJECT_MEMORY, NULL,
 					iter.data, iter.begin,
 					iter.end - iter.begin,
@@ -361,7 +361,7 @@ target_write_memory_blocks (const std::vector<memory_write_request> &requests,
 	{
 	  LONGEST len;
 
-	  len = target_write_with_progress (&current_target,
+	  len = target_write_with_progress (target_stack,
 					    TARGET_OBJECT_FLASH, NULL,
 					    iter.data, iter.begin,
 					    iter.end - iter.begin,
diff --git a/gdb/target.c b/gdb/target.c
index 2ff028cfa8..022da5919a 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -86,10 +86,6 @@ static struct address_space *default_thread_address_space
 
 static void tcomplain (void) ATTRIBUTE_NORETURN;
 
-static int return_zero (struct target_ops *);
-
-static int return_zero_has_execution (struct target_ops *, ptid_t);
-
 static struct target_ops *find_default_run_target (const char *);
 
 static struct gdbarch *default_thread_architecture (struct target_ops *ops,
@@ -107,14 +103,6 @@ static const char *default_pid_to_str (struct target_ops *ops, ptid_t ptid);
 static enum exec_direction_kind default_execution_direction
     (struct target_ops *self);
 
-static struct target_ops debug_target;
-
-#include "target-delegates.c"
-
-static void init_dummy_target (void);
-
-static void update_current_target (void);
-
 /* Vector of existing target structures. */
 typedef struct target_ops *target_ops_p;
 DEF_VEC_P (target_ops_p);
@@ -123,16 +111,14 @@ static VEC (target_ops_p) *target_structs;
 /* The initial current target, so that there is always a semi-valid
    current target.  */
 
-static struct target_ops dummy_target;
+static struct target_ops *the_dummy_target;
+static struct target_ops *the_debug_target;
 
 /* Top of target stack.  */
-
-static struct target_ops *target_stack;
-
 /* The target structure we are currently using to talk to a process
    or file or whatever "inferior" we have.  */
 
-struct target_ops current_target;
+struct target_ops *target_stack;
 
 /* Command list for target.  */
 
@@ -171,7 +157,10 @@ static unsigned int targetdebug = 0;
 static void
 set_targetdebug  (const char *args, int from_tty, struct cmd_list_element *c)
 {
-  update_current_target ();
+  if (targetdebug)
+    push_target (the_debug_target);
+  else
+    unpush_target (the_debug_target);
 }
 
 static void
@@ -181,8 +170,6 @@ show_targetdebug (struct ui_file *file, int from_tty,
   fprintf_filtered (file, _("Target debugging is %s.\n"), value);
 }
 
-static void setup_target_debug (void);
-
 /* The user just typed 'target' without the name of a target.  */
 
 static void
@@ -195,7 +182,7 @@ target_command (const char *arg, int from_tty)
 /* Default target_has_* methods for process_stratum targets.  */
 
 int
-default_child_has_all_memory (struct target_ops *ops)
+default_child_has_all_memory ()
 {
   /* If no inferior selected, then we can't read memory here.  */
   if (ptid_equal (inferior_ptid, null_ptid))
@@ -205,7 +192,7 @@ default_child_has_all_memory (struct target_ops *ops)
 }
 
 int
-default_child_has_memory (struct target_ops *ops)
+default_child_has_memory ()
 {
   /* If no inferior selected, then we can't read memory here.  */
   if (ptid_equal (inferior_ptid, null_ptid))
@@ -215,7 +202,7 @@ default_child_has_memory (struct target_ops *ops)
 }
 
 int
-default_child_has_stack (struct target_ops *ops)
+default_child_has_stack ()
 {
   /* If no inferior selected, there's no stack.  */
   if (ptid_equal (inferior_ptid, null_ptid))
@@ -225,7 +212,7 @@ default_child_has_stack (struct target_ops *ops)
 }
 
 int
-default_child_has_registers (struct target_ops *ops)
+default_child_has_registers ()
 {
   /* Can't read registers from no inferior.  */
   if (ptid_equal (inferior_ptid, null_ptid))
@@ -235,7 +222,7 @@ default_child_has_registers (struct target_ops *ops)
 }
 
 int
-default_child_has_execution (struct target_ops *ops, ptid_t the_ptid)
+default_child_has_execution (ptid_t the_ptid)
 {
   /* If there's no thread selected, then we can't make it run through
      hoops.  */
@@ -251,8 +238,8 @@ target_has_all_memory_1 (void)
 {
   struct target_ops *t;
 
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_has_all_memory (t))
+  for (t = target_stack; t != NULL; t = t->beneath)
+    if (t->has_all_memory ())
       return 1;
 
   return 0;
@@ -263,8 +250,8 @@ target_has_memory_1 (void)
 {
   struct target_ops *t;
 
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_has_memory (t))
+  for (t = target_stack; t != NULL; t = t->beneath)
+    if (t->has_memory ())
       return 1;
 
   return 0;
@@ -275,8 +262,8 @@ target_has_stack_1 (void)
 {
   struct target_ops *t;
 
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_has_stack (t))
+  for (t = target_stack; t != NULL; t = t->beneath)
+    if (t->has_stack ())
       return 1;
 
   return 0;
@@ -287,8 +274,8 @@ target_has_registers_1 (void)
 {
   struct target_ops *t;
 
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_has_registers (t))
+  for (t = target_stack; t != NULL; t = t->beneath)
+    if (t->has_registers ())
       return 1;
 
   return 0;
@@ -299,8 +286,8 @@ target_has_execution_1 (ptid_t the_ptid)
 {
   struct target_ops *t;
 
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_has_execution (t, the_ptid))
+  for (t = target_stack; t != NULL; t = t->beneath)
+    if (t->has_execution (the_ptid))
       return 1;
 
   return 0;
@@ -312,38 +299,6 @@ target_has_execution_current (void)
   return target_has_execution_1 (inferior_ptid);
 }
 
-/* Complete initialization of T.  This ensures that various fields in
-   T are set, if needed by the target implementation.  */
-
-void
-complete_target_initialization (struct target_ops *t)
-{
-  /* Provide default values for all "must have" methods.  */
-
-  if (t->to_has_all_memory == NULL)
-    t->to_has_all_memory = return_zero;
-
-  if (t->to_has_memory == NULL)
-    t->to_has_memory = return_zero;
-
-  if (t->to_has_stack == NULL)
-    t->to_has_stack = return_zero;
-
-  if (t->to_has_registers == NULL)
-    t->to_has_registers = return_zero;
-
-  if (t->to_has_execution == NULL)
-    t->to_has_execution = return_zero_has_execution;
-
-  /* These methods can be called on an unpushed target and so require
-     a default implementation if the target might plausibly be the
-     default run target.  */
-  gdb_assert (t->to_can_run == NULL || (t->to_can_async_p != NULL
-					&& t->to_supports_non_stop != NULL));
-
-  install_delegators (t);
-}
-
 /* This is used to implement the various target commands.  */
 
 static void
@@ -353,17 +308,17 @@ open_target (const char *args, int from_tty, struct cmd_list_element *command)
 
   if (targetdebug)
     fprintf_unfiltered (gdb_stdlog, "-> %s->to_open (...)\n",
-			ops->to_shortname);
+			ops->shortname ());
 
-  ops->to_open (args, from_tty);
+  ops->open (args, from_tty);
 
   if (targetdebug)
     fprintf_unfiltered (gdb_stdlog, "<- %s->to_open (%s, %d)\n",
-			ops->to_shortname, args, from_tty);
+			ops->shortname (), args, from_tty);
 }
 
 /* Add possible target architecture T to the list and add a new
-   command 'target T->to_shortname'.  Set COMPLETER as the command's
+   command 'target T->shortname ()'.  Set COMPLETER as the command's
    completer if not NULL.  */
 
 void
@@ -372,8 +327,6 @@ add_target_with_completer (struct target_ops *t,
 {
   struct cmd_list_element *c;
 
-  complete_target_initialization (t);
-
   VEC_safe_push (target_ops_p, target_structs, t);
 
   if (targetlist == NULL)
@@ -384,7 +337,7 @@ Remaining arguments are interpreted by the target protocol.  For more\n\
 information on the arguments for a particular protocol, type\n\
 `help target ' followed by the protocol name."),
 		    &targetlist, "target ", 0, &cmdlist);
-  c = add_cmd (t->to_shortname, no_class, t->to_doc, &targetlist);
+  c = add_cmd (t->shortname (), no_class, t->doc (), &targetlist);
   set_cmd_sfunc (c, open_target);
   set_cmd_context (c, t);
   if (completer != NULL)
@@ -409,10 +362,10 @@ add_deprecated_target_alias (struct target_ops *t, const char *alias)
 
   /* If we use add_alias_cmd, here, we do not get the deprecated warning,
      see PR cli/15104.  */
-  c = add_cmd (alias, no_class, t->to_doc, &targetlist);
+  c = add_cmd (alias, no_class, t->doc (), &targetlist);
   set_cmd_sfunc (c, open_target);
   set_cmd_context (c, t);
-  alt = xstrprintf ("target %s", t->to_shortname);
+  alt = xstrprintf ("target %s", t->shortname ());
   deprecate_cmd (c, alt);
 }
 
@@ -421,14 +374,14 @@ add_deprecated_target_alias (struct target_ops *t, const char *alias)
 void
 target_kill (void)
 {
-  current_target.to_kill (&current_target);
+  target_stack->kill ();
 }
 
 void
 target_load (const char *arg, int from_tty)
 {
   target_dcache_invalidate ();
-  (*current_target.to_load) (&current_target, arg, from_tty);
+  target_stack->load (arg, from_tty);
 }
 
 /* Define it.  */
@@ -441,7 +394,7 @@ target_terminal_state target_terminal::m_terminal_state
 void
 target_terminal::init (void)
 {
-  (*current_target.to_terminal_init) (&current_target);
+  target_stack->terminal_init ();
 
   m_terminal_state = target_terminal_state::is_ours;
 }
@@ -472,7 +425,7 @@ target_terminal::inferior (void)
 
   if (inf->terminal_state != target_terminal_state::is_inferior)
     {
-      (*current_target.to_terminal_inferior) (&current_target);
+      target_stack->terminal_inferior ();
       inf->terminal_state = target_terminal_state::is_inferior;
     }
 
@@ -508,7 +461,7 @@ target_terminal::restore_inferior (void)
 	if (inf->terminal_state == target_terminal_state::is_ours_for_output)
 	  {
 	    set_current_inferior (inf);
-	    (*current_target.to_terminal_inferior) (&current_target);
+	    target_stack->terminal_inferior ();
 	    inf->terminal_state = target_terminal_state::is_inferior;
 	  }
       }
@@ -541,7 +494,7 @@ target_terminal_is_ours_kind (target_terminal_state desired_state)
       if (inf->terminal_state == target_terminal_state::is_inferior)
 	{
 	  set_current_inferior (inf);
-	  (*current_target.to_terminal_save_inferior) (&current_target);
+	  target_stack->terminal_save_inferior ();
 	}
     }
 
@@ -556,9 +509,9 @@ target_terminal_is_ours_kind (target_terminal_state desired_state)
 	{
 	  set_current_inferior (inf);
 	  if (desired_state == target_terminal_state::is_ours)
-	    (*current_target.to_terminal_ours) (&current_target);
+	    target_stack->terminal_ours ();
 	  else if (desired_state == target_terminal_state::is_ours_for_output)
-	    (*current_target.to_terminal_ours_for_output) (&current_target);
+	    target_stack->terminal_ours_for_output ();
 	  else
 	    gdb_assert_not_reached ("unhandled desired state");
 	  inf->terminal_state = desired_state;
@@ -607,7 +560,7 @@ target_terminal::ours_for_output ()
 void
 target_terminal::info (const char *arg, int from_tty)
 {
-  (*current_target.to_terminal_info) (&current_target, arg, from_tty);
+  target_stack->terminal_info (arg, from_tty);
 }
 
 /* See target.h.  */
@@ -615,23 +568,14 @@ target_terminal::info (const char *arg, int from_tty)
 int
 target_supports_terminal_ours (void)
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    {
-      if (t->to_terminal_ours != delegate_terminal_ours
-	  && t->to_terminal_ours != tdefault_terminal_ours)
-	return 1;
-    }
-
-  return 0;
+  return target_stack->supports_terminal_ours ();
 }
 
 static void
 tcomplain (void)
 {
   error (_("You can't do that when your target is `%s'"),
-	 current_target.to_shortname);
+	 target_stack->shortname ());
 }
 
 void
@@ -670,57 +614,6 @@ default_execution_direction (struct target_ops *self)
 to_execution_direction must be implemented for reverse async");
 }
 
-/* Go through the target stack from top to bottom, copying over zero
-   entries in current_target, then filling in still empty entries.  In
-   effect, we are doing class inheritance through the pushed target
-   vectors.
-
-   NOTE: cagney/2003-10-17: The problem with this inheritance, as it
-   is currently implemented, is that it discards any knowledge of
-   which target an inherited method originally belonged to.
-   Consequently, new new target methods should instead explicitly and
-   locally search the target stack for the target that can handle the
-   request.  */
-
-static void
-update_current_target (void)
-{
-  struct target_ops *t;
-
-  /* First, reset current's contents.  */
-  memset (&current_target, 0, sizeof (current_target));
-
-  /* Install the delegators.  */
-  install_delegators (&current_target);
-
-  current_target.to_stratum = target_stack->to_stratum;
-
-#define INHERIT(FIELD, TARGET) \
-      if (!current_target.FIELD) \
-	current_target.FIELD = (TARGET)->FIELD
-
-  /* Do not add any new INHERITs here.  Instead, use the delegation
-     mechanism provided by make-target-delegates.  */
-  for (t = target_stack; t; t = t->beneath)
-    {
-      INHERIT (to_shortname, t);
-      INHERIT (to_longname, t);
-      INHERIT (to_attach_no_wait, t);
-      INHERIT (to_have_steppable_watchpoint, t);
-      INHERIT (to_have_continuable_watchpoint, t);
-      INHERIT (to_has_thread_control, t);
-    }
-#undef INHERIT
-
-  /* Finally, position the target-stack beneath the squashed
-     "current_target".  That way code looking for a non-inherited
-     target method can quickly and simply find it.  */
-  current_target.beneath = target_stack;
-
-  if (targetdebug)
-    setup_target_debug ();
-}
-
 /* Push a new target type into the stack of the existing target accessors,
    possibly superseding some of the existing accessors.
 
@@ -733,17 +626,6 @@ push_target (struct target_ops *t)
 {
   struct target_ops **cur;
 
-  /* Check magic number.  If wrong, it probably means someone changed
-     the struct definition, but not all the places that initialize one.  */
-  if (t->to_magic != OPS_MAGIC)
-    {
-      fprintf_unfiltered (gdb_stderr,
-			  "Magic number of %s target struct wrong\n",
-			  t->to_shortname);
-      internal_error (__FILE__, __LINE__,
-		      _("failed internal consistency check"));
-    }
-
   /* Find the proper stratum to install this target in.  */
   for (cur = &target_stack; (*cur) != NULL; cur = &(*cur)->beneath)
     {
@@ -768,8 +650,6 @@ push_target (struct target_ops *t)
   /* We have removed all targets in our stratum, now add the new one.  */
   t->beneath = (*cur);
   (*cur) = t;
-
-  update_current_target ();
 }
 
 /* Remove a target_ops vector from the stack, wherever it may be.
@@ -804,8 +684,6 @@ unpush_target (struct target_ops *t)
   (*cur) = (*cur)->beneath;
   tmp->beneath = NULL;
 
-  update_current_target ();
-
   /* Finally close the target.  Note we do this after unchaining, so
      any target method calls from within the target_close
      implementation don't end up in T anymore.  */
@@ -823,7 +701,7 @@ unpush_target_and_assert (struct target_ops *target)
     {
       fprintf_unfiltered (gdb_stderr,
 			  "pop_all_targets couldn't find target %s\n",
-			  target->to_shortname);
+			  target->shortname ());
       internal_error (__FILE__, __LINE__,
 		      _("failed internal consistency check"));
     }
@@ -832,7 +710,7 @@ unpush_target_and_assert (struct target_ops *target)
 void
 pop_all_targets_above (enum strata above_stratum)
 {
-  while ((int) (current_target.to_stratum) > (int) above_stratum)
+  while ((int) (target_stack->to_stratum) > (int) above_stratum)
     unpush_target_and_assert (target_stack);
 }
 
@@ -841,7 +719,7 @@ pop_all_targets_above (enum strata above_stratum)
 void
 pop_all_targets_at_and_above (enum strata stratum)
 {
-  while ((int) (current_target.to_stratum) >= (int) stratum)
+  while ((int) (target_stack->to_stratum) >= (int) stratum)
     unpush_target_and_assert (target_stack);
 }
 
@@ -858,17 +736,6 @@ target_is_pushed (struct target_ops *t)
 {
   struct target_ops *cur;
 
-  /* Check magic number.  If wrong, it probably means someone changed
-     the struct definition, but not all the places that initialize one.  */
-  if (t->to_magic != OPS_MAGIC)
-    {
-      fprintf_unfiltered (gdb_stderr,
-			  "Magic number of %s target struct wrong\n",
-			  t->to_shortname);
-      internal_error (__FILE__, __LINE__,
-		      _("failed internal consistency check"));
-    }
-
   for (cur = target_stack; cur != NULL; cur = cur->beneath)
     if (cur == t)
       return 1;
@@ -891,7 +758,7 @@ CORE_ADDR
 target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset)
 {
   volatile CORE_ADDR addr = 0;
-  struct target_ops *target = &current_target;
+  struct target_ops *target = target_stack;
 
   if (gdbarch_fetch_tls_load_module_address_p (target_gdbarch ()))
     {
@@ -905,8 +772,7 @@ target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset)
 	  lm_addr = gdbarch_fetch_tls_load_module_address (target_gdbarch (),
 	                                                   objfile);
 
-	  addr = target->to_get_thread_local_address (target, ptid,
-						      lm_addr, offset);
+	  addr = target->get_thread_local_address (ptid, lm_addr, offset);
 	}
       /* If an error occurred, print TLS related messages here.  Otherwise,
          throw the error to some higher catcher.  */
@@ -1064,7 +930,7 @@ done:
 struct target_section_table *
 target_get_section_table (struct target_ops *target)
 {
-  return (*target->to_get_section_table) (target);
+  return target->get_section_table ();
 }
 
 /* Find a section containing ADDR.  */
@@ -1152,9 +1018,9 @@ raw_memory_xfer_partial (struct target_ops *ops, gdb_byte *readbuf,
 
   do
     {
-      res = ops->to_xfer_partial (ops, TARGET_OBJECT_MEMORY, NULL,
-				  readbuf, writebuf, memaddr, len,
-				  xfered_len);
+      res = ops->xfer_partial (TARGET_OBJECT_MEMORY, NULL,
+			       readbuf, writebuf, memaddr, len,
+			       xfered_len);
       if (res == TARGET_XFER_OK)
 	break;
 
@@ -1164,7 +1030,7 @@ raw_memory_xfer_partial (struct target_ops *ops, gdb_byte *readbuf,
 
       /* We want to continue past core files to executables, but not
 	 past a running target's memory.  */
-      if (ops->to_has_all_memory (ops))
+      if (ops->has_all_memory ())
 	break;
 
       ops = ops->beneath;
@@ -1326,7 +1192,7 @@ memory_xfer_partial (struct target_ops *ops, enum target_object object,
 	 shadow handling even though we only end up writing a small
 	 subset of it.  Cap writes to a limit specified by the target
 	 to mitigate this.  */
-      len = std::min (ops->to_get_memory_xfer_limit (ops), len);
+      len = std::min (ops->get_memory_xfer_limit (), len);
 
       gdb::byte_vector buf (writebuf, writebuf + len);
       breakpoint_xfer_memory (NULL, buf.data (), writebuf, memaddr, len);
@@ -1354,8 +1220,6 @@ target_xfer_partial (struct target_ops *ops,
 {
   enum target_xfer_status retval;
 
-  gdb_assert (ops->to_xfer_partial != NULL);
-
   /* Transfer is done when LEN is zero.  */
   if (len == 0)
     return TARGET_XFER_EOF;
@@ -1390,8 +1254,8 @@ target_xfer_partial (struct target_ops *ops,
 					xfered_len);
     }
   else
-    retval = ops->to_xfer_partial (ops, object, annex, readbuf,
-				   writebuf, offset, len, xfered_len);
+    retval = ops->xfer_partial (object, annex, readbuf,
+				writebuf, offset, len, xfered_len);
 
   if (targetdebug)
     {
@@ -1400,7 +1264,7 @@ target_xfer_partial (struct target_ops *ops,
       fprintf_unfiltered (gdb_stdlog,
 			  "%s:target_xfer_partial "
 			  "(%d, %s, %s, %s, %s, %s) = %d, %s",
-			  ops->to_shortname,
+			  ops->shortname (),
 			  (int) object,
 			  (annex ? annex : "(null)"),
 			  host_address_to_string (readbuf),
@@ -1460,10 +1324,7 @@ target_xfer_partial (struct target_ops *ops,
 int
 target_read_memory (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
 {
-  /* Dispatch to the topmost target, not the flattened current_target.
-     Memory accesses check target->to_has_(all_)memory, and the
-     flattened target doesn't inherit those.  */
-  if (target_read (current_target.beneath, TARGET_OBJECT_MEMORY, NULL,
+  if (target_read (target_stack, TARGET_OBJECT_MEMORY, NULL,
 		   myaddr, memaddr, len) == len)
     return 0;
   else
@@ -1493,9 +1354,7 @@ target_read_uint32 (CORE_ADDR memaddr, uint32_t *result)
 int
 target_read_raw_memory (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
 {
-  /* See comment in target_read_memory about why the request starts at
-     current_target.beneath.  */
-  if (target_read (current_target.beneath, TARGET_OBJECT_RAW_MEMORY, NULL,
+  if (target_read (target_stack, TARGET_OBJECT_RAW_MEMORY, NULL,
 		   myaddr, memaddr, len) == len)
     return 0;
   else
@@ -1508,9 +1367,7 @@ target_read_raw_memory (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
 int
 target_read_stack (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
 {
-  /* See comment in target_read_memory about why the request starts at
-     current_target.beneath.  */
-  if (target_read (current_target.beneath, TARGET_OBJECT_STACK_MEMORY, NULL,
+  if (target_read (target_stack, TARGET_OBJECT_STACK_MEMORY, NULL,
 		   myaddr, memaddr, len) == len)
     return 0;
   else
@@ -1523,9 +1380,7 @@ target_read_stack (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
 int
 target_read_code (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
 {
-  /* See comment in target_read_memory about why the request starts at
-     current_target.beneath.  */
-  if (target_read (current_target.beneath, TARGET_OBJECT_CODE_MEMORY, NULL,
+  if (target_read (target_stack, TARGET_OBJECT_CODE_MEMORY, NULL,
 		   myaddr, memaddr, len) == len)
     return 0;
   else
@@ -1541,9 +1396,7 @@ target_read_code (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
 int
 target_write_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, ssize_t len)
 {
-  /* See comment in target_read_memory about why the request starts at
-     current_target.beneath.  */
-  if (target_write (current_target.beneath, TARGET_OBJECT_MEMORY, NULL,
+  if (target_write (target_stack, TARGET_OBJECT_MEMORY, NULL,
 		    myaddr, memaddr, len) == len)
     return 0;
   else
@@ -1559,9 +1412,7 @@ target_write_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, ssize_t len)
 int
 target_write_raw_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, ssize_t len)
 {
-  /* See comment in target_read_memory about why the request starts at
-     current_target.beneath.  */
-  if (target_write (current_target.beneath, TARGET_OBJECT_RAW_MEMORY, NULL,
+  if (target_write (target_stack, TARGET_OBJECT_RAW_MEMORY, NULL,
 		    myaddr, memaddr, len) == len)
     return 0;
   else
@@ -1573,8 +1424,7 @@ target_write_raw_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, ssize_t len)
 std::vector<mem_region>
 target_memory_map (void)
 {
-  std::vector<mem_region> result
-    = current_target.to_memory_map (&current_target);
+  std::vector<mem_region> result = target_stack->memory_map ();
   if (result.empty ())
     return result;
 
@@ -1604,13 +1454,13 @@ target_memory_map (void)
 void
 target_flash_erase (ULONGEST address, LONGEST length)
 {
-  current_target.to_flash_erase (&current_target, address, length);
+  target_stack->flash_erase (address, length);
 }
 
 void
 target_flash_done (void)
 {
-  current_target.to_flash_done (&current_target);
+  target_stack->flash_done ();
 }
 
 static void
@@ -2065,8 +1915,7 @@ target_insert_breakpoint (struct gdbarch *gdbarch,
       return 1;
     }
 
-  return current_target.to_insert_breakpoint (&current_target,
-					      gdbarch, bp_tgt);
+  return target_stack->insert_breakpoint (gdbarch, bp_tgt);
 }
 
 /* See target.h.  */
@@ -2086,8 +1935,7 @@ target_remove_breakpoint (struct gdbarch *gdbarch,
       return 1;
     }
 
-  return current_target.to_remove_breakpoint (&current_target,
-					      gdbarch, bp_tgt, reason);
+  return target_stack->remove_breakpoint (gdbarch, bp_tgt, reason);
 }
 
 static void
@@ -2102,7 +1950,7 @@ info_target_command (const char *args, int from_tty)
 
   for (t = target_stack; t != NULL; t = t->beneath)
     {
-      if (!(*t->to_has_memory) (t))
+      if (!t->has_memory ())
 	continue;
 
       if ((int) (t->to_stratum) <= (int) dummy_stratum)
@@ -2110,9 +1958,9 @@ info_target_command (const char *args, int from_tty)
       if (has_all_mem)
 	printf_unfiltered (_("\tWhile running this, "
 			     "GDB does not access memory from...\n"));
-      printf_unfiltered ("%s:\n", t->to_longname);
-      (t->to_files_info) (t);
-      has_all_mem = (*t->to_has_all_memory) (t);
+      printf_unfiltered ("%s:\n", t->longname ());
+      t->files_info ();
+      has_all_mem = t->has_all_memory ();
     }
 }
 
@@ -2236,7 +2084,7 @@ target_detach (inferior *inf, int from_tty)
 
   prepare_for_detach ();
 
-  current_target.to_detach (&current_target, inf, from_tty);
+  target_stack->detach (inf, from_tty);
 }
 
 void
@@ -2247,7 +2095,7 @@ target_disconnect (const char *args, int from_tty)
      disconnecting.  */
   remove_breakpoints ();
 
-  current_target.to_disconnect (&current_target, args, from_tty);
+  target_stack->disconnect (args, from_tty);
 }
 
 /* See target/target.h.  */
@@ -2255,7 +2103,7 @@ target_disconnect (const char *args, int from_tty)
 ptid_t
 target_wait (ptid_t ptid, struct target_waitstatus *status, int options)
 {
-  return (current_target.to_wait) (&current_target, ptid, status, options);
+  return target_stack->wait (ptid, status, options);
 }
 
 /* See target.h.  */
@@ -2272,13 +2120,13 @@ default_target_wait (struct target_ops *ops,
 const char *
 target_pid_to_str (ptid_t ptid)
 {
-  return (*current_target.to_pid_to_str) (&current_target, ptid);
+  return target_stack->pid_to_str (ptid);
 }
 
 const char *
 target_thread_name (struct thread_info *info)
 {
-  return current_target.to_thread_name (&current_target, info);
+  return target_stack->thread_name (info);
 }
 
 struct thread_info *
@@ -2286,8 +2134,8 @@ target_thread_handle_to_thread_info (const gdb_byte *thread_handle,
 				     int handle_len,
 				     struct inferior *inf)
 {
-  return current_target.to_thread_handle_to_thread_info
-           (&current_target, thread_handle, handle_len, inf);
+  return target_stack->thread_handle_to_thread_info (thread_handle,
+						     handle_len, inf);
 }
 
 void
@@ -2295,7 +2143,7 @@ target_resume (ptid_t ptid, int step, enum gdb_signal signal)
 {
   target_dcache_invalidate ();
 
-  current_target.to_resume (&current_target, ptid, step, signal);
+  target_stack->resume (ptid, step, signal);
 
   registers_changed_ptid (ptid);
   /* We only set the internal executing state here.  The user/frontend
@@ -2315,7 +2163,7 @@ target_commit_resume (void)
   if (defer_target_commit_resume)
     return;
 
-  current_target.to_commit_resume (&current_target);
+  target_stack->commit_resume ();
 }
 
 /* See target.h.  */
@@ -2329,14 +2177,13 @@ make_scoped_defer_target_commit_resume ()
 void
 target_pass_signals (int numsigs, unsigned char *pass_signals)
 {
-  (*current_target.to_pass_signals) (&current_target, numsigs, pass_signals);
+  target_stack->pass_signals (numsigs, pass_signals);
 }
 
 void
 target_program_signals (int numsigs, unsigned char *program_signals)
 {
-  (*current_target.to_program_signals) (&current_target,
-					numsigs, program_signals);
+  target_stack->program_signals (numsigs, program_signals);
 }
 
 static int
@@ -2354,8 +2201,7 @@ default_follow_fork (struct target_ops *self, int follow_child,
 int
 target_follow_fork (int follow_child, int detach_fork)
 {
-  return current_target.to_follow_fork (&current_target,
-					follow_child, detach_fork);
+  return target_stack->follow_fork (follow_child, detach_fork);
 }
 
 /* Target wrapper for follow exec hook.  */
@@ -2363,7 +2209,7 @@ target_follow_fork (int follow_child, int detach_fork)
 void
 target_follow_exec (struct inferior *inf, char *execd_pathname)
 {
-  current_target.to_follow_exec (&current_target, inf, execd_pathname);
+  target_stack->follow_exec (inf, execd_pathname);
 }
 
 static void
@@ -2377,7 +2223,7 @@ void
 target_mourn_inferior (ptid_t ptid)
 {
   gdb_assert (ptid_equal (ptid, inferior_ptid));
-  current_target.to_mourn_inferior (&current_target);
+  target_stack->mourn_inferior ();
 
   /* We no longer need to keep handles on any of the object files.
      Make sure to release them to avoid unnecessarily locking any
@@ -2391,7 +2237,7 @@ target_mourn_inferior (ptid_t ptid)
 const struct target_desc *
 target_read_description (struct target_ops *target)
 {
-  return target->to_read_description (target);
+  return target->read_description ();
 }
 
 /* This implements a basic search of memory, reading target memory and
@@ -2504,7 +2350,7 @@ default_search_memory (struct target_ops *self,
 		       CORE_ADDR *found_addrp)
 {
   /* Start over from the top of the target stack.  */
-  return simple_search_memory (current_target.beneath,
+  return simple_search_memory (target_stack,
 			       start_addr, search_space_len,
 			       pattern, pattern_len, found_addrp);
 }
@@ -2521,9 +2367,8 @@ target_search_memory (CORE_ADDR start_addr, ULONGEST search_space_len,
 		      const gdb_byte *pattern, ULONGEST pattern_len,
 		      CORE_ADDR *found_addrp)
 {
-  return current_target.to_search_memory (&current_target, start_addr,
-					  search_space_len,
-					  pattern, pattern_len, found_addrp);
+  return target_stack->search_memory (start_addr, search_space_len,
+				      pattern, pattern_len, found_addrp);
 }
 
 /* Look through the currently pushed targets.  If none of them will
@@ -2541,20 +2386,18 @@ target_require_runnable (void)
 	 assume we will still be able to after killing the current
 	 one.  Either killing and mourning will not pop T, or else
 	 find_default_run_target will find it again.  */
-      if (t->to_create_inferior != NULL)
+      if (t->can_create_inferior ())
 	return;
 
       /* Do not worry about targets at certain strata that can not
 	 create inferiors.  Assume they will be pushed again if
 	 necessary, and continue to the process_stratum.  */
-      if (t->to_stratum == thread_stratum
-	  || t->to_stratum == record_stratum
-	  || t->to_stratum == arch_stratum)
+      if (t->to_stratum > process_stratum)
 	continue;
 
       error (_("The \"%s\" target does not support \"run\".  "
 	       "Try \"help target\" or \"continue\"."),
-	     t->to_shortname);
+	     t->shortname ());
     }
 
   /* This function is only called if the target is running.  In that
@@ -2597,7 +2440,7 @@ find_default_run_target (const char *do_mesg)
 
       for (i = 0; VEC_iterate (target_ops_p, target_structs, i, t); ++i)
 	{
-	  if (t->to_can_run != delegate_can_run && target_can_run (t))
+	  if (t->can_run ())
 	    {
 	      runable = t;
 	      ++count;
@@ -2627,9 +2470,9 @@ find_attach_target (void)
   struct target_ops *t;
 
   /* If a target on the current stack can attach, use it.  */
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
+  for (t = target_stack; t != NULL; t = t->beneath)
     {
-      if (t->to_attach != NULL)
+      if (t->can_attach ())
 	break;
     }
 
@@ -2647,10 +2490,10 @@ find_run_target (void)
 {
   struct target_ops *t;
 
-  /* If a target on the current stack can attach, use it.  */
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
+  /* If a target on the current stack can run, use it.  */
+  for (t = target_stack; t != NULL; t = t->beneath)
     {
-      if (t->to_create_inferior != NULL)
+      if (t->can_create_inferior ())
 	break;
     }
 
@@ -2661,6 +2504,12 @@ find_run_target (void)
   return t;
 }
 
+bool
+target_ops::info_proc (const char *args, enum info_proc_what what)
+{
+  return false;
+}
+
 /* Implement the "info proc" command.  */
 
 int
@@ -2671,17 +2520,14 @@ target_info_proc (const char *args, enum info_proc_what what)
   /* If we're already connected to something that can get us OS
      related data, use it.  Otherwise, try using the native
      target.  */
-  if (current_target.to_stratum >= process_stratum)
-    t = current_target.beneath;
-  else
+  t = find_target_at (process_stratum);
+  if (t == NULL)
     t = find_default_run_target (NULL);
 
   for (; t != NULL; t = t->beneath)
     {
-      if (t->to_info_proc != NULL)
+      if (t->info_proc (args, what))
 	{
-	  t->to_info_proc (t, args, what);
-
 	  if (targetdebug)
 	    fprintf_unfiltered (gdb_stdlog,
 				"target_info_proc (\"%s\", %d)\n", args, what);
@@ -2699,21 +2545,15 @@ find_default_supports_disable_randomization (struct target_ops *self)
   struct target_ops *t;
 
   t = find_default_run_target (NULL);
-  if (t && t->to_supports_disable_randomization)
-    return (t->to_supports_disable_randomization) (t);
+  if (t != NULL)
+    return t->supports_disable_randomization ();
   return 0;
 }
 
 int
 target_supports_disable_randomization (void)
 {
-  struct target_ops *t;
-
-  for (t = &current_target; t != NULL; t = t->beneath)
-    if (t->to_supports_disable_randomization)
-      return t->to_supports_disable_randomization (t);
-
-  return 0;
+  return target_stack->supports_disable_randomization ();
 }
 
 /* See target/target.h.  */
@@ -2721,7 +2561,7 @@ target_supports_disable_randomization (void)
 int
 target_supports_multi_process (void)
 {
-  return (*current_target.to_supports_multi_process) (&current_target);
+  return target_stack->supports_multi_process ();
 }
 
 /* See target.h.  */
@@ -2734,9 +2574,8 @@ target_get_osdata (const char *type)
   /* If we're already connected to something that can get us OS
      related data, use it.  Otherwise, try using the native
      target.  */
-  if (current_target.to_stratum >= process_stratum)
-    t = current_target.beneath;
-  else
+  t = find_target_at (process_stratum);
+  if (t == NULL)
     t = find_default_run_target ("get OS data");
 
   if (!t)
@@ -2769,24 +2608,81 @@ target_thread_address_space (ptid_t ptid)
 {
   struct address_space *aspace;
 
-  aspace = current_target.to_thread_address_space (&current_target, ptid);
+  aspace = target_stack->thread_address_space (ptid);
   gdb_assert (aspace != NULL);
 
   return aspace;
 }
 
+void
+target_ops::open (const char *, int)
+{
+  gdb_assert_not_reached ("target_ops::open called");
+}
+
+void
+target_ops::close ()
+{
+}
+
+bool
+target_ops::can_attach ()
+{
+  return 0;
+}
+
+void
+target_ops::attach (const char *, int)
+{
+  gdb_assert_not_reached ("target_ops::attach called");
+}
+
+bool
+target_ops::can_create_inferior ()
+{
+  return 0;
+}
+
+void
+target_ops::create_inferior (const char *, const std::string &,
+			     char **, int)
+{
+  gdb_assert_not_reached ("target_ops::create_inferior called");
+}
+
+int
+target_ops::can_run ()
+{
+  return 0;
+}
+
+int
+target_can_run ()
+{
+  struct target_ops *t;
+
+  for (t = target_stack; t != NULL; t = t->beneath)
+    {
+      if (t->can_run ())
+	return 1;
+    }
+
+  return 0;
+}
 
 /* Target file operations.  */
 
 static struct target_ops *
 default_fileio_target (void)
 {
+  struct target_ops *t;
+
   /* If we're already connected to something that can perform
      file I/O, use it. Otherwise, try using the native target.  */
-  if (current_target.to_stratum >= process_stratum)
-    return current_target.beneath;
-  else
-    return find_default_run_target ("file I/O");
+  t = find_target_at (process_stratum);
+  if (t != NULL)
+    return t;
+  return find_default_run_target ("file I/O");
 }
 
 /* File handle for target file operations.  */
@@ -2878,6 +2774,67 @@ fileio_fd_to_fh (int fd)
   return &fileio_fhandles[fd];
 }
 
+
+/* Default implementations of file i/o methods.  We don't want these
+   to delegate automatically, because we need to know which target
+   supported the method, in order to call it directly from within
+   pread/pwrite, etc.  */
+
+int
+target_ops::fileio_open (struct inferior *inf, const char *filename,
+			 int flags, int mode, int warn_if_slow,
+			 int *target_errno)
+{
+  *target_errno = FILEIO_ENOSYS;
+  return -1;
+}
+
+int
+target_ops::fileio_pwrite (int fd, const gdb_byte *write_buf, int len,
+			   ULONGEST offset, int *target_errno)
+{
+  *target_errno = FILEIO_ENOSYS;
+  return -1;
+}
+
+int
+target_ops::fileio_pread (int fd, gdb_byte *read_buf, int len,
+			  ULONGEST offset, int *target_errno)
+{
+  *target_errno = FILEIO_ENOSYS;
+  return -1;
+}
+
+int
+target_ops::fileio_fstat (int fd, struct stat *sb, int *target_errno)
+{
+  *target_errno = FILEIO_ENOSYS;
+  return -1;
+}
+
+int
+target_ops::fileio_close (int fd, int *target_errno)
+{
+  *target_errno = FILEIO_ENOSYS;
+  return -1;
+}
+
+int
+target_ops::fileio_unlink (struct inferior *inf, const char *filename,
+			   int *target_errno)
+{
+  *target_errno = FILEIO_ENOSYS;
+  return -1;
+}
+
+gdb::optional<std::string>
+target_ops::fileio_readlink (struct inferior *inf, const char *filename,
+			     int *target_errno)
+{
+  *target_errno = FILEIO_ENOSYS;
+  return {};
+}
+
 /* Helper for target_fileio_open and
    target_fileio_open_warn_if_slow.  */
 
@@ -2890,26 +2847,26 @@ target_fileio_open_1 (struct inferior *inf, const char *filename,
 
   for (t = default_fileio_target (); t != NULL; t = t->beneath)
     {
-      if (t->to_fileio_open != NULL)
-	{
-	  int fd = t->to_fileio_open (t, inf, filename, flags, mode,
-				      warn_if_slow, target_errno);
+      int fd = t->fileio_open (inf, filename, flags, mode,
+			       warn_if_slow, target_errno);
 
-	  if (fd < 0)
-	    fd = -1;
-	  else
-	    fd = acquire_fileio_fd (t, fd);
+      if (fd == -1 && *target_errno == FILEIO_ENOSYS)
+	continue;
 
-	  if (targetdebug)
-	    fprintf_unfiltered (gdb_stdlog,
+      if (fd < 0)
+	fd = -1;
+      else
+	fd = acquire_fileio_fd (t, fd);
+
+      if (targetdebug)
+	fprintf_unfiltered (gdb_stdlog,
 				"target_fileio_open (%d,%s,0x%x,0%o,%d)"
 				" = %d (%d)\n",
 				inf == NULL ? 0 : inf->num,
 				filename, flags, mode,
 				warn_if_slow, fd,
 				fd != -1 ? 0 : *target_errno);
-	  return fd;
-	}
+      return fd;
     }
 
   *target_errno = FILEIO_ENOSYS;
@@ -2951,8 +2908,8 @@ target_fileio_pwrite (int fd, const gdb_byte *write_buf, int len,
   else if (fh->target == NULL)
     *target_errno = EIO;
   else
-    ret = fh->target->to_fileio_pwrite (fh->target, fh->target_fd, write_buf,
-					len, offset, target_errno);
+    ret = fh->target->fileio_pwrite (fh->target_fd, write_buf,
+				     len, offset, target_errno);
 
   if (targetdebug)
     fprintf_unfiltered (gdb_stdlog,
@@ -2977,8 +2934,8 @@ target_fileio_pread (int fd, gdb_byte *read_buf, int len,
   else if (fh->target == NULL)
     *target_errno = EIO;
   else
-    ret = fh->target->to_fileio_pread (fh->target, fh->target_fd, read_buf,
-				       len, offset, target_errno);
+    ret = fh->target->fileio_pread (fh->target_fd, read_buf,
+				    len, offset, target_errno);
 
   if (targetdebug)
     fprintf_unfiltered (gdb_stdlog,
@@ -3002,8 +2959,7 @@ target_fileio_fstat (int fd, struct stat *sb, int *target_errno)
   else if (fh->target == NULL)
     *target_errno = EIO;
   else
-    ret = fh->target->to_fileio_fstat (fh->target, fh->target_fd,
-				       sb, target_errno);
+    ret = fh->target->fileio_fstat (fh->target_fd, sb, target_errno);
 
   if (targetdebug)
     fprintf_unfiltered (gdb_stdlog,
@@ -3025,8 +2981,8 @@ target_fileio_close (int fd, int *target_errno)
   else
     {
       if (fh->target != NULL)
-	ret = fh->target->to_fileio_close (fh->target, fh->target_fd,
-					   target_errno);
+	ret = fh->target->fileio_close (fh->target_fd,
+					target_errno);
       else
 	ret = 0;
       release_fileio_fd (fd, fh);
@@ -3049,19 +3005,18 @@ target_fileio_unlink (struct inferior *inf, const char *filename,
 
   for (t = default_fileio_target (); t != NULL; t = t->beneath)
     {
-      if (t->to_fileio_unlink != NULL)
-	{
-	  int ret = t->to_fileio_unlink (t, inf, filename,
-					 target_errno);
+      int ret = t->fileio_unlink (inf, filename, target_errno);
 
-	  if (targetdebug)
-	    fprintf_unfiltered (gdb_stdlog,
-				"target_fileio_unlink (%d,%s)"
-				" = %d (%d)\n",
-				inf == NULL ? 0 : inf->num, filename,
-				ret, ret != -1 ? 0 : *target_errno);
-	  return ret;
-	}
+      if (ret == -1 && *target_errno == FILEIO_ENOSYS)
+	continue;
+
+      if (targetdebug)
+	fprintf_unfiltered (gdb_stdlog,
+			    "target_fileio_unlink (%d,%s)"
+			    " = %d (%d)\n",
+			    inf == NULL ? 0 : inf->num, filename,
+			    ret, ret != -1 ? 0 : *target_errno);
+      return ret;
     }
 
   *target_errno = FILEIO_ENOSYS;
@@ -3078,20 +3033,20 @@ target_fileio_readlink (struct inferior *inf, const char *filename,
 
   for (t = default_fileio_target (); t != NULL; t = t->beneath)
     {
-      if (t->to_fileio_readlink != NULL)
-	{
-	  gdb::optional<std::string> ret
-	    = t->to_fileio_readlink (t, inf, filename, target_errno);
+      gdb::optional<std::string> ret
+	= t->fileio_readlink (inf, filename, target_errno);
 
-	  if (targetdebug)
-	    fprintf_unfiltered (gdb_stdlog,
-				"target_fileio_readlink (%d,%s)"
-				" = %s (%d)\n",
-				inf == NULL ? 0 : inf->num,
-				filename, ret ? ret->c_str () : "(nil)",
-				ret ? 0 : *target_errno);
-	  return ret;
-	}
+      if (!ret.has_value () && *target_errno == FILEIO_ENOSYS)
+	continue;
+
+      if (targetdebug)
+	fprintf_unfiltered (gdb_stdlog,
+			    "target_fileio_readlink (%d,%s)"
+			    " = %s (%d)\n",
+			    inf == NULL ? 0 : inf->num,
+			    filename, ret ? ret->c_str () : "(nil)",
+			    ret ? 0 : *target_errno);
+      return ret;
     }
 
   *target_errno = FILEIO_ENOSYS;
@@ -3256,18 +3211,6 @@ default_thread_architecture (struct target_ops *ops, ptid_t ptid)
   return inf->gdbarch;
 }
 
-static int
-return_zero (struct target_ops *ignore)
-{
-  return 0;
-}
-
-static int
-return_zero_has_execution (struct target_ops *ignore, ptid_t ignore2)
-{
-  return 0;
-}
-
 /*
  * Find the next target down the stack from the specified target.
  */
@@ -3285,7 +3228,7 @@ find_target_at (enum strata stratum)
 {
   struct target_ops *t;
 
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
+  for (t = target_stack; t != NULL; t = t->beneath)
     if (t->to_stratum == stratum)
       return t;
 
@@ -3386,27 +3329,55 @@ dummy_make_corefile_notes (struct target_ops *self,
   return NULL;
 }
 
-/* Set up the handful of non-empty slots needed by the dummy target
-   vector.  */
+#include "target-delegates.c"
+
 
-static void
-init_dummy_target (void)
-{
-  dummy_target.to_shortname = "None";
-  dummy_target.to_longname = "None";
-  dummy_target.to_doc = "";
-  dummy_target.to_supports_disable_randomization
-    = find_default_supports_disable_randomization;
-  dummy_target.to_stratum = dummy_stratum;
-  dummy_target.to_has_all_memory = return_zero;
-  dummy_target.to_has_memory = return_zero;
-  dummy_target.to_has_stack = return_zero;
-  dummy_target.to_has_registers = return_zero;
-  dummy_target.to_has_execution = return_zero_has_execution;
-  dummy_target.to_magic = OPS_MAGIC;
-
-  install_dummy_methods (&dummy_target);
+dummy_target::dummy_target ()
+{
+  to_stratum = dummy_stratum;
+}
+
+const char *
+dummy_target::shortname ()
+{
+  return "None";
+}
+
+const char *
+dummy_target::longname ()
+{
+  return _("None");
 }
+
+const char *
+dummy_target::doc ()
+{
+  return "";
+}
+
+debug_target::debug_target ()
+{
+  to_stratum = debug_stratum;
+}
+
+const char *
+debug_target::shortname ()
+{
+  return beneath->shortname ();
+}
+
+const char *
+debug_target::longname ()
+{
+  return beneath->longname ();
+}
+
+const char *
+debug_target::doc ()
+{
+  return beneath->doc ();
+}
+
 \f
 
 void
@@ -3416,8 +3387,7 @@ target_close (struct target_ops *targ)
 
   fileio_handles_invalidate_target (targ);
 
-  if (targ->to_close != NULL)
-    targ->to_close (targ);
+  targ->close ();
 
   if (targetdebug)
     fprintf_unfiltered (gdb_stdlog, "target_close ()\n");
@@ -3426,13 +3396,13 @@ target_close (struct target_ops *targ)
 int
 target_thread_alive (ptid_t ptid)
 {
-  return current_target.to_thread_alive (&current_target, ptid);
+  return target_stack->thread_alive (ptid);
 }
 
 void
 target_update_thread_list (void)
 {
-  current_target.to_update_thread_list (&current_target);
+  target_stack->update_thread_list ();
 }
 
 void
@@ -3444,7 +3414,7 @@ target_stop (ptid_t ptid)
       return;
     }
 
-  (*current_target.to_stop) (&current_target, ptid);
+  target_stack->stop (ptid);
 }
 
 void
@@ -3456,7 +3426,7 @@ target_interrupt ()
       return;
     }
 
-  (*current_target.to_interrupt) (&current_target);
+  target_stack->interrupt ();
 }
 
 /* See target.h.  */
@@ -3464,7 +3434,7 @@ target_interrupt ()
 void
 target_pass_ctrlc (void)
 {
-  (*current_target.to_pass_ctrlc) (&current_target);
+  target_stack->pass_ctrlc ();
 }
 
 /* See target.h.  */
@@ -3559,7 +3529,7 @@ target_options_to_string (int target_options)
 void
 target_fetch_registers (struct regcache *regcache, int regno)
 {
-  current_target.to_fetch_registers (&current_target, regcache, regno);
+  target_stack->fetch_registers (regcache, regno);
   if (targetdebug)
     regcache->debug_print_register ("target_fetch_registers", regno);
 }
@@ -3570,7 +3540,7 @@ target_store_registers (struct regcache *regcache, int regno)
   if (!may_write_registers)
     error (_("Writing to registers is not allowed (regno %d)"), regno);
 
-  current_target.to_store_registers (&current_target, regcache, regno);
+  target_stack->store_registers (regcache, regno);
   if (targetdebug)
     {
       regcache->debug_print_register ("target_store_registers", regno);
@@ -3580,7 +3550,7 @@ target_store_registers (struct regcache *regcache, int regno)
 int
 target_core_of_thread (ptid_t ptid)
 {
-  return current_target.to_core_of_thread (&current_target, ptid);
+  return target_stack->core_of_thread (ptid);
 }
 
 int
@@ -3618,15 +3588,14 @@ default_verify_memory (struct target_ops *self,
 		       const gdb_byte *data, CORE_ADDR memaddr, ULONGEST size)
 {
   /* Start over from the top of the target stack.  */
-  return simple_verify_memory (current_target.beneath,
+  return simple_verify_memory (target_stack,
 			       data, memaddr, size);
 }
 
 int
 target_verify_memory (const gdb_byte *data, CORE_ADDR memaddr, ULONGEST size)
 {
-  return current_target.to_verify_memory (&current_target,
-					  data, memaddr, size);
+  return target_stack->verify_memory (data, memaddr, size);
 }
 
 /* The documentation for this function is in its prototype declaration in
@@ -3636,8 +3605,7 @@ int
 target_insert_mask_watchpoint (CORE_ADDR addr, CORE_ADDR mask,
 			       enum target_hw_bp_type rw)
 {
-  return current_target.to_insert_mask_watchpoint (&current_target,
-						   addr, mask, rw);
+  return target_stack->insert_mask_watchpoint (addr, mask, rw);
 }
 
 /* The documentation for this function is in its prototype declaration in
@@ -3647,8 +3615,7 @@ int
 target_remove_mask_watchpoint (CORE_ADDR addr, CORE_ADDR mask,
 			       enum target_hw_bp_type rw)
 {
-  return current_target.to_remove_mask_watchpoint (&current_target,
-						   addr, mask, rw);
+  return target_stack->remove_mask_watchpoint (addr, mask, rw);
 }
 
 /* The documentation for this function is in its prototype declaration
@@ -3657,8 +3624,7 @@ target_remove_mask_watchpoint (CORE_ADDR addr, CORE_ADDR mask,
 int
 target_masked_watch_num_registers (CORE_ADDR addr, CORE_ADDR mask)
 {
-  return current_target.to_masked_watch_num_registers (&current_target,
-						       addr, mask);
+  return target_stack->masked_watch_num_registers (addr, mask);
 }
 
 /* The documentation for this function is in its prototype declaration
@@ -3667,7 +3633,7 @@ target_masked_watch_num_registers (CORE_ADDR addr, CORE_ADDR mask)
 int
 target_ranged_break_num_registers (void)
 {
-  return current_target.to_ranged_break_num_registers (&current_target);
+  return target_stack->ranged_break_num_registers ();
 }
 
 /* See target.h.  */
@@ -3675,7 +3641,7 @@ target_ranged_break_num_registers (void)
 struct btrace_target_info *
 target_enable_btrace (ptid_t ptid, const struct btrace_config *conf)
 {
-  return current_target.to_enable_btrace (&current_target, ptid, conf);
+  return target_stack->enable_btrace (ptid, conf);
 }
 
 /* See target.h.  */
@@ -3683,7 +3649,7 @@ target_enable_btrace (ptid_t ptid, const struct btrace_config *conf)
 void
 target_disable_btrace (struct btrace_target_info *btinfo)
 {
-  current_target.to_disable_btrace (&current_target, btinfo);
+  target_stack->disable_btrace (btinfo);
 }
 
 /* See target.h.  */
@@ -3691,7 +3657,7 @@ target_disable_btrace (struct btrace_target_info *btinfo)
 void
 target_teardown_btrace (struct btrace_target_info *btinfo)
 {
-  current_target.to_teardown_btrace (&current_target, btinfo);
+  target_stack->teardown_btrace (btinfo);
 }
 
 /* See target.h.  */
@@ -3701,7 +3667,7 @@ target_read_btrace (struct btrace_data *btrace,
 		    struct btrace_target_info *btinfo,
 		    enum btrace_read_type type)
 {
-  return current_target.to_read_btrace (&current_target, btrace, btinfo, type);
+  return target_stack->read_btrace (btrace, btinfo, type);
 }
 
 /* See target.h.  */
@@ -3709,7 +3675,7 @@ target_read_btrace (struct btrace_data *btrace,
 const struct btrace_config *
 target_btrace_conf (const struct btrace_target_info *btinfo)
 {
-  return current_target.to_btrace_conf (&current_target, btinfo);
+  return target_stack->btrace_conf (btinfo);
 }
 
 /* See target.h.  */
@@ -3717,7 +3683,7 @@ target_btrace_conf (const struct btrace_target_info *btinfo)
 void
 target_stop_recording (void)
 {
-  current_target.to_stop_recording (&current_target);
+  target_stack->stop_recording ();
 }
 
 /* See target.h.  */
@@ -3725,22 +3691,15 @@ target_stop_recording (void)
 void
 target_save_record (const char *filename)
 {
-  current_target.to_save_record (&current_target, filename);
+  target_stack->save_record (filename);
 }
 
 /* See target.h.  */
 
 int
-target_supports_delete_record (void)
+target_supports_delete_record ()
 {
-  struct target_ops *t;
-
-  for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_delete_record != delegate_delete_record
-	&& t->to_delete_record != tdefault_delete_record)
-      return 1;
-
-  return 0;
+  return target_stack->supports_delete_record ();
 }
 
 /* See target.h.  */
@@ -3748,7 +3707,7 @@ target_supports_delete_record (void)
 void
 target_delete_record (void)
 {
-  current_target.to_delete_record (&current_target);
+  target_stack->delete_record ();
 }
 
 /* See target.h.  */
@@ -3756,7 +3715,7 @@ target_delete_record (void)
 enum record_method
 target_record_method (ptid_t ptid)
 {
-  return current_target.to_record_method (&current_target, ptid);
+  return target_stack->record_method (ptid);
 }
 
 /* See target.h.  */
@@ -3764,7 +3723,7 @@ target_record_method (ptid_t ptid)
 int
 target_record_is_replaying (ptid_t ptid)
 {
-  return current_target.to_record_is_replaying (&current_target, ptid);
+  return target_stack->record_is_replaying (ptid);
 }
 
 /* See target.h.  */
@@ -3772,7 +3731,7 @@ target_record_is_replaying (ptid_t ptid)
 int
 target_record_will_replay (ptid_t ptid, int dir)
 {
-  return current_target.to_record_will_replay (&current_target, ptid, dir);
+  return target_stack->record_will_replay (ptid, dir);
 }
 
 /* See target.h.  */
@@ -3780,7 +3739,7 @@ target_record_will_replay (ptid_t ptid, int dir)
 void
 target_record_stop_replaying (void)
 {
-  current_target.to_record_stop_replaying (&current_target);
+  target_stack->record_stop_replaying ();
 }
 
 /* See target.h.  */
@@ -3788,7 +3747,7 @@ target_record_stop_replaying (void)
 void
 target_goto_record_begin (void)
 {
-  current_target.to_goto_record_begin (&current_target);
+  target_stack->goto_record_begin ();
 }
 
 /* See target.h.  */
@@ -3796,7 +3755,7 @@ target_goto_record_begin (void)
 void
 target_goto_record_end (void)
 {
-  current_target.to_goto_record_end (&current_target);
+  target_stack->goto_record_end ();
 }
 
 /* See target.h.  */
@@ -3804,7 +3763,7 @@ target_goto_record_end (void)
 void
 target_goto_record (ULONGEST insn)
 {
-  current_target.to_goto_record (&current_target, insn);
+  target_stack->goto_record (insn);
 }
 
 /* See target.h.  */
@@ -3812,7 +3771,7 @@ target_goto_record (ULONGEST insn)
 void
 target_insn_history (int size, gdb_disassembly_flags flags)
 {
-  current_target.to_insn_history (&current_target, size, flags);
+  target_stack->insn_history (size, flags);
 }
 
 /* See target.h.  */
@@ -3821,7 +3780,7 @@ void
 target_insn_history_from (ULONGEST from, int size,
 			  gdb_disassembly_flags flags)
 {
-  current_target.to_insn_history_from (&current_target, from, size, flags);
+  target_stack->insn_history_from (from, size, flags);
 }
 
 /* See target.h.  */
@@ -3830,7 +3789,7 @@ void
 target_insn_history_range (ULONGEST begin, ULONGEST end,
 			   gdb_disassembly_flags flags)
 {
-  current_target.to_insn_history_range (&current_target, begin, end, flags);
+  target_stack->insn_history_range (begin, end, flags);
 }
 
 /* See target.h.  */
@@ -3838,7 +3797,7 @@ target_insn_history_range (ULONGEST begin, ULONGEST end,
 void
 target_call_history (int size, record_print_flags flags)
 {
-  current_target.to_call_history (&current_target, size, flags);
+  target_stack->call_history (size, flags);
 }
 
 /* See target.h.  */
@@ -3846,7 +3805,7 @@ target_call_history (int size, record_print_flags flags)
 void
 target_call_history_from (ULONGEST begin, int size, record_print_flags flags)
 {
-  current_target.to_call_history_from (&current_target, begin, size, flags);
+  target_stack->call_history_from (begin, size, flags);
 }
 
 /* See target.h.  */
@@ -3854,7 +3813,7 @@ target_call_history_from (ULONGEST begin, int size, record_print_flags flags)
 void
 target_call_history_range (ULONGEST begin, ULONGEST end, record_print_flags flags)
 {
-  current_target.to_call_history_range (&current_target, begin, end, flags);
+  target_stack->call_history_range (begin, end, flags);
 }
 
 /* See target.h.  */
@@ -3862,7 +3821,7 @@ target_call_history_range (ULONGEST begin, ULONGEST end, record_print_flags flag
 const struct frame_unwind *
 target_get_unwinder (void)
 {
-  return current_target.to_get_unwinder (&current_target);
+  return target_stack->get_unwinder ();
 }
 
 /* See target.h.  */
@@ -3870,7 +3829,7 @@ target_get_unwinder (void)
 const struct frame_unwind *
 target_get_tailcall_unwinder (void)
 {
-  return current_target.to_get_tailcall_unwinder (&current_target);
+  return target_stack->get_tailcall_unwinder ();
 }
 
 /* See target.h.  */
@@ -3878,7 +3837,7 @@ target_get_tailcall_unwinder (void)
 void
 target_prepare_to_generate_core (void)
 {
-  current_target.to_prepare_to_generate_core (&current_target);
+  target_stack->prepare_to_generate_core ();
 }
 
 /* See target.h.  */
@@ -3886,16 +3845,9 @@ target_prepare_to_generate_core (void)
 void
 target_done_generating_core (void)
 {
-  current_target.to_done_generating_core (&current_target);
+  target_stack->done_generating_core ();
 }
 
-static void
-setup_target_debug (void)
-{
-  memcpy (&debug_target, &current_target, sizeof debug_target);
-
-  init_debug_target (&current_target);
-}
 \f
 
 static char targ_desc[] =
@@ -3965,7 +3917,9 @@ maintenance_print_target_stack (const char *cmd, int from_tty)
 
   for (t = target_stack; t != NULL; t = t->beneath)
     {
-      printf_filtered ("  - %s (%s)\n", t->to_shortname, t->to_longname);
+      if (t->to_stratum == debug_stratum)
+	continue;
+      printf_filtered ("  - %s (%s)\n", t->shortname (), t->longname ());
     }
 }
 
@@ -3975,7 +3929,7 @@ void
 target_async (int enable)
 {
   infrun_async (enable);
-  current_target.to_async (&current_target, enable);
+  target_stack->async (enable);
 }
 
 /* See target.h.  */
@@ -3983,7 +3937,7 @@ target_async (int enable)
 void
 target_thread_events (int enable)
 {
-  current_target.to_thread_events (&current_target, enable);
+  target_stack->thread_events (enable);
 }
 
 /* Controls if targets can report that they can/are async.  This is
@@ -4023,7 +3977,7 @@ maint_show_target_async_command (struct ui_file *file, int from_tty,
 static int
 target_always_non_stop_p (void)
 {
-  return current_target.to_always_non_stop_p (&current_target);
+  return target_stack->always_non_stop_p ();
 }
 
 /* See target.h.  */
@@ -4133,59 +4087,13 @@ set_write_memory_permission (const char *args, int from_tty,
   update_observer_mode ();
 }
 
-#if GDB_SELF_TEST
-namespace selftests {
-
-static int
-test_target_has_registers (target_ops *self)
-{
-  return 1;
-}
-
-static int
-test_target_has_stack (target_ops *self)
-{
-  return 1;
-}
-
-static int
-test_target_has_memory (target_ops *self)
-{
-  return 1;
-}
-
-static void
-test_target_prepare_to_store (target_ops *self, regcache *regs)
-{
-}
-
-static void
-test_target_store_registers (target_ops *self, regcache *regs, int regno)
-{
-}
-
-test_target_ops::test_target_ops ()
-  : target_ops {}
-{
-  to_magic = OPS_MAGIC;
-  to_stratum = process_stratum;
-  to_has_memory = test_target_has_memory;
-  to_has_stack = test_target_has_stack;
-  to_has_registers = test_target_has_registers;
-  to_prepare_to_store = test_target_prepare_to_store;
-  to_store_registers = test_target_store_registers;
-
-  complete_target_initialization (this);
-}
-
-} // namespace selftests
-#endif /* GDB_SELF_TEST */
-
 void
 initialize_targets (void)
 {
-  init_dummy_target ();
-  push_target (&dummy_target);
+  the_dummy_target = new dummy_target ();
+  push_target (the_dummy_target);
+
+  the_debug_target = new debug_target ();
 
   add_info ("target", info_target_command, targ_desc);
   add_info ("files", info_target_command, targ_desc);
diff --git a/gdb/target.h b/gdb/target.h
index f329362285..b23b7625be 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -87,7 +87,8 @@ enum strata
     process_stratum,		/* Executing processes or core dump files */
     thread_stratum,		/* Executing threads */
     record_stratum,		/* Support record debugging */
-    arch_stratum		/* Architecture overrides */
+    arch_stratum,		/* Architecture overrides */
+    debug_stratum		/* Target debug.  Must be last.  */
   };
 
 enum thread_control_capabilities
@@ -406,65 +407,71 @@ typedef void async_callback_ftype (enum inferior_event_type event_type,
 struct target_ops
   {
     struct target_ops *beneath;	/* To the target under this one.  */
-    const char *to_shortname;	/* Name this target type */
-    const char *to_longname;	/* Name for printing */
-    const char *to_doc;		/* Documentation.  Does not include trailing
-				   newline, and starts with a one-line descrip-
-				   tion (probably similar to to_longname).  */
-    /* Per-target scratch pad.  */
-    void *to_data;
+
+    virtual ~target_ops () {}
+
+    /* Name this target type.  */
+    virtual const char *shortname () = 0;
+
+    /* Name for printing.  */
+    virtual const char *longname () = 0;
+
+    /* Documentation.  Does not include trailing newline, and starts
+       ith a one-line description (probably similar to longname).  */
+    virtual const char *doc () = 0;
+
     /* The open routine takes the rest of the parameters from the
        command, and (if successful) pushes a new target onto the
        stack.  Targets should supply this routine, if only to provide
        an error message.  */
-    void (*to_open) (const char *, int);
+    virtual void open (const char *, int);
 
     /* Close the target.  This is where the target can handle
        teardown.  Heap-allocated targets should delete themselves
        before returning.  */
-    void (*to_close) (struct target_ops *);
+    virtual void close ();
 
     /* Attaches to a process on the target side.  Arguments are as
        passed to the `attach' command by the user.  This routine can
        be called when the target is not on the target-stack, if the
-       target_can_run routine returns 1; in that case, it must push
+       target_ops::can_run method returns 1; in that case, it must push
        itself onto the stack.  Upon exit, the target should be ready
        for normal operations, and should be ready to deliver the
        status of the process immediately (without waiting) to an
        upcoming target_wait call.  */
-    void (*to_attach) (struct target_ops *ops, const char *, int);
-    void (*to_post_attach) (struct target_ops *, int)
+    virtual bool can_attach ();
+    virtual void attach (const char *, int);
+    virtual void post_attach (int)
       TARGET_DEFAULT_IGNORE ();
-    void (*to_detach) (struct target_ops *ops, inferior *, int)
+    virtual void detach (inferior *, int)
       TARGET_DEFAULT_IGNORE ();
-    void (*to_disconnect) (struct target_ops *, const char *, int)
+    virtual void disconnect (const char *, int)
       TARGET_DEFAULT_NORETURN (tcomplain ());
-    void (*to_resume) (struct target_ops *, ptid_t,
-		       int TARGET_DEBUG_PRINTER (target_debug_print_step),
-		       enum gdb_signal)
+    virtual void resume (ptid_t,
+			 int TARGET_DEBUG_PRINTER (target_debug_print_step),
+			 enum gdb_signal)
       TARGET_DEFAULT_NORETURN (noprocess ());
-    void (*to_commit_resume) (struct target_ops *)
+    virtual void commit_resume ()
       TARGET_DEFAULT_IGNORE ();
-    ptid_t (*to_wait) (struct target_ops *,
-		       ptid_t, struct target_waitstatus *,
-		       int TARGET_DEBUG_PRINTER (target_debug_print_options))
+    virtual ptid_t wait (ptid_t, struct target_waitstatus *,
+			 int TARGET_DEBUG_PRINTER (target_debug_print_options))
       TARGET_DEFAULT_FUNC (default_target_wait);
-    void (*to_fetch_registers) (struct target_ops *, struct regcache *, int)
+    virtual void fetch_registers (struct regcache *, int)
       TARGET_DEFAULT_IGNORE ();
-    void (*to_store_registers) (struct target_ops *, struct regcache *, int)
+    virtual void store_registers (struct regcache *, int)
       TARGET_DEFAULT_NORETURN (noprocess ());
-    void (*to_prepare_to_store) (struct target_ops *, struct regcache *)
+    virtual void prepare_to_store (struct regcache *)
       TARGET_DEFAULT_NORETURN (noprocess ());
 
-    void (*to_files_info) (struct target_ops *)
+    virtual void files_info ()
       TARGET_DEFAULT_IGNORE ();
-    int (*to_insert_breakpoint) (struct target_ops *, struct gdbarch *,
+    virtual int insert_breakpoint (struct gdbarch *,
 				 struct bp_target_info *)
-      TARGET_DEFAULT_FUNC (memory_insert_breakpoint);
-    int (*to_remove_breakpoint) (struct target_ops *, struct gdbarch *,
+      TARGET_DEFAULT_NORETURN (noprocess ());
+    virtual int remove_breakpoint (struct gdbarch *,
 				 struct bp_target_info *,
 				 enum remove_bp_reason)
-      TARGET_DEFAULT_FUNC (memory_remove_breakpoint);
+      TARGET_DEFAULT_NORETURN (noprocess ());
 
     /* Returns true if the target stopped because it executed a
        software breakpoint.  This is necessary for correct background
@@ -475,10 +482,10 @@ struct target_ops
        done from the target, so GDB needs to be able to tell whether
        it should ignore the event and whether it should adjust the PC.
        See adjust_pc_after_break.  */
-    int (*to_stopped_by_sw_breakpoint) (struct target_ops *)
+    virtual int stopped_by_sw_breakpoint ()
       TARGET_DEFAULT_RETURN (0);
     /* Returns true if the above method is supported.  */
-    int (*to_supports_stopped_by_sw_breakpoint) (struct target_ops *)
+    virtual int supports_stopped_by_sw_breakpoint ()
       TARGET_DEFAULT_RETURN (0);
 
     /* Returns true if the target stopped for a hardware breakpoint.
@@ -488,204 +495,203 @@ struct target_ops
        require PC adjustment, GDB needs to be able to tell whether the
        hardware breakpoint event is a delayed event for a breakpoint
        that is already gone and should thus be ignored.  */
-    int (*to_stopped_by_hw_breakpoint) (struct target_ops *)
+    virtual int stopped_by_hw_breakpoint ()
       TARGET_DEFAULT_RETURN (0);
     /* Returns true if the above method is supported.  */
-    int (*to_supports_stopped_by_hw_breakpoint) (struct target_ops *)
+    virtual int supports_stopped_by_hw_breakpoint ()
       TARGET_DEFAULT_RETURN (0);
 
-    int (*to_can_use_hw_breakpoint) (struct target_ops *,
-				     enum bptype, int, int)
+    virtual int can_use_hw_breakpoint (enum bptype, int, int)
       TARGET_DEFAULT_RETURN (0);
-    int (*to_ranged_break_num_registers) (struct target_ops *)
+    virtual int ranged_break_num_registers ()
       TARGET_DEFAULT_RETURN (-1);
-    int (*to_insert_hw_breakpoint) (struct target_ops *,
-				    struct gdbarch *, struct bp_target_info *)
+    virtual int insert_hw_breakpoint (struct gdbarch *,
+				      struct bp_target_info *)
       TARGET_DEFAULT_RETURN (-1);
-    int (*to_remove_hw_breakpoint) (struct target_ops *,
-				    struct gdbarch *, struct bp_target_info *)
+    virtual int remove_hw_breakpoint (struct gdbarch *,
+				      struct bp_target_info *)
       TARGET_DEFAULT_RETURN (-1);
 
     /* Documentation of what the two routines below are expected to do is
        provided with the corresponding target_* macros.  */
-    int (*to_remove_watchpoint) (struct target_ops *, CORE_ADDR, int,
+    virtual int remove_watchpoint (CORE_ADDR, int,
 				 enum target_hw_bp_type, struct expression *)
       TARGET_DEFAULT_RETURN (-1);
-    int (*to_insert_watchpoint) (struct target_ops *, CORE_ADDR, int,
+    virtual int insert_watchpoint (CORE_ADDR, int,
 				 enum target_hw_bp_type, struct expression *)
       TARGET_DEFAULT_RETURN (-1);
 
-    int (*to_insert_mask_watchpoint) (struct target_ops *,
-				      CORE_ADDR, CORE_ADDR,
-				      enum target_hw_bp_type)
+    virtual int insert_mask_watchpoint (CORE_ADDR, CORE_ADDR,
+					enum target_hw_bp_type)
       TARGET_DEFAULT_RETURN (1);
-    int (*to_remove_mask_watchpoint) (struct target_ops *,
-				      CORE_ADDR, CORE_ADDR,
-				      enum target_hw_bp_type)
+    virtual int remove_mask_watchpoint (CORE_ADDR, CORE_ADDR,
+					enum target_hw_bp_type)
       TARGET_DEFAULT_RETURN (1);
-    int (*to_stopped_by_watchpoint) (struct target_ops *)
+    virtual int stopped_by_watchpoint ()
       TARGET_DEFAULT_RETURN (0);
-    int to_have_steppable_watchpoint;
-    int to_have_continuable_watchpoint;
-    int (*to_stopped_data_address) (struct target_ops *, CORE_ADDR *)
+    virtual int have_steppable_watchpoint ()
       TARGET_DEFAULT_RETURN (0);
-    int (*to_watchpoint_addr_within_range) (struct target_ops *,
-					    CORE_ADDR, CORE_ADDR, int)
+    virtual bool have_continuable_watchpoint ()
+      TARGET_DEFAULT_RETURN (0);
+    virtual int stopped_data_address (CORE_ADDR *)
+      TARGET_DEFAULT_RETURN (0);
+    virtual int watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, int)
       TARGET_DEFAULT_FUNC (default_watchpoint_addr_within_range);
 
     /* Documentation of this routine is provided with the corresponding
        target_* macro.  */
-    int (*to_region_ok_for_hw_watchpoint) (struct target_ops *,
-					   CORE_ADDR, int)
+    virtual int region_ok_for_hw_watchpoint (CORE_ADDR, int)
       TARGET_DEFAULT_FUNC (default_region_ok_for_hw_watchpoint);
 
-    int (*to_can_accel_watchpoint_condition) (struct target_ops *,
-					      CORE_ADDR, int, int,
-					      struct expression *)
+    virtual int can_accel_watchpoint_condition (CORE_ADDR, int, int,
+						struct expression *)
       TARGET_DEFAULT_RETURN (0);
-    int (*to_masked_watch_num_registers) (struct target_ops *,
-					  CORE_ADDR, CORE_ADDR)
+    virtual int masked_watch_num_registers (CORE_ADDR, CORE_ADDR)
       TARGET_DEFAULT_RETURN (-1);
 
     /* Return 1 for sure target can do single step.  Return -1 for
        unknown.  Return 0 for target can't do.  */
-    int (*to_can_do_single_step) (struct target_ops *)
+    virtual int can_do_single_step ()
       TARGET_DEFAULT_RETURN (-1);
 
-    void (*to_terminal_init) (struct target_ops *)
+    virtual bool supports_terminal_ours ()
+      TARGET_DEFAULT_RETURN (0);
+    virtual void terminal_init ()
       TARGET_DEFAULT_IGNORE ();
-    void (*to_terminal_inferior) (struct target_ops *)
+    virtual void terminal_inferior ()
       TARGET_DEFAULT_IGNORE ();
-    void (*to_terminal_save_inferior) (struct target_ops *)
+    virtual void terminal_save_inferior ()
       TARGET_DEFAULT_IGNORE ();
-    void (*to_terminal_ours_for_output) (struct target_ops *)
+    virtual void terminal_ours_for_output ()
       TARGET_DEFAULT_IGNORE ();
-    void (*to_terminal_ours) (struct target_ops *)
+    virtual void terminal_ours ()
       TARGET_DEFAULT_IGNORE ();
-    void (*to_terminal_info) (struct target_ops *, const char *, int)
+    virtual void terminal_info (const char *, int)
       TARGET_DEFAULT_FUNC (default_terminal_info);
-    void (*to_kill) (struct target_ops *)
+    virtual void kill ()
       TARGET_DEFAULT_NORETURN (noprocess ());
-    void (*to_load) (struct target_ops *, const char *, int)
+    virtual void load (const char *, int)
       TARGET_DEFAULT_NORETURN (tcomplain ());
     /* Start an inferior process and set inferior_ptid to its pid.
        EXEC_FILE is the file to run.
        ALLARGS is a string containing the arguments to the program.
        ENV is the environment vector to pass.  Errors reported with error().
        On VxWorks and various standalone systems, we ignore exec_file.  */
-    void (*to_create_inferior) (struct target_ops *, 
-				const char *, const std::string &,
-				char **, int);
-    void (*to_post_startup_inferior) (struct target_ops *, ptid_t)
+    virtual bool can_create_inferior ();
+    virtual void create_inferior (const char *, const std::string &,
+				  char **, int);
+    virtual void post_startup_inferior (ptid_t)
       TARGET_DEFAULT_IGNORE ();
-    int (*to_insert_fork_catchpoint) (struct target_ops *, int)
+    virtual int insert_fork_catchpoint (int)
       TARGET_DEFAULT_RETURN (1);
-    int (*to_remove_fork_catchpoint) (struct target_ops *, int)
+    virtual int remove_fork_catchpoint (int)
       TARGET_DEFAULT_RETURN (1);
-    int (*to_insert_vfork_catchpoint) (struct target_ops *, int)
+    virtual int insert_vfork_catchpoint (int)
       TARGET_DEFAULT_RETURN (1);
-    int (*to_remove_vfork_catchpoint) (struct target_ops *, int)
+    virtual int remove_vfork_catchpoint (int)
       TARGET_DEFAULT_RETURN (1);
-    int (*to_follow_fork) (struct target_ops *, int, int)
+    virtual int follow_fork (int, int)
       TARGET_DEFAULT_FUNC (default_follow_fork);
-    int (*to_insert_exec_catchpoint) (struct target_ops *, int)
+    virtual int insert_exec_catchpoint (int)
       TARGET_DEFAULT_RETURN (1);
-    int (*to_remove_exec_catchpoint) (struct target_ops *, int)
+    virtual int remove_exec_catchpoint (int)
       TARGET_DEFAULT_RETURN (1);
-    void (*to_follow_exec) (struct target_ops *, struct inferior *, char *)
+    virtual void follow_exec (struct inferior *, char *)
       TARGET_DEFAULT_IGNORE ();
-    int (*to_set_syscall_catchpoint) (struct target_ops *,
-				      int, bool, int,
-				      gdb::array_view<const int>)
+    virtual int set_syscall_catchpoint (int, bool, int,
+					gdb::array_view<const int>)
       TARGET_DEFAULT_RETURN (1);
-    void (*to_mourn_inferior) (struct target_ops *)
+    virtual void mourn_inferior ()
       TARGET_DEFAULT_FUNC (default_mourn_inferior);
-    /* Note that to_can_run is special and can be invoked on an
-       unpushed target.  Targets defining this method must also define
+
+    /* Note that can_run is special and can be invoked on an unpushed
+       target.  Targets defining this method must also define
        to_can_async_p and to_supports_non_stop.  */
-    int (*to_can_run) (struct target_ops *)
-      TARGET_DEFAULT_RETURN (0);
+    virtual int can_run ();
 
     /* Documentation of this routine is provided with the corresponding
        target_* macro.  */
-    void (*to_pass_signals) (struct target_ops *, int,
-			     unsigned char * TARGET_DEBUG_PRINTER (target_debug_print_signals))
+    virtual void pass_signals (int,
+			       unsigned char * TARGET_DEBUG_PRINTER (target_debug_print_signals))
       TARGET_DEFAULT_IGNORE ();
 
     /* Documentation of this routine is provided with the
        corresponding target_* function.  */
-    void (*to_program_signals) (struct target_ops *, int,
-				unsigned char * TARGET_DEBUG_PRINTER (target_debug_print_signals))
+    virtual void program_signals (int,
+				  unsigned char * TARGET_DEBUG_PRINTER (target_debug_print_signals))
       TARGET_DEFAULT_IGNORE ();
 
-    int (*to_thread_alive) (struct target_ops *, ptid_t ptid)
+    virtual int thread_alive (ptid_t ptid)
       TARGET_DEFAULT_RETURN (0);
-    void (*to_update_thread_list) (struct target_ops *)
+    virtual void update_thread_list ()
       TARGET_DEFAULT_IGNORE ();
-    const char *(*to_pid_to_str) (struct target_ops *, ptid_t)
+    virtual const char *pid_to_str (ptid_t)
       TARGET_DEFAULT_FUNC (default_pid_to_str);
-    const char *(*to_extra_thread_info) (struct target_ops *, struct thread_info *)
+    virtual const char *extra_thread_info (thread_info *)
       TARGET_DEFAULT_RETURN (NULL);
-    const char *(*to_thread_name) (struct target_ops *, struct thread_info *)
+    virtual const char *thread_name (thread_info *)
       TARGET_DEFAULT_RETURN (NULL);
-    struct thread_info *(*to_thread_handle_to_thread_info) (struct target_ops *,
-                                                            const gdb_byte *,
-							    int,
-							    struct inferior *inf)
+    virtual thread_info *thread_handle_to_thread_info (const gdb_byte *,
+						       int,
+						       inferior *inf)
       TARGET_DEFAULT_RETURN (NULL);
-    void (*to_stop) (struct target_ops *, ptid_t)
+    virtual void stop (ptid_t)
       TARGET_DEFAULT_IGNORE ();
-    void (*to_interrupt) (struct target_ops *)
+    virtual void interrupt ()
       TARGET_DEFAULT_IGNORE ();
-    void (*to_pass_ctrlc) (struct target_ops *)
+    virtual void pass_ctrlc ()
       TARGET_DEFAULT_FUNC (default_target_pass_ctrlc);
-    void (*to_rcmd) (struct target_ops *,
-		     const char *command, struct ui_file *output)
+    virtual void rcmd (const char *command, struct ui_file *output)
       TARGET_DEFAULT_FUNC (default_rcmd);
-    char *(*to_pid_to_exec_file) (struct target_ops *, int pid)
+    virtual char *pid_to_exec_file (int pid)
       TARGET_DEFAULT_RETURN (NULL);
-    void (*to_log_command) (struct target_ops *, const char *)
+    virtual void log_command (const char *)
       TARGET_DEFAULT_IGNORE ();
-    struct target_section_table *(*to_get_section_table) (struct target_ops *)
+    virtual struct target_section_table *get_section_table ()
       TARGET_DEFAULT_RETURN (NULL);
     enum strata to_stratum;
-    int (*to_has_all_memory) (struct target_ops *);
-    int (*to_has_memory) (struct target_ops *);
-    int (*to_has_stack) (struct target_ops *);
-    int (*to_has_registers) (struct target_ops *);
-    int (*to_has_execution) (struct target_ops *, ptid_t);
-    int to_has_thread_control;	/* control thread execution */
-    int to_attach_no_wait;
+
+    /* Provide default values for all "must have" methods.  */
+    virtual int has_all_memory () { return 0; }
+    virtual int has_memory () { return 0; }
+    virtual int has_stack () { return 0; }
+    virtual int has_registers () { return 0; }
+    virtual int has_execution (ptid_t) { return 0; }
+
+    /* Control thread execution.  */
+    virtual thread_control_capabilities get_thread_control_capabilities ()
+      TARGET_DEFAULT_RETURN (tc_none);
+    virtual bool attach_no_wait ()
+      TARGET_DEFAULT_RETURN (0);
     /* This method must be implemented in some situations.  See the
-       comment on 'to_can_run'.  */
-    int (*to_can_async_p) (struct target_ops *)
+       comment on 'can_run'.  */
+    virtual int can_async_p ()
       TARGET_DEFAULT_RETURN (0);
-    int (*to_is_async_p) (struct target_ops *)
+    virtual int is_async_p ()
       TARGET_DEFAULT_RETURN (0);
-    void (*to_async) (struct target_ops *, int)
+    virtual void async (int)
       TARGET_DEFAULT_NORETURN (tcomplain ());
-    void (*to_thread_events) (struct target_ops *, int)
+    virtual void thread_events (int)
       TARGET_DEFAULT_IGNORE ();
     /* This method must be implemented in some situations.  See the
-       comment on 'to_can_run'.  */
-    int (*to_supports_non_stop) (struct target_ops *)
+       comment on 'can_run'.  */
+    virtual int supports_non_stop ()
       TARGET_DEFAULT_RETURN (0);
     /* Return true if the target operates in non-stop mode even with
        "set non-stop off".  */
-    int (*to_always_non_stop_p) (struct target_ops *)
+    virtual int always_non_stop_p ()
       TARGET_DEFAULT_RETURN (0);
     /* find_memory_regions support method for gcore */
-    int (*to_find_memory_regions) (struct target_ops *,
-				   find_memory_region_ftype func, void *data)
+    virtual int find_memory_regions (find_memory_region_ftype func, void *data)
       TARGET_DEFAULT_FUNC (dummy_find_memory_regions);
     /* make_corefile_notes support method for gcore */
-    char * (*to_make_corefile_notes) (struct target_ops *, bfd *, int *)
+    virtual char *make_corefile_notes (bfd *, int *)
       TARGET_DEFAULT_FUNC (dummy_make_corefile_notes);
     /* get_bookmark support method for bookmarks */
-    gdb_byte * (*to_get_bookmark) (struct target_ops *, const char *, int)
+    virtual gdb_byte *get_bookmark (const char *, int)
       TARGET_DEFAULT_NORETURN (tcomplain ());
     /* goto_bookmark support method for bookmarks */
-    void (*to_goto_bookmark) (struct target_ops *, const gdb_byte *, int)
+    virtual void goto_bookmark (const gdb_byte *, int)
       TARGET_DEFAULT_NORETURN (tcomplain ());
     /* Return the thread-local address at OFFSET in the
        thread-local storage for the thread PTID and the shared library
@@ -693,10 +699,9 @@ struct target_ops
        thread-local storage hasn't been allocated yet, this function
        may return an error.  LOAD_MODULE_ADDR may be zero for statically
        linked multithreaded inferiors.  */
-    CORE_ADDR (*to_get_thread_local_address) (struct target_ops *ops,
-					      ptid_t ptid,
-					      CORE_ADDR load_module_addr,
-					      CORE_ADDR offset)
+    virtual CORE_ADDR get_thread_local_address (ptid_t ptid,
+						CORE_ADDR load_module_addr,
+						CORE_ADDR offset)
       TARGET_DEFAULT_NORETURN (generic_tls_error ());
 
     /* Request that OPS transfer up to LEN addressable units of the target's
@@ -731,19 +736,18 @@ struct target_ops
        See target_read and target_write for more information.  One,
        and only one, of readbuf or writebuf must be non-NULL.  */
 
-    enum target_xfer_status (*to_xfer_partial) (struct target_ops *ops,
-						enum target_object object,
-						const char *annex,
-						gdb_byte *readbuf,
-						const gdb_byte *writebuf,
-						ULONGEST offset, ULONGEST len,
-						ULONGEST *xfered_len)
+    virtual enum target_xfer_status xfer_partial (enum target_object object,
+						  const char *annex,
+						  gdb_byte *readbuf,
+						  const gdb_byte *writebuf,
+						  ULONGEST offset, ULONGEST len,
+						  ULONGEST *xfered_len)
       TARGET_DEFAULT_RETURN (TARGET_XFER_E_IO);
 
     /* Return the limit on the size of any single memory transfer
        for the target.  */
 
-    ULONGEST (*to_get_memory_xfer_limit) (struct target_ops *)
+    virtual ULONGEST get_memory_xfer_limit ()
       TARGET_DEFAULT_RETURN (ULONGEST_MAX);
 
     /* Returns the memory map for the target.  A return value of NULL
@@ -759,7 +763,7 @@ struct target_ops
        This method should not cache data; if the memory map could
        change unexpectedly, it should be invalidated, and higher
        layers will re-fetch it.  */
-    std::vector<mem_region> (*to_memory_map) (struct target_ops *)
+    virtual std::vector<mem_region> memory_map ()
       TARGET_DEFAULT_RETURN (std::vector<mem_region> ());
 
     /* Erases the region of flash memory starting at ADDRESS, of
@@ -767,38 +771,36 @@ struct target_ops
 
        Precondition: both ADDRESS and ADDRESS+LENGTH should be aligned
        on flash block boundaries, as reported by 'to_memory_map'.  */
-    void (*to_flash_erase) (struct target_ops *,
-                           ULONGEST address, LONGEST length)
+    virtual void flash_erase (ULONGEST address, LONGEST length)
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
     /* Finishes a flash memory write sequence.  After this operation
        all flash memory should be available for writing and the result
        of reading from areas written by 'to_flash_write' should be
        equal to what was written.  */
-    void (*to_flash_done) (struct target_ops *)
+    virtual void flash_done ()
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
     /* Describe the architecture-specific features of this target.  If
        OPS doesn't have a description, this should delegate to the
        "beneath" target.  Returns the description found, or NULL if no
        description was available.  */
-    const struct target_desc *(*to_read_description) (struct target_ops *ops)
+    virtual const struct target_desc *read_description ()
 	 TARGET_DEFAULT_RETURN (NULL);
 
     /* Build the PTID of the thread on which a given task is running,
        based on LWP and THREAD.  These values are extracted from the
        task Private_Data section of the Ada Task Control Block, and
        their interpretation depends on the target.  */
-    ptid_t (*to_get_ada_task_ptid) (struct target_ops *,
-				    long lwp, long thread)
+    virtual ptid_t get_ada_task_ptid (long lwp, long thread)
       TARGET_DEFAULT_FUNC (default_get_ada_task_ptid);
 
     /* Read one auxv entry from *READPTR, not reading locations >= ENDPTR.
        Return 0 if *READPTR is already at the end of the buffer.
        Return -1 if there is insufficient buffer for a whole entry.
        Return 1 if an entry was read into *TYPEP and *VALP.  */
-    int (*to_auxv_parse) (struct target_ops *ops, gdb_byte **readptr,
-                         gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
+    virtual int auxv_parse (gdb_byte **readptr,
+			    gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
       TARGET_DEFAULT_FUNC (default_auxv_parse);
 
     /* Search SEARCH_SPACE_LEN bytes beginning at START_ADDR for the
@@ -807,47 +809,47 @@ struct target_ops
        The result is 1 if found, 0 if not found, and -1 if there was an error
        requiring halting of the search (e.g. memory read error).
        If the pattern is found the address is recorded in FOUND_ADDRP.  */
-    int (*to_search_memory) (struct target_ops *ops,
-			     CORE_ADDR start_addr, ULONGEST search_space_len,
-			     const gdb_byte *pattern, ULONGEST pattern_len,
-			     CORE_ADDR *found_addrp)
+    virtual int search_memory (CORE_ADDR start_addr, ULONGEST search_space_len,
+			       const gdb_byte *pattern, ULONGEST pattern_len,
+			       CORE_ADDR *found_addrp)
       TARGET_DEFAULT_FUNC (default_search_memory);
 
     /* Can target execute in reverse?  */
-    int (*to_can_execute_reverse) (struct target_ops *)
+    virtual int can_execute_reverse ()
       TARGET_DEFAULT_RETURN (0);
 
     /* The direction the target is currently executing.  Must be
        implemented on targets that support reverse execution and async
        mode.  The default simply returns forward execution.  */
-    enum exec_direction_kind (*to_execution_direction) (struct target_ops *)
+    virtual enum exec_direction_kind execution_direction ()
       TARGET_DEFAULT_FUNC (default_execution_direction);
 
     /* Does this target support debugging multiple processes
        simultaneously?  */
-    int (*to_supports_multi_process) (struct target_ops *)
+    virtual int supports_multi_process ()
       TARGET_DEFAULT_RETURN (0);
 
     /* Does this target support enabling and disabling tracepoints while a trace
        experiment is running?  */
-    int (*to_supports_enable_disable_tracepoint) (struct target_ops *)
+    virtual int supports_enable_disable_tracepoint ()
       TARGET_DEFAULT_RETURN (0);
 
     /* Does this target support disabling address space randomization?  */
-    int (*to_supports_disable_randomization) (struct target_ops *);
+    virtual int supports_disable_randomization ()
+      TARGET_DEFAULT_FUNC (find_default_supports_disable_randomization);
 
     /* Does this target support the tracenz bytecode for string collection?  */
-    int (*to_supports_string_tracing) (struct target_ops *)
+    virtual int supports_string_tracing ()
       TARGET_DEFAULT_RETURN (0);
 
     /* Does this target support evaluation of breakpoint conditions on its
        end?  */
-    int (*to_supports_evaluation_of_breakpoint_conditions) (struct target_ops *)
+    virtual int supports_evaluation_of_breakpoint_conditions ()
       TARGET_DEFAULT_RETURN (0);
 
     /* Does this target support evaluation of breakpoint commands on its
        end?  */
-    int (*to_can_run_breakpoint_commands) (struct target_ops *)
+    virtual int can_run_breakpoint_commands ()
       TARGET_DEFAULT_RETURN (0);
 
     /* Determine current architecture of thread PTID.
@@ -860,22 +862,21 @@ struct target_ops
        ptrace operations need to operate according to target_gdbarch ().
 
        The default implementation always returns target_gdbarch ().  */
-    struct gdbarch *(*to_thread_architecture) (struct target_ops *, ptid_t)
+    virtual struct gdbarch *thread_architecture (ptid_t)
       TARGET_DEFAULT_FUNC (default_thread_architecture);
 
     /* Determine current address space of thread PTID.
 
        The default implementation always returns the inferior's
        address space.  */
-    struct address_space *(*to_thread_address_space) (struct target_ops *,
-						      ptid_t)
+    virtual struct address_space *thread_address_space (ptid_t)
       TARGET_DEFAULT_FUNC (default_thread_address_space);
 
     /* Target file operations.  */
 
     /* Return nonzero if the filesystem seen by the current inferior
        is the local filesystem, zero otherwise.  */
-    int (*to_filesystem_is_local) (struct target_ops *)
+    virtual int filesystem_is_local ()
       TARGET_DEFAULT_RETURN (1);
 
     /* Open FILENAME on the target, in the filesystem as seen by INF,
@@ -885,111 +886,99 @@ struct target_ops
        is being accessed over a link that may be slow.  Return a
        target file descriptor, or -1 if an error occurs (and set
        *TARGET_ERRNO).  */
-    int (*to_fileio_open) (struct target_ops *,
-			   struct inferior *inf, const char *filename,
-			   int flags, int mode, int warn_if_slow,
-			   int *target_errno);
+    virtual int fileio_open (struct inferior *inf, const char *filename,
+			     int flags, int mode, int warn_if_slow,
+			     int *target_errno);
 
     /* Write up to LEN bytes from WRITE_BUF to FD on the target.
        Return the number of bytes written, or -1 if an error occurs
        (and set *TARGET_ERRNO).  */
-    int (*to_fileio_pwrite) (struct target_ops *,
-			     int fd, const gdb_byte *write_buf, int len,
-			     ULONGEST offset, int *target_errno);
+    virtual int fileio_pwrite (int fd, const gdb_byte *write_buf, int len,
+			       ULONGEST offset, int *target_errno);
 
     /* Read up to LEN bytes FD on the target into READ_BUF.
        Return the number of bytes read, or -1 if an error occurs
        (and set *TARGET_ERRNO).  */
-    int (*to_fileio_pread) (struct target_ops *,
-			    int fd, gdb_byte *read_buf, int len,
-			    ULONGEST offset, int *target_errno);
+    virtual int fileio_pread (int fd, gdb_byte *read_buf, int len,
+			      ULONGEST offset, int *target_errno);
 
     /* Get information about the file opened as FD and put it in
        SB.  Return 0 on success, or -1 if an error occurs (and set
        *TARGET_ERRNO).  */
-    int (*to_fileio_fstat) (struct target_ops *,
-			    int fd, struct stat *sb, int *target_errno);
+    virtual int fileio_fstat (int fd, struct stat *sb, int *target_errno);
 
     /* Close FD on the target.  Return 0, or -1 if an error occurs
        (and set *TARGET_ERRNO).  */
-    int (*to_fileio_close) (struct target_ops *, int fd, int *target_errno);
+    virtual int fileio_close (int fd, int *target_errno);
 
     /* Unlink FILENAME on the target, in the filesystem as seen by
        INF.  If INF is NULL, use the filesystem seen by the debugger
        (GDB or, for remote targets, the remote stub).  Return 0, or
        -1 if an error occurs (and set *TARGET_ERRNO).  */
-    int (*to_fileio_unlink) (struct target_ops *,
-			     struct inferior *inf,
-			     const char *filename,
-			     int *target_errno);
+    virtual int fileio_unlink (struct inferior *inf,
+			       const char *filename,
+			       int *target_errno);
 
     /* Read value of symbolic link FILENAME on the target, in the
        filesystem as seen by INF.  If INF is NULL, use the filesystem
        seen by the debugger (GDB or, for remote targets, the remote
        stub).  Return a string, or an empty optional if an error
        occurs (and set *TARGET_ERRNO).  */
-    gdb::optional<std::string> (*to_fileio_readlink) (struct target_ops *,
-						      struct inferior *inf,
-						      const char *filename,
-						      int *target_errno);
+    virtual gdb::optional<std::string> fileio_readlink (struct inferior *inf,
+							const char *filename,
+							int *target_errno);
 
-
-    /* Implement the "info proc" command.  */
-    void (*to_info_proc) (struct target_ops *, const char *,
-			  enum info_proc_what);
+    /* Implement the "info proc" command.  Returns true if the target
+       actually implemented the command, false otherwise.  */
+    virtual bool info_proc (const char *, enum info_proc_what);
 
     /* Tracepoint-related operations.  */
 
     /* Prepare the target for a tracing run.  */
-    void (*to_trace_init) (struct target_ops *)
+    virtual void trace_init ()
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
     /* Send full details of a tracepoint location to the target.  */
-    void (*to_download_tracepoint) (struct target_ops *,
-				    struct bp_location *location)
+    virtual void download_tracepoint (struct bp_location *location)
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
     /* Is the target able to download tracepoint locations in current
        state?  */
-    int (*to_can_download_tracepoint) (struct target_ops *)
+    virtual int can_download_tracepoint ()
       TARGET_DEFAULT_RETURN (0);
 
     /* Send full details of a trace state variable to the target.  */
-    void (*to_download_trace_state_variable) (struct target_ops *,
-					      const trace_state_variable &tsv)
+    virtual void download_trace_state_variable (const trace_state_variable &tsv)
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
     /* Enable a tracepoint on the target.  */
-    void (*to_enable_tracepoint) (struct target_ops *,
-				  struct bp_location *location)
+    virtual void enable_tracepoint (struct bp_location *location)
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
     /* Disable a tracepoint on the target.  */
-    void (*to_disable_tracepoint) (struct target_ops *,
-				   struct bp_location *location)
+    virtual void disable_tracepoint (struct bp_location *location)
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
     /* Inform the target info of memory regions that are readonly
        (such as text sections), and so it should return data from
        those rather than look in the trace buffer.  */
-    void (*to_trace_set_readonly_regions) (struct target_ops *)
+    virtual void trace_set_readonly_regions ()
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
     /* Start a trace run.  */
-    void (*to_trace_start) (struct target_ops *)
+    virtual void trace_start ()
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
     /* Get the current status of a tracing run.  */
-    int (*to_get_trace_status) (struct target_ops *, struct trace_status *ts)
+    virtual int get_trace_status (struct trace_status *ts)
       TARGET_DEFAULT_RETURN (-1);
 
-    void (*to_get_tracepoint_status) (struct target_ops *,
-				      struct breakpoint *tp,
-				      struct uploaded_tp *utp)
+    virtual void get_tracepoint_status (struct breakpoint *tp,
+					struct uploaded_tp *utp)
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
     /* Stop a trace run.  */
-    void (*to_trace_stop) (struct target_ops *)
+    virtual void trace_stop ()
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
    /* Ask the target to find a trace frame of the given type TYPE,
@@ -997,55 +986,50 @@ struct target_ops
       number of the trace frame, and also the tracepoint number at
       TPP.  If no trace frame matches, return -1.  May throw if the
       operation fails.  */
-    int (*to_trace_find) (struct target_ops *,
-			  enum trace_find_type type, int num,
-			  CORE_ADDR addr1, CORE_ADDR addr2, int *tpp)
+    virtual int trace_find (enum trace_find_type type, int num,
+			    CORE_ADDR addr1, CORE_ADDR addr2, int *tpp)
       TARGET_DEFAULT_RETURN (-1);
 
     /* Get the value of the trace state variable number TSV, returning
        1 if the value is known and writing the value itself into the
        location pointed to by VAL, else returning 0.  */
-    int (*to_get_trace_state_variable_value) (struct target_ops *,
-					      int tsv, LONGEST *val)
+    virtual int get_trace_state_variable_value (int tsv, LONGEST *val)
       TARGET_DEFAULT_RETURN (0);
 
-    int (*to_save_trace_data) (struct target_ops *, const char *filename)
+    virtual int save_trace_data (const char *filename)
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
-    int (*to_upload_tracepoints) (struct target_ops *,
-				  struct uploaded_tp **utpp)
+    virtual int upload_tracepoints (struct uploaded_tp **utpp)
       TARGET_DEFAULT_RETURN (0);
 
-    int (*to_upload_trace_state_variables) (struct target_ops *,
-					    struct uploaded_tsv **utsvp)
+    virtual int upload_trace_state_variables (struct uploaded_tsv **utsvp)
       TARGET_DEFAULT_RETURN (0);
 
-    LONGEST (*to_get_raw_trace_data) (struct target_ops *, gdb_byte *buf,
-				      ULONGEST offset, LONGEST len)
+    virtual LONGEST get_raw_trace_data (gdb_byte *buf,
+					ULONGEST offset, LONGEST len)
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
     /* Get the minimum length of instruction on which a fast tracepoint
        may be set on the target.  If this operation is unsupported,
        return -1.  If for some reason the minimum length cannot be
        determined, return 0.  */
-    int (*to_get_min_fast_tracepoint_insn_len) (struct target_ops *)
+    virtual int get_min_fast_tracepoint_insn_len ()
       TARGET_DEFAULT_RETURN (-1);
 
     /* Set the target's tracing behavior in response to unexpected
        disconnection - set VAL to 1 to keep tracing, 0 to stop.  */
-    void (*to_set_disconnected_tracing) (struct target_ops *, int val)
+    virtual void set_disconnected_tracing (int val)
       TARGET_DEFAULT_IGNORE ();
-    void (*to_set_circular_trace_buffer) (struct target_ops *, int val)
+    virtual void set_circular_trace_buffer (int val)
       TARGET_DEFAULT_IGNORE ();
     /* Set the size of trace buffer in the target.  */
-    void (*to_set_trace_buffer_size) (struct target_ops *, LONGEST val)
+    virtual void set_trace_buffer_size (LONGEST val)
       TARGET_DEFAULT_IGNORE ();
 
     /* Add/change textual notes about the trace run, returning 1 if
        successful, 0 otherwise.  */
-    int (*to_set_trace_notes) (struct target_ops *,
-			       const char *user, const char *notes,
-			       const char *stopnotes)
+    virtual int set_trace_notes (const char *user, const char *notes,
+				 const char *stopnotes)
       TARGET_DEFAULT_RETURN (0);
 
     /* Return the processor core that thread PTID was last seen on.
@@ -1055,222 +1039,201 @@ struct target_ops
        If the core cannot be determined -- either for the specified
        thread, or right now, or in this debug session, or for this
        target -- return -1.  */
-    int (*to_core_of_thread) (struct target_ops *, ptid_t ptid)
+    virtual int core_of_thread (ptid_t ptid)
       TARGET_DEFAULT_RETURN (-1);
 
     /* Verify that the memory in the [MEMADDR, MEMADDR+SIZE) range
        matches the contents of [DATA,DATA+SIZE).  Returns 1 if there's
        a match, 0 if there's a mismatch, and -1 if an error is
        encountered while reading memory.  */
-    int (*to_verify_memory) (struct target_ops *, const gdb_byte *data,
-			     CORE_ADDR memaddr, ULONGEST size)
+    virtual int verify_memory (const gdb_byte *data,
+			       CORE_ADDR memaddr, ULONGEST size)
       TARGET_DEFAULT_FUNC (default_verify_memory);
 
     /* Return the address of the start of the Thread Information Block
        a Windows OS specific feature.  */
-    int (*to_get_tib_address) (struct target_ops *,
-			       ptid_t ptid, CORE_ADDR *addr)
+    virtual int get_tib_address (ptid_t ptid, CORE_ADDR *addr)
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
     /* Send the new settings of write permission variables.  */
-    void (*to_set_permissions) (struct target_ops *)
+    virtual void set_permissions ()
       TARGET_DEFAULT_IGNORE ();
 
     /* Look for a static tracepoint marker at ADDR, and fill in MARKER
        with its details.  Return true on success, false on failure.  */
-    bool (*to_static_tracepoint_marker_at) (struct target_ops *, CORE_ADDR,
-					    static_tracepoint_marker *marker)
+    virtual bool static_tracepoint_marker_at (CORE_ADDR,
+					      static_tracepoint_marker *marker)
       TARGET_DEFAULT_RETURN (false);
 
     /* Return a vector of all tracepoints markers string id ID, or all
        markers if ID is NULL.  */
-    std::vector<static_tracepoint_marker>
-      (*to_static_tracepoint_markers_by_strid) (struct target_ops *,
-						const char *id)
+    virtual std::vector<static_tracepoint_marker> static_tracepoint_markers_by_strid (const char *id)
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
     /* Return a traceframe info object describing the current
        traceframe's contents.  This method should not cache data;
        higher layers take care of caching, invalidating, and
        re-fetching when necessary.  */
-    traceframe_info_up (*to_traceframe_info) (struct target_ops *)
+    virtual traceframe_info_up traceframe_info ()
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
     /* Ask the target to use or not to use agent according to USE.  Return 1
        successful, 0 otherwise.  */
-    int (*to_use_agent) (struct target_ops *, int use)
+    virtual int use_agent (int use)
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
     /* Is the target able to use agent in current state?  */
-    int (*to_can_use_agent) (struct target_ops *)
+    virtual int can_use_agent ()
       TARGET_DEFAULT_RETURN (0);
 
     /* Enable branch tracing for PTID using CONF configuration.
        Return a branch trace target information struct for reading and for
        disabling branch trace.  */
-    struct btrace_target_info *(*to_enable_btrace) (struct target_ops *,
-						    ptid_t ptid,
-						    const struct btrace_config *conf)
+    virtual struct btrace_target_info *enable_btrace (ptid_t ptid,
+						      const struct btrace_config *conf)
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
     /* Disable branch tracing and deallocate TINFO.  */
-    void (*to_disable_btrace) (struct target_ops *,
-			       struct btrace_target_info *tinfo)
+    virtual void disable_btrace (struct btrace_target_info *tinfo)
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
     /* Disable branch tracing and deallocate TINFO.  This function is similar
        to to_disable_btrace, except that it is called during teardown and is
        only allowed to perform actions that are safe.  A counter-example would
        be attempting to talk to a remote target.  */
-    void (*to_teardown_btrace) (struct target_ops *,
-				struct btrace_target_info *tinfo)
+    virtual void teardown_btrace (struct btrace_target_info *tinfo)
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
     /* Read branch trace data for the thread indicated by BTINFO into DATA.
        DATA is cleared before new trace is added.  */
-    enum btrace_error (*to_read_btrace) (struct target_ops *self,
-					 struct btrace_data *data,
-					 struct btrace_target_info *btinfo,
-					 enum btrace_read_type type)
+    virtual enum btrace_error read_btrace (struct btrace_data *data,
+					   struct btrace_target_info *btinfo,
+					   enum btrace_read_type type)
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
     /* Get the branch trace configuration.  */
-    const struct btrace_config *(*to_btrace_conf) (struct target_ops *self,
-						   const struct btrace_target_info *)
+    virtual const struct btrace_config *btrace_conf (const struct btrace_target_info *)
       TARGET_DEFAULT_RETURN (NULL);
 
     /* Current recording method.  */
-    enum record_method (*to_record_method) (struct target_ops *, ptid_t ptid)
+    virtual enum record_method record_method (ptid_t ptid)
       TARGET_DEFAULT_RETURN (RECORD_METHOD_NONE);
 
     /* Stop trace recording.  */
-    void (*to_stop_recording) (struct target_ops *)
+    virtual void stop_recording ()
       TARGET_DEFAULT_IGNORE ();
 
     /* Print information about the recording.  */
-    void (*to_info_record) (struct target_ops *)
+    virtual void info_record ()
       TARGET_DEFAULT_IGNORE ();
 
     /* Save the recorded execution trace into a file.  */
-    void (*to_save_record) (struct target_ops *, const char *filename)
+    virtual void save_record (const char *filename)
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
     /* Delete the recorded execution trace from the current position
        onwards.  */
-    void (*to_delete_record) (struct target_ops *)
+    virtual bool supports_delete_record ()
+      TARGET_DEFAULT_RETURN (false);
+    virtual void delete_record ()
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
     /* Query if the record target is currently replaying PTID.  */
-    int (*to_record_is_replaying) (struct target_ops *, ptid_t ptid)
+    virtual int record_is_replaying (ptid_t ptid)
       TARGET_DEFAULT_RETURN (0);
 
     /* Query if the record target will replay PTID if it were resumed in
        execution direction DIR.  */
-    int (*to_record_will_replay) (struct target_ops *, ptid_t ptid, int dir)
+    virtual int record_will_replay (ptid_t ptid, int dir)
       TARGET_DEFAULT_RETURN (0);
 
     /* Stop replaying.  */
-    void (*to_record_stop_replaying) (struct target_ops *)
+    virtual void record_stop_replaying ()
       TARGET_DEFAULT_IGNORE ();
 
     /* Go to the begin of the execution trace.  */
-    void (*to_goto_record_begin) (struct target_ops *)
+    virtual void goto_record_begin ()
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
     /* Go to the end of the execution trace.  */
-    void (*to_goto_record_end) (struct target_ops *)
+    virtual void goto_record_end ()
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
     /* Go to a specific location in the recorded execution trace.  */
-    void (*to_goto_record) (struct target_ops *, ULONGEST insn)
+    virtual void goto_record (ULONGEST insn)
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
     /* Disassemble SIZE instructions in the recorded execution trace from
        the current position.
        If SIZE < 0, disassemble abs (SIZE) preceding instructions; otherwise,
        disassemble SIZE succeeding instructions.  */
-    void (*to_insn_history) (struct target_ops *, int size,
-			     gdb_disassembly_flags flags)
+    virtual void insn_history (int size, gdb_disassembly_flags flags)
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
     /* Disassemble SIZE instructions in the recorded execution trace around
        FROM.
        If SIZE < 0, disassemble abs (SIZE) instructions before FROM; otherwise,
        disassemble SIZE instructions after FROM.  */
-    void (*to_insn_history_from) (struct target_ops *,
-				  ULONGEST from, int size,
-				  gdb_disassembly_flags flags)
+    virtual void insn_history_from (ULONGEST from, int size,
+				    gdb_disassembly_flags flags)
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
     /* Disassemble a section of the recorded execution trace from instruction
        BEGIN (inclusive) to instruction END (inclusive).  */
-    void (*to_insn_history_range) (struct target_ops *,
-				   ULONGEST begin, ULONGEST end,
-				   gdb_disassembly_flags flags)
+    virtual void insn_history_range (ULONGEST begin, ULONGEST end,
+				     gdb_disassembly_flags flags)
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
     /* Print a function trace of the recorded execution trace.
        If SIZE < 0, print abs (SIZE) preceding functions; otherwise, print SIZE
        succeeding functions.  */
-    void (*to_call_history) (struct target_ops *, int size, record_print_flags flags)
+    virtual void call_history (int size, record_print_flags flags)
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
     /* Print a function trace of the recorded execution trace starting
        at function FROM.
        If SIZE < 0, print abs (SIZE) functions before FROM; otherwise, print
        SIZE functions after FROM.  */
-    void (*to_call_history_from) (struct target_ops *,
-				  ULONGEST begin, int size, record_print_flags flags)
+    virtual void call_history_from (ULONGEST begin, int size, record_print_flags flags)
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
     /* Print a function trace of an execution trace section from function BEGIN
        (inclusive) to function END (inclusive).  */
-    void (*to_call_history_range) (struct target_ops *,
-				   ULONGEST begin, ULONGEST end, record_print_flags flags)
+    virtual void call_history_range (ULONGEST begin, ULONGEST end, record_print_flags flags)
       TARGET_DEFAULT_NORETURN (tcomplain ());
 
     /* Nonzero if TARGET_OBJECT_LIBRARIES_SVR4 may be read with a
        non-empty annex.  */
-    int (*to_augmented_libraries_svr4_read) (struct target_ops *)
+    virtual int augmented_libraries_svr4_read ()
       TARGET_DEFAULT_RETURN (0);
 
     /* Those unwinders are tried before any other arch unwinders.  If
        SELF doesn't have unwinders, it should delegate to the
        "beneath" target.  */
-    const struct frame_unwind *(*to_get_unwinder) (struct target_ops *self)
+    virtual const struct frame_unwind *get_unwinder ()
       TARGET_DEFAULT_RETURN (NULL);
 
-    const struct frame_unwind *(*to_get_tailcall_unwinder) (struct target_ops *self)
+    virtual const struct frame_unwind *get_tailcall_unwinder ()
       TARGET_DEFAULT_RETURN (NULL);
 
     /* Prepare to generate a core file.  */
-    void (*to_prepare_to_generate_core) (struct target_ops *)
+    virtual void prepare_to_generate_core ()
       TARGET_DEFAULT_IGNORE ();
 
     /* Cleanup after generating a core file.  */
-    void (*to_done_generating_core) (struct target_ops *)
+    virtual void done_generating_core ()
       TARGET_DEFAULT_IGNORE ();
-
-    int to_magic;
-    /* Need sub-structure for target machine related rather than comm related?
-     */
   };
 
-/* Magic number for checking ops size.  If a struct doesn't end with this
-   number, somebody changed the declaration but didn't change all the
-   places that initialize one.  */
-
-#define	OPS_MAGIC	3840
-
 /* The ops structure for our "current" target process.  This should
    never be NULL.  If there is no target, it points to the dummy_target.  */
 
-extern struct target_ops current_target;
+extern struct target_ops *target_stack;
 
 /* Define easy words for doing these operations on our current target.  */
 
-#define	target_shortname	(current_target.to_shortname)
-#define	target_longname		(current_target.to_longname)
+#define	target_shortname	(target_stack->shortname ())
+#define	target_longname		(target_stack->longname ())
 
 /* Does whatever cleanup is required for a target that we are no
    longer going to be calling.  This routine is automatically always
@@ -1297,8 +1260,8 @@ extern struct target_ops *find_run_target (void);
    or their target_attach implementation takes care of the waiting.
    These targets must set to_attach_no_wait.  */
 
-#define target_attach_no_wait \
-     (current_target.to_attach_no_wait)
+#define target_attach_no_wait() \
+  (target_stack->attach_no_wait ())
 
 /* The target_attach operation places a process under debugger control,
    and stops the process.
@@ -1306,7 +1269,7 @@ extern struct target_ops *find_run_target (void);
    This operation provides a target-specific hook that allows the
    necessary bookkeeping to be performed after an attach completes.  */
 #define target_post_attach(pid) \
-     (*current_target.to_post_attach) (&current_target, pid)
+     (target_stack->post_attach) (pid)
 
 /* Display a message indicating we're about to detach from the current
    inferior process.  */
@@ -1388,7 +1351,7 @@ extern void target_store_registers (struct regcache *regcache, int regs);
    debugged.  */
 
 #define	target_prepare_to_store(regcache)	\
-     (*current_target.to_prepare_to_store) (&current_target, regcache)
+     (target_stack->prepare_to_store) (regcache)
 
 /* Determine current address space of thread PTID.  */
 
@@ -1409,22 +1372,22 @@ int target_supports_disable_randomization (void);
    while a trace experiment is running.  */
 
 #define target_supports_enable_disable_tracepoint() \
-  (*current_target.to_supports_enable_disable_tracepoint) (&current_target)
+  (target_stack->supports_enable_disable_tracepoint) ()
 
 #define target_supports_string_tracing() \
-  (*current_target.to_supports_string_tracing) (&current_target)
+  (target_stack->supports_string_tracing) ()
 
 /* Returns true if this target can handle breakpoint conditions
    on its end.  */
 
 #define target_supports_evaluation_of_breakpoint_conditions() \
-  (*current_target.to_supports_evaluation_of_breakpoint_conditions) (&current_target)
+  (target_stack->supports_evaluation_of_breakpoint_conditions) ()
 
 /* Returns true if this target can handle breakpoint commands
    on its end.  */
 
 #define target_can_run_breakpoint_commands() \
-  (*current_target.to_can_run_breakpoint_commands) (&current_target)
+  (target_stack->can_run_breakpoint_commands) ()
 
 extern int target_read_string (CORE_ADDR, gdb::unique_xmalloc_ptr<char> *,
 			       int, int *);
@@ -1507,7 +1470,7 @@ int target_write_memory_blocks
 /* Print a line about the current target.  */
 
 #define	target_files_info()	\
-     (*current_target.to_files_info) (&current_target)
+     (target_stack->files_info) ()
 
 /* Insert a breakpoint at address BP_TGT->placed_address in
    the target machine.  Returns 0 for success, and returns non-zero or
@@ -1525,7 +1488,7 @@ extern int target_remove_breakpoint (struct gdbarch *gdbarch,
 				     enum remove_bp_reason reason);
 
 /* Return true if the target stack has a non-default
-  "to_terminal_ours" method.  */
+  "terminal_ours" method.  */
 
 extern int target_supports_terminal_ours (void);
 
@@ -1557,7 +1520,7 @@ extern void target_load (const char *arg, int from_tty);
    Such targets will supply an appropriate definition for this function.  */
 
 #define target_post_startup_inferior(ptid) \
-     (*current_target.to_post_startup_inferior) (&current_target, ptid)
+     (target_stack->post_startup_inferior) (ptid)
 
 /* On some targets, we can catch an inferior fork or vfork event when
    it occurs.  These functions insert/remove an already-created
@@ -1565,16 +1528,16 @@ extern void target_load (const char *arg, int from_tty);
    catchpoint type is not supported and -1 for failure.  */
 
 #define target_insert_fork_catchpoint(pid) \
-     (*current_target.to_insert_fork_catchpoint) (&current_target, pid)
+     (target_stack->insert_fork_catchpoint) (pid)
 
 #define target_remove_fork_catchpoint(pid) \
-     (*current_target.to_remove_fork_catchpoint) (&current_target, pid)
+     (target_stack->remove_fork_catchpoint) (pid)
 
 #define target_insert_vfork_catchpoint(pid) \
-     (*current_target.to_insert_vfork_catchpoint) (&current_target, pid)
+     (target_stack->insert_vfork_catchpoint) (pid)
 
 #define target_remove_vfork_catchpoint(pid) \
-     (*current_target.to_remove_vfork_catchpoint) (&current_target, pid)
+     (target_stack->remove_vfork_catchpoint) (pid)
 
 /* If the inferior forks or vforks, this function will be called at
    the next resume in order to perform any bookkeeping and fiddling
@@ -1597,10 +1560,10 @@ void target_follow_exec (struct inferior *inf, char *execd_pathname);
    catchpoint type is not supported and -1 for failure.  */
 
 #define target_insert_exec_catchpoint(pid) \
-     (*current_target.to_insert_exec_catchpoint) (&current_target, pid)
+     (target_stack->insert_exec_catchpoint) (pid)
 
 #define target_remove_exec_catchpoint(pid) \
-     (*current_target.to_remove_exec_catchpoint) (&current_target, pid)
+     (target_stack->remove_exec_catchpoint) (pid)
 
 /* Syscall catch.
 
@@ -1619,9 +1582,8 @@ void target_follow_exec (struct inferior *inf, char *execd_pathname);
    for failure.  */
 
 #define target_set_syscall_catchpoint(pid, needed, any_count, syscall_counts) \
-     (*current_target.to_set_syscall_catchpoint) (&current_target,	\
-						  pid, needed, any_count, \
-						  syscall_counts)
+     (target_stack->set_syscall_catchpoint) (pid, needed, any_count, \
+					     syscall_counts)
 
 /* The debugger has completed a blocking wait() call.  There is now
    some process event that must be processed.  This function should
@@ -1630,10 +1592,9 @@ void target_follow_exec (struct inferior *inf, char *execd_pathname);
 
 /* For target_mourn_inferior see target/target.h.  */
 
-/* Does target have enough data to do a run or attach command? */
+/* Does target have enough data to do a run or attach command?  */
 
-#define target_can_run(t) \
-     ((t)->to_can_run) (t)
+extern int target_can_run ();
 
 /* Set list of signals to be handled in the target.
 
@@ -1705,7 +1666,7 @@ extern void default_target_pass_ctrlc (struct target_ops *ops);
    placed in OUTBUF.  */
 
 #define target_rcmd(command, outbuf) \
-     (*current_target.to_rcmd) (&current_target, command, outbuf)
+     (target_stack->rcmd) (command, outbuf)
 
 
 /* Does the target include all of memory, or only part of it?  This
@@ -1750,27 +1711,26 @@ extern int target_has_execution_current (void);
 /* Default implementations for process_stratum targets.  Return true
    if there's a selected inferior, false otherwise.  */
 
-extern int default_child_has_all_memory (struct target_ops *ops);
-extern int default_child_has_memory (struct target_ops *ops);
-extern int default_child_has_stack (struct target_ops *ops);
-extern int default_child_has_registers (struct target_ops *ops);
-extern int default_child_has_execution (struct target_ops *ops,
-					ptid_t the_ptid);
+extern int default_child_has_all_memory ();
+extern int default_child_has_memory ();
+extern int default_child_has_stack ();
+extern int default_child_has_registers ();
+extern int default_child_has_execution (ptid_t the_ptid);
 
 /* Can the target support the debugger control of thread execution?
    Can it lock the thread scheduler?  */
 
 #define target_can_lock_scheduler \
-     (current_target.to_has_thread_control & tc_schedlock)
+  (target_stack->get_thread_control_capabilities () & tc_schedlock)
 
 /* Controls whether async mode is permitted.  */
 extern int target_async_permitted;
 
 /* Can the target support asynchronous execution?  */
-#define target_can_async_p() (current_target.to_can_async_p (&current_target))
+#define target_can_async_p() (target_stack->can_async_p ())
 
 /* Is the target in asynchronous execution mode?  */
-#define target_is_async_p() (current_target.to_is_async_p (&current_target))
+#define target_is_async_p() (target_stack->is_async_p ())
 
 /* Enables/disabled async target events.  */
 extern void target_async (int enable);
@@ -1788,7 +1748,7 @@ extern enum auto_boolean target_non_stop_enabled;
 extern int target_is_non_stop_p (void);
 
 #define target_execution_direction() \
-  (current_target.to_execution_direction (&current_target))
+  (target_stack->execution_direction ())
 
 /* Converts a process id to a string.  Usually, the string just contains
    `process xyz', but on some systems it may contain
@@ -1803,7 +1763,7 @@ extern const char *normal_pid_to_str (ptid_t ptid);
    is okay.  */
 
 #define target_extra_thread_info(TP) \
-     (current_target.to_extra_thread_info (&current_target, TP))
+     (target_stack->extra_thread_info (TP))
 
 /* Return the thread's name, or NULL if the target is unable to determine it.
    The returned value must not be freed by the caller.  */
@@ -1829,12 +1789,12 @@ extern struct thread_info *target_thread_handle_to_thread_info
    it must persist.  */
 
 #define target_pid_to_exec_file(pid) \
-     (current_target.to_pid_to_exec_file) (&current_target, pid)
+     (target_stack->pid_to_exec_file) (pid)
 
 /* See the to_thread_architecture description in struct target_ops.  */
 
 #define target_thread_architecture(ptid) \
-     (current_target.to_thread_architecture (&current_target, ptid))
+     (target_stack->thread_architecture (ptid))
 
 /*
  * Iterator function for target memory regions.
@@ -1844,21 +1804,21 @@ extern struct thread_info *target_thread_handle_to_thread_info
  */
 
 #define target_find_memory_regions(FUNC, DATA) \
-     (current_target.to_find_memory_regions) (&current_target, FUNC, DATA)
+     (target_stack->find_memory_regions) (FUNC, DATA)
 
 /*
  * Compose corefile .note section.
  */
 
 #define target_make_corefile_notes(BFD, SIZE_P) \
-     (current_target.to_make_corefile_notes) (&current_target, BFD, SIZE_P)
+     (target_stack->make_corefile_notes) (BFD, SIZE_P)
 
 /* Bookmark interfaces.  */
 #define target_get_bookmark(ARGS, FROM_TTY) \
-     (current_target.to_get_bookmark) (&current_target, ARGS, FROM_TTY)
+     (target_stack->get_bookmark) (ARGS, FROM_TTY)
 
 #define target_goto_bookmark(ARG, FROM_TTY) \
-     (current_target.to_goto_bookmark) (&current_target, ARG, FROM_TTY)
+     (target_stack->goto_bookmark) (ARG, FROM_TTY)
 
 /* Hardware watchpoint interfaces.  */
 
@@ -1866,32 +1826,32 @@ extern struct thread_info *target_thread_handle_to_thread_info
    write).  Only the INFERIOR_PTID task is being queried.  */
 
 #define target_stopped_by_watchpoint()		\
-  ((*current_target.to_stopped_by_watchpoint) (&current_target))
+  ((target_stack->stopped_by_watchpoint) ())
 
 /* Returns non-zero if the target stopped because it executed a
    software breakpoint instruction.  */
 
 #define target_stopped_by_sw_breakpoint()		\
-  ((*current_target.to_stopped_by_sw_breakpoint) (&current_target))
+  ((target_stack->stopped_by_sw_breakpoint) ())
 
 #define target_supports_stopped_by_sw_breakpoint() \
-  ((*current_target.to_supports_stopped_by_sw_breakpoint) (&current_target))
+  ((target_stack->supports_stopped_by_sw_breakpoint) ())
 
 #define target_stopped_by_hw_breakpoint()				\
-  ((*current_target.to_stopped_by_hw_breakpoint) (&current_target))
+  ((target_stack->stopped_by_hw_breakpoint) ())
 
 #define target_supports_stopped_by_hw_breakpoint() \
-  ((*current_target.to_supports_stopped_by_hw_breakpoint) (&current_target))
+  ((target_stack->supports_stopped_by_hw_breakpoint) ())
 
 /* Non-zero if we have steppable watchpoints  */
 
 #define target_have_steppable_watchpoint \
-   (current_target.to_have_steppable_watchpoint)
+  (target_stack->have_steppable_watchpoint ())
 
 /* Non-zero if we have continuable watchpoints  */
 
 #define target_have_continuable_watchpoint \
-   (current_target.to_have_continuable_watchpoint)
+  (target_stack->have_continuable_watchpoint ())
 
 /* Provide defaults for hardware watchpoint functions.  */
 
@@ -1908,19 +1868,18 @@ extern struct thread_info *target_thread_handle_to_thread_info
    this one used so far.  */
 
 #define target_can_use_hardware_watchpoint(TYPE,CNT,OTHERTYPE) \
- (*current_target.to_can_use_hw_breakpoint) (&current_target,  \
+ (target_stack->can_use_hw_breakpoint) ( \
 					     TYPE, CNT, OTHERTYPE)
 
 /* Returns the number of debug registers needed to watch the given
    memory region, or zero if not supported.  */
 
 #define target_region_ok_for_hw_watchpoint(addr, len) \
-    (*current_target.to_region_ok_for_hw_watchpoint) (&current_target,	\
-						      addr, len)
+    (target_stack->region_ok_for_hw_watchpoint) (addr, len)
 
 
 #define target_can_do_single_step() \
-  (*current_target.to_can_do_single_step) (&current_target)
+  (target_stack->can_do_single_step) ()
 
 /* Set/clear a hardware watchpoint starting at ADDR, for LEN bytes.
    TYPE is 0 for write, 1 for read, and 2 for read/write accesses.
@@ -1929,12 +1888,10 @@ extern struct thread_info *target_thread_handle_to_thread_info
    -1 for failure.  */
 
 #define	target_insert_watchpoint(addr, len, type, cond) \
-     (*current_target.to_insert_watchpoint) (&current_target,	\
-					     addr, len, type, cond)
+     (target_stack->insert_watchpoint) (addr, len, type, cond)
 
 #define	target_remove_watchpoint(addr, len, type, cond) \
-     (*current_target.to_remove_watchpoint) (&current_target,	\
-					     addr, len, type, cond)
+     (target_stack->remove_watchpoint) (addr, len, type, cond)
 
 /* Insert a new masked watchpoint at ADDR using the mask MASK.
    RW may be hw_read for a read watchpoint, hw_write for a write watchpoint
@@ -1958,12 +1915,10 @@ extern int target_remove_mask_watchpoint (CORE_ADDR, CORE_ADDR,
    message) otherwise.  */
 
 #define target_insert_hw_breakpoint(gdbarch, bp_tgt) \
-     (*current_target.to_insert_hw_breakpoint) (&current_target,	\
-						gdbarch, bp_tgt)
+     (target_stack->insert_hw_breakpoint) (gdbarch, bp_tgt)
 
 #define target_remove_hw_breakpoint(gdbarch, bp_tgt) \
-     (*current_target.to_remove_hw_breakpoint) (&current_target,	\
-						gdbarch, bp_tgt)
+     (target_stack->remove_hw_breakpoint) (gdbarch, bp_tgt)
 
 /* Return number of debug registers needed for a ranged breakpoint,
    or -1 if ranged breakpoints are not supported.  */
@@ -1974,12 +1929,12 @@ extern int target_ranged_break_num_registers (void);
    target_stopped_by_watchpoint, in such case place it to *ADDR_P.  Only the
    INFERIOR_PTID task is being queried.  */
 #define target_stopped_data_address(target, addr_p) \
-    (*(target)->to_stopped_data_address) (target, addr_p)
+  (target)->stopped_data_address (addr_p)
 
 /* Return non-zero if ADDR is within the range of a watchpoint spanning
    LENGTH bytes beginning at START.  */
 #define target_watchpoint_addr_within_range(target, addr, start, length) \
-  (*(target)->to_watchpoint_addr_within_range) (target, addr, start, length)
+  (target)->watchpoint_addr_within_range (addr, start, length)
 
 /* Return non-zero if the target is capable of using hardware to evaluate
    the condition expression.  In this case, if the condition is false when
@@ -1992,8 +1947,7 @@ extern int target_ranged_break_num_registers (void);
    For this reason, GDB will still evaluate the condition expression when
    the watchpoint triggers.  */
 #define target_can_accel_watchpoint_condition(addr, len, type, cond) \
-  (*current_target.to_can_accel_watchpoint_condition) (&current_target,	\
-						       addr, len, type, cond)
+  (target_stack->can_accel_watchpoint_condition) (addr, len, type, cond)
 
 /* Return number of debug registers needed for a masked watchpoint,
    -1 if masked watchpoints are not supported or -2 if the given address
@@ -2003,12 +1957,12 @@ extern int target_masked_watch_num_registers (CORE_ADDR addr, CORE_ADDR mask);
 
 /* Target can execute in reverse?  */
 #define target_can_execute_reverse \
-      current_target.to_can_execute_reverse (&current_target)
+      target_stack->can_execute_reverse ()
 
 extern const struct target_desc *target_read_description (struct target_ops *);
 
 #define target_get_ada_task_ptid(lwp, tid) \
-     (*current_target.to_get_ada_task_ptid) (&current_target, lwp,tid)
+     (target_stack->get_ada_task_ptid) (lwp,tid)
 
 /* Utility implementation of searching memory.  */
 extern int simple_search_memory (struct target_ops* ops,
@@ -2030,7 +1984,7 @@ extern int target_search_memory (CORE_ADDR start_addr,
 /* Return nonzero if the filesystem seen by the current inferior
    is the local filesystem, zero otherwise.  */
 #define target_filesystem_is_local() \
-  current_target.to_filesystem_is_local (&current_target)
+  target_stack->filesystem_is_local ()
 
 /* Open FILENAME on the target, in the filesystem as seen by INF,
    using FLAGS and MODE.  If INF is NULL, use the filesystem seen
@@ -2117,105 +2071,100 @@ extern gdb::unique_xmalloc_ptr<char> target_fileio_read_stralloc
 /* Tracepoint-related operations.  */
 
 #define target_trace_init() \
-  (*current_target.to_trace_init) (&current_target)
+  (target_stack->trace_init) ()
 
 #define target_download_tracepoint(t) \
-  (*current_target.to_download_tracepoint) (&current_target, t)
+  (target_stack->download_tracepoint) (t)
 
 #define target_can_download_tracepoint() \
-  (*current_target.to_can_download_tracepoint) (&current_target)
+  (target_stack->can_download_tracepoint) ()
 
 #define target_download_trace_state_variable(tsv) \
-  (*current_target.to_download_trace_state_variable) (&current_target, tsv)
+  (target_stack->download_trace_state_variable) (tsv)
 
 #define target_enable_tracepoint(loc) \
-  (*current_target.to_enable_tracepoint) (&current_target, loc)
+  (target_stack->enable_tracepoint) (loc)
 
 #define target_disable_tracepoint(loc) \
-  (*current_target.to_disable_tracepoint) (&current_target, loc)
+  (target_stack->disable_tracepoint) (loc)
 
 #define target_trace_start() \
-  (*current_target.to_trace_start) (&current_target)
+  (target_stack->trace_start) ()
 
 #define target_trace_set_readonly_regions() \
-  (*current_target.to_trace_set_readonly_regions) (&current_target)
+  (target_stack->trace_set_readonly_regions) ()
 
 #define target_get_trace_status(ts) \
-  (*current_target.to_get_trace_status) (&current_target, ts)
+  (target_stack->get_trace_status) (ts)
 
 #define target_get_tracepoint_status(tp,utp)		\
-  (*current_target.to_get_tracepoint_status) (&current_target, tp, utp)
+  (target_stack->get_tracepoint_status) (tp, utp)
 
 #define target_trace_stop() \
-  (*current_target.to_trace_stop) (&current_target)
+  (target_stack->trace_stop) ()
 
 #define target_trace_find(type,num,addr1,addr2,tpp) \
-  (*current_target.to_trace_find) (&current_target, \
+  (target_stack->trace_find) (\
 				   (type), (num), (addr1), (addr2), (tpp))
 
 #define target_get_trace_state_variable_value(tsv,val) \
-  (*current_target.to_get_trace_state_variable_value) (&current_target,	\
-						       (tsv), (val))
+  (target_stack->get_trace_state_variable_value) ((tsv), (val))
 
 #define target_save_trace_data(filename) \
-  (*current_target.to_save_trace_data) (&current_target, filename)
+  (target_stack->save_trace_data) (filename)
 
 #define target_upload_tracepoints(utpp) \
-  (*current_target.to_upload_tracepoints) (&current_target, utpp)
+  (target_stack->upload_tracepoints) (utpp)
 
 #define target_upload_trace_state_variables(utsvp) \
-  (*current_target.to_upload_trace_state_variables) (&current_target, utsvp)
+  (target_stack->upload_trace_state_variables) (utsvp)
 
 #define target_get_raw_trace_data(buf,offset,len) \
-  (*current_target.to_get_raw_trace_data) (&current_target,	\
-					   (buf), (offset), (len))
+  (target_stack->get_raw_trace_data) ((buf), (offset), (len))
 
 #define target_get_min_fast_tracepoint_insn_len() \
-  (*current_target.to_get_min_fast_tracepoint_insn_len) (&current_target)
+  (target_stack->get_min_fast_tracepoint_insn_len) ()
 
 #define target_set_disconnected_tracing(val) \
-  (*current_target.to_set_disconnected_tracing) (&current_target, val)
+  (target_stack->set_disconnected_tracing) (val)
 
 #define	target_set_circular_trace_buffer(val)	\
-  (*current_target.to_set_circular_trace_buffer) (&current_target, val)
+  (target_stack->set_circular_trace_buffer) (val)
 
 #define	target_set_trace_buffer_size(val)	\
-  (*current_target.to_set_trace_buffer_size) (&current_target, val)
+  (target_stack->set_trace_buffer_size) (val)
 
 #define	target_set_trace_notes(user,notes,stopnotes)		\
-  (*current_target.to_set_trace_notes) (&current_target,	\
-					(user), (notes), (stopnotes))
+  (target_stack->set_trace_notes) ((user), (notes), (stopnotes))
 
 #define target_get_tib_address(ptid, addr) \
-  (*current_target.to_get_tib_address) (&current_target, (ptid), (addr))
+  (target_stack->get_tib_address) ((ptid), (addr))
 
 #define target_set_permissions() \
-  (*current_target.to_set_permissions) (&current_target)
+  (target_stack->set_permissions) ()
 
 #define target_static_tracepoint_marker_at(addr, marker) \
-  (*current_target.to_static_tracepoint_marker_at) (&current_target,	\
-						    addr, marker)
+  (target_stack->static_tracepoint_marker_at) (addr, marker)
 
 #define target_static_tracepoint_markers_by_strid(marker_id) \
-  (*current_target.to_static_tracepoint_markers_by_strid) (&current_target, \
-							   marker_id)
+  (target_stack->static_tracepoint_markers_by_strid) (marker_id)
 
 #define target_traceframe_info() \
-  (*current_target.to_traceframe_info) (&current_target)
+  (target_stack->traceframe_info) ()
 
 #define target_use_agent(use) \
-  (*current_target.to_use_agent) (&current_target, use)
+  (target_stack->use_agent) (use)
 
 #define target_can_use_agent() \
-  (*current_target.to_can_use_agent) (&current_target)
+  (target_stack->can_use_agent) ()
 
 #define target_augmented_libraries_svr4_read() \
-  (*current_target.to_augmented_libraries_svr4_read) (&current_target)
+  (target_stack->augmented_libraries_svr4_read) ()
 
 /* Command logging facility.  */
 
 #define target_log_command(p)					\
-  (*current_target.to_log_command) (&current_target, p)
+  (target_stack->log_command) (p)
 
 
 extern int target_core_of_thread (ptid_t ptid);
@@ -2244,11 +2193,6 @@ int target_verify_memory (const gdb_byte *data,
 
 /* Routines for maintenance of the target structures...
 
-   complete_target_initialization: Finalize a target_ops by filling in
-   any fields needed by the target implementation.  Unnecessary for
-   targets which are registered via add_target, as this part gets
-   taken care of then.
-
    add_target:   Add a target to the list of all possible targets.
    This only makes sense for targets that should be activated using
    the "target TARGET_NAME ..." command.
@@ -2267,8 +2211,6 @@ extern void add_target (struct target_ops *);
 extern void add_target_with_completer (struct target_ops *t,
 				       completer_ftype *completer);
 
-extern void complete_target_initialization (struct target_ops *t);
-
 /* Adds a command ALIAS for target T and marks it deprecated.  This is useful
    for maintaining backwards compatibility when renaming targets.  */
 
@@ -2338,12 +2280,28 @@ extern struct target_section_table *target_get_section_table
 
 /* From mem-break.c */
 
-extern int memory_remove_breakpoint (struct target_ops *, struct gdbarch *,
-				     struct bp_target_info *,
+extern int memory_remove_breakpoint (struct target_ops *,
+				     struct gdbarch *, struct bp_target_info *,
 				     enum remove_bp_reason);
 
-extern int memory_insert_breakpoint (struct target_ops *, struct gdbarch *,
-				     struct bp_target_info *);
+extern int memory_insert_breakpoint (struct target_ops *,
+				     struct gdbarch *, struct bp_target_info *);
+
+/* Convenience template use to add memory breakpoints support to a
+   target.  */
+
+template <typename BaseTarget>
+struct memory_breakpoint_target : public BaseTarget
+{
+  int insert_breakpoint (struct gdbarch *gdbarch,
+			 struct bp_target_info *bp_tgt) override
+  { return memory_insert_breakpoint (this, gdbarch, bp_tgt); }
+
+  int remove_breakpoint (struct gdbarch *gdbarch,
+			 struct bp_target_info *bp_tgt,
+			 enum remove_bp_reason reason) override
+  { return memory_remove_breakpoint (this, gdbarch, bp_tgt, reason); }
+};
 
 /* Check whether the memory at the breakpoint's placed address still
    contains the expected breakpoint instruction.  */
@@ -2501,8 +2459,52 @@ namespace selftests {
 class test_target_ops : public target_ops
 {
 public:
-  test_target_ops ();
+  test_target_ops ()
+    : target_ops {}
+  {
+    to_stratum = process_stratum;
+  }
+
+  const char *shortname () override
+  {
+    return NULL;
+  }
+
+  const char *longname () override
+  {
+    return NULL;
+  }
+
+  const char *doc () override
+  {
+    return NULL;
+  }
+
+  int has_registers () override
+  {
+    return 1;
+  }
+
+  int has_stack () override
+  {
+    return 1;
+  }
+
+  int has_memory () override
+  {
+    return 1;
+  }
+
+  void prepare_to_store (regcache *regs) override
+  {
+  }
+
+  void store_registers (regcache *regs, int regno) override
+  {
+  }
 };
+
+
 } // namespace selftests
 #endif /* GDB_SELF_TEST */
 
diff --git a/gdb/testsuite/gdb.base/breakpoint-in-ro-region.exp b/gdb/testsuite/gdb.base/breakpoint-in-ro-region.exp
index e888e17a02..61a6319c45 100644
--- a/gdb/testsuite/gdb.base/breakpoint-in-ro-region.exp
+++ b/gdb/testsuite/gdb.base/breakpoint-in-ro-region.exp
@@ -40,7 +40,7 @@ proc probe_target_hardware_step {} {
     gdb_test_no_output "set debug target 1"
     set test "probe target hardware step"
     gdb_test_multiple "si" $test {
-	-re "to_resume \\(\[^\r\n\]+, step, .*$gdb_prompt $" {
+	-re "resume \\(\[^\r\n\]+, step, .*$gdb_prompt $" {
 	    set hw_step 1
 	    pass $test
 	}
@@ -48,7 +48,7 @@ proc probe_target_hardware_step {} {
 	    pass $test
 	}
     }
-    gdb_test "set debug target 0" "->to_log_command.*\\).*"
+    gdb_test "set debug target 0" "->log_command.*\\).*"
     return $hw_step
 }
 
diff --git a/gdb/testsuite/gdb.base/sss-bp-on-user-bp-2.exp b/gdb/testsuite/gdb.base/sss-bp-on-user-bp-2.exp
index 54ff015556..3775954713 100644
--- a/gdb/testsuite/gdb.base/sss-bp-on-user-bp-2.exp
+++ b/gdb/testsuite/gdb.base/sss-bp-on-user-bp-2.exp
@@ -62,7 +62,7 @@ gdb_test_no_output "set debug target 1"
 set hardware_step 0
 set test "probe target hardware step"
 gdb_test_multiple "si" $test {
-    -re "to_resume \\(\[^\r\n\]+, step, .*$gdb_prompt $" {
+    -re "resume \\(\[^\r\n\]+, step, .*$gdb_prompt $" {
 	set hardware_step 1
 	pass $test
     }
@@ -76,7 +76,7 @@ if { $hardware_step } {
     return
 }
 
-gdb_test "set debug target 0" "->to_log_command.*\\)"
+gdb_test "set debug target 0" "->log_command.*\\)"
 
 set line_re "\[^\r\n\]*"
 
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index 7e173ce75d..d358927915 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -3811,7 +3811,7 @@ sdata_make_value (struct gdbarch *gdbarch, struct internalvar *var,
 {
   /* We need to read the whole object before we know its size.  */
   gdb::optional<gdb::byte_vector> buf
-    = target_read_alloc (&current_target, TARGET_OBJECT_STATIC_TRACE_DATA,
+    = target_read_alloc (target_stack, TARGET_OBJECT_STATIC_TRACE_DATA,
 			 NULL);
   if (buf)
     {
diff --git a/gdb/valops.c b/gdb/valops.c
index 1f655b5187..62a86c06a3 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -964,7 +964,7 @@ read_value_memory (struct value *val, LONGEST bit_offset,
       enum target_xfer_status status;
       ULONGEST xfered_partial;
 
-      status = target_xfer_partial (current_target.beneath,
+      status = target_xfer_partial (target_stack,
 				    object, NULL,
 				    buffer + xfered_total * unit_size, NULL,
 				    memaddr + xfered_total,
@@ -1208,7 +1208,7 @@ value_assign (struct value *toval, struct value *fromval)
     case lval_register:
     case lval_computed:
 
-      gdb::observers::target_changed.notify (&current_target);
+      gdb::observers::target_changed.notify (target_stack);
 
       /* Having destroyed the frame cache, restore the selected
 	 frame.  */
diff --git a/gdb/valprint.c b/gdb/valprint.c
index 3104e0b45e..bed2cecf2c 100644
--- a/gdb/valprint.c
+++ b/gdb/valprint.c
@@ -1885,7 +1885,7 @@ print_function_pointer_address (const struct value_print_options *options,
 {
   CORE_ADDR func_addr
     = gdbarch_convert_from_func_ptr_addr (gdbarch, address,
-					  &current_target);
+					  target_stack);
 
   /* If the function pointer is represented by a description, print
      the address of the description.  */
diff --git a/gdb/value.c b/gdb/value.c
index 12aa2b8bb4..c1acbecc5b 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -3071,7 +3071,7 @@ value_fn_field (struct value **arg1p, struct fn_field *f,
 
       set_value_address (v,
 	gdbarch_convert_from_func_ptr_addr
-	   (gdbarch, BMSYMBOL_VALUE_ADDRESS (msym), &current_target));
+	   (gdbarch, BMSYMBOL_VALUE_ADDRESS (msym), target_stack));
     }
 
   if (arg1p)
diff --git a/gdb/windows-tdep.c b/gdb/windows-tdep.c
index 8b3db5d168..eb44d8d407 100644
--- a/gdb/windows-tdep.c
+++ b/gdb/windows-tdep.c
@@ -331,7 +331,7 @@ display_one_tib (ptid_t ptid)
       return -1;
     }
 
-  if (target_read (&current_target, TARGET_OBJECT_MEMORY,
+  if (target_read (target_stack, TARGET_OBJECT_MEMORY,
 		   NULL, tib, thread_local_base, tib_size) != tib_size)
     {
       printf_filtered (_("Unable to read thread information "
-- 
2.14.3

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 31/40] target_ops/C++: Base FreeBSD target
  2018-04-14 19:19 ` [PATCH 31/40] target_ops/C++: Base FreeBSD target Pedro Alves
@ 2018-04-17 16:12   ` John Baldwin
  2018-04-17 17:07     ` Pedro Alves
  0 siblings, 1 reply; 65+ messages in thread
From: John Baldwin @ 2018-04-17 16:12 UTC (permalink / raw)
  To: gdb-patches; +Cc: Pedro Alves

On Saturday, April 14, 2018 08:09:44 PM Pedro Alves wrote:
> The
> 
>   $architecture x NetBSD/OpenBSD/FreeBSD
> 
> support matrix complicates things a bit.  There's common BSD target
> code, and there's common architecture-specific code shared between the
> different BSDs.  Current, all that is stiched together to form a final
> target, via the i386bsd_target, x86bsd_target, fbsd_nat_add_target
> functions etc.
> 
> Introduces a fbsd_nat_target base/prototype target.  To be used in
> following patches.

I will do some tests of FreeBSD/amd64 first and let you know what I find.
One small thing I noticed:

> diff --git a/gdb/fbsd-nat.h b/gdb/fbsd-nat.h
> index 8326b96db7..a4418bb8f8 100644
> --- a/gdb/fbsd-nat.h
> +++ b/gdb/fbsd-nat.h
> +
> +#ifdef PL_FLAG_EXEC
> +  int insert_exec_catchpoint (int) override;
> +  int remove_exec_catchpoint (int) override;
> +#endif
> +
> +#ifdef HAVE_STRUCT_PTRACE_LWPINFO_PL_SYSCALL_CODE
> +  int set_syscall_catchpoint (int, bool, int, gdb::array_view<const int>)
> +    override;
> +#endif /* HAVE_STRUCT_PTRACE_LWPINFO_PL_SYSCALL_CODE */
> +
> +#endif /* PT_LWPINFO */
> +};

Do we want to be consistent about whether or not to have comments for
#endif's?  Most in this change don't but these two do.

(Also, my initial impression is that the #ifdef's are more readable in this
version than the current code)

-- 
John Baldwin

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 31/40] target_ops/C++: Base FreeBSD target
  2018-04-17 16:12   ` John Baldwin
@ 2018-04-17 17:07     ` Pedro Alves
  2018-04-17 17:28       ` Kamil Rytarowski
  2018-04-18  0:40       ` John Baldwin
  0 siblings, 2 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-17 17:07 UTC (permalink / raw)
  To: John Baldwin, gdb-patches

On 04/17/2018 05:05 PM, John Baldwin wrote:
> On Saturday, April 14, 2018 08:09:44 PM Pedro Alves wrote:
>> The
>>
>>   $architecture x NetBSD/OpenBSD/FreeBSD
>>
>> support matrix complicates things a bit.  There's common BSD target
>> code, and there's common architecture-specific code shared between the
>> different BSDs.  Current, all that is stiched together to form a final
>> target, via the i386bsd_target, x86bsd_target, fbsd_nat_add_target
>> functions etc.
>>
>> Introduces a fbsd_nat_target base/prototype target.  To be used in
>> following patches.
> 
> I will do some tests of FreeBSD/amd64 first and let you know what I find.

Thank you!

> One small thing I noticed:
> 
>> diff --git a/gdb/fbsd-nat.h b/gdb/fbsd-nat.h
>> index 8326b96db7..a4418bb8f8 100644
>> --- a/gdb/fbsd-nat.h
>> +++ b/gdb/fbsd-nat.h
>> +
>> +#ifdef PL_FLAG_EXEC
>> +  int insert_exec_catchpoint (int) override;
>> +  int remove_exec_catchpoint (int) override;
>> +#endif
>> +
>> +#ifdef HAVE_STRUCT_PTRACE_LWPINFO_PL_SYSCALL_CODE
>> +  int set_syscall_catchpoint (int, bool, int, gdb::array_view<const int>)
>> +    override;
>> +#endif /* HAVE_STRUCT_PTRACE_LWPINFO_PL_SYSCALL_CODE */
>> +
>> +#endif /* PT_LWPINFO */
>> +};
> 
> Do we want to be consistent about whether or not to have comments for
> #endif's?  Most in this change don't but these two do.

I think I have added the one for PT_LWPINFO thinking that the
corresponding #ifdef is so far away, and then added the one just
above too, while missing the others.

I don't have a strong opinion on whether all should have the
comment, I'm fine either way since the #ifdef blocks are small,
i.e., removing the comment for HAVE_STRUCT_PTRACE_LWPINFO_PL_SYSCALL_CODE
is totally fine with me and may even reduce noise.  I do think
the comment for "#endif PT_LWPINFO" is beneficial, however.

> 
> (Also, my initial impression is that the #ifdef's are more readable in this
> version than the current code)
> 

Yeah, the #endif for PT_LWPINFO is the one that I think I
recall gave me pause in the current code.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 31/40] target_ops/C++: Base FreeBSD target
  2018-04-17 17:07     ` Pedro Alves
@ 2018-04-17 17:28       ` Kamil Rytarowski
  2018-04-17 18:13         ` Pedro Alves
  2018-04-18  0:40       ` John Baldwin
  1 sibling, 1 reply; 65+ messages in thread
From: Kamil Rytarowski @ 2018-04-17 17:28 UTC (permalink / raw)
  To: Pedro Alves, John Baldwin, gdb-patches


[-- Attachment #1.1: Type: text/plain, Size: 969 bytes --]

On 17.04.2018 19:07, Pedro Alves wrote:
> On 04/17/2018 05:05 PM, John Baldwin wrote:
>> On Saturday, April 14, 2018 08:09:44 PM Pedro Alves wrote:
>>> The
>>>
>>>   $architecture x NetBSD/OpenBSD/FreeBSD
>>>
>>> support matrix complicates things a bit.  There's common BSD target
>>> code, and there's common architecture-specific code shared between the
>>> different BSDs.  Current, all that is stiched together to form a final
>>> target, via the i386bsd_target, x86bsd_target, fbsd_nat_add_target
>>> functions etc.
>>>
>>> Introduces a fbsd_nat_target base/prototype target.  To be used in
>>> following patches.
>>
>> I will do some tests of FreeBSD/amd64 first and let you know what I find.
> 
> Thank you!
> 

Common BSD target should be changed in future to common BSD/Linux target
like in LLDB. There is a shared Remote Process Plugin used by Linux and
NetBSD.

Enforcing a layer of common BSD code is counterproductive nowadays.


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 850 bytes --]

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 31/40] target_ops/C++: Base FreeBSD target
  2018-04-17 17:28       ` Kamil Rytarowski
@ 2018-04-17 18:13         ` Pedro Alves
  2018-04-17 18:50           ` Kamil Rytarowski
  0 siblings, 1 reply; 65+ messages in thread
From: Pedro Alves @ 2018-04-17 18:13 UTC (permalink / raw)
  To: Kamil Rytarowski, John Baldwin, gdb-patches

Hi Kamil!

Will you be able to smoke test the branch on your favorite
port?  That'd be super.  :-)

On 04/17/2018 06:30 PM, Kamil Rytarowski wrote:

> Common BSD target should be changed in future to common BSD/Linux target
> like in LLDB. There is a shared Remote Process Plugin used by Linux and
> NetBSD.

I think that is confusing or oversimplifying things.  Also, it's
a bit orthogonal to the present effort.  :-)  The "shared" Remote
Process Plugin is just the equivalent of "target remote" in gdb.

See:

 https://sourceware.org/gdb/wiki/Common
 https://sourceware.org/gdb/wiki/LocalRemoteFeatureParity

What we're missing is that gdbserver was never ported over to the
BSDs.  At least, upstream.  Just like in lldb not all ports
have been converted to use the remote process plugin.

Clearly there needs to be a shared interface the different target
backends such as BSD and Linux implement to interact with the
core of the debugger or the server.  In gdb and gdbserver that is
their corresponding target_ops definitions (they're similar, but
not the same).  So even when "going always remote", the target
backend implementations can well share code.

If you're considering porting gdbserver to some platform that
gdb already supports debugging natively, I strongly suggest
making gdbserver reuse the native target code in gdb instead of
duplicating the code.  A few years back someone was working
on doing that for a Hurd gdbserver port, but unfortunately
the work was never completed.  I was positively surprised how
little change the gdb code was requiring for gdbserver
adaptation though.

If done right (by making gdb and gdbserver use the same native
backend target_ops-like interface), there's nothing preventing using
the same backend code in-process in both gdb and gdbserver if we'd like,
instead of always forcing use of gdbserver behind the scenes.  There
are advantages to supporting native-without-forcing-gdbserver
debugging too.  It's all open in the air at this point.

> Enforcing a layer of common BSD code is counterproductive nowadays.

Note that nothing is being "enforced" and that there's no actual
"common BSD layer" in the sense that everything sits on top of some
common BSD layer.  There are simply a few pieces of shared functionality.
If some BSD port doesn't want to use the shared bits, it's very easy
not to use them.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 31/40] target_ops/C++: Base FreeBSD target
  2018-04-17 18:13         ` Pedro Alves
@ 2018-04-17 18:50           ` Kamil Rytarowski
  0 siblings, 0 replies; 65+ messages in thread
From: Kamil Rytarowski @ 2018-04-17 18:50 UTC (permalink / raw)
  To: Pedro Alves, John Baldwin, gdb-patches


[-- Attachment #1.1: Type: text/plain, Size: 3802 bytes --]

On 17.04.2018 20:13, Pedro Alves wrote:
> Hi Kamil!
> 
> Will you be able to smoke test the branch on your favorite
> port?  That'd be super.  :-)
> 

I can try to test it on NetBSD/amd64.

> On 04/17/2018 06:30 PM, Kamil Rytarowski wrote:
> 
>> Common BSD target should be changed in future to common BSD/Linux target
>> like in LLDB. There is a shared Remote Process Plugin used by Linux and
>> NetBSD.
> 
> I think that is confusing or oversimplifying things.  Also, it's
> a bit orthogonal to the present effort.  :-)  The "shared" Remote
> Process Plugin is just the equivalent of "target remote" in gdb.
> 

My comment was rather orthogonal to the process plugin model. I wanted
to state that FreeBSD and NetBSD diverged, while NetBSD was trying to
follow FreeBSD / Linux API with a clean room design.

Cloning 1:1: other BSD would require breakage in existing software as
the APIs were already incompatible. For example PT_LWPINFO has a
different meaning on FreeBSD (get thread info with trap details) and
NetBSD (iterate over threads in tracee).

This means that we are today a distinct target. It's an open question
about OpenBSD, they could follow NetBSD with marginal differences...
once we could convince them to sync up with proper support in debuggers.

> See:
> 
>  https://sourceware.org/gdb/wiki/Common
>  https://sourceware.org/gdb/wiki/LocalRemoteFeatureParity
> 
> What we're missing is that gdbserver was never ported over to the
> BSDs.  At least, upstream.  Just like in lldb not all ports
> have been converted to use the remote process plugin.
> 
> Clearly there needs to be a shared interface the different target
> backends such as BSD and Linux implement to interact with the
> core of the debugger or the server.  In gdb and gdbserver that is
> their corresponding target_ops definitions (they're similar, but
> not the same).  So even when "going always remote", the target
> backend implementations can well share code.
> 
> If you're considering porting gdbserver to some platform that
> gdb already supports debugging natively, I strongly suggest
> making gdbserver reuse the native target code in gdb instead of
> duplicating the code.  A few years back someone was working
> on doing that for a Hurd gdbserver port, but unfortunately
> the work was never completed.  I was positively surprised how
> little change the gdb code was requiring for gdbserver
> adaptation though.
> 
> If done right (by making gdb and gdbserver use the same native
> backend target_ops-like interface), there's nothing preventing using
> the same backend code in-process in both gdb and gdbserver if we'd like,
> instead of always forcing use of gdbserver behind the scenes.  There
> are advantages to supporting native-without-forcing-gdbserver
> debugging too.  It's all open in the air at this point.
> 

There was a port of gdbserver to NetBSD, perhaps so old that it's no
longer relevant today (code from 2010).

http://gnats.netbsd.org/43332 gdbserver for powerpc

Right now, I'm busy with kernel work improving correctness of
forking-like code in the context of debuggers, it will be followed by
signals and threads. It's mostly a one-man show as of today... so it's a
process taking time. I'm reporting the monthly progress on blog.netbsd.org.

>> Enforcing a layer of common BSD code is counterproductive nowadays.
> 
> Note that nothing is being "enforced" and that there's no actual
> "common BSD layer" in the sense that everything sits on top of some
> common BSD layer.  There are simply a few pieces of shared functionality.
> If some BSD port doesn't want to use the shared bits, it's very easy
> not to use them.
> 

It will be revisited in future.

> Thanks,
> Pedro Alves
> 



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 850 bytes --]

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 39/40] linux_nat_target: More low methods
  2018-04-14 19:10 ` [PATCH 39/40] linux_nat_target: More low methods Pedro Alves
@ 2018-04-18  0:40   ` John Baldwin
  0 siblings, 0 replies; 65+ messages in thread
From: John Baldwin @ 2018-04-18  0:40 UTC (permalink / raw)
  To: gdb-patches; +Cc: Pedro Alves

On Saturday, April 14, 2018 08:09:52 PM Pedro Alves wrote:
> This converts the remaining linux-nat.c hooks low_ methods like had
> been started in a previous patch.  The linux_nat_set_foo routines are
> all gone with this.

Probably not in this series as it's large enough as it is, but we should
probably do something similar with the x86_dr_low stuff where x86_nat adds
them as abstract virtual methods or some such.

-- 
John Baldwin

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 31/40] target_ops/C++: Base FreeBSD target
  2018-04-17 17:07     ` Pedro Alves
  2018-04-17 17:28       ` Kamil Rytarowski
@ 2018-04-18  0:40       ` John Baldwin
  2018-04-18  1:51         ` Kamil Rytarowski
  2018-04-18 11:21         ` Pedro Alves
  1 sibling, 2 replies; 65+ messages in thread
From: John Baldwin @ 2018-04-18  0:40 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On Tuesday, April 17, 2018 06:07:37 PM Pedro Alves wrote:
> On 04/17/2018 05:05 PM, John Baldwin wrote:
> > On Saturday, April 14, 2018 08:09:44 PM Pedro Alves wrote:
> >> The
> >>
> >>   $architecture x NetBSD/OpenBSD/FreeBSD
> >>
> >> support matrix complicates things a bit.  There's common BSD target
> >> code, and there's common architecture-specific code shared between the
> >> different BSDs.  Current, all that is stiched together to form a final
> >> target, via the i386bsd_target, x86bsd_target, fbsd_nat_add_target
> >> functions etc.
> >>
> >> Introduces a fbsd_nat_target base/prototype target.  To be used in
> >> following patches.
> > 
> > I will do some tests of FreeBSD/amd64 first and let you know what I find.
> 
> Thank you!

I've pushed a target_ops-cxx branch to github.com/bsdjhb/gdb.git that has
some small fixups (compile fixes).  I've built the amd64, i386, arm, and
aarch64 FreeBSD native targets so far.  Simple testing of the the amd64
and i386 binaries seems to work, but I encountered a new test failure
in the testsuite for FreeBSD/amd64 that is a bit odd.  In particular,
I get a core dump running 'info set' when it tries to display the
current setting of whether ASLR is disabled.  Looking at the core of gdb:

Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x0000000000d3a7d4 in target_ops::supports_disable_randomization (
    this=0x28d4c68 <the_amd64_fbsd_nat_target>)
    at ../../gdb/target-delegates.c:2732
2732      return this->beneath->supports_disable_randomization ();

(top-gdb) where
#0  0x0000000000d3a7d4 in target_ops::supports_disable_randomization (
    this=0x28d4c68 <the_amd64_fbsd_nat_target>)
    at ../../gdb/target-delegates.c:2732
#1  0x0000000000d3a857 in find_default_supports_disable_randomization (
#2  0x0000000000d3a805 in dummy_target::supports_disable_randomization (
    this=0x8040d6060) at ../../gdb/target-delegates.c:2738
#3  0x0000000000d2edd8 in target_supports_disable_randomization ()
    at ../../gdb/target.c:2560
#4  0x0000000000b9adbc in show_disable_randomization (file=0x8047b1200, 
    from_tty=1, c=0x80476db80, value=0x7fffffffd859 "on")
    at ../../gdb/infrun.c:181
#5  0x00000000007b1178 in do_show_command (arg=0x0, from_tty=1, c=0x80476db80)
    at ../../gdb/cli/cli-setshow.c:646
#6  0x00000000007b1434 in cmd_show_list (list=0x80476db80, from_tty=1, 
    prefix=0x22a7ead "") at ../../gdb/cli/cli-setshow.c:685
...

The native target isn't currently in the target_stack so its 'beneath' is
NULL:

(top-gdb) p beneath
During symbol reading, missing name for subprogram DIE at 14709647.
$1 = (target_ops *) 0x0
(top-gdb) p target_stack
$2 = (target_ops *) 0x8040d6060
(top-gdb) p *target_stack
$3 = {_vptr$target_ops = 0x183aaf0 <vtable for dummy_target+16>, 
  beneath = 0x0, to_stratum = dummy_stratum}

From the stack trace we can see that it already bounced down to the dummy
target which calls find_default_supports_disable_randomization.  That
finds the native "run" target and invokes its method without pushing
it onto the stack.  I think before if a native target didn't support ASLR
at all it just didn't set the function pointer and no harm was done.
Now the function pointer is effectively always set but to something that
assumes 'beneath' is valid.  I'm not quite sure how you want to fix this.
The simple solution is to change the default method to return false if
beneath is NULL, but I'm not quite sure that fits in with the design this
branch is aiming for.

-- 
John Baldwin

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 31/40] target_ops/C++: Base FreeBSD target
  2018-04-18  0:40       ` John Baldwin
@ 2018-04-18  1:51         ` Kamil Rytarowski
  2018-04-18 11:23           ` Pedro Alves
  2018-04-18 11:21         ` Pedro Alves
  1 sibling, 1 reply; 65+ messages in thread
From: Kamil Rytarowski @ 2018-04-18  1:51 UTC (permalink / raw)
  To: John Baldwin, Pedro Alves; +Cc: gdb-patches


[-- Attachment #1.1: Type: text/plain, Size: 1597 bytes --]

On 18.04.2018 02:37, John Baldwin wrote:
> On Tuesday, April 17, 2018 06:07:37 PM Pedro Alves wrote:
>> On 04/17/2018 05:05 PM, John Baldwin wrote:
>>> On Saturday, April 14, 2018 08:09:44 PM Pedro Alves wrote:
>>>> The
>>>>
>>>>   $architecture x NetBSD/OpenBSD/FreeBSD
>>>>
>>>> support matrix complicates things a bit.  There's common BSD target
>>>> code, and there's common architecture-specific code shared between the
>>>> different BSDs.  Current, all that is stiched together to form a final
>>>> target, via the i386bsd_target, x86bsd_target, fbsd_nat_add_target
>>>> functions etc.
>>>>
>>>> Introduces a fbsd_nat_target base/prototype target.  To be used in
>>>> following patches.
>>>
>>> I will do some tests of FreeBSD/amd64 first and let you know what I find.
>>
>> Thank you!
> 
> I've pushed a target_ops-cxx branch to github.com/bsdjhb/gdb.git that has
> some small fixups (compile fixes).  I've built the amd64, i386, arm, and
> aarch64 FreeBSD native targets so far.  Simple testing of the the amd64
> and i386 binaries seems to work, but I encountered a new test failure
> in the testsuite for FreeBSD/amd64 that is a bit odd.  In particular,
> I get a core dump running 'info set' when it tries to display the
> current setting of whether ASLR is disabled.  Looking at the core of gdb:
> 

I've checked this branch on NetBSD/amd64 8.99.7 (target_ops-cxx
github.com/bsdjhb/gdb.git). It builds and it's not fully functional..
perhaps not much different to previous versions, for I'm not going to
open new threads and focus on kernel fixes.


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 850 bytes --]

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 31/40] target_ops/C++: Base FreeBSD target
  2018-04-18  0:40       ` John Baldwin
  2018-04-18  1:51         ` Kamil Rytarowski
@ 2018-04-18 11:21         ` Pedro Alves
  2018-04-18 14:20           ` Pedro Alves
  1 sibling, 1 reply; 65+ messages in thread
From: Pedro Alves @ 2018-04-18 11:21 UTC (permalink / raw)
  To: John Baldwin; +Cc: gdb-patches

On 04/18/2018 01:37 AM, John Baldwin wrote:
> On Tuesday, April 17, 2018 06:07:37 PM Pedro Alves wrote:
>> On 04/17/2018 05:05 PM, John Baldwin wrote:
>>> On Saturday, April 14, 2018 08:09:44 PM Pedro Alves wrote:
>>>> The
>>>>
>>>>   $architecture x NetBSD/OpenBSD/FreeBSD
>>>>
>>>> support matrix complicates things a bit.  There's common BSD target
>>>> code, and there's common architecture-specific code shared between the
>>>> different BSDs.  Current, all that is stiched together to form a final
>>>> target, via the i386bsd_target, x86bsd_target, fbsd_nat_add_target
>>>> functions etc.
>>>>
>>>> Introduces a fbsd_nat_target base/prototype target.  To be used in
>>>> following patches.
>>>
>>> I will do some tests of FreeBSD/amd64 first and let you know what I find.
>>
>> Thank you!
> 
> I've pushed a target_ops-cxx branch to github.com/bsdjhb/gdb.git that has
> some small fixups (compile fixes).  

Thank you!

> I've built the amd64, i386, arm, and
> aarch64 FreeBSD native targets so far.  Simple testing of the the amd64
> and i386 binaries seems to work, but I encountered a new test failure
> in the testsuite for FreeBSD/amd64 that is a bit odd.  In particular,
> I get a core dump running 'info set' when it tries to display the
> current setting of whether ASLR is disabled.  Looking at the core of gdb:

Ah, I wasn't seeing this because the Linux target implements
the supports_disable_randomization method.  If I hack that away, I
can reproduce the crash.

> 
> Program terminated with signal SIGSEGV, Segmentation fault.
> #0  0x0000000000d3a7d4 in target_ops::supports_disable_randomization (
>     this=0x28d4c68 <the_amd64_fbsd_nat_target>)
>     at ../../gdb/target-delegates.c:2732
> 2732      return this->beneath->supports_disable_randomization ();
> 

... 

> 
> From the stack trace we can see that it already bounced down to the dummy
> target which calls find_default_supports_disable_randomization.  That
> finds the native "run" target and invokes its method without pushing
> it onto the stack.  I think before if a native target didn't support ASLR
> at all it just didn't set the function pointer and no harm was done.
> Now the function pointer is effectively always set but to something that
> assumes 'beneath' is valid.  I'm not quite sure how you want to fix this.
> The simple solution is to change the default method to return false if
> beneath is NULL, but I'm not quite sure that fits in with the design this
> branch is aiming for.

Thanks for the analysis, that helps.

There's a small set of target methods that must always be
implemented by native targets, to avoid falling down to the
target beneath (since the target may not be pushed when the
method is called).  See target.c:complete_target_initialization
in current master.  Since all native targets inherit from inf-child
(just like in current master), in the C++ version, we can override
it there.  Like below.  This fixes it for me.

diff --git c/gdb/inf-child.h w/gdb/inf-child.h
index d3f8b71589..956cee2a0a 100644
--- c/gdb/inf-child.h
+++ w/gdb/inf-child.h
@@ -72,6 +72,7 @@ public:
      target that can run.  */
   bool can_async_p ()  override { return false; }
   bool supports_non_stop ()  override { return false; }
+  bool supports_disable_randomization () override { return false; }
 
   char *pid_to_exec_file (int pid) override;

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 31/40] target_ops/C++: Base FreeBSD target
  2018-04-18  1:51         ` Kamil Rytarowski
@ 2018-04-18 11:23           ` Pedro Alves
  0 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-04-18 11:23 UTC (permalink / raw)
  To: Kamil Rytarowski, John Baldwin; +Cc: gdb-patches

On 04/18/2018 02:52 AM, Kamil Rytarowski wrote:

> I've checked this branch on NetBSD/amd64 8.99.7 (target_ops-cxx
> github.com/bsdjhb/gdb.git). It builds and it's not fully functional..
> perhaps not much different to previous versions, for I'm not going to
> open new threads and focus on kernel fixes.

Thanks for testing!

Pedro Alves

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 31/40] target_ops/C++: Base FreeBSD target
  2018-04-18 11:21         ` Pedro Alves
@ 2018-04-18 14:20           ` Pedro Alves
  2018-04-18 20:55             ` John Baldwin
  0 siblings, 1 reply; 65+ messages in thread
From: Pedro Alves @ 2018-04-18 14:20 UTC (permalink / raw)
  To: John Baldwin; +Cc: gdb-patches

On 04/18/2018 12:21 PM, Pedro Alves wrote:
> On 04/18/2018 01:37 AM, John Baldwin wrote:

>> I've pushed a target_ops-cxx branch to github.com/bsdjhb/gdb.git that has
>> some small fixups (compile fixes).  
> 
> Thank you!

I've now merged/squashed those fixes to the patches in the branch,
and added your name to the WIP ChangeLog entry.

I diff my branch against yours to double-checked whether I was
missing anything, then rebased on top of current master.

I force-pushed the result to users/palves/target_ops-cxx on sourceware.org.

Thanks again.

> There's a small set of target methods that must always be
> implemented by native targets, to avoid falling down to the
> target beneath (since the target may not be pushed when the
> method is called).  See target.c:complete_target_initialization
> in current master.  Since all native targets inherit from inf-child
> (just like in current master), in the C++ version, we can override
> it there.  Like below.  This fixes it for me.
> 
> diff --git c/gdb/inf-child.h w/gdb/inf-child.h
> index d3f8b71589..956cee2a0a 100644
> --- c/gdb/inf-child.h
> +++ w/gdb/inf-child.h
> @@ -72,6 +72,7 @@ public:
>       target that can run.  */
>    bool can_async_p ()  override { return false; }
>    bool supports_non_stop ()  override { return false; }
> +  bool supports_disable_randomization () override { return false; }
>  
>    char *pid_to_exec_file (int pid) override;

This is in the branch too now.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 31/40] target_ops/C++: Base FreeBSD target
  2018-04-18 14:20           ` Pedro Alves
@ 2018-04-18 20:55             ` John Baldwin
  0 siblings, 0 replies; 65+ messages in thread
From: John Baldwin @ 2018-04-18 20:55 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On Wednesday, April 18, 2018 03:20:19 PM Pedro Alves wrote:
> On 04/18/2018 12:21 PM, Pedro Alves wrote:
> > On 04/18/2018 01:37 AM, John Baldwin wrote:
> 
> >> I've pushed a target_ops-cxx branch to github.com/bsdjhb/gdb.git that has
> >> some small fixups (compile fixes).  
> > 
> > Thank you!
> 
> I've now merged/squashed those fixes to the patches in the branch,
> and added your name to the WIP ChangeLog entry.
> 
> I diff my branch against yours to double-checked whether I was
> missing anything, then rebased on top of current master.
> 
> I force-pushed the result to users/palves/target_ops-cxx on sourceware.org.
> 
> Thanks again.

Thanks for the explanation of the proper fix.  I've pulled the updated branch
and FreeBSD/amd64 has basically the same test results as master now.  (There
are a few differences but I think they are due to timing issues/races in the
tests rather than actual behavioral differences.)  There are a few other
platforms I haven't built yet (FreeBSD/mips and FreeBSD/powerpc) but I'm fine
with fixing those post-commit if there are any fixes needed.  If I am able to
test them before you merge this in I'll send you any needed patches.

-- 
John Baldwin

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 00/40] C++ify target_ops, toward multi-target
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (39 preceding siblings ...)
  2018-04-16 15:15 ` [RESEND][PATCH 01/40] Convert struct target_ops to C++ Pedro Alves
@ 2018-04-27 15:47 ` Tom Tromey
  2018-05-02 22:55   ` Pedro Alves
  2018-04-29 15:22 ` Simon Marchi
  41 siblings, 1 reply; 65+ messages in thread
From: Tom Tromey @ 2018-04-27 15:47 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes:

Pedro> Here's another chunk from the multi-target branch.
Pedro> This converts target_ops to a C++ class with virtual methods.

Pedro> The reason this is part of the multi-target effort is that with
Pedro> multi-target, we will want to be able to instantiate the remote, core,
Pedro> etc. targets more than once at the same time.
[...]
Pedro> In the end, I'm
Pedro> convinced this paid off.

As you know I worked on this a bit, without success, a few years ago.  I
think your approach is definitely the way to go.

Tom

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 00/40] C++ify target_ops, toward multi-target
  2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
                   ` (40 preceding siblings ...)
  2018-04-27 15:47 ` [PATCH 00/40] C++ify target_ops, toward multi-target Tom Tromey
@ 2018-04-29 15:22 ` Simon Marchi
  2018-05-02 22:51   ` Pedro Alves
  41 siblings, 1 reply; 65+ messages in thread
From: Simon Marchi @ 2018-04-29 15:22 UTC (permalink / raw)
  To: Pedro Alves, gdb-patches

On 2018-04-14 03:09 PM, Pedro Alves wrote:
> Here's another chunk from the multi-target branch.

Hi Pedro,

It's kind of difficult to properly review this series, because the important
non-mechanical bits are lost in a sea of mechanical changes.  But I didn't
find anything fundamental I would change, and all you wrote in commit logs
made sense to me.

Maybe one little comment about 40/40 (because I just finished looking at that
patch): it might be good to add an assertion (the_native_target == nullptr)
in set_native_target and one in add_target
(target_factories.find (&t) == target_factories.end ()).  I think it could
help catch problems if somebody is trying to add a new target or change
existing ones.

Otherwise, I would suggest not waiting too long before merging it to
avoid having to resolve too many conflicts.  Thanks a lot for doing this!

Simon

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 00/40] C++ify target_ops, toward multi-target
  2018-04-29 15:22 ` Simon Marchi
@ 2018-05-02 22:51   ` Pedro Alves
  0 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-05-02 22:51 UTC (permalink / raw)
  To: Simon Marchi, gdb-patches

On 04/29/2018 04:22 PM, Simon Marchi wrote:
> On 2018-04-14 03:09 PM, Pedro Alves wrote:
>> Here's another chunk from the multi-target branch.
> 
> Hi Pedro,
> 
> It's kind of difficult to properly review this series, because the important
> non-mechanical bits are lost in a sea of mechanical changes.  

Yeah, sorry about that.

> But I didn't
> find anything fundamental I would change, and all you wrote in commit logs
> made sense to me.
> 
> Maybe one little comment about 40/40 (because I just finished looking at that
> patch): it might be good to add an assertion (the_native_target == nullptr)
> in set_native_target and one in add_target
> (target_factories.find (&t) == target_factories.end ()).  I think it could
> help catch problems if somebody is trying to add a new target or change
> existing ones.

Good idea.  I'm adding this to patch #40:

 gdb/target.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/gdb/target.c b/gdb/target.c
index b957769a3f..824855e7df 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -352,7 +352,11 @@ add_target (const target_info &t, target_open_ftype *func,
 {
   struct cmd_list_element *c;
 
-  target_factories[&t] = func;
+  auto &func_slot = target_factories[&t];
+  if (func_slot != nullptr)
+    internal_error (__FILE__, __LINE__,
+		    "target already added (\"%s\").", t.shortname);
+  func_slot = func;
 
   if (targetlist == NULL)
     add_prefix_cmd ("target", class_run, target_command, _("\
@@ -2447,6 +2451,11 @@ static target_ops *the_native_target;
 void
 set_native_target (target_ops *target)
 {
+  if (the_native_target != NULL)
+    internal_error (__FILE__, __LINE__,
+		    _("native target already set (\"%s\")."),
+		    the_native_target->longname ());
+
   the_native_target = target;
 }

> Otherwise, I would suggest not waiting too long before merging it to
> avoid having to resolve too many conflicts.  Thanks a lot for doing this!
Alright, I wrote the missing ChangeLogs today, and will proceed with
squashing the patches that need to be squashed and getting it all in.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 00/40] C++ify target_ops, toward multi-target
  2018-04-27 15:47 ` [PATCH 00/40] C++ify target_ops, toward multi-target Tom Tromey
@ 2018-05-02 22:55   ` Pedro Alves
  0 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-05-02 22:55 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

On 04/27/2018 04:47 PM, Tom Tromey wrote:
>>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes:
> 
> Pedro> Here's another chunk from the multi-target branch.
> Pedro> This converts target_ops to a C++ class with virtual methods.
> 
> Pedro> The reason this is part of the multi-target effort is that with
> Pedro> multi-target, we will want to be able to instantiate the remote, core,
> Pedro> etc. targets more than once at the same time.
> [...]
> Pedro> In the end, I'm
> Pedro> convinced this paid off.
> 
> As you know I worked on this a bit, without success, a few years ago.  I
> think your approach is definitely the way to go.

Thanks Tom.  I wouldn't say without success at all -- you finished
important groundwork at the time, like for example all the
delegation cleaning up and normalization.  Remember that 200 patch
series? :-)  And of course the ideas on my branch draw lessons from
your earlier experiments.

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RESEND][PATCH 01/40] Convert struct target_ops to C++
  2018-04-16 15:15 ` [RESEND][PATCH 01/40] Convert struct target_ops to C++ Pedro Alves
@ 2018-05-03  0:06   ` Pedro Alves
  2018-10-27 21:58     ` 8.2 regression for invalid -data-directory [Re: [RESEND][PATCH 01/40] Convert struct target_ops to C++] Jan Kratochvil
  2019-02-14 15:30     ` [RESEND][PATCH 01/40] Convert struct target_ops to C++ Thomas Schwinge
  0 siblings, 2 replies; 65+ messages in thread
From: Pedro Alves @ 2018-05-03  0:06 UTC (permalink / raw)
  To: gdb-patches

On 04/16/2018 04:14 PM, Pedro Alves wrote:
> Since the patch would be too big
> to review and manage as a single unit, I split it in many chunks.
> This patch contains the core changes.  The following patches that have
> "target_ops/C++:" in their subject line each converts some target or
> targets over.  For pushing, all the "target_ops/C++:" patches must be
> squashed into this patch and pushed together, to avoid breaking the
> build (as much as possible).  I also haven't written ChangeLog entries
> for this part of the series yet, because it's going to be very
> mechanical, and I'd rather send this out sooner than later, in order
> to hopefuly get some help with testing on native ports that I don't
> have access to.

I've now written the ChangeLog entries, squashed all the 
"target_ops/C++:" patches into this one, and pushed the whole series
in.

For the record, below is what the commit looks like, git log + ChangeLog.
The actual patch is elided.

From f6ac5f3d63e03a81c4ff3749aba234961cc9090e Mon Sep 17 00:00:00 2001
From: Pedro Alves <palves@redhat.com>
Date: Thu, 3 May 2018 00:37:22 +0100
Subject: [PATCH] Convert struct target_ops to C++

I.e., use C++ virtual methods and inheritance instead of tables of
function pointers.

Unfortunately, there's no way to do a smooth transition.  ALL native
targets in the tree must be converted at the same time.  I've tested
all I could with cross compilers and with help from GCC compile farm,
but naturally I haven't been able to test many of the ports.  Still, I
made a best effort to port everything over, and while I expect some
build problems due to typos and such, which should be trivial to fix,
I don't expect any design problems.

* Implementation notes:

- The flattened current_target is gone.  References to current_target
  or current_target.beneath are replaced with references to
  target_stack (the top of the stack) directly.

- To keep "set debug target" working, this adds a new debug_stratum
  layer that sits on top of the stack, prints the debug, and delegates
  to the target beneath.

  In addition, this makes the shortname and longname properties of
  target_ops be virtual methods instead of data fields, and makes the
  debug target defer those to the target beneath.  This is so that
  debug code sprinkled around that does "if (debugtarget) ..."  can
  transparently print the name of the target beneath.

  A patch later in the series actually splits out the
  shortname/longname methods to a separate structure, but I preferred
  to keep that chance separate as it is associated with changing a bit
  the design of how targets are registered and open.

- Since you can't check whether a C++ virtual method is overridden,
  the old method of checking whether a target_ops implements a method
  by comparing the function pointer must be replaced with something
  else.

  Some cases are fixed by adding a parallel "can_do_foo" target_ops
  methods.  E.g.,:

    +  for (t = target_stack; t != NULL; t = t->beneath)
	 {
    -      if (t->to_create_inferior != NULL)
    +      if (t->can_create_inferior ())
	    break;
	 }

  Others are fixed by changing void return type to bool or int return
  type, and have the default implementation return false or -1, to
  indicate lack of support.

- make-target-delegates was adjusted to generate C++ classes and
  methods.

  It needed tweaks to grok "virtual" in front of the target method
  name, and for the fact that methods are no longer function pointers.
  (In particular, the current code parsing the return type was simple
  because it could simply parse up until the '(' in '(*to_foo)'.

  It now generates a couple C++ classes that inherit target_ops:
  dummy_target and debug_target.

  Since we need to generate the class declarations as well, i.e., we
  need to emit methods twice, we now generate the code in two passes.

- The core_target global is renamed to avoid conflict with the
  "core_target" class.

- ctf/tfile targets

  init_tracefile_ops is replaced by a base class that is inherited by
  both ctf and tfile.

- bsd-uthread

  The bsd_uthread_ops_hack hack is gone.  It's not needed because
  nothing was extending a target created by bsd_uthread_target.

- remote/extended-remote targets

  This is a first pass, just enough to C++ify target_ops.

  A later pass will convert more free functions to methods, and make
  remote_state be truly per remote instance, allowing multiple
  simultaneous instances of remote targets.

- inf-child/"native" is converted to an actual base class
  (inf_child_target), that is inherited by all native targets.

- GNU/Linux

  The old weird double-target linux_ops mechanism in linux-nat.c, is
  gone, replaced by adding a few virtual methods to linux-nat.h's
  target_ops, called low_XXX, that the concrete linux-nat
  implementations override.  Sort of like gdbserver's
  linux_target_ops, but simpler, for requiring only one
  target_ops-like hierarchy, which spares implementing the same method
  twice when we need to forward the method to a low implementation.
  The low target simply reimplements the target_ops method directly in
  that case.

  There are a few remaining linux-nat.c hooks that would be better
  converted to low_ methods like above too.  E.g.:

   linux_nat_set_new_thread (t, x86_linux_new_thread);
   linux_nat_set_new_fork (t, x86_linux_new_fork);
   linux_nat_set_forget_process

  That'll be done in a follow up patch.

- We can no longer use functions like x86_use_watchpoints to install
  custom methods on an arbitrary base target.

  The patch replaces instances of such a pattern with template mixins.
  For example memory_breakpoint_target defined in target.h, or
  x86_nat_target in x86-nat.h.

- linux_trad_target, MIPS and Alpha GNU/Linux

  The code in the new linux-nat-trad.h/c files which was split off of
  inf-ptrace.h/c recently, is converted to a C++ base class, and used
  by the MIPS and Alpha GNU/Linux ports.

- BSD targets

  The

    $architecture x NetBSD/OpenBSD/FreeBSD

  support matrix complicates things a bit.  There's common BSD target
  code, and there's common architecture-specific code shared between
  the different BSDs.  Currently, all that is stiched together to form
  a final target, via the i386bsd_target, x86bsd_target,
  fbsd_nat_add_target functions etc.

  This introduces new fbsd_nat_target, obsd_nat_target and
  nbsd_nat_target classes that serve as base/prototype target for the
  corresponding BSD variant.

  And introduces generic i386/AMD64 BSD targets, to be used as
  template mixin to build a final target.  Similarly, a generic SPARC
  target is added, used by both BSD and Linux ports.

- bsd_kvm_add_target, BSD libkvm target

  I considered making bsd_kvm_supply_pcb a virtual method, and then
  have each port inherit bsd_kvm_target and override that method, but
  that was resulting in lots of unjustified churn, so I left the
  function pointer mechanism alone.

gdb/ChangeLog:
2018-05-02  Pedro Alves  <palves@redhat.com>
	    John Baldwin  <jhb@freebsd.org>

	* target.h (enum strata) <debug_stratum>: New.
	(struct target_ops) <all delegation methods>: Replace by C++
	virtual methods, and drop "to_" prefix.  All references updated
	throughout.
	<to_shortname, to_longname, to_doc, to_data,
	to_have_steppable_watchpoint, to_have_continuable_watchpoint,
	to_has_thread_control, to_attach_no_wait>: Delete, replaced by
	virtual methods.  All references updated throughout.
	<can_attach, supports_terminal_ours, can_create_inferior,
	get_thread_control_capabilities, attach_no_wait>: New
	virtual methods.
	<insert_breakpoint, remove_breakpoint>: Now
	TARGET_DEFAULT_NORETURN methods.
	<info_proc>: Now returns bool.
	<to_magic>: Delete.
	(OPS_MAGIC): Delete.
	(current_target): Delete.  All references replaced by references
	to ...
	(target_stack): ... this.  New.
	(target_shortname, target_longname): Adjust.
	(target_can_run): Now a function declaration.
	(default_child_has_all_memory, default_child_has_memory)
	(default_child_has_stack, default_child_has_registers)
	(default_child_has_execution): Remove target_ops parameter.
	(complete_target_initialization): Delete.
	(memory_breakpoint_target): New template class.
	(test_target_ops): Refactor as a C++ class with virtual methods.
	* make-target-delegates (NAME_PART): Tighten.
	(POINTER_PART, CP_SYMBOL): New.
	(SIMPLE_RETURN_PART): Reimplement.
	(VEC_RETURN_PART): Expect less.
	(RETURN_PART, VIRTUAL_PART): New.
	(METHOD): Adjust to C++ virtual methods.
	(scan_target_h): Remove reference to C99.
	(dname): Output "target_ops::" prefix.
	(write_function_header): Adjust to output a C++ class method.
	(write_declaration): New.
	(write_delegator): Adjust to output a C++ class method.
	(tdname): Output "dummy_target::" prefix.
	(write_tdefault, write_debugmethod): Adjust to output a C++ class
	method.
	(tdefault_names, debug_names): Delete.
	(return_types, tdefaults, styles, argtypes_array): New.
	(top level): All methods are delegators.
	(print_class): New.
	(top level): Print dummy_target and debug_target classes.
	* target-delegates.c: Regenerate.
	* target-debug.h (target_debug_print_enum_info_proc_what)
	(target_debug_print_thread_control_capabilities)
	(target_debug_print_thread_info_p): New.
	* target.c (dummy_target): Delete.
	(the_dummy_target, the_debug_target): New.
	(target_stack): Now extern.
	(set_targetdebug): Push/unpush debug target.
	(default_child_has_all_memory, default_child_has_memory)
	(default_child_has_stack, default_child_has_registers)
	(default_child_has_execution): Remove target_ops parameter.
	(complete_target_initialization): Delete.
	(add_target_with_completer): No longer call
	complete_target_initialization.
	(target_supports_terminal_ours): Use regular delegation.
	(update_current_target): Delete.
	(push_target): No longer check magic number.  Don't call
	update_current_target.
	(unpush_target): Don't call update_current_target.
	(target_is_pushed): No longer check magic number.
	(target_require_runnable): Skip for all stratums over
	process_stratum.
	(target_ops::info_proc): New.
	(target_info_proc): Use find_target_at and
	find_default_run_target.
	(target_supports_disable_randomization): Use regular delegation.
	(target_get_osdata): Use find_target_at.
	(target_ops::open, target_ops::close, target_ops::can_attach)
	(target_ops::attach, target_ops::can_create_inferior)
	(target_ops::create_inferior, target_ops::can_run)
	(target_can_run): New.
	(default_fileio_target): Use regular delegation.
	(target_ops::fileio_open, target_ops::fileio_pwrite)
	(target_ops::fileio_pread, target_ops::fileio_fstat)
	(target_ops::fileio_close, target_ops::fileio_unlink)
	(target_ops::fileio_readlink): New.
	(target_fileio_open_1, target_fileio_unlink)
	(target_fileio_readlink): Always call the target method.  Handle
	FILEIO_ENOSYS.
	(return_zero, return_zero_has_execution): Delete.
	(init_dummy_target): Delete.
	(dummy_target::dummy_target, dummy_target::shortname)
	(dummy_target::longname, dummy_target::doc)
	(debug_target::debug_target, debug_target::shortname)
	(debug_target::longname, debug_target::doc): New.
	(target_supports_delete_record): Use regular delegation.
	(setup_target_debug): Delete.
	(maintenance_print_target_stack): Skip debug_stratum.
	(initialize_targets): Instantiate the_dummy_target and
	the_debug_target.
	* auxv.c (target_auxv_parse): Remove 'ops' parameter.  Adjust to
	use target_stack.
	(target_auxv_search, fprint_target_auxv): Adjust.
	(info_auxv_command): Adjust to use target_stack.
	* auxv.h (target_auxv_parse): Remove 'ops' parameter.
	* exceptions.c (print_flush): Handle a NULL target_stack.
	* regcache.c (target_ops_no_register): Refactor as class with
	virtual methods.

	* exec.c (exec_target): New class.
	(exec_ops): Now an exec_target.
	(exec_open, exec_close_1, exec_get_section_table)
	(exec_xfer_partial, exec_files_info, exec_has_memory)
	(exec_make_note_section): Refactor as exec_target methods.
	(exec_file_clear, ignore, exec_remove_breakpoint, init_exec_ops):
	Delete.
	(exec_target::find_memory_regions): New.
	(_initialize_exec): Don't call init_exec_ops.
	* gdbcore.h (exec_file_clear): Delete.

	* corefile.c (core_target): Delete.
	(core_file_command): Adjust.
	* corelow.c (core_target): New class.
	(the_core_target): New.
	(core_close): Remove target_ops parameter.
	(core_close_cleanup): Adjust.
	(core_target::close): New.
	(core_open, core_detach, get_core_registers, core_files_info)
	(core_xfer_partial, core_thread_alive, core_read_description)
	(core_pid_to_str, core_thread_name, core_has_memory)
	(core_has_stack, core_has_registers, core_info_proc): Rework as
	core_target methods.
	(ignore, core_remove_breakpoint, init_core_ops): Delete.
	(_initialize_corelow): Initialize the_core_target.
	* gdbcore.h (core_target): Delete.
	(the_core_target): New.

	* ctf.c: (ctf_target): New class.
	(ctf_ops): Now a ctf_target.
	(ctf_open, ctf_close, ctf_files_info, ctf_fetch_registers)
	(ctf_xfer_partial, ctf_get_trace_state_variable_value)
	(ctf_trace_find, ctf_traceframe_info): Refactor as ctf_target
	methods.
	(init_ctf_ops): Delete.
	(_initialize_ctf): Don't call it.
	* tracefile-tfile.c (tfile_target): New class.
	(tfile_ops): Now a tfile_target.
	(tfile_open, tfile_close, tfile_files_info)
	(tfile_get_tracepoint_status, tfile_trace_find)
	(tfile_fetch_registers, tfile_xfer_partial)
	(tfile_get_trace_state_variable_value, tfile_traceframe_info):
	Refactor as tfile_target methods.
	(tfile_xfer_partial_features): Remove target_ops parameter.
	(init_tfile_ops): Delete.
	(_initialize_tracefile_tfile): Don't call it.
	* tracefile.c (tracefile_has_all_memory, tracefile_has_memory)
	(tracefile_has_stack, tracefile_has_registers)
	(tracefile_thread_alive, tracefile_get_trace_status): Refactor as
	tracefile_target methods.
	(init_tracefile_ops): Delete.
	(tracefile_target::tracefile_target): New.
	* tracefile.h: Include "target.h".
	(tracefile_target): New class.
	(init_tracefile_ops): Delete.

	* spu-multiarch.c (spu_multiarch_target): New class.
	(spu_ops): Now a spu_multiarch_target.
	(spu_thread_architecture, spu_region_ok_for_hw_watchpoint)
	(spu_fetch_registers, spu_store_registers, spu_xfer_partial)
	(spu_search_memory, spu_mourn_inferior): Refactor as
	spu_multiarch_target methods.
	(init_spu_ops): Delete.
	(_initialize_spu_multiarch): Remove references to init_spu_ops,
	complete_target_initialization.

	* ravenscar-thread.c (ravenscar_thread_target): New class.
	(ravenscar_ops): Now a ravenscar_thread_target.
	(ravenscar_resume, ravenscar_wait, ravenscar_update_thread_list)
	(ravenscar_thread_alive, ravenscar_pid_to_str)
	(ravenscar_fetch_registers, ravenscar_store_registers)
	(ravenscar_prepare_to_store, ravenscar_stopped_by_sw_breakpoint)
	(ravenscar_stopped_by_hw_breakpoint)
	(ravenscar_stopped_by_watchpoint, ravenscar_stopped_data_address)
	(ravenscar_mourn_inferior, ravenscar_core_of_thread)
	(ravenscar_get_ada_task_ptid): Refactor as ravenscar_thread_target
	methods.
	(init_ravenscar_thread_ops): Delete.
	(_initialize_ravenscar): Remove references to
	init_ravenscar_thread_ops and complete_target_initialization.

	* bsd-uthread.c (bsd_uthread_ops_hack): Delete.
	(bsd_uthread_target): New class.
	(bsd_uthread_ops): Now a bsd_uthread_target.
	(bsd_uthread_activate): Adjust to refer to bsd_uthread_ops.
	(bsd_uthread_close, bsd_uthread_mourn_inferior)
	(bsd_uthread_fetch_registers, bsd_uthread_store_registers)
	(bsd_uthread_wait, bsd_uthread_resume, bsd_uthread_thread_alive)
	(bsd_uthread_update_thread_list, bsd_uthread_extra_thread_info)
	(bsd_uthread_pid_to_str): Refactor as bsd_uthread_target methods.
	(bsd_uthread_target): Delete function.
	(_initialize_bsd_uthread): Remove reference to
	complete_target_initialization.

	* bfd-target.c (target_bfd_data): Delete.  Fields folded into ...
	(target_bfd): ... this new class.
	(target_bfd_xfer_partial, target_bfd_get_section_table)
	(target_bfd_close): Refactor as target_bfd methods.
	(target_bfd::~target_bfd): New.
	(target_bfd_reopen): Adjust.
	(target_bfd::close): New.

	* record-btrace.c (record_btrace_target): New class.
	(record_btrace_ops): Now a record_btrace_target.
	(record_btrace_open, record_btrace_stop_recording)
	(record_btrace_disconnect, record_btrace_close)
	(record_btrace_async, record_btrace_info)
	(record_btrace_insn_history, record_btrace_insn_history_range)
	(record_btrace_insn_history_from, record_btrace_call_history)
	(record_btrace_call_history_range)
	(record_btrace_call_history_from, record_btrace_record_method)
	(record_btrace_is_replaying, record_btrace_will_replay)
	(record_btrace_xfer_partial, record_btrace_insert_breakpoint)
	(record_btrace_remove_breakpoint, record_btrace_fetch_registers)
	(record_btrace_store_registers, record_btrace_prepare_to_store)
	(record_btrace_to_get_unwinder)
	(record_btrace_to_get_tailcall_unwinder, record_btrace_resume)
	(record_btrace_commit_resume, record_btrace_wait)
	(record_btrace_stop, record_btrace_can_execute_reverse)
	(record_btrace_stopped_by_sw_breakpoint)
	(record_btrace_supports_stopped_by_sw_breakpoint)
	(record_btrace_stopped_by_hw_breakpoint)
	(record_btrace_supports_stopped_by_hw_breakpoint)
	(record_btrace_update_thread_list, record_btrace_thread_alive)
	(record_btrace_goto_begin, record_btrace_goto_end)
	(record_btrace_goto, record_btrace_stop_replaying_all)
	(record_btrace_execution_direction)
	(record_btrace_prepare_to_generate_core)
	(record_btrace_done_generating_core): Refactor as
	record_btrace_target methods.
	(init_record_btrace_ops): Delete.
	(_initialize_record_btrace): Remove reference to
	init_record_btrace_ops.
	* record-full.c (RECORD_FULL_IS_REPLAY): Adjust to always refer to
	the execution_direction global.
	(record_full_base_target, record_full_target)
	(record_full_core_target): New classes.
	(record_full_ops): Now a record_full_target.
	(record_full_core_ops): Now a record_full_core_target.
	(record_full_target::detach, record_full_target::disconnect)
	(record_full_core_target::disconnect)
	(record_full_target::mourn_inferior, record_full_target::kill):
	New.
	(record_full_open, record_full_close, record_full_async): Refactor
	as methods of the record_full_base_target class.
	(record_full_resume, record_full_commit_resume): Refactor
	as methods of the record_full_target class.
	(record_full_wait, record_full_stopped_by_watchpoint)
	(record_full_stopped_data_address)
	(record_full_stopped_by_sw_breakpoint)
	(record_full_supports_stopped_by_sw_breakpoint)
	(record_full_stopped_by_hw_breakpoint)
	(record_full_supports_stopped_by_hw_breakpoint): Refactor as
	methods of the record_full_base_target class.
	(record_full_store_registers, record_full_xfer_partial)
	(record_full_insert_breakpoint, record_full_remove_breakpoint):
	Refactor as methods of the record_full_target class.
	(record_full_can_execute_reverse, record_full_get_bookmark)
	(record_full_goto_bookmark, record_full_execution_direction)
	(record_full_record_method, record_full_info, record_full_delete)
	(record_full_is_replaying, record_full_will_replay)
	(record_full_goto_begin, record_full_goto_end, record_full_goto)
	(record_full_stop_replaying): Refactor as methods of the
	record_full_base_target class.
	(record_full_core_resume, record_full_core_kill)
	(record_full_core_fetch_registers)
	(record_full_core_prepare_to_store)
	(record_full_core_store_registers, record_full_core_xfer_partial)
	(record_full_core_insert_breakpoint)
	(record_full_core_remove_breakpoint)
	(record_full_core_has_execution): Refactor
	as methods of the record_full_core_target class.
	(record_full_base_target::supports_delete_record): New.
	(init_record_full_ops): Delete.
	(init_record_full_core_ops): Delete.
	(record_full_save): Refactor as method of the
	record_full_base_target class.
	(_initialize_record_full): Remove references to
	init_record_full_ops and init_record_full_core_ops.

	* remote.c (remote_target, extended_remote_target): New classes.
	(remote_ops): Now a remote_target.
	(extended_remote_ops): Now an extended_remote_target.
	(remote_insert_fork_catchpoint, remote_remove_fork_catchpoint)
	(remote_insert_vfork_catchpoint, remote_remove_vfork_catchpoint)
	(remote_insert_exec_catchpoint, remote_remove_exec_catchpoint)
	(remote_pass_signals, remote_set_syscall_catchpoint)
	(remote_program_signals, )
	(remote_thread_always_alive): Remove target_ops parameter.
	(remote_thread_alive, remote_thread_name)
	(remote_update_thread_list, remote_threads_extra_info)
	(remote_static_tracepoint_marker_at)
	(remote_static_tracepoint_markers_by_strid)
	(remote_get_ada_task_ptid, remote_close, remote_start_remote)
	(remote_open): Refactor as methods of remote_target.
	(extended_remote_open, extended_remote_detach)
	(extended_remote_attach, extended_remote_post_attach):
	(extended_remote_supports_disable_randomization)
	(extended_remote_create_inferior): : Refactor as method of
	extended_remote_target.
	(remote_set_permissions, remote_open_1, remote_detach)
	(remote_follow_fork, remote_follow_exec, remote_disconnect)
	(remote_resume, remote_commit_resume, remote_stop)
	(remote_interrupt, remote_pass_ctrlc, remote_terminal_inferior)
	(remote_terminal_ours, remote_wait, remote_fetch_registers)
	(remote_prepare_to_store, remote_store_registers)
	(remote_flash_erase, remote_flash_done, remote_files_info)
	(remote_kill, remote_mourn, remote_insert_breakpoint)
	(remote_remove_breakpoint, remote_insert_watchpoint)
	(remote_watchpoint_addr_within_range)
	(remote_remove_watchpoint, remote_region_ok_for_hw_watchpoint)
	(remote_check_watch_resources, remote_stopped_by_sw_breakpoint)
	(remote_supports_stopped_by_sw_breakpoint)
	(remote_stopped_by_hw_breakpoint)
	(remote_supports_stopped_by_hw_breakpoint)
	(remote_stopped_by_watchpoint, remote_stopped_data_address)
	(remote_insert_hw_breakpoint, remote_remove_hw_breakpoint)
	(remote_verify_memory): Refactor as methods of remote_target.
	(remote_write_qxfer, remote_read_qxfer): Remove target_ops
	parameter.
	(remote_xfer_partial, remote_get_memory_xfer_limit)
	(remote_search_memory, remote_rcmd, remote_memory_map)
	(remote_pid_to_str, remote_get_thread_local_address)
	(remote_get_tib_address, remote_read_description): Refactor as
	methods of remote_target.
	(remote_target::fileio_open, remote_target::fileio_pwrite)
	(remote_target::fileio_pread, remote_target::fileio_close): New.
	(remote_hostio_readlink, remote_hostio_fstat)
	(remote_filesystem_is_local, remote_can_execute_reverse)
	(remote_supports_non_stop, remote_supports_disable_randomization)
	(remote_supports_multi_process, remote_supports_cond_breakpoints)
	(remote_supports_enable_disable_tracepoint)
	(remote_supports_string_tracing)
	(remote_can_run_breakpoint_commands, remote_trace_init)
	(remote_download_tracepoint, remote_can_download_tracepoint)
	(remote_download_trace_state_variable, remote_enable_tracepoint)
	(remote_disable_tracepoint, remote_trace_set_readonly_regions)
	(remote_trace_start, remote_get_trace_status)
	(remote_get_tracepoint_status, remote_trace_stop)
	(remote_trace_find, remote_get_trace_state_variable_value)
	(remote_save_trace_data, remote_get_raw_trace_data)
	(remote_set_disconnected_tracing, remote_core_of_thread)
	(remote_set_circular_trace_buffer, remote_traceframe_info)
	(remote_get_min_fast_tracepoint_insn_len)
	(remote_set_trace_buffer_size, remote_set_trace_notes)
	(remote_use_agent, remote_can_use_agent, remote_enable_btrace)
	(remote_disable_btrace, remote_teardown_btrace)
	(remote_read_btrace, remote_btrace_conf)
	(remote_augmented_libraries_svr4_read, remote_load)
	(remote_pid_to_exec_file, remote_can_do_single_step)
	(remote_execution_direction, remote_thread_handle_to_thread_info):
	Refactor as methods of remote_target.
	(init_remote_ops, init_extended_remote_ops): Delete.
	(remote_can_async_p, remote_is_async_p, remote_async)
	(remote_thread_events, remote_upload_tracepoints)
	(remote_upload_trace_state_variables): Refactor as methods of
	remote_target.
	(_initialize_remote): Remove references to init_remote_ops and
	init_extended_remote_ops.

	* remote-sim.c (gdbsim_target): New class.
	(gdbsim_fetch_register, gdbsim_store_register, gdbsim_kill)
	(gdbsim_load, gdbsim_create_inferior, gdbsim_open, gdbsim_close)
	(gdbsim_detach, gdbsim_resume, gdbsim_interrupt)
	(gdbsim_wait, gdbsim_prepare_to_store, gdbsim_xfer_partial)
	(gdbsim_files_info, gdbsim_mourn_inferior, gdbsim_thread_alive)
	(gdbsim_pid_to_str, gdbsim_has_all_memory, gdbsim_has_memory):
	Refactor as methods of gdbsim_target.
	(gdbsim_ops): Now a gdbsim_target.
	(init_gdbsim_ops): Delete.
	(gdbsim_cntrl_c): Adjust.
	(_initialize_remote_sim): Remove reference to init_gdbsim_ops.

	* amd64-linux-nat.c (amd64_linux_nat_target): New class.
	(the_amd64_linux_nat_target): New.
	(amd64_linux_fetch_inferior_registers)
	(amd64_linux_store_inferior_registers): Refactor as methods of
	amd64_linux_nat_target.
	(_initialize_amd64_linux_nat): Adjust.  Set linux_target.
	* i386-linux-nat.c: Don't include "linux-nat.h".
	(i386_linux_nat_target): New class.
	(the_i386_linux_nat_target): New.
	(i386_linux_fetch_inferior_registers)
	(i386_linux_store_inferior_registers, i386_linux_resume): Refactor
	as methods of i386_linux_nat_target.
	(_initialize_i386_linux_nat): Adjust.  Set linux_target.
	* inf-child.c (inf_child_ops): Delete.
	(inf_child_fetch_inferior_registers)
	(inf_child_store_inferior_registers): Delete.
	(inf_child_post_attach, inf_child_prepare_to_store): Refactor as
	methods of inf_child_target.
	(inf_child_target::supports_terminal_ours)
	(inf_child_target::terminal_init)
	(inf_child_target::terminal_inferior)
	(inf_child_target::terminal_ours_for_output)
	(inf_child_target::terminal_ours, inf_child_target::interrupt)
	(inf_child_target::pass_ctrlc, inf_child_target::terminal_info):
	New.
	(inf_child_open, inf_child_disconnect, inf_child_close)
	(inf_child_mourn_inferior, inf_child_maybe_unpush_target)
	(inf_child_post_startup_inferior, inf_child_can_run)
	(inf_child_pid_to_exec_file): Refactor as methods of
	inf_child_target.
	(inf_child_follow_fork): Delete.
	(inf_child_target::can_create_inferior)
	(inf_child_target::can_attach): New.
	(inf_child_target::has_all_memory, inf_child_target::has_memory)
	(inf_child_target::has_stack, inf_child_target::has_registers)
	(inf_child_target::has_execution): New.
	(inf_child_fileio_open, inf_child_fileio_pwrite)
	(inf_child_fileio_pread, inf_child_fileio_fstat)
	(inf_child_fileio_close, inf_child_fileio_unlink)
	(inf_child_fileio_readlink, inf_child_use_agent)
	(inf_child_can_use_agent): Refactor as methods of
	inf_child_target.
	(return_zero, inf_child_target): Delete.
	(inf_child_target::inf_child_target): New.
	* inf-child.h: Include "target.h".
	(inf_child_target): Delete function prototype.
	(inf_child_target): New class.
	(inf_child_open_target, inf_child_mourn_inferior)
	(inf_child_maybe_unpush_target): Delete.
	* inf-ptrace.c (inf_ptrace_target::~inf_ptrace_target): New.
	(inf_ptrace_follow_fork, inf_ptrace_insert_fork_catchpoint)
	(inf_ptrace_remove_fork_catchpoint, inf_ptrace_create_inferior)
	(inf_ptrace_post_startup_inferior, inf_ptrace_mourn_inferior)
	(inf_ptrace_attach, inf_ptrace_post_attach, inf_ptrace_detach)
	(inf_ptrace_detach_success, inf_ptrace_kill, inf_ptrace_resume)
	(inf_ptrace_wait, inf_ptrace_xfer_partial)
	(inf_ptrace_thread_alive, inf_ptrace_files_info)
	(inf_ptrace_pid_to_str, inf_ptrace_auxv_parse): Refactor as
	methods of inf_ptrace_target.
	(inf_ptrace_target): Delete function.
	* inf-ptrace.h: Include "inf-child.h".
	(inf_ptrace_target): Delete function declaration.
	(inf_ptrace_target): New class.
	(inf_ptrace_trad_target, inf_ptrace_detach_success): Delete.
	* linux-nat.c (linux_target): New.
	(linux_ops, linux_ops_saved, super_xfer_partial): Delete.
	(linux_nat_target::~linux_nat_target): New.
	(linux_child_post_attach, linux_child_post_startup_inferior)
	(linux_child_follow_fork, linux_child_insert_fork_catchpoint)
	(linux_child_remove_fork_catchpoint)
	(linux_child_insert_vfork_catchpoint)
	(linux_child_remove_vfork_catchpoint)
	(linux_child_insert_exec_catchpoint)
	(linux_child_remove_exec_catchpoint)
	(linux_child_set_syscall_catchpoint, linux_nat_pass_signals)
	(linux_nat_create_inferior, linux_nat_attach, linux_nat_detach)
	(linux_nat_resume, linux_nat_stopped_by_watchpoint)
	(linux_nat_stopped_data_address)
	(linux_nat_stopped_by_sw_breakpoint)
	(linux_nat_supports_stopped_by_sw_breakpoint)
	(linux_nat_stopped_by_hw_breakpoint)
	(linux_nat_supports_stopped_by_hw_breakpoint, linux_nat_wait)
	(linux_nat_kill, linux_nat_mourn_inferior)
	(linux_nat_xfer_partial, linux_nat_thread_alive)
	(linux_nat_update_thread_list, linux_nat_pid_to_str)
	(linux_nat_thread_name, linux_child_pid_to_exec_file)
	(linux_child_static_tracepoint_markers_by_strid)
	(linux_nat_is_async_p, linux_nat_can_async_p)
	(linux_nat_supports_non_stop, linux_nat_always_non_stop_p)
	(linux_nat_supports_multi_process)
	(linux_nat_supports_disable_randomization, linux_nat_async)
	(linux_nat_stop, linux_nat_close, linux_nat_thread_address_space)
	(linux_nat_core_of_thread, linux_nat_filesystem_is_local)
	(linux_nat_fileio_open, linux_nat_fileio_readlink)
	(linux_nat_fileio_unlink, linux_nat_thread_events): Refactor as
	methods of linux_nat_target.
	(linux_nat_wait_1, linux_xfer_siginfo, linux_proc_xfer_partial)
	(linux_proc_xfer_spu, linux_nat_xfer_osdata): Remove target_ops
	parameter.
	(check_stopped_by_watchpoint): Adjust.
	(linux_xfer_partial): Delete.
	(linux_target_install_ops, linux_target, linux_nat_add_target):
	Delete.
	(linux_nat_target::linux_nat_target): New.
	* linux-nat.h: Include "inf-ptrace.h".
	(linux_nat_target): New.
	(linux_target, linux_target_install_ops, linux_nat_add_target):
	Delete function declarations.
	(linux_target): Declare global.
	* linux-thread-db.c (thread_db_target): New.
	(thread_db_target::thread_db_target): New.
	(thread_db_ops): Delete.
	(the_thread_db_target): New.
	(thread_db_detach, thread_db_wait, thread_db_mourn_inferior)
	(thread_db_update_thread_list, thread_db_pid_to_str)
	(thread_db_extra_thread_info)
	(thread_db_thread_handle_to_thread_info)
	(thread_db_get_thread_local_address, thread_db_get_ada_task_ptid)
	(thread_db_resume): Refactor as methods of thread_db_target.
	(init_thread_db_ops): Delete.
	(_initialize_thread_db): Remove reference to init_thread_db_ops.
	* x86-linux-nat.c: Don't include "linux-nat.h".
	(super_post_startup_inferior): Delete.
	(x86_linux_nat_target::~x86_linux_nat_target): New.
	(x86_linux_child_post_startup_inferior)
	(x86_linux_read_description, x86_linux_enable_btrace)
	(x86_linux_disable_btrace, x86_linux_teardown_btrace)
	(x86_linux_read_btrace, x86_linux_btrace_conf): Refactor as
	methods of x86_linux_nat_target.
	(x86_linux_create_target): Delete.  Bits folded ...
	(x86_linux_add_target): ... here.  Now takes a linux_nat_target
	pointer.
	* x86-linux-nat.h: Include "linux-nat.h" and "x86-nat.h".
	(x86_linux_nat_target): New class.
	(x86_linux_create_target): Delete.
	(x86_linux_add_target): Now takes a linux_nat_target pointer.
	* x86-nat.c (x86_insert_watchpoint, x86_remove_watchpoint)
	(x86_region_ok_for_watchpoint, x86_stopped_data_address)
	(x86_stopped_by_watchpoint, x86_insert_hw_breakpoint)
	(x86_remove_hw_breakpoint, x86_can_use_hw_breakpoint)
	(x86_stopped_by_hw_breakpoint): Remove target_ops parameter and
	make extern.
	(x86_use_watchpoints): Delete.
	* x86-nat.h: Include "breakpoint.h" and "target.h".
	(x86_use_watchpoints): Delete.
	(x86_can_use_hw_breakpoint, x86_region_ok_for_hw_watchpoint)
	(x86_stopped_by_watchpoint, x86_stopped_data_address)
	(x86_insert_watchpoint, x86_remove_watchpoint)
	(x86_insert_hw_breakpoint, x86_remove_hw_breakpoint)
	(x86_stopped_by_hw_breakpoint): New declarations.
	(x86_nat_target): New template class.

	* ppc-linux-nat.c (ppc_linux_nat_target): New class.
	(the_ppc_linux_nat_target): New.
	(ppc_linux_fetch_inferior_registers)
	(ppc_linux_can_use_hw_breakpoint)
	(ppc_linux_region_ok_for_hw_watchpoint)
	(ppc_linux_ranged_break_num_registers)
	(ppc_linux_insert_hw_breakpoint, ppc_linux_remove_hw_breakpoint)
	(ppc_linux_insert_mask_watchpoint)
	(ppc_linux_remove_mask_watchpoint)
	(ppc_linux_can_accel_watchpoint_condition)
	(ppc_linux_insert_watchpoint, ppc_linux_remove_watchpoint)
	(ppc_linux_stopped_data_address, ppc_linux_stopped_by_watchpoint)
	(ppc_linux_watchpoint_addr_within_range)
	(ppc_linux_masked_watch_num_registers)
	(ppc_linux_store_inferior_registers, ppc_linux_auxv_parse)
	(ppc_linux_read_description): Refactor as methods of
	ppc_linux_nat_target.
	(_initialize_ppc_linux_nat): Adjust.  Set linux_target.

	* procfs.c (procfs_xfer_partial): Delete forward declaration.
	(procfs_target): New class.
	(the_procfs_target): New.
	(procfs_target): Delete function.
	(procfs_auxv_parse, procfs_attach, procfs_detach)
	(procfs_fetch_registers, procfs_store_registers, procfs_wait)
	(procfs_xfer_partial, procfs_resume, procfs_pass_signals)
	(procfs_files_info, procfs_kill_inferior, procfs_mourn_inferior)
	(procfs_create_inferior, procfs_update_thread_list)
	(procfs_thread_alive, procfs_pid_to_str)
	(procfs_can_use_hw_breakpoint, procfs_stopped_by_watchpoint)
	(procfs_stopped_data_address, procfs_insert_watchpoint)
	(procfs_remove_watchpoint, procfs_region_ok_for_hw_watchpoint)
	(proc_find_memory_regions, procfs_info_proc)
	(procfs_make_note_section): Refactor as methods of procfs_target.
	(_initialize_procfs): Adjust.
	* sol-thread.c (sol_thread_target): New class.
	(sol_thread_ops): Now a sol_thread_target.
	(sol_thread_detach, sol_thread_resume, sol_thread_wait)
	(sol_thread_fetch_registers, sol_thread_store_registers)
	(sol_thread_xfer_partial, sol_thread_mourn_inferior)
	(sol_thread_alive, solaris_pid_to_str, sol_update_thread_list)
	(sol_get_ada_task_ptid): Refactor as methods of sol_thread_target.
	(init_sol_thread_ops): Delete.
	(_initialize_sol_thread): Adjust.  Remove references to
	init_sol_thread_ops and complete_target_initialization.

	* windows-nat.c (windows_nat_target): New class.
	(windows_fetch_inferior_registers)
	(windows_store_inferior_registers, windows_resume, windows_wait)
	(windows_attach, windows_detach, windows_pid_to_exec_file)
	(windows_files_info, windows_create_inferior)
	(windows_mourn_inferior, windows_interrupt, windows_kill_inferior)
	(windows_close, windows_pid_to_str, windows_xfer_partial)
	(windows_get_tib_address, windows_get_ada_task_ptid)
	(windows_thread_name, windows_thread_alive): Refactor as
	windows_nat_target methods.
	(do_initial_windows_stuff): Adjust.
	(windows_target): Delete function.
	(_initialize_windows_nat): Adjust.

	* darwin-nat.c (darwin_resume, darwin_wait_to, darwin_interrupt)
	(darwin_mourn_inferior, darwin_kill_inferior)
	(darwin_create_inferior, darwin_attach, darwin_detach)
	(darwin_pid_to_str, darwin_thread_alive, darwin_xfer_partial)
	(darwin_pid_to_exec_file, darwin_get_ada_task_ptid)
	(darwin_supports_multi_process): Refactor as darwin_nat_target
	methods.
	(darwin_resume_to, darwin_files_info): Delete.
	(_initialize_darwin_inferior): Rename to ...
	(_initialize_darwin_nat): ... this.  Adjust to C++ification.
	* darwin-nat.h: Include "inf-child.h".
	(darwin_nat_target): New class.
	(darwin_complete_target): Delete.
	* i386-darwin-nat.c (i386_darwin_nat_target): New class.
	(darwin_target): New.
	(i386_darwin_fetch_inferior_registers)
	(i386_darwin_store_inferior_registers): Refactor as methods of
	darwin_nat_target.
	(darwin_complete_target): Delete, with ...
	(_initialize_i386_darwin_nat): ... bits factored out here.

	* alpha-linux-nat.c (alpha_linux_nat_target): New class.
	(the_alpha_linux_nat_target): New.
	(alpha_linux_register_u_offset): Refactor as
	alpha_linux_nat_target method.
	(_initialize_alpha_linux_nat): Adjust.
	* linux-nat-trad.c (inf_ptrace_register_u_offset): Delete.
	(inf_ptrace_fetch_register, inf_ptrace_fetch_registers)
	(inf_ptrace_store_register, inf_ptrace_store_registers): Refact as
	methods of linux_nat_trad_target.
	(linux_trad_target): Delete.
	* linux-nat-trad.h (linux_trad_target): Delete function.
	(linux_nat_trad_target): New class.
	* mips-linux-nat.c (mips_linux_nat_target): New class.
	(super_fetch_registers, super_store_registers, super_close):
	Delete.
	(the_mips_linux_nat_target): New.
	(mips64_linux_regsets_fetch_registers)
	(mips64_linux_regsets_store_registers)
	(mips64_linux_fetch_registers, mips64_linux_store_registers)
	(mips_linux_register_u_offset, mips_linux_read_description)
	(mips_linux_can_use_hw_breakpoint)
	(mips_linux_stopped_by_watchpoint)
	(mips_linux_stopped_data_address)
	(mips_linux_region_ok_for_hw_watchpoint)
	(mips_linux_insert_watchpoint, mips_linux_remove_watchpoint)
	(mips_linux_close): Refactor as methods of mips_linux_nat.
	(_initialize_mips_linux_nat): Adjust to C++ification.

	* aix-thread.c (aix_thread_target): New class.
	(aix_thread_ops): Now an aix_thread_target.
	(aix_thread_detach, aix_thread_resume, aix_thread_wait)
	(aix_thread_fetch_registers, aix_thread_store_registers)
	(aix_thread_xfer_partial, aix_thread_mourn_inferior)
	(aix_thread_thread_alive, aix_thread_pid_to_str)
	(aix_thread_extra_thread_info, aix_thread_get_ada_task_ptid):
	Refactor as methods of aix_thread_target.
	(init_aix_thread_ops): Delete.
	(_initialize_aix_thread): Remove references to init_aix_thread_ops
	and complete_target_initialization.
	* rs6000-nat.c (rs6000_xfer_shared_libraries): Delete.
	(rs6000_nat_target): New class.
	(the_rs6000_nat_target): New.
	(rs6000_fetch_inferior_registers, rs6000_store_inferior_registers)
	(rs6000_xfer_partial, rs6000_wait, rs6000_create_inferior)
	(rs6000_xfer_shared_libraries): Refactor as rs6000_nat_target methods.
	(super_create_inferior): Delete.
	(_initialize_rs6000_nat): Adjust to C++ification.

	* arm-linux-nat.c (arm_linux_nat_target): New class.
	(the_arm_linux_nat_target): New.
	(arm_linux_fetch_inferior_registers)
	(arm_linux_store_inferior_registers, arm_linux_read_description)
	(arm_linux_can_use_hw_breakpoint, arm_linux_insert_hw_breakpoint)
	(arm_linux_remove_hw_breakpoint)
	(arm_linux_region_ok_for_hw_watchpoint)
	(arm_linux_insert_watchpoint, arm_linux_remove_watchpoint)
	(arm_linux_stopped_data_address, arm_linux_stopped_by_watchpoint)
	(arm_linux_watchpoint_addr_within_range): Refactor as methods of
	arm_linux_nat_target.
	(_initialize_arm_linux_nat): Adjust to C++ification.

	* aarch64-linux-nat.c (aarch64_linux_nat_target): New class.
	(the_aarch64_linux_nat_target): New.
	(aarch64_linux_fetch_inferior_registers)
	(aarch64_linux_store_inferior_registers)
	(aarch64_linux_child_post_startup_inferior)
	(aarch64_linux_read_description)
	(aarch64_linux_can_use_hw_breakpoint)
	(aarch64_linux_insert_hw_breakpoint)
	(aarch64_linux_remove_hw_breakpoint)
	(aarch64_linux_insert_watchpoint, aarch64_linux_remove_watchpoint)
	(aarch64_linux_region_ok_for_hw_watchpoint)
	(aarch64_linux_stopped_data_address)
	(aarch64_linux_stopped_by_watchpoint)
	(aarch64_linux_watchpoint_addr_within_range)
	(aarch64_linux_can_do_single_step): Refactor as methods of
	aarch64_linux_nat_target.
	(super_post_startup_inferior): Delete.
	(_initialize_aarch64_linux_nat): Adjust to C++ification.

	* hppa-linux-nat.c (hppa_linux_nat_target): New class.
	(the_hppa_linux_nat_target): New.
	(hppa_linux_fetch_inferior_registers)
	(hppa_linux_store_inferior_registers): Refactor as methods of
	hppa_linux_nat_target.
	(_initialize_hppa_linux_nat): Adjust to C++ification.

	* ia64-linux-nat.c (ia64_linux_nat_target): New class.
	(the_ia64_linux_nat_target): New.
	(ia64_linux_insert_watchpoint, ia64_linux_remove_watchpoint)
	(ia64_linux_stopped_data_address)
	(ia64_linux_stopped_by_watchpoint, ia64_linux_fetch_registers)
	(ia64_linux_store_registers, ia64_linux_xfer_partial): Refactor as
	ia64_linux_nat_target methods.
	(super_xfer_partial): Delete.
	(_initialize_ia64_linux_nat): Adjust to C++ification.

	* m32r-linux-nat.c (m32r_linux_nat_target): New class.
	(the_m32r_linux_nat_target): New.
	(m32r_linux_fetch_inferior_registers)
	(m32r_linux_store_inferior_registers): Refactor as
	m32r_linux_nat_target methods.
	(_initialize_m32r_linux_nat): Adjust to C++ification.

	* m68k-linux-nat.c (m68k_linux_nat_target): New class.
	(the_m68k_linux_nat_target): New.
	(m68k_linux_fetch_inferior_registers)
	(m68k_linux_store_inferior_registers): Refactor as
	m68k_linux_nat_target methods.
	(_initialize_m68k_linux_nat): Adjust to C++ification.

	* s390-linux-nat.c (s390_linux_nat_target): New class.
	(the_s390_linux_nat_target): New.
	(s390_linux_fetch_inferior_registers)
	(s390_linux_store_inferior_registers, s390_stopped_by_watchpoint)
	(s390_insert_watchpoint, s390_remove_watchpoint)
	(s390_can_use_hw_breakpoint, s390_insert_hw_breakpoint)
	(s390_remove_hw_breakpoint, s390_region_ok_for_hw_watchpoint)
	(s390_auxv_parse, s390_read_description): Refactor as methods of
	s390_linux_nat_target.
	(_initialize_s390_nat): Adjust to C++ification.

	* sparc-linux-nat.c (sparc_linux_nat_target): New class.
	(the_sparc_linux_nat_target): New.
	(_initialize_sparc_linux_nat): Adjust to C++ification.
	* sparc-nat.c (sparc_fetch_inferior_registers)
	(sparc_store_inferior_registers): Remove target_ops parameter.
	* sparc-nat.h (sparc_fetch_inferior_registers)
	(sparc_store_inferior_registers): Remove target_ops parameter.
	* sparc64-linux-nat.c (sparc64_linux_nat_target): New class.
	(the_sparc64_linux_nat_target): New.
	(_initialize_sparc64_linux_nat): Adjust to C++ification.

	* spu-linux-nat.c (spu_linux_nat_target): New class.
	(the_spu_linux_nat_target): New.
	(spu_child_post_startup_inferior, spu_child_post_attach)
	(spu_child_wait, spu_fetch_inferior_registers)
	(spu_store_inferior_registers, spu_xfer_partial)
	(spu_can_use_hw_breakpoint): Refactor as spu_linux_nat_target
	methods.
	(_initialize_spu_nat): Adjust to C++ification.

	* tilegx-linux-nat.c (tilegx_linux_nat_target): New class.
	(the_tilegx_linux_nat_target): New.
	(fetch_inferior_registers, store_inferior_registers):
	Refactor as methods.
	(_initialize_tile_linux_nat): Adjust to C++ification.

	* xtensa-linux-nat.c (xtensa_linux_nat_target): New class.
	(the_xtensa_linux_nat_target): New.
	(xtensa_linux_fetch_inferior_registers)
	(xtensa_linux_store_inferior_registers): Refactor as
	xtensa_linux_nat_target methods.
	(_initialize_xtensa_linux_nat): Adjust to C++ification.

	* fbsd-nat.c (USE_SIGTRAP_SIGINFO): Delete.
	(fbsd_pid_to_exec_file, fbsd_find_memory_regions)
	(fbsd_find_memory_regions, fbsd_info_proc, fbsd_xfer_partial)
	(fbsd_thread_alive, fbsd_pid_to_str, fbsd_thread_name)
	(fbsd_update_thread_list, fbsd_resume, fbsd_wait)
	(fbsd_stopped_by_sw_breakpoint)
	(fbsd_supports_stopped_by_sw_breakpoint, fbsd_follow_fork)
	(fbsd_insert_fork_catchpoint, fbsd_remove_fork_catchpoint)
	(fbsd_insert_vfork_catchpoint, fbsd_remove_vfork_catchpoint)
	(fbsd_post_startup_inferior, fbsd_post_attach)
	(fbsd_insert_exec_catchpoint, fbsd_remove_exec_catchpoint)
	(fbsd_set_syscall_catchpoint)
	(super_xfer_partial, super_resume, super_wait)
	(fbsd_supports_stopped_by_hw_breakpoint): Delete.
	(fbsd_handle_debug_trap): Remove target_ops parameter.
	(fbsd_nat_add_target): Delete.
	* fbsd-nat.h: Include "inf-ptrace.h".
	(fbsd_nat_add_target): Delete.
	(USE_SIGTRAP_SIGINFO): Define.
	(fbsd_nat_target): New class.

	* amd64-bsd-nat.c (amd64bsd_fetch_inferior_registers)
	(amd64bsd_store_inferior_registers): Remove target_ops parameter.
	(amd64bsd_target): Delete.
	* amd64-bsd-nat.h: New file.
	* amd64-fbsd-nat.c: Include "amd64-bsd-nat.h" instead of
	"x86-bsd-nat.h".
	(amd64_fbsd_nat_target): New class.
	(the_amd64_fbsd_nat_target): New.
	(amd64fbsd_read_description): Refactor as method of
	amd64_fbsd_nat_target.
	(amd64_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New.
	(_initialize_amd64fbsd_nat): Adjust to C++ification.
	* amd64-nat.h (amd64bsd_target): Delete function declaration.
	* i386-bsd-nat.c (i386bsd_fetch_inferior_registers)
	(i386bsd_store_inferior_registers): Remove target_ops parameter.
	(i386bsd_target): Delete.
	* i386-bsd-nat.h (i386bsd_target): Delete function declaration.
	(i386bsd_fetch_inferior_registers)
	(i386bsd_store_inferior_registers): Declare.
	(i386_bsd_nat_target): New class.
	* i386-fbsd-nat.c (i386_fbsd_nat_target): New class.
	(the_i386_fbsd_nat_target): New.
	(i386fbsd_resume, i386fbsd_read_description): Refactor as
	i386_fbsd_nat_target methods.
	(i386_fbsd_nat_target::supports_stopped_by_hw_breakpoint): New.
	(_initialize_i386fbsd_nat): Adjust to C++ification.
	* x86-bsd-nat.c (super_mourn_inferior): Delete.
	(x86bsd_mourn_inferior, x86bsd_target): Delete.
	(_initialize_x86_bsd_nat): Adjust to C++ification.
	* x86-bsd-nat.h: Include "x86-nat.h".
	(x86bsd_target): Delete declaration.
	(x86bsd_nat_target): New class.

	* aarch64-fbsd-nat.c (aarch64_fbsd_nat_target): New class.
	(the_aarch64_fbsd_nat_target): New.
	(aarch64_fbsd_fetch_inferior_registers)
	(aarch64_fbsd_store_inferior_registers): Refactor as methods of
	aarch64_fbsd_nat_target.
	(_initialize_aarch64_fbsd_nat): Adjust to C++ification.
	* alpha-bsd-nat.c (alpha_bsd_nat_target): New class.
	(the_alpha_bsd_nat_target): New.
	(alphabsd_fetch_inferior_registers)
	(alphabsd_store_inferior_registers): Refactor as
	alpha_bsd_nat_target methods.
	(_initialize_alphabsd_nat): Refactor as methods of
	alpha_bsd_nat_target.
	* amd64-nbsd-nat.c: Include "amd64-bsd-nat.h".
	(the_amd64_nbsd_nat_target): New.
	(_initialize_amd64nbsd_nat): Adjust to C++ification.
	* amd64-obsd-nat.c: Include "amd64-bsd-nat.h".
	(the_amd64_obsd_nat_target): New.
	(_initialize_amd64obsd_nat): Adjust to C++ification.
	* arm-fbsd-nat.c (arm_fbsd_nat_target): New.
	(the_arm_fbsd_nat_target): New.
	(arm_fbsd_fetch_inferior_registers)
	(arm_fbsd_store_inferior_registers, arm_fbsd_read_description):
	(_initialize_arm_fbsd_nat): Refactor as methods of
	arm_fbsd_nat_target.
	(_initialize_arm_fbsd_nat): Adjust to C++ification.
	* arm-nbsd-nat.c (arm_netbsd_nat_target): New class.
	(the_arm_netbsd_nat_target): New.
	(armnbsd_fetch_registers, armnbsd_store_registers): Refactor as
	arm_netbsd_nat_target.
	(_initialize_arm_netbsd_nat): Adjust to C++ification.
	* hppa-nbsd-nat.c (hppa_nbsd_nat_target): New class.
	(the_hppa_nbsd_nat_target): New.
	(hppanbsd_fetch_registers, hppanbsd_store_registers): Refactor as
	hppa_nbsd_nat_target methods.
	(_initialize_hppanbsd_nat): Adjust to C++ification.
	* hppa-obsd-nat.c (hppa_obsd_nat_target): New class.
	(the_hppa_obsd_nat_target): New.
	(hppaobsd_fetch_registers, hppaobsd_store_registers): Refactor as
	methods of hppa_obsd_nat_target.
	(_initialize_hppaobsd_nat): Adjust to C++ification.  Use
	add_target.
	* i386-nbsd-nat.c (the_i386_nbsd_nat_target): New.
	(_initialize_i386nbsd_nat): Adjust to C++ification.  Use
	add_target.
	* i386-obsd-nat.c (the_i386_obsd_nat_target): New.
	(_initialize_i386obsd_nat): Use add_target.
	* m68k-bsd-nat.c (m68k_bsd_nat_target): New class.
	(the_m68k_bsd_nat_target): New.
	(m68kbsd_fetch_inferior_registers)
	(m68kbsd_store_inferior_registers): Refactor as methods of
	m68k_bsd_nat_target.
	(_initialize_m68kbsd_nat): Adjust to C++ification.
	* mips-fbsd-nat.c (mips_fbsd_nat_target): New class.
	(the_mips_fbsd_nat_target): New.
	(mips_fbsd_fetch_inferior_registers)
	(mips_fbsd_store_inferior_registers): Refactor as methods of
	mips_fbsd_nat_target.
	(_initialize_mips_fbsd_nat): Adjust to C++ification.  Use
	add_target.
	* mips-nbsd-nat.c (mips_nbsd_nat_target): New class.
	(the_mips_nbsd_nat_target): New.
	(mipsnbsd_fetch_inferior_registers)
	(mipsnbsd_store_inferior_registers): Refactor as methods of
	mips_nbsd_nat_target.
	(_initialize_mipsnbsd_nat): Adjust to C++ification.
	* mips64-obsd-nat.c (mips64_obsd_nat_target): New class.
	(the_mips64_obsd_nat_target): New.
	(mips64obsd_fetch_inferior_registers)
	(mips64obsd_store_inferior_registers): Refactor as methods of
	mips64_obsd_nat_target.
	(_initialize_mips64obsd_nat): Adjust to C++ification.  Use
	add_target.
	* nbsd-nat.c (nbsd_pid_to_exec_file): Refactor as method of
	nbsd_nat_target.
	* nbsd-nat.h: Include "inf-ptrace.h".
	(nbsd_nat_target): New class.
	* obsd-nat.c (obsd_pid_to_str, obsd_update_thread_list)
	(obsd_wait): Refactor as methods of obsd_nat_target.
	(obsd_add_target): Delete.
	* obsd-nat.h: Include "inf-ptrace.h".
	(obsd_nat_target): New class.
	* ppc-fbsd-nat.c (ppc_fbsd_nat_target): New class.
	(the_ppc_fbsd_nat_target): New.
	(ppcfbsd_fetch_inferior_registers)
	(ppcfbsd_store_inferior_registers): Refactor as methods of
	ppc_fbsd_nat_target.
	(_initialize_ppcfbsd_nat): Adjust to C++ification.  Use
	add_target.
	* ppc-nbsd-nat.c (ppc_nbsd_nat_target): New class.
	(the_ppc_nbsd_nat_target): New.
	(ppcnbsd_fetch_inferior_registers)
	(ppcnbsd_store_inferior_registers): Refactor as methods of
	ppc_nbsd_nat_target.
	(_initialize_ppcnbsd_nat): Adjust to C++ification.
	* ppc-obsd-nat.c (ppc_obsd_nat_target): New class.
	(the_ppc_obsd_nat_target): New.
	(ppcobsd_fetch_registers, ppcobsd_store_registers): Refactor as
	methods of ppc_obsd_nat_target.
	(_initialize_ppcobsd_nat): Adjust to C++ification.  Use
	add_target.
	* sh-nbsd-nat.c (sh_nbsd_nat_target): New class.
	(the_sh_nbsd_nat_target): New.
	(shnbsd_fetch_inferior_registers)
	(shnbsd_store_inferior_registers): Refactor as methods of
	sh_nbsd_nat_target.
	(_initialize_shnbsd_nat): Adjust to C++ification.
	* sparc-nat.c (sparc_xfer_wcookie): Make extern.
	(inf_ptrace_xfer_partial): Delete.
	(sparc_xfer_partial, sparc_target): Delete.
	* sparc-nat.h (sparc_fetch_inferior_registers)
	(sparc_store_inferior_registers, sparc_xfer_wcookie): Declare.
	(sparc_target): Delete function declaration.
	(sparc_target): New template class.
	* sparc-nbsd-nat.c (the_sparc_nbsd_nat_target): New.
	(_initialize_sparcnbsd_nat): Adjust to C++ification.
	* sparc64-fbsd-nat.c (the_sparc64_fbsd_nat_target): New.
	(_initialize_sparc64fbsd_nat): Adjust to C++ification.  Use
	add_target.
	* sparc64-nbsd-nat.c (the_sparc64_nbsd_nat_target): New.
	(_initialize_sparc64nbsd_nat): Adjust to C++ification.
	* sparc64-obsd-nat.c (the_sparc64_obsd_nat_target): New.
	(_initialize_sparc64obsd_nat): Adjust to C++ification.  Use
	add_target.
	* vax-bsd-nat.c (vax_bsd_nat_target): New class.
	(the_vax_bsd_nat_target): New.
	(vaxbsd_fetch_inferior_registers)
	(vaxbsd_store_inferior_registers): Refactor as vax_bsd_nat_target
	methods.
	(_initialize_vaxbsd_nat): Adjust to C++ification.

	* bsd-kvm.c (bsd_kvm_target): New class.
	(bsd_kvm_ops): Now a bsd_kvm_target.
	(bsd_kvm_open, bsd_kvm_close, bsd_kvm_xfer_partial)
	(bsd_kvm_files_info, bsd_kvm_fetch_registers)
	(bsd_kvm_thread_alive, bsd_kvm_pid_to_str): Refactor as methods of
	bsd_kvm_target.
	(bsd_kvm_return_one): Delete.
	(bsd_kvm_add_target): Adjust to C++ification.

	* nto-procfs.c (nto_procfs_target, nto_procfs_target_native)
	(nto_procfs_target_procfs): New classes.
	(procfs_open_1, procfs_thread_alive, procfs_update_thread_list)
	(procfs_files_info, procfs_pid_to_exec_file, procfs_attach)
	(procfs_post_attach, procfs_wait, procfs_fetch_registers)
	(procfs_xfer_partial, procfs_detach, procfs_insert_breakpoint)
	(procfs_remove_breakpoint, procfs_insert_hw_breakpoint)
	(procfs_remove_hw_breakpoint, procfs_resume)
	(procfs_mourn_inferior, procfs_create_inferior, procfs_interrupt)
	(procfs_kill_inferior, procfs_store_registers)
	(procfs_pass_signals, procfs_pid_to_str, procfs_can_run): Refactor
	as methods of nto_procfs_target.
	(nto_procfs_ops): Now an nto_procfs_target_procfs.
	(nto_native_ops): Delete.
	(procfs_open, procfs_native_open): Delete.
	(nto_native_ops): Now an nto_procfs_target_native.
	(init_procfs_targets): Adjust to C++ification.
	(procfs_can_use_hw_breakpoint, procfs_remove_hw_watchpoint)
	(procfs_insert_hw_watchpoint, procfs_stopped_by_watchpoint):
	Refactor as methods of nto_procfs_target.

	* go32-nat.c (go32_nat_target): New class.
	(the_go32_nat_target): New.
	(go32_attach, go32_resume, go32_wait, go32_fetch_registers)
	(go32_store_registers, go32_xfer_partial, go32_files_info)
	(go32_kill_inferior, go32_create_inferior, go32_mourn_inferior)
	(go32_terminal_init, go32_terminal_info, go32_terminal_inferior)
	(go32_terminal_ours, go32_pass_ctrlc, go32_thread_alive)
	(go32_pid_to_str): Refactor as methods of go32_nat_target.
	(go32_target): Delete.
	(_initialize_go32_nat): Adjust to C++ification.

	* gnu-nat.c (gnu_wait, gnu_resume, gnu_kill_inferior)
	(gnu_mourn_inferior, gnu_create_inferior, gnu_attach, gnu_detach)
	(gnu_stop, gnu_thread_alive, gnu_xfer_partial)
	(gnu_find_memory_regions, gnu_pid_to_str): Refactor as methods of
	gnu_nat_target.
	(gnu_target): Delete.
	* gnu-nat.h (gnu_target): Delete.
	(gnu_nat_target): New class.
	* i386-gnu-nat.c (gnu_base_target): New.
	(i386_gnu_nat_target): New class.
	(the_i386_gnu_nat_target): New.
	(_initialize_i386gnu_nat): Adjust to C++ification.

gdb/testsuite/ChangeLog:
2018-05-02  Pedro Alves  <palves@redhat.com>

	* gdb.base/breakpoint-in-ro-region.exp: Adjust to to_resume and
	to_log_command renames.
	* gdb.base/sss-bp-on-user-bp-2.exp: Likewise.
---
 gdb/ChangeLog                                      | 1008 ++++
 gdb/testsuite/ChangeLog                            |    6 +
 gdb/aarch64-fbsd-nat.c                             |   27 +-
 gdb/aarch64-linux-nat.c                            |  177 +-
 gdb/aix-thread.c                                   |  161 +-
 gdb/alpha-bsd-nat.c                                |   25 +-
 gdb/alpha-linux-nat.c                              |   18 +-
 gdb/amd64-bsd-nat.c                                |   24 +-
 gdb/amd64-bsd-nat.h                                |   44 +
 gdb/amd64-fbsd-nat.c                               |   39 +-
 gdb/amd64-linux-nat.c                              |   33 +-
 gdb/amd64-nat.h                                    |    5 -
 gdb/amd64-nbsd-nat.c                               |   10 +-
 gdb/amd64-obsd-nat.c                               |    6 +-
 gdb/arm-fbsd-nat.c                                 |   35 +-
 gdb/arm-linux-nat.c                                |  138 +-
 gdb/arm-nbsd-nat.c                                 |   27 +-
 gdb/auxv.c                                         |   13 +-
 gdb/auxv.h                                         |    3 +-
 gdb/avr-tdep.c                                     |    4 +-
 gdb/bfd-target.c                                   |  104 +-
 gdb/breakpoint.c                                   |    7 +-
 gdb/bsd-kvm.c                                      |  103 +-
 gdb/bsd-uthread.c                                  |  137 +-
 gdb/corefile.c                                     |   12 +-
 gdb/corelow.c                                      |  202 +-
 gdb/ctf.c                                          |  103 +-
 gdb/darwin-nat.c                                   |  142 +-
 gdb/darwin-nat.h                                   |   46 +-
 gdb/elfread.c                                      |   10 +-
 gdb/eval.c                                         |    2 +-
 gdb/exceptions.c                                   |    6 +-
 gdb/exec.c                                         |  139 +-
 gdb/fbsd-nat.c                                     |  234 +-
 gdb/fbsd-nat.h                                     |   79 +-
 gdb/frame.c                                        |    2 +-
 gdb/gdbarch-selftests.c                            |    4 +-
 gdb/gdbcore.h                                      |    6 +-
 gdb/gnu-nat.c                                      |  101 +-
 gdb/gnu-nat.h                                      |   34 +-
 gdb/gnu-v3-abi.c                                   |    2 +-
 gdb/go32-nat.c                                     |  181 +-
 gdb/hppa-linux-nat.c                               |   33 +-
 gdb/hppa-nbsd-nat.c                                |   30 +-
 gdb/hppa-obsd-nat.c                                |   25 +-
 gdb/i386-bsd-nat.c                                 |   24 +-
 gdb/i386-bsd-nat.h                                 |   22 +-
 gdb/i386-darwin-nat.c                              |   28 +-
 gdb/i386-fbsd-nat.c                                |   51 +-
 gdb/i386-gnu-nat.c                                 |   29 +-
 gdb/i386-linux-nat.c                               |   42 +-
 gdb/i386-nbsd-nat.c                                |    9 +-
 gdb/i386-obsd-nat.c                                |    5 +-
 gdb/ia64-linux-nat.c                               |  134 +-
 gdb/ia64-tdep.c                                    |    2 +-
 gdb/ia64-vms-tdep.c                                |    2 +-
 gdb/inf-child.c                                    |  295 +-
 gdb/inf-child.h                                    |  113 +-
 gdb/inf-ptrace.c                                   |  142 +-
 gdb/inf-ptrace.h                                   |   67 +-
 gdb/infcall.c                                      |    4 +-
 gdb/infcmd.c                                       |   36 +-
 gdb/infrun.c                                       |   12 +-
 gdb/linespec.c                                     |    2 +-
 gdb/linux-nat-trad.c                               |   54 +-
 gdb/linux-nat-trad.h                               |   24 +-
 gdb/linux-nat.c                                    |  480 +-
 gdb/linux-nat.h                                    |  141 +-
 gdb/linux-tdep.c                                   |   18 +-
 gdb/linux-thread-db.c                              |  155 +-
 gdb/m32r-linux-nat.c                               |   30 +-
 gdb/m68k-bsd-nat.c                                 |   25 +-
 gdb/m68k-linux-nat.c                               |   33 +-
 gdb/make-target-delegates                          |  205 +-
 gdb/mi/mi-main.c                                   |   13 +-
 gdb/minsyms.c                                      |    2 +-
 gdb/mips-fbsd-nat.c                                |   25 +-
 gdb/mips-linux-nat.c                               |  176 +-
 gdb/mips-nbsd-nat.c                                |   25 +-
 gdb/mips64-obsd-nat.c                              |   23 +-
 gdb/nbsd-nat.c                                     |    2 +-
 gdb/nbsd-nat.h                                     |   10 +-
 gdb/nto-procfs.c                                   |  332 +-
 gdb/obsd-nat.c                                     |   32 +-
 gdb/obsd-nat.h                                     |   10 +-
 gdb/ppc-fbsd-nat.c                                 |   26 +-
 gdb/ppc-linux-nat.c                                |  195 +-
 gdb/ppc-linux-tdep.c                               |   10 +-
 gdb/ppc-nbsd-nat.c                                 |   26 +-
 gdb/ppc-obsd-nat.c                                 |   26 +-
 gdb/procfs.c                                       |  306 +-
 gdb/ravenscar-thread.c                             |  230 +-
 gdb/record-btrace.c                                |  557 +--
 gdb/record-full.c                                  |  596 +--
 gdb/record.c                                       |   18 +-
 gdb/regcache.c                                     |   64 +-
 gdb/remote-sim.c                                   |  220 +-
 gdb/remote.c                                       | 1331 +++---
 gdb/rs6000-nat.c                                   |   95 +-
 gdb/rs6000-tdep.c                                  |    2 +-
 gdb/s390-linux-nat.c                               |  124 +-
 gdb/s390-tdep.c                                    |    2 +-
 gdb/sh-nbsd-nat.c                                  |   24 +-
 gdb/sol-thread.c                                   |  165 +-
 gdb/solib-aix.c                                    |    2 +-
 gdb/solib-darwin.c                                 |    2 +-
 gdb/solib-dsbt.c                                   |    4 +-
 gdb/solib-spu.c                                    |    6 +-
 gdb/solib-svr4.c                                   |   18 +-
 gdb/solib-target.c                                 |    2 +-
 gdb/sparc-linux-nat.c                              |   25 +-
 gdb/sparc-nat.c                                    |   39 +-
 gdb/sparc-nat.h                                    |   41 +-
 gdb/sparc-nbsd-nat.c                               |    5 +-
 gdb/sparc-tdep.c                                   |    2 +-
 gdb/sparc64-fbsd-nat.c                             |    7 +-
 gdb/sparc64-linux-nat.c                            |   25 +-
 gdb/sparc64-nbsd-nat.c                             |    6 +-
 gdb/sparc64-obsd-nat.c                             |    5 +-
 gdb/sparc64-tdep.c                                 |    4 +-
 gdb/spu-linux-nat.c                                |   78 +-
 gdb/spu-multiarch.c                                |  163 +-
 gdb/spu-tdep.c                                     |   30 +-
 gdb/symfile.c                                      |    2 +-
 gdb/symtab.c                                       |    2 +-
 gdb/target-debug.h                                 |    6 +
 gdb/target-delegates.c                             | 5036 +++++++++-----------
 gdb/target-descriptions.c                          |    4 +-
 gdb/target-memory.c                                |    4 +-
 gdb/target.c                                       |  846 ++--
 gdb/target.h                                       |  830 ++--
 gdb/testsuite/gdb.base/breakpoint-in-ro-region.exp |    4 +-
 gdb/testsuite/gdb.base/sss-bp-on-user-bp-2.exp     |    4 +-
 gdb/tilegx-linux-nat.c                             |   35 +-
 gdb/tracefile-tfile.c                              |  120 +-
 gdb/tracefile.c                                    |   38 +-
 gdb/tracefile.h                                    |   16 +-
 gdb/tracepoint.c                                   |    2 +-
 gdb/valops.c                                       |    4 +-
 gdb/valprint.c                                     |    2 +-
 gdb/value.c                                        |    2 +-
 gdb/vax-bsd-nat.c                                  |   25 +-
 gdb/windows-nat.c                                  |  216 +-
 gdb/windows-tdep.c                                 |    2 +-
 gdb/x86-bsd-nat.c                                  |   27 +-
 gdb/x86-bsd-nat.h                                  |   21 +-
 gdb/x86-linux-nat.c                                |   80 +-
 gdb/x86-linux-nat.h                                |   44 +-
 gdb/x86-nat.c                                      |   64 +-
 gdb/x86-nat.h                                      |   79 +-
 gdb/xtensa-linux-nat.c                             |   33 +-
 151 files changed, 9667 insertions(+), 8743 deletions(-)
 create mode 100644 gdb/amd64-bsd-nat.h

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 28/40] target_ops/C++: SPU/Linux
  2018-04-14 19:28 ` [PATCH 28/40] target_ops/C++: SPU/Linux Pedro Alves
@ 2018-05-04 17:09   ` Ulrich Weigand
  2018-05-04 17:15     ` Pedro Alves
  0 siblings, 1 reply; 65+ messages in thread
From: Ulrich Weigand @ 2018-05-04 17:09 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

Hi Pedro,

> +ptid_t
> +spu_linux_nat_target:::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
> +			     int options)

This syntax error (:::) causes a build break on SPU.

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU/Linux compilers and toolchain
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 28/40] target_ops/C++: SPU/Linux
  2018-05-04 17:09   ` Ulrich Weigand
@ 2018-05-04 17:15     ` Pedro Alves
  2018-05-04 17:22       ` Ulrich Weigand
  0 siblings, 1 reply; 65+ messages in thread
From: Pedro Alves @ 2018-05-04 17:15 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gdb-patches

On 05/04/2018 06:08 PM, Ulrich Weigand wrote:
> Hi Pedro,
> 
>> +ptid_t
>> +spu_linux_nat_target:::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
>> +			     int options)
> 
> This syntax error (:::) causes a build break on SPU.
Sorry about that.  Are you able to push in the obvious fix,
or would you rather me do it?

Thanks,
Pedro Alves

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 28/40] target_ops/C++: SPU/Linux
  2018-05-04 17:15     ` Pedro Alves
@ 2018-05-04 17:22       ` Ulrich Weigand
  2018-05-04 17:27         ` Pedro Alves
  0 siblings, 1 reply; 65+ messages in thread
From: Ulrich Weigand @ 2018-05-04 17:22 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

Pedro Alves wrote:
> On 05/04/2018 06:08 PM, Ulrich Weigand wrote:
> > Hi Pedro,
> > 
> >> +ptid_t
> >> +spu_linux_nat_target:::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
> >> +			     int options)
> > 
> > This syntax error (:::) causes a build break on SPU.
> Sorry about that.  Are you able to push in the obvious fix,
> or would you rather me do it?

No problem :-)   I've checked the fix in now.

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU/Linux compilers and toolchain
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [PATCH 28/40] target_ops/C++: SPU/Linux
  2018-05-04 17:22       ` Ulrich Weigand
@ 2018-05-04 17:27         ` Pedro Alves
  0 siblings, 0 replies; 65+ messages in thread
From: Pedro Alves @ 2018-05-04 17:27 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gdb-patches

On 05/04/2018 06:22 PM, Ulrich Weigand wrote:
> Pedro Alves wrote:
>> On 05/04/2018 06:08 PM, Ulrich Weigand wrote:
>>> Hi Pedro,
>>>
>>>> +ptid_t
>>>> +spu_linux_nat_target:::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
>>>> +			     int options)
>>>
>>> This syntax error (:::) causes a build break on SPU.
>> Sorry about that.  Are you able to push in the obvious fix,
>> or would you rather me do it?
> 
> No problem :-)   I've checked the fix in now.
Thanks you.  :-)

Pedro Alves

^ permalink raw reply	[flat|nested] 65+ messages in thread

* 8.2 regression for invalid -data-directory  [Re: [RESEND][PATCH 01/40] Convert struct target_ops to C++]
  2018-05-03  0:06   ` Pedro Alves
@ 2018-10-27 21:58     ` Jan Kratochvil
  2018-10-30 20:24       ` Tom Tromey
  2019-02-14 15:30     ` [RESEND][PATCH 01/40] Convert struct target_ops to C++ Thomas Schwinge
  1 sibling, 1 reply; 65+ messages in thread
From: Jan Kratochvil @ 2018-10-27 21:58 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

f6ac5f3d63e03a81c4ff3749aba234961cc9090e is the first bad commit
commit f6ac5f3d63e03a81c4ff3749aba234961cc9090e
Author: Pedro Alves <palves@redhat.com>
Date:   Thu May 3 00:37:22 2018 +0100
    Convert struct target_ops to C++
    
$ ./gdb -data-directory gdb
Segmentation fault

Program received signal SIGSEGV, Segmentation fault.
target_supports_terminal_ours () at target.c:590
590	  return current_top_target ()->supports_terminal_ours ();
(gdb) bt
#0  target_supports_terminal_ours () at target.c:590
#1  0x0000000000c0c0d0 in vwarning (string=0x14bc4ca "%s is not a directory.", args=0x7fffffffc8e0) at utils.c:173
#2  0x00000000005af49d in warning (fmt=0x14bc4ca "%s is not a directory.") at common/errors.c:31
#3  0x0000000000873848 in set_gdb_data_directory (new_datadir=0x7fffffffd1f4 "gdb") at main.c:121
#4  0x000000000087465a in captured_main_1 (context=0x7fffffffcce0) at main.c:763
#5  0x00000000008753e1 in captured_main (data=0x7fffffffcce0) at main.c:1163
#6  0x00000000008754bd in gdb_main (args=0x7fffffffcce0) at main.c:1189
#7  0x00000000004129dc in main (argc=3, argv=0x7fffffffcde8) at gdb.c:32
(gdb) _

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: 8.2 regression for invalid -data-directory  [Re: [RESEND][PATCH 01/40] Convert struct target_ops to C++]
  2018-10-27 21:58     ` 8.2 regression for invalid -data-directory [Re: [RESEND][PATCH 01/40] Convert struct target_ops to C++] Jan Kratochvil
@ 2018-10-30 20:24       ` Tom Tromey
  0 siblings, 0 replies; 65+ messages in thread
From: Tom Tromey @ 2018-10-30 20:24 UTC (permalink / raw)
  To: Jan Kratochvil; +Cc: Pedro Alves, gdb-patches

>>>>> "Jan" == Jan Kratochvil <jan.kratochvil@redhat.com> writes:

Jan> f6ac5f3d63e03a81c4ff3749aba234961cc9090e is the first bad commit
Jan> commit f6ac5f3d63e03a81c4ff3749aba234961cc9090e
Jan> Author: Pedro Alves <palves@redhat.com>
Jan> Date:   Thu May 3 00:37:22 2018 +0100
Jan>     Convert struct target_ops to C++
    
Jan> $ ./gdb -data-directory gdb
Jan> Segmentation fault

I sent a patch for this a while back, but still need to write a test
case.

Tom

^ permalink raw reply	[flat|nested] 65+ messages in thread

* Re: [RESEND][PATCH 01/40] Convert struct target_ops to C++
  2018-05-03  0:06   ` Pedro Alves
  2018-10-27 21:58     ` 8.2 regression for invalid -data-directory [Re: [RESEND][PATCH 01/40] Convert struct target_ops to C++] Jan Kratochvil
@ 2019-02-14 15:30     ` Thomas Schwinge
  1 sibling, 0 replies; 65+ messages in thread
From: Thomas Schwinge @ 2019-02-14 15:30 UTC (permalink / raw)
  To: gdb-patches; +Cc: Pedro Alves

[-- Attachment #1: Type: text/plain, Size: 477 bytes --]

Hi!

On Thu, 3 May 2018 01:05:55 +0100, Pedro Alves <palves@redhat.com> wrote:
> >From f6ac5f3d63e03a81c4ff3749aba234961cc9090e Mon Sep 17 00:00:00 2001
> From: Pedro Alves <palves@redhat.com>
> Date: Thu, 3 May 2018 00:37:22 +0100
> Subject: [PATCH] Convert struct target_ops to C++

Pushed to master the attached commit
2d0a338c7c321de6c63be4e7e3f06ba12b783c63 '[gdb, hurd] Repair build after
"Convert struct target_ops to C++" changes'.


Grüße
 Thomas



[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-gdb-hurd-Repair-build-after-Convert-struct-target_op.patch --]
[-- Type: text/x-diff, Size: 5515 bytes --]

From 2d0a338c7c321de6c63be4e7e3f06ba12b783c63 Mon Sep 17 00:00:00 2001
From: Thomas Schwinge <thomas@codesourcery.com>
Date: Fri, 20 Jul 2018 02:03:25 +0200
Subject: [PATCH] [gdb, hurd] Repair build after "Convert struct target_ops to
 C++" changes

..., that is commit f6ac5f3d63e03a81c4ff3749aba234961cc9090e causing:

    In file included from [...]/gdb/gnu-nat.c:24:0:
    [...]/gdb/gnu-nat.h:123:1: error: expected class-name before '{' token
     {
     ^
    [...]/gdb/gnu-nat.h:128:16: error: 'inferior' has not been declared
       void detach (inferior *, int) override;
                    ^~~~~~~~
    [...]/gdb/gnu-nat.h:132:8: error: use of enum 'target_xfer_status' without previous declaration
       enum target_xfer_status xfer_partial (enum target_object object,
            ^~~~~~~~~~~~~~~~~~
    [...]/gdb/gnu-nat.h:132:46: error: use of enum 'target_object' without previous declaration
       enum target_xfer_status xfer_partial (enum target_object object,
                                                  ^~~~~~~~~~~~~
    [...]/gdb/gnu-nat.h:124:8: error: 'void gnu_nat_target::attach(const char*, int)' marked 'override', but does not override
       void attach (const char *, int) override;
            ^~~~~~
    [...]

    [...]/gdb/gnu-nat.c: In member function 'virtual void gnu_nat_target::detach(inferior*, int)':
    [...]/gdb/gnu-nat.c:2286:34: error: 'ops' was not declared in this scope
       inf_child_maybe_unpush_target (ops);
                                      ^~~
    [...]/gdb/gnu-nat.c:2286:34: note: suggested alternative: 'open'
       inf_child_maybe_unpush_target (ops);
                                      ^~~
                                      open
    [...]/gdb/gnu-nat.c:2286:3: error: 'inf_child_maybe_unpush_target' was not declared in this scope
       inf_child_maybe_unpush_target (ops);
       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    [...]/gdb/gnu-nat.c:2286:3: note: suggested alternative: 'maybe_unpush_target'
       inf_child_maybe_unpush_target (ops);
       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       maybe_unpush_target

    [...]/gdb/i386-gnu-nat.c:200:1: warning: 'void gnu_store_registers(target_ops*, regcache*, int)' defined but not used [-Wunused-function]
     gnu_store_registers (struct target_ops *ops,
     ^~~~~~~~~~~~~~~~~~~
    [...]/gdb/i386-gnu-nat.c:109:1: warning: 'void gnu_fetch_registers(target_ops*, regcache*, int)' defined but not used [-Wunused-function]
     gnu_fetch_registers (struct target_ops *ops,
     ^~~~~~~~~~~~~~~~~~~
    [...]
    /usr/bin/ld: i386-gnu-nat.o:(.data.rel+0x0): undefined reference to `vtable for i386_gnu_nat_target'
    collect2: error: ld returned 1 exit status

	gdb/
	* gnu-nat.c (gnu_nat_target::detach): Instead of
	'inf_child_maybe_unpush_target (ops)' call 'maybe_unpush_target'.
	* gnu-nat.h: #include "inf-child.h".
	* i386-gnu-nat.c (gnu_fetch_registers): Rename/move to
	'i386_gnu_nat_target::fetch_registers'.
	(gnu_store_registers): Rename/move to
	'i386_gnu_nat_target::store_registers'.
---
 gdb/ChangeLog      |  8 ++++++++
 gdb/gnu-nat.c      |  2 +-
 gdb/gnu-nat.h      |  2 ++
 gdb/i386-gnu-nat.c | 10 ++++------
 4 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index c88216b94b..fcaae6125e 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,13 @@
 2019-02-14  Thomas Schwinge  <thomas@codesourcery.com>
 
+	* gnu-nat.c (gnu_nat_target::detach): Instead of
+	'inf_child_maybe_unpush_target (ops)' call 'maybe_unpush_target'.
+	* gnu-nat.h: #include "inf-child.h".
+	* i386-gnu-nat.c (gnu_fetch_registers): Rename/move to
+	'i386_gnu_nat_target::fetch_registers'.
+	(gnu_store_registers): Rename/move to
+	'i386_gnu_nat_target::store_registers'.
+
 	* config/i386/nm-i386gnu.h: Don't "#include" any files.
 	* gnu-nat.h (mach_thread_info): New function.
 	* gnu-nat.c (thread_takeover_sc_cmd): Use it.
diff --git a/gdb/gnu-nat.c b/gdb/gnu-nat.c
index bd8fcb6e59..78966c805d 100644
--- a/gdb/gnu-nat.c
+++ b/gdb/gnu-nat.c
@@ -2280,7 +2280,7 @@ gnu_nat_target::detach (inferior *inf, int from_tty)
   inferior_ptid = null_ptid;
   detach_inferior (pid);
 
-  inf_child_maybe_unpush_target (ops);
+  maybe_unpush_target ();
 }
 \f
 
diff --git a/gdb/gnu-nat.h b/gdb/gnu-nat.h
index dbad0cac93..4bd4176ead 100644
--- a/gdb/gnu-nat.h
+++ b/gdb/gnu-nat.h
@@ -35,6 +35,8 @@ extern __typeof__ (mach_thread_info) mach_thread_info asm ("thread_info");
 
 #include <unistd.h>
 
+#include "inf-child.h"
+
 struct inf;
 
 extern struct inf *gnu_current_inf;
diff --git a/gdb/i386-gnu-nat.c b/gdb/i386-gnu-nat.c
index c23c4bc79c..75ae641f8e 100644
--- a/gdb/i386-gnu-nat.c
+++ b/gdb/i386-gnu-nat.c
@@ -105,9 +105,8 @@ fetch_fpregs (struct regcache *regcache, struct proc *thread)
 }
 
 /* Fetch register REGNO, or all regs if REGNO is -1.  */
-static void
-gnu_fetch_registers (struct target_ops *ops,
-		     struct regcache *regcache, int regno)
+void
+i386_gnu_nat_target::fetch_registers (struct regcache *regcache, int regno)
 {
   struct proc *thread;
   ptid_t ptid = regcache->ptid ();
@@ -196,9 +195,8 @@ store_fpregs (const struct regcache *regcache, struct proc *thread, int regno)
 }
 
 /* Store at least register REGNO, or all regs if REGNO == -1.  */
-static void
-gnu_store_registers (struct target_ops *ops,
-		     struct regcache *regcache, int regno)
+void
+i386_gnu_nat_target::store_registers (struct regcache *regcache, int regno)
 {
   struct proc *thread;
   struct gdbarch *gdbarch = regcache->arch ();
-- 
2.19.2


^ permalink raw reply	[flat|nested] 65+ messages in thread

end of thread, other threads:[~2019-02-14 15:30 UTC | newest]

Thread overview: 65+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-14 19:09 [PATCH 00/40] C++ify target_ops, toward multi-target Pedro Alves
2018-04-14 19:10 ` [PATCH 02/40] make-target-delegates: line break between return type and function name Pedro Alves
2018-04-14 19:10 ` [PATCH 17/40] target_ops/C++: macOS/Darwin target Pedro Alves
2018-04-14 19:10 ` [PATCH 03/40] target_ops/C++: exec target Pedro Alves
2018-04-14 19:10 ` [PATCH 07/40] target_ops/C++: ravenscar-thread Pedro Alves
2018-04-14 19:10 ` [PATCH 38/40] target_ops: Use bool throughout Pedro Alves
2018-04-14 19:10 ` [PATCH 32/40] target_ops/C++: Generic i386/AMD64 BSD targets Pedro Alves
2018-04-14 19:10 ` [PATCH 29/40] target_ops/C++: Tile-Gx GNU/Linux Pedro Alves
2018-04-14 19:10 ` [PATCH 08/40] target_ops/C++: bsd-uthread Pedro Alves
2018-04-14 19:10 ` [PATCH 19/40] target_ops/C++: AIX target Pedro Alves
2018-04-14 19:10 ` [PATCH 40/40] target factories, target open and multiple instances of targets Pedro Alves
2018-04-14 19:10 ` [PATCH 27/40] target_ops/C++: SPARC GNU/Linux Pedro Alves
2018-04-14 19:10 ` [PATCH 37/40] target_ops/C++: The Hurd Pedro Alves
2018-04-14 19:10 ` [PATCH 39/40] linux_nat_target: More low methods Pedro Alves
2018-04-18  0:40   ` John Baldwin
2018-04-14 19:10 ` [PATCH 20/40] target_ops/C++: ARM GNU/Linux Pedro Alves
2018-04-14 19:10 ` [PATCH 09/40] target_ops/C++: bfd-target Pedro Alves
2018-04-14 19:10 ` [PATCH 34/40] target_ops/C++: bsd_kvm_add_target, BSD libkvm target Pedro Alves
2018-04-14 19:10 ` [PATCH 23/40] target_ops/C++: IA-64 GNU/Linux Pedro Alves
2018-04-14 19:15 ` [PATCH 14/40] target_ops/C++: PPC/PPC64 GNU/Linux Pedro Alves
2018-04-14 19:15 ` [PATCH 12/40] target_ops/C++: target remote-sim Pedro Alves
2018-04-14 19:15 ` [PATCH 22/40] target_ops/C++: HP-PA GNU/Linux Pedro Alves
2018-04-14 19:18 ` [PATCH 04/40] target_ops/C++: core target Pedro Alves
2018-04-14 19:18 ` [PATCH 36/40] target_ops/C++: go32/DJGPP Pedro Alves
2018-04-14 19:18 ` [PATCH 25/40] target_ops/C++: m68k GNU/Linux Pedro Alves
2018-04-14 19:18 ` [PATCH 24/40] target_ops/C++: m32r GNU/Linux Pedro Alves
2018-04-14 19:19 ` [PATCH 05/40] target_ops/C++: ctf/tfile targets Pedro Alves
2018-04-14 19:19 ` [PATCH 31/40] target_ops/C++: Base FreeBSD target Pedro Alves
2018-04-17 16:12   ` John Baldwin
2018-04-17 17:07     ` Pedro Alves
2018-04-17 17:28       ` Kamil Rytarowski
2018-04-17 18:13         ` Pedro Alves
2018-04-17 18:50           ` Kamil Rytarowski
2018-04-18  0:40       ` John Baldwin
2018-04-18  1:51         ` Kamil Rytarowski
2018-04-18 11:23           ` Pedro Alves
2018-04-18 11:21         ` Pedro Alves
2018-04-18 14:20           ` Pedro Alves
2018-04-18 20:55             ` John Baldwin
2018-04-14 19:19 ` [PATCH 15/40] target_ops/C++: Solaris/procfs Pedro Alves
2018-04-14 19:19 ` [PATCH 30/40] target_ops/C++: Xtensa GNU/Linux Pedro Alves
2018-04-14 19:19 ` [PATCH 26/40] target_ops/C++: s390 GNU/Linux Pedro Alves
2018-04-14 19:19 ` [PATCH 35/40] target_ops/C++: NTO/QNX, nto-procfs.c Pedro Alves
2018-04-14 19:19 ` [PATCH 16/40] target_ops/C++: Windows targets Pedro Alves
2018-04-14 19:20 ` [PATCH 10/40] target_ops/C++: record targets Pedro Alves
2018-04-14 19:20 ` [PATCH 11/40] target_ops/C++: remote/extended-remote targets Pedro Alves
2018-04-14 19:20 ` [PATCH 33/40] target_ops/C++: The rest of the BSD targets Pedro Alves
2018-04-14 19:20 ` [PATCH 06/40] target_ops/C++: spu-multiarch Pedro Alves
2018-04-14 19:28 ` [PATCH 28/40] target_ops/C++: SPU/Linux Pedro Alves
2018-05-04 17:09   ` Ulrich Weigand
2018-05-04 17:15     ` Pedro Alves
2018-05-04 17:22       ` Ulrich Weigand
2018-05-04 17:27         ` Pedro Alves
2018-04-14 19:28 ` [PATCH 21/40] target_ops/C++: Aarch64 GNU/Linux Pedro Alves
2018-04-14 19:29 ` [PATCH 13/40] target_ops/C++: GNU/Linux + x86/AMD64 Pedro Alves
2018-04-14 19:30 ` [PATCH 18/40] target_ops/C++: linux_trad_target, MIPS and Alpha GNU/Linux Pedro Alves
2018-04-16 15:15 ` [RESEND][PATCH 01/40] Convert struct target_ops to C++ Pedro Alves
2018-05-03  0:06   ` Pedro Alves
2018-10-27 21:58     ` 8.2 regression for invalid -data-directory [Re: [RESEND][PATCH 01/40] Convert struct target_ops to C++] Jan Kratochvil
2018-10-30 20:24       ` Tom Tromey
2019-02-14 15:30     ` [RESEND][PATCH 01/40] Convert struct target_ops to C++ Thomas Schwinge
2018-04-27 15:47 ` [PATCH 00/40] C++ify target_ops, toward multi-target Tom Tromey
2018-05-02 22:55   ` Pedro Alves
2018-04-29 15:22 ` Simon Marchi
2018-05-02 22:51   ` Pedro Alves

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).