Multi-target support
[deliverable/binutils-gdb.git] / gdb / gdbserver / linux-low.c
index ea3c81b8476b7b3095fb77003733c65a3f42670e..676dea26c637afbd0a146f78810f20ccbda0b830 100644 (file)
@@ -1,5 +1,5 @@
 /* Low level interface to ptrace, for the remote server for GDB.
-   Copyright (C) 1995-2017 Free Software Foundation, Inc.
+   Copyright (C) 1995-2020 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "server.h"
 #include "linux-low.h"
 #include "nat/linux-osdata.h"
-#include "agent.h"
+#include "gdbsupport/agent.h"
 #include "tdesc.h"
-#include "rsp-low.h"
-#include "signals-state-save-restore.h"
+#include "gdbsupport/rsp-low.h"
+#include "gdbsupport/signals-state-save-restore.h"
 #include "nat/linux-nat.h"
 #include "nat/linux-waitpid.h"
-#include "gdb_wait.h"
+#include "gdbsupport/gdb_wait.h"
 #include "nat/gdb_ptrace.h"
 #include "nat/linux-ptrace.h"
 #include "nat/linux-procfs.h"
 #include <sys/stat.h>
 #include <sys/vfs.h>
 #include <sys/uio.h>
-#include "filestuff.h"
+#include "gdbsupport/filestuff.h"
 #include "tracepoint.h"
 #include "hostio.h"
 #include <inttypes.h>
+#include "gdbsupport/common-inferior.h"
+#include "nat/fork-inferior.h"
+#include "gdbsupport/environ.h"
+#include "gdbsupport/gdb-sigmask.h"
+#include "gdbsupport/scoped_restore.h"
 #ifndef ELFMAG0
 /* Don't include <linux/elf.h> here.  If it got included by gdb_proc_service.h
    then ELFMAG0 will have been defined.  If it didn't get included by
 #endif
 #include "nat/linux-namespaces.h"
 
-#ifndef SPUFS_MAGIC
-#define SPUFS_MAGIC 0x23c9b64e
-#endif
-
 #ifdef HAVE_PERSONALITY
 # include <sys/personality.h>
 # if !HAVE_DECL_ADDR_NO_RANDOMIZE
 #define O_LARGEFILE 0
 #endif
 
+#ifndef AT_HWCAP2
+#define AT_HWCAP2 26
+#endif
+
 /* Some targets did not define these ptrace constants from the start,
    so gdbserver defines them locally here.  In the future, these may
    be removed after they are added to asm/ptrace.h.  */
 
 #ifdef HAVE_LINUX_BTRACE
 # include "nat/linux-btrace.h"
-# include "btrace-common.h"
+# include "gdbsupport/btrace-common.h"
 #endif
 
 #ifndef HAVE_ELF32_AUXV_T
@@ -276,7 +281,7 @@ static void enqueue_pending_signal (struct lwp_info *lwp, int signal, siginfo_t
 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 int proceed_one_lwp (struct inferior_list_entry *entry, void *except);
+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.  */
@@ -411,7 +416,12 @@ delete_lwp (struct lwp_info *lwp)
     debug_printf ("deleting %ld\n", lwpid_of (thr));
 
   remove_thread (thr);
-  free (lwp->arch_private);
+
+  if (the_low_target.delete_thread != NULL)
+    the_low_target.delete_thread (lwp->arch_private);
+  else
+    gdb_assert (lwp->arch_private == NULL);
+
   free (lwp);
 }
 
@@ -466,6 +476,7 @@ linux_arch_setup_thread (struct thread_info *thread)
 static int
 handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat)
 {
+  client_state &cs = get_client_state ();
   struct lwp_info *event_lwp = *orig_event_lwp;
   int event = linux_ptrace_get_extended_event (wstat);
   struct thread_info *event_thr = get_lwp_thread (event_lwp);
@@ -513,14 +524,14 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat)
          struct thread_info *child_thr;
          struct target_desc *tdesc;
 
-         ptid = ptid_build (new_pid, new_pid, 0);
+         ptid = ptid_t (new_pid, new_pid, 0);
 
          if (debug_threads)
            {
              debug_printf ("HEW: Got fork event from LWP %ld, "
                            "new child is %d\n",
-                           ptid_get_lwp (ptid_of (event_thr)),
-                           ptid_get_pid (ptid));
+                           ptid_of (event_thr).lwp (),
+                           ptid.pid ());
            }
 
          /* Add the new process to the tables and clone the breakpoint
@@ -567,7 +578,7 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat)
 
          clone_all_breakpoints (child_thr, event_thr);
 
-         tdesc = XNEW (struct target_desc);
+         tdesc = allocate_target_description ();
          copy_target_description (tdesc, parent_proc->tdesc);
          child_proc->tdesc = tdesc;
 
@@ -620,7 +631,7 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat)
                      "from LWP %ld, new child is LWP %ld\n",
                      lwpid_of (event_thr), new_pid);
 
-      ptid = ptid_build (pid_of (event_thr), new_pid, 0);
+      ptid = ptid_t (pid_of (event_thr), new_pid, 0);
       new_lwp = add_lwp (ptid);
 
       /* Either we're going to immediately resume the new thread
@@ -646,13 +657,17 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat)
          new_lwp->status_pending_p = 1;
          new_lwp->status_pending = status;
        }
-      else if (report_thread_events)
+      else if (cs.report_thread_events)
        {
          new_lwp->waitstatus.kind = TARGET_WAITKIND_THREAD_CREATED;
          new_lwp->status_pending_p = 1;
          new_lwp->status_pending = status;
        }
 
+#ifdef USE_THREAD_DB
+      thread_db_notice_clone (event_thr, ptid);
+#endif
+
       /* Don't report the event.  */
       return 1;
     }
@@ -670,10 +685,10 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat)
       /* Report the event.  */
       return 0;
     }
-  else if (event == PTRACE_EVENT_EXEC && report_exec_events)
+  else if (event == PTRACE_EVENT_EXEC && cs.report_exec_events)
     {
       struct process_info *proc;
-      VEC (int) *syscalls_to_catch;
+      std::vector<int> syscalls_to_catch;
       ptid_t event_ptid;
       pid_t event_pid;
 
@@ -685,12 +700,11 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat)
 
       /* Get the event ptid.  */
       event_ptid = ptid_of (event_thr);
-      event_pid = ptid_get_pid (event_ptid);
+      event_pid = event_ptid.pid ();
 
       /* Save the syscall list from the execing process.  */
       proc = get_thread_process (event_thr);
-      syscalls_to_catch = proc->syscalls_to_catch;
-      proc->syscalls_to_catch = NULL;
+      syscalls_to_catch = std::move (proc->syscalls_to_catch);
 
       /* Delete the execing process and all its threads.  */
       linux_mourn (proc);
@@ -721,7 +735,7 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat)
       /* Restore the list to catch.  Don't rely on the client, which is free
         to avoid sending a new list when the architecture doesn't change.
         Also, for ANY_SYSCALL, the architecture doesn't really matter.  */
-      proc->syscalls_to_catch = syscalls_to_catch;
+      proc->syscalls_to_catch = std::move (syscalls_to_catch);
 
       /* Report the event.  */
       *orig_event_lwp = event_lwp;
@@ -938,76 +952,78 @@ add_lwp (ptid_t ptid)
 
   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);
 
-  lwp->thread = add_thread (ptid, lwp);
-
   return lwp;
 }
 
+/* Callback to be used when calling fork_inferior, responsible for
+   actually initiating the tracing of the inferior.  */
+
+static void
+linux_ptrace_fun ()
+{
+  if (ptrace (PTRACE_TRACEME, 0, (PTRACE_TYPE_ARG3) 0,
+             (PTRACE_TYPE_ARG4) 0) < 0)
+    trace_start_error_with_name ("ptrace");
+
+  if (setpgid (0, 0) < 0)
+    trace_start_error_with_name ("setpgid");
+
+  /* If GDBserver is connected to gdb via stdio, redirect the inferior's
+     stdout to stderr so that inferior i/o doesn't corrupt the connection.
+     Also, redirect stdin to /dev/null.  */
+  if (remote_connection_is_stdio ())
+    {
+      if (close (0) < 0)
+       trace_start_error_with_name ("close");
+      if (open ("/dev/null", O_RDONLY) < 0)
+       trace_start_error_with_name ("open");
+      if (dup2 (2, 1) < 0)
+       trace_start_error_with_name ("dup2");
+      if (write (2, "stdin/stdout redirected\n",
+                sizeof ("stdin/stdout redirected\n") - 1) < 0)
+       {
+         /* Errors ignored.  */;
+       }
+    }
+}
+
 /* Start an inferior process and returns its pid.
-   ALLARGS is a vector of program-name and args. */
+   PROGRAM is the name of the program to be started, and PROGRAM_ARGS
+   are its arguments.  */
 
 static int
-linux_create_inferior (char *program, char **allargs)
+linux_create_inferior (const char *program,
+                      const std::vector<char *> &program_args)
 {
+  client_state &cs = get_client_state ();
   struct lwp_info *new_lwp;
   int pid;
   ptid_t ptid;
-  struct cleanup *restore_personality
-    = maybe_disable_address_space_randomization (disable_randomization);
-
-#if defined(__UCLIBC__) && defined(HAS_NOMMU)
-  pid = vfork ();
-#else
-  pid = fork ();
-#endif
-  if (pid < 0)
-    perror_with_name ("fork");
-
-  if (pid == 0)
-    {
-      close_most_fds ();
-      ptrace (PTRACE_TRACEME, 0, (PTRACE_TYPE_ARG3) 0, (PTRACE_TYPE_ARG4) 0);
-
-      setpgid (0, 0);
 
-      /* If gdbserver is connected to gdb via stdio, redirect the inferior's
-        stdout to stderr so that inferior i/o doesn't corrupt the connection.
-        Also, redirect stdin to /dev/null.  */
-      if (remote_connection_is_stdio ())
-       {
-         close (0);
-         open ("/dev/null", O_RDONLY);
-         dup2 (2, 1);
-         if (write (2, "stdin/stdout redirected\n",
-                    sizeof ("stdin/stdout redirected\n") - 1) < 0)
-           {
-             /* Errors ignored.  */;
-           }
-       }
-
-      restore_original_signals_state ();
-
-      execv (program, allargs);
-      if (errno == ENOENT)
-       execvp (program, allargs);
-
-      fprintf (stderr, "Cannot exec %s: %s.\n", program,
-              strerror (errno));
-      fflush (stderr);
-      _exit (0177);
-    }
+  {
+    maybe_disable_address_space_randomization restore_personality
+      (cs.disable_randomization);
+    std::string str_program_args = stringify_argv (program_args);
 
-  do_cleanups (restore_personality);
+    pid = fork_inferior (program,
+                        str_program_args.c_str (),
+                        get_environ ()->envp (), linux_ptrace_fun,
+                        NULL, NULL, NULL, NULL);
+  }
 
   linux_add_process (pid, 0);
 
-  ptid = ptid_build (pid, pid, 0);
+  ptid = ptid_t (pid, pid, 0);
   new_lwp = add_lwp (ptid);
   new_lwp->must_set_ptrace_flags = 1;
 
+  post_fork_inferior (pid, program);
+
   return pid;
 }
 
@@ -1037,7 +1053,7 @@ int
 linux_attach_lwp (ptid_t ptid)
 {
   struct lwp_info *new_lwp;
-  int lwpid = ptid_get_lwp (ptid);
+  int lwpid = ptid.lwp ();
 
   if (ptrace (PTRACE_ATTACH, lwpid, (PTRACE_TYPE_ARG3) 0, (PTRACE_TYPE_ARG4) 0)
       != 0)
@@ -1125,7 +1141,7 @@ attach_proc_task_lwp_callback (ptid_t ptid)
   /* Is this a new thread?  */
   if (find_thread_ptid (ptid) == NULL)
     {
-      int lwpid = ptid_get_lwp (ptid);
+      int lwpid = ptid.lwp ();
       int err;
 
       if (debug_threads)
@@ -1144,14 +1160,15 @@ attach_proc_task_lwp_callback (ptid_t ptid)
            {
              debug_printf ("Cannot attach to lwp %d: "
                            "thread is gone (%d: %s)\n",
-                           lwpid, err, strerror (err));
+                           lwpid, err, safe_strerror (err));
            }
        }
       else if (err != 0)
        {
-         warning (_("Cannot attach to lwp %d: %s"),
-                  lwpid,
-                  linux_ptrace_attach_fail_reason_string (ptid, err));
+         std::string reason
+           = linux_ptrace_attach_fail_reason_string (ptid, err);
+
+         warning (_("Cannot attach to lwp %d: %s"), lwpid, reason.c_str ());
        }
 
       return 1;
