Patchwork [39/40] linux_nat_target: More low methods

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

Comments

Pedro Alves - April 14, 2018, 7:09 p.m.
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(-)
John Baldwin - April 18, 2018, 12:40 a.m.
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.

Patch

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);
 
 
@@ -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)
 }
 
 
-/* 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); }
 };
 
 
@@ -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);
-
-
-/* Add an x86 GNU/Linux target.  */
-
-extern void x86_linux_add_target (linux_nat_target *t);
 
 #endif