Multi-target support
[deliverable/binutils-gdb.git] / gdb / gdbserver / linux-low.c
index 7b176ec9d4c6b0c43c50a5ab11de728003a67781..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 "common-inferior.h"
+#include "gdbsupport/common-inferior.h"
 #include "nat/fork-inferior.h"
-#include "environ.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
@@ -279,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 (thread_info *thread, 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.  */
@@ -474,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);
@@ -521,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
@@ -628,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
@@ -654,14 +657,16 @@ 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;
@@ -680,7 +685,7 @@ 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;
       std::vector<int> syscalls_to_catch;
@@ -695,7 +700,7 @@ 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);
@@ -947,11 +952,11 @@ 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;
 }
 
@@ -995,13 +1000,14 @@ static int
 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;
 
   {
     maybe_disable_address_space_randomization restore_personality
-      (disable_randomization);
+      (cs.disable_randomization);
     std::string str_program_args = stringify_argv (program_args);
 
     pid = fork_inferior (program,
@@ -1012,7 +1018,7 @@ linux_create_inferior (const char *program,
 
   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;
 
@@ -1047,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)
@@ -1135,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)
@@ -1154,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;
@@ -1179,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
@@ -1217,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)
        {
@@ -1246,7 +1257,7 @@ last_thread_of_process_p (int pid)
 {
   bool seen_one = false;
 
-  thread_info *thread = find_thread (pid, [&] (thread_info *thread)
+  thread_info *thread = find_thread (pid, [&] (thread_info *thr_arg)
     {
       if (!seen_one)
        {
@@ -1293,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;
@@ -1304,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");
     }
 }
 
@@ -1314,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;
 
@@ -1376,14 +1387,9 @@ kill_one_lwp_callback (thread_info *thread, int pid)
 }
 
 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.  */
@@ -1396,7 +1402,7 @@ linux_kill (int 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)
     {
@@ -1422,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);
@@ -1462,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",
@@ -1470,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.  */
@@ -1521,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);
@@ -1530,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,
@@ -1555,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))
            {
@@ -1568,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)
@@ -1598,22 +1604,17 @@ linux_detach_lwp_callback (thread_info *thread)
 }
 
 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);
