Patchwork [33/40] target_ops/C++: The rest of the BSD targets

login
register
mail settings
Submitter Pedro Alves
Date April 14, 2018, 7:09 p.m.
Message ID <20180414190953.24481-34-palves@redhat.com>
Download mbox | patch
Permalink /patch/26741/
State New
Headers show

Comments

Pedro Alves - April 14, 2018, 7:09 p.m.
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(-)

Patch

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);
-}
 
-/* 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);