@@ -1169,21 +1186,25 @@ linux_attach (unsigned long pid)
 {
   struct process_info *proc;
   struct thread_info *initial_thread;
-  ptid_t ptid = ptid_build (pid, pid, 0);
+  ptid_t ptid = ptid_t (pid, pid, 0);
   int err;
 
+  proc = linux_add_process (pid, 1);
+
   /* Attach to PID.  We will check for other threads
      soon.  */
   err = linux_attach_lwp (ptid);
   if (err != 0)
-    error ("Cannot attach to process %ld: %s",
-          pid, linux_ptrace_attach_fail_reason_string (ptid, err));
+    {
+      remove_process (proc);
 
-  proc = linux_add_process (pid, 1);
+      std::string reason = linux_ptrace_attach_fail_reason_string (ptid, err);
+      error ("Cannot attach to process %ld: %s", pid, reason.c_str ());
+    }
 
   /* 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_build (pid, pid, 0));
+  initial_thread = find_thread_ptid (ptid_t (pid, pid, 0));
   initial_thread->last_resume_kind = resume_stop;
 
   /* We must attach to every LWP.  If /proc is mounted, use that to
@@ -1207,13 +1228,13 @@ linux_attach (unsigned long pid)
     {
       struct lwp_info *lwp;
       int wstat, lwpid;
-      ptid_t pid_ptid = pid_to_ptid (pid);
+      ptid_t pid_ptid = ptid_t (pid);
 
       lwpid = linux_wait_for_event_filtered (pid_ptid, pid_ptid,
                                             &wstat, __WALL);
       gdb_assert (lwpid > 0);
 
-      lwp = find_lwp_pid (pid_to_ptid (lwpid));
+      lwp = find_lwp_pid (ptid_t (lwpid));
 
       if (!WIFSTOPPED (wstat) || WSTOPSIG (wstat) != SIGSTOP)
        {
@@ -1231,33 +1252,27 @@ linux_attach (unsigned long pid)
   return 0;
 }
 
-struct counter
-{
-  int pid;
-  int count;
-};
-
 static int
-second_thread_of_pid_p (struct inferior_list_entry *entry, void *args)
+last_thread_of_process_p (int pid)
 {
-  struct counter *counter = (struct counter *) args;
+  bool seen_one = false;
 
-  if (ptid_get_pid (entry->id) == counter->pid)
+  thread_info *thread = find_thread (pid, [&] (thread_info *thr_arg)
     {
-      if (++counter->count > 1)
-       return 1;
-    }
-
-  return 0;
-}
-
-static int
-last_thread_of_process_p (int pid)
-{
-  struct counter counter = { pid , 0 };
+      if (!seen_one)
+       {
+         /* This is the first thread of this process we see.  */
+         seen_one = true;
+         return false;
+       }
+      else
+       {
+         /* This is the second thread of this process we see.  */
+         return true;
+       }
+    });
 
-  return (find_inferior (&all_threads,
-                        second_thread_of_pid_p, &counter) == NULL);
+  return thread == NULL;
 }
 
 /* Kill LWP.  */
@@ -1289,7 +1304,7 @@ linux_kill_one_lwp (struct lwp_info *lwp)
 
       debug_printf ("LKL:  kill_lwp (SIGKILL) %s, 0, 0 (%s)\n",
                    target_pid_to_str (ptid_of (thr)),
-                   save_errno ? strerror (save_errno) : "OK");
+                   save_errno ? safe_strerror (save_errno) : "OK");
     }
 
   errno = 0;
@@ -1300,7 +1315,7 @@ linux_kill_one_lwp (struct lwp_info *lwp)
 
       debug_printf ("LKL:  PTRACE_KILL %s, 0, 0 (%s)\n",
                    target_pid_to_str (ptid_of (thr)),
-                   save_errno ? strerror (save_errno) : "OK");
+                   save_errno ? safe_strerror (save_errno) : "OK");
     }
 }
 
@@ -1310,8 +1325,8 @@ static void
 kill_wait_lwp (struct lwp_info *lwp)
 {
   struct thread_info *thr = get_lwp_thread (lwp);
-  int pid = ptid_get_pid (ptid_of (thr));
-  int lwpid = ptid_get_lwp (ptid_of (thr));
+  int pid = ptid_of (thr).pid ();
+  int lwpid = ptid_of (thr).lwp ();
   int wstat;
   int res;
 
@@ -1347,18 +1362,13 @@ kill_wait_lwp (struct lwp_info *lwp)
     perror_with_name ("kill_wait_lwp");
 }
 
-/* Callback for `find_inferior'.  Kills an lwp of a given process,
+/* Callback for `for_each_thread'.  Kills an lwp of a given process,
    except the leader.  */
 
-static int
-kill_one_lwp_callback (struct inferior_list_entry *entry, void *args)
+static void
+kill_one_lwp_callback (thread_info *thread, int pid)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct lwp_info *lwp = get_thread_lwp (thread);
-  int pid = * (int *) args;
-
-  if (ptid_get_pid (entry->id) != pid)
-    return 0;
 
   /* We avoid killing the first thread here, because of a Linux kernel (at
      least 2.6.0-test7 through 2.6.8-rc4) bug; if we kill the parent before
@@ -1369,33 +1379,30 @@ kill_one_lwp_callback (struct inferior_list_entry *entry, void *args)
     {
       if (debug_threads)
        debug_printf ("lkop: is last of process %s\n",
-                     target_pid_to_str (entry->id));
-      return 0;
+                     target_pid_to_str (thread->id));
+      return;
     }
 
   kill_wait_lwp (lwp);
-  return 0;
 }
 
 static int
-linux_kill (int pid)
+linux_kill (process_info *process)
 {
-  struct process_info *process;
-  struct lwp_info *lwp;
-
-  process = find_process_pid (pid);
-  if (process == NULL)
-    return -1;
+  int pid = process->pid;
 
   /* If we're killing a running inferior, make sure it is stopped
      first, as PTRACE_KILL will not work otherwise.  */
   stop_all_lwps (0, NULL);
 
-  find_inferior (&all_threads, kill_one_lwp_callback , &pid);
+  for_each_thread (pid, [&] (thread_info *thread)
+    {
+      kill_one_lwp_callback (thread, pid);
+    });
 
   /* See the comment in linux_kill_one_lwp.  We did not kill the first
      thread in the list, so do so now.  */
-  lwp = find_lwp_pid (pid_to_ptid (pid));
+  lwp_info *lwp = find_lwp_pid (ptid_t (pid));
 
   if (lwp == NULL)
     {
@@ -1421,6 +1428,7 @@ linux_kill (int pid)
 static int
 get_detach_signal (struct thread_info *thread)
 {
+  client_state &cs = get_client_state ();
   enum gdb_signal signo = GDB_SIGNAL_0;
   int status;
   struct lwp_info *lp = get_thread_lwp (thread);
@@ -1461,7 +1469,7 @@ get_detach_signal (struct thread_info *thread)
 
   signo = gdb_signal_from_host (WSTOPSIG (status));
 
-  if (program_signals_p && !program_signals[signo])
+  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",
@@ -1469,7 +1477,7 @@ get_detach_signal (struct thread_info *thread)
                      gdb_signal_to_string (signo));
       return 0;
     }
-  else if (!program_signals_p
+  else if (!cs.program_signals_p
           /* If we have no way to know which signals GDB does not
              want to have passed to the program, assume
              SIGTRAP/SIGINT, which is GDB's default.  */
@@ -1520,7 +1528,7 @@ linux_detach_one_lwp (struct lwp_info *lwp)
   /* Preparing to resume may try to write registers, and fail if the
      lwp is zombie.  If that happens, ignore the error.  We'll handle
      it below, when detach fails with ESRCH.  */
-  TRY
+  try
     {
       /* Flush any pending changes to the process's registers.  */
       regcache_invalidate_thread (thread);
@@ -1529,12 +1537,11 @@ linux_detach_one_lwp (struct lwp_info *lwp)
       if (the_low_target.prepare_to_resume != NULL)
        the_low_target.prepare_to_resume (lwp);
     }
-  CATCH (ex, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &ex)
     {
       if (!check_ptrace_stopped_lwp_gone (lwp))
-       throw_exception (ex);
+       throw;
     }
-  END_CATCH
 
   lwpid = lwpid_of (thread);
   if (ptrace (PTRACE_DETACH, lwpid, (PTRACE_TYPE_ARG3) 0,
@@ -1554,7 +1561,7 @@ linux_detach_one_lwp (struct lwp_info *lwp)
          if (ret == -1)
            {
              warning (_("Couldn't reap LWP %d while detaching: %s"),
-                      lwpid, strerror (errno));
+                      lwpid, safe_strerror (errno));
            }
          else if (!WIFEXITED (status) && !WIFSIGNALED (status))
            {
@@ -1567,7 +1574,7 @@ linux_detach_one_lwp (struct lwp_info *lwp)
        {
          error (_("Can't detach %s: %s"),
                 target_pid_to_str (ptid_of (thread)),
-                strerror (save_errno));
+                safe_strerror (save_errno));
        }
     }
   else if (debug_threads)
@@ -1580,48 +1587,34 @@ linux_detach_one_lwp (struct lwp_info *lwp)
   delete_lwp (lwp);
 }
 
-/* Callback for find_inferior.  Detaches from non-leader threads of a
+/* Callback for for_each_thread.  Detaches from non-leader threads of a
    given process.  */
 
-static int
-linux_detach_lwp_callback (struct inferior_list_entry *entry, void *args)
+static void
+linux_detach_lwp_callback (thread_info *thread)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
-  struct lwp_info *lwp = get_thread_lwp (thread);
-  int pid = *(int *) args;
-  int lwpid = lwpid_of (thread);
-
-  /* Skip other processes.  */
-  if (ptid_get_pid (entry->id) != pid)
-    return 0;
-
   /* 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 (ptid_get_pid (entry->id) == lwpid)
-    return 0;
+  if (thread->id.pid () == thread->id.lwp ())
+    return;
 
+  lwp_info *lwp = get_thread_lwp (thread);
   linux_detach_one_lwp (lwp);
-  return 0;
 }
 
 static int
-linux_detach (int pid)
+linux_detach (process_info *process)
 {
-  struct process_info *process;
   struct lwp_info *main_lwp;
 
-  process = find_process_pid (pid);
-  if (process == NULL)
-    return -1;
-
   /* As there's a step over already in progress, let it finish first,
      otherwise nesting a stabilize_threads operation on top gets real
      messy.  */
   complete_ongoing_step_over ();
 
   /* Stop all threads before detaching.  First, ptrace requires that
-     the thread is stopped to sucessfully detach.  Second, thread_db
+     the thread is stopped to successfully detach.  Second, thread_db
      may need to uninstall thread event breakpoints from memory, which
      only works with a stopped process anyway.  */
   stop_all_lwps (0, NULL);
@@ -1636,9 +1629,9 @@ linux_detach (int pid)
   /* 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.  */
-  find_inferior (&all_threads, linux_detach_lwp_callback, &pid);
+  for_each_thread (process->pid, linux_detach_lwp_callback);
 
-  main_lwp = find_lwp_pid (pid_to_ptid (pid));
+  main_lwp = find_lwp_pid (ptid_t (process->pid));
   linux_detach_one_lwp (main_lwp);
 
   the_target->mourn (process);
@@ -1651,19 +1644,6 @@ linux_detach (int pid)
 
 /* Remove all LWPs that belong to process PROC from the lwp list.  */
 
-static int
-delete_lwp_callback (struct inferior_list_entry *entry, void *proc)
-{
-  struct thread_info *thread = (struct thread_info *) entry;
-  struct lwp_info *lwp = get_thread_lwp (thread);
-  struct process_info *process = (struct process_info *) proc;
-
-  if (pid_of (thread) == pid_of (process))
-    delete_lwp (lwp);
-
-  return 0;
-}
-
 static void
 linux_mourn (struct process_info *process)
 {
@@ -1673,11 +1653,17 @@ linux_mourn (struct process_info *process)
   thread_db_mourn (process);
 #endif
 
-  find_inferior (&all_threads, delete_lwp_callback, process);
+  for_each_thread (process->pid, [] (thread_info *thread)
+    {
+      delete_lwp (get_thread_lwp (thread));
+    });
 
   /* Freeing all private data.  */
   priv = process->priv;
-  free (priv->arch_private);
+  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;
 
@@ -1799,17 +1785,15 @@ lwp_resumed (struct lwp_info *lwp)
   return 0;
 }
 
-/* Return 1 if this lwp has an interesting status pending.  */
-static int
-status_pending_p_callback (struct inferior_list_entry *entry, void *arg)
+/* Return true if this lwp has an interesting status pending.  */
+static bool
+status_pending_p_callback (thread_info *thread, ptid_t ptid)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct lwp_info *lp = get_thread_lwp (thread);
-  ptid_t ptid = * (ptid_t *) arg;
 
   /* Check if we're only interested in events from a specific process
      or a specific LWP.  */
-  if (!ptid_match (ptid_of (thread), ptid))
+  if (!thread->id.matches (ptid))
     return 0;
 
   if (!lwp_resumed (lp))
@@ -1825,33 +1809,19 @@ status_pending_p_callback (struct inferior_list_entry *entry, void *arg)
   return lp->status_pending_p;
 }
 