@@ -1628,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.  */
-  for_each_thread (pid, linux_detach_lwp_callback);
+  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);
@@ -1811,10 +1812,10 @@ status_pending_p_callback (thread_info *thread, ptid_t ptid)
 struct lwp_info *
 find_lwp_pid (ptid_t ptid)
 {
-  thread_info *thread = find_thread ([&] (thread_info *thread)
+  thread_info *thread = find_thread ([&] (thread_info *thr_arg)
     {
       int lwp = ptid.lwp () != 0 ? ptid.lwp () : ptid.pid ();
-      return thread->id.lwp () == lwp;
+      return thr_arg->id.lwp () == lwp;
     });
 
   if (thread == NULL)
@@ -1842,14 +1843,13 @@ num_lwps (int pid)
 
 struct lwp_info *
 iterate_over_lwps (ptid_t filter,
-                  iterate_over_lwps_ftype callback,
-                  void *data)
+                  gdb::function_view<iterate_over_lwps_ftype> callback)
 {
-  thread_info *thread = find_thread (filter, [&] (thread_info *thread)
+  thread_info *thread = find_thread (filter, [&] (thread_info *thr_arg)
     {
-      lwp_info *lwp = get_thread_lwp (thread);
+      lwp_info *lwp = get_thread_lwp (thr_arg);
 
-      return callback (lwp, data);
+      return callback (lwp);
     });
 
   if (thread == NULL)
@@ -1868,7 +1868,7 @@ check_zombie_leaders (void)
     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, "
@@ -2321,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;
@@ -2347,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.
@@ -2379,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;
@@ -2418,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
@@ -2623,7 +2625,7 @@ 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 = find_thread_in_random ([&] (thread_info *thread)
        {
@@ -2635,7 +2637,7 @@ linux_wait_for_event_filtered (ptid_t wait_ptid, ptid_t filter_ptid,
       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);
 
@@ -2688,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
@@ -2714,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)
        {
@@ -2736,7 +2738,7 @@ 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.  */
@@ -2774,7 +2776,7 @@ linux_wait_for_event_filtered (ptid_t wait_ptid, ptid_t filter_ptid,
        {
          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;
        }
 
@@ -2784,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;
        }
 
@@ -2793,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;
 
@@ -2823,7 +2825,6 @@ linux_wait_for_event (ptid_t ptid, int *wstatp, int options)
 static void
 select_event_lwp (struct lwp_info **orig_lp)
 {
-  int random_selector;
   struct thread_info *event_thread = NULL;
 
   /* In all-stop, give preference to the LWP that is being
@@ -2857,39 +2858,13 @@ 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.  */
-      int num_events = 0;
-      for_each_thread ([&] (thread_info *thread)
-       {
-         lwp_info *lp = get_thread_lwp (thread);
-
-         /* Count only resumed LWPs that have an event pending. */
-         if (thread->last_status.kind == TARGET_WAITKIND_IGNORE
-             && lp->status_pending_p)
-           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 ([&] (thread_info *thread)
+      event_thread = find_thread_in_random ([&] (thread_info *thread)
        {
          lwp_info *lp = get_thread_lwp (thread);
 
-         /* Select only resumed LWPs that have an event pending.  */
-         if (thread->last_status.kind == TARGET_WAITKIND_IGNORE
-             && lp->status_pending_p)
-           if (random_selector-- == 0)
-             return true;
-
-         return false;
+         /* Only resumed LWPs that have an event pending. */
+         return (thread->last_status.kind == TARGET_WAITKIND_IGNORE
+                 && lp->status_pending_p);
        });
     }
 
@@ -2919,7 +2894,7 @@ unsuspend_all_lwps (struct lwp_info *except)
 
 static void move_out_of_jump_pad_callback (thread_info *thread);
 static bool stuck_in_jump_pad_callback (thread_info *thread);
-static int lwp_running (thread_info *thread, void *data);
+static bool lwp_running (thread_info *thread);
 static ptid_t linux_wait_1 (ptid_t ptid,
                            struct target_waitstatus *ourstatus,
                            int target_options);
@@ -2972,10 +2947,10 @@ linux_stabilize_threads (void)
   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;
@@ -3042,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;
@@ -3099,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;
@@ -3145,7 +3122,7 @@ linux_wait_1 (ptid_t ptid,
   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
     {
@@ -3234,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)))
@@ -3468,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,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;
@@ -3775,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;
 
@@ -3813,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)
     {
@@ -3872,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;
@@ -3933,36 +3910,35 @@ send_sigstop (struct lwp_info *lwp)
   kill_lwp (pid, SIGSTOP);
 }
 
-static int
-send_sigstop_callback (thread_info *thread, void *except)
+static void
+send_sigstop (thread_info *thread, lwp_info *except)
 {
   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 (thread_info *thread, void *except)
+static void
+suspend_and_send_sigstop (thread_info *thread, lwp_info *except)
 {
   struct lwp_info *lwp = get_thread_lwp (thread);
 
   /* Ignore EXCEPT.  */
   if (lwp == except)
-    return 0;
+    return;
 
   lwp_suspended_inc (lwp);
 
-  return send_sigstop_callback (thread, except);
+  send_sigstop (thread, except);
 }
 
 static void
@@ -4121,16 +4097,15 @@ move_out_of_jump_pad_callback (thread_info *thread)
   current_thread = saved_thread;
 }
 
-static int
-lwp_running (thread_info *thread, void *data)
+static bool
+lwp_running (thread_info *thread)
 {
   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.
@@ -4158,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;
 
@@ -4196,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.
@@ -4496,16 +4477,15 @@ 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
 }
 
 /* This function is called once per thread via for_each_thread.
@@ -4524,13 +4504,13 @@ linux_set_resume_request (thread_info *thread, thread_resume *resume, size_t n)
   for (int ndx = 0; ndx < n; ndx++)
     {
       ptid_t ptid = resume[ndx].thread;
-      if (ptid_equal (ptid, minus_one_ptid)
+      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 (resume[ndx].kind == resume_stop
              && thread->last_resume_kind == resume_stop)
@@ -4620,8 +4600,8 @@ linux_set_resume_request (thread_info *thread, thread_resume *resume, size_t n)
   lwp->resume = NULL;
 }
 
-/* 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 bool
 resume_status_pending_p (thread_info *thread)
@@ -4755,7 +4735,7 @@ need_step_over_p (thread_info *thread)
                          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 true;
@@ -4881,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;
@@ -4918,15 +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 (thread_info *thread, void *arg)
+static void
+linux_resume_one_thread (thread_info *thread, bool leave_all_stopped)
 {
   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)
     {
@@ -4973,7 +4952,7 @@ linux_resume_one_thread (thread_info *thread, 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,
@@ -5021,14 +5000,12 @@ linux_resume_one_thread (thread_info *thread, 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_info *need_step_over = NULL;
-  int leave_all_stopped;
 
   if (debug_threads)
     {
@@ -5060,7 +5037,7 @@ linux_resume (struct thread_resume *resume_info, size_t n)
   if (!any_pending && supports_breakpoints ())
     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)
     {
@@ -5075,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));
@@ -5101,14 +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 (thread_info *thread, void *except)
+static void
+proceed_one_lwp (thread_info *thread, lwp_info *except)
 {
   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));
@@ -5117,7 +5097,7 @@ proceed_one_lwp (thread_info *thread, 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
@@ -5126,7 +5106,7 @@ proceed_one_lwp (thread_info *thread, 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)
@@ -5134,7 +5114,7 @@ proceed_one_lwp (thread_info *thread, 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);
@@ -5143,7 +5123,7 @@ proceed_one_lwp (thread_info *thread, 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
@@ -5196,20 +5176,19 @@ proceed_one_lwp (thread_info *thread, void *except)
     step = 0;
 
   linux_resume_one_lwp (lwp, step, 0, NULL);
-  return 0;
 }
 
-static int
-unsuspend_and_proceed_one_lwp (thread_info *thread, void *except)
+static void
+unsuspend_and_proceed_one_lwp (thread_info *thread, lwp_info *except)
 {
   struct lwp_info *lwp = get_thread_lwp (thread);
 
   if (lwp == except)
-    return 0;
+    return;
 
   lwp_suspended_decr (lwp);
 
-  return proceed_one_lwp (thread, except);
+  proceed_one_lwp (thread, except);
 }
 
 /* When we finish a step-over, set threads running again.  If there's
@@ -5245,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
@@ -5266,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)
     {
@@ -5342,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)
@@ -5440,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)
@@ -5542,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)
@@ -5600,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);
     }
@@ -6188,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);
     }
@@ -6223,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)
        {
@@ -6231,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;
@@ -6257,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;
@@ -6362,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
 {
@@ -6965,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;
@@ -6996,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;
 
@@ -7016,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
        {
@@ -7070,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,
@@ -7102,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
@@ -7115,31 +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);
-
              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;
-               }
-
-             std::string name = xml_escape_text ((char *) libname);
-             p += sprintf (p, "<library name=\"%s\" lm=\"0x%lx\" "
-                           "l_addr=\"0x%lx\" l_ld=\"0x%lx\"/>",
-                           name.c_str (), (unsigned long) lm_addr,
-                           (unsigned long) l_addr, (unsigned long) l_ld);
+             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);
            }
        }
 
@@ -7150,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
@@ -7163,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;
 }
@@ -7215,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)
@@ -7238,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)
@@ -7252,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;
@@ -7290,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.  */
@@ -7430,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.  */
+
+CORE_ADDR
+linux_get_hwcap (int wordsize)
+{
+  CORE_ADDR hwcap = 0;
+  linux_get_auxv (wordsize, AT_HWCAP, &hwcap);
+  return hwcap;
+}
+
+/* See linux-low.h.  */
 
-static struct target_ops linux_target_ops = {
+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,
@@ -7473,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,
@@ -7508,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,
@@ -7518,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,
@@ -7559,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.047733 seconds and 4 git commands to generate.