]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdbserver/linux-low.cc
gdb, gdbserver, gdbsupport: fix whitespace issues
[thirdparty/binutils-gdb.git] / gdbserver / linux-low.cc
index 4db25cbdc6e8a0721dea43b843eb147ee5bde4d7..e6a39202a98af314738aa6a46c7f091e1c298424 100644 (file)
@@ -1,5 +1,5 @@
 /* Low level interface to ptrace, for the remote server for GDB.
-   Copyright (C) 1995-2020 Free Software Foundation, Inc.
+   Copyright (C) 1995-2023 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -21,6 +21,8 @@
 #include "nat/linux-osdata.h"
 #include "gdbsupport/agent.h"
 #include "tdesc.h"
+#include "gdbsupport/event-loop.h"
+#include "gdbsupport/event-pipe.h"
 #include "gdbsupport/rsp-low.h"
 #include "gdbsupport/signals-state-save-restore.h"
 #include "nat/linux-nat.h"
 #endif
 #include "nat/linux-namespaces.h"
 
-#ifdef HAVE_PERSONALITY
-# include <sys/personality.h>
-# if !HAVE_DECL_ADDR_NO_RANDOMIZE
-#  define ADDR_NO_RANDOMIZE 0x0040000
-# endif
-#endif
-
 #ifndef O_LARGEFILE
 #define O_LARGEFILE 0
 #endif
 #define PT_TEXT_ADDR 49*4
 #define PT_DATA_ADDR 50*4
 #define PT_TEXT_END_ADDR  51*4
-/* BFIN already defines these since at least 2.6.32 kernels.  */
-#elif defined(BFIN)
-#define PT_TEXT_ADDR 220
-#define PT_TEXT_END_ADDR 224
-#define PT_DATA_ADDR 228
 /* These are still undefined in 3.10 kernels.  */
 #elif defined(__TMS320C6X__)
 #define PT_TEXT_ADDR     (0x10000*4)
@@ -145,6 +135,15 @@ typedef struct
 /* Does the current host support PTRACE_GETREGSET?  */
 int have_ptrace_getregset = -1;
 
+/* Return TRUE if THREAD is the leader thread of the process.  */
+
+static bool
+is_leader (thread_info *thread)
+{
+  ptid_t ptid = ptid_of (thread);
+  return ptid.pid () == ptid.lwp ();
+}
+
 /* LWP accessors.  */
 
 /* See nat/linux-nat.h.  */
@@ -211,7 +210,7 @@ struct simple_pid_list
   /* Next in chain.  */
   struct simple_pid_list *next;
 };
-struct simple_pid_list *stopped_pids;
+static struct simple_pid_list *stopped_pids;
 
 /* Trivial list manipulation functions to keep track of a list of new
    stopped processes.  */
@@ -258,7 +257,7 @@ enum stopping_threads_kind
   };
 
 /* This is set while stop_all_lwps is in effect.  */
-enum stopping_threads_kind stopping_threads = NOT_STOPPING_THREADS;
+static stopping_threads_kind stopping_threads = NOT_STOPPING_THREADS;
 
 /* FIXME make into a target method?  */
 int using_threads = 1;
@@ -267,67 +266,47 @@ int using_threads = 1;
    jump pads).  */
 static int stabilizing_threads;
 
-static void linux_resume_one_lwp (struct lwp_info *lwp,
-                                 int step, int signal, siginfo_t *info);
-static void stop_all_lwps (int suspend, struct lwp_info *except);
-static void unstop_all_lwps (int unsuspend, struct lwp_info *except);
 static void unsuspend_all_lwps (struct lwp_info *except);
-static int linux_wait_for_event_filtered (ptid_t wait_ptid, ptid_t filter_ptid,
-                                         int *wstat, int options);
-static int linux_wait_for_event (ptid_t ptid, int *wstat, int options);
-static struct lwp_info *add_lwp (ptid_t ptid);
 static void mark_lwp_dead (struct lwp_info *lwp, int wstat);
 static int lwp_is_marked_dead (struct lwp_info *lwp);
-static void proceed_all_lwps (void);
-static int finish_step_over (struct lwp_info *lwp);
 static int kill_lwp (unsigned long lwpid, int signo);
 static void enqueue_pending_signal (struct lwp_info *lwp, int signal, siginfo_t *info);
-static void complete_ongoing_step_over (void);
 static int linux_low_ptrace_options (int attached);
 static int check_ptrace_stopped_lwp_gone (struct lwp_info *lp);
-static void proceed_one_lwp (thread_info *thread, lwp_info *except);
 
 /* When the event-loop is doing a step-over, this points at the thread
    being stepped.  */
-ptid_t step_over_bkpt;
-
-/* True if the low target can hardware single-step.  */
+static ptid_t step_over_bkpt;
 
-static int
-can_hardware_single_step (void)
+bool
+linux_process_target::low_supports_breakpoints ()
 {
-  if (the_low_target.supports_hardware_single_step != NULL)
-    return the_low_target.supports_hardware_single_step ();
-  else
-    return 0;
+  return false;
 }
 
-/* True if the low target can software single-step.  Such targets
-   implement the GET_NEXT_PCS callback.  */
-
-static int
-can_software_single_step (void)
+CORE_ADDR
+linux_process_target::low_get_pc (regcache *regcache)
 {
-  return (the_low_target.get_next_pcs != NULL);
+  return 0;
 }
 
-/* True if the low target supports memory breakpoints.  If so, we'll
-   have a GET_PC implementation.  */
-
-static int
-supports_breakpoints (void)
+void
+linux_process_target::low_set_pc (regcache *regcache, CORE_ADDR newpc)
 {
-  return (the_low_target.get_pc != NULL);
+  gdb_assert_not_reached ("linux target op low_set_pc is not implemented");
 }
 
-/* Returns true if this target can support fast tracepoints.  This
-   does not mean that the in-process agent has been loaded in the
-   inferior.  */
+std::vector<CORE_ADDR>
+linux_process_target::low_get_next_pcs (regcache *regcache)
+{
+  gdb_assert_not_reached ("linux target op low_get_next_pcs is not "
+                         "implemented");
+}
 
-static int
-supports_fast_tracepoints (void)
+int
+linux_process_target::low_decr_pc_after_break ()
 {
-  return the_low_target.install_fast_tracepoint_jump_pad != NULL;
+  return 0;
 }
 
 /* True if LWP is stopped in its stepping range.  */
@@ -340,22 +319,13 @@ lwp_in_step_range (struct lwp_info *lwp)
   return (pc >= lwp->step_range_start && pc < lwp->step_range_end);
 }
 
-struct pending_signals
-{
-  int signal;
-  siginfo_t info;
-  struct pending_signals *prev;
-};
-
-/* The read/write ends of the pipe registered as waitable file in the
-   event loop.  */
-static int linux_event_pipe[2] = { -1, -1 };
+/* The event pipe registered as a waitable file in the event loop.  */
+static event_pipe linux_event_pipe;
 
 /* True if we're currently in async mode.  */
-#define target_is_async_p() (linux_event_pipe[0] != -1)
+#define target_is_async_p() (linux_event_pipe.is_open ())
 
 static void send_sigstop (struct lwp_info *lwp);
-static void wait_for_sigstop (void);
 
 /* Return non-zero if HEADER is a 64-bit ELF file.  */
 
@@ -411,74 +381,111 @@ linux_pid_exe_is_elf_64_file (int pid, unsigned int *machine)
   return elf_64_file_p (file, machine);
 }
 
-static void
-delete_lwp (struct lwp_info *lwp)
+void
+linux_process_target::delete_lwp (lwp_info *lwp)
 {
   struct thread_info *thr = get_lwp_thread (lwp);
 
-  if (debug_threads)
-    debug_printf ("deleting %ld\n", lwpid_of (thr));
+  threads_debug_printf ("deleting %ld", lwpid_of (thr));
 
   remove_thread (thr);
 
-  if (the_low_target.delete_thread != NULL)
-    the_low_target.delete_thread (lwp->arch_private);
-  else
-    gdb_assert (lwp->arch_private == NULL);
+  low_delete_thread (lwp->arch_private);
+
+  delete lwp;
+}
 
-  free (lwp);
+void
+linux_process_target::low_delete_thread (arch_lwp_info *info)
+{
+  /* Default implementation should be overridden if architecture-specific
+     info is being used.  */
+  gdb_assert (info == nullptr);
 }
 
-/* Add a process to the common process list, and set its private
-   data.  */
+/* Open the /proc/PID/mem file for PROC.  */
+
+static void
+open_proc_mem_file (process_info *proc)
+{
+  gdb_assert (proc->priv->mem_fd == -1);
+
+  char filename[64];
+  xsnprintf (filename, sizeof filename, "/proc/%d/mem", proc->pid);
+
+  proc->priv->mem_fd
+    = gdb_open_cloexec (filename, O_RDWR | O_LARGEFILE, 0).release ();
+}
 
-static struct process_info *
-linux_add_process (int pid, int attached)
+process_info *
+linux_process_target::add_linux_process_no_mem_file (int pid, int attached)
 {
   struct process_info *proc;
 
   proc = add_process (pid, attached);
   proc->priv = XCNEW (struct process_info_private);
 
-  if (the_low_target.new_process != NULL)
-    proc->priv->arch_private = the_low_target.new_process ();
+  proc->priv->arch_private = low_new_process ();
+  proc->priv->mem_fd = -1;
 
   return proc;
 }
 
-static CORE_ADDR get_pc (struct lwp_info *lwp);
 
-/* Call the target arch_setup function on the current thread.  */
+process_info *
+linux_process_target::add_linux_process (int pid, int attached)
+{
+  process_info *proc = add_linux_process_no_mem_file (pid, attached);
+  open_proc_mem_file (proc);
+  return proc;
+}
 
-static void
-linux_arch_setup (void)
+void
+linux_process_target::remove_linux_process (process_info *proc)
 {
-  the_low_target.arch_setup ();
+  if (proc->priv->mem_fd >= 0)
+    close (proc->priv->mem_fd);
+
+  this->low_delete_process (proc->priv->arch_private);
+
+  xfree (proc->priv);
+  proc->priv = nullptr;
+
+  remove_process (proc);
 }
 
-/* Call the target arch_setup function on THREAD.  */
+arch_process_info *
+linux_process_target::low_new_process ()
+{
+  return nullptr;
+}
 
-static void
-linux_arch_setup_thread (struct thread_info *thread)
+void
+linux_process_target::low_delete_process (arch_process_info *info)
 {
-  struct thread_info *saved_thread;
+  /* Default implementation must be overridden if architecture-specific
+     info exists.  */
+  gdb_assert (info == nullptr);
+}
 
-  saved_thread = current_thread;
-  current_thread = thread;
+void
+linux_process_target::low_new_fork (process_info *parent, process_info *child)
+{
+  /* Nop.  */
+}
 
-  linux_arch_setup ();
+void
+linux_process_target::arch_setup_thread (thread_info *thread)
+{
+  scoped_restore_current_thread restore_thread;
+  switch_to_thread (thread);
 
-  current_thread = saved_thread;
+  low_arch_setup ();
 }
 
-/* Handle a GNU/Linux extended wait response.  If we see a clone,
-   fork, or vfork event, we need to add the new LWP to our list
-   (and return 0 so as not to report the trap to higher layers).
-   If we see an exec event, we will modify ORIG_EVENT_LWP to point
-   to a new LWP representing the new program.  */
-
-static int
-handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat)
+int
+linux_process_target::handle_extended_wait (lwp_info **orig_event_lwp,
+                                           int wstat)
 {
   client_state &cs = get_client_state ();
   struct lwp_info *event_lwp = *orig_event_lwp;
@@ -486,7 +493,7 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat)
   struct thread_info *event_thr = get_lwp_thread (event_lwp);
   struct lwp_info *new_lwp;
 
-  gdb_assert (event_lwp->waitstatus.kind == TARGET_WAITKIND_IGNORE);
+  gdb_assert (event_lwp->waitstatus.kind () == TARGET_WAITKIND_IGNORE);
 
   /* All extended events we currently use are mid-syscall.  Only
      PTRACE_EVENT_STOP is delivered more like a signal-stop, but
@@ -526,24 +533,20 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat)
          struct process_info *child_proc;
          struct lwp_info *child_lwp;
          struct thread_info *child_thr;
-         struct target_desc *tdesc;
 
-         ptid = ptid_t (new_pid, new_pid, 0);
+         ptid = ptid_t (new_pid, new_pid);
 
-         if (debug_threads)
-           {
-             debug_printf ("HEW: Got fork event from LWP %ld, "
-                           "new child is %d\n",
-                           ptid_of (event_thr).lwp (),
-                           ptid.pid ());
-           }
+         threads_debug_printf ("Got fork event from LWP %ld, "
+                               "new child is %d",
+                               ptid_of (event_thr).lwp (),
+                               ptid.pid ());
 
          /* Add the new process to the tables and clone the breakpoint
             lists of the parent.  We need to do this even if the new process
             will be detached, since we will need the process object and the
             breakpoints to remove any breakpoints from memory when we
             detach, and the client side will access registers.  */
-         child_proc = linux_add_process (new_pid, 0);
+         child_proc = add_linux_process (new_pid, 0);
          gdb_assert (child_proc != NULL);
          child_lwp = add_lwp (ptid);
          gdb_assert (child_lwp != NULL);
@@ -552,7 +555,7 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat)
          child_lwp->status_pending_p = 0;
          child_thr = get_lwp_thread (child_lwp);
          child_thr->last_resume_kind = resume_stop;
-         child_thr->last_status.kind = TARGET_WAITKIND_STOPPED;
+         child_thr->last_status.set_stopped (GDB_SIGNAL_0);
 
          /* If we're suspending all threads, leave this one suspended
             too.  If the fork/clone parent is stepping over a breakpoint,
@@ -561,8 +564,7 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat)
          if (stopping_threads == STOPPING_AND_SUSPENDING_THREADS
              || event_lwp->bp_reinsert != 0)
            {
-             if (debug_threads)
-               debug_printf ("HEW: leaving child suspended\n");
+             threads_debug_printf ("leaving child suspended");
              child_lwp->suspended = 1;
            }
 
@@ -570,7 +572,7 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat)
          child_proc->attached = parent_proc->attached;
 
          if (event_lwp->bp_reinsert != 0
-             && can_software_single_step ()
+             && supports_software_single_step ()
              && event == PTRACE_EVENT_VFORK)
            {
              /* If we leave single-step breakpoints there, child will
@@ -582,21 +584,18 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat)
 
          clone_all_breakpoints (child_thr, event_thr);
 
-         tdesc = allocate_target_description ();
-         copy_target_description (tdesc, parent_proc->tdesc);
-         child_proc->tdesc = tdesc;
+         target_desc_up tdesc = allocate_target_description ();
+         copy_target_description (tdesc.get (), parent_proc->tdesc);
+         child_proc->tdesc = tdesc.release ();
 
          /* Clone arch-specific process data.  */
-         if (the_low_target.new_fork != NULL)
-           the_low_target.new_fork (parent_proc, child_proc);
+         low_new_fork (parent_proc, child_proc);
 
          /* Save fork info in the parent thread.  */
          if (event == PTRACE_EVENT_FORK)
-           event_lwp->waitstatus.kind = TARGET_WAITKIND_FORKED;
+           event_lwp->waitstatus.set_forked (ptid);
          else if (event == PTRACE_EVENT_VFORK)
-           event_lwp->waitstatus.kind = TARGET_WAITKIND_VFORKED;
-
-         event_lwp->waitstatus.value.related_pid = ptid;
+           event_lwp->waitstatus.set_vforked (ptid);
 
          /* The status_pending field contains bits denoting the
             extended event, so when the pending event is handled,
@@ -615,7 +614,7 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat)
             In case of vfork, we'll reinsert them back once vforked
             child is done.  */
          if (event_lwp->bp_reinsert != 0
-             && can_software_single_step ())
+             && supports_software_single_step ())
            {
              /* The child process is forked and stopped, so it is safe
                 to access its memory without stopping all other threads
@@ -630,18 +629,17 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat)
          return 0;
        }
 
-      if (debug_threads)
-       debug_printf ("HEW: Got clone event "
-                     "from LWP %ld, new child is LWP %ld\n",
-                     lwpid_of (event_thr), new_pid);
+      threads_debug_printf
+       ("Got clone event from LWP %ld, new child is LWP %ld",
+        lwpid_of (event_thr), new_pid);
 
-      ptid = ptid_t (pid_of (event_thr), new_pid, 0);
+      ptid = ptid_t (pid_of (event_thr), new_pid);
       new_lwp = add_lwp (ptid);
 
       /* Either we're going to immediately resume the new thread
-        or leave it stopped.  linux_resume_one_lwp is a nop if it
+        or leave it stopped.  resume_one_lwp is a nop if it
         thinks the thread is currently running, so set this first
-        before calling linux_resume_one_lwp.  */
+        before calling resume_one_lwp.  */
       new_lwp->stopped = 1;
 
       /* If we're suspending all threads, leave this one suspended
@@ -663,7 +661,7 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat)
        }
       else if (cs.report_thread_events)
        {
-         new_lwp->waitstatus.kind = TARGET_WAITKIND_THREAD_CREATED;
+         new_lwp->waitstatus.set_thread_created ();
          new_lwp->status_pending_p = 1;
          new_lwp->status_pending = status;
        }
@@ -677,9 +675,9 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat)
     }
   else if (event == PTRACE_EVENT_VFORK_DONE)
     {
-      event_lwp->waitstatus.kind = TARGET_WAITKIND_VFORK_DONE;
+      event_lwp->waitstatus.set_vfork_done ();
 
-      if (event_lwp->bp_reinsert != 0 && can_software_single_step ())
+      if (event_lwp->bp_reinsert != 0 && supports_software_single_step ())
        {
          reinsert_single_step_breakpoints (event_thr);
 
@@ -696,11 +694,8 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat)
       ptid_t event_ptid;
       pid_t event_pid;
 
-      if (debug_threads)
-       {
-         debug_printf ("HEW: Got exec event from LWP %ld\n",
-                       lwpid_of (event_thr));
-       }
+      threads_debug_printf ("Got exec event from LWP %ld",
+                           lwpid_of (event_thr));
 
       /* Get the event ptid.  */
       event_ptid = ptid_of (event_thr);
@@ -711,27 +706,27 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat)
       syscalls_to_catch = std::move (proc->syscalls_to_catch);
 
       /* Delete the execing process and all its threads.  */
-      the_target->pt->mourn (proc);
-      current_thread = NULL;
+      mourn (proc);
+      switch_to_thread (nullptr);
 
       /* Create a new process/lwp/thread.  */
-      proc = linux_add_process (event_pid, 0);
+      proc = add_linux_process (event_pid, 0);
       event_lwp = add_lwp (event_ptid);
       event_thr = get_lwp_thread (event_lwp);
       gdb_assert (current_thread == event_thr);
-      linux_arch_setup_thread (event_thr);
+      arch_setup_thread (event_thr);
 
       /* Set the event status.  */
-      event_lwp->waitstatus.kind = TARGET_WAITKIND_EXECD;
-      event_lwp->waitstatus.value.execd_pathname
-       = xstrdup (linux_proc_pid_to_exec_file (lwpid_of (event_thr)));
+      event_lwp->waitstatus.set_execd
+       (make_unique_xstrdup
+          (linux_proc_pid_to_exec_file (lwpid_of (event_thr))));
 
       /* Mark the exec status as pending.  */
       event_lwp->stopped = 1;
       event_lwp->status_pending_p = 1;
       event_lwp->status_pending = wstat;
       event_thr->last_resume_kind = resume_continue;
-      event_thr->last_status.kind = TARGET_WAITKIND_IGNORE;
+      event_thr->last_status.set_ignore ();
 
       /* Update syscall state in the new lwp, effectively mid-syscall too.  */
       event_lwp->syscall_state = TARGET_WAITKIND_SYSCALL_ENTRY;
@@ -746,91 +741,76 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat)
       return 0;
     }
 
-  internal_error (__FILE__, __LINE__, _("unknown ptrace event %d"), event);
+  internal_error (_("unknown ptrace event %d"), event);
 }
 
-/* Return the PC as read from the regcache of LWP, without any
-   adjustment.  */
-
-static CORE_ADDR
-get_pc (struct lwp_info *lwp)
+CORE_ADDR
+linux_process_target::get_pc (lwp_info *lwp)
 {
-  struct thread_info *saved_thread;
-  struct regcache *regcache;
-  CORE_ADDR pc;
+  process_info *proc = get_thread_process (get_lwp_thread (lwp));
+  gdb_assert (!proc->starting_up);
 
-  if (the_low_target.get_pc == NULL)
+  if (!low_supports_breakpoints ())
     return 0;
 
-  saved_thread = current_thread;
-  current_thread = get_lwp_thread (lwp);
+  scoped_restore_current_thread restore_thread;
+  switch_to_thread (get_lwp_thread (lwp));
 
-  regcache = get_thread_regcache (current_thread, 1);
-  pc = (*the_low_target.get_pc) (regcache);
+  struct regcache *regcache = get_thread_regcache (current_thread, 1);
+  CORE_ADDR pc = low_get_pc (regcache);
 
-  if (debug_threads)
-    debug_printf ("pc is 0x%lx\n", (long) pc);
+  threads_debug_printf ("pc is 0x%lx", (long) pc);
 
-  current_thread = saved_thread;
   return pc;
 }
 
-/* This function should only be called if LWP got a SYSCALL_SIGTRAP.
-   Fill *SYSNO with the syscall nr trapped.  */
-
-static void
-get_syscall_trapinfo (struct lwp_info *lwp, int *sysno)
+void
+linux_process_target::get_syscall_trapinfo (lwp_info *lwp, int *sysno)
 {
-  struct thread_info *saved_thread;
   struct regcache *regcache;
 
-  if (the_low_target.get_syscall_trapinfo == NULL)
-    {
-      /* If we cannot get the syscall trapinfo, report an unknown
-        system call number.  */
-      *sysno = UNKNOWN_SYSCALL;
-      return;
-    }
-
-  saved_thread = current_thread;
-  current_thread = get_lwp_thread (lwp);
+  scoped_restore_current_thread restore_thread;
+  switch_to_thread (get_lwp_thread (lwp));
 
   regcache = get_thread_regcache (current_thread, 1);
-  (*the_low_target.get_syscall_trapinfo) (regcache, sysno);
-
-  if (debug_threads)
-    debug_printf ("get_syscall_trapinfo sysno %d\n", *sysno);
+  low_get_syscall_trapinfo (regcache, sysno);
 
-  current_thread = saved_thread;
+  threads_debug_printf ("get_syscall_trapinfo sysno %d", *sysno);
 }
 
-static int check_stopped_by_watchpoint (struct lwp_info *child);
-
-/* Called when the LWP stopped for a signal/trap.  If it stopped for a
-   trap check what caused it (breakpoint, watchpoint, trace, etc.),
-   and save the result in the LWP's stop_reason field.  If it stopped
-   for a breakpoint, decrement the PC if necessary on the lwp's
-   architecture.  Returns true if we now have the LWP's stop PC.  */
+void
+linux_process_target::low_get_syscall_trapinfo (regcache *regcache, int *sysno)
+{
+  /* By default, report an unknown system call number.  */
+  *sysno = UNKNOWN_SYSCALL;
+}
 
