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"
 
 
+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)
 }
 
 
-/* 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)
 
 
 #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 */