-static int
-same_lwp (struct inferior_list_entry *entry, void *data)
-{
-  ptid_t ptid = *(ptid_t *) data;
-  int lwp;
-
-  if (ptid_get_lwp (ptid) != 0)
-    lwp = ptid_get_lwp (ptid);
-  else
-    lwp = ptid_get_pid (ptid);
-
-  if (ptid_get_lwp (entry->id) == lwp)
-    return 1;
-
-  return 0;
-}
-
 struct lwp_info *
 find_lwp_pid (ptid_t ptid)
 {
-  struct inferior_list_entry *thread
-    = find_inferior (&all_threads, same_lwp, &ptid);
+  thread_info *thread = find_thread ([&] (thread_info *thr_arg)
+    {
+      int lwp = ptid.lwp () != 0 ? ptid.lwp () : ptid.pid ();
+      return thr_arg->id.lwp () == lwp;
+    });
 
   if (thread == NULL)
     return NULL;
 
-  return get_thread_lwp ((struct thread_info *) thread);
+  return get_thread_lwp (thread);
 }
 
 /* Return the number of known LWPs in the tgid given by PID.  */
@@ -1859,70 +1829,33 @@ find_lwp_pid (ptid_t ptid)
 static int
 num_lwps (int pid)
 {
-  struct inferior_list_entry *inf, *tmp;
   int count = 0;
 
-  ALL_INFERIORS (&all_threads, inf, tmp)
+  for_each_thread (pid, [&] (thread_info *thread)
     {
-      if (ptid_get_pid (inf->id) == pid)
-       count++;
-    }
+      count++;
+    });
 
   return count;
 }
 
-/* The arguments passed to iterate_over_lwps.  */
-
-struct iterate_over_lwps_args
-{
-  /* The FILTER argument passed to iterate_over_lwps.  */
-  ptid_t filter;
-
-  /* The CALLBACK argument passed to iterate_over_lwps.  */
-  iterate_over_lwps_ftype *callback;
-
-  /* The DATA argument passed to iterate_over_lwps.  */
-  void *data;
-};
-
-/* Callback for find_inferior used by iterate_over_lwps to filter
-   calls to the callback supplied to that function.  Returning a
-   nonzero value causes find_inferiors to stop iterating and return
-   the current inferior_list_entry.  Returning zero indicates that
-   find_inferiors should continue iterating.  */
-
-static int
-iterate_over_lwps_filter (struct inferior_list_entry *entry, void *args_p)
-{
-  struct iterate_over_lwps_args *args
-    = (struct iterate_over_lwps_args *) args_p;
-
-  if (ptid_match (entry->id, args->filter))
-    {
-      struct thread_info *thr = (struct thread_info *) entry;
-      struct lwp_info *lwp = get_thread_lwp (thr);
-
-      return (*args->callback) (lwp, args->data);
-    }
-
-  return 0;
-}
-
 /* See nat/linux-nat.h.  */
 
 struct lwp_info *
 iterate_over_lwps (ptid_t filter,
-                  iterate_over_lwps_ftype callback,
-                  void *data)
+                  gdb::function_view<iterate_over_lwps_ftype> callback)
 {
-  struct iterate_over_lwps_args args = {filter, callback, data};
-  struct inferior_list_entry *entry;
+  thread_info *thread = find_thread (filter, [&] (thread_info *thr_arg)
+    {
+      lwp_info *lwp = get_thread_lwp (thr_arg);
+
+      return callback (lwp);
+    });
 
-  entry = find_inferior (&all_threads, iterate_over_lwps_filter, &args);
-  if (entry == NULL)
+  if (thread == NULL)
     return NULL;
 
-  return get_thread_lwp ((struct thread_info *) entry);
+  return get_thread_lwp (thread);
 }
 
 /* Detect zombie thread group leaders, and "exit" them.  We can't reap
@@ -1931,83 +1864,74 @@ iterate_over_lwps (ptid_t filter,
 static void
 check_zombie_leaders (void)
 {
-  struct process_info *proc, *tmp;
-
-  ALL_PROCESSES (proc, tmp)
-    {
-      pid_t leader_pid = pid_of (proc);
-      struct lwp_info *leader_lp;
+  for_each_process ([] (process_info *proc) {
+    pid_t leader_pid = pid_of (proc);
+    struct lwp_info *leader_lp;
 
-      leader_lp = find_lwp_pid (pid_to_ptid (leader_pid));
+    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 ("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 (debug_threads)
-           debug_printf ("CZL: Thread group leader %d zombie "
-                         "(it exited, or another thread execd).\n",
-                         leader_pid);
-
-         delete_lwp (leader_lp);
-       }
-    }
+    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);
+      }
+    });
 }
 
-/* Callback for `find_inferior'.  Returns the first LWP that is not
-   stopped.  ARG is a PTID filter.  */
+/* Callback for `find_thread'.  Returns the first LWP that is not
+   stopped.  */
 
-static int
-not_stopped_callback (struct inferior_list_entry *entry, void *arg)
+static bool
+not_stopped_callback (thread_info *thread, ptid_t filter)
 {
-  struct thread_info *thr = (struct thread_info *) entry;
-  struct lwp_info *lwp;
-  ptid_t filter = *(ptid_t *) arg;
+  if (!thread->id.matches (filter))
+    return false;
 
-  if (!ptid_match (ptid_of (thr), filter))
-    return 0;
-
-  lwp = get_thread_lwp (thr);
-  if (!lwp->stopped)
-    return 1;
+  lwp_info *lwp = get_thread_lwp (thread);
 
-  return 0;
+  return !lwp->stopped;
 }
 
 /* Increment LWP's suspend count.  */
@@ -2079,7 +2003,9 @@ handle_tracepoints (struct lwp_info *lwp)
   lwp_suspended_decr (lwp);
 
   gdb_assert (lwp->suspended == 0);
-  gdb_assert (!stabilizing_threads || lwp->collecting_fast_tracepoint);
+  gdb_assert (!stabilizing_threads
+             || (lwp->collecting_fast_tracepoint
+                 != fast_tpoint_collect_result::not_collecting));
 
   if (tpoint_related_event)
     {
@@ -2091,10 +2017,10 @@ handle_tracepoints (struct lwp_info *lwp)
   return 0;
 }
 
-/* Convenience wrapper.  Returns true if LWP is presently collecting a
-   fast tracepoint.  */
+/* Convenience wrapper.  Returns information about LWP's fast tracepoint
+   collection status.  */
 
-static int
+static fast_tpoint_collect_result
 linux_fast_tracepoint_collecting (struct lwp_info *lwp,
                                  struct fast_tpoint_collect_status *status)
 {
@@ -2102,14 +2028,14 @@ linux_fast_tracepoint_collecting (struct lwp_info *lwp,
   struct thread_info *thread = get_lwp_thread (lwp);
 
   if (the_low_target.get_thread_area == NULL)
-    return 0;
+    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)
-    return 0;
+    return fast_tpoint_collect_result::not_collecting;
 
   return fast_tracepoint_collecting (thread_area, lwp->stop_pc, status);
 }
