Multi-target support
[deliverable/binutils-gdb.git] / gdb / gdbserver / linux-low.c
index a290b5b8b7360fdc74ea772e06437f133741050d..676dea26c637afbd0a146f78810f20ccbda0b830 100644 (file)
@@ -1,5 +1,5 @@
 /* Low level interface to ptrace, for the remote server for GDB.
-   Copyright (C) 1995-2018 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 "common/scoped_restore.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
@@ -951,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;
 }
 
@@ -1159,7 +1160,7 @@ 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)
@@ -1188,18 +1189,19 @@ linux_attach (unsigned long pid)
   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)
     {
-      std::string reason = linux_ptrace_attach_fail_reason_string (ptid, err);
+      remove_process (proc);
 
+      std::string reason = linux_ptrace_attach_fail_reason_string (ptid, err);
       error ("Cannot attach to process %ld: %s", pid, reason.c_str ());
     }
 
-  proc = linux_add_process (pid, 1);
-
   /* Don't ignore the initial SIGSTOP if we just attached to this
      process.  It will be collected by wait shortly.  */
   initial_thread = find_thread_ptid (ptid_t (pid, pid, 0));
@@ -1255,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)
        {
@@ -1302,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;
@@ -1313,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");
     }
 }
 
@@ -1385,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.  */
@@ -1405,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 (ptid_t (pid));
+  lwp_info *lwp = find_lwp_pid (ptid_t (pid));
 
   if (lwp == NULL)
     {
@@ -1531,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);
@@ -1540,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,
@@ -1565,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))
            {
@@ -1578,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)
@@ -1608,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);
@@ -1638,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 (ptid_t (pid));
+  main_lwp = find_lwp_pid (ptid_t (process->pid));
   linux_detach_one_lwp (main_lwp);
 
   the_target->mourn (process);
@@ -1821,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)
@@ -1852,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)
@@ -2635,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)
        {
@@ -2647,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);
 
@@ -2700,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
@@ -2726,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)
        {
@@ -2786,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;
        }
 
@@ -2796,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;
        }
 
@@ -2805,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;
 
@@ -2835,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
@@ -2869,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);
        });
     }
 
@@ -3159,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
     {
@@ -3248,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)))
@@ -3736,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;
@@ -3827,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)
     {
@@ -3886,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;
@@ -4514,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.
@@ -4542,12 +4504,12 @@ 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.pid () == pid_of (thread)
-             && (ptid_is_pid (ptid)
+             && (ptid.is_pid ()
                  || ptid.lwp () == -1)))
        {
          if (resume[ndx].kind == resume_stop
@@ -4899,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;
@@ -5368,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)
@@ -5466,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)
@@ -5630,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);
     }
@@ -6218,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);
     }
@@ -6253,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)
        {
@@ -6261,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;
@@ -6287,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;
@@ -6392,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
 {
@@ -7042,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
        {
@@ -7223,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)
@@ -7246,9 +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;
 
   err = linux_read_btrace (&btrace, tinfo, type);
   if (err != BTRACE_ERR_NONE)
@@ -7271,11 +7139,9 @@ linux_low_read_btrace (struct btrace_target_info *tinfo, struct buffer *buffer,
       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;
@@ -7431,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.  */
+
+CORE_ADDR
+linux_get_hwcap2 (int wordsize)
+{
+  CORE_ADDR hwcap2 = 0;
+  linux_get_auxv (wordsize, AT_HWCAP2, &hwcap2);
+  return hwcap2;
+}
 
-static struct target_ops linux_target_ops = {
+static process_stratum_target linux_target_ops = {
   linux_create_inferior,
   linux_post_create_inferior,
   linux_attach,
@@ -7474,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,
@@ -7558,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.036957 seconds and 4 git commands to generate.