-static int
-save_stop_reason (struct lwp_info *lwp)
+bool
+linux_process_target::save_stop_reason (lwp_info *lwp)
 {
   CORE_ADDR pc;
   CORE_ADDR sw_breakpoint_pc;
-  struct thread_info *saved_thread;
 #if USE_SIGTRAP_SIGINFO
   siginfo_t siginfo;
 #endif
 
-  if (the_low_target.get_pc == NULL)
-    return 0;
+  if (!low_supports_breakpoints ())
+    return false;
+
+  process_info *proc = get_thread_process (get_lwp_thread (lwp));
+  if (proc->starting_up)
+    {
+      /* Claim we have the stop PC so that the caller doesn't try to
+        fetch it itself.  */
+      return true;
+    }
 
   pc = get_pc (lwp);
-  sw_breakpoint_pc = pc - the_low_target.decr_pc_after_break;
+  sw_breakpoint_pc = pc - low_decr_pc_after_break ();
 
   /* breakpoint_at reads from the current thread.  */
-  saved_thread = current_thread;
-  current_thread = get_lwp_thread (lwp);
+  scoped_restore_current_thread restore_thread;
+  switch_to_thread (get_lwp_thread (lwp));
 
 #if USE_SIGTRAP_SIGINFO
   if (ptrace (PTRACE_GETSIGINFO, lwpid_of (current_thread),
@@ -880,7 +860,7 @@ save_stop_reason (struct lwp_info *lwp)
      then the user inserts a breakpoint inside the range.  In that
      case we need to report the breakpoint PC.  */
   if ((!lwp->stepping || lwp->stop_pc == sw_breakpoint_pc)
-      && (*the_low_target.breakpoint_at) (sw_breakpoint_pc))
+      && low_breakpoint_at (sw_breakpoint_pc))
     lwp->stop_reason = TARGET_STOPPED_BY_SW_BREAKPOINT;
 
   if (hardware_breakpoint_inserted_here (pc))
@@ -892,78 +872,56 @@ save_stop_reason (struct lwp_info *lwp)
 
   if (lwp->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT)
     {
-      if (debug_threads)
-       {
-         struct thread_info *thr = get_lwp_thread (lwp);
-
-         debug_printf ("CSBB: %s stopped by software breakpoint\n",
-                       target_pid_to_str (ptid_of (thr)));
-       }
+      threads_debug_printf
+       ("%s stopped by software breakpoint",
+        target_pid_to_str (ptid_of (get_lwp_thread (lwp))).c_str ());
 
       /* Back up the PC if necessary.  */
       if (pc != sw_breakpoint_pc)
        {
          struct regcache *regcache
            = get_thread_regcache (current_thread, 1);
-         (*the_low_target.set_pc) (regcache, sw_breakpoint_pc);
+         low_set_pc (regcache, sw_breakpoint_pc);
        }
 
       /* Update this so we record the correct stop PC below.  */
       pc = sw_breakpoint_pc;
     }
   else if (lwp->stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT)
-    {
-      if (debug_threads)
-       {
-         struct thread_info *thr = get_lwp_thread (lwp);
-
-         debug_printf ("CSBB: %s stopped by hardware breakpoint\n",
-                       target_pid_to_str (ptid_of (thr)));
-       }
-    }
+    threads_debug_printf
+      ("%s stopped by hardware breakpoint",
+       target_pid_to_str (ptid_of (get_lwp_thread (lwp))).c_str ());
   else if (lwp->stop_reason == TARGET_STOPPED_BY_WATCHPOINT)
-    {
-      if (debug_threads)
-       {
-         struct thread_info *thr = get_lwp_thread (lwp);
-
-         debug_printf ("CSBB: %s stopped by hardware watchpoint\n",
-                       target_pid_to_str (ptid_of (thr)));
-       }
-    }
+    threads_debug_printf
+      ("%s stopped by hardware watchpoint",
+       target_pid_to_str (ptid_of (get_lwp_thread (lwp))).c_str ());
   else if (lwp->stop_reason == TARGET_STOPPED_BY_SINGLE_STEP)
-    {
-      if (debug_threads)
-       {
-         struct thread_info *thr = get_lwp_thread (lwp);
-
-         debug_printf ("CSBB: %s stopped by trace\n",
-                       target_pid_to_str (ptid_of (thr)));
-       }
-    }
+    threads_debug_printf
+      ("%s stopped by trace",
+       target_pid_to_str (ptid_of (get_lwp_thread (lwp))).c_str ());
 
   lwp->stop_pc = pc;
-  current_thread = saved_thread;
-  return 1;
+  return true;
 }
 
-static struct lwp_info *
-add_lwp (ptid_t ptid)
+lwp_info *
+linux_process_target::add_lwp (ptid_t ptid)
 {
-  struct lwp_info *lwp;
-
-  lwp = XCNEW (struct lwp_info);
-
-  lwp->waitstatus.kind = TARGET_WAITKIND_IGNORE;
+  lwp_info *lwp = new lwp_info;
 
   lwp->thread = add_thread (ptid, lwp);
 
-  if (the_low_target.new_thread != NULL)
-    the_low_target.new_thread (lwp);
+  low_new_thread (lwp);
 
   return lwp;
 }
 
+void
+linux_process_target::low_new_thread (lwp_info *info)
+{
+  /* Nop.  */
+}
+
 /* Callback to be used when calling fork_inferior, responsible for
    actually initiating the tracing of the inferior.  */
 
@@ -1012,7 +970,7 @@ linux_process_target::create_inferior (const char *program,
   {
     maybe_disable_address_space_randomization restore_personality
       (cs.disable_randomization);
-    std::string str_program_args = stringify_argv (program_args);
+    std::string str_program_args = construct_inferior_arguments (program_args);
 
     pid = fork_inferior (program,
                         str_program_args.c_str (),
@@ -1020,14 +978,22 @@ linux_process_target::create_inferior (const char *program,
                         NULL, NULL, NULL, NULL);
   }
 
-  linux_add_process (pid, 0);
+  /* When spawning a new process, we can't open the mem file yet.  We
+     still have to nurse the process through the shell, and that execs
+     a couple times.  The address space a /proc/PID/mem file is
+     accessing is destroyed on exec.  */
+  process_info *proc = add_linux_process_no_mem_file (pid, 0);
 
-  ptid = ptid_t (pid, pid, 0);
+  ptid = ptid_t (pid, pid);
   new_lwp = add_lwp (ptid);
   new_lwp->must_set_ptrace_flags = 1;
 
   post_fork_inferior (pid, program);
 
+  /* PROC is now past the shell running the program we want, so we can
+     open the /proc/PID/mem file.  */
+  open_proc_mem_file (proc);
+
   return pid;
 }
 
@@ -1038,7 +1004,7 @@ linux_process_target::post_create_inferior ()
 {
   struct lwp_info *lwp = get_thread_lwp (current_thread);
 
-  linux_arch_setup ();
+  low_arch_setup ();
 
   if (lwp->must_set_ptrace_flags)
     {
@@ -1050,11 +1016,8 @@ linux_process_target::post_create_inferior ()
     }
 }
 
-/* Attach to an inferior process.  Returns 0 on success, ERRNO on
-   error.  */
-
 int
-linux_attach_lwp (ptid_t ptid)
+linux_process_target::attach_lwp (ptid_t ptid)
 {
   struct lwp_info *new_lwp;
   int lwpid = ptid.lwp ();
@@ -1071,8 +1034,7 @@ linux_attach_lwp (ptid_t ptid)
 
   if (linux_proc_pid_is_stopped (lwpid))
     {
-      if (debug_threads)
-       debug_printf ("Attached to a stopped process\n");
+      threads_debug_printf ("Attached to a stopped process");
 
       /* The process is definitely stopped.  It is in a job control
         stop, unless the kernel predates the TASK_STOPPED /
@@ -1148,10 +1110,9 @@ attach_proc_task_lwp_callback (ptid_t ptid)
       int lwpid = ptid.lwp ();
       int err;
 
-      if (debug_threads)
-       debug_printf ("Found new lwp %d\n", lwpid);
+      threads_debug_printf ("Found new lwp %d", lwpid);
 
-      err = linux_attach_lwp (ptid);
+      err = the_linux_target->attach_lwp (ptid);
 
       /* Be quiet if we simply raced with the thread exiting.  EPERM
         is returned if the thread's task still exists, and is marked
@@ -1159,14 +1120,9 @@ attach_proc_task_lwp_callback (ptid_t ptid)
         case, confirm the status in /proc/PID/status.  */
       if (err == ESRCH
          || (err == EPERM && linux_proc_pid_is_gone (lwpid)))
-       {
-         if (debug_threads)
-           {
-             debug_printf ("Cannot attach to lwp %d: "
-                           "thread is gone (%d: %s)\n",
-                           lwpid, err, safe_strerror (err));
-           }
-       }
+       threads_debug_printf
+         ("Cannot attach to lwp %d: thread is gone (%d: %s)",
+          lwpid, err, safe_strerror (err));
       else if (err != 0)
        {
          std::string reason
@@ -1190,25 +1146,29 @@ linux_process_target::attach (unsigned long pid)
 {
   struct process_info *proc;
   struct thread_info *initial_thread;
-  ptid_t ptid = ptid_t (pid, pid, 0);
+  ptid_t ptid = ptid_t (pid, pid);
   int err;
 
-  proc = linux_add_process (pid, 1);
+  /* Delay opening the /proc/PID/mem file until we've successfully
+     attached.  */
+  proc = add_linux_process_no_mem_file (pid, 1);
 
   /* Attach to PID.  We will check for other threads
      soon.  */
-  err = linux_attach_lwp (ptid);
+  err = attach_lwp (ptid);
   if (err != 0)
     {
-      remove_process (proc);
+      this->remove_linux_process (proc);
 
       std::string reason = linux_ptrace_attach_fail_reason_string (ptid, err);
       error ("Cannot attach to process %ld: %s", pid, reason.c_str ());
     }
 
+  open_proc_mem_file (proc);
+
   /* Don't ignore the initial SIGSTOP if we just attached to this
      process.  It will be collected by wait shortly.  */
-  initial_thread = find_thread_ptid (ptid_t (pid, pid, 0));
+  initial_thread = find_thread_ptid (ptid_t (pid, pid));
   initial_thread->last_resume_kind = resume_stop;
 
   /* We must attach to every LWP.  If /proc is mounted, use that to
@@ -1234,8 +1194,7 @@ linux_process_target::attach (unsigned long pid)
       int wstat, lwpid;
       ptid_t pid_ptid = ptid_t (pid);
 
-      lwpid = linux_wait_for_event_filtered (pid_ptid, pid_ptid,
-                                            &wstat, __WALL);
+      lwpid = wait_for_event_filtered (pid_ptid, pid_ptid, &wstat, __WALL);
       gdb_assert (lwpid > 0);
 
       lwp = find_lwp_pid (ptid_t (lwpid));
@@ -1306,9 +1265,9 @@ linux_kill_one_lwp (struct lwp_info *lwp)
     {
       int save_errno = errno;
 
-      debug_printf ("LKL:  kill_lwp (SIGKILL) %s, 0, 0 (%s)\n",
-                   target_pid_to_str (ptid_of (thr)),
-                   save_errno ? safe_strerror (save_errno) : "OK");
+      threads_debug_printf ("kill_lwp (SIGKILL) %s, 0, 0 (%s)",
+                           target_pid_to_str (ptid_of (thr)).c_str (),
+                           save_errno ? safe_strerror (save_errno) : "OK");
     }
 
   errno = 0;
@@ -1317,9 +1276,9 @@ linux_kill_one_lwp (struct lwp_info *lwp)
     {
       int save_errno = errno;
 
-      debug_printf ("LKL:  PTRACE_KILL %s, 0, 0 (%s)\n",
-                   target_pid_to_str (ptid_of (thr)),
-                   save_errno ? safe_strerror (save_errno) : "OK");
+      threads_debug_printf ("PTRACE_KILL %s, 0, 0 (%s)",
+                           target_pid_to_str (ptid_of (thr)).c_str (),
+                           save_errno ? safe_strerror (save_errno) : "OK");
     }
 }
 
@@ -1334,8 +1293,7 @@ kill_wait_lwp (struct lwp_info *lwp)
   int wstat;
   int res;
 
-  if (debug_threads)
-    debug_printf ("kwl: killing lwp %d, for pid: %d\n", lwpid, pid);
+  threads_debug_printf ("killing lwp %d, for pid: %d", lwpid, pid);
 
   do
     {
@@ -1345,7 +1303,7 @@ kill_wait_lwp (struct lwp_info *lwp)
 
         - The loop is most likely unnecessary.
 
-        - We don't use linux_wait_for_event as that could delete lwps
+        - We don't use wait_for_event as that could delete lwps
           while we're iterating over them.  We're not interested in
           any pending status at this point, only in making sure all
           wait status on the kernel side are collected until the
@@ -1381,9 +1339,8 @@ kill_one_lwp_callback (thread_info *thread, int pid)
 
   if (lwpid_of (thread) == pid)
     {
-      if (debug_threads)
-       debug_printf ("lkop: is last of process %s\n",
-                     target_pid_to_str (thread->id));
+      threads_debug_printf ("is last of process %s",
+                           target_pid_to_str (thread->id).c_str ());
       return;
     }
 
@@ -1409,11 +1366,7 @@ linux_process_target::kill (process_info *process)
   lwp_info *lwp = find_lwp_pid (ptid_t (pid));
 
   if (lwp == NULL)
-    {
-      if (debug_threads)
-       debug_printf ("lk_1: cannot find lwp for pid: %d\n",
-                     pid);
-    }
+    threads_debug_printf ("cannot find lwp for pid: %d", pid);
   else
     kill_wait_lwp (lwp);
 
@@ -1444,8 +1397,8 @@ get_detach_signal (struct thread_info *thread)
       /* If the thread had been suspended by gdbserver, and it stopped
         cleanly, then it'll have stopped with SIGSTOP.  But we don't
         want to deliver that SIGSTOP.  */
-      if (thread->last_status.kind != TARGET_WAITKIND_STOPPED
-         || thread->last_status.value.sig == GDB_SIGNAL_0)
+      if (thread->last_status.kind () != TARGET_WAITKIND_STOPPED
+         || thread->last_status.sig () == GDB_SIGNAL_0)
        return 0;
 
       /* Otherwise, we may need to deliver the signal we
@@ -1455,19 +1408,17 @@ get_detach_signal (struct thread_info *thread)
 
   if (!WIFSTOPPED (status))
     {
-      if (debug_threads)
-       debug_printf ("GPS: lwp %s hasn't stopped: no pending signal\n",
-                     target_pid_to_str (ptid_of (thread)));
+      threads_debug_printf ("lwp %s hasn't stopped: no pending signal",
+                           target_pid_to_str (ptid_of (thread)).c_str ());
       return 0;
     }
 
   /* Extended wait statuses aren't real SIGTRAPs.  */
   if (WSTOPSIG (status) == SIGTRAP && linux_is_extended_waitstatus (status))
     {
-      if (debug_threads)
-       debug_printf ("GPS: lwp %s had stopped with extended "
-                     "status: no pending signal\n",
-                     target_pid_to_str (ptid_of (thread)));
+      threads_debug_printf ("lwp %s had stopped with extended "
+                           "status: no pending signal",
+                           target_pid_to_str (ptid_of (thread)).c_str ());
       return 0;
     }
 
@@ -1475,10 +1426,9 @@ get_detach_signal (struct thread_info *thread)
 
   if (cs.program_signals_p && !cs.program_signals[signo])
     {
-      if (debug_threads)
-       debug_printf ("GPS: lwp %s had signal %s, but it is in nopass state\n",
-                     target_pid_to_str (ptid_of (thread)),
-                     gdb_signal_to_string (signo));
+      threads_debug_printf ("lwp %s had signal %s, but it is in nopass state",
+                           target_pid_to_str (ptid_of (thread)).c_str (),
+                           gdb_signal_to_string (signo));
       return 0;
     }
   else if (!cs.program_signals_p
@@ -1487,29 +1437,25 @@ get_detach_signal (struct thread_info *thread)
              SIGTRAP/SIGINT, which is GDB's default.  */
           && (signo == GDB_SIGNAL_TRAP || signo == GDB_SIGNAL_INT))
     {
-      if (debug_threads)
-       debug_printf ("GPS: lwp %s had signal %s, "
-                     "but we don't know if we should pass it. "
-                     "Default to not.\n",
-                     target_pid_to_str (ptid_of (thread)),
-                     gdb_signal_to_string (signo));
+      threads_debug_printf ("lwp %s had signal %s, "
+                           "but we don't know if we should pass it. "
+                           "Default to not.",
+                           target_pid_to_str (ptid_of (thread)).c_str (),
+                           gdb_signal_to_string (signo));
       return 0;
     }
   else
     {
-      if (debug_threads)
-       debug_printf ("GPS: lwp %s has pending signal %s: delivering it.\n",
-                     target_pid_to_str (ptid_of (thread)),
-                     gdb_signal_to_string (signo));
+      threads_debug_printf ("lwp %s has pending signal %s: delivering it",
+                           target_pid_to_str (ptid_of (thread)).c_str (),
+                           gdb_signal_to_string (signo));
 
       return WSTOPSIG (status);
     }
 }
 
-/* Detach from LWP.  */
-
-static void
-linux_detach_one_lwp (struct lwp_info *lwp)
+void
+linux_process_target::detach_one_lwp (lwp_info *lwp)
 {
   struct thread_info *thread = get_lwp_thread (lwp);
   int sig;
@@ -1518,9 +1464,8 @@ linux_detach_one_lwp (struct lwp_info *lwp)
   /* If there is a pending SIGSTOP, get rid of it.  */
   if (lwp->stop_expected)
     {
-      if (debug_threads)
-       debug_printf ("Sending SIGCONT to %s\n",
-                     target_pid_to_str (ptid_of (thread)));
+      threads_debug_printf ("Sending SIGCONT to %s",
+                           target_pid_to_str (ptid_of (thread)).c_str ());
 
       kill_lwp (lwpid_of (thread), SIGCONT);
       lwp->stop_expected = 0;
@@ -1538,8 +1483,7 @@ linux_detach_one_lwp (struct lwp_info *lwp)
       regcache_invalidate_thread (thread);
 
       /* Finally, let it resume.  */
-      if (the_low_target.prepare_to_resume != NULL)
-       the_low_target.prepare_to_resume (lwp);
+      low_prepare_to_resume (lwp);
     }
   catch (const gdb_exception_error &ex)
     {
@@ -1577,36 +1521,18 @@ linux_detach_one_lwp (struct lwp_info *lwp)
       else
        {
          error (_("Can't detach %s: %s"),
-                target_pid_to_str (ptid_of (thread)),
+                target_pid_to_str (ptid_of (thread)).c_str (),
                 safe_strerror (save_errno));
        }
     }
-  else if (debug_threads)
-    {
-      debug_printf ("PTRACE_DETACH (%s, %s, 0) (OK)\n",
-                   target_pid_to_str (ptid_of (thread)),
-                   strsignal (sig));
-    }
+  else
+    threads_debug_printf ("PTRACE_DETACH (%s, %s, 0) (OK)",
+                         target_pid_to_str (ptid_of (thread)).c_str (),
+                         strsignal (sig));
 
   delete_lwp (lwp);
 }
 
-/* Callback for for_each_thread.  Detaches from non-leader threads of a
-   given process.  */
-
-static void
-linux_detach_lwp_callback (thread_info *thread)
-{
-  /* We don't actually detach from the thread group leader just yet.
-     If the thread group exits, we must reap the zombie clone lwps
-     before we're able to reap the leader.  */
-  if (thread->id.pid () == thread->id.lwp ())
-    return;
-
-  lwp_info *lwp = get_thread_lwp (thread);
-  linux_detach_one_lwp (lwp);
-}
-
 int
 linux_process_target::detach (process_info *process)
 {
@@ -1633,10 +1559,20 @@ linux_process_target::detach (process_info *process)
   /* Detach from the clone lwps first.  If the thread group exits just
      while we're detaching, we must reap the clone lwps before we're
      able to reap the leader.  */
-  for_each_thread (process->pid, linux_detach_lwp_callback);
+  for_each_thread (process->pid, [this] (thread_info *thread)
+    {
+      /* We don't actually detach from the thread group leader just yet.
+        If the thread group exits, we must reap the zombie clone lwps
+        before we're able to reap the leader.  */
+      if (thread->id.pid () == thread->id.lwp ())
+       return;
+
+      lwp_info *lwp = get_thread_lwp (thread);
+      detach_one_lwp (lwp);
+    });
 
   main_lwp = find_lwp_pid (ptid_t (process->pid));
-  linux_detach_one_lwp (main_lwp);
+  detach_one_lwp (main_lwp);
 
   mourn (process);
 
@@ -1651,27 +1587,16 @@ linux_process_target::detach (process_info *process)
 void
 linux_process_target::mourn (process_info *process)
 {
-  struct process_info_private *priv;
-
 #ifdef USE_THREAD_DB
   thread_db_mourn (process);
 #endif
 
-  for_each_thread (process->pid, [] (thread_info *thread)
+  for_each_thread (process->pid, [this] (thread_info *thread)
     {
       delete_lwp (get_thread_lwp (thread));
     });
 
-  /* Freeing all private data.  */
-  priv = process->priv;
-  if (the_low_target.delete_process != NULL)
-    the_low_target.delete_process (priv->arch_private);
-  else
-    gdb_assert (priv->arch_private == NULL);
-  free (priv);
-  process->priv = NULL;
-
-  remove_process (process);
+  this->remove_linux_process (process);
 }
 
 void
@@ -1702,12 +1627,8 @@ linux_process_target::thread_alive (ptid_t ptid)
     return 0;
 }
 
-/* Return 1 if this lwp still has an interesting status pending.  If
-   not (e.g., it had stopped for a breakpoint that is gone), return
-   false.  */
-
-static int
-thread_still_has_status_pending_p (struct thread_info *thread)
+bool
+linux_process_target::thread_still_has_status_pending (thread_info *thread)
 {
   struct lwp_info *lp = get_thread_lwp (thread);
 
@@ -1718,7 +1639,6 @@ thread_still_has_status_pending_p (struct thread_info *thread)
       && (lp->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT
          || lp->stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT))
     {
-      struct thread_info *saved_thread;
       CORE_ADDR pc;
       int discard = 0;
 
@@ -1726,42 +1646,36 @@ thread_still_has_status_pending_p (struct thread_info *thread)
 
       pc = get_pc (lp);
 
-      saved_thread = current_thread;
-      current_thread = thread;
+      scoped_restore_current_thread restore_thread;
+      switch_to_thread (thread);
 
       if (pc != lp->stop_pc)
        {
-         if (debug_threads)
-           debug_printf ("PC of %ld changed\n",
-                         lwpid_of (thread));
+         threads_debug_printf ("PC of %ld changed",
+                               lwpid_of (thread));
          discard = 1;
        }
 
 #if !USE_SIGTRAP_SIGINFO
       else if (lp->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT
-              && !(*the_low_target.breakpoint_at) (pc))
+              && !low_breakpoint_at (pc))
        {
-         if (debug_threads)
-           debug_printf ("previous SW breakpoint of %ld gone\n",
-                         lwpid_of (thread));
+         threads_debug_printf ("previous SW breakpoint of %ld gone",
+                               lwpid_of (thread));
          discard = 1;
        }
       else if (lp->stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT
               && !hardware_breakpoint_inserted_here (pc))
        {
-         if (debug_threads)
-           debug_printf ("previous HW breakpoint of %ld gone\n",
-                         lwpid_of (thread));
+         threads_debug_printf ("previous HW breakpoint of %ld gone",
+                               lwpid_of (thread));
          discard = 1;
        }
 #endif
 
-      current_thread = saved_thread;
-
       if (discard)
        {
-         if (debug_threads)
-           debug_printf ("discarding pending breakpoint status\n");
+         threads_debug_printf ("discarding pending breakpoint status");
          lp->status_pending_p = 0;
          return 0;
        }
@@ -1784,15 +1698,15 @@ lwp_resumed (struct lwp_info *lwp)
      corresponding stop to gdb yet?  If so, the thread is still
      resumed/running from gdb's perspective.  */
   if (thread->last_resume_kind == resume_stop
-      && thread->last_status.kind == TARGET_WAITKIND_IGNORE)
+      && thread->last_status.kind () == TARGET_WAITKIND_IGNORE)
     return 1;
 
   return 0;
 }
 
-/* Return true if this lwp has an interesting status pending.  */
-static bool
-status_pending_p_callback (thread_info *thread, ptid_t ptid)
+bool
+linux_process_target::status_pending_p_callback (thread_info *thread,
+                                                ptid_t ptid)
 {
   struct lwp_info *lp = get_thread_lwp (thread);
 
@@ -1805,9 +1719,9 @@ status_pending_p_callback (thread_info *thread, ptid_t ptid)
     return 0;
 
   if (lp->status_pending_p
-      && !thread_still_has_status_pending_p (thread))
+      && !thread_still_has_status_pending (thread))
     {
-      linux_resume_one_lwp (lp, lp->stepping, GDB_SIGNAL_0, NULL);
+      resume_one_lwp (lp, lp->stepping, GDB_SIGNAL_0, NULL);
       return 0;
     }
 
@@ -1817,9 +1731,9 @@ status_pending_p_callback (thread_info *thread, ptid_t ptid)
 struct lwp_info *
 find_lwp_pid (ptid_t ptid)
 {
-  thread_info *thread = find_thread ([&] (thread_info *thr_arg)
+  long lwp = ptid.lwp () != 0 ? ptid.lwp () : ptid.pid ();
+  thread_info *thread = find_thread ([lwp] (thread_info *thr_arg)
     {
-      int lwp = ptid.lwp () != 0 ? ptid.lwp () : ptid.pid ();
       return thr_arg->id.lwp () == lwp;
     });
 
@@ -1863,65 +1777,80 @@ iterate_over_lwps (ptid_t filter,
   return get_thread_lwp (thread);
 }
 
-/* Detect zombie thread group leaders, and "exit" them.  We can't reap
-   their exits until all other threads in the group have exited.  */
-
-static void
-check_zombie_leaders (void)
-{
-  for_each_process ([] (process_info *proc) {
-    pid_t leader_pid = pid_of (proc);
-    struct lwp_info *leader_lp;
-
-    leader_lp = find_lwp_pid (ptid_t (leader_pid));
-
-    if (debug_threads)
-      debug_printf ("leader_pid=%d, leader_lp!=NULL=%d, "
-                   "num_lwps=%d, zombie=%d\n",
-                   leader_pid, leader_lp!= NULL, num_lwps (leader_pid),
-                   linux_proc_pid_is_zombie (leader_pid));
-
-    if (leader_lp != NULL && !leader_lp->stopped
-       /* Check if there are other threads in the group, as we may
-          have raced with the inferior simply exiting.  */
-       && !last_thread_of_process_p (leader_pid)
-       && linux_proc_pid_is_zombie (leader_pid))
-      {
-       /* A leader zombie can mean one of two things:
-
-          - It exited, and there's an exit status pending
-          available, or only the leader exited (not the whole
-          program).  In the latter case, we can't waitpid the
-          leader's exit status until all other threads are gone.
-
-          - There are 3 or more threads in the group, and a thread
-          other than the leader exec'd.  On an exec, the Linux
-          kernel destroys all other threads (except the execing
-          one) in the thread group, and resets the execing thread's
-          tid to the tgid.  No exit notification is sent for the
-          execing thread -- from the ptracer's perspective, it
-          appears as though the execing thread just vanishes.
-          Until we reap all other threads except the leader and the
-          execing thread, the leader will be zombie, and the
-          execing thread will be in `D (disc sleep)'.  As soon as
-          all other threads are reaped, the execing thread changes
-          it's tid to the tgid, and the previous (zombie) leader
-          vanishes, giving place to the "new" leader.  We could try
-          distinguishing the exit and exec cases, by waiting once
-          more, and seeing if something comes out, but it doesn't
-          sound useful.  The previous leader _does_ go away, and
-          we'll re-add the new one once we see the exec event
-          (which is just the same as what would happen if the
-          previous leader did exit voluntarily before some other
-          thread execs).  */
-
-       if (debug_threads)
-         debug_printf ("CZL: Thread group leader %d zombie "
-                       "(it exited, or another thread execd).\n",
-                       leader_pid);
-
-       delete_lwp (leader_lp);
-      }
+void
+linux_process_target::check_zombie_leaders ()
+{
+  for_each_process ([this] (process_info *proc)
+    {
+      pid_t leader_pid = pid_of (proc);
+      lwp_info *leader_lp = find_lwp_pid (ptid_t (leader_pid));
+
+      threads_debug_printf ("leader_pid=%d, leader_lp!=NULL=%d, "
+                           "num_lwps=%d, zombie=%d",
+                           leader_pid, leader_lp!= NULL, num_lwps (leader_pid),
+                           linux_proc_pid_is_zombie (leader_pid));
+
+      if (leader_lp != NULL && !leader_lp->stopped
+         /* Check if there are other threads in the group, as we may
+            have raced with the inferior simply exiting.  Note this
+            isn't a watertight check.  If the inferior is
+            multi-threaded and is exiting, it may be we see the
+            leader as zombie before we reap all the non-leader
+            threads.  See comments below.  */
+         && !last_thread_of_process_p (leader_pid)
+         && linux_proc_pid_is_zombie (leader_pid))
+       {
+         /* A zombie leader in a multi-threaded program can mean one
+            of three things:
+
+            #1 - Only the leader exited, not the whole program, e.g.,
+            with pthread_exit.  Since we can't reap the leader's exit
+            status until all other threads are gone and reaped too,
+            we want to delete the zombie leader right away, as it
+            can't be debugged, we can't read its registers, etc.
+            This is the main reason we check for zombie leaders
+            disappearing.
+
+            #2 - The whole thread-group/process exited (a group exit,
+            via e.g. exit(3), and there is (or will be shortly) an
+            exit reported for each thread in the process, and then
+            finally an exit for the leader once the non-leaders are
+            reaped.
+
+            #3 - There are 3 or more threads in the group, and a
+            thread other than the leader exec'd.  See comments on
+            exec events at the top of the file.
+
+            Ideally we would never delete the leader for case #2.
+            Instead, we want to collect the exit status of each
+            non-leader thread, and then finally collect the exit
+            status of the leader as normal and use its exit code as
+            whole-process exit code.  Unfortunately, there's no
+            race-free way to distinguish cases #1 and #2.  We can't
+            assume the exit events for the non-leaders threads are
+            already pending in the kernel, nor can we assume the
+            non-leader threads are in zombie state already.  Between
+            the leader becoming zombie and the non-leaders exiting
+            and becoming zombie themselves, there's a small time
+            window, so such a check would be racy.  Temporarily
+            pausing all threads and checking to see if all threads
+            exit or not before re-resuming them would work in the
+            case that all threads are running right now, but it
+            wouldn't work if some thread is currently already
+            ptrace-stopped, e.g., due to scheduler-locking.
+
+            So what we do is we delete the leader anyhow, and then
+            later on when we see its exit status, we re-add it back.
+            We also make sure that we only report a whole-process
+            exit when we see the leader exiting, as opposed to when
+            the last LWP in the LWP list exits, which can be a
+            non-leader if we deleted the leader here.  */
+         threads_debug_printf ("Thread group leader %d zombie "
+                               "(it exited, or another thread execd), "
+                               "deleting it.",
+                               leader_pid);
+         delete_lwp (leader_lp);
+       }
     });
 }
 
@@ -1946,13 +1875,10 @@ lwp_suspended_inc (struct lwp_info *lwp)
 {
   lwp->suspended++;
 
-  if (debug_threads && lwp->suspended > 4)
-    {
-      struct thread_info *thread = get_lwp_thread (lwp);
-
-      debug_printf ("LWP %ld has a suspiciously high suspend count,"
-                   " suspended=%d\n", lwpid_of (thread), lwp->suspended);
-    }
+  if (lwp->suspended > 4)
+    threads_debug_printf
+      ("LWP %ld has a suspiciously high suspend count, suspended=%d",
+       lwpid_of (get_lwp_thread (lwp)), lwp->suspended);
 }
 
 /* Decrement LWP's suspend count.  */
@@ -1966,8 +1892,7 @@ lwp_suspended_decr (struct lwp_info *lwp)
     {
       struct thread_info *thread = get_lwp_thread (lwp);
 
-      internal_error (__FILE__, __LINE__,
-                     "unsuspend LWP %ld, suspended=%d\n", lwpid_of (thread),
+      internal_error ("unsuspend LWP %ld, suspended=%d\n", lwpid_of (thread),
                      lwp->suspended);
     }
 }
@@ -2014,49 +1939,41 @@ handle_tracepoints (struct lwp_info *lwp)
 
   if (tpoint_related_event)
     {
-      if (debug_threads)
-       debug_printf ("got a tracepoint event\n");
+      threads_debug_printf ("got a tracepoint event");
       return 1;
     }
 
   return 0;
 }
 
-/* Convenience wrapper.  Returns information about LWP's fast tracepoint
-   collection status.  */
-
-static fast_tpoint_collect_result
-linux_fast_tracepoint_collecting (struct lwp_info *lwp,
-                                 struct fast_tpoint_collect_status *status)
+fast_tpoint_collect_result
+linux_process_target::linux_fast_tracepoint_collecting
+  (lwp_info *lwp, fast_tpoint_collect_status *status)
 {
   CORE_ADDR thread_area;
   struct thread_info *thread = get_lwp_thread (lwp);
 
-  if (the_low_target.get_thread_area == NULL)
-    return fast_tpoint_collect_result::not_collecting;
-
   /* Get the thread area address.  This is used to recognize which
      thread is which when tracing with the in-process agent library.
      We don't read anything from the address, and treat it as opaque;
      it's the address itself that we assume is unique per-thread.  */
-  if ((*the_low_target.get_thread_area) (lwpid_of (thread), &thread_area) == -1)
+  if (low_get_thread_area (lwpid_of (thread), &thread_area) == -1)
     return fast_tpoint_collect_result::not_collecting;
 
   return fast_tracepoint_collecting (thread_area, lwp->stop_pc, status);
 }
 
-/* The reason we resume in the caller, is because we want to be able
-   to pass lwp->status_pending as WSTAT, and we need to clear
-   status_pending_p before resuming, otherwise, linux_resume_one_lwp
-   refuses to resume.  */
-
-static int
-maybe_move_out_of_jump_pad (struct lwp_info *lwp, int *wstat)
+int
+linux_process_target::low_get_thread_area (int lwpid, CORE_ADDR *addrp)
 {
-  struct thread_info *saved_thread;
+  return -1;
+}
 
-  saved_thread = current_thread;
-  current_thread = get_lwp_thread (lwp);
+bool
+linux_process_target::maybe_move_out_of_jump_pad (lwp_info *lwp, int *wstat)
+{
+  scoped_restore_current_thread restore_thread;
+  switch_to_thread (get_lwp_thread (lwp));
 
   if ((wstat == NULL
        || (WIFSTOPPED (*wstat) && WSTOPSIG (*wstat) != SIGTRAP))
@@ -2065,10 +1982,9 @@ maybe_move_out_of_jump_pad (struct lwp_info *lwp, int *wstat)
     {
       struct fast_tpoint_collect_status status;
 
-      if (debug_threads)
-       debug_printf ("Checking whether LWP %ld needs to move out of the "
-                     "jump pad.\n",
-                     lwpid_of (current_thread));
+      threads_debug_printf
+       ("Checking whether LWP %ld needs to move out of the jump pad.",
+        lwpid_of (current_thread));
 
       fast_tpoint_collect_result r
        = linux_fast_tracepoint_collecting (lwp, &status);
@@ -2093,13 +2009,11 @@ maybe_move_out_of_jump_pad (struct lwp_info *lwp, int *wstat)
                    = set_breakpoint_at (status.adjusted_insn_addr, NULL);
                }
 
-             if (debug_threads)
-               debug_printf ("Checking whether LWP %ld needs to move out of "
-                             "the jump pad...it does\n",
-                             lwpid_of (current_thread));
-             current_thread = saved_thread;
+             threads_debug_printf
+               ("Checking whether LWP %ld needs to move out of the jump pad..."
+                " it does", lwpid_of (current_thread));
 
-             return 1;
+             return true;
            }
        }
       else
@@ -2139,7 +2053,7 @@ maybe_move_out_of_jump_pad (struct lwp_info *lwp, int *wstat)
                }
 
              regcache = get_thread_regcache (current_thread, 1);
-             (*the_low_target.set_pc) (regcache, status.tpoint_addr);
+             low_set_pc (regcache, status.tpoint_addr);
              lwp->stop_pc = status.tpoint_addr;
 
              /* Cancel any fast tracepoint lock this thread was
@@ -2149,9 +2063,9 @@ maybe_move_out_of_jump_pad (struct lwp_info *lwp, int *wstat)
 
          if (lwp->exit_jump_pad_bkpt != NULL)
            {
-             if (debug_threads)
-               debug_printf ("Cancelling fast exit-jump-pad: removing bkpt. "
-                             "stopping all threads momentarily.\n");
+             threads_debug_printf
+               ("Cancelling fast exit-jump-pad: removing bkpt."
+                "stopping all threads momentarily.");
 
              stop_all_lwps (1, lwp);
 
@@ -2165,13 +2079,11 @@ maybe_move_out_of_jump_pad (struct lwp_info *lwp, int *wstat)
        }
     }
 
-  if (debug_threads)
-    debug_printf ("Checking whether LWP %ld needs to move out of the "
-                 "jump pad...no\n",
-                 lwpid_of (current_thread));
+  threads_debug_printf
+    ("Checking whether LWP %ld needs to move out of the jump pad... no",
+     lwpid_of (current_thread));
 
-  current_thread = saved_thread;
-  return 0;
+  return false;
 }
 
 /* Enqueue one signal in the "signals to report later when out of the
@@ -2180,24 +2092,17 @@ maybe_move_out_of_jump_pad (struct lwp_info *lwp, int *wstat)
 static void
 enqueue_one_deferred_signal (struct lwp_info *lwp, int *wstat)
 {
-  struct pending_signals *p_sig;
   struct thread_info *thread = get_lwp_thread (lwp);
 
-  if (debug_threads)
-    debug_printf ("Deferring signal %d for LWP %ld.\n",
-                 WSTOPSIG (*wstat), lwpid_of (thread));
+  threads_debug_printf ("Deferring signal %d for LWP %ld.",
+                       WSTOPSIG (*wstat), lwpid_of (thread));
 
   if (debug_threads)
     {
-      struct pending_signals *sig;
+      for (const auto &sig : lwp->pending_signals_to_report)
+       threads_debug_printf ("   Already queued %d", sig.signal);
 
-      for (sig = lwp->pending_signals_to_report;
-          sig != NULL;
-          sig = sig->prev)
-       debug_printf ("   Already queued %d\n",
-                     sig->signal);
-
-      debug_printf ("   (no more currently queued signals)\n");
+      threads_debug_printf ("   (no more currently queued signals)");
     }
 
   /* Don't enqueue non-RT signals if they are already in the deferred
@@ -2205,32 +2110,22 @@ enqueue_one_deferred_signal (struct lwp_info *lwp, int *wstat)
      twice)  */
   if (WSTOPSIG (*wstat) < __SIGRTMIN)
     {
-      struct pending_signals *sig;
-
-      for (sig = lwp->pending_signals_to_report;
-          sig != NULL;
-          sig = sig->prev)
+      for (const auto &sig : lwp->pending_signals_to_report)
        {
-         if (sig->signal == WSTOPSIG (*wstat))
+         if (sig.signal == WSTOPSIG (*wstat))
            {
-             if (debug_threads)
-               debug_printf ("Not requeuing already queued non-RT signal %d"
-                             " for LWP %ld\n",
-                             sig->signal,
-                             lwpid_of (thread));
+             threads_debug_printf
+               ("Not requeuing already queued non-RT signal %d for LWP %ld",
+                sig.signal, lwpid_of (thread));
              return;
            }
        }
     }
 
-  p_sig = XCNEW (struct pending_signals);
-  p_sig->prev = lwp->pending_signals_to_report;
-  p_sig->signal = WSTOPSIG (*wstat);
+  lwp->pending_signals_to_report.emplace_back (WSTOPSIG (*wstat));
 
   ptrace (PTRACE_GETSIGINFO, lwpid_of (thread), (PTRACE_TYPE_ARG3) 0,
-         &p_sig->info);
-
-  lwp->pending_signals_to_report = p_sig;
+         &lwp->pending_signals_to_report.back ().info);
 }
 
 /* Dequeue one signal from the "signals to report later when out of
@@ -2241,36 +2136,26 @@ dequeue_one_deferred_signal (struct lwp_info *lwp, int *wstat)
 {
   struct thread_info *thread = get_lwp_thread (lwp);
 
-  if (lwp->pending_signals_to_report != NULL)
+  if (!lwp->pending_signals_to_report.empty ())
     {
-      struct pending_signals **p_sig;
-
-      p_sig = &lwp->pending_signals_to_report;
-      while ((*p_sig)->prev != NULL)
-       p_sig = &(*p_sig)->prev;
+      const pending_signal &p_sig = lwp->pending_signals_to_report.front ();
 
-      *wstat = W_STOPCODE ((*p_sig)->signal);
-      if ((*p_sig)->info.si_signo != 0)
+      *wstat = W_STOPCODE (p_sig.signal);
+      if (p_sig.info.si_signo != 0)
        ptrace (PTRACE_SETSIGINFO, lwpid_of (thread), (PTRACE_TYPE_ARG3) 0,
-               &(*p_sig)->info);
-      free (*p_sig);
-      *p_sig = NULL;
+               &p_sig.info);
 
-      if (debug_threads)
-       debug_printf ("Reporting deferred signal %d for LWP %ld.\n",
-                     WSTOPSIG (*wstat), lwpid_of (thread));
+      lwp->pending_signals_to_report.pop_front ();
+
+      threads_debug_printf ("Reporting deferred signal %d for LWP %ld.",
+                           WSTOPSIG (*wstat), lwpid_of (thread));
 
       if (debug_threads)
        {
-         struct pending_signals *sig;
+         for (const auto &sig : lwp->pending_signals_to_report)
+           threads_debug_printf ("   Still queued %d", sig.signal);
 
-         for (sig = lwp->pending_signals_to_report;
-              sig != NULL;
-              sig = sig->prev)
-           debug_printf ("   Still queued %d\n",
-                         sig->signal);
-
-         debug_printf ("   (no more queued signals)\n");
+         threads_debug_printf ("   (no more queued signals)");
        }
 
       return 1;
@@ -2279,48 +2164,33 @@ dequeue_one_deferred_signal (struct lwp_info *lwp, int *wstat)
   return 0;
 }
 
-/* Fetch the possibly triggered data watchpoint info and store it in
-   CHILD.
-
-   On some archs, like x86, that use debug registers to set
-   watchpoints, it's possible that the way to know which watched
-   address trapped, is to check the register that is used to select
-   which address to watch.  Problem is, between setting the watchpoint
-   and reading back which data address trapped, the user may change
-   the set of watchpoints, and, as a consequence, GDB changes the
-   debug registers in the inferior.  To avoid reading back a stale
-   stopped-data-address when that happens, we cache in LP the fact
-   that a watchpoint trapped, and the corresponding data address, as
-   soon as we see CHILD stop with a SIGTRAP.  If GDB changes the debug
-   registers meanwhile, we have the cached data we can rely on.  */
-
-static int
-check_stopped_by_watchpoint (struct lwp_info *child)
+bool
+linux_process_target::check_stopped_by_watchpoint (lwp_info *child)
 {
-  if (the_low_target.stopped_by_watchpoint != NULL)
-    {
-      struct thread_info *saved_thread;
+  scoped_restore_current_thread restore_thread;
+  switch_to_thread (get_lwp_thread (child));
 
-      saved_thread = current_thread;
-      current_thread = get_lwp_thread (child);
-
-      if (the_low_target.stopped_by_watchpoint ())
-       {
-         child->stop_reason = TARGET_STOPPED_BY_WATCHPOINT;
-
-         if (the_low_target.stopped_data_address != NULL)
-           child->stopped_data_address
-             = the_low_target.stopped_data_address ();
-         else
-           child->stopped_data_address = 0;
-       }
-
-      current_thread = saved_thread;
+  if (low_stopped_by_watchpoint ())
+    {
+      child->stop_reason = TARGET_STOPPED_BY_WATCHPOINT;
+      child->stopped_data_address = low_stopped_data_address ();
     }
 
   return child->stop_reason == TARGET_STOPPED_BY_WATCHPOINT;
 }
 
+bool
+linux_process_target::low_stopped_by_watchpoint ()
+{
+  return false;
+}
+
+CORE_ADDR
+linux_process_target::low_stopped_data_address ()
+{
+  return 0;
+}
+
 /* Return the ptrace options that we want to try to enable.  */
 
 static int
@@ -2346,12 +2216,8 @@ linux_low_ptrace_options (int attached)
   return options;
 }
 
-/* Do low-level handling of the event, and check if we should go on
-   and pass it to caller code.  Return the affected lwp if we are, or
-   NULL otherwise.  */
-
-static struct lwp_info *
-linux_low_filter_event (int lwpid, int wstat)
+void
+linux_process_target::filter_event (int lwpid, int wstat)
 {
   client_state &cs = get_client_state ();
   struct lwp_info *child;
@@ -2360,49 +2226,65 @@ linux_low_filter_event (int lwpid, int wstat)
 
   child = find_lwp_pid (ptid_t (lwpid));
 
-  /* Check for stop events reported by a process we didn't already
-     know about - anything not already in our LWP list.
-
-     If we're expecting to receive stopped processes after
-     fork, vfork, and clone events, then we'll just add the
-     new one to our list and go back to waiting for the event
-     to be reported - the stopped process might be returned
-     from waitpid before or after the event is.
-
-     But note the case of a non-leader thread exec'ing after the
-     leader having exited, and gone from our lists (because
-     check_zombie_leaders deleted it).  The non-leader thread
-     changes its tid to the tgid.  */
-
-  if (WIFSTOPPED (wstat) && child == NULL && WSTOPSIG (wstat) == SIGTRAP
-      && linux_ptrace_get_extended_event (wstat) == PTRACE_EVENT_EXEC)
+  /* Check for events reported by anything not in our LWP list.  */
+  if (child == nullptr)
     {
-      ptid_t child_ptid;
-
-      /* A multi-thread exec after we had seen the leader exiting.  */
-      if (debug_threads)
+      if (WIFSTOPPED (wstat))
        {
-         debug_printf ("LLW: Re-adding thread group leader LWP %d"
-                       "after exec.\n", lwpid);
+         if (WSTOPSIG (wstat) == SIGTRAP
+             && linux_ptrace_get_extended_event (wstat) == PTRACE_EVENT_EXEC)
+           {
+             /* A non-leader thread exec'ed after we've seen the
+                leader zombie, and removed it from our lists (in
+                check_zombie_leaders).  The non-leader thread changes
+                its tid to the tgid.  */
+             threads_debug_printf
+               ("Re-adding thread group leader LWP %d after exec.",
+                lwpid);
+
+             child = add_lwp (ptid_t (lwpid, lwpid));
+             child->stopped = 1;
+             switch_to_thread (child->thread);
+           }
+         else
+           {
+             /* A process we are controlling has forked and the new
+                child's stop was reported to us by the kernel.  Save
+                its PID and go back to waiting for the fork event to
+                be reported - the stopped process might be returned
+                from waitpid before or after the fork event is.  */
+             threads_debug_printf
+               ("Saving LWP %d status %s in stopped_pids list",
+                lwpid, status_to_str (wstat).c_str ());
+             add_to_pid_list (&stopped_pids, lwpid, wstat);
+           }
        }
+      else
+       {
+         /* Don't report an event for the exit of an LWP not in our
+            list, i.e. not part of any inferior we're debugging.
+            This can happen if we detach from a program we originally
+            forked and then it exits.  However, note that we may have
+            earlier deleted a leader of an inferior we're debugging,
+            in check_zombie_leaders.  Re-add it back here if so.  */
+         find_process ([&] (process_info *proc)
+           {
+             if (proc->pid == lwpid)
+               {
+                 threads_debug_printf
+                   ("Re-adding thread group leader LWP %d after exit.",
+                    lwpid);
 
-      child_ptid = ptid_t (lwpid, lwpid, 0);
-      child = add_lwp (child_ptid);
-      child->stopped = 1;
-      current_thread = child->thread;
-    }
+                 child = add_lwp (ptid_t (lwpid, lwpid));
+                 return true;
+               }
+             return false;
+           });
+       }
 
-  /* If we didn't find a process, one of two things presumably happened:
-     - A process we started and then detached from has exited.  Ignore it.
-     - A process we are controlling has forked and the new child's stop
-     was reported to us by the kernel.  Save its PID.  */
-  if (child == NULL && WIFSTOPPED (wstat))
-    {
-      add_to_pid_list (&stopped_pids, lwpid, wstat);
-      return NULL;
+      if (child == nullptr)
+       return;
     }
-  else if (child == NULL)
-    return NULL;
 
   thread = get_lwp_thread (child);
 
@@ -2413,8 +2295,7 @@ linux_low_filter_event (int lwpid, int wstat)
   /* Check if the thread has exited.  */
   if ((WIFEXITED (wstat) || WIFSIGNALED (wstat)))
     {
-      if (debug_threads)
-       debug_printf ("LLFE: %d exited.\n", lwpid);
+      threads_debug_printf ("%d exited", lwpid);
 
       if (finish_step_over (child))
        {
@@ -2422,22 +2303,21 @@ linux_low_filter_event (int lwpid, int wstat)
          unsuspend_all_lwps (child);
        }
 
-      /* If there is at least one more LWP, then the exit signal was
-        not the end of the debugged application and should be
-        ignored, unless GDB wants to hear about thread exits.  */
-      if (cs.report_thread_events
-         || last_thread_of_process_p (pid_of (thread)))
+      /* If this is not the leader LWP, then the exit signal was not
+        the end of the debugged application and should be ignored,
+        unless GDB wants to hear about thread exits.  */
+      if (cs.report_thread_events || is_leader (thread))
        {
          /* Since events are serialized to GDB core, and we can't
             report this one right now.  Leave the status pending for
             the next time we're able to report it.  */
          mark_lwp_dead (child, wstat);
-         return child;
+         return;
        }
       else
        {
          delete_lwp (child);
-         return NULL;
+         return;
        }
     }
 
@@ -2456,7 +2336,7 @@ linux_low_filter_event (int lwpid, int wstat)
              /* This needs to happen after we have attached to the
                 inferior and it is stopped for the first time, but
                 before we access any inferior registers.  */
-             linux_arch_setup_thread (thread);
+             arch_setup_thread (thread);
            }
          else
            {
@@ -2465,7 +2345,7 @@ linux_low_filter_event (int lwpid, int wstat)
                 the first instruction.  */
              child->status_pending_p = 1;
              child->status_pending = wstat;
-             return child;
+             return;
            }
        }
     }
@@ -2504,7 +2384,7 @@ linux_low_filter_event (int lwpid, int wstat)
        {
          /* The event has been handled, so just return without
             reporting it.  */
-         return NULL;
+         return;
        }
     }
 
@@ -2520,102 +2400,83 @@ linux_low_filter_event (int lwpid, int wstat)
   if (WIFSTOPPED (wstat) && WSTOPSIG (wstat) == SIGSTOP
       && child->stop_expected)
     {
-      if (debug_threads)
-       debug_printf ("Expected stop.\n");
+      threads_debug_printf ("Expected stop.");
+
       child->stop_expected = 0;
 
       if (thread->last_resume_kind == resume_stop)
        {
          /* We want to report the stop to the core.  Treat the
             SIGSTOP as a normal event.  */
-         if (debug_threads)
-           debug_printf ("LLW: resume_stop SIGSTOP caught for %s.\n",
-                         target_pid_to_str (ptid_of (thread)));
+         threads_debug_printf ("resume_stop SIGSTOP caught for %s.",
+                               target_pid_to_str (ptid_of (thread)).c_str ());
        }
       else if (stopping_threads != NOT_STOPPING_THREADS)
        {
          /* Stopping threads.  We don't want this SIGSTOP to end up
             pending.  */
-         if (debug_threads)
-           debug_printf ("LLW: SIGSTOP caught for %s "
-                         "while stopping threads.\n",
-                         target_pid_to_str (ptid_of (thread)));
-         return NULL;
+         threads_debug_printf ("SIGSTOP caught for %s while stopping threads.",
+                               target_pid_to_str (ptid_of (thread)).c_str ());
+         return;
        }
       else
        {
          /* This is a delayed SIGSTOP.  Filter out the event.  */
-         if (debug_threads)
-           debug_printf ("LLW: %s %s, 0, 0 (discard delayed SIGSTOP)\n",
+         threads_debug_printf ("%s %s, 0, 0 (discard delayed SIGSTOP)",
                          child->stepping ? "step" : "continue",
-                         target_pid_to_str (ptid_of (thread)));
+                         target_pid_to_str (ptid_of (thread)).c_str ());
 
-         linux_resume_one_lwp (child, child->stepping, 0, NULL);
-         return NULL;
+         resume_one_lwp (child, child->stepping, 0, NULL);
+         return;
        }
     }
 
   child->status_pending_p = 1;
   child->status_pending = wstat;
-  return child;
+  return;
 }
 
-/* Return true if THREAD is doing hardware single step.  */
-
-static int
-maybe_hw_step (struct thread_info *thread)
+bool
+linux_process_target::maybe_hw_step (thread_info *thread)
 {
-  if (can_hardware_single_step ())
-    return 1;
+  if (supports_hardware_single_step ())
+    return true;
   else
     {
       /* GDBserver must insert single-step breakpoint for software
         single step.  */
       gdb_assert (has_single_step_breakpoints (thread));
-      return 0;
+      return false;
     }
 }
 
-/* Resume LWPs that are currently stopped without any pending status
-   to report, but are resumed from the core's perspective.  */
-
-static void
-resume_stopped_resumed_lwps (thread_info *thread)
+void
+linux_process_target::resume_stopped_resumed_lwps (thread_info *thread)
 {
   struct lwp_info *lp = get_thread_lwp (thread);
 
   if (lp->stopped
       && !lp->suspended
       && !lp->status_pending_p
-      && thread->last_status.kind == TARGET_WAITKIND_IGNORE)
+      && thread->last_status.kind () == TARGET_WAITKIND_IGNORE)
     {
       int step = 0;
 
       if (thread->last_resume_kind == resume_step)
        step = maybe_hw_step (thread);
 
-      if (debug_threads)
-       debug_printf ("RSRL: resuming stopped-resumed LWP %s at %s: step=%d\n",
-                     target_pid_to_str (ptid_of (thread)),
-                     paddress (lp->stop_pc),
-                     step);
+      threads_debug_printf ("resuming stopped-resumed LWP %s at %s: step=%d",
+                           target_pid_to_str (ptid_of (thread)).c_str (),
+                           paddress (lp->stop_pc), step);
 
-      linux_resume_one_lwp (lp, step, GDB_SIGNAL_0, NULL);
+      resume_one_lwp (lp, step, GDB_SIGNAL_0, NULL);
     }
 }
 
-/* Wait for an event from child(ren) WAIT_PTID, and return any that
-   match FILTER_PTID (leaving others pending).  The PTIDs can be:
-   minus_one_ptid, to specify any child; a pid PTID, specifying all
-   lwps of a thread group; or a PTID representing a single lwp.  Store
-   the stop status through the status pointer WSTAT.  OPTIONS is
-   passed to the waitpid call.  Return 0 if no event was found and
-   OPTIONS contains WNOHANG.  Return -1 if no unwaited-for children
-   was found.  Return the PID of the stopped child otherwise.  */
-
-static int
-linux_wait_for_event_filtered (ptid_t wait_ptid, ptid_t filter_ptid,
-                              int *wstatp, int options)
+int
+linux_process_target::wait_for_event_filtered (ptid_t wait_ptid,
+                                              ptid_t filter_ptid,
+                                              int *wstatp, int options)
 {
   struct thread_info *event_thread;
   struct lwp_info *event_child, *requested_child;
@@ -2638,9 +2499,10 @@ linux_wait_for_event_filtered (ptid_t wait_ptid, ptid_t filter_ptid,
        });
 
       if (event_thread != NULL)
-       event_child = get_thread_lwp (event_thread);
-      if (debug_threads && event_thread)
-       debug_printf ("Got a pending child %ld\n", lwpid_of (event_thread));
+       {
+         event_child = get_thread_lwp (event_thread);
+         threads_debug_printf ("Got a pending child %ld", lwpid_of (event_thread));
+       }
     }
   else if (filter_ptid != null_ptid)
     {
@@ -2655,14 +2517,13 @@ linux_wait_for_event_filtered (ptid_t wait_ptid, ptid_t filter_ptid,
                                       &requested_child->status_pending);
          requested_child->status_pending_p = 0;
          requested_child->status_pending = 0;
-         linux_resume_one_lwp (requested_child, 0, 0, NULL);
+         resume_one_lwp (requested_child, 0, 0, NULL);
        }
 
       if (requested_child->suspended
          && requested_child->status_pending_p)
        {
-         internal_error (__FILE__, __LINE__,
-                         "requesting an event out of a"
+         internal_error ("requesting an event out of a"
                          " suspended child?");
        }
 
@@ -2675,13 +2536,14 @@ linux_wait_for_event_filtered (ptid_t wait_ptid, ptid_t filter_ptid,
 
   if (event_child != NULL)
     {
-      if (debug_threads)
-       debug_printf ("Got an event from pending child %ld (%04x)\n",
-                     lwpid_of (event_thread), event_child->status_pending);
+      threads_debug_printf ("Got an event from pending child %ld (%04x)",
+                           lwpid_of (event_thread),
+                           event_child->status_pending);
+
       *wstatp = event_child->status_pending;
       event_child->status_pending_p = 0;
       event_child->status_pending = 0;
-      current_thread = event_thread;
+      switch_to_thread (event_thread);
       return lwpid_of (event_thread);
     }
 
@@ -2719,22 +2581,18 @@ linux_wait_for_event_filtered (ptid_t wait_ptid, ptid_t filter_ptid,
       errno = 0;
       ret = my_waitpid (-1, wstatp, options | WNOHANG);
 
-      if (debug_threads)
-       debug_printf ("LWFE: waitpid(-1, ...) returned %d, %s\n",
-                     ret, errno ? safe_strerror (errno) : "ERRNO-OK");
+      threads_debug_printf ("waitpid(-1, ...) returned %d, %s",
+                           ret, errno ? safe_strerror (errno) : "ERRNO-OK");
 
       if (ret > 0)
        {
-         if (debug_threads)
-           {
-             debug_printf ("LLW: waitpid %ld received %s\n",
-                           (long) ret, status_to_str (*wstatp));
-           }
+         threads_debug_printf ("waitpid %ld received %s",
+                               (long) ret, status_to_str (*wstatp).c_str ());
 
          /* Filter all events.  IOW, leave all events pending.  We'll
             randomly select an event LWP out of all that have events
             below.  */
-         linux_low_filter_event (ret, *wstatp);
+         filter_event (ret, *wstatp);
          /* Retry until nothing comes out of waitpid.  A single
             SIGCHLD can indicate more than one child stopped.  */
          continue;
@@ -2743,7 +2601,10 @@ linux_wait_for_event_filtered (ptid_t wait_ptid, ptid_t filter_ptid,
       /* Now that we've pulled all events out of the kernel, resume
         LWPs that don't have an interesting event to report.  */
       if (stopping_threads == NOT_STOPPING_THREADS)
-       for_each_thread (resume_stopped_resumed_lwps);
+       for_each_thread ([this] (thread_info *thread)
+         {
+           resume_stopped_resumed_lwps (thread);
+         });
 
       /* ... and find an LWP with a status to report to the core, if
         any.  */
@@ -2779,8 +2640,8 @@ linux_wait_for_event_filtered (ptid_t wait_ptid, ptid_t filter_ptid,
         over 0 (below), as it is more detailed.  */
       if (find_thread (not_stopped) == NULL)
        {
-         if (debug_threads)
-           debug_printf ("LLW: exit (no unwaited-for LWP)\n");
+         threads_debug_printf ("exit (no unwaited-for LWP)");
+
          gdb_sigmask (SIG_SETMASK, &prev_mask, NULL);
          return -1;
        }
@@ -2788,16 +2649,14 @@ linux_wait_for_event_filtered (ptid_t wait_ptid, ptid_t filter_ptid,
       /* No interesting event to report to the caller.  */
       if ((options & WNOHANG))
        {
-         if (debug_threads)
-           debug_printf ("WNOHANG set, no event found\n");
+         threads_debug_printf ("WNOHANG set, no event found");
 
          gdb_sigmask (SIG_SETMASK, &prev_mask, NULL);
          return 0;
        }
 
       /* Block until we get an event reported with SIGCHLD.  */
-      if (debug_threads)
-       debug_printf ("sigsuspend'ing\n");
+      threads_debug_printf ("sigsuspend'ing");
 
       sigsuspend (&prev_mask);
       gdb_sigmask (SIG_SETMASK, &prev_mask, NULL);
@@ -2806,23 +2665,15 @@ linux_wait_for_event_filtered (ptid_t wait_ptid, ptid_t filter_ptid,
 
   gdb_sigmask (SIG_SETMASK, &prev_mask, NULL);
 
-  current_thread = event_thread;
+  switch_to_thread (event_thread);
 
   return lwpid_of (event_thread);
 }
 
-/* Wait for an event from child(ren) PTID.  PTIDs can be:
-   minus_one_ptid, to specify any child; a pid PTID, specifying all
-   lwps of a thread group; or a PTID representing a single lwp.  Store
-   the stop status through the status pointer WSTAT.  OPTIONS is
-   passed to the waitpid call.  Return 0 if no event was found and
-   OPTIONS contains WNOHANG.  Return -1 if no unwaited-for children
-   was found.  Return the PID of the stopped child otherwise.  */
-
-static int
-linux_wait_for_event (ptid_t ptid, int *wstatp, int options)
+int
+linux_process_target::wait_for_event (ptid_t ptid, int *wstatp, int options)
 {
-  return linux_wait_for_event_filtered (ptid, ptid, wstatp, options);
+  return wait_for_event_filtered (ptid, ptid, wstatp, options);
 }
 
 /* Select one LWP out of those that have events pending.  */
@@ -2846,29 +2697,27 @@ select_event_lwp (struct lwp_info **orig_lp)
        {
          lwp_info *lp = get_thread_lwp (thread);
 
-         return (thread->last_status.kind == TARGET_WAITKIND_IGNORE
+         return (thread->last_status.kind () == TARGET_WAITKIND_IGNORE
                  && thread->last_resume_kind == resume_step
                  && lp->status_pending_p);
        });
 
       if (event_thread != NULL)
-       {
-         if (debug_threads)
-           debug_printf ("SEL: Select single-step %s\n",
-                         target_pid_to_str (ptid_of (event_thread)));
-       }
+       threads_debug_printf
+         ("Select single-step %s",
+          target_pid_to_str (ptid_of (event_thread)).c_str ());
     }
   if (event_thread == NULL)
     {
       /* No single-stepping LWP.  Select one at random, out of those
-         which have had events.  */
+        which have had events.  */
 
       event_thread = find_thread_in_random ([&] (thread_info *thread)
        {
          lwp_info *lp = get_thread_lwp (thread);
 
          /* Only resumed LWPs that have an event pending. */
-         return (thread->last_status.kind == TARGET_WAITKIND_IGNORE
+         return (thread->last_status.kind () == TARGET_WAITKIND_IGNORE
                  && lp->status_pending_p);
        });
     }
@@ -2897,12 +2746,7 @@ unsuspend_all_lwps (struct lwp_info *except)
     });
 }
 
-static void move_out_of_jump_pad_callback (thread_info *thread);
-static bool stuck_in_jump_pad_callback (thread_info *thread);
 static bool lwp_running (thread_info *thread);
-static ptid_t linux_wait_1 (ptid_t ptid,
-                           struct target_waitstatus *ourstatus,
-                           int target_options);
 
 /* Stabilize threads (move out of jump pads).
 
@@ -2937,22 +2781,27 @@ static ptid_t linux_wait_1 (ptid_t ptid,
 void
 linux_process_target::stabilize_threads ()
 {
-  thread_info *thread_stuck = find_thread (stuck_in_jump_pad_callback);
+  thread_info *thread_stuck = find_thread ([this] (thread_info *thread)
+                               {
+                                 return stuck_in_jump_pad (thread);
+                               });
 
   if (thread_stuck != NULL)
     {
-      if (debug_threads)
-       debug_printf ("can't stabilize, LWP %ld is stuck in jump pad\n",
-                     lwpid_of (thread_stuck));
+      threads_debug_printf ("can't stabilize, LWP %ld is stuck in jump pad",
+                           lwpid_of (thread_stuck));
       return;
     }
 
-  thread_info *saved_thread = current_thread;
+  scoped_restore_current_thread restore_thread;
 
   stabilizing_threads = 1;
 
   /* Kick 'em all.  */
-  for_each_thread (move_out_of_jump_pad_callback);
+  for_each_thread ([this] (thread_info *thread)
+    {
+      move_out_of_jump_pad (thread);
+    });
 
   /* Loop until all are stopped out of the jump pads.  */
   while (find_thread (lwp_running) != NULL)
@@ -2964,19 +2813,19 @@ linux_process_target::stabilize_threads ()
       /* Note that we go through the full wait even loop.  While
         moving threads out of jump pad, we need to be able to step
         over internal breakpoints and such.  */
-      linux_wait_1 (minus_one_ptid, &ourstatus, 0);
+      wait_1 (minus_one_ptid, &ourstatus, 0);
 
-      if (ourstatus.kind == TARGET_WAITKIND_STOPPED)
+      if (ourstatus.kind () == TARGET_WAITKIND_STOPPED)
        {
          lwp = get_thread_lwp (current_thread);
 
          /* Lock it.  */
          lwp_suspended_inc (lwp);
 
-         if (ourstatus.value.sig != GDB_SIGNAL_0
+         if (ourstatus.sig () != GDB_SIGNAL_0
              || current_thread->last_resume_kind == resume_stop)
            {
-             wstat = W_STOPCODE (gdb_signal_to_host (ourstatus.value.sig));
+             wstat = W_STOPCODE (gdb_signal_to_host (ourstatus.sig ()));
              enqueue_one_deferred_signal (lwp, &wstat);
            }
        }
@@ -2986,15 +2835,17 @@ linux_process_target::stabilize_threads ()
 
   stabilizing_threads = 0;
 
-  current_thread = saved_thread;
-
   if (debug_threads)
     {
-      thread_stuck = find_thread (stuck_in_jump_pad_callback);
+      thread_stuck = find_thread ([this] (thread_info *thread)
+                      {
+                        return stuck_in_jump_pad (thread);
+                      });
 
       if (thread_stuck != NULL)
-       debug_printf ("couldn't stabilize, LWP %ld got stuck in jump pad\n",
-                     lwpid_of (thread_stuck));
+       threads_debug_printf
+         ("couldn't stabilize, LWP %ld got stuck in jump pad",
+          lwpid_of (thread_stuck));
     }
 }
 
@@ -3009,29 +2860,24 @@ ignore_event (struct target_waitstatus *ourstatus)
      another target_wait call.  */
   async_file_mark ();
 
-  ourstatus->kind = TARGET_WAITKIND_IGNORE;
+  ourstatus->set_ignore ();
   return null_ptid;
 }
 
-/* Convenience function that is called when the kernel reports an exit
-   event.  This decides whether to report the event to GDB as a
-   process exit event, a thread exit event, or to suppress the
-   event.  */
-
-static ptid_t
-filter_exit_event (struct lwp_info *event_child,
-                  struct target_waitstatus *ourstatus)
+ptid_t
+linux_process_target::filter_exit_event (lwp_info *event_child,
+                                        target_waitstatus *ourstatus)
 {
   client_state &cs = get_client_state ();
   struct thread_info *thread = get_lwp_thread (event_child);
   ptid_t ptid = ptid_of (thread);
 
-  if (!last_thread_of_process_p (pid_of (thread)))
+  if (!is_leader (thread))
     {
       if (cs.report_thread_events)
-       ourstatus->kind = TARGET_WAITKIND_THREAD_EXITED;
+       ourstatus->set_thread_exited (0);
       else
-       ourstatus->kind = TARGET_WAITKIND_IGNORE;
+       ourstatus->set_ignore ();
 
       delete_lwp (event_child);
     }
@@ -3049,37 +2895,34 @@ gdb_catching_syscalls_p (struct lwp_info *event_child)
   return !proc->syscalls_to_catch.empty ();
 }
 
-/* Returns 1 if GDB is interested in the event_child syscall.
-   Only to be called when stopped reason is SYSCALL_SIGTRAP.  */
-
-static int
-gdb_catch_this_syscall_p (struct lwp_info *event_child)
+bool
+linux_process_target::gdb_catch_this_syscall (lwp_info *event_child)
 {
   int sysno;
   struct thread_info *thread = get_lwp_thread (event_child);
   struct process_info *proc = get_thread_process (thread);
 
   if (proc->syscalls_to_catch.empty ())
-    return 0;
+    return false;
 
   if (proc->syscalls_to_catch[0] == ANY_SYSCALL)
-    return 1;
+    return true;
 
   get_syscall_trapinfo (event_child, &sysno);
 
   for (int iter : proc->syscalls_to_catch)
     if (iter == sysno)
-      return 1;
+      return true;
 
-  return 0;
+  return false;
 }
 
-/* Wait for process, returns status.  */
-
-static ptid_t
-linux_wait_1 (ptid_t ptid,
-             struct target_waitstatus *ourstatus, int target_options)
+ptid_t
+linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus,
+                             target_wait_flags target_options)
 {
+  THREADS_SCOPED_DEBUG_ENTER_EXIT;
+
   client_state &cs = get_client_state ();
   int w;
   struct lwp_info *event_child;
@@ -3093,11 +2936,7 @@ linux_wait_1 (ptid_t ptid,
   int in_step_range;
   int any_resumed;
 
-  if (debug_threads)
-    {
-      debug_enter ();
-      debug_printf ("linux_wait_1: [%s]\n", target_pid_to_str (ptid));
-    }
+  threads_debug_printf ("[%s]", target_pid_to_str (ptid).c_str ());
 
   /* Translate generic target options into linux options.  */
   options = __WALL;
@@ -3107,7 +2946,7 @@ linux_wait_1 (ptid_t ptid,
   bp_explains_trap = 0;
   trace_event = 0;
   in_step_range = 0;
-  ourstatus->kind = TARGET_WAITKIND_IGNORE;
+  ourstatus->set_ignore ();
 
   auto status_pending_p_any = [&] (thread_info *thread)
     {
@@ -3128,78 +2967,57 @@ linux_wait_1 (ptid_t ptid,
     any_resumed = 0;
 
   if (step_over_bkpt == null_ptid)
-    pid = linux_wait_for_event (ptid, &w, options);
+    pid = wait_for_event (ptid, &w, options);
   else
     {
-      if (debug_threads)
-       debug_printf ("step_over_bkpt set [%s], doing a blocking wait\n",
-                     target_pid_to_str (step_over_bkpt));
-      pid = linux_wait_for_event (step_over_bkpt, &w, options & ~WNOHANG);
+      threads_debug_printf ("step_over_bkpt set [%s], doing a blocking wait",
+                           target_pid_to_str (step_over_bkpt).c_str ());
+      pid = wait_for_event (step_over_bkpt, &w, options & ~WNOHANG);
     }
 
   if (pid == 0 || (pid == -1 && !any_resumed))
     {
       gdb_assert (target_options & TARGET_WNOHANG);
 
-      if (debug_threads)
-       {
-         debug_printf ("linux_wait_1 ret = null_ptid, "
-                       "TARGET_WAITKIND_IGNORE\n");
-         debug_exit ();
-       }
+      threads_debug_printf ("ret = null_ptid, TARGET_WAITKIND_IGNORE");
 
-      ourstatus->kind = TARGET_WAITKIND_IGNORE;
+      ourstatus->set_ignore ();
       return null_ptid;
     }
   else if (pid == -1)
     {
-      if (debug_threads)
-       {
-         debug_printf ("linux_wait_1 ret = null_ptid, "
-                       "TARGET_WAITKIND_NO_RESUMED\n");
-         debug_exit ();
-       }
+      threads_debug_printf ("ret = null_ptid, TARGET_WAITKIND_NO_RESUMED");
 
-      ourstatus->kind = TARGET_WAITKIND_NO_RESUMED;
+      ourstatus->set_no_resumed ();
       return null_ptid;
     }
 
   event_child = get_thread_lwp (current_thread);
 
-  /* linux_wait_for_event only returns an exit status for the last
+  /* wait_for_event only returns an exit status for the last
      child of a process.  Report it.  */
   if (WIFEXITED (w) || WIFSIGNALED (w))
     {
       if (WIFEXITED (w))
        {
-         ourstatus->kind = TARGET_WAITKIND_EXITED;
-         ourstatus->value.integer = WEXITSTATUS (w);
+         ourstatus->set_exited (WEXITSTATUS (w));
 
-         if (debug_threads)
-           {
-             debug_printf ("linux_wait_1 ret = %s, exited with "
-                           "retcode %d\n",
-                           target_pid_to_str (ptid_of (current_thread)),
-                           WEXITSTATUS (w));
-             debug_exit ();
-           }
+         threads_debug_printf
+           ("ret = %s, exited with retcode %d",
+            target_pid_to_str (ptid_of (current_thread)).c_str (),
+            WEXITSTATUS (w));
        }
       else
        {
-         ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
-         ourstatus->value.sig = gdb_signal_from_host (WTERMSIG (w));
+         ourstatus->set_signalled (gdb_signal_from_host (WTERMSIG (w)));
 
-         if (debug_threads)
-           {
-             debug_printf ("linux_wait_1 ret = %s, terminated with "
-                           "signal %d\n",
-                           target_pid_to_str (ptid_of (current_thread)),
-                           WTERMSIG (w));
-             debug_exit ();
-           }
+         threads_debug_printf
+           ("ret = %s, terminated with signal %d",
+            target_pid_to_str (ptid_of (current_thread)).c_str (),
+            WTERMSIG (w));
        }
 
-      if (ourstatus->kind == TARGET_WAITKIND_EXITED)
+      if (ourstatus->kind () == TARGET_WAITKIND_EXITED)
        return filter_exit_event (event_child, ourstatus);
 
       return ptid_of (current_thread);
@@ -3225,15 +3043,12 @@ linux_wait_1 (ptid_t ptid,
       int breakpoint_kind = 0;
       CORE_ADDR stop_pc = event_child->stop_pc;
 
-      breakpoint_kind =
-       the_target->pt->breakpoint_kind_from_current_state (&stop_pc);
-      the_target->pt->sw_breakpoint_from_kind (breakpoint_kind, &increment_pc);
+      breakpoint_kind = breakpoint_kind_from_current_state (&stop_pc);
+      sw_breakpoint_from_kind (breakpoint_kind, &increment_pc);
 
-      if (debug_threads)
-       {
-         debug_printf ("step-over for %s executed software breakpoint\n",
-                       target_pid_to_str (ptid_of (current_thread)));
-       }
+      threads_debug_printf
+       ("step-over for %s executed software breakpoint",
+        target_pid_to_str (ptid_of (current_thread)).c_str ());
 
       if (increment_pc != 0)
        {
@@ -3241,9 +3056,9 @@ linux_wait_1 (ptid_t ptid,
            = get_thread_regcache (current_thread, 1);
 
          event_child->stop_pc += increment_pc;
-         (*the_low_target.set_pc) (regcache, event_child->stop_pc);
+         low_set_pc (regcache, event_child->stop_pc);
 
-         if (!(*the_low_target.breakpoint_at) (event_child->stop_pc))
+         if (!low_breakpoint_at (event_child->stop_pc))
            event_child->stop_reason = TARGET_STOPPED_BY_NO_REASON;
        }
     }
@@ -3254,11 +3069,11 @@ linux_wait_1 (ptid_t ptid,
      not support internal breakpoints at all, we also report the
      SIGTRAP without further processing; it's of no concern to us.  */
   maybe_internal_trap
-    = (supports_breakpoints ()
+    = (low_supports_breakpoints ()
        && (WSTOPSIG (w) == SIGTRAP
           || ((WSTOPSIG (w) == SIGILL
                || WSTOPSIG (w) == SIGSEGV)
-              && (*the_low_target.breakpoint_at) (event_child->stop_pc))));
+              && low_breakpoint_at (event_child->stop_pc))));
 
   if (maybe_internal_trap)
     {
@@ -3286,10 +3101,7 @@ linux_wait_1 (ptid_t ptid,
       trace_event = handle_tracepoints (event_child);
 
       if (bp_explains_trap)
-       {
-         if (debug_threads)
-           debug_printf ("Hit a gdbserver breakpoint.\n");
-       }
+       threads_debug_printf ("Hit a gdbserver breakpoint.");
     }
   else
     {
@@ -3310,10 +3122,9 @@ linux_wait_1 (ptid_t ptid,
       && supports_fast_tracepoints ()
       && agent_loaded_p ())
     {
-      if (debug_threads)
-       debug_printf ("Got signal %d for LWP %ld.  Check if we need "
-                     "to defer or adjust it.\n",
-                     WSTOPSIG (w), lwpid_of (current_thread));
+      threads_debug_printf ("Got signal %d for LWP %ld.  Check if we need "
+                           "to defer or adjust it.",
+                           WSTOPSIG (w), lwpid_of (current_thread));
 
       /* Allow debugging the jump pad itself.  */
       if (current_thread->last_resume_kind != resume_step
@@ -3321,14 +3132,11 @@ linux_wait_1 (ptid_t ptid,
        {
          enqueue_one_deferred_signal (event_child, &w);
 
-         if (debug_threads)
-           debug_printf ("Signal %d for LWP %ld deferred (in jump pad)\n",
-                         WSTOPSIG (w), lwpid_of (current_thread));
+         threads_debug_printf ("Signal %d for LWP %ld deferred (in jump pad)",
+                               WSTOPSIG (w), lwpid_of (current_thread));
 
-         linux_resume_one_lwp (event_child, 0, 0, NULL);
+         resume_one_lwp (event_child, 0, 0, NULL);
 
-         if (debug_threads)
-           debug_exit ();
          return ignore_event (ourstatus);
        }
     }
@@ -3336,11 +3144,11 @@ linux_wait_1 (ptid_t ptid,
   if (event_child->collecting_fast_tracepoint
       != fast_tpoint_collect_result::not_collecting)
     {
-      if (debug_threads)
-       debug_printf ("LWP %ld was trying to move out of the jump pad (%d). "
-                     "Check if we're already there.\n",
-                     lwpid_of (current_thread),
-                     (int) event_child->collecting_fast_tracepoint);
+      threads_debug_printf
+       ("LWP %ld was trying to move out of the jump pad (%d). "
+        "Check if we're already there.",
+        lwpid_of (current_thread),
+        (int) event_child->collecting_fast_tracepoint);
 
       trace_event = 1;
 
@@ -3353,9 +3161,9 @@ linux_wait_1 (ptid_t ptid,
          /* No longer need this breakpoint.  */
          if (event_child->exit_jump_pad_bkpt != NULL)
            {
-             if (debug_threads)
-               debug_printf ("No longer need exit-jump-pad bkpt; removing it."
-                             "stopping all threads momentarily.\n");
+             threads_debug_printf
+               ("No longer need exit-jump-pad bkpt; removing it."
+                "stopping all threads momentarily.");
 
              /* Other running threads could hit this breakpoint.
                 We don't handle moribund locations like GDB does,
@@ -3378,33 +3186,23 @@ linux_wait_1 (ptid_t ptid,
       if (event_child->collecting_fast_tracepoint
          == fast_tpoint_collect_result::not_collecting)
        {
-         if (debug_threads)
-           debug_printf ("fast tracepoint finished "
-                         "collecting successfully.\n");
+         threads_debug_printf
+           ("fast tracepoint finished collecting successfully.");
 
          /* We may have a deferred signal to report.  */
          if (dequeue_one_deferred_signal (event_child, &w))
-           {
-             if (debug_threads)
-               debug_printf ("dequeued one signal.\n");
-           }
+           threads_debug_printf ("dequeued one signal.");
          else
            {
-             if (debug_threads)
-               debug_printf ("no deferred signals.\n");
+             threads_debug_printf ("no deferred signals.");
 
              if (stabilizing_threads)
                {
-                 ourstatus->kind = TARGET_WAITKIND_STOPPED;
-                 ourstatus->value.sig = GDB_SIGNAL_0;
+                 ourstatus->set_stopped (GDB_SIGNAL_0);
 
-                 if (debug_threads)
-                   {
-                     debug_printf ("linux_wait_1 ret = %s, stopped "
-                                   "while stabilizing threads\n",
-                                   target_pid_to_str (ptid_of (current_thread)));
-                     debug_exit ();
-                   }
+                 threads_debug_printf
+                   ("ret = %s, stopped while stabilizing threads",
+                    target_pid_to_str (ptid_of (current_thread)).c_str ());
 
                  return ptid_of (current_thread);
                }
@@ -3417,19 +3215,13 @@ linux_wait_1 (ptid_t ptid,
   /* Check if GDB is interested in this syscall.  */
   if (WIFSTOPPED (w)
       && WSTOPSIG (w) == SYSCALL_SIGTRAP
-      && !gdb_catch_this_syscall_p (event_child))
+      && !gdb_catch_this_syscall (event_child))
     {
-      if (debug_threads)
-       {
-         debug_printf ("Ignored syscall for LWP %ld.\n",
-                       lwpid_of (current_thread));
-       }
+      threads_debug_printf ("Ignored syscall for LWP %ld.",
+                           lwpid_of (current_thread));
 
-      linux_resume_one_lwp (event_child, event_child->stepping,
-                           0, NULL);
+      resume_one_lwp (event_child, event_child->stepping, 0, NULL);
 
-      if (debug_threads)
-       debug_exit ();
       return ignore_event (ourstatus);
     }
 
@@ -3457,9 +3249,8 @@ linux_wait_1 (ptid_t ptid,
     {
       siginfo_t info, *info_p;
 
-      if (debug_threads)
-       debug_printf ("Ignored signal %d for LWP %ld.\n",
-                     WSTOPSIG (w), lwpid_of (current_thread));
+      threads_debug_printf ("Ignored signal %d for LWP %ld.",
+                           WSTOPSIG (w), lwpid_of (current_thread));
 
       if (ptrace (PTRACE_GETSIGINFO, lwpid_of (current_thread),
                  (PTRACE_TYPE_ARG3) 0, &info) == 0)
@@ -3482,13 +3273,10 @@ linux_wait_1 (ptid_t ptid,
        }
       else
        {
-         linux_resume_one_lwp (event_child, event_child->stepping,
-                               WSTOPSIG (w), info_p);
+         resume_one_lwp (event_child, event_child->stepping,
+                         WSTOPSIG (w), info_p);
        }
 
-      if (debug_threads)
-       debug_exit ();
-
       return ignore_event (ourstatus);
     }
 
@@ -3522,7 +3310,7 @@ linux_wait_1 (ptid_t ptid,
                   || (gdb_breakpoint_here (event_child->stop_pc)
                       && gdb_condition_true_at_breakpoint (event_child->stop_pc)
                       && gdb_no_commands_at_breakpoint (event_child->stop_pc))
-                  || event_child->waitstatus.kind != TARGET_WAITKIND_IGNORE);
+                  || event_child->waitstatus.kind () != TARGET_WAITKIND_IGNORE);
 
   run_breakpoint_commands (event_child->stop_pc);
 
@@ -3531,30 +3319,30 @@ linux_wait_1 (ptid_t ptid,
      shouldn't know about.  */
   if (!report_to_gdb)
     {
-      if (debug_threads)
-       {
-         if (bp_explains_trap)
-           debug_printf ("Hit a gdbserver breakpoint.\n");
-         if (step_over_finished)
-           debug_printf ("Step-over finished.\n");
-         if (trace_event)
-           debug_printf ("Tracepoint event.\n");
-         if (lwp_in_step_range (event_child))
-           debug_printf ("Range stepping pc 0x%s [0x%s, 0x%s).\n",
-                         paddress (event_child->stop_pc),
-                         paddress (event_child->step_range_start),
-                         paddress (event_child->step_range_end));
-       }
+      if (bp_explains_trap)
+       threads_debug_printf ("Hit a gdbserver breakpoint.");
+
+      if (step_over_finished)
+       threads_debug_printf ("Step-over finished.");
+
+      if (trace_event)
+       threads_debug_printf ("Tracepoint event.");
+
+      if (lwp_in_step_range (event_child))
+       threads_debug_printf ("Range stepping pc 0x%s [0x%s, 0x%s).",
+                             paddress (event_child->stop_pc),
+                             paddress (event_child->step_range_start),
+                             paddress (event_child->step_range_end));
 
       /* We're not reporting this breakpoint to GDB, so apply the
         decr_pc_after_break adjustment to the inferior's regcache
         ourselves.  */
 
-      if (the_low_target.set_pc != NULL)
+      if (low_supports_breakpoints ())
        {
          struct regcache *regcache
            = get_thread_regcache (current_thread, 1);
-         (*the_low_target.set_pc) (regcache, event_child->stop_pc);
+         low_set_pc (regcache, event_child->stop_pc);
        }
 
       if (step_over_finished)
@@ -3571,7 +3359,7 @@ linux_wait_1 (ptid_t ptid,
          /* Remove the single-step breakpoints if any.  Note that
             there isn't single-step breakpoint if we finished stepping
             over.  */
-         if (can_software_single_step ()
+         if (supports_software_single_step ()
              && has_single_step_breakpoints (current_thread))
            {
              stop_all_lwps (0, event_child);
@@ -3580,45 +3368,41 @@ linux_wait_1 (ptid_t ptid,
            }
        }
 
-      if (debug_threads)
-       debug_printf ("proceeding all threads.\n");
-      proceed_all_lwps ();
+      threads_debug_printf ("proceeding all threads.");
 
-      if (debug_threads)
-       debug_exit ();
+      proceed_all_lwps ();
 
       return ignore_event (ourstatus);
     }
 
-  if (debug_threads)
-    {
-      if (event_child->waitstatus.kind != TARGET_WAITKIND_IGNORE)
-       {
-         std::string str
-           = target_waitstatus_to_string (&event_child->waitstatus);
+    if (debug_threads)
+      {
+       if (event_child->waitstatus.kind () != TARGET_WAITKIND_IGNORE)
+         threads_debug_printf ("LWP %ld: extended event with waitstatus %s",
+                               lwpid_of (get_lwp_thread (event_child)),
+                               event_child->waitstatus.to_string ().c_str ());
+
+       if (current_thread->last_resume_kind == resume_step)
+         {
+           if (event_child->step_range_start == event_child->step_range_end)
+             threads_debug_printf
+               ("GDB wanted to single-step, reporting event.");
+           else if (!lwp_in_step_range (event_child))
+             threads_debug_printf ("Out of step range, reporting event.");
+         }
+
+       if (event_child->stop_reason == TARGET_STOPPED_BY_WATCHPOINT)
+         threads_debug_printf ("Stopped by watchpoint.");
+       else if (gdb_breakpoint_here (event_child->stop_pc))
+         threads_debug_printf ("Stopped by GDB breakpoint.");
+      }
 
-         debug_printf ("LWP %ld: extended event with waitstatus %s\n",
-                       lwpid_of (get_lwp_thread (event_child)), str.c_str ());
-       }
-      if (current_thread->last_resume_kind == resume_step)
-       {
-         if (event_child->step_range_start == event_child->step_range_end)
-           debug_printf ("GDB wanted to single-step, reporting event.\n");
-         else if (!lwp_in_step_range (event_child))
-           debug_printf ("Out of step range, reporting event.\n");
-       }
-      if (event_child->stop_reason == TARGET_STOPPED_BY_WATCHPOINT)
-       debug_printf ("Stopped by watchpoint.\n");
-      else if (gdb_breakpoint_here (event_child->stop_pc))
-       debug_printf ("Stopped by GDB breakpoint.\n");
-      if (debug_threads)
-       debug_printf ("Hit a non-gdbserver trap event.\n");
-    }
+    threads_debug_printf ("Hit a non-gdbserver trap event.");
 
   /* Alright, we're going to report a stop.  */
 
   /* Remove single-step breakpoints.  */
-  if (can_software_single_step ())
+  if (supports_software_single_step ())
     {
       /* Remove single-step breakpoints or not.  It it is true, stop all
         lwps, so that other threads won't hit the breakpoint in the
@@ -3712,7 +3496,7 @@ linux_wait_1 (ptid_t ptid,
          select_event_lwp (&event_child);
 
          /* current_thread and event_child must stay in sync.  */
-         current_thread = get_lwp_thread (event_child);
+         switch_to_thread (get_lwp_thread (event_child));
 
          event_child->status_pending_p = 0;
          w = event_child->status_pending;
@@ -3733,14 +3517,17 @@ linux_wait_1 (ptid_t ptid,
        unstop_all_lwps (1, event_child);
     }
 
-  if (event_child->waitstatus.kind != TARGET_WAITKIND_IGNORE)
+  /* At this point, we haven't set OURSTATUS.  This is where we do it.  */
+  gdb_assert (ourstatus->kind () == TARGET_WAITKIND_IGNORE);
+
+  if (event_child->waitstatus.kind () != TARGET_WAITKIND_IGNORE)
     {
       /* If the reported event is an exit, fork, vfork or exec, let
         GDB know.  */
 
       /* Break the unreported fork relationship chain.  */
-      if (event_child->waitstatus.kind == TARGET_WAITKIND_FORKED
-         || event_child->waitstatus.kind == TARGET_WAITKIND_VFORKED)
+      if (event_child->waitstatus.kind () == TARGET_WAITKIND_FORKED
+         || event_child->waitstatus.kind () == TARGET_WAITKIND_VFORKED)
        {
          event_child->fork_relative->fork_relative = NULL;
          event_child->fork_relative = NULL;
@@ -3748,10 +3535,36 @@ linux_wait_1 (ptid_t ptid,
 
       *ourstatus = event_child->waitstatus;
       /* Clear the event lwp's waitstatus since we handled it already.  */
-      event_child->waitstatus.kind = TARGET_WAITKIND_IGNORE;
+      event_child->waitstatus.set_ignore ();
     }
   else
-    ourstatus->kind = TARGET_WAITKIND_STOPPED;
+    {
+      /* The LWP stopped due to a plain signal or a syscall signal.  Either way,
+        event_chid->waitstatus wasn't filled in with the details, so look at
+        the wait status W.  */
+      if (WSTOPSIG (w) == SYSCALL_SIGTRAP)
+       {
+         int syscall_number;
+
+         get_syscall_trapinfo (event_child, &syscall_number);
+         if (event_child->syscall_state == TARGET_WAITKIND_SYSCALL_ENTRY)
+           ourstatus->set_syscall_entry (syscall_number);
+         else if (event_child->syscall_state == TARGET_WAITKIND_SYSCALL_RETURN)
+           ourstatus->set_syscall_return (syscall_number);
+         else
+           gdb_assert_not_reached ("unexpected syscall state");
+       }
+      else if (current_thread->last_resume_kind == resume_stop
+              && WSTOPSIG (w) == SIGSTOP)
+       {
+         /* A thread that has been requested to stop by GDB with vCont;t,
+            and it stopped cleanly, so report as SIG0.  The use of
+            SIGSTOP is an implementation detail.  */
+         ourstatus->set_stopped (GDB_SIGNAL_0);
+       }
+      else
+       ourstatus->set_stopped (gdb_signal_from_host (WSTOPSIG (w)));
+    }
 
   /* Now that we've selected our final event LWP, un-adjust its PC if
      it was a software breakpoint, and the client doesn't know we can
@@ -3759,53 +3572,23 @@ linux_wait_1 (ptid_t ptid,
   if (event_child->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT
       && !cs.swbreak_feature)
     {
-      int decr_pc = the_low_target.decr_pc_after_break;
+      int decr_pc = low_decr_pc_after_break ();
 
       if (decr_pc != 0)
        {
          struct regcache *regcache
            = get_thread_regcache (current_thread, 1);
-         (*the_low_target.set_pc) (regcache, event_child->stop_pc + decr_pc);
+         low_set_pc (regcache, event_child->stop_pc + decr_pc);
        }
     }
 
-  if (WSTOPSIG (w) == SYSCALL_SIGTRAP)
-    {
-      get_syscall_trapinfo (event_child,
-                           &ourstatus->value.syscall_number);
-      ourstatus->kind = event_child->syscall_state;
-    }
-  else if (current_thread->last_resume_kind == resume_stop
-          && WSTOPSIG (w) == SIGSTOP)
-    {
-      /* A thread that has been requested to stop by GDB with vCont;t,
-        and it stopped cleanly, so report as SIG0.  The use of
-        SIGSTOP is an implementation detail.  */
-      ourstatus->value.sig = GDB_SIGNAL_0;
-    }
-  else if (current_thread->last_resume_kind == resume_stop
-          && WSTOPSIG (w) != SIGSTOP)
-    {
-      /* A thread that has been requested to stop by GDB with vCont;t,
-        but, it stopped for other reasons.  */
-      ourstatus->value.sig = gdb_signal_from_host (WSTOPSIG (w));
-    }
-  else if (ourstatus->kind == TARGET_WAITKIND_STOPPED)
-    {
-      ourstatus->value.sig = gdb_signal_from_host (WSTOPSIG (w));
-    }
-
   gdb_assert (step_over_bkpt == null_ptid);
 
-  if (debug_threads)
-    {
-      debug_printf ("linux_wait_1 ret = %s, %d, %d\n",
-                   target_pid_to_str (ptid_of (current_thread)),
-                   ourstatus->kind, ourstatus->value.sig);
-      debug_exit ();
-    }
+  threads_debug_printf ("ret = %s, %s",
+                       target_pid_to_str (ptid_of (current_thread)).c_str (),
+                       ourstatus->to_string ().c_str ());
 
-  if (ourstatus->kind == TARGET_WAITKIND_EXITED)
+  if (ourstatus->kind () == TARGET_WAITKIND_EXITED)
     return filter_exit_event (event_child, ourstatus);
 
   return ptid_of (current_thread);
@@ -3815,34 +3598,20 @@ linux_wait_1 (ptid_t ptid,
 static void
 async_file_flush (void)
 {
-  int ret;
-  char buf;
-
-  do
-    ret = read (linux_event_pipe[0], &buf, 1);
-  while (ret >= 0 || (ret == -1 && errno == EINTR));
+  linux_event_pipe.flush ();
 }
 
 /* Put something in the pipe, so the event loop wakes up.  */
 static void
 async_file_mark (void)
 {
-  int ret;
-
-  async_file_flush ();
-
-  do
-    ret = write (linux_event_pipe[1], "+", 1);
-  while (ret == 0 || (ret == -1 && errno == EINTR));
-
-  /* Ignore EAGAIN.  If the pipe is full, the event loop will already
-     be awakened anyway.  */
+  linux_event_pipe.mark ();
 }
 
 ptid_t
 linux_process_target::wait (ptid_t ptid,
                            target_waitstatus *ourstatus,
-                           int target_options)
+                           target_wait_flags target_options)
 {
   ptid_t event_ptid;
 
@@ -3852,11 +3621,11 @@ linux_process_target::wait (ptid_t ptid,
 
   do
     {
-      event_ptid = linux_wait_1 (ptid, ourstatus, target_options);
+      event_ptid = wait_1 (ptid, ourstatus, target_options);
     }
   while ((target_options & TARGET_WNOHANG) == 0
         && event_ptid == null_ptid
-        && ourstatus->kind == TARGET_WAITKIND_IGNORE);
+        && ourstatus->kind () == TARGET_WAITKIND_IGNORE);
 
   /* If at least one stop was reported, there may be more.  A single
      SIGCHLD can signal more than one child stop.  */
@@ -3903,14 +3672,12 @@ send_sigstop (struct lwp_info *lwp)
      send another.  */
   if (lwp->stop_expected)
     {
-      if (debug_threads)
-       debug_printf ("Have pending sigstop for lwp %d\n", pid);
+      threads_debug_printf ("Have pending sigstop for lwp %d", pid);
 
       return;
     }
 
-  if (debug_threads)
-    debug_printf ("Sending sigstop to lwp %d\n", pid);
+  threads_debug_printf ("Sending sigstop to lwp %d", pid);
 
   lwp->stop_expected = 1;
   kill_lwp (pid, SIGSTOP);
@@ -3957,15 +3724,9 @@ mark_lwp_dead (struct lwp_info *lwp, int wstat)
   /* Store in waitstatus as well, as there's nothing else to process
      for this event.  */
   if (WIFEXITED (wstat))
-    {
-      lwp->waitstatus.kind = TARGET_WAITKIND_EXITED;
-      lwp->waitstatus.value.integer = WEXITSTATUS (wstat);
-    }
+    lwp->waitstatus.set_exited (WEXITSTATUS (wstat));
   else if (WIFSIGNALED (wstat))
-    {
-      lwp->waitstatus.kind = TARGET_WAITKIND_SIGNALLED;
-      lwp->waitstatus.value.sig = gdb_signal_from_host (WTERMSIG (wstat));
-    }
+    lwp->waitstatus.set_signalled (gdb_signal_from_host (WTERMSIG (wstat)));
 
   /* Prevent trying to stop it.  */
   lwp->stopped = 1;
@@ -3985,10 +3746,8 @@ lwp_is_marked_dead (struct lwp_info *lwp)
              || WIFSIGNALED (lwp->status_pending)));
 }
 
-/* Wait for all children to stop for the SIGSTOPs we just queued.  */
-
-static void
-wait_for_sigstop (void)
+void
+linux_process_target::wait_for_sigstop ()
 {
   struct thread_info *saved_thread;
   ptid_t saved_tid;
@@ -4001,44 +3760,38 @@ wait_for_sigstop (void)
   else
     saved_tid = null_ptid; /* avoid bogus unused warning */
 
-  if (debug_threads)
-    debug_printf ("wait_for_sigstop: pulling events\n");
+  scoped_restore_current_thread restore_thread;
+
+  threads_debug_printf ("pulling events");
 
   /* Passing NULL_PTID as filter indicates we want all events to be
      left pending.  Eventually this returns when there are no
      unwaited-for children left.  */
-  ret = linux_wait_for_event_filtered (minus_one_ptid, null_ptid,
-                                      &wstat, __WALL);
+  ret = wait_for_event_filtered (minus_one_ptid, null_ptid, &wstat, __WALL);
   gdb_assert (ret == -1);
 
   if (saved_thread == NULL || mythread_alive (saved_tid))
-    current_thread = saved_thread;
+    return;
   else
     {
-      if (debug_threads)
-       debug_printf ("Previously current thread died.\n");
+      threads_debug_printf ("Previously current thread died.");
 
       /* We can't change the current inferior behind GDB's back,
         otherwise, a subsequent command may apply to the wrong
         process.  */
-      current_thread = NULL;
+      restore_thread.dont_restore ();
+      switch_to_thread (nullptr);
     }
 }
 
-/* Returns true if THREAD is stopped in a jump pad, and we can't
-   move it out, because we need to report the stop event to GDB.  For
-   example, if the user puts a breakpoint in the jump pad, it's
-   because she wants to debug it.  */
-
-static bool
-stuck_in_jump_pad_callback (thread_info *thread)
+bool
+linux_process_target::stuck_in_jump_pad (thread_info *thread)
 {
   struct lwp_info *lwp = get_thread_lwp (thread);
 
   if (lwp->suspended != 0)
     {
-      internal_error (__FILE__, __LINE__,
-                     "LWP %ld is suspended, suspended=%d\n",
+      internal_error ("LWP %ld is suspended, suspended=%d\n",
                      lwpid_of (thread), lwp->suspended);
     }
   gdb_assert (lwp->stopped);
@@ -4053,24 +3806,22 @@ stuck_in_jump_pad_callback (thread_info *thread)
              != fast_tpoint_collect_result::not_collecting));
 }
 
-static void
-move_out_of_jump_pad_callback (thread_info *thread)
+void
+linux_process_target::move_out_of_jump_pad (thread_info *thread)
 {
-  struct thread_info *saved_thread;
   struct lwp_info *lwp = get_thread_lwp (thread);
   int *wstat;
 
   if (lwp->suspended != 0)
     {
-      internal_error (__FILE__, __LINE__,
-                     "LWP %ld is suspended, suspended=%d\n",
+      internal_error ("LWP %ld is suspended, suspended=%d\n",
                      lwpid_of (thread), lwp->suspended);
     }
   gdb_assert (lwp->stopped);
 
   /* For gdb_breakpoint_here.  */
-  saved_thread = current_thread;
-  current_thread = thread;
+  scoped_restore_current_thread restore_thread;
+  switch_to_thread (thread);
 
   wstat = lwp->status_pending_p ? &lwp->status_pending : NULL;
 
@@ -4080,27 +3831,22 @@ move_out_of_jump_pad_callback (thread_info *thread)
       && thread->last_resume_kind != resume_step
       && maybe_move_out_of_jump_pad (lwp, wstat))
     {
-      if (debug_threads)
-       debug_printf ("LWP %ld needs stabilizing (in jump pad)\n",
-                     lwpid_of (thread));
+      threads_debug_printf ("LWP %ld needs stabilizing (in jump pad)",
+                           lwpid_of (thread));
 
       if (wstat)
        {
          lwp->status_pending_p = 0;
          enqueue_one_deferred_signal (lwp, wstat);
 
-         if (debug_threads)
-           debug_printf ("Signal %d for LWP %ld deferred "
-                         "(in jump pad)\n",
-                         WSTOPSIG (*wstat), lwpid_of (thread));
+         threads_debug_printf ("Signal %d for LWP %ld deferred (in jump pad",
+                               WSTOPSIG (*wstat), lwpid_of (thread));
        }
 
-      linux_resume_one_lwp (lwp, 0, 0, NULL);
+      resume_one_lwp (lwp, 0, 0, NULL);
     }
   else
     lwp_suspended_inc (lwp);
-
-  current_thread = saved_thread;
 }
 
 static bool
@@ -4114,25 +3860,19 @@ lwp_running (thread_info *thread)
   return !lwp->stopped;
 }
 
-/* Stop all lwps that aren't stopped yet, except EXCEPT, if not NULL.
-   If SUSPEND, then also increase the suspend count of every LWP,
-   except EXCEPT.  */
-
-static void
-stop_all_lwps (int suspend, struct lwp_info *except)
+void
+linux_process_target::stop_all_lwps (int suspend, lwp_info *except)
 {
   /* Should not be called recursively.  */
   gdb_assert (stopping_threads == NOT_STOPPING_THREADS);
 
-  if (debug_threads)
-    {
-      debug_enter ();
-      debug_printf ("stop_all_lwps (%s, except=%s)\n",
-                   suspend ? "stop-and-suspend" : "stop",
-                   except != NULL
-                   ? target_pid_to_str (ptid_of (get_lwp_thread (except)))
-                   : "none");
-    }
+  THREADS_SCOPED_DEBUG_ENTER_EXIT;
+
+  threads_debug_printf
+    ("%s, except=%s", suspend ? "stop-and-suspend" : "stop",
+     (except != NULL
+      ? target_pid_to_str (ptid_of (get_lwp_thread (except))).c_str ()
+      : "none"));
 
   stopping_threads = (suspend
                      ? STOPPING_AND_SUSPENDING_THREADS
@@ -4152,12 +3892,7 @@ stop_all_lwps (int suspend, struct lwp_info *except)
   wait_for_sigstop ();
   stopping_threads = NOT_STOPPING_THREADS;
 
-  if (debug_threads)
-    {
-      debug_printf ("stop_all_lwps done, setting stopping_threads "
-                   "back to !stopping\n");
-      debug_exit ();
-    }
+  threads_debug_printf ("setting stopping_threads back to !stopping");
 }
 
 /* Enqueue one signal in the chain of signals which need to be
@@ -4166,57 +3901,44 @@ stop_all_lwps (int suspend, struct lwp_info *except)
 static void
 enqueue_pending_signal (struct lwp_info *lwp, int signal, siginfo_t *info)
 {
-  struct pending_signals *p_sig = XNEW (struct pending_signals);
-
-  p_sig->prev = lwp->pending_signals;
-  p_sig->signal = signal;
-  if (info == NULL)
-    memset (&p_sig->info, 0, sizeof (siginfo_t));
+  lwp->pending_signals.emplace_back (signal);
+  if (info == nullptr)
+    memset (&lwp->pending_signals.back ().info, 0, sizeof (siginfo_t));
   else
-    memcpy (&p_sig->info, info, sizeof (siginfo_t));
-  lwp->pending_signals = p_sig;
+    lwp->pending_signals.back ().info = *info;
 }
 
-/* Install breakpoints for software single stepping.  */
-
-static void
-install_software_single_step_breakpoints (struct lwp_info *lwp)
+void
+linux_process_target::install_software_single_step_breakpoints (lwp_info *lwp)
 {
   struct thread_info *thread = get_lwp_thread (lwp);
   struct regcache *regcache = get_thread_regcache (thread, 1);
 
-  scoped_restore save_current_thread = make_scoped_restore (&current_thread);
+  scoped_restore_current_thread restore_thread;
 
-  current_thread = thread;
-  std::vector<CORE_ADDR> next_pcs = the_low_target.get_next_pcs (regcache);
+  switch_to_thread (thread);
+  std::vector<CORE_ADDR> next_pcs = low_get_next_pcs (regcache);
 
   for (CORE_ADDR pc : next_pcs)
     set_single_step_breakpoint (pc, current_ptid);
 }
 
-/* Single step via hardware or software single step.
-   Return 1 if hardware single stepping, 0 if software single stepping
-   or can't single step.  */
-
-static int
-single_step (struct lwp_info* lwp)
+int
+linux_process_target::single_step (lwp_info* lwp)
 {
   int step = 0;
 
-  if (can_hardware_single_step ())
+  if (supports_hardware_single_step ())
     {
       step = 1;
     }
-  else if (can_software_single_step ())
+  else if (supports_software_single_step ())
     {
       install_software_single_step_breakpoints (lwp);
       step = 0;
     }
   else
-    {
-      if (debug_threads)
-       debug_printf ("stepping is not implemented on this target");
-    }
+    threads_debug_printf ("stepping is not implemented on this target");
 
   return step;
 }
@@ -4234,15 +3956,11 @@ lwp_signal_can_be_delivered (struct lwp_info *lwp)
          == fast_tpoint_collect_result::not_collecting);
 }
 
-/* Resume execution of LWP.  If STEP is nonzero, single-step it.  If
-   SIGNAL is nonzero, give it that signal.  */
-
-static void
-linux_resume_one_lwp_throw (struct lwp_info *lwp,
-                           int step, int signal, siginfo_t *info)
+void
+linux_process_target::resume_one_lwp_throw (lwp_info *lwp, int step,
+                                           int signal, siginfo_t *info)
 {
   struct thread_info *thread = get_lwp_thread (lwp);
-  struct thread_info *saved_thread;
   int ptrace_request;
   struct process_info *proc = get_thread_process (thread);
 
@@ -4256,7 +3974,7 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp,
   if (lwp->stopped == 0)
     return;
 
-  gdb_assert (lwp->waitstatus.kind == TARGET_WAITKIND_IGNORE);
+  gdb_assert (lwp->waitstatus.kind () == TARGET_WAITKIND_IGNORE);
 
   fast_tpoint_collect_result fast_tp_collecting
     = lwp->collecting_fast_tracepoint;
@@ -4279,7 +3997,7 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp,
      inferior right now.  */
   if (signal != 0
       && (lwp->status_pending_p
-         || lwp->pending_signals != NULL
+         || !lwp->pending_signals.empty ()
          || !lwp_signal_can_be_delivered (lwp)))
     {
       enqueue_pending_signal (lwp, signal, info);
@@ -4290,16 +4008,15 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp,
 
   if (lwp->status_pending_p)
     {
-      if (debug_threads)
-       debug_printf ("Not resuming lwp %ld (%s, stop %s);"
-                     " has pending status\n",
-                     lwpid_of (thread), step ? "step" : "continue",
-                     lwp->stop_expected ? "expected" : "not expected");
+      threads_debug_printf
+       ("Not resuming lwp %ld (%s, stop %s); has pending status",
+        lwpid_of (thread), step ? "step" : "continue",
+        lwp->stop_expected ? "expected" : "not expected");
       return;
     }
 
-  saved_thread = current_thread;
-  current_thread = thread;
+  scoped_restore_current_thread restore_thread;
+  switch_to_thread (thread);
 
   /* This bit needs some thinking about.  If we get a signal that
      we must report while a single-step reinsert is still pending,
@@ -4313,11 +4030,10 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp,
      worthwhile just to solve this one, however.  */
   if (lwp->bp_reinsert != 0)
     {
-      if (debug_threads)
-       debug_printf ("  pending reinsert at 0x%s\n",
-                     paddress (lwp->bp_reinsert));
+      threads_debug_printf ("  pending reinsert at 0x%s",
+                           paddress (lwp->bp_reinsert));
 
-      if (can_hardware_single_step ())
+      if (supports_hardware_single_step ())
        {
          if (fast_tp_collecting == fast_tpoint_collect_result::not_collecting)
            {
@@ -4333,25 +4049,21 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp,
     }
 
   if (fast_tp_collecting == fast_tpoint_collect_result::before_insn)
-    {
-      if (debug_threads)
-       debug_printf ("lwp %ld wants to get out of fast tracepoint jump pad"
-                     " (exit-jump-pad-bkpt)\n",
-                     lwpid_of (thread));
-    }
+    threads_debug_printf
+      ("lwp %ld wants to get out of fast tracepoint jump pad "
+       "(exit-jump-pad-bkpt)", lwpid_of (thread));
+
   else if (fast_tp_collecting == fast_tpoint_collect_result::at_insn)
     {
-      if (debug_threads)
-       debug_printf ("lwp %ld wants to get out of fast tracepoint jump pad"
-                     " single-stepping\n",
-                     lwpid_of (thread));
+      threads_debug_printf
+       ("lwp %ld wants to get out of fast tracepoint jump pad single-stepping",
+        lwpid_of (thread));
 
-      if (can_hardware_single_step ())
+      if (supports_hardware_single_step ())
        step = 1;
       else
        {
-         internal_error (__FILE__, __LINE__,
-                         "moving out of jump pad single-stepping"
+         internal_error ("moving out of jump pad single-stepping"
                          " not implemented on this target");
        }
     }
@@ -4366,52 +4078,42 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp,
      enhancement.  */
   if (thread->while_stepping != NULL)
     {
-      if (debug_threads)
-       debug_printf ("lwp %ld has a while-stepping action -> forcing step.\n",
-                     lwpid_of (thread));
+      threads_debug_printf
+       ("lwp %ld has a while-stepping action -> forcing step.",
+        lwpid_of (thread));
 
       step = single_step (lwp);
     }
 
-  if (proc->tdesc != NULL && the_low_target.get_pc != NULL)
+  if (proc->tdesc != NULL && low_supports_breakpoints ())
     {
       struct regcache *regcache = get_thread_regcache (current_thread, 1);
 
-      lwp->stop_pc = (*the_low_target.get_pc) (regcache);
+      lwp->stop_pc = low_get_pc (regcache);
 
-      if (debug_threads)
-       {
-         debug_printf ("  %s from pc 0x%lx\n", step ? "step" : "continue",
-                       (long) lwp->stop_pc);
-       }
+      threads_debug_printf ("  %s from pc 0x%lx", step ? "step" : "continue",
+                           (long) lwp->stop_pc);
     }
 
   /* If we have pending signals, consume one if it can be delivered to
      the inferior.  */
-  if (lwp->pending_signals != NULL && lwp_signal_can_be_delivered (lwp))
+  if (!lwp->pending_signals.empty () && lwp_signal_can_be_delivered (lwp))
     {
-      struct pending_signals **p_sig;
-
-      p_sig = &lwp->pending_signals;
-      while ((*p_sig)->prev != NULL)
-       p_sig = &(*p_sig)->prev;
+      const pending_signal &p_sig = lwp->pending_signals.front ();
 
-      signal = (*p_sig)->signal;
-      if ((*p_sig)->info.si_signo != 0)
+      signal = p_sig.signal;
+      if (p_sig.info.si_signo != 0)
        ptrace (PTRACE_SETSIGINFO, lwpid_of (thread), (PTRACE_TYPE_ARG3) 0,
-               &(*p_sig)->info);
+               &p_sig.info);
 
-      free (*p_sig);
-      *p_sig = NULL;
+      lwp->pending_signals.pop_front ();
     }
 
-  if (debug_threads)
-    debug_printf ("Resuming lwp %ld (%s, signal %d, stop %s)\n",
-                 lwpid_of (thread), step ? "step" : "continue", signal,
-                 lwp->stop_expected ? "expected" : "not expected");
+  threads_debug_printf ("Resuming lwp %ld (%s, signal %d, stop %s)",
+                       lwpid_of (thread), step ? "step" : "continue", signal,
+                       lwp->stop_expected ? "expected" : "not expected");
 
-  if (the_low_target.prepare_to_resume != NULL)
-    the_low_target.prepare_to_resume (lwp);
+  low_prepare_to_resume (lwp);
 
   regcache_invalidate_thread (thread);
   errno = 0;
@@ -4429,9 +4131,16 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp,
             of coercing an 8 byte integer to a 4 byte pointer.  */
          (PTRACE_TYPE_ARG4) (uintptr_t) signal);
 
-  current_thread = saved_thread;
   if (errno)
-    perror_with_name ("resuming thread");
+    {
+      int saved_errno = errno;
+
+      threads_debug_printf ("ptrace errno = %d (%s)",
+                           saved_errno, strerror (saved_errno));
+
+      errno = saved_errno;
+      perror_with_name ("resuming thread");
+    }
 
   /* Successfully resumed.  Clear state that no longer makes sense,
      and mark the LWP as running.  Must not do this before resuming
@@ -4443,6 +4152,12 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp,
   lwp->stop_reason = TARGET_STOPPED_BY_NO_REASON;
 }
 
+void
+linux_process_target::low_prepare_to_resume (lwp_info *lwp)
+{
+  /* Nop.  */
+}
+
 /* Called when we try to resume a stopped LWP and that errors out.  If
    the LWP is no longer in ptrace-stopped state (meaning it's zombie,
    or about to become), discard the error, clear any pending status
@@ -4476,20 +4191,25 @@ check_ptrace_stopped_lwp_gone (struct lwp_info *lp)
   return 0;
 }
 
-/* Like linux_resume_one_lwp_throw, but no error is thrown if the LWP
-   disappears while we try to resume it.  */
-
-static void
-linux_resume_one_lwp (struct lwp_info *lwp,
-                     int step, int signal, siginfo_t *info)
+void
+linux_process_target::resume_one_lwp (lwp_info *lwp, int step, int signal,
+                                     siginfo_t *info)
 {
   try
     {
-      linux_resume_one_lwp_throw (lwp, step, signal, info);
+      resume_one_lwp_throw (lwp, step, signal, info);
     }
   catch (const gdb_exception_error &ex)
     {
-      if (!check_ptrace_stopped_lwp_gone (lwp))
+      if (check_ptrace_stopped_lwp_gone (lwp))
+       {
+         /* This could because we tried to resume an LWP after its leader
+            exited.  Mark it as resumed, so we can collect an exit event
+            from it.  */
+         lwp->stopped = 0;
+         lwp->stop_reason = TARGET_STOPPED_BY_NO_REASON;
+       }
+      else
        throw;
     }
 }
@@ -4521,13 +4241,11 @@ linux_set_resume_request (thread_info *thread, thread_resume *resume, size_t n)
          if (resume[ndx].kind == resume_stop
              && thread->last_resume_kind == resume_stop)
            {
-             if (debug_threads)
-               debug_printf ("already %s LWP %ld at GDB's request\n",
-                             (thread->last_status.kind
-                              == TARGET_WAITKIND_STOPPED)
-                             ? "stopped"
-                             : "stopping",
-                             lwpid_of (thread));
+             threads_debug_printf
+               ("already %s LWP %ld at GDB's request",
+                (thread->last_status.kind () == TARGET_WAITKIND_STOPPED
+                 ? "stopped" : "stopping"),
+                 lwpid_of (thread));
 
              continue;
            }
@@ -4537,13 +4255,11 @@ linux_set_resume_request (thread_info *thread, thread_resume *resume, size_t n)
          if (resume[ndx].kind != resume_stop
              && thread->last_resume_kind != resume_stop)
            {
-             if (debug_threads)
-               debug_printf ("already %s LWP %ld at GDB's request\n",
-                             (thread->last_resume_kind
-                              == resume_step)
-                             ? "stepping"
-                             : "continuing",
-                             lwpid_of (thread));
+             threads_debug_printf
+               ("already %s LWP %ld at GDB's request",
+                (thread->last_resume_kind == resume_step
+                 ? "stepping" : "continuing"),
+                lwpid_of (thread));
              continue;
            }
 
@@ -4554,12 +4270,12 @@ linux_set_resume_request (thread_info *thread, thread_resume *resume, size_t n)
              struct lwp_info *rel = lwp->fork_relative;
 
              if (rel->status_pending_p
-                 && (rel->waitstatus.kind == TARGET_WAITKIND_FORKED
-                     || rel->waitstatus.kind == TARGET_WAITKIND_VFORKED))
+                 && (rel->waitstatus.kind () == TARGET_WAITKIND_FORKED
+                     || rel->waitstatus.kind () == TARGET_WAITKIND_VFORKED))
                {
-                 if (debug_threads)
-                   debug_printf ("not resuming LWP %ld: has queued stop reply\n",
-                                 lwpid_of (thread));
+                 threads_debug_printf
+                   ("not resuming LWP %ld: has queued stop reply",
+                    lwpid_of (thread));
                  continue;
                }
            }
@@ -4570,9 +4286,9 @@ linux_set_resume_request (thread_info *thread, thread_resume *resume, size_t n)
             (wildcard) resume request.  */
          if (in_queued_stop_replies (thread->id))
            {
-             if (debug_threads)
-               debug_printf ("not resuming LWP %ld: has queued stop reply\n",
-                             lwpid_of (thread));
+             threads_debug_printf
+               ("not resuming LWP %ld: has queued stop reply",
+                lwpid_of (thread));
              continue;
            }
 
@@ -4591,11 +4307,11 @@ linux_set_resume_request (thread_info *thread, thread_resume *resume, size_t n)
            {
              lwp->status_pending_p = 1;
 
-             if (debug_threads)
-               debug_printf ("Dequeueing deferred signal %d for LWP %ld, "
-                             "leaving status pending.\n",
-                             WSTOPSIG (lwp->status_pending),
-                             lwpid_of (thread));
+             threads_debug_printf
+               ("Dequeueing deferred signal %d for LWP %ld, "
+                "leaving status pending.",
+                WSTOPSIG (lwp->status_pending),
+                lwpid_of (thread));
            }
 
          return;
@@ -4606,11 +4322,8 @@ linux_set_resume_request (thread_info *thread, thread_resume *resume, size_t n)
   lwp->resume = NULL;
 }
 
-/* find_thread callback for linux_resume.  Return true if this lwp has an
-   interesting status pending.  */
-
-static bool
-resume_status_pending_p (thread_info *thread)
+bool
+linux_process_target::resume_status_pending (thread_info *thread)
 {
   struct lwp_info *lwp = get_thread_lwp (thread);
 
@@ -4619,19 +4332,13 @@ resume_status_pending_p (thread_info *thread)
   if (lwp->resume == NULL)
     return false;
 
-  return thread_still_has_status_pending_p (thread);
+  return thread_still_has_status_pending (thread);
 }
 
-/* Return 1 if this lwp that GDB wants running is stopped at an
-   internal breakpoint that we need to step over.  It assumes that any
-   required STOP_PC adjustment has already been propagated to the
-   inferior's regcache.  */
-
-static bool
-need_step_over_p (thread_info *thread)
+bool
+linux_process_target::thread_needs_step_over (thread_info *thread)
 {
   struct lwp_info *lwp = get_thread_lwp (thread);
-  struct thread_info *saved_thread;
   CORE_ADDR pc;
   struct process_info *proc = get_thread_process (thread);
 
@@ -4645,18 +4352,16 @@ need_step_over_p (thread_info *thread)
 
   if (!lwp->stopped)
     {
-      if (debug_threads)
-       debug_printf ("Need step over [LWP %ld]? Ignoring, not stopped\n",
-                     lwpid_of (thread));
+      threads_debug_printf ("Need step over [LWP %ld]? Ignoring, not stopped",
+                           lwpid_of (thread));
       return false;
     }
 
   if (thread->last_resume_kind == resume_stop)
     {
-      if (debug_threads)
-       debug_printf ("Need step over [LWP %ld]? Ignoring, should remain"
-                     " stopped\n",
-                     lwpid_of (thread));
+      threads_debug_printf
+       ("Need step over [LWP %ld]? Ignoring, should remain stopped",
+        lwpid_of (thread));
       return false;
     }
 
@@ -4664,18 +4369,16 @@ need_step_over_p (thread_info *thread)
 
   if (lwp->suspended)
     {
-      if (debug_threads)
-       debug_printf ("Need step over [LWP %ld]? Ignoring, suspended\n",
-                     lwpid_of (thread));
+      threads_debug_printf ("Need step over [LWP %ld]? Ignoring, suspended",
+                           lwpid_of (thread));
       return false;
     }
 
   if (lwp->status_pending_p)
     {
-      if (debug_threads)
-       debug_printf ("Need step over [LWP %ld]? Ignoring, has pending"
-                     " status.\n",
-                     lwpid_of (thread));
+      threads_debug_printf
+       ("Need step over [LWP %ld]? Ignoring, has pending status.",
+        lwpid_of (thread));
       return false;
     }
 
@@ -4690,30 +4393,28 @@ need_step_over_p (thread_info *thread)
      command, or poked thread's registers herself.  */
   if (pc != lwp->stop_pc)
     {
-      if (debug_threads)
-       debug_printf ("Need step over [LWP %ld]? Cancelling, PC was changed. "
-                     "Old stop_pc was 0x%s, PC is now 0x%s\n",
-                     lwpid_of (thread),
-                     paddress (lwp->stop_pc), paddress (pc));
+      threads_debug_printf
+       ("Need step over [LWP %ld]? Cancelling, PC was changed. "
+        "Old stop_pc was 0x%s, PC is now 0x%s", lwpid_of (thread),
+        paddress (lwp->stop_pc), paddress (pc));
       return false;
     }
 
   /* On software single step target, resume the inferior with signal
      rather than stepping over.  */
-  if (can_software_single_step ()
-      && lwp->pending_signals != NULL
+  if (supports_software_single_step ()
+      && !lwp->pending_signals.empty ()
       && lwp_signal_can_be_delivered (lwp))
     {
-      if (debug_threads)
-       debug_printf ("Need step over [LWP %ld]? Ignoring, has pending"
-                     " signals.\n",
-                     lwpid_of (thread));
+      threads_debug_printf
+       ("Need step over [LWP %ld]? Ignoring, has pending signals.",
+        lwpid_of (thread));
 
       return false;
     }
 
-  saved_thread = current_thread;
-  current_thread = thread;
+  scoped_restore_current_thread restore_thread;
+  switch_to_thread (thread);
 
   /* We can only step over breakpoints we know about.  */
   if (breakpoint_here (pc) || fast_tracepoint_jump_here (pc))
@@ -4725,72 +4426,49 @@ need_step_over_p (thread_info *thread)
          && gdb_condition_true_at_breakpoint (pc)
          && gdb_no_commands_at_breakpoint (pc))
        {
-         if (debug_threads)
-           debug_printf ("Need step over [LWP %ld]? yes, but found"
-                         " GDB breakpoint at 0x%s; skipping step over\n",
-                         lwpid_of (thread), paddress (pc));
+         threads_debug_printf ("Need step over [LWP %ld]? yes, but found"
+                               " GDB breakpoint at 0x%s; skipping step over",
+                               lwpid_of (thread), paddress (pc));
 
-         current_thread = saved_thread;
          return false;
        }
       else
        {
-         if (debug_threads)
-           debug_printf ("Need step over [LWP %ld]? yes, "
-                         "found breakpoint at 0x%s\n",
-                         lwpid_of (thread), paddress (pc));
+         threads_debug_printf ("Need step over [LWP %ld]? yes, "
+                               "found breakpoint at 0x%s",
+                               lwpid_of (thread), paddress (pc));
 
          /* We've found an lwp that needs stepping over --- return 1 so
             that find_thread stops looking.  */
-         current_thread = saved_thread;
-
          return true;
        }
     }
 
-  current_thread = saved_thread;
-
-  if (debug_threads)
-    debug_printf ("Need step over [LWP %ld]? No, no breakpoint found"
-                 " at 0x%s\n",
-                 lwpid_of (thread), paddress (pc));
+  threads_debug_printf
+    ("Need step over [LWP %ld]? No, no breakpoint found at 0x%s",
+     lwpid_of (thread), paddress (pc));
 
   return false;
 }
 
-/* Start a step-over operation on LWP.  When LWP stopped at a
-   breakpoint, to make progress, we need to remove the breakpoint out
-   of the way.  If we let other threads run while we do that, they may
-   pass by the breakpoint location and miss hitting it.  To avoid
-   that, a step-over momentarily stops all threads while LWP is
-   single-stepped by either hardware or software while the breakpoint
-   is temporarily uninserted from the inferior.  When the single-step
-   finishes, we reinsert the breakpoint, and let all threads that are
-   supposed to be running, run again.  */
-
-static int
-start_step_over (struct lwp_info *lwp)
+void
+linux_process_target::start_step_over (lwp_info *lwp)
 {
   struct thread_info *thread = get_lwp_thread (lwp);
-  struct thread_info *saved_thread;
   CORE_ADDR pc;
-  int step;
 
-  if (debug_threads)
-    debug_printf ("Starting step-over on LWP %ld.  Stopping all threads\n",
-                 lwpid_of (thread));
+  threads_debug_printf ("Starting step-over on LWP %ld.  Stopping all threads",
+                       lwpid_of (thread));
 
   stop_all_lwps (1, lwp);
 
   if (lwp->suspended != 0)
     {
-      internal_error (__FILE__, __LINE__,
-                     "LWP %ld suspended=%d\n", lwpid_of (thread),
+      internal_error ("LWP %ld suspended=%d\n", lwpid_of (thread),
                      lwp->suspended);
     }
 
-  if (debug_threads)
-    debug_printf ("Done stopping all threads for step-over.\n");
+  threads_debug_printf ("Done stopping all threads for step-over.");
 
   /* Note, we should always reach here with an already adjusted PC,
      either by GDB (if we're resuming due to GDB's request), or by our
@@ -4798,39 +4476,34 @@ start_step_over (struct lwp_info *lwp)
      shouldn't care about.  */
   pc = get_pc (lwp);
 
-  saved_thread = current_thread;
-  current_thread = thread;
-
-  lwp->bp_reinsert = pc;
-  uninsert_breakpoints_at (pc);
-  uninsert_fast_tracepoint_jumps_at (pc);
+  bool step = false;
+  {
+    scoped_restore_current_thread restore_thread;
+    switch_to_thread (thread);
 
-  step = single_step (lwp);
+    lwp->bp_reinsert = pc;
+    uninsert_breakpoints_at (pc);
+    uninsert_fast_tracepoint_jumps_at (pc);
 
-  current_thread = saved_thread;
+    step = single_step (lwp);
+  }
 
-  linux_resume_one_lwp (lwp, step, 0, NULL);
+  resume_one_lwp (lwp, step, 0, NULL);
 
   /* Require next event from this LWP.  */
   step_over_bkpt = thread->id;
-  return 1;
 }
 
-/* Finish a step-over.  Reinsert the breakpoint we had uninserted in
-   start_step_over, if still there, and delete any single-step
-   breakpoints we've set, on non hardware single-step targets.  */
-
-static int
-finish_step_over (struct lwp_info *lwp)
+bool
+linux_process_target::finish_step_over (lwp_info *lwp)
 {
   if (lwp->bp_reinsert != 0)
     {
-      struct thread_info *saved_thread = current_thread;
+      scoped_restore_current_thread restore_thread;
 
-      if (debug_threads)
-       debug_printf ("Finished step over.\n");
+      threads_debug_printf ("Finished step over.");
 
-      current_thread = get_lwp_thread (lwp);
+      switch_to_thread (get_lwp_thread (lwp));
 
       /* Reinsert any breakpoint at LWP->BP_REINSERT.  Note that there
         may be no breakpoint to reinsert there by now.  */
@@ -4844,28 +4517,21 @@ finish_step_over (struct lwp_info *lwp)
         and later not being able to explain it, because we were
         stepping over a breakpoint, and we hold all threads but
         LWP stopped while doing that.  */
-      if (!can_hardware_single_step ())
+      if (!supports_hardware_single_step ())
        {
          gdb_assert (has_single_step_breakpoints (current_thread));
          delete_single_step_breakpoints (current_thread);
        }
 
       step_over_bkpt = null_ptid;
-      current_thread = saved_thread;
-      return 1;
+      return true;
     }
   else
-    return 0;
+    return false;
 }
 
-/* If there's a step over in progress, wait until all threads stop
-   (that is, until the stepping thread finishes its step), and
-   unsuspend all lwps.  The stepping thread ends with its status
-   pending, which is processed later when we get back to processing
-   events.  */
-
-static void
-complete_ongoing_step_over (void)
+void
+linux_process_target::complete_ongoing_step_over ()
 {
   if (step_over_bkpt != null_ptid)
     {
@@ -4873,39 +4539,49 @@ complete_ongoing_step_over (void)
       int wstat;
       int ret;
 
-      if (debug_threads)
-       debug_printf ("detach: step over in progress, finish it first\n");
+      threads_debug_printf ("detach: step over in progress, finish it first");
 
       /* Passing NULL_PTID as filter indicates we want all events to
         be left pending.  Eventually this returns when there are no
         unwaited-for children left.  */
-      ret = linux_wait_for_event_filtered (minus_one_ptid, null_ptid,
-                                          &wstat, __WALL);
+      ret = wait_for_event_filtered (minus_one_ptid, null_ptid, &wstat,
+                                    __WALL);
       gdb_assert (ret == -1);
 
       lwp = find_lwp_pid (step_over_bkpt);
       if (lwp != NULL)
-       finish_step_over (lwp);
+       {
+         finish_step_over (lwp);
+
+         /* If we got our step SIGTRAP, don't leave it pending,
+            otherwise we would report it to GDB as a spurious
+            SIGTRAP.  */
+         gdb_assert (lwp->status_pending_p);
+         if (WIFSTOPPED (lwp->status_pending)
+             && WSTOPSIG (lwp->status_pending) == SIGTRAP)
+           {
+             thread_info *thread = get_lwp_thread (lwp);
+             if (thread->last_resume_kind != resume_step)
+               {
+                 threads_debug_printf ("detach: discard step-over SIGTRAP");
+
+                 lwp->status_pending_p = 0;
+                 lwp->status_pending = 0;
+                 resume_one_lwp (lwp, lwp->stepping, 0, NULL);
+               }
+             else
+               threads_debug_printf
+                 ("detach: resume_step, not discarding step-over SIGTRAP");
+           }
+       }
       step_over_bkpt = null_ptid;
       unsuspend_all_lwps (lwp);
     }
 }
 
-/* This function is called once per thread.  We check the thread's resume
-   request, which will tell us whether to resume, step, or leave the thread
-   stopped; and what signal, if any, it should be sent.
-
-   For threads which we aren't explicitly told otherwise, we preserve
-   the stepping flag; this is used for stepping over gdbserver-placed
-   breakpoints.
-
-   If pending_flags was set in any thread, we queue any needed
-   signals, since we won't actually resume.  We already have a pending
-   event to report, so we don't need to preserve any step requests;
-   they should be re-issued if necessary.  */
-
-static void
-linux_resume_one_thread (thread_info *thread, bool leave_all_stopped)
+void
+linux_process_target::resume_one_thread (thread_info *thread,
+                                        bool leave_all_stopped)
 {
   struct lwp_info *lwp = get_thread_lwp (thread);
   int leave_pending;
@@ -4915,13 +4591,12 @@ linux_resume_one_thread (thread_info *thread, bool leave_all_stopped)
 
   if (lwp->resume->kind == resume_stop)
     {
-      if (debug_threads)
-       debug_printf ("resume_stop request for LWP %ld\n", lwpid_of (thread));
+      threads_debug_printf ("resume_stop request for LWP %ld",
+                           lwpid_of (thread));
 
       if (!lwp->stopped)
        {
-         if (debug_threads)
-           debug_printf ("stopping LWP %ld\n", lwpid_of (thread));
+         threads_debug_printf ("stopping LWP %ld", lwpid_of (thread));
 
          /* Stop the thread, and wait for the event asynchronously,
             through the event loop.  */
@@ -4929,9 +4604,7 @@ linux_resume_one_thread (thread_info *thread, bool leave_all_stopped)
        }
       else
        {
-         if (debug_threads)
-           debug_printf ("already stopped LWP %ld\n",
-                         lwpid_of (thread));
+         threads_debug_printf ("already stopped LWP %ld", lwpid_of (thread));
 
          /* The LWP may have been stopped in an internal event that
             was not meant to be notified back to GDB (e.g., gdbserver
@@ -4951,13 +4624,13 @@ linux_resume_one_thread (thread_info *thread, bool leave_all_stopped)
             midway through moving the LWP out of the jumppad, and we
             will report the pending signal as soon as that is
             finished.  */
-         if (lwp->pending_signals_to_report == NULL)
+         if (lwp->pending_signals_to_report.empty ())
            send_sigstop (lwp);
        }
 
       /* For stop requests, we're done.  */
       lwp->resume = NULL;
-      thread->last_status.kind = TARGET_WAITKIND_IGNORE;
+      thread->last_status.set_ignore ();
       return;
     }
 
@@ -4993,18 +4666,14 @@ linux_resume_one_thread (thread_info *thread, bool leave_all_stopped)
 
   if (!leave_pending)
     {
-      if (debug_threads)
-       debug_printf ("resuming LWP %ld\n", lwpid_of (thread));
+      threads_debug_printf ("resuming LWP %ld", lwpid_of (thread));
 
       proceed_one_lwp (thread, NULL);
     }
   else
-    {
-      if (debug_threads)
-       debug_printf ("leaving LWP %ld stopped\n", lwpid_of (thread));
-    }
+    threads_debug_printf ("leaving LWP %ld stopped", lwpid_of (thread));
 
-  thread->last_status.kind = TARGET_WAITKIND_IGNORE;
+  thread->last_status.set_ignore ();
   lwp->resume = NULL;
 }
 
@@ -5013,11 +4682,7 @@ linux_process_target::resume (thread_resume *resume_info, size_t n)
 {
   struct thread_info *need_step_over = NULL;
 
-  if (debug_threads)
-    {
-      debug_enter ();
-      debug_printf ("linux_resume:\n");
-    }
+ THREADS_SCOPED_DEBUG_ENTER_EXIT;
 
   for_each_thread ([&] (thread_info *thread)
     {
@@ -5032,7 +4697,10 @@ linux_process_target::resume (thread_resume *resume_info, size_t n)
      before considering to start a step-over (in all-stop).  */
   bool any_pending = false;
   if (!non_stop)
-    any_pending = find_thread (resume_status_pending_p) != NULL;
+    any_pending = find_thread ([this] (thread_info *thread)
+                   {
+                     return resume_status_pending (thread);
+                   }) != nullptr;
 
   /* If there is a thread which would otherwise be resumed, which is
      stopped at a breakpoint that needs stepping over, then don't
@@ -5040,55 +4708,40 @@ linux_process_target::resume (thread_resume *resume_info, size_t n)
      other threads stopped, then resume all threads again.  Make sure
      to queue any signals that would otherwise be delivered or
      queued.  */
-  if (!any_pending && supports_breakpoints ())
-    need_step_over = find_thread (need_step_over_p);
+  if (!any_pending && low_supports_breakpoints ())
+    need_step_over = find_thread ([this] (thread_info *thread)
+                      {
+                        return thread_needs_step_over (thread);
+                      });
 
   bool leave_all_stopped = (need_step_over != NULL || any_pending);
 
-  if (debug_threads)
-    {
-      if (need_step_over != NULL)
-       debug_printf ("Not resuming all, need step over\n");
-      else if (any_pending)
-       debug_printf ("Not resuming, all-stop and found "
-                     "an LWP with pending status\n");
-      else
-       debug_printf ("Resuming, no pending status or step over needed\n");
-    }
+  if (need_step_over != NULL)
+    threads_debug_printf ("Not resuming all, need step over");
+  else if (any_pending)
+    threads_debug_printf ("Not resuming, all-stop and found "
+                         "an LWP with pending status");
+  else
+    threads_debug_printf ("Resuming, no pending status or step over needed");
 
   /* Even if we're leaving threads stopped, queue all signals we'd
      otherwise deliver.  */
   for_each_thread ([&] (thread_info *thread)
     {
-      linux_resume_one_thread (thread, leave_all_stopped);
+      resume_one_thread (thread, leave_all_stopped);
     });
 
   if (need_step_over)
     start_step_over (get_thread_lwp (need_step_over));
 
-  if (debug_threads)
-    {
-      debug_printf ("linux_resume done\n");
-      debug_exit ();
-    }
-
   /* We may have events that were pending that can/should be sent to
      the client now.  Trigger a linux_wait call.  */
   if (target_is_async_p ())
     async_file_mark ();
 }
 
-/* This function is called once per thread.  We check the thread's
-   last resume request, which will tell us whether to resume, step, or
-   leave the thread stopped.  Any signal the client requested to be
-   delivered has already been enqueued at this point.
-
-   If any thread that GDB wants running is stopped at an internal
-   breakpoint that needs stepping over, we start a step-over operation
-   on that particular thread, and leave all others stopped.  */
-
-static void
-proceed_one_lwp (thread_info *thread, lwp_info *except)
+void
+linux_process_target::proceed_one_lwp (thread_info *thread, lwp_info *except)
 {
   struct lwp_info *lwp = get_thread_lwp (thread);
   int step;
@@ -5096,30 +4749,26 @@ proceed_one_lwp (thread_info *thread, lwp_info *except)
   if (lwp == except)
     return;
 
-  if (debug_threads)
-    debug_printf ("proceed_one_lwp: lwp %ld\n", lwpid_of (thread));
+  threads_debug_printf ("lwp %ld", lwpid_of (thread));
 
   if (!lwp->stopped)
     {
-      if (debug_threads)
-       debug_printf ("   LWP %ld already running\n", lwpid_of (thread));
+      threads_debug_printf ("   LWP %ld already running", lwpid_of (thread));
       return;
     }
 
   if (thread->last_resume_kind == resume_stop
-      && thread->last_status.kind != TARGET_WAITKIND_IGNORE)
+      && thread->last_status.kind () != TARGET_WAITKIND_IGNORE)
     {
-      if (debug_threads)
-       debug_printf ("   client wants LWP to remain %ld stopped\n",
-                     lwpid_of (thread));
+      threads_debug_printf ("   client wants LWP to remain %ld stopped",
+                           lwpid_of (thread));
       return;
     }
 
   if (lwp->status_pending_p)
     {
-      if (debug_threads)
-       debug_printf ("   LWP %ld has pending status, leaving stopped\n",
-                     lwpid_of (thread));
+      threads_debug_printf ("   LWP %ld has pending status, leaving stopped",
+                           lwpid_of (thread));
       return;
     }
 
@@ -5127,13 +4776,12 @@ proceed_one_lwp (thread_info *thread, lwp_info *except)
 
   if (lwp->suspended)
     {
-      if (debug_threads)
-       debug_printf ("   LWP %ld is suspended\n", lwpid_of (thread));
+      threads_debug_printf ("   LWP %ld is suspended", lwpid_of (thread));
       return;
     }
 
   if (thread->last_resume_kind == resume_stop
-      && lwp->pending_signals_to_report == NULL
+      && lwp->pending_signals_to_report.empty ()
       && (lwp->collecting_fast_tracepoint
          == fast_tpoint_collect_result::not_collecting))
     {
@@ -5147,24 +4795,22 @@ proceed_one_lwp (thread_info *thread, lwp_info *except)
         another one here.  Note that if the LWP already has a SIGSTOP
         pending, this is a no-op.  */
 
-      if (debug_threads)
-       debug_printf ("Client wants LWP %ld to stop. "
-                     "Making sure it has a SIGSTOP pending\n",
-                     lwpid_of (thread));
+      threads_debug_printf
+       ("Client wants LWP %ld to stop.  Making sure it has a SIGSTOP pending",
+        lwpid_of (thread));
 
       send_sigstop (lwp);
     }
 
   if (thread->last_resume_kind == resume_step)
     {
-      if (debug_threads)
-       debug_printf ("   stepping LWP %ld, client wants it stepping\n",
-                     lwpid_of (thread));
+      threads_debug_printf ("   stepping LWP %ld, client wants it stepping",
+                           lwpid_of (thread));
 
       /* If resume_step is requested by GDB, install single-step
         breakpoints when the thread is about to be actually resumed if
         the single-step breakpoints weren't removed.  */
-      if (can_software_single_step ()
+      if (supports_software_single_step ()
          && !has_single_step_breakpoints (thread))
        install_software_single_step_breakpoints (lwp);
 
@@ -5172,20 +4818,20 @@ proceed_one_lwp (thread_info *thread, lwp_info *except)
     }
   else if (lwp->bp_reinsert != 0)
     {
-      if (debug_threads)
-       debug_printf ("   stepping LWP %ld, reinsert set\n",
-                     lwpid_of (thread));
+      threads_debug_printf ("   stepping LWP %ld, reinsert set",
+                           lwpid_of (thread));
 
       step = maybe_hw_step (thread);
     }
   else
     step = 0;
 
-  linux_resume_one_lwp (lwp, step, 0, NULL);
+  resume_one_lwp (lwp, step, 0, NULL);
 }
 
-static void
-unsuspend_and_proceed_one_lwp (thread_info *thread, lwp_info *except)
+void
+linux_process_target::unsuspend_and_proceed_one_lwp (thread_info *thread,
+                                                    lwp_info *except)
 {
   struct lwp_info *lwp = get_thread_lwp (thread);
 
@@ -5197,12 +4843,8 @@ unsuspend_and_proceed_one_lwp (thread_info *thread, lwp_info *except)
   proceed_one_lwp (thread, except);
 }
 
-/* When we finish a step-over, set threads running again.  If there's
-   another thread that may need a step-over, now's the time to start
-   it.  Eventually, we'll move all threads past their breakpoints.  */
-
-static void
-proceed_all_lwps (void)
+void
+linux_process_target::proceed_all_lwps ()
 {
   struct thread_info *need_step_over;
 
@@ -5211,47 +4853,41 @@ proceed_all_lwps (void)
      resume any threads - have it step over the breakpoint with all
      other threads stopped, then resume all threads again.  */
 
-  if (supports_breakpoints ())
+  if (low_supports_breakpoints ())
     {
-      need_step_over = find_thread (need_step_over_p);
+      need_step_over = find_thread ([this] (thread_info *thread)
+                        {
+                          return thread_needs_step_over (thread);
+                        });
 
       if (need_step_over != NULL)
        {
-         if (debug_threads)
-           debug_printf ("proceed_all_lwps: found "
-                         "thread %ld needing a step-over\n",
-                         lwpid_of (need_step_over));
+         threads_debug_printf ("found thread %ld needing a step-over",
+                               lwpid_of (need_step_over));
 
          start_step_over (get_thread_lwp (need_step_over));
          return;
        }
     }
 
-  if (debug_threads)
-    debug_printf ("Proceeding, no step-over needed\n");
+  threads_debug_printf ("Proceeding, no step-over needed");
 
-  for_each_thread ([] (thread_info *thread)
+  for_each_thread ([this] (thread_info *thread)
     {
       proceed_one_lwp (thread, NULL);
     });
 }
 
-/* Stopped LWPs that the client wanted to be running, that don't have
-   pending statuses, are set to run again, except for EXCEPT, if not
-   NULL.  This undoes a stop_all_lwps call.  */
-
-static void
-unstop_all_lwps (int unsuspend, struct lwp_info *except)
+void
+linux_process_target::unstop_all_lwps (int unsuspend, lwp_info *except)
 {
-  if (debug_threads)
-    {
-      debug_enter ();
-      if (except)
-       debug_printf ("unstopping all lwps, except=(LWP %ld)\n",
-                     lwpid_of (get_lwp_thread (except)));
-      else
-       debug_printf ("unstopping all lwps\n");
-    }
+  THREADS_SCOPED_DEBUG_ENTER_EXIT;
+
+  if (except)
+    threads_debug_printf ("except=(LWP %ld)",
+                 lwpid_of (get_lwp_thread (except)));
+  else
+    threads_debug_printf ("except=nullptr");
 
   if (unsuspend)
     for_each_thread ([&] (thread_info *thread)
@@ -5263,12 +4899,6 @@ unstop_all_lwps (int unsuspend, struct lwp_info *except)
       {
        proceed_one_lwp (thread, except);
       });
-
-  if (debug_threads)
-    {
-      debug_printf ("unstop_all_lwps done\n");
-      debug_exit ();
-    }
 }
 
 
@@ -5447,7 +5077,7 @@ regsets_store_inferior_registers (struct regsets_info *regsets_info,
              /* At this point, ESRCH should mean the process is
                 already gone, in which case we simply ignore attempts
                 to change its registers.  See also the related
-                comment in linux_resume_one_lwp.  */
+                comment in resume_one_lwp.  */
              free (buf);
              return 0;
            }
@@ -5503,10 +5133,10 @@ register_addr (const struct usrregs_info *usrregs, int regnum)
   return addr;
 }
 
-/* Fetch one register.  */
-static void
-fetch_register (const struct usrregs_info *usrregs,
-               struct regcache *regcache, int regno)
+
+void
+linux_process_target::fetch_register (const usrregs_info *usrregs,
+                                     regcache *regcache, int regno)
 {
   CORE_ADDR regaddr;
   int i, size;
@@ -5515,7 +5145,7 @@ fetch_register (const struct usrregs_info *usrregs,
 
   if (regno >= usrregs->num_regs)
     return;
-  if ((*the_low_target.cannot_fetch_register) (regno))
+  if (low_cannot_fetch_register (regno))
     return;
 
   regaddr = register_addr (usrregs, regno);
@@ -5545,16 +5175,12 @@ fetch_register (const struct usrregs_info *usrregs,
        }
     }
 
-  if (the_low_target.supply_ptrace_register)
-    the_low_target.supply_ptrace_register (regcache, regno, buf);
-  else
-    supply_register (regcache, regno, buf);
+  low_supply_ptrace_register (regcache, regno, buf);
 }
 
-/* Store one register.  */
-static void
-store_register (const struct usrregs_info *usrregs,
-               struct regcache *regcache, int regno)
+void
+linux_process_target::store_register (const usrregs_info *usrregs,
+                                     regcache *regcache, int regno)
 {
   CORE_ADDR regaddr;
   int i, size;
@@ -5563,7 +5189,7 @@ store_register (const struct usrregs_info *usrregs,
 
   if (regno >= usrregs->num_regs)
     return;
-  if ((*the_low_target.cannot_store_register) (regno))
+  if (low_cannot_store_register (regno))
     return;
 
   regaddr = register_addr (usrregs, regno);
@@ -5576,10 +5202,7 @@ store_register (const struct usrregs_info *usrregs,
   buf = (char *) alloca (size);
   memset (buf, 0, size);
 
-  if (the_low_target.collect_ptrace_register)
-    the_low_target.collect_ptrace_register (regcache, regno, buf);
-  else
-    collect_register (regcache, regno, buf);
+  low_collect_ptrace_register (regcache, regno, buf);
 
   pid = lwpid_of (current_thread);
   for (i = 0; i < size; i += sizeof (PTRACE_XFER_TYPE))
@@ -5595,26 +5218,39 @@ store_register (const struct usrregs_info *usrregs,
          /* At this point, ESRCH should mean the process is
             already gone, in which case we simply ignore attempts
             to change its registers.  See also the related
-            comment in linux_resume_one_lwp.  */
+            comment in resume_one_lwp.  */
          if (errno == ESRCH)
            return;
 
-         if ((*the_low_target.cannot_store_register) (regno) == 0)
+
+         if (!low_cannot_store_register (regno))
            error ("writing register %d: %s", regno, safe_strerror (errno));
        }
       regaddr += sizeof (PTRACE_XFER_TYPE);
     }
 }
+#endif /* HAVE_LINUX_USRREGS */
 
-/* Fetch all registers, or just one, from the child process.
-   If REGNO is -1, do this for all registers, skipping any that are
-   assumed to have been retrieved by regsets_fetch_inferior_registers,
-   unless ALL is non-zero.
-   Otherwise, REGNO specifies which register (so we can save time).  */
-static void
-usr_fetch_inferior_registers (const struct regs_info *regs_info,
-                             struct regcache *regcache, int regno, int all)
+void
+linux_process_target::low_collect_ptrace_register (regcache *regcache,
+                                                  int regno, char *buf)
+{
+  collect_register (regcache, regno, buf);
+}
+
+void
+linux_process_target::low_supply_ptrace_register (regcache *regcache,
+                                                 int regno, const char *buf)
+{
+  supply_register (regcache, regno, buf);
+}
+
+void
+linux_process_target::usr_fetch_inferior_registers (const regs_info *regs_info,
+                                                   regcache *regcache,
+                                                   int regno, int all)
 {
+#ifdef HAVE_LINUX_USRREGS
   struct usrregs_info *usr = regs_info->usrregs;
 
   if (regno == -1)
@@ -5625,17 +5261,15 @@ usr_fetch_inferior_registers (const struct regs_info *regs_info,
     }
   else
     fetch_register (usr, regcache, regno);
+#endif
 }
 
-/* Store our register values back into the inferior.
-   If REGNO is -1, do this for all registers, skipping any that are
-   assumed to have been saved by regsets_store_inferior_registers,
-   unless ALL is non-zero.
-   Otherwise, REGNO specifies which register (so we can save time).  */
-static void
-usr_store_inferior_registers (const struct regs_info *regs_info,
-                             struct regcache *regcache, int regno, int all)
+void
+linux_process_target::usr_store_inferior_registers (const regs_info *regs_info,
+                                                   regcache *regcache,
+                                                   int regno, int all)
 {
+#ifdef HAVE_LINUX_USRREGS
   struct usrregs_info *usr = regs_info->usrregs;
 
   if (regno == -1)
@@ -5646,29 +5280,21 @@ usr_store_inferior_registers (const struct regs_info *regs_info,
     }
   else
     store_register (usr, regcache, regno);
-}
-
-#else /* !HAVE_LINUX_USRREGS */
-
-#define usr_fetch_inferior_registers(regs_info, regcache, regno, all) do {} while (0)
-#define usr_store_inferior_registers(regs_info, regcache, regno, all) do {} while (0)
-
 #endif
-
+}
 
 void
 linux_process_target::fetch_registers (regcache *regcache, int regno)
 {
   int use_regsets;
   int all = 0;
-  const struct regs_info *regs_info = (*the_low_target.regs_info) ();
+  const regs_info *regs_info = get_regs_info ();
 
   if (regno == -1)
     {
-      if (the_low_target.fetch_register != NULL
-         && regs_info->usrregs != NULL)
+      if (regs_info->usrregs != NULL)
        for (regno = 0; regno < regs_info->usrregs->num_regs; regno++)
-         (*the_low_target.fetch_register) (regcache, regno);
+         low_fetch_register (regcache, regno);
 
       all = regsets_fetch_inferior_registers (regs_info->regsets_info, regcache);
       if (regs_info->usrregs != NULL)
@@ -5676,8 +5302,7 @@ linux_process_target::fetch_registers (regcache *regcache, int regno)
     }
   else
     {
-      if (the_low_target.fetch_register != NULL
-         && (*the_low_target.fetch_register) (regcache, regno))
+      if (low_fetch_register (regcache, regno))
        return;
 
       use_regsets = linux_register_in_regsets (regs_info, regno);
@@ -5694,7 +5319,7 @@ linux_process_target::store_registers (regcache *regcache, int regno)
 {
   int use_regsets;
   int all = 0;
-  const struct regs_info *regs_info = (*the_low_target.regs_info) ();
+  const regs_info *regs_info = get_regs_info ();
 
   if (regno == -1)
     {
@@ -5714,102 +5339,85 @@ linux_process_target::store_registers (regcache *regcache, int regno)
     }
 }
 
+bool
+linux_process_target::low_fetch_register (regcache *regcache, int regno)
+{
+  return false;
+}
 
 /* A wrapper for the read_memory target op.  */
 
 static int
 linux_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
 {
-  return the_target->pt->read_memory (memaddr, myaddr, len);
+  return the_target->read_memory (memaddr, myaddr, len);
 }
 
-/* Copy LEN bytes from inferior's memory starting at MEMADDR
-   to debugger memory starting at MYADDR.  */
 
-int
-linux_process_target::read_memory (CORE_ADDR memaddr,
-                                  unsigned char *myaddr, int len)
+/* Helper for read_memory/write_memory using /proc/PID/mem.  Because
+   we can use a single read/write call, this can be much more
+   efficient than banging away at PTRACE_PEEKTEXT.  Also, unlike
+   PTRACE_PEEKTEXT/PTRACE_POKETEXT, this works with running threads.
+   One an only one of READBUF and WRITEBUF is non-null.  If READBUF is
+   not null, then we're reading, otherwise we're writing.  */
+
+static int
+proc_xfer_memory (CORE_ADDR memaddr, unsigned char *readbuf,
+                 const gdb_byte *writebuf, int len)
 {
-  int pid = lwpid_of (current_thread);
-  PTRACE_XFER_TYPE *buffer;
-  CORE_ADDR addr;
-  int count;
-  char filename[64];
-  int i;
-  int ret;
-  int fd;
+  gdb_assert ((readbuf == nullptr) != (writebuf == nullptr));
 
-  /* Try using /proc.  Don't bother for one word.  */
-  if (len >= 3 * sizeof (long))
+  process_info *proc = current_process ();
+
+  int fd = proc->priv->mem_fd;
+  if (fd == -1)
+    return EIO;
+
+  while (len > 0)
     {
       int bytes;
 
-      /* We could keep this file open and cache it - possibly one per
-        thread.  That requires some juggling, but is even faster.  */
-      sprintf (filename, "/proc/%d/mem", pid);
-      fd = open (filename, O_RDONLY | O_LARGEFILE);
-      if (fd == -1)
-       goto no_proc;
-
       /* If pread64 is available, use it.  It's faster if the kernel
         supports it (only one syscall), and it's 64-bit safe even on
         32-bit platforms (for instance, SPARC debugging a SPARC64
         application).  */
 #ifdef HAVE_PREAD64
-      bytes = pread64 (fd, myaddr, len, memaddr);
+      bytes = (readbuf != nullptr
+              ? pread64 (fd, readbuf, len, memaddr)
+              : pwrite64 (fd, writebuf, len, memaddr));
 #else
       bytes = -1;
       if (lseek (fd, memaddr, SEEK_SET) != -1)
-       bytes = read (fd, myaddr, len);
+       bytes = (readbuf != nullptr
+                ? read (fd, readbuf, len)
+                : write (fd, writebuf, len));
 #endif
 
-      close (fd);
-      if (bytes == len)
-       return 0;
-
-      /* Some data was read, we'll try to get the rest with ptrace.  */
-      if (bytes > 0)
+      if (bytes < 0)
+       return errno;
+      else if (bytes == 0)
        {
-         memaddr += bytes;
-         myaddr += bytes;
-         len -= bytes;
+         /* EOF means the address space is gone, the whole process
+            exited or execed.  */
+         return EIO;
        }
-    }
-
- no_proc:
-  /* Round starting address down to longword boundary.  */
-  addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE);
-  /* Round ending address up; get number of longwords that makes.  */
-  count = ((((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1)
-          / sizeof (PTRACE_XFER_TYPE));
-  /* Allocate buffer of that many longwords.  */
-  buffer = XALLOCAVEC (PTRACE_XFER_TYPE, count);
 
-  /* Read all the longwords */
-  errno = 0;
-  for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
-    {
-      /* Coerce the 3rd arg to a uintptr_t first to avoid potential gcc warning
-        about coercing an 8 byte integer to a 4 byte pointer.  */
-      buffer[i] = ptrace (PTRACE_PEEKTEXT, pid,
-                         (PTRACE_TYPE_ARG3) (uintptr_t) addr,
-                         (PTRACE_TYPE_ARG4) 0);
-      if (errno)
-       break;
+      memaddr += bytes;
+      if (readbuf != nullptr)
+       readbuf += bytes;
+      else
+       writebuf += bytes;
+      len -= bytes;
     }
-  ret = errno;
 
-  /* Copy appropriate bytes out of the buffer.  */
-  if (i > 0)
-    {
-      i *= sizeof (PTRACE_XFER_TYPE);
-      i -= memaddr & (sizeof (PTRACE_XFER_TYPE) - 1);
-      memcpy (myaddr,
-             (char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)),
-             i < len ? i : len);
-    }
+  return 0;
+}
 
-  return ret;
+int
+linux_process_target::read_memory (CORE_ADDR memaddr,
+                                  unsigned char *myaddr, int len)
+{
+  return proc_xfer_memory (memaddr, myaddr, nullptr, len);
 }
 
 /* Copy LEN bytes of data from debugger memory at MYADDR to inferior's
@@ -5820,25 +5428,6 @@ int
 linux_process_target::write_memory (CORE_ADDR memaddr,
                                    const unsigned char *myaddr, int len)
 {
-  int i;
-  /* Round starting address down to longword boundary.  */
-  CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE);
-  /* Round ending address up; get number of longwords that makes.  */
-  int count
-    = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1)
-    / sizeof (PTRACE_XFER_TYPE);
-
-  /* Allocate buffer of that many longwords.  */
-  PTRACE_XFER_TYPE *buffer = XALLOCAVEC (PTRACE_XFER_TYPE, count);
-
-  int pid = lwpid_of (current_thread);
-
-  if (len == 0)
-    {
-      /* Zero length write always succeeds.  */
-      return 0;
-    }
-
   if (debug_threads)
     {
       /* Dump up to four bytes.  */
@@ -5846,62 +5435,18 @@ linux_process_target::write_memory (CORE_ADDR memaddr,
       char *p = str;
       int dump = len < 4 ? len : 4;
 
-      for (i = 0; i < dump; i++)
+      for (int i = 0; i < dump; i++)
        {
          sprintf (p, "%02x", myaddr[i]);
          p += 2;
        }
       *p = '\0';
 
-      debug_printf ("Writing %s to 0x%08lx in process %d\n",
-                   str, (long) memaddr, pid);
+      threads_debug_printf ("Writing %s to 0x%08lx in process %d",
+                           str, (long) memaddr, current_process ()->pid);
     }
 
-  /* Fill start and end extra bytes of buffer with existing memory data.  */
-
-  errno = 0;
-  /* Coerce the 3rd arg to a uintptr_t first to avoid potential gcc warning
-     about coercing an 8 byte integer to a 4 byte pointer.  */
-  buffer[0] = ptrace (PTRACE_PEEKTEXT, pid,
-                     (PTRACE_TYPE_ARG3) (uintptr_t) addr,
-                     (PTRACE_TYPE_ARG4) 0);
-  if (errno)
-    return errno;
-
-  if (count > 1)
-    {
-      errno = 0;
-      buffer[count - 1]
-       = ptrace (PTRACE_PEEKTEXT, pid,
-                 /* Coerce to a uintptr_t first to avoid potential gcc warning
-                    about coercing an 8 byte integer to a 4 byte pointer.  */
-                 (PTRACE_TYPE_ARG3) (uintptr_t) (addr + (count - 1)
-                                                 * sizeof (PTRACE_XFER_TYPE)),
-                 (PTRACE_TYPE_ARG4) 0);
-      if (errno)
-       return errno;
-    }
-
-  /* Copy data to be written over corresponding part of buffer.  */
-
-  memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)),
-         myaddr, len);
-
-  /* Write the entire buffer.  */
-
-  for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
-    {
-      errno = 0;
-      ptrace (PTRACE_POKETEXT, pid,
-             /* Coerce to a uintptr_t first to avoid potential gcc warning
-                about coercing an 8 byte integer to a 4 byte pointer.  */
-             (PTRACE_TYPE_ARG3) (uintptr_t) addr,
-             (PTRACE_TYPE_ARG4) buffer[i]);
-      if (errno)
-       return errno;
-    }
-
-  return 0;
+  return proc_xfer_memory (memaddr, nullptr, myaddr, len);
 }
 
 void
@@ -5922,7 +5467,10 @@ linux_process_target::request_interrupt ()
 {
   /* Send a SIGINT to the process group.  This acts just like the user
      typed a ^C on the controlling terminal.  */
-  ::kill (-signal_pid, SIGINT);
+  int res = ::kill (-signal_pid, SIGINT);
+  if (res == -1)
+    warning (_("Sending SIGINT to process group of pid %ld failed: %s"),
+            signal_pid, safe_strerror (errno));
 }
 
 bool
@@ -5935,12 +5483,11 @@ linux_process_target::supports_read_auxv ()
    to debugger memory starting at MYADDR.  */
 
 int
-linux_process_target::read_auxv (CORE_ADDR offset, unsigned char *myaddr,
-                                unsigned int len)
+linux_process_target::read_auxv (int pid, CORE_ADDR offset,
+                                unsigned char *myaddr, unsigned int len)
 {
   char filename[PATH_MAX];
   int fd, n;
-  int pid = lwpid_of (current_thread);
 
   xsnprintf (filename, sizeof filename, "/proc/%d/auxv", pid);
 
@@ -5959,28 +5506,22 @@ linux_process_target::read_auxv (CORE_ADDR offset, unsigned char *myaddr,
   return n;
 }
 
-/* These breakpoint and watchpoint related wrapper functions simply
-   pass on the function call if the target has registered a
-   corresponding function.  */
-
-bool
-linux_process_target::supports_z_point_type (char z_type)
-{
-  return (the_low_target.supports_z_point_type != NULL
-         && the_low_target.supports_z_point_type (z_type));
-}
-
 int
 linux_process_target::insert_point (enum raw_bkpt_type type, CORE_ADDR addr,
                                    int size, raw_breakpoint *bp)
 {
   if (type == raw_bkpt_type_sw)
     return insert_memory_breakpoint (bp);
-  else if (the_low_target.insert_point != NULL)
-    return the_low_target.insert_point (type, addr, size, bp);
   else
-    /* Unsupported (see target.h).  */
-    return 1;
+    return low_insert_point (type, addr, size, bp);
+}
+
+int
+linux_process_target::low_insert_point (raw_bkpt_type type, CORE_ADDR addr,
+                                       int size, raw_breakpoint *bp)
+{
+  /* Unsupported (see target.h).  */
+  return 1;
 }
 
 int
@@ -5989,11 +5530,16 @@ linux_process_target::remove_point (enum raw_bkpt_type type, CORE_ADDR addr,
 {
   if (type == raw_bkpt_type_sw)
     return remove_memory_breakpoint (bp);
-  else if (the_low_target.remove_point != NULL)
-    return the_low_target.remove_point (type, addr, size, bp);
   else
-    /* Unsupported (see target.h).  */
-    return 1;
+    return low_remove_point (type, addr, size, bp);
+}
+
+int
+linux_process_target::low_remove_point (raw_bkpt_type type, CORE_ADDR addr,
+                                       int size, raw_breakpoint *bp)
+{
+  /* Unsupported (see target.h).  */
+  return 1;
 }
 
 /* Implement the stopped_by_sw_breakpoint target_ops
@@ -6041,13 +5587,7 @@ linux_process_target::supports_stopped_by_hw_breakpoint ()
 bool
 linux_process_target::supports_hardware_single_step ()
 {
-  return can_hardware_single_step ();
-}
-
-bool
-linux_process_target::supports_software_single_step ()
-{
-  return can_software_single_step ();
+  return true;
 }
 
 bool
@@ -6160,16 +5700,11 @@ linux_process_target::qxfer_osdata (const char *annex,
   return linux_common_xfer_osdata (annex, readbuf, offset, len);
 }
 
-/* Convert a native/host siginfo object, into/from the siginfo in the
-   layout of the inferiors' architecture.  */
-
-static void
-siginfo_fixup (siginfo_t *siginfo, gdb_byte *inf_siginfo, int direction)
+void
+linux_process_target::siginfo_fixup (siginfo_t *siginfo,
+                                    gdb_byte *inf_siginfo, int direction)
 {
-  int done = 0;
-
-  if (the_low_target.siginfo_fixup != NULL)
-    done = the_low_target.siginfo_fixup (siginfo, inf_siginfo, direction);
+  bool done = low_siginfo_fixup (siginfo, inf_siginfo, direction);
 
   /* If there was no callback, or the callback didn't do anything,
      then just do a straight memcpy.  */
@@ -6182,6 +5717,13 @@ siginfo_fixup (siginfo_t *siginfo, gdb_byte *inf_siginfo, int direction)
     }
 }
 
+bool
+linux_process_target::low_siginfo_fixup (siginfo_t *native, gdb_byte *inf,
+                                        int direction)
+{
+  return false;
+}
+
 bool
 linux_process_target::supports_qxfer_siginfo ()
 {
@@ -6203,10 +5745,9 @@ linux_process_target::qxfer_siginfo (const char *annex,
 
   pid = lwpid_of (current_thread);
 
-  if (debug_threads)
-    debug_printf ("%s siginfo for lwp %d.\n",
-                 readbuf != NULL ? "Reading" : "Writing",
-                 pid);
+  threads_debug_printf ("%s siginfo for lwp %d.",
+                       readbuf != NULL ? "Reading" : "Writing",
+                       pid);
 
   if (offset >= sizeof (siginfo))
     return -1;
@@ -6276,9 +5817,8 @@ linux_process_target::async (bool enable)
 {
   bool previous = target_is_async_p ();
 
-  if (debug_threads)
-    debug_printf ("linux_async (%d), previous=%d\n",
-                 enable, previous);
+  threads_debug_printf ("async (%d), previous=%d",
+                       enable, previous);
 
   if (previous != enable)
     {
@@ -6290,34 +5830,27 @@ linux_process_target::async (bool enable)
 
       if (enable)
        {
-         if (pipe (linux_event_pipe) == -1)
+         if (!linux_event_pipe.open_pipe ())
            {
-             linux_event_pipe[0] = -1;
-             linux_event_pipe[1] = -1;
              gdb_sigmask (SIG_UNBLOCK, &mask, NULL);
 
              warning ("creating event pipe failed.");
              return previous;
            }
 
-         fcntl (linux_event_pipe[0], F_SETFL, O_NONBLOCK);
-         fcntl (linux_event_pipe[1], F_SETFL, O_NONBLOCK);
-
          /* Register the event loop handler.  */
-         add_file_handler (linux_event_pipe[0],
-                           handle_target_event, NULL);
+         add_file_handler (linux_event_pipe.event_fd (),
+                           handle_target_event, NULL,
+                           "linux-low");
 
          /* Always trigger a linux_wait.  */
          async_file_mark ();
        }
       else
        {
-         delete_file_handler (linux_event_pipe[0]);
+         delete_file_handler (linux_event_pipe.event_fd ());
 
-         close (linux_event_pipe[0]);
-         close (linux_event_pipe[1]);
-         linux_event_pipe[0] = -1;
-         linux_event_pipe[1] = -1;
+         linux_event_pipe.close_pipe ();
        }
 
       gdb_sigmask (SIG_UNBLOCK, &mask, NULL);
@@ -6349,7 +5882,7 @@ linux_process_target::supports_multi_process ()
 bool
 linux_process_target::supports_fork_events ()
 {
-  return linux_supports_tracefork ();
+  return true;
 }
 
 /* Check if vfork events are supported.  */
@@ -6357,7 +5890,7 @@ linux_process_target::supports_fork_events ()
 bool
 linux_process_target::supports_vfork_events ()
 {
-  return linux_supports_tracefork ();
+  return true;
 }
 
 /* Check if exec events are supported.  */
@@ -6365,7 +5898,7 @@ linux_process_target::supports_vfork_events ()
 bool
 linux_process_target::supports_exec_events ()
 {
-  return linux_supports_traceexec ();
+  return true;
 }
 
 /* Target hook for 'handle_new_gdb_connection'.  Causes a reset of the
@@ -6417,11 +5950,7 @@ linux_process_target::core_of_thread (ptid_t ptid)
 bool
 linux_process_target::supports_disable_randomization ()
 {
-#ifdef HAVE_PERSONALITY
   return true;
-#else
-  return false;
-#endif
 }
 
 bool
@@ -6433,12 +5962,16 @@ linux_process_target::supports_agent ()
 bool
 linux_process_target::supports_range_stepping ()
 {
-  if (can_software_single_step ())
+  if (supports_software_single_step ())
     return true;
-  if (*the_low_target.supports_range_stepping == NULL)
-    return false;
 
-  return (*the_low_target.supports_range_stepping) ();
+  return low_supports_range_stepping ();
+}
+
+bool
+linux_process_target::low_supports_range_stepping ()
+{
+  return false;
 }
 
 bool
@@ -6447,7 +5980,7 @@ linux_process_target::supports_pid_to_exec_file ()
   return true;
 }
 
-char *
+const char *
 linux_process_target::pid_to_exec_file (int pid)
 {
   return linux_proc_pid_to_exec_file (pid);
@@ -6561,53 +6094,33 @@ linux_process_target::read_loadmap (const char *annex, CORE_ADDR offset,
 }
 #endif /* defined PT_GETDSBT || defined PTRACE_GETFDPIC */
 
-void
-linux_process_target::process_qsupported (char **features, int count)
-{
-  if (the_low_target.process_qsupported != NULL)
-    the_low_target.process_qsupported (features, count);
-}
-
 bool
 linux_process_target::supports_catch_syscall ()
 {
-  return (the_low_target.get_syscall_trapinfo != NULL
-         && linux_supports_tracesysgood ());
-}
-
-static int
-linux_get_ipa_tdesc_idx (void)
-{
-  if (the_low_target.get_ipa_tdesc_idx == NULL)
-    return 0;
-
-  return (*the_low_target.get_ipa_tdesc_idx) ();
+  return low_supports_catch_syscall ();
 }
 
 bool
-linux_process_target::supports_tracepoints ()
+linux_process_target::low_supports_catch_syscall ()
 {
-  if (*the_low_target.supports_tracepoints == NULL)
-    return false;
-
-  return (*the_low_target.supports_tracepoints) ();
+  return false;
 }
 
 CORE_ADDR
 linux_process_target::read_pc (regcache *regcache)
 {
-  if (the_low_target.get_pc == NULL)
+  if (!low_supports_breakpoints ())
     return 0;
 
-  return (*the_low_target.get_pc) (regcache);
+  return low_get_pc (regcache);
 }
 
 void
 linux_process_target::write_pc (regcache *regcache, CORE_ADDR pc)
 {
-  gdb_assert (the_low_target.set_pc != NULL);
+  gdb_assert (low_supports_breakpoints ());
 
-  (*the_low_target.set_pc) (regcache, pc);
+  low_set_pc (regcache, pc);
 }
 
 bool
@@ -6639,63 +6152,6 @@ linux_process_target::unpause_all (bool unfreeze)
   unstop_all_lwps (unfreeze, NULL);
 }
 
-int
-linux_process_target::prepare_to_access_memory ()
-{
-  /* Neither ptrace nor /proc/PID/mem allow accessing memory through a
-     running LWP.  */
-  if (non_stop)
-    target_pause_all (true);
-  return 0;
-}
-
-void
-linux_process_target::done_accessing_memory ()
-{
-  /* Neither ptrace nor /proc/PID/mem allow accessing memory through a
-     running LWP.  */
-  if (non_stop)
-    target_unpause_all (true);
-}
-
-bool
-linux_process_target::supports_fast_tracepoints ()
-{
-  return the_low_target.install_fast_tracepoint_jump_pad != nullptr;
-}
-
-int
-linux_process_target::install_fast_tracepoint_jump_pad
-  (CORE_ADDR tpoint, CORE_ADDR tpaddr, CORE_ADDR collector,
-   CORE_ADDR lockaddr, ULONGEST orig_size, CORE_ADDR *jump_entry,
-   CORE_ADDR *trampoline, ULONGEST *trampoline_size,
-   unsigned char *jjump_pad_insn, ULONGEST *jjump_pad_insn_size,
-   CORE_ADDR *adjusted_insn_addr, CORE_ADDR *adjusted_insn_addr_end,
-   char *err)
-{
-  return (*the_low_target.install_fast_tracepoint_jump_pad)
-    (tpoint, tpaddr, collector, lockaddr, orig_size,
-     jump_entry, trampoline, trampoline_size,
-     jjump_pad_insn, jjump_pad_insn_size,
-     adjusted_insn_addr, adjusted_insn_addr_end,
-     err);
-}
-
-emit_ops *
-linux_process_target::emit_ops ()
-{
-  if (the_low_target.emit_ops != NULL)
-    return (*the_low_target.emit_ops) ();
-  else
-    return NULL;
-}
-
-int
-linux_process_target::get_min_fast_tracepoint_insn_len ()
-{
-  return (*the_low_target.get_min_fast_tracepoint_insn_len) ();
-}
-
 /* Extract &phdr and num_phdr in the inferior.  Return 0 on success.  */
 
 static int
@@ -6983,6 +6439,9 @@ struct link_map_offsets
     /* Offset and size of r_debug.r_map.  */
     int r_map_offset;
 
+    /* Offset of r_debug_extended.r_next.  */
+    int r_next_offset;
+
     /* Offset to l_addr field in struct link_map.  */
     int l_addr_offset;
 
@@ -6999,6 +6458,79 @@ struct link_map_offsets
     int l_prev_offset;
   };
 
+static const link_map_offsets lmo_32bit_offsets =
+  {
+    0,     /* r_version offset.  */
+    4,     /* r_debug.r_map offset.  */
+    20,    /* r_debug_extended.r_next.  */
+    0,     /* l_addr offset in link_map.  */
+    4,     /* l_name offset in link_map.  */
+    8,     /* l_ld offset in link_map.  */
+    12,    /* l_next offset in link_map.  */
+    16     /* l_prev offset in link_map.  */
+  };
+
+static const link_map_offsets lmo_64bit_offsets =
+  {
+    0,     /* r_version offset.  */
+    8,     /* r_debug.r_map offset.  */
+    40,    /* r_debug_extended.r_next.  */
+    0,     /* l_addr offset in link_map.  */
+    8,     /* l_name offset in link_map.  */
+    16,    /* l_ld offset in link_map.  */
+    24,    /* l_next offset in link_map.  */
+    32     /* l_prev offset in link_map.  */
+  };
+
+/* Get the loaded shared libraries from one namespace.  */
+
+static void
+read_link_map (std::string &document, CORE_ADDR lmid, CORE_ADDR lm_addr,
+              CORE_ADDR lm_prev, int ptr_size, const link_map_offsets *lmo)
+{
+  CORE_ADDR l_name, l_addr, l_ld, l_next, l_prev;
+
+  while (lm_addr
+        && read_one_ptr (lm_addr + lmo->l_name_offset,
+                         &l_name, ptr_size) == 0
+        && read_one_ptr (lm_addr + lmo->l_addr_offset,
+                         &l_addr, ptr_size) == 0
+        && read_one_ptr (lm_addr + lmo->l_ld_offset,
+                         &l_ld, ptr_size) == 0
+        && read_one_ptr (lm_addr + lmo->l_prev_offset,
+                         &l_prev, ptr_size) == 0
+        && read_one_ptr (lm_addr + lmo->l_next_offset,
+                         &l_next, ptr_size) == 0)
+    {
+      unsigned char libname[PATH_MAX];
+
+      if (lm_prev != l_prev)
+       {
+         warning ("Corrupted shared library list: 0x%s != 0x%s",
+                  paddress (lm_prev), paddress (l_prev));
+         break;
+       }
+
+      /* Not checking for error because reading may stop before we've got
+        PATH_MAX worth of characters.  */
+      libname[0] = '\0';
+      linux_read_memory (l_name, libname, sizeof (libname) - 1);
+      libname[sizeof (libname) - 1] = '\0';
+      if (libname[0] != '\0')
+       {
+         string_appendf (document, "<library name=\"");
+         xml_escape_text_append (document, (char *) libname);
+         string_appendf (document, "\" lm=\"0x%s\" l_addr=\"0x%s\" "
+                         "l_ld=\"0x%s\" lmid=\"0x%s\"/>",
+                         paddress (lm_addr), paddress (l_addr),
+                         paddress (l_ld), paddress (lmid));
+       }
+
+      lm_prev = lm_addr;
+      lm_addr = l_next;
+    }
+}
+
 /* Construct qXfer:libraries-svr4:read reply.  */
 
 int
@@ -7010,34 +6542,8 @@ linux_process_target::qxfer_libraries_svr4 (const char *annex,
   struct process_info_private *const priv = current_process ()->priv;
   char filename[PATH_MAX];
   int pid, is_elf64;
-
-  static const struct link_map_offsets lmo_32bit_offsets =
-    {
-      0,     /* r_version offset. */
-      4,     /* r_debug.r_map offset.  */
-      0,     /* l_addr offset in link_map.  */
-      4,     /* l_name offset in link_map.  */
-      8,     /* l_ld offset in link_map.  */
-      12,    /* l_next offset in link_map.  */
-      16     /* l_prev offset in link_map.  */
-    };
-
-  static const struct link_map_offsets lmo_64bit_offsets =
-    {
-      0,     /* r_version offset. */
-      8,     /* r_debug.r_map offset.  */
-      0,     /* l_addr offset in link_map.  */
-      8,     /* l_name offset in link_map.  */
-      16,    /* l_ld offset in link_map.  */
-      24,    /* l_next offset in link_map.  */
-      32     /* l_prev offset in link_map.  */
-    };
-  const struct link_map_offsets *lmo;
   unsigned int machine;
-  int ptr_size;
-  CORE_ADDR lm_addr = 0, lm_prev = 0;
-  CORE_ADDR l_name, l_addr, l_ld, l_next, l_prev;
-  int header_done = 0;
+  CORE_ADDR lmid = 0, lm_addr = 0, lm_prev = 0;
 
   if (writebuf != NULL)
     return -2;
@@ -7047,8 +6553,18 @@ linux_process_target::qxfer_libraries_svr4 (const char *annex,
   pid = lwpid_of (current_thread);
   xsnprintf (filename, sizeof filename, "/proc/%d/exe", pid);
   is_elf64 = elf_64_file_p (filename, &machine);
-  lmo = is_elf64 ? &lmo_64bit_offsets : &lmo_32bit_offsets;
-  ptr_size = is_elf64 ? 8 : 4;
+  const link_map_offsets *lmo;
+  int ptr_size;
+  if (is_elf64)
+    {
+      lmo = &lmo_64bit_offsets;
+      ptr_size = 8;
+    }
+  else
+    {
+      lmo = &lmo_32bit_offsets;
+      ptr_size = 4;
+    }
 
   while (annex[0] != '\0')
     {
@@ -7061,7 +6577,9 @@ linux_process_target::qxfer_libraries_svr4 (const char *annex,
        break;
 
       name_len = sep - annex;
-      if (name_len == 5 && startswith (annex, "start"))
+      if (name_len == 4 && startswith (annex, "lmid"))
+       addrp = &lmid;
+      else if (name_len == 5 && startswith (annex, "start"))
        addrp = &lm_addr;
       else if (name_len == 4 && startswith (annex, "prev"))
        addrp = &lm_prev;
@@ -7077,104 +6595,109 @@ linux_process_target::qxfer_libraries_svr4 (const char *annex,
       annex = decode_address_to_semicolon (addrp, sep + 1);
     }
 
-  if (lm_addr == 0)
+  std::string document = "<library-list-svr4 version=\"1.0\"";
+
+  /* When the starting LM_ADDR is passed in the annex, only traverse that
+     namespace, which is assumed to be identified by LMID.
+
+     Otherwise, start with R_DEBUG and traverse all namespaces we find.  */
+  if (lm_addr != 0)
     {
-      int r_version = 0;
+      document += ">";
+      read_link_map (document, lmid, lm_addr, lm_prev, ptr_size, lmo);
+    }
+  else
+    {
+      if (lm_prev != 0)
+       warning ("ignoring prev=0x%s without start", paddress (lm_prev));
+
+      /* We could interpret LMID as 'provide only the libraries for this
+        namespace' but GDB is currently only providing lmid, start, and
+        prev, or nothing.  */
+      if (lmid != 0)
+       warning ("ignoring lmid=0x%s without start", paddress (lmid));
 
-      if (priv->r_debug == 0)
-       priv->r_debug = get_r_debug (pid, is_elf64);
+      CORE_ADDR r_debug = priv->r_debug;
+      if (r_debug == 0)
+       r_debug = priv->r_debug = get_r_debug (pid, is_elf64);
 
       /* We failed to find DT_DEBUG.  Such situation will not change
         for this inferior - do not retry it.  Report it to GDB as
         E01, see for the reasons at the GDB solib-svr4.c side.  */
-      if (priv->r_debug == (CORE_ADDR) -1)
+      if (r_debug == (CORE_ADDR) -1)
        return -1;
 
-      if (priv->r_debug != 0)
+      /* Terminate the header if we end up with an empty list.  */
+      if (r_debug == 0)
+       document += ">";
+
+      while (r_debug != 0)
        {
-         if (linux_read_memory (priv->r_debug + lmo->r_version_offset,
+         int r_version = 0;
+         if (linux_read_memory (r_debug + lmo->r_version_offset,
                                 (unsigned char *) &r_version,
-                                sizeof (r_version)) != 0
-             || r_version != 1)
+                                sizeof (r_version)) != 0)
            {
-             warning ("unexpected r_debug version %d", r_version);
+             warning ("unable to read r_version from 0x%s",
+                      paddress (r_debug + lmo->r_version_offset));
+             break;
            }
-         else if (read_one_ptr (priv->r_debug + lmo->r_map_offset,
-                                &lm_addr, ptr_size) != 0)
+
+         if (r_version < 1)
            {
-             warning ("unable to read r_map from 0x%lx",
-                      (long) priv->r_debug + lmo->r_map_offset);
+             warning ("unexpected r_debug version %d", r_version);
+             break;
            }
-       }
-    }
 
-  std::string document = "<library-list-svr4 version=\"1.0\"";
-
-  while (lm_addr
-        && read_one_ptr (lm_addr + lmo->l_name_offset,
-                         &l_name, ptr_size) == 0
-        && read_one_ptr (lm_addr + lmo->l_addr_offset,
-                         &l_addr, ptr_size) == 0
-        && read_one_ptr (lm_addr + lmo->l_ld_offset,
-                         &l_ld, ptr_size) == 0
-        && read_one_ptr (lm_addr + lmo->l_prev_offset,
-                         &l_prev, ptr_size) == 0
-        && read_one_ptr (lm_addr + lmo->l_next_offset,
-                         &l_next, ptr_size) == 0)
-    {
-      unsigned char libname[PATH_MAX];
+         if (read_one_ptr (r_debug + lmo->r_map_offset, &lm_addr,
+                           ptr_size) != 0)
+           {
+             warning ("unable to read r_map from 0x%s",
+                      paddress (r_debug + lmo->r_map_offset));
+             break;
+           }
 
-      if (lm_prev != l_prev)
-       {
-         warning ("Corrupted shared library list: 0x%lx != 0x%lx",
-                  (long) lm_prev, (long) l_prev);
-         break;
-       }
+         /* We read the entire namespace.  */
+         lm_prev = 0;
 
-      /* Ignore the first entry even if it has valid name as the first entry
-        corresponds to the main executable.  The first entry should not be
-        skipped if the dynamic loader was loaded late by a static executable
-        (see solib-svr4.c parameter ignore_first).  But in such case the main
-        executable does not have PT_DYNAMIC present and this function already
-        exited above due to failed get_r_debug.  */
-      if (lm_prev == 0)
-       string_appendf (document, " main-lm=\"0x%lx\"", (unsigned long) lm_addr);
-      else
-       {
-         /* Not checking for error because reading may stop before
-            we've got PATH_MAX worth of characters.  */
-         libname[0] = '\0';
-         linux_read_memory (l_name, libname, sizeof (libname) - 1);
-         libname[sizeof (libname) - 1] = '\0';
-         if (libname[0] != '\0')
+         /* The first entry corresponds to the main executable unless the
+            dynamic loader was loaded late by a static executable.  But
+            in such case the main executable does not have PT_DYNAMIC
+            present and we would not have gotten here.  */
+         if (r_debug == priv->r_debug)
            {
-             if (!header_done)
+             if (lm_addr != 0)
+               string_appendf (document, " main-lm=\"0x%s\">",
+                               paddress (lm_addr));
+             else
+               document += ">";
+
+             lm_prev = lm_addr;
+             if (read_one_ptr (lm_addr + lmo->l_next_offset,
+                               &lm_addr, ptr_size) != 0)
                {
-                 /* Terminate `<library-list-svr4'.  */
-                 document += '>';
-                 header_done = 1;
+                 warning ("unable to read l_next from 0x%s",
+                          paddress (lm_addr + lmo->l_next_offset));
+                 break;
                }
+           }
+
+         read_link_map (document, r_debug, lm_addr, lm_prev, ptr_size, lmo);
+
+         if (r_version < 2)
+           break;
 
-             string_appendf (document, "<library name=\"");
-             xml_escape_text_append (&document, (char *) libname);
-             string_appendf (document, "\" lm=\"0x%lx\" "
-                             "l_addr=\"0x%lx\" l_ld=\"0x%lx\"/>",
-                             (unsigned long) lm_addr, (unsigned long) l_addr,
-                             (unsigned long) l_ld);
+         if (read_one_ptr (r_debug + lmo->r_next_offset, &r_debug,
+                           ptr_size) != 0)
+           {
+             warning ("unable to read r_next from 0x%s",
+                      paddress (r_debug + lmo->r_next_offset));
+             break;
            }
        }
-
-      lm_prev = lm_addr;
-      lm_addr = l_next;
     }
 
-  if (!header_done)
-    {
-      /* Empty list; terminate `<library-list-svr4'.  */
-      document += "/>";
-    }
-  else
-    document += "</library-list-svr4>";
+  document += "</library-list-svr4>";
 
   int document_len = document.length ();
   if (offset < document_len)
@@ -7191,11 +6714,17 @@ linux_process_target::qxfer_libraries_svr4 (const char *annex,
 
 #ifdef HAVE_LINUX_BTRACE
 
+bool
+linux_process_target::supports_btrace ()
+{
+  return true;
+}
+
 btrace_target_info *
-linux_process_target::enable_btrace (ptid_t ptid,
+linux_process_target::enable_btrace (thread_info *tp,
                                     const btrace_config *conf)
 {
-  return linux_enable_btrace (ptid, conf);
+  return linux_enable_btrace (tp->id, conf);
 }
 
 /* See to_disable_btrace target method.  */
@@ -7212,38 +6741,38 @@ linux_process_target::disable_btrace (btrace_target_info *tinfo)
 /* Encode an Intel Processor Trace configuration.  */
 
 static void
-linux_low_encode_pt_config (struct buffer *buffer,
+linux_low_encode_pt_config (std::string *buffer,
                            const struct btrace_data_pt_config *config)
 {
-  buffer_grow_str (buffer, "<pt-config>\n");
+  *buffer += "<pt-config>\n";
 
   switch (config->cpu.vendor)
     {
     case CV_INTEL:
-      buffer_xml_printf (buffer, "<cpu vendor=\"GenuineIntel\" family=\"%u\" "
-                        "model=\"%u\" stepping=\"%u\"/>\n",
-                        config->cpu.family, config->cpu.model,
-                        config->cpu.stepping);
+      string_xml_appendf (*buffer, "<cpu vendor=\"GenuineIntel\" family=\"%u\" "
+                         "model=\"%u\" stepping=\"%u\"/>\n",
+                         config->cpu.family, config->cpu.model,
+                         config->cpu.stepping);
       break;
 
     default:
       break;
     }
 
-  buffer_grow_str (buffer, "</pt-config>\n");
+  *buffer += "</pt-config>\n";
 }
 
 /* Encode a raw buffer.  */
 
 static void
-linux_low_encode_raw (struct buffer *buffer, const gdb_byte *data,
+linux_low_encode_raw (std::string *buffer, const gdb_byte *data,
                      unsigned int size)
 {
   if (size == 0)
     return;
 
   /* We use hex encoding - see gdbsupport/rsp-low.h.  */
-  buffer_grow_str (buffer, "<raw>\n");
+  *buffer += "<raw>\n";
 
   while (size-- > 0)
     {
@@ -7252,17 +6781,17 @@ linux_low_encode_raw (struct buffer *buffer, const gdb_byte *data,
       elem[0] = tohex ((*data >> 4) & 0xf);
       elem[1] = tohex (*data++ & 0xf);
 
-      buffer_grow (buffer, elem, 2);
+      buffer->append (elem, 2);
     }
 
-  buffer_grow_str (buffer, "</raw>\n");
+  *buffer += "</raw>\n";
 }
 
 /* See to_read_btrace target method.  */
 
 int
 linux_process_target::read_btrace (btrace_target_info *tinfo,
-                                  buffer *buffer,
+                                  std::string *buffer,
                                   enum btrace_read_type type)
 {
   struct btrace_data btrace;
@@ -7272,9 +6801,9 @@ linux_process_target::read_btrace (btrace_target_info *tinfo,
   if (err != BTRACE_ERR_NONE)
     {
       if (err == BTRACE_ERR_OVERFLOW)
-       buffer_grow_str0 (buffer, "E.Overflow.");
+       *buffer += "E.Overflow.";
       else
-       buffer_grow_str0 (buffer, "E.Generic Error.");
+       *buffer += "E.Generic Error.";
 
       return -1;
     }
@@ -7282,36 +6811,36 @@ linux_process_target::read_btrace (btrace_target_info *tinfo,
   switch (btrace.format)
     {
     case BTRACE_FORMAT_NONE:
-      buffer_grow_str0 (buffer, "E.No Trace.");
+      *buffer += "E.No Trace.";
       return -1;
 
     case BTRACE_FORMAT_BTS:
-      buffer_grow_str (buffer, "<!DOCTYPE btrace SYSTEM \"btrace.dtd\">\n");
-      buffer_grow_str (buffer, "<btrace version=\"1.0\">\n");
+      *buffer += "<!DOCTYPE btrace SYSTEM \"btrace.dtd\">\n";
+      *buffer += "<btrace version=\"1.0\">\n";
 
       for (const btrace_block &block : *btrace.variant.bts.blocks)
-       buffer_xml_printf (buffer, "<block begin=\"0x%s\" end=\"0x%s\"/>\n",
-                          paddress (block.begin), paddress (block.end));
+       string_xml_appendf (*buffer, "<block begin=\"0x%s\" end=\"0x%s\"/>\n",
+                           paddress (block.begin), paddress (block.end));
 
-      buffer_grow_str0 (buffer, "</btrace>\n");
+      *buffer += "</btrace>\n";
       break;
 
     case BTRACE_FORMAT_PT:
-      buffer_grow_str (buffer, "<!DOCTYPE btrace SYSTEM \"btrace.dtd\">\n");
-      buffer_grow_str (buffer, "<btrace version=\"1.0\">\n");
-      buffer_grow_str (buffer, "<pt>\n");
+      *buffer += "<!DOCTYPE btrace SYSTEM \"btrace.dtd\">\n";
+      *buffer += "<btrace version=\"1.0\">\n";
+      *buffer += "<pt>\n";
 
       linux_low_encode_pt_config (buffer, &btrace.variant.pt.config);
 
       linux_low_encode_raw (buffer, btrace.variant.pt.data,
                            btrace.variant.pt.size);
 
-      buffer_grow_str (buffer, "</pt>\n");
-      buffer_grow_str0 (buffer, "</btrace>\n");
+      *buffer += "</pt>\n";
+      *buffer += "</btrace>\n";
       break;
 
     default:
-      buffer_grow_str0 (buffer, "E.Unsupported Trace Format.");
+      *buffer += "E.Unsupported Trace Format.";
       return -1;
     }
 
@@ -7322,12 +6851,12 @@ linux_process_target::read_btrace (btrace_target_info *tinfo,
 
 int
 linux_process_target::read_btrace_conf (const btrace_target_info *tinfo,
-                                       buffer *buffer)
+                                       std::string *buffer)
 {
   const struct btrace_config *conf;
 
-  buffer_grow_str (buffer, "<!DOCTYPE btrace-conf SYSTEM \"btrace-conf.dtd\">\n");
-  buffer_grow_str (buffer, "<btrace-conf version=\"1.0\">\n");
+  *buffer += "<!DOCTYPE btrace-conf SYSTEM \"btrace-conf.dtd\">\n";
+  *buffer += "<btrace-conf version=\"1.0\">\n";
 
   conf = linux_btrace_conf (tinfo);
   if (conf != NULL)
@@ -7338,20 +6867,20 @@ linux_process_target::read_btrace_conf (const btrace_target_info *tinfo,
          break;
 
        case BTRACE_FORMAT_BTS:
-         buffer_xml_printf (buffer, "<bts");
-         buffer_xml_printf (buffer, " size=\"0x%x\"", conf->bts.size);
-         buffer_xml_printf (buffer, " />\n");
+         string_xml_appendf (*buffer, "<bts");
+         string_xml_appendf (*buffer, " size=\"0x%x\"", conf->bts.size);
+         string_xml_appendf (*buffer, " />\n");
          break;
 
        case BTRACE_FORMAT_PT:
-         buffer_xml_printf (buffer, "<pt");
-         buffer_xml_printf (buffer, " size=\"0x%x\"", conf->pt.size);
-         buffer_xml_printf (buffer, "/>\n");
+         string_xml_appendf (*buffer, "<pt");
+         string_xml_appendf (*buffer, " size=\"0x%x\"", conf->pt.size);
+         string_xml_appendf (*buffer, "/>\n");
          break;
        }
     }
 
-  buffer_grow_str0 (buffer, "</btrace-conf>\n");
+  *buffer += "</btrace-conf>\n";
   return 0;
 }
 #endif /* HAVE_LINUX_BTRACE */
@@ -7364,39 +6893,6 @@ current_lwp_ptid (void)
   return ptid_of (current_thread);
 }
 
-/* Implementation of the target_ops method "breakpoint_kind_from_pc".  */
-
-int
-linux_process_target::breakpoint_kind_from_pc (CORE_ADDR *pcptr)
-{
-  if (the_low_target.breakpoint_kind_from_pc != NULL)
-    return (*the_low_target.breakpoint_kind_from_pc) (pcptr);
-  else
-    return process_target::breakpoint_kind_from_pc (pcptr);
-}
-
-/* Implementation of the target_ops method "sw_breakpoint_from_kind".  */
-
-const gdb_byte *
-linux_process_target::sw_breakpoint_from_kind (int kind, int *size)
-{
-  gdb_assert (the_low_target.sw_breakpoint_from_kind != NULL);
-
-  return (*the_low_target.sw_breakpoint_from_kind) (kind, size);
-}
-
-/* Implementation of the target_ops method
-   "breakpoint_kind_from_current_state".  */
-
-int
-linux_process_target::breakpoint_kind_from_current_state (CORE_ADDR *pcptr)
-{
-  if (the_low_target.breakpoint_kind_from_current_state != NULL)
-    return (*the_low_target.breakpoint_kind_from_current_state) (pcptr);
-  else
-    return breakpoint_kind_from_pc (pcptr);
-}
-
 const char *
 linux_process_target::thread_name (ptid_t thread)
 {
@@ -7412,6 +6908,28 @@ linux_process_target::thread_handle (ptid_t ptid, gdb_byte **handle,
 }
 #endif
 
+thread_info *
+linux_process_target::thread_pending_parent (thread_info *thread)
+{
+  lwp_info *parent = get_thread_lwp (thread)->pending_parent ();
+
+  if (parent == nullptr)
+    return nullptr;
+
+  return get_lwp_thread (parent);
+}
+
+thread_info *
+linux_process_target::thread_pending_child (thread_info *thread)
+{
+  lwp_info *child = get_thread_lwp (thread)->pending_child ();
+
+  if (child == nullptr)
+    return nullptr;
+
+  return get_lwp_thread (child);
+}
+
 /* Default implementation of linux_target_ops method "set_pc" for
    32-bit pc register which is literally named "pc".  */
 
@@ -7432,8 +6950,7 @@ linux_get_pc_32bit (struct regcache *regcache)
   uint32_t pc;
 
   collect_register_by_name (regcache, "pc", &pc);
-  if (debug_threads)
-    debug_printf ("stop pc is 0x%" PRIx32 "\n", pc);
+  threads_debug_printf ("stop pc is 0x%" PRIx32, pc);
   return pc;
 }
 
@@ -7457,22 +6974,22 @@ linux_get_pc_64bit (struct regcache *regcache)
   uint64_t pc;
 
   collect_register_by_name (regcache, "pc", &pc);
-  if (debug_threads)
-    debug_printf ("stop pc is 0x%" PRIx64 "\n", pc);
+  threads_debug_printf ("stop pc is 0x%" PRIx64, pc);
   return pc;
 }
 
 /* See linux-low.h.  */
 
 int
-linux_get_auxv (int wordsize, CORE_ADDR match, CORE_ADDR *valp)
+linux_get_auxv (int pid, int wordsize, CORE_ADDR match, CORE_ADDR *valp)
 {
   gdb_byte *data = (gdb_byte *) alloca (2 * wordsize);
   int offset = 0;
 
   gdb_assert (wordsize == 4 || wordsize == 8);
 
-  while (the_target->pt->read_auxv (offset, data, 2 * wordsize) == 2 * wordsize)
+  while (the_target->read_auxv (pid, offset, data, 2 * wordsize)
+        == 2 * wordsize)
     {
       if (wordsize == 4)
        {
@@ -7502,32 +7019,23 @@ linux_get_auxv (int wordsize, CORE_ADDR match, CORE_ADDR *valp)
 /* See linux-low.h.  */
 
 CORE_ADDR
-linux_get_hwcap (int wordsize)
+linux_get_hwcap (int pid, int wordsize)
 {
   CORE_ADDR hwcap = 0;
-  linux_get_auxv (wordsize, AT_HWCAP, &hwcap);
+  linux_get_auxv (pid, wordsize, AT_HWCAP, &hwcap);
   return hwcap;
 }
 
 /* See linux-low.h.  */
 
 CORE_ADDR
-linux_get_hwcap2 (int wordsize)
+linux_get_hwcap2 (int pid, int wordsize)
 {
   CORE_ADDR hwcap2 = 0;
-  linux_get_auxv (wordsize, AT_HWCAP2, &hwcap2);
+  linux_get_auxv (pid, wordsize, AT_HWCAP2, &hwcap2);
   return hwcap2;
 }
 
-/* The linux target ops object.  */
-
-static linux_process_target the_linux_target;
-
-static process_stratum_target linux_target_ops = {
-  linux_get_ipa_tdesc_idx,
-  &the_linux_target,
-};
-
 #ifdef HAVE_LINUX_REGSETS
 void
 initialize_regsets_info (struct regsets_info *info)
@@ -7545,7 +7053,7 @@ initialize_low (void)
   struct sigaction sigchld_action;
 
   memset (&sigchld_action, 0, sizeof (sigchld_action));
-  set_target_ops (&linux_target_ops);
+  set_target_ops (the_linux_target);
 
   linux_ptrace_init_warnings ();
   linux_proc_init_warnings ();