@@ -2133,14 +2059,14 @@ maybe_move_out_of_jump_pad (struct lwp_info *lwp, int *wstat)
       && agent_loaded_p ())
     {
       struct fast_tpoint_collect_status status;
-      int r;
 
       if (debug_threads)
        debug_printf ("Checking whether LWP %ld needs to move out of the "
                      "jump pad.\n",
                      lwpid_of (current_thread));
 
-      r = linux_fast_tracepoint_collecting (lwp, &status);
+      fast_tpoint_collect_result r
+       = linux_fast_tracepoint_collecting (lwp, &status);
 
       if (wstat == NULL
          || (WSTOPSIG (*wstat) != SIGILL
@@ -2150,9 +2076,10 @@ maybe_move_out_of_jump_pad (struct lwp_info *lwp, int *wstat)
        {
          lwp->collecting_fast_tracepoint = r;
 
-         if (r != 0)
+         if (r != fast_tpoint_collect_result::not_collecting)
            {
-             if (r == 1 && lwp->exit_jump_pad_bkpt == NULL)
+             if (r == fast_tpoint_collect_result::before_insn
+                 && lwp->exit_jump_pad_bkpt == NULL)
                {
                  /* Haven't executed the original instruction yet.
                     Set breakpoint there, and wait till it's hit,
@@ -2178,9 +2105,10 @@ maybe_move_out_of_jump_pad (struct lwp_info *lwp, int *wstat)
             reporting to GDB.  Otherwise, it's an IPA lib bug: just
             report the signal to GDB, and pray for the best.  */
 
-         lwp->collecting_fast_tracepoint = 0;
+         lwp->collecting_fast_tracepoint
+           = fast_tpoint_collect_result::not_collecting;
 
-         if (r != 0
+         if (r != fast_tpoint_collect_result::not_collecting
              && (status.adjusted_insn_addr <= lwp->stop_pc
                  && lwp->stop_pc < status.adjusted_insn_addr_end))
            {
@@ -2393,18 +2321,19 @@ check_stopped_by_watchpoint (struct lwp_info *child)
 static int
 linux_low_ptrace_options (int attached)
 {
+  client_state &cs = get_client_state ();
   int options = 0;
 
   if (!attached)
     options |= PTRACE_O_EXITKILL;
 
-  if (report_fork_events)
+  if (cs.report_fork_events)
     options |= PTRACE_O_TRACEFORK;
 
-  if (report_vfork_events)
+  if (cs.report_vfork_events)
     options |= (PTRACE_O_TRACEVFORK | PTRACE_O_TRACEVFORKDONE);
 
-  if (report_exec_events)
+  if (cs.report_exec_events)
     options |= PTRACE_O_TRACEEXEC;
 
   options |= PTRACE_O_TRACESYSGOOD;
@@ -2419,11 +2348,12 @@ linux_low_ptrace_options (int attached)
 static struct lwp_info *
 linux_low_filter_event (int lwpid, int wstat)
 {
+  client_state &cs = get_client_state ();
   struct lwp_info *child;
   struct thread_info *thread;
   int have_stop_pc = 0;
 
-  child = find_lwp_pid (pid_to_ptid (lwpid));
+  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.
@@ -2451,7 +2381,7 @@ linux_low_filter_event (int lwpid, int wstat)
                        "after exec.\n", lwpid);
        }
 
-      child_ptid = ptid_build (lwpid, lwpid, 0);
+      child_ptid = ptid_t (lwpid, lwpid, 0);
       child = add_lwp (child_ptid);
       child->stopped = 1;
       current_thread = child->thread;
@@ -2490,7 +2420,7 @@ linux_low_filter_event (int lwpid, int wstat)
       /* 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 (report_thread_events
+      if (cs.report_thread_events
          || last_thread_of_process_p (pid_of (thread)))
        {
          /* Since events are serialized to GDB core, and we can't
@@ -2645,9 +2575,8 @@ maybe_hw_step (struct thread_info *thread)
    to report, but are resumed from the core's perspective.  */
 
 static void
-resume_stopped_resumed_lwps (struct inferior_list_entry *entry)
+resume_stopped_resumed_lwps (thread_info *thread)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct lwp_info *lp = get_thread_lwp (thread);
 
   if (lp->stopped
@@ -2696,23 +2625,26 @@ linux_wait_for_event_filtered (ptid_t wait_ptid, ptid_t filter_ptid,
 
   /* Check for a lwp with a pending status.  */
 
-  if (ptid_equal (filter_ptid, minus_one_ptid) || ptid_is_pid (filter_ptid))
+  if (filter_ptid == minus_one_ptid || filter_ptid.is_pid ())
     {
-      event_thread = (struct thread_info *)
-       find_inferior_in_random (&all_threads, status_pending_p_callback,
-                                &filter_ptid);
+      event_thread = find_thread_in_random ([&] (thread_info *thread)
+       {
+         return status_pending_p_callback (thread, 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));
     }
-  else if (!ptid_equal (filter_ptid, null_ptid))
+  else if (filter_ptid != null_ptid)
     {
       requested_child = find_lwp_pid (filter_ptid);
 
       if (stopping_threads == NOT_STOPPING_THREADS
          && requested_child->status_pending_p
-         && requested_child->collecting_fast_tracepoint)
+         && (requested_child->collecting_fast_tracepoint
+             != fast_tpoint_collect_result::not_collecting))
        {
          enqueue_one_deferred_signal (requested_child,
                                       &requested_child->status_pending);
@@ -2758,7 +2690,7 @@ linux_wait_for_event_filtered (ptid_t wait_ptid, ptid_t filter_ptid,
   /* Make sure SIGCHLD is blocked until the sigsuspend below.  Block
      all signals while here.  */
   sigfillset (&block_mask);
-  sigprocmask (SIG_BLOCK, &block_mask, &prev_mask);
+  gdb_sigmask (SIG_BLOCK, &block_mask, &prev_mask);
 
   /* Always pull all events out of the kernel.  We'll randomly select
      an event LWP out of all that have events, to prevent
@@ -2784,7 +2716,7 @@ linux_wait_for_event_filtered (ptid_t wait_ptid, ptid_t filter_ptid,
 
       if (debug_threads)
        debug_printf ("LWFE: waitpid(-1, ...) returned %d, %s\n",
-                     ret, errno ? strerror (errno) : "ERRNO-OK");
+                     ret, errno ? safe_strerror (errno) : "ERRNO-OK");
 
       if (ret > 0)
        {
@@ -2806,13 +2738,15 @@ 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_inferior (&all_threads, resume_stopped_resumed_lwps);
+       for_each_thread (resume_stopped_resumed_lwps);
 
       /* ... and find an LWP with a status to report to the core, if
         any.  */
-      event_thread = (struct thread_info *)
-       find_inferior_in_random (&all_threads, status_pending_p_callback,
-                                &filter_ptid);
+      event_thread = find_thread_in_random ([&] (thread_info *thread)
+       {
+         return status_pending_p_callback (thread, filter_ptid);
+       });
+
       if (event_thread != NULL)
        {
          event_child = get_thread_lwp (event_thread);
@@ -2826,6 +2760,11 @@ linux_wait_for_event_filtered (ptid_t wait_ptid, ptid_t filter_ptid,
         until all other threads in the thread group are.  */
       check_zombie_leaders ();
 
+      auto not_stopped = [&] (thread_info *thread)
+       {
+         return not_stopped_callback (thread, wait_ptid);
+       };
+
       /* If there are no resumed children left in the set of LWPs we
         want to wait for, bail.  We can't just block in
         waitpid/sigsuspend, because lwps might have been left stopped
@@ -2833,13 +2772,11 @@ linux_wait_for_event_filtered (ptid_t wait_ptid, ptid_t filter_ptid,
         their status to change (which would only happen if we resumed
         them).  Even if WNOHANG is set, this return code is preferred
         over 0 (below), as it is more detailed.  */
-      if ((find_inferior (&all_threads,
-                         not_stopped_callback,
-                         &wait_ptid) == NULL))
+      if (find_thread (not_stopped) == NULL)
        {
          if (debug_threads)
            debug_printf ("LLW: exit (no unwaited-for LWP)\n");
-         sigprocmask (SIG_SETMASK, &prev_mask, NULL);
+         gdb_sigmask (SIG_SETMASK, &prev_mask, NULL);
          return -1;
        }
 
@@ -2849,7 +2786,7 @@ linux_wait_for_event_filtered (ptid_t wait_ptid, ptid_t filter_ptid,
          if (debug_threads)
            debug_printf ("WNOHANG set, no event found\n");
 
-         sigprocmask (SIG_SETMASK, &prev_mask, NULL);
+         gdb_sigmask (SIG_SETMASK, &prev_mask, NULL);
          return 0;
        }
 
@@ -2858,11 +2795,11 @@ linux_wait_for_event_filtered (ptid_t wait_ptid, ptid_t filter_ptid,
        debug_printf ("sigsuspend'ing\n");
 
       sigsuspend (&prev_mask);
-      sigprocmask (SIG_SETMASK, &prev_mask, NULL);
+      gdb_sigmask (SIG_SETMASK, &prev_mask, NULL);
       goto retry;
     }
 
-  sigprocmask (SIG_SETMASK, &prev_mask, NULL);
+  gdb_sigmask (SIG_SETMASK, &prev_mask, NULL);
 
   current_thread = event_thread;
 
@@ -2883,68 +2820,11 @@ linux_wait_for_event (ptid_t ptid, int *wstatp, int options)
   return linux_wait_for_event_filtered (ptid, ptid, wstatp, options);
 }
 
-/* Count the LWP's that have had events.  */
-
-static int
-count_events_callback (struct inferior_list_entry *entry, void *data)
-{
-  struct thread_info *thread = (struct thread_info *) entry;
-  struct lwp_info *lp = get_thread_lwp (thread);
-  int *count = (int *) data;
-
-  gdb_assert (count != NULL);
-
-  /* Count only resumed LWPs that have an event pending. */
-  if (thread->last_status.kind == TARGET_WAITKIND_IGNORE
-      && lp->status_pending_p)
-    (*count)++;
-
-  return 0;
-}
-
-/* Select the LWP (if any) that is currently being single-stepped.  */
-
-static int
-select_singlestep_lwp_callback (struct inferior_list_entry *entry, void *data)
-{
-  struct thread_info *thread = (struct thread_info *) entry;
-  struct lwp_info *lp = get_thread_lwp (thread);
-
-  if (thread->last_status.kind == TARGET_WAITKIND_IGNORE
-      && thread->last_resume_kind == resume_step
-      && lp->status_pending_p)
-    return 1;
-  else
-    return 0;
-}
-
-/* Select the Nth LWP that has had an event.  */
-
-static int
-select_event_lwp_callback (struct inferior_list_entry *entry, void *data)
-{
-  struct thread_info *thread = (struct thread_info *) entry;
-  struct lwp_info *lp = get_thread_lwp (thread);
-  int *selector = (int *) data;
-
-  gdb_assert (selector != NULL);
-
-  /* Select only resumed LWPs that have an event pending. */
-  if (thread->last_status.kind == TARGET_WAITKIND_IGNORE
-      && lp->status_pending_p)
-    if ((*selector)-- == 0)
-      return 1;
-
-  return 0;
-}
-
 /* Select one LWP out of those that have events pending.  */
 
 static void
 select_event_lwp (struct lwp_info **orig_lp)
 {
-  int num_events = 0;
-  int random_selector;
   struct thread_info *event_thread = NULL;
 
   /* In all-stop, give preference to the LWP that is being
@@ -2957,10 +2837,15 @@ select_event_lwp (struct lwp_info **orig_lp)
      would report it to the user as a random signal.  */
   if (!non_stop)
     {
-      event_thread
-       = (struct thread_info *) find_inferior (&all_threads,
-                                               select_singlestep_lwp_callback,
-                                               NULL);
+      event_thread = find_thread ([] (thread_info *thread)
+       {
+         lwp_info *lp = get_thread_lwp (thread);
+
+         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)
@@ -2973,23 +2858,14 @@ select_event_lwp (struct lwp_info **orig_lp)
       /* No single-stepping LWP.  Select one at random, out of those
          which have had events.  */
 
-      /* First see how many events we have.  */
-      find_inferior (&all_threads, count_events_callback, &num_events);
-      gdb_assert (num_events > 0);
-
-      /* Now randomly pick a LWP out of those that have had
-        events.  */
-      random_selector = (int)
-       ((num_events * (double) rand ()) / (RAND_MAX + 1.0));
-
-      if (debug_threads && num_events > 1)
-       debug_printf ("SEL: Found %d SIGTRAP events, selecting #%d\n",
-                     num_events, random_selector);
+      event_thread = find_thread_in_random ([&] (thread_info *thread)
+       {
+         lwp_info *lp = get_thread_lwp (thread);
 
-      event_thread
-       = (struct thread_info *) find_inferior (&all_threads,
-                                               select_event_lwp_callback,
-                                               &random_selector);
+         /* Only resumed LWPs that have an event pending. */
+         return (thread->last_status.kind == TARGET_WAITKIND_IGNORE
+                 && lp->status_pending_p);
+       });
     }
 
   if (event_thread != NULL)
@@ -3001,35 +2877,24 @@ select_event_lwp (struct lwp_info **orig_lp)
     }
 }
 
-/* Decrement the suspend count of an LWP.  */
-
-static int
-unsuspend_one_lwp (struct inferior_list_entry *entry, void *except)
-{
-  struct thread_info *thread = (struct thread_info *) entry;
-  struct lwp_info *lwp = get_thread_lwp (thread);
-
-  /* Ignore EXCEPT.  */
-  if (lwp == except)
-    return 0;
-
-  lwp_suspended_decr (lwp);
-  return 0;
-}
-
 /* Decrement the suspend count of all LWPs, except EXCEPT, if non
    NULL.  */
 
 static void
 unsuspend_all_lwps (struct lwp_info *except)
 {
-  find_inferior (&all_threads, unsuspend_one_lwp, except);
+  for_each_thread ([&] (thread_info *thread)
+    {
+      lwp_info *lwp = get_thread_lwp (thread);
+
+      if (lwp != except)
+       lwp_suspended_decr (lwp);
+    });
 }
 
-static void move_out_of_jump_pad_callback (struct inferior_list_entry *entry);
-static int stuck_in_jump_pad_callback (struct inferior_list_entry *entry,
-                                      void *data);
-static int lwp_running (struct inferior_list_entry *entry, void *data);
+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);
@@ -3067,13 +2932,8 @@ static ptid_t linux_wait_1 (ptid_t ptid,
 static void
 linux_stabilize_threads (void)
 {
-  struct thread_info *saved_thread;
-  struct thread_info *thread_stuck;
+  thread_info *thread_stuck = find_thread (stuck_in_jump_pad_callback);
 
-  thread_stuck
-    = (struct thread_info *) find_inferior (&all_threads,
-                                           stuck_in_jump_pad_callback,
-                                           NULL);
   if (thread_stuck != NULL)
     {
       if (debug_threads)
@@ -3082,15 +2942,15 @@ linux_stabilize_threads (void)
       return;
     }
 
-  saved_thread = current_thread;
+  thread_info *saved_thread = current_thread;
 
   stabilizing_threads = 1;
 
   /* Kick 'em all.  */
-  for_each_inferior (&all_threads, move_out_of_jump_pad_callback);
+  for_each_thread (move_out_of_jump_pad_callback);
 
   /* Loop until all are stopped out of the jump pads.  */
-  while (find_inferior (&all_threads, lwp_running, NULL) != NULL)
+  while (find_thread (lwp_running) != NULL)
     {
       struct target_waitstatus ourstatus;
       struct lwp_info *lwp;
@@ -3125,10 +2985,8 @@ linux_stabilize_threads (void)
 
   if (debug_threads)
     {
-      thread_stuck
-       = (struct thread_info *) find_inferior (&all_threads,
-                                               stuck_in_jump_pad_callback,
-                                               NULL);
+      thread_stuck = find_thread (stuck_in_jump_pad_callback);
+
       if (thread_stuck != NULL)
        debug_printf ("couldn't stabilize, LWP %ld got stuck in jump pad\n",
                      lwpid_of (thread_stuck));
@@ -3159,12 +3017,13 @@ static ptid_t
 filter_exit_event (struct lwp_info *event_child,
                   struct 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 (report_thread_events)
+      if (cs.report_thread_events)
        ourstatus->kind = TARGET_WAITKIND_THREAD_EXITED;
       else
        ourstatus->kind = TARGET_WAITKIND_IGNORE;
@@ -3182,7 +3041,7 @@ gdb_catching_syscalls_p (struct lwp_info *event_child)
   struct thread_info *thread = get_lwp_thread (event_child);
   struct process_info *proc = get_thread_process (thread);
 
-  return !VEC_empty (int, proc->syscalls_to_catch);
+  return !proc->syscalls_to_catch.empty ();
 }
 
 /* Returns 1 if GDB is interested in the event_child syscall.
@@ -3191,21 +3050,19 @@ gdb_catching_syscalls_p (struct lwp_info *event_child)
 static int
 gdb_catch_this_syscall_p (struct lwp_info *event_child)
 {
-  int i, iter;
   int sysno;
   struct thread_info *thread = get_lwp_thread (event_child);
   struct process_info *proc = get_thread_process (thread);
 
-  if (VEC_empty (int, proc->syscalls_to_catch))
+  if (proc->syscalls_to_catch.empty ())
     return 0;
 
-  if (VEC_index (int, proc->syscalls_to_catch, 0) == ANY_SYSCALL)
+  if (proc->syscalls_to_catch[0] == ANY_SYSCALL)
     return 1;
 
   get_syscall_trapinfo (event_child, &sysno);
-  for (i = 0;
-       VEC_iterate (int, proc->syscalls_to_catch, i, iter);
-       i++)
+
+  for (int iter : proc->syscalls_to_catch)
     if (iter == sysno)
       return 1;
 
@@ -3218,6 +3075,7 @@ static ptid_t
 linux_wait_1 (ptid_t ptid,
              struct target_waitstatus *ourstatus, int target_options)
 {
+  client_state &cs = get_client_state ();
   int w;
   struct lwp_info *event_child;
   int options;
@@ -3246,19 +3104,25 @@ linux_wait_1 (ptid_t ptid,
   in_step_range = 0;
   ourstatus->kind = TARGET_WAITKIND_IGNORE;
 
+  auto status_pending_p_any = [&] (thread_info *thread)
+    {
+      return status_pending_p_callback (thread, minus_one_ptid);
+    };
+
+  auto not_stopped = [&] (thread_info *thread)
+    {
+      return not_stopped_callback (thread, minus_one_ptid);
+    };
+
   /* Find a resumed LWP, if any.  */
-  if (find_inferior (&all_threads,
-                    status_pending_p_callback,
-                    &minus_one_ptid) != NULL)
+  if (find_thread (status_pending_p_any) != NULL)
     any_resumed = 1;
-  else if ((find_inferior (&all_threads,
-                          not_stopped_callback,
-                          &minus_one_ptid) != NULL))
+  else if (find_thread (not_stopped) != NULL)
     any_resumed = 1;
   else
     any_resumed = 0;
 
-  if (ptid_equal (step_over_bkpt, null_ptid))
+  if (step_over_bkpt == null_ptid)
     pid = linux_wait_for_event (ptid, &w, options);
   else
     {
@@ -3347,7 +3211,7 @@ linux_wait_1 (ptid_t ptid,
      if it's not the single_step_breakpoint we are hitting.
      This avoids that a program would keep trapping a permanent breakpoint
      forever.  */
-  if (!ptid_equal (step_over_bkpt, null_ptid)
+  if (step_over_bkpt != null_ptid
       && event_child->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT
       && (event_child->stepping
          || !single_step_breakpoint_inserted_here (event_child->stop_pc)))
@@ -3464,20 +3328,22 @@ linux_wait_1 (ptid_t ptid,
        }
     }
 
-  if (event_child->collecting_fast_tracepoint)
+  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),
-                     event_child->collecting_fast_tracepoint);
+                     (int) event_child->collecting_fast_tracepoint);
 
       trace_event = 1;
 
       event_child->collecting_fast_tracepoint
        = linux_fast_tracepoint_collecting (event_child, NULL);
 
-      if (event_child->collecting_fast_tracepoint != 1)
+      if (event_child->collecting_fast_tracepoint
+         != fast_tpoint_collect_result::before_insn)
        {
          /* No longer need this breakpoint.  */
          if (event_child->exit_jump_pad_bkpt != NULL)
@@ -3504,7 +3370,8 @@ linux_wait_1 (ptid_t ptid,
            }
        }
 
-      if (event_child->collecting_fast_tracepoint == 0)
+      if (event_child->collecting_fast_tracepoint
+         == fast_tpoint_collect_result::not_collecting)
        {
          if (debug_threads)
            debug_printf ("fast tracepoint finished "
@@ -3578,7 +3445,7 @@ linux_wait_1 (ptid_t ptid,
               || WSTOPSIG (w) == __SIGRTMIN + 1))
          ||
 #endif
-         (pass_signals[gdb_signal_from_host (WSTOPSIG (w))]
+         (cs.pass_signals[gdb_signal_from_host (WSTOPSIG (w))]
           && !(WSTOPSIG (w) == SIGSTOP
                && current_thread->last_resume_kind == resume_stop)
           && !linux_wstatus_maybe_breakpoint (w))))
@@ -3722,12 +3589,11 @@ linux_wait_1 (ptid_t ptid,
     {
       if (event_child->waitstatus.kind != TARGET_WAITKIND_IGNORE)
        {
-         char *str;
+         std::string str
+           = target_waitstatus_to_string (&event_child->waitstatus);
 
-         str = target_waitstatus_to_string (&event_child->waitstatus);
          debug_printf ("LWP %ld: extended event with waitstatus %s\n",
-                       lwpid_of (get_lwp_thread (event_child)), str);
-         xfree (str);
+                       lwpid_of (get_lwp_thread (event_child)), str.c_str ());
        }
       if (current_thread->last_resume_kind == resume_step)
        {
@@ -3763,18 +3629,16 @@ linux_wait_1 (ptid_t ptid,
        {
          /* In all-stop, a stop reply cancels all previous resume
             requests.  Delete all single-step breakpoints.  */
-         struct inferior_list_entry *inf, *tmp;
 
-         ALL_INFERIORS (&all_threads, inf, tmp)
-           {
-             struct thread_info *thread = (struct thread_info *) inf;
+         find_thread ([&] (thread_info *thread) {
+           if (has_single_step_breakpoints (thread))
+             {
+               remove_single_step_breakpoints_p = 1;
+               return true;
+             }
 
-             if (has_single_step_breakpoints (thread))
-               {
-                 remove_single_step_breakpoints_p = 1;
-                 break;
-               }
-           }
+           return false;
+         });
        }
 
       if (remove_single_step_breakpoints_p)
@@ -3791,15 +3655,10 @@ linux_wait_1 (ptid_t ptid,
            }
          else
            {
-             struct inferior_list_entry *inf, *tmp;
-
-             ALL_INFERIORS (&all_threads, inf, tmp)
-               {
-                 struct thread_info *thread = (struct thread_info *) inf;
-
-                 if (has_single_step_breakpoints (thread))
-                   delete_single_step_breakpoints (thread);
-               }
+             for_each_thread ([] (thread_info *thread){
+               if (has_single_step_breakpoints (thread))
+                 delete_single_step_breakpoints (thread);
+             });
            }
 
          unstop_all_lwps (0, event_child);
@@ -3840,7 +3699,7 @@ linux_wait_1 (ptid_t ptid,
         from among those that have had events.  Giving equal priority
         to all LWPs that have had events helps prevent
         starvation.  */
-      if (ptid_equal (ptid, minus_one_ptid))
+      if (ptid == minus_one_ptid)
        {
          event_child->status_pending_p = 1;
          event_child->status_pending = w;
@@ -3893,7 +3752,7 @@ linux_wait_1 (ptid_t ptid,
      it was a software breakpoint, and the client doesn't know we can
      adjust the breakpoint ourselves.  */
   if (event_child->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT
-      && !swbreak_feature)
+      && !cs.swbreak_feature)
     {
       int decr_pc = the_low_target.decr_pc_after_break;
 
@@ -3931,7 +3790,7 @@ linux_wait_1 (ptid_t ptid,
       ourstatus->value.sig = gdb_signal_from_host (WSTOPSIG (w));
     }
 
-  gdb_assert (ptid_equal (step_over_bkpt, null_ptid));
+  gdb_assert (step_over_bkpt == null_ptid);
 
   if (debug_threads)
     {
@@ -3990,14 +3849,14 @@ linux_wait (ptid_t ptid,
       event_ptid = linux_wait_1 (ptid, ourstatus, target_options);
     }
   while ((target_options & TARGET_WNOHANG) == 0
-        && ptid_equal (event_ptid, null_ptid)
+        && event_ptid == null_ptid
         && 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.  */
   if (target_is_async_p ()
       && (target_options & TARGET_WNOHANG) != 0
-      && !ptid_equal (event_ptid, null_ptid))
+      && event_ptid != null_ptid)
     async_file_mark ();
 
   return event_ptid;
@@ -4051,39 +3910,35 @@ send_sigstop (struct lwp_info *lwp)
   kill_lwp (pid, SIGSTOP);
 }
 
-static int
-send_sigstop_callback (struct inferior_list_entry *entry, void *except)
+static void
+send_sigstop (thread_info *thread, lwp_info *except)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct lwp_info *lwp = get_thread_lwp (thread);
 
   /* Ignore EXCEPT.  */
   if (lwp == except)
-    return 0;
+    return;
 
   if (lwp->stopped)
-    return 0;
+    return;
 
   send_sigstop (lwp);
-  return 0;
 }
 
 /* Increment the suspend count of an LWP, and stop it, if not stopped
    yet.  */
-static int
-suspend_and_send_sigstop_callback (struct inferior_list_entry *entry,
-                                  void *except)
+static void
+suspend_and_send_sigstop (thread_info *thread, lwp_info *except)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct lwp_info *lwp = get_thread_lwp (thread);
 
   /* Ignore EXCEPT.  */
   if (lwp == except)
-    return 0;
+    return;
 
   lwp_suspended_inc (lwp);
 
-  return send_sigstop_callback (entry, except);
+  send_sigstop (thread, except);
 }
 
 static void
@@ -4136,7 +3991,7 @@ wait_for_sigstop (void)
 
   saved_thread = current_thread;
   if (saved_thread != NULL)
-    saved_tid = saved_thread->entry.id;
+    saved_tid = saved_thread->id;
   else
     saved_tid = null_ptid; /* avoid bogus unused warning */
 
@@ -4164,15 +4019,14 @@ wait_for_sigstop (void)
     }
 }
 
-/* Returns true if LWP ENTRY is stopped in a jump pad, and we can't
+/* 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 int
-stuck_in_jump_pad_callback (struct inferior_list_entry *entry, void *data)
+static bool
+stuck_in_jump_pad_callback (thread_info *thread)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct lwp_info *lwp = get_thread_lwp (thread);
 
   if (lwp->suspended != 0)
@@ -4189,13 +4043,13 @@ stuck_in_jump_pad_callback (struct inferior_list_entry *entry, void *data)
          && (gdb_breakpoint_here (lwp->stop_pc)
              || lwp->stop_reason == TARGET_STOPPED_BY_WATCHPOINT
              || thread->last_resume_kind == resume_step)
-         && linux_fast_tracepoint_collecting (lwp, NULL));
+         && (linux_fast_tracepoint_collecting (lwp, NULL)
+             != fast_tpoint_collect_result::not_collecting));
 }
 
 static void
-move_out_of_jump_pad_callback (struct inferior_list_entry *entry)
+move_out_of_jump_pad_callback (thread_info *thread)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct thread_info *saved_thread;
   struct lwp_info *lwp = get_thread_lwp (thread);
   int *wstat;
@@ -4243,17 +4097,15 @@ move_out_of_jump_pad_callback (struct inferior_list_entry *entry)
   current_thread = saved_thread;
 }
 
-static int
-lwp_running (struct inferior_list_entry *entry, void *data)
+static bool
+lwp_running (thread_info *thread)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct lwp_info *lwp = get_thread_lwp (thread);
 
   if (lwp_is_marked_dead (lwp))
-    return 0;
-  if (lwp->stopped)
-    return 0;
-  return 1;
+    return false;
+
+  return !lwp->stopped;
 }
 
 /* Stop all lwps that aren't stopped yet, except EXCEPT, if not NULL.
@@ -4281,9 +4133,16 @@ stop_all_lwps (int suspend, struct lwp_info *except)
                      : STOPPING_THREADS);
 
   if (suspend)
-    find_inferior (&all_threads, suspend_and_send_sigstop_callback, except);
+    for_each_thread ([&] (thread_info *thread)
+      {
+       suspend_and_send_sigstop (thread, except);
+      });
   else
-    find_inferior (&all_threads, send_sigstop_callback, except);
+    for_each_thread ([&] (thread_info *thread)
+      {
+        send_sigstop (thread, except);
+      });
+
   wait_for_sigstop ();
   stopping_threads = NOT_STOPPING_THREADS;
 
@@ -4319,15 +4178,14 @@ install_software_single_step_breakpoints (struct lwp_info *lwp)
 {
   struct thread_info *thread = get_lwp_thread (lwp);
   struct regcache *regcache = get_thread_regcache (thread, 1);
-  struct cleanup *old_chain = make_cleanup_restore_current_thread ();
+
+  scoped_restore save_current_thread = make_scoped_restore (&current_thread);
 
   current_thread = thread;
   std::vector<CORE_ADDR> next_pcs = the_low_target.get_next_pcs (regcache);
 
   for (CORE_ADDR pc : next_pcs)
     set_single_step_breakpoint (pc, current_ptid);
-
-  do_cleanups (old_chain);
 }
 
 /* Single step via hardware or software single step.
@@ -4366,7 +4224,8 @@ single_step (struct lwp_info* lwp)
 static int
 lwp_signal_can_be_delivered (struct lwp_info *lwp)
 {
-  return !lwp->collecting_fast_tracepoint;
+  return (lwp->collecting_fast_tracepoint
+         == fast_tpoint_collect_result::not_collecting);
 }
 
 /* Resume execution of LWP.  If STEP is nonzero, single-step it.  If
@@ -4378,7 +4237,6 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp,
 {
   struct thread_info *thread = get_lwp_thread (lwp);
   struct thread_info *saved_thread;
-  int fast_tp_collecting;
   int ptrace_request;
   struct process_info *proc = get_thread_process (thread);
 
@@ -4394,9 +4252,12 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp,
 
   gdb_assert (lwp->waitstatus.kind == TARGET_WAITKIND_IGNORE);
 
-  fast_tp_collecting = lwp->collecting_fast_tracepoint;
+  fast_tpoint_collect_result fast_tp_collecting
+    = lwp->collecting_fast_tracepoint;
 
-  gdb_assert (!stabilizing_threads || fast_tp_collecting);
+  gdb_assert (!stabilizing_threads
+             || (fast_tp_collecting
+                 != fast_tpoint_collect_result::not_collecting));
 
   /* Cancel actions that rely on GDB not changing the PC (e.g., the
      user used the "jump" command, or "set $pc = foo").  */
@@ -4452,7 +4313,7 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp,
 
       if (can_hardware_single_step ())
        {
-         if (fast_tp_collecting == 0)
+         if (fast_tp_collecting == fast_tpoint_collect_result::not_collecting)
            {
              if (step == 0)
                warning ("BAD - reinserting but not stepping.");
@@ -4465,14 +4326,14 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp,
       step = maybe_hw_step (thread);
     }
 
-  if (fast_tp_collecting == 1)
+  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));
     }
-  else if (fast_tp_collecting == 2)
+  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"
@@ -4616,55 +4477,42 @@ static void
 linux_resume_one_lwp (struct lwp_info *lwp,
                      int step, int signal, siginfo_t *info)
 {
-  TRY
+  try
     {
       linux_resume_one_lwp_throw (lwp, step, signal, info);
     }
-  CATCH (ex, RETURN_MASK_ERROR)
+  catch (const gdb_exception_error &ex)
     {
       if (!check_ptrace_stopped_lwp_gone (lwp))
-       throw_exception (ex);
+       throw;
     }
-  END_CATCH
 }
 
-struct thread_resume_array
-{
-  struct thread_resume *resume;
-  size_t n;
-};
-
-/* This function is called once per thread via find_inferior.
-   ARG is a pointer to a thread_resume_array struct.
-   We look up the thread specified by ENTRY in ARG, and mark the thread
-   with a pointer to the appropriate resume request.
+/* This function is called once per thread via for_each_thread.
+   We look up which resume request applies to THREAD and mark it with a
+   pointer to the appropriate resume request.
 
    This algorithm is O(threads * resume elements), but resume elements
    is small (and will remain small at least until GDB supports thread
    suspension).  */
 
-static int
-linux_set_resume_request (struct inferior_list_entry *entry, void *arg)
+static void
+linux_set_resume_request (thread_info *thread, thread_resume *resume, size_t n)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct lwp_info *lwp = get_thread_lwp (thread);
-  int ndx;
-  struct thread_resume_array *r;
-
-  r = (struct thread_resume_array *) arg;
 
-  for (ndx = 0; ndx < r->n; ndx++)
+  for (int ndx = 0; ndx < n; ndx++)
     {
-      ptid_t ptid = r->resume[ndx].thread;
-      if (ptid_equal (ptid, minus_one_ptid)
-         || ptid_equal (ptid, entry->id)
+      ptid_t ptid = resume[ndx].thread;
+      if (ptid == minus_one_ptid
+         || ptid == thread->id
          /* Handle both 'pPID' and 'pPID.-1' as meaning 'all threads
             of PID'.  */
-         || (ptid_get_pid (ptid) == pid_of (thread)
-             && (ptid_is_pid (ptid)
-                 || ptid_get_lwp (ptid) == -1)))
+         || (ptid.pid () == pid_of (thread)
+             && (ptid.is_pid ()
+                 || ptid.lwp () == -1)))
        {
-         if (r->resume[ndx].kind == resume_stop
+         if (resume[ndx].kind == resume_stop
              && thread->last_resume_kind == resume_stop)
            {
              if (debug_threads)
@@ -4680,7 +4528,7 @@ linux_set_resume_request (struct inferior_list_entry *entry, void *arg)
 
          /* Ignore (wildcard) resume requests for already-resumed
             threads.  */
-         if (r->resume[ndx].kind != resume_stop
+         if (resume[ndx].kind != resume_stop
              && thread->last_resume_kind != resume_stop)
            {
              if (debug_threads)
@@ -4697,7 +4545,6 @@ linux_set_resume_request (struct inferior_list_entry *entry, void *arg)
             does not yet know are new fork children.  */
          if (lwp->fork_relative != NULL)
            {
-             struct inferior_list_entry *inf, *tmp;
              struct lwp_info *rel = lwp->fork_relative;
 
              if (rel->status_pending_p
@@ -4715,7 +4562,7 @@ linux_set_resume_request (struct inferior_list_entry *entry, void *arg)
             reported to GDBserver core, but GDB has not pulled the
             event out of the vStopped queue yet, likewise, ignore the
             (wildcard) resume request.  */
-         if (in_queued_stop_replies (entry->id))
+         if (in_queued_stop_replies (thread->id))
            {
              if (debug_threads)
                debug_printf ("not resuming LWP %ld: has queued stop reply\n",
@@ -4723,7 +4570,7 @@ linux_set_resume_request (struct inferior_list_entry *entry, void *arg)
              continue;
            }
 
-         lwp->resume = &r->resume[ndx];
+         lwp->resume = &resume[ndx];
          thread->last_resume_kind = lwp->resume->kind;
 
          lwp->step_range_start = lwp->resume->step_range_start;
@@ -4745,34 +4592,28 @@ linux_set_resume_request (struct inferior_list_entry *entry, void *arg)
                              lwpid_of (thread));
            }
 
-         return 0;
+         return;
        }
     }
 
   /* No resume action for this thread.  */
   lwp->resume = NULL;
-
-  return 0;
 }
 
-/* find_inferior callback for linux_resume.
-   Set *FLAG_P if this lwp has an interesting status pending.  */
+/* find_thread callback for linux_resume.  Return true if this lwp has an
+   interesting status pending.  */
 
-static int
-resume_status_pending_p (struct inferior_list_entry *entry, void *flag_p)
+static bool
+resume_status_pending_p (thread_info *thread)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct lwp_info *lwp = get_thread_lwp (thread);
 
   /* LWPs which will not be resumed are not interesting, because
      we might not wait for them next time through linux_wait.  */
   if (lwp->resume == NULL)
-    return 0;
-
-  if (thread_still_has_status_pending_p (thread))
-    * (int *) flag_p = 1;
+    return false;
 
-  return 0;
+  return thread_still_has_status_pending_p (thread);
 }
 
 /* Return 1 if this lwp that GDB wants running is stopped at an
@@ -4780,10 +4621,9 @@ resume_status_pending_p (struct inferior_list_entry *entry, void *flag_p)
    required STOP_PC adjustment has already been propagated to the
    inferior's regcache.  */
 
-static int
-need_step_over_p (struct inferior_list_entry *entry, void *dummy)
+static bool
+need_step_over_p (thread_info *thread)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct lwp_info *lwp = get_thread_lwp (thread);
   struct thread_info *saved_thread;
   CORE_ADDR pc;
@@ -4792,7 +4632,7 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
   /* GDBserver is skipping the extra traps from the wrapper program,
      don't have to do step over.  */
   if (proc->tdesc == NULL)
-    return 0;
+    return false;
 
   /* LWPs which will not be resumed are not interesting, because we
      might not wait for them next time through linux_wait.  */
@@ -4802,7 +4642,7 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
       if (debug_threads)
        debug_printf ("Need step over [LWP %ld]? Ignoring, not stopped\n",
                      lwpid_of (thread));
-      return 0;
+      return false;
     }
 
   if (thread->last_resume_kind == resume_stop)
@@ -4811,7 +4651,7 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
        debug_printf ("Need step over [LWP %ld]? Ignoring, should remain"
                      " stopped\n",
                      lwpid_of (thread));
-      return 0;
+      return false;
     }
 
   gdb_assert (lwp->suspended >= 0);
@@ -4821,7 +4661,7 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
       if (debug_threads)
        debug_printf ("Need step over [LWP %ld]? Ignoring, suspended\n",
                      lwpid_of (thread));
-      return 0;
+      return false;
     }
 
   if (lwp->status_pending_p)
@@ -4830,7 +4670,7 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
        debug_printf ("Need step over [LWP %ld]? Ignoring, has pending"
                      " status.\n",
                      lwpid_of (thread));
-      return 0;
+      return false;
     }
 
   /* Note: PC, not STOP_PC.  Either GDB has adjusted the PC already,
@@ -4849,7 +4689,7 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
                      "Old stop_pc was 0x%s, PC is now 0x%s\n",
                      lwpid_of (thread),
                      paddress (lwp->stop_pc), paddress (pc));
-      return 0;
+      return false;
     }
 
   /* On software single step target, resume the inferior with signal
@@ -4863,7 +4703,7 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
                      " signals.\n",
                      lwpid_of (thread));
 
-      return 0;
+      return false;
     }
 
   saved_thread = current_thread;
@@ -4885,7 +4725,7 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
                          lwpid_of (thread), paddress (pc));
 
          current_thread = saved_thread;
-         return 0;
+         return false;
        }
       else
        {
@@ -4895,10 +4735,10 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
                          lwpid_of (thread), paddress (pc));
 
          /* We've found an lwp that needs stepping over --- return 1 so
-            that find_inferior stops looking.  */
+            that find_thread stops looking.  */
          current_thread = saved_thread;
 
-         return 1;
+         return true;
        }
     }
 
@@ -4909,7 +4749,7 @@ need_step_over_p (struct inferior_list_entry *entry, void *dummy)
                  " at 0x%s\n",
                  lwpid_of (thread), paddress (pc));
 
-  return 0;
+  return false;
 }
 
 /* Start a step-over operation on LWP.  When LWP stopped at a
@@ -4966,7 +4806,7 @@ start_step_over (struct lwp_info *lwp)
   linux_resume_one_lwp (lwp, step, 0, NULL);
 
   /* Require next event from this LWP.  */
-  step_over_bkpt = thread->entry.id;
+  step_over_bkpt = thread->id;
   return 1;
 }
 
@@ -5021,7 +4861,7 @@ finish_step_over (struct lwp_info *lwp)
 static void
 complete_ongoing_step_over (void)
 {
-  if (!ptid_equal (step_over_bkpt, null_ptid))
+  if (step_over_bkpt != null_ptid)
     {
       struct lwp_info *lwp;
       int wstat;
@@ -5058,16 +4898,14 @@ complete_ongoing_step_over (void)
    event to report, so we don't need to preserve any step requests;
    they should be re-issued if necessary.  */
 
-static int
-linux_resume_one_thread (struct inferior_list_entry *entry, void *arg)
+static void
+linux_resume_one_thread (thread_info *thread, bool leave_all_stopped)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct lwp_info *lwp = get_thread_lwp (thread);
-  int leave_all_stopped = * (int *) arg;
   int leave_pending;
 
   if (lwp->resume == NULL)
-    return 0;
+    return;
 
   if (lwp->resume->kind == resume_stop)
     {
@@ -5114,7 +4952,7 @@ linux_resume_one_thread (struct inferior_list_entry *entry, void *arg)
       /* For stop requests, we're done.  */
       lwp->resume = NULL;
       thread->last_status.kind = TARGET_WAITKIND_IGNORE;
-      return 0;
+      return;
     }
 
   /* If this thread which is about to be resumed has a pending status,
@@ -5152,7 +4990,7 @@ linux_resume_one_thread (struct inferior_list_entry *entry, void *arg)
       if (debug_threads)
        debug_printf ("resuming LWP %ld\n", lwpid_of (thread));
 
-      proceed_one_lwp (entry, NULL);
+      proceed_one_lwp (thread, NULL);
     }
   else
     {
@@ -5162,16 +5000,12 @@ linux_resume_one_thread (struct inferior_list_entry *entry, void *arg)
 
   thread->last_status.kind = TARGET_WAITKIND_IGNORE;
   lwp->resume = NULL;
-  return 0;
 }
 
 static void
 linux_resume (struct thread_resume *resume_info, size_t n)
 {
-  struct thread_resume_array array = { resume_info, n };
   struct thread_info *need_step_over = NULL;
-  int any_pending;
-  int leave_all_stopped;
 
   if (debug_threads)
     {
@@ -5179,7 +5013,10 @@ linux_resume (struct thread_resume *resume_info, size_t n)
       debug_printf ("linux_resume:\n");
     }
 
-  find_inferior (&all_threads, linux_set_resume_request, &array);
+  for_each_thread ([&] (thread_info *thread)
+    {
+      linux_set_resume_request (thread, resume_info, n);
+    });
 
   /* If there is a thread which would otherwise be resumed, which has
      a pending status, then don't resume any threads - we can just
@@ -5187,9 +5024,9 @@ linux_resume (struct thread_resume *resume_info, size_t n)
      would otherwise be sent.  In non-stop mode, we'll apply this
      logic to each thread individually.  We consume all pending events
      before considering to start a step-over (in all-stop).  */
-  any_pending = 0;
+  bool any_pending = false;
   if (!non_stop)
-    find_inferior (&all_threads, resume_status_pending_p, &any_pending);
+    any_pending = find_thread (resume_status_pending_p) != NULL;
 
   /* If there is a thread which would otherwise be resumed, which is
      stopped at a breakpoint that needs stepping over, then don't
@@ -5198,11 +5035,9 @@ linux_resume (struct thread_resume *resume_info, size_t n)
      to queue any signals that would otherwise be delivered or
      queued.  */
   if (!any_pending && supports_breakpoints ())
-    need_step_over
-      = (struct thread_info *) find_inferior (&all_threads,
-                                             need_step_over_p, NULL);
+    need_step_over = find_thread (need_step_over_p);
 
-  leave_all_stopped = (need_step_over != NULL || any_pending);
+  bool leave_all_stopped = (need_step_over != NULL || any_pending);
 
   if (debug_threads)
     {
@@ -5217,7 +5052,10 @@ linux_resume (struct thread_resume *resume_info, size_t n)
 
   /* Even if we're leaving threads stopped, queue all signals we'd
      otherwise deliver.  */
-  find_inferior (&all_threads, linux_resume_one_thread, &leave_all_stopped);
+  for_each_thread ([&] (thread_info *thread)
+    {
+      linux_resume_one_thread (thread, leave_all_stopped);
+    });
 
   if (need_step_over)
     start_step_over (get_thread_lwp (need_step_over));
@@ -5243,15 +5081,14 @@ linux_resume (struct thread_resume *resume_info, size_t n)
    breakpoint that needs stepping over, we start a step-over operation
    on that particular thread, and leave all others stopped.  */
 
-static int
-proceed_one_lwp (struct inferior_list_entry *entry, void *except)
+static void
+proceed_one_lwp (thread_info *thread, lwp_info *except)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct lwp_info *lwp = get_thread_lwp (thread);
   int step;
 
   if (lwp == except)
-    return 0;
+    return;
 
   if (debug_threads)
     debug_printf ("proceed_one_lwp: lwp %ld\n", lwpid_of (thread));
@@ -5260,7 +5097,7 @@ proceed_one_lwp (struct inferior_list_entry *entry, void *except)
     {
       if (debug_threads)
        debug_printf ("   LWP %ld already running\n", lwpid_of (thread));
-      return 0;
+      return;
     }
 
   if (thread->last_resume_kind == resume_stop
@@ -5269,7 +5106,7 @@ proceed_one_lwp (struct inferior_list_entry *entry, void *except)
       if (debug_threads)
        debug_printf ("   client wants LWP to remain %ld stopped\n",
                      lwpid_of (thread));
-      return 0;
+      return;
     }
 
   if (lwp->status_pending_p)
@@ -5277,7 +5114,7 @@ proceed_one_lwp (struct inferior_list_entry *entry, void *except)
       if (debug_threads)
        debug_printf ("   LWP %ld has pending status, leaving stopped\n",
                      lwpid_of (thread));
-      return 0;
+      return;
     }
 
   gdb_assert (lwp->suspended >= 0);
@@ -5286,12 +5123,13 @@ proceed_one_lwp (struct inferior_list_entry *entry, void *except)
     {
       if (debug_threads)
        debug_printf ("   LWP %ld is suspended\n", lwpid_of (thread));
-      return 0;
+      return;
     }
 
   if (thread->last_resume_kind == resume_stop
       && lwp->pending_signals_to_report == NULL
-      && lwp->collecting_fast_tracepoint == 0)
+      && (lwp->collecting_fast_tracepoint
+         == fast_tpoint_collect_result::not_collecting))
     {
       /* We haven't reported this LWP as stopped yet (otherwise, the
         last_status.kind check above would catch it, and we wouldn't
@@ -5338,21 +5176,19 @@ proceed_one_lwp (struct inferior_list_entry *entry, void *except)
     step = 0;
 
   linux_resume_one_lwp (lwp, step, 0, NULL);
-  return 0;
 }
 
-static int
-unsuspend_and_proceed_one_lwp (struct inferior_list_entry *entry, void *except)
+static void
+unsuspend_and_proceed_one_lwp (thread_info *thread, lwp_info *except)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct lwp_info *lwp = get_thread_lwp (thread);
 
   if (lwp == except)
-    return 0;
+    return;
 
   lwp_suspended_decr (lwp);
 
-  return proceed_one_lwp (entry, except);
+  proceed_one_lwp (thread, except);
 }
 
 /* When we finish a step-over, set threads running again.  If there's
@@ -5371,9 +5207,7 @@ proceed_all_lwps (void)
 
   if (supports_breakpoints ())
     {
-      need_step_over
-       = (struct thread_info *) find_inferior (&all_threads,
-                                               need_step_over_p, NULL);
+      need_step_over = find_thread (need_step_over_p);
 
       if (need_step_over != NULL)
        {
@@ -5390,7 +5224,10 @@ proceed_all_lwps (void)
   if (debug_threads)
     debug_printf ("Proceeding, no step-over needed\n");
 
-  find_inferior (&all_threads, proceed_one_lwp, NULL);
+  for_each_thread ([] (thread_info *thread)
+    {
+      proceed_one_lwp (thread, NULL);
+    });
 }
 
 /* Stopped LWPs that the client wanted to be running, that don't have
@@ -5411,9 +5248,15 @@ unstop_all_lwps (int unsuspend, struct lwp_info *except)
     }
 
   if (unsuspend)
-    find_inferior (&all_threads, unsuspend_and_proceed_one_lwp, except);
+    for_each_thread ([&] (thread_info *thread)
+      {
+       unsuspend_and_proceed_one_lwp (thread, except);
+      });
   else
-    find_inferior (&all_threads, proceed_one_lwp, except);
+    for_each_thread ([&] (thread_info *thread)
+      {
+       proceed_one_lwp (thread, except);
+      });
 
   if (debug_threads)
     {
@@ -5487,10 +5330,11 @@ regsets_fetch_inferior_registers (struct regsets_info *regsets_info,
 #endif
       if (res < 0)
        {
-         if (errno == EIO)
+         if (errno == EIO
+             || (errno == EINVAL && regset->type == OPTIONAL_REGS))
            {
-             /* If we get EIO on a regset, do not try it again for
-                this process mode.  */
+             /* If we get EIO on a regset, or an EINVAL and the regset is
+                optional, do not try it again for this process mode.  */
              disable_regset (regsets_info, regset);
            }
          else if (errno == ENODATA)
@@ -5585,10 +5429,11 @@ regsets_store_inferior_registers (struct regsets_info *regsets_info,
 
       if (res < 0)
        {
-         if (errno == EIO)
+         if (errno == EIO
+             || (errno == EINVAL && regset->type == OPTIONAL_REGS))
            {
-             /* If we get EIO on a regset, do not try it again for
-                this process mode.  */
+             /* If we get EIO on a regset, or an EINVAL and the regset is
+                optional, do not try it again for this process mode.  */
              disable_regset (regsets_info, regset);
            }
          else if (errno == ESRCH)
@@ -5687,7 +5532,11 @@ fetch_register (const struct usrregs_info *usrregs,
                (PTRACE_TYPE_ARG3) (uintptr_t) regaddr, (PTRACE_TYPE_ARG4) 0);
       regaddr += sizeof (PTRACE_XFER_TYPE);
       if (errno != 0)
-       error ("reading register %d: %s", regno, strerror (errno));
+       {
+         /* Mark register REGNO unavailable.  */
+         supply_register (regcache, regno, NULL);
+         return;
+       }
     }
 
   if (the_low_target.supply_ptrace_register)
@@ -5745,7 +5594,7 @@ store_register (const struct usrregs_info *usrregs,
            return;
 
          if ((*the_low_target.cannot_store_register) (regno) == 0)
-           error ("writing register %d: %s", regno, strerror (errno));
+           error ("writing register %d: %s", regno, safe_strerror (errno));
        }
       regaddr += sizeof (PTRACE_XFER_TYPE);
     }
@@ -5867,11 +5716,11 @@ static int
 linux_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
 {
   int pid = lwpid_of (current_thread);
-  register PTRACE_XFER_TYPE *buffer;
-  register CORE_ADDR addr;
-  register int count;
+  PTRACE_XFER_TYPE *buffer;
+  CORE_ADDR addr;
+  int count;
   char filename[64];
-  register int i;
+  int i;
   int ret;
   int fd;
 
@@ -5955,16 +5804,16 @@ linux_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
 static int
 linux_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
 {
-  register int i;
+  int i;
   /* Round starting address down to longword boundary.  */
-  register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE);
+  CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE);
   /* Round ending address up; get number of longwords that makes.  */
-  register int count
+  int count
     = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1)
     / sizeof (PTRACE_XFER_TYPE);
 
   /* Allocate buffer of that many longwords.  */
-  register PTRACE_XFER_TYPE *buffer = XALLOCAVEC (PTRACE_XFER_TYPE, count);
+  PTRACE_XFER_TYPE *buffer = XALLOCAVEC (PTRACE_XFER_TYPE, count);
 
   int pid = lwpid_of (current_thread);
 
@@ -6055,8 +5904,6 @@ linux_look_up_symbols (void)
 static void
 linux_request_interrupt (void)
 {
-  extern unsigned long signal_pid;
-
   /* Send a SIGINT to the process group.  This acts just like the user
      typed a ^C on the controlling terminal.  */
   kill (-signal_pid, SIGINT);
@@ -6335,10 +6182,9 @@ sigchld_handler (int signo)
     {
       do
        {
-         /* fprintf is not async-signal-safe, so call write
-            directly.  */
-         if (write (2, "sigchld_handler\n",
-                    sizeof ("sigchld_handler\n") - 1) < 0)
+         /* Use the async signal safe debug function.  */
+         if (debug_write ("sigchld_handler\n",
+                          sizeof ("sigchld_handler\n") - 1) < 0)
            break; /* just ignore */
        } while (0);
     }
@@ -6370,7 +6216,7 @@ linux_async (int enable)
       sigemptyset (&mask);
       sigaddset (&mask, SIGCHLD);
 
-      sigprocmask (SIG_BLOCK, &mask, NULL);
+      gdb_sigmask (SIG_BLOCK, &mask, NULL);
 
       if (enable)
        {
@@ -6378,7 +6224,7 @@ linux_async (int enable)
            {
              linux_event_pipe[0] = -1;
              linux_event_pipe[1] = -1;
-             sigprocmask (SIG_UNBLOCK, &mask, NULL);
+             gdb_sigmask (SIG_UNBLOCK, &mask, NULL);
 
              warning ("creating event pipe failed.");
              return previous;
@@ -6404,7 +6250,7 @@ linux_async (int enable)
          linux_event_pipe[1] = -1;
        }
 
-      sigprocmask (SIG_UNBLOCK, &mask, NULL);
+      gdb_sigmask (SIG_UNBLOCK, &mask, NULL);
     }
 
   return previous;
@@ -6452,35 +6298,6 @@ linux_supports_exec_events (void)
   return linux_supports_traceexec ();
 }
 
-/* Callback for 'find_inferior'.  Set the (possibly changed) ptrace
-   options for the specified lwp.  */
-
-static int
-reset_lwp_ptrace_options_callback (struct inferior_list_entry *entry,
-                                  void *args)
-{
-  struct thread_info *thread = (struct thread_info *) entry;
-  struct lwp_info *lwp = get_thread_lwp (thread);
-
-  if (!lwp->stopped)
-    {
-      /* Stop the lwp so we can modify its ptrace options.  */
-      lwp->must_set_ptrace_flags = 1;
-      linux_stop_lwp (lwp);
-    }
-  else
-    {
-      /* Already stopped; go ahead and set the ptrace options.  */
-      struct process_info *proc = find_process_pid (pid_of (thread));
-      int options = linux_low_ptrace_options (proc->attached);
-
-      linux_enable_event_reporting (lwpid_of (thread), options);
-      lwp->must_set_ptrace_flags = 0;
-    }
-
-  return 0;
-}
-
 /* Target hook for 'handle_new_gdb_connection'.  Causes a reset of the
    ptrace flags for all inferiors.  This is in case the new GDB connection
    doesn't support the same set of events that the previous one did.  */
@@ -6488,10 +6305,27 @@ reset_lwp_ptrace_options_callback (struct inferior_list_entry *entry,
 static void
 linux_handle_new_gdb_connection (void)
 {
-  pid_t pid;
-
   /* Request that all the lwps reset their ptrace options.  */
-  find_inferior (&all_threads, reset_lwp_ptrace_options_callback , &pid);
+  for_each_thread ([] (thread_info *thread)
+    {
+      struct lwp_info *lwp = get_thread_lwp (thread);
+
+      if (!lwp->stopped)
+       {
+         /* Stop the lwp so we can modify its ptrace options.  */
+         lwp->must_set_ptrace_flags = 1;
+         linux_stop_lwp (lwp);
+       }
+      else
+       {
+         /* Already stopped; go ahead and set the ptrace options.  */
+         struct process_info *proc = find_process_pid (pid_of (thread));
+         int options = linux_low_ptrace_options (proc->attached);
+
+         linux_enable_event_reporting (lwpid_of (thread), options);
+         lwp->must_set_ptrace_flags = 0;
+       }
+    });
 }
 
 static int
@@ -6521,99 +6355,6 @@ linux_supports_range_stepping (void)
   return (*the_low_target.supports_range_stepping) ();
 }
 
-/* Enumerate spufs IDs for process PID.  */
-static int
-spu_enumerate_spu_ids (long pid, unsigned char *buf, CORE_ADDR offset, int len)
-{
-  int pos = 0;
-  int written = 0;
-  char path[128];
-  DIR *dir;
-  struct dirent *entry;
-
-  sprintf (path, "/proc/%ld/fd", pid);
-  dir = opendir (path);
-  if (!dir)
-    return -1;
-
-  rewinddir (dir);
-  while ((entry = readdir (dir)) != NULL)
-    {
-      struct stat st;
-      struct statfs stfs;
-      int fd;
-
-      fd = atoi (entry->d_name);
-      if (!fd)
-        continue;
-
-      sprintf (path, "/proc/%ld/fd/%d", pid, fd);
-      if (stat (path, &st) != 0)
-        continue;
-      if (!S_ISDIR (st.st_mode))
-        continue;
-
-      if (statfs (path, &stfs) != 0)
-        continue;
-      if (stfs.f_type != SPUFS_MAGIC)
-        continue;
-
-      if (pos >= offset && pos + 4 <= offset + len)
-        {
-          *(unsigned int *)(buf + pos - offset) = fd;
-          written += 4;
-        }
-      pos += 4;
-    }
-
-  closedir (dir);
-  return written;
-}
-
-/* Implements the to_xfer_partial interface for the TARGET_OBJECT_SPU
-   object type, using the /proc file system.  */
-static int
-linux_qxfer_spu (const char *annex, unsigned char *readbuf,
-                unsigned const char *writebuf,
-                CORE_ADDR offset, int len)
-{
-  long pid = lwpid_of (current_thread);
-  char buf[128];
-  int fd = 0;
-  int ret = 0;
-
-  if (!writebuf && !readbuf)
-    return -1;
-
-  if (!*annex)
-    {
-      if (!readbuf)
-       return -1;
-      else
-       return spu_enumerate_spu_ids (pid, readbuf, offset, len);
-    }
-
-  sprintf (buf, "/proc/%ld/fd/%s", pid, annex);
-  fd = open (buf, writebuf? O_WRONLY : O_RDONLY);
-  if (fd <= 0)
-    return -1;
-
-  if (offset != 0
-      && lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset)
-    {
-      close (fd);
-      return 0;
-    }
-
-  if (writebuf)
-    ret = write (fd, writebuf, (size_t) len);
-  else
-    ret = read (fd, readbuf, (size_t) len);
-
-  close (fd);
-  return ret;
-}
-
 #if defined PT_GETDSBT || defined PTRACE_GETFDPIC
 struct target_loadseg
 {
@@ -7124,8 +6865,6 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf,
                            unsigned const char *writebuf,
                            CORE_ADDR offset, int len)
 {
-  char *document;
-  unsigned document_len;
   struct process_info_private *const priv = current_process ()->priv;
   char filename[PATH_MAX];
   int pid, is_elf64;
@@ -7155,8 +6894,6 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf,
   unsigned int machine;
   int ptr_size;
   CORE_ADDR lm_addr = 0, lm_prev = 0;
-  int allocated = 1024;
-  char *p;
   CORE_ADDR l_name, l_addr, l_ld, l_next, l_prev;
   int header_done = 0;
 
@@ -7175,16 +6912,16 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf,
     {
       const char *sep;
       CORE_ADDR *addrp;
-      int len;
+      int name_len;
 
       sep = strchr (annex, '=');
       if (sep == NULL)
        break;
 
-      len = sep - annex;
-      if (len == 5 && startswith (annex, "start"))
+      name_len = sep - annex;
+      if (name_len == 5 && startswith (annex, "start"))
        addrp = &lm_addr;
-      else if (len == 4 && startswith (annex, "prev"))
+      else if (name_len == 4 && startswith (annex, "prev"))
        addrp = &lm_prev;
       else
        {
@@ -7229,9 +6966,7 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf,
        }
     }
 
-  document = (char *) xmalloc (allocated);
-  strcpy (document, "<library-list-svr4 version=\"1.0\"");
-  p = document + strlen (document);
+  std::string document = "<library-list-svr4 version=\"1.0\"";
 
   while (lm_addr
         && read_one_ptr (lm_addr + lmo->l_name_offset,
@@ -7261,10 +6996,7 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf,
         executable does not have PT_DYNAMIC present and this function already
         exited above due to failed get_r_debug.  */
       if (lm_prev == 0)
-       {
-         sprintf (p, " main-lm=\"0x%lx\"", (unsigned long) lm_addr);
-         p = p + strlen (p);
-       }
+       string_appendf (document, " main-lm=\"0x%lx\"", (unsigned long) lm_addr);
       else
        {
          /* Not checking for error because reading may stop before
@@ -7274,33 +7006,19 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf,
          libname[sizeof (libname) - 1] = '\0';
          if (libname[0] != '\0')
            {
-             /* 6x the size for xml_escape_text below.  */
-             size_t len = 6 * strlen ((char *) libname);
-             char *name;
-
              if (!header_done)
                {
                  /* Terminate `<library-list-svr4'.  */
-                 *p++ = '>';
+                 document += '>';
                  header_done = 1;
                }
 
-             while (allocated < p - document + len + 200)
-               {
-                 /* Expand to guarantee sufficient storage.  */
-                 uintptr_t document_len = p - document;
-
-                 document = (char *) xrealloc (document, 2 * allocated);
-                 allocated *= 2;
-                 p = document + document_len;
-               }
-
-             name = xml_escape_text ((char *) libname);
-             p += sprintf (p, "<library name=\"%s\" lm=\"0x%lx\" "
-                           "l_addr=\"0x%lx\" l_ld=\"0x%lx\"/>",
-                           name, (unsigned long) lm_addr,
-                           (unsigned long) l_addr, (unsigned long) l_ld);
-             free (name);
+             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);
            }
        }
 
@@ -7311,12 +7029,12 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf,
   if (!header_done)
     {
       /* Empty list; terminate `<library-list-svr4'.  */
-      strcpy (p, "/>");
+      document += "/>";
     }
   else
-    strcpy (p, "</library-list-svr4>");
+    document += "</library-list-svr4>";
 
-  document_len = strlen (document);
+  int document_len = document.length ();
   if (offset < document_len)
     document_len -= offset;
   else
@@ -7324,8 +7042,7 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf,
   if (len > document_len)
     len = document_len;
 
-  memcpy (readbuf, document + offset, len);
-  xfree (document);
+  memcpy (readbuf, document.data () + offset, len);
 
   return len;
 }
@@ -7376,7 +7093,7 @@ linux_low_encode_raw (struct buffer *buffer, const gdb_byte *data,
   if (size == 0)
     return;
 
-  /* We use hex encoding - see common/rsp-low.h.  */
+  /* We use hex encoding - see gdbsupport/rsp-low.h.  */
   buffer_grow_str (buffer, "<raw>\n");
 
   while (size-- > 0)
@@ -7399,11 +7116,7 @@ linux_low_read_btrace (struct btrace_target_info *tinfo, struct buffer *buffer,
                       enum btrace_read_type type)
 {
   struct btrace_data btrace;
-  struct btrace_block *block;
   enum btrace_error err;
-  int i;
-
-  btrace_data_init (&btrace);
 
   err = linux_read_btrace (&btrace, tinfo, type);
   if (err != BTRACE_ERR_NONE)
@@ -7413,24 +7126,22 @@ linux_low_read_btrace (struct btrace_target_info *tinfo, struct buffer *buffer,
       else
        buffer_grow_str0 (buffer, "E.Generic Error.");
 
-      goto err;
+      return -1;
     }
 
   switch (btrace.format)
     {
     case BTRACE_FORMAT_NONE:
       buffer_grow_str0 (buffer, "E.No Trace.");
-      goto err;
+      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");
 
-      for (i = 0;
-          VEC_iterate (btrace_block_s, btrace.variant.bts.blocks, i, block);
-          i++)
+      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));
+                          paddress (block.begin), paddress (block.end));
 
       buffer_grow_str0 (buffer, "</btrace>\n");
       break;
@@ -7451,15 +7162,10 @@ linux_low_read_btrace (struct btrace_target_info *tinfo, struct buffer *buffer,
 
     default:
       buffer_grow_str0 (buffer, "E.Unsupported Trace Format.");
-      goto err;
+      return -1;
     }
 
-  btrace_data_fini (&btrace);
   return 0;
-
-err:
-  btrace_data_fini (&btrace);
-  return -1;
 }
 
 /* See to_btrace_conf target method.  */
@@ -7591,8 +7297,64 @@ linux_get_pc_64bit (struct regcache *regcache)
   return pc;
 }
 
+/* See linux-low.h.  */
+
+int
+linux_get_auxv (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->read_auxv) (offset, data, 2 * wordsize) == 2 * wordsize)
+    {
+      if (wordsize == 4)
+       {
+         uint32_t *data_p = (uint32_t *) data;
+         if (data_p[0] == match)
+           {
+             *valp = data_p[1];
+             return 1;
+           }
+       }
+      else
+       {
+         uint64_t *data_p = (uint64_t *) data;
+         if (data_p[0] == match)
+           {
+             *valp = data_p[1];
+             return 1;
+           }
+       }
+
+      offset += 2 * wordsize;
+    }
+
+  return 0;
+}
+
+/* See linux-low.h.  */
 
-static struct target_ops linux_target_ops = {
+CORE_ADDR
+linux_get_hwcap (int wordsize)
+{
+  CORE_ADDR hwcap = 0;
+  linux_get_auxv (wordsize, AT_HWCAP, &hwcap);
+  return hwcap;
+}
+
+/* See linux-low.h.  */
+
+CORE_ADDR
+linux_get_hwcap2 (int wordsize)
+{
+  CORE_ADDR hwcap2 = 0;
+  linux_get_auxv (wordsize, AT_HWCAP2, &hwcap2);
+  return hwcap2;
+}
+
+static process_stratum_target linux_target_ops = {
   linux_create_inferior,
   linux_post_create_inferior,
   linux_attach,
@@ -7634,7 +7396,6 @@ static struct target_ops linux_target_ops = {
 #else
   NULL,
 #endif
-  linux_qxfer_spu,
   hostio_last_error_from_errno,
   linux_qxfer_osdata,
   linux_xfer_siginfo,
@@ -7669,7 +7430,6 @@ static struct target_ops linux_target_ops = {
   linux_qxfer_libraries_svr4,
   linux_supports_agent,
 #ifdef HAVE_LINUX_BTRACE
-  linux_supports_btrace,
   linux_enable_btrace,
   linux_low_disable_btrace,
   linux_low_read_btrace,
@@ -7679,7 +7439,6 @@ static struct target_ops linux_target_ops = {
   NULL,
   NULL,
   NULL,
-  NULL,
 #endif
   linux_supports_range_stepping,
   linux_proc_pid_to_exec_file,
@@ -7693,6 +7452,11 @@ static struct target_ops linux_target_ops = {
   linux_supports_software_single_step,
   linux_supports_catch_syscall,
   linux_get_ipa_tdesc_idx,
+#if USE_THREAD_DB
+  thread_db_thread_handle,
+#else
+  NULL,
+#endif
 };
 
 #ifdef HAVE_LINUX_REGSETS
@@ -7715,6 +7479,7 @@ initialize_low (void)
   set_target_ops (&linux_target_ops);
 
   linux_ptrace_init_warnings ();
+  linux_proc_init_warnings ();
 
   sigchld_action.sa_handler = sigchld_handler;
   sigemptyset (&sigchld_action.sa_mask);
This page took 0.066099 seconds and 4 git commands to generate.