gnulib: define the path to gnulib's parent dir
[binutils-gdb.git] / gdbserver / linux-low.cc
index b3f87947ff682ccef100cb62b315e372d31dec61..5c6191d941c3261d829198fc1ac451b050e7bc75 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-2021 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #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)
@@ -211,7 +199,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 +246,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;
@@ -268,10 +256,8 @@ int using_threads = 1;
 static int stabilizing_threads;
 
 static void unsuspend_all_lwps (struct lwp_info *except);
-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 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 int linux_low_ptrace_options (int attached);
@@ -279,18 +265,7 @@ static int check_ptrace_stopped_lwp_gone (struct lwp_info *lp);
 
 /* 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 int
-can_hardware_single_step (void)
-{
-  if (the_low_target.supports_hardware_single_step != NULL)
-    return the_low_target.supports_hardware_single_step ();
-  else
-    return 0;
-}
+static ptid_t step_over_bkpt;
 
 bool
 linux_process_target::low_supports_breakpoints ()
@@ -323,16 +298,6 @@ linux_process_target::low_decr_pc_after_break ()
   return 0;
 }
 
-/* Returns true if this target can support fast tracepoints.  This
-   does not mean that the in-process agent has been loaded in the
-   inferior.  */
-
-static int
-supports_fast_tracepoints (void)
-{
-  return the_low_target.install_fast_tracepoint_jump_pad != NULL;
-}
-
 /* True if LWP is stopped in its stepping range.  */
 
 static int
@@ -343,13 +308,6 @@ 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 };
@@ -413,8 +371,8 @@ 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);
 
@@ -423,31 +381,52 @@ delete_lwp (struct lwp_info *lwp)
 
   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);
 
-  free (lwp);
+  delete lwp;
 }
 
-/* Add a process to the common process list, and set its private
-   data.  */
+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);
+}
 
-static struct process_info *
-linux_add_process (int pid, int attached)
+process_info *
+linux_process_target::add_linux_process (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 ();
 
   return proc;
 }
 
+arch_process_info *
+linux_process_target::low_new_process ()
+{
+  return nullptr;
+}
+
+void
+linux_process_target::low_delete_process (arch_process_info *info)
+{
+  /* Default implementation must be overridden if architecture-specific
+     info exists.  */
+  gdb_assert (info == nullptr);
+}
+
+void
+linux_process_target::low_new_fork (process_info *parent, process_info *child)
+{
+  /* Nop.  */
+}
+
 void
 linux_process_target::arch_setup_thread (thread_info *thread)
 {
@@ -511,7 +490,6 @@ linux_process_target::handle_extended_wait (lwp_info **orig_event_lwp,
          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);
 
@@ -528,7 +506,7 @@ linux_process_target::handle_extended_wait (lwp_info **orig_event_lwp,
             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);
@@ -567,13 +545,12 @@ linux_process_target::handle_extended_wait (lwp_info **orig_event_lwp,
 
          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)
@@ -700,7 +677,7 @@ linux_process_target::handle_extended_wait (lwp_info **orig_event_lwp,
       current_thread = NULL;
 
       /* 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);
@@ -757,28 +734,17 @@ linux_process_target::get_pc (lwp_info *lwp)
   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);
 
   regcache = get_thread_regcache (current_thread, 1);
-  (*the_low_target.get_syscall_trapinfo) (regcache, sysno);
+  low_get_syscall_trapinfo (regcache, sysno);
 
   if (debug_threads)
     debug_printf ("get_syscall_trapinfo sysno %d\n", *sysno);
@@ -786,7 +752,12 @@ get_syscall_trapinfo (struct lwp_info *lwp, int *sysno)
   current_thread = saved_thread;
 }
 
-static int check_stopped_by_watchpoint (struct lwp_info *child);
+void
+linux_process_target::low_get_syscall_trapinfo (regcache *regcache, int *sysno)
+{
+  /* By default, report an unknown system call number.  */
+  *sysno = UNKNOWN_SYSCALL;
+}
 
 bool
 linux_process_target::save_stop_reason (lwp_info *lwp)
@@ -923,23 +894,28 @@ linux_process_target::save_stop_reason (lwp_info *lwp)
   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 = new lwp_info {};
 
   lwp->waitstatus.kind = TARGET_WAITKIND_IGNORE;
 
   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.  */
 
@@ -988,7 +964,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 (),
@@ -996,7 +972,7 @@ linux_process_target::create_inferior (const char *program,
                         NULL, NULL, NULL, NULL);
   }
 
-  linux_add_process (pid, 0);
+  add_linux_process (pid, 0);
 
   ptid = ptid_t (pid, pid, 0);
   new_lwp = add_lwp (ptid);
@@ -1026,11 +1002,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 ();
@@ -1127,7 +1100,7 @@ attach_proc_task_lwp_callback (ptid_t ptid)
       if (debug_threads)
        debug_printf ("Found new lwp %d\n", 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
@@ -1169,11 +1142,11 @@ linux_process_target::attach (unsigned long pid)
   ptid_t ptid = ptid_t (pid, pid, 0);
   int err;
 
-  proc = linux_add_process (pid, 1);
+  proc = add_linux_process (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);
@@ -1481,10 +1454,8 @@ get_detach_signal (struct thread_info *thread)
     }
 }
 
-/* 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;
@@ -1513,8 +1484,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)
     {
@@ -1566,22 +1536,6 @@ linux_detach_one_lwp (struct lwp_info *lwp)
   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)
 {
@@ -1608,10 +1562,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);
 
@@ -1632,17 +1596,14 @@ linux_process_target::mourn (process_info *process)
   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);
+  low_delete_process (priv->arch_private);
   free (priv);
   process->priv = NULL;
 
@@ -1834,13 +1795,10 @@ 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)
+void
+linux_process_target::check_zombie_leaders ()
 {
-  for_each_process ([] (process_info *proc) {
+  for_each_process ([this] (process_info *proc) {
     pid_t leader_pid = pid_of (proc);
     struct lwp_info *leader_lp;
 
@@ -1993,29 +1951,29 @@ handle_tracepoints (struct lwp_info *lwp)
   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);
 }
 
+int
+linux_process_target::low_get_thread_area (int lwpid, CORE_ADDR *addrp)
+{
+  return -1;
+}
+
 bool
 linux_process_target::maybe_move_out_of_jump_pad (lwp_info *lwp, int *wstat)
 {
@@ -2146,7 +2104,6 @@ linux_process_target::maybe_move_out_of_jump_pad (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)
@@ -2155,13 +2112,9 @@ enqueue_one_deferred_signal (struct lwp_info *lwp, int *wstat)
 
   if (debug_threads)
     {
-      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)
        debug_printf ("   Already queued %d\n",
-                     sig->signal);
+                     sig.signal);
 
       debug_printf ("   (no more currently queued signals)\n");
     }
@@ -2171,32 +2124,24 @@ 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,
+                             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
@@ -2207,20 +2152,16 @@ 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);
+
+      lwp->pending_signals_to_report.pop_front ();
 
       if (debug_threads)
        debug_printf ("Reporting deferred signal %d for LWP %ld.\n",
@@ -2228,13 +2169,9 @@ dequeue_one_deferred_signal (struct lwp_info *lwp, int *wstat)
 
       if (debug_threads)
        {
-         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)
            debug_printf ("   Still queued %d\n",
-                         sig->signal);
+                         sig.signal);
 
          debug_printf ("   (no more queued signals)\n");
        }
@@ -2245,46 +2182,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;
+  struct thread_info *saved_thread = current_thread;
+  current_thread = get_lwp_thread (child);
 
-      saved_thread = current_thread;
-      current_thread = get_lwp_thread (child);
+  if (low_stopped_by_watchpoint ())
+    {
+      child->stop_reason = TARGET_STOPPED_BY_WATCHPOINT;
+      child->stopped_data_address = low_stopped_data_address ();
+    }
 
-      if (the_low_target.stopped_by_watchpoint ())
-       {
-         child->stop_reason = TARGET_STOPPED_BY_WATCHPOINT;
+  current_thread = saved_thread;
 
-         if (the_low_target.stopped_data_address != NULL)
-           child->stopped_data_address
-             = the_low_target.stopped_data_address ();
-         else
-           child->stopped_data_address = 0;
-       }
+  return child->stop_reason == TARGET_STOPPED_BY_WATCHPOINT;
+}
 
-      current_thread = saved_thread;
-    }
+bool
+linux_process_target::low_stopped_by_watchpoint ()
+{
+  return false;
+}
 
-  return child->stop_reason == TARGET_STOPPED_BY_WATCHPOINT;
+CORE_ADDR
+linux_process_target::low_stopped_data_address ()
+{
+  return 0;
 }
 
 /* Return the ptrace options that we want to try to enable.  */
@@ -2312,7 +2236,7 @@ linux_low_ptrace_options (int attached)
   return options;
 }
 
-lwp_info *
+void
 linux_process_target::filter_event (int lwpid, int wstat)
 {
   client_state &cs = get_client_state ();
@@ -2361,10 +2285,10 @@ linux_process_target::filter_event (int lwpid, int wstat)
   if (child == NULL && WIFSTOPPED (wstat))
     {
       add_to_pid_list (&stopped_pids, lwpid, wstat);
-      return NULL;
+      return;
     }
   else if (child == NULL)
-    return NULL;
+    return;
 
   thread = get_lwp_thread (child);
 
@@ -2394,12 +2318,12 @@ linux_process_target::filter_event (int lwpid, int wstat)
             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;
        }
     }
 
@@ -2427,7 +2351,7 @@ linux_process_target::filter_event (int lwpid, int wstat)
                 the first instruction.  */
              child->status_pending_p = 1;
              child->status_pending = wstat;
-             return child;
+             return;
            }
        }
     }
@@ -2466,7 +2390,7 @@ linux_process_target::filter_event (int lwpid, int wstat)
        {
          /* The event has been handled, so just return without
             reporting it.  */
-         return NULL;
+         return;
        }
     }
 
@@ -2502,7 +2426,7 @@ linux_process_target::filter_event (int lwpid, int wstat)
            debug_printf ("LLW: SIGSTOP caught for %s "
                          "while stopping threads.\n",
                          target_pid_to_str (ptid_of (thread)));
-         return NULL;
+         return;
        }
       else
        {
@@ -2513,28 +2437,26 @@ linux_process_target::filter_event (int lwpid, int wstat)
                          target_pid_to_str (ptid_of (thread)));
 
          resume_one_lwp (child, child->stepping, 0, NULL);
-         return 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;
     }
 }
 
@@ -2679,7 +2601,7 @@ linux_process_target::wait_for_event_filtered (ptid_t wait_ptid,
          if (debug_threads)
            {
              debug_printf ("LLW: waitpid %ld received %s\n",
-                           (long) ret, status_to_str (*wstatp));
+                           (long) ret, status_to_str (*wstatp).c_str ());
            }
 
          /* Filter all events.  IOW, leave all events pending.  We'll
@@ -2807,7 +2729,7 @@ select_event_lwp (struct lwp_info **orig_lp)
   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)
        {
@@ -2843,7 +2765,6 @@ unsuspend_all_lwps (struct lwp_info *except)
     });
 }
 
-static bool stuck_in_jump_pad_callback (thread_info *thread);
 static bool lwp_running (thread_info *thread);
 
 /* Stabilize threads (move out of jump pads).
@@ -2879,7 +2800,10 @@ static bool lwp_running (thread_info *thread);
 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)
     {
@@ -2935,7 +2859,10 @@ linux_process_target::stabilize_threads ()
 
   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",
@@ -2958,14 +2885,9 @@ ignore_event (struct target_waitstatus *ourstatus)
   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);
@@ -2994,34 +2916,31 @@ 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;
 }
 
 ptid_t
 linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus,
-                             int target_options)
+                             target_wait_flags target_options)
 {
   client_state &cs = get_client_state ();
   int w;
@@ -3359,7 +3278,7 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus,
   /* 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)
        {
@@ -3783,7 +3702,7 @@ async_file_mark (void)
 ptid_t
 linux_process_target::wait (ptid_t ptid,
                            target_waitstatus *ourstatus,
-                           int target_options)
+                           target_wait_flags target_options)
 {
   ptid_t event_ptid;
 
@@ -3963,13 +3882,8 @@ linux_process_target::wait_for_sigstop ()
     }
 }
 
-/* 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);
 
@@ -4100,15 +4014,11 @@ linux_process_target::stop_all_lwps (int suspend, 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;
 }
 
 void
@@ -4131,7 +4041,7 @@ linux_process_target::single_step (lwp_info* lwp)
 {
   int step = 0;
 
-  if (can_hardware_single_step ())
+  if (supports_hardware_single_step ())
     {
       step = 1;
     }
@@ -4204,7 +4114,7 @@ linux_process_target::resume_one_lwp_throw (lwp_info *lwp, int step,
      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);
@@ -4242,7 +4152,7 @@ linux_process_target::resume_one_lwp_throw (lwp_info *lwp, int step,
        debug_printf ("  pending reinsert at 0x%s\n",
                      paddress (lwp->bp_reinsert));
 
-      if (can_hardware_single_step ())
+      if (supports_hardware_single_step ())
        {
          if (fast_tp_collecting == fast_tpoint_collect_result::not_collecting)
            {
@@ -4271,7 +4181,7 @@ linux_process_target::resume_one_lwp_throw (lwp_info *lwp, int step,
                      " single-stepping\n",
                      lwpid_of (thread));
 
-      if (can_hardware_single_step ())
+      if (supports_hardware_single_step ())
        step = 1;
       else
        {
@@ -4313,21 +4223,16 @@ linux_process_target::resume_one_lwp_throw (lwp_info *lwp, int step,
 
   /* 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)
@@ -4335,8 +4240,7 @@ linux_process_target::resume_one_lwp_throw (lwp_info *lwp, int step,
                  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;
@@ -4368,6 +4272,12 @@ linux_process_target::resume_one_lwp_throw (lwp_info *lwp, int step,
   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
@@ -4615,7 +4525,7 @@ linux_process_target::thread_needs_step_over (thread_info *thread)
   /* On software single step target, resume the inferior with signal
      rather than stepping over.  */
   if (supports_software_single_step ()
-      && lwp->pending_signals != NULL
+      && !lwp->pending_signals.empty ()
       && lwp_signal_can_be_delivered (lwp))
     {
       if (debug_threads)
@@ -4719,12 +4629,8 @@ linux_process_target::start_step_over (lwp_info *lwp)
   step_over_bkpt = thread->id;
 }
 
-/* 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)
     {
@@ -4747,7 +4653,7 @@ 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);
@@ -4755,10 +4661,10 @@ finish_step_over (struct lwp_info *lwp)
 
       step_over_bkpt = null_ptid;
       current_thread = saved_thread;
-      return 1;
+      return true;
     }
   else
-    return 0;
+    return false;
 }
 
 void
@@ -4782,7 +4688,34 @@ linux_process_target::complete_ongoing_step_over ()
 
       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)
+               {
+                 if (debug_threads)
+                   debug_printf ("detach: discard step-over SIGTRAP\n");
+
+                 lwp->status_pending_p = 0;
+                 lwp->status_pending = 0;
+                 resume_one_lwp (lwp, lwp->stepping, 0, NULL);
+               }
+             else
+               {
+                 if (debug_threads)
+                   debug_printf ("detach: resume_step, "
+                                 "not discarding step-over SIGTRAP\n");
+               }
+           }
+       }
       step_over_bkpt = null_ptid;
       unsuspend_all_lwps (lwp);
     }
@@ -4836,7 +4769,7 @@ linux_process_target::resume_one_thread (thread_info *thread,
             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);
        }
 
@@ -5015,7 +4948,7 @@ linux_process_target::proceed_one_lwp (thread_info *thread, lwp_info *except)
     }
 
   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))
     {
@@ -5423,10 +5356,7 @@ linux_process_target::fetch_register (const 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);
 }
 
 void
@@ -5453,10 +5383,7 @@ linux_process_target::store_register (const 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))
@@ -5485,6 +5412,20 @@ linux_process_target::store_register (const usrregs_info *usrregs,
 }
 #endif /* HAVE_LINUX_USRREGS */
 
+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,
@@ -5829,28 +5770,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
@@ -5859,11 +5794,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
@@ -5911,7 +5851,7 @@ linux_process_target::supports_stopped_by_hw_breakpoint ()
 bool
 linux_process_target::supports_hardware_single_step ()
 {
-  return can_hardware_single_step ();
+  return true;
 }
 
 bool
@@ -6024,16 +5964,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.  */
@@ -6046,6 +5981,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 ()
 {
@@ -6169,7 +6111,8 @@ linux_process_target::async (bool enable)
 
          /* Register the event loop handler.  */
          add_file_handler (linux_event_pipe[0],
-                           handle_target_event, NULL);
+                           handle_target_event, NULL,
+                           "linux-low");
 
          /* Always trigger a linux_wait.  */
          async_file_mark ();
@@ -6281,11 +6224,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
@@ -6299,10 +6238,14 @@ linux_process_target::supports_range_stepping ()
 {
   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
@@ -6311,7 +6254,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);
@@ -6425,36 +6368,17 @@ 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
+  return (low_supports_catch_syscall ()
          && linux_supports_tracesysgood ());
 }
 
-int
-linux_process_target::get_ipa_tdesc_idx ()
-{
-  if (the_low_target.get_ipa_tdesc_idx == NULL)
-    return 0;
-
-  return (*the_low_target.get_ipa_tdesc_idx) ();
-}
-
 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
@@ -6522,44 +6446,6 @@ linux_process_target::done_accessing_memory ()
     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