]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdbserver/linux-low.cc
gdb, gdbserver, gdbsupport: fix whitespace issues
[thirdparty/binutils-gdb.git] / gdbserver / linux-low.cc
index 449c6641f58f99f9eb9e5426011f58012f24d579..e6a39202a98af314738aa6a46c7f091e1c298424 100644 (file)
@@ -1,5 +1,5 @@
 /* Low level interface to ptrace, for the remote server for GDB.
-   Copyright (C) 1995-2022 Free Software Foundation, Inc.
+   Copyright (C) 1995-2023 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -440,6 +440,20 @@ linux_process_target::add_linux_process (int pid, int attached)
   return proc;
 }
 
+void
+linux_process_target::remove_linux_process (process_info *proc)
+{
+  if (proc->priv->mem_fd >= 0)
+    close (proc->priv->mem_fd);
+
+  this->low_delete_process (proc->priv->arch_private);
+
+  xfree (proc->priv);
+  proc->priv = nullptr;
+
+  remove_process (proc);
+}
+
 arch_process_info *
 linux_process_target::low_new_process ()
 {
@@ -727,14 +741,14 @@ linux_process_target::handle_extended_wait (lwp_info **orig_event_lwp,
       return 0;
     }
 
-  internal_error (__FILE__, __LINE__, _("unknown ptrace event %d"), event);
+  internal_error (_("unknown ptrace event %d"), event);
 }
 
 CORE_ADDR
 linux_process_target::get_pc (lwp_info *lwp)
 {
-  struct regcache *regcache;
-  CORE_ADDR pc;
+  process_info *proc = get_thread_process (get_lwp_thread (lwp));
+  gdb_assert (!proc->starting_up);
 
   if (!low_supports_breakpoints ())
     return 0;
@@ -742,8 +756,8 @@ linux_process_target::get_pc (lwp_info *lwp)
   scoped_restore_current_thread restore_thread;
   switch_to_thread (get_lwp_thread (lwp));
 
-  regcache = get_thread_regcache (current_thread, 1);
-  pc = low_get_pc (regcache);
+  struct regcache *regcache = get_thread_regcache (current_thread, 1);
+  CORE_ADDR pc = low_get_pc (regcache);
 
   threads_debug_printf ("pc is 0x%lx", (long) pc);
 
@@ -783,6 +797,14 @@ linux_process_target::save_stop_reason (lwp_info *lwp)
   if (!low_supports_breakpoints ())
     return false;
 
+  process_info *proc = get_thread_process (get_lwp_thread (lwp));
+  if (proc->starting_up)
+    {
+      /* Claim we have the stop PC so that the caller doesn't try to
+        fetch it itself.  */
+      return true;
+    }
+
   pc = get_pc (lwp);
   sw_breakpoint_pc = pc - low_decr_pc_after_break ();
 
@@ -1136,7 +1158,7 @@ linux_process_target::attach (unsigned long pid)
   err = attach_lwp (ptid);
   if (err != 0)
     {
-      remove_process (proc);
+      this->remove_linux_process (proc);
 
       std::string reason = linux_ptrace_attach_fail_reason_string (ptid, err);
       error ("Cannot attach to process %ld: %s", pid, reason.c_str ());
@@ -1565,8 +1587,6 @@ linux_process_target::detach (process_info *process)
 void
 linux_process_target::mourn (process_info *process)
 {
-  struct process_info_private *priv;
-
 #ifdef USE_THREAD_DB
   thread_db_mourn (process);
 #endif
@@ -1576,14 +1596,7 @@ linux_process_target::mourn (process_info *process)
       delete_lwp (get_thread_lwp (thread));
     });
 
-  /* Freeing all private data.  */
-  priv = process->priv;
-  close (priv->mem_fd);
-  low_delete_process (priv->arch_private);
-  free (priv);
-  process->priv = NULL;
-
-  remove_process (process);
+  this->remove_linux_process (process);
 }
 
 void
@@ -1718,9 +1731,9 @@ linux_process_target::status_pending_p_callback (thread_info *thread,
 struct lwp_info *
 find_lwp_pid (ptid_t ptid)
 {
-  thread_info *thread = find_thread ([&] (thread_info *thr_arg)
+  long lwp = ptid.lwp () != 0 ? ptid.lwp () : ptid.pid ();
+  thread_info *thread = find_thread ([lwp] (thread_info *thr_arg)
     {
-      int lwp = ptid.lwp () != 0 ? ptid.lwp () : ptid.pid ();
       return thr_arg->id.lwp () == lwp;
     });
 
@@ -1879,8 +1892,7 @@ lwp_suspended_decr (struct lwp_info *lwp)
     {
       struct thread_info *thread = get_lwp_thread (lwp);
 
-      internal_error (__FILE__, __LINE__,
-                     "unsuspend LWP %ld, suspended=%d\n", lwpid_of (thread),
+      internal_error ("unsuspend LWP %ld, suspended=%d\n", lwpid_of (thread),
                      lwp->suspended);
     }
 }
@@ -2511,8 +2523,7 @@ linux_process_target::wait_for_event_filtered (ptid_t wait_ptid,
       if (requested_child->suspended
          && requested_child->status_pending_p)
        {
-         internal_error (__FILE__, __LINE__,
-                         "requesting an event out of a"
+         internal_error ("requesting an event out of a"
                          " suspended child?");
        }
 
@@ -3529,7 +3540,7 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus,
   else
     {
       /* The LWP stopped due to a plain signal or a syscall signal.  Either way,
-         event_chid->waitstatus wasn't filled in with the details, so look at
+        event_chid->waitstatus wasn't filled in with the details, so look at
         the wait status W.  */
       if (WSTOPSIG (w) == SYSCALL_SIGTRAP)
        {
@@ -3780,8 +3791,7 @@ linux_process_target::stuck_in_jump_pad (thread_info *thread)
 
   if (lwp->suspended != 0)
     {
-      internal_error (__FILE__, __LINE__,
-                     "LWP %ld is suspended, suspended=%d\n",
+      internal_error ("LWP %ld is suspended, suspended=%d\n",
                      lwpid_of (thread), lwp->suspended);
     }
   gdb_assert (lwp->stopped);
@@ -3804,8 +3814,7 @@ linux_process_target::move_out_of_jump_pad (thread_info *thread)
 
   if (lwp->suspended != 0)
     {
-      internal_error (__FILE__, __LINE__,
-                     "LWP %ld is suspended, suspended=%d\n",
+      internal_error ("LWP %ld is suspended, suspended=%d\n",
                      lwpid_of (thread), lwp->suspended);
     }
   gdb_assert (lwp->stopped);
@@ -4054,8 +4063,7 @@ linux_process_target::resume_one_lwp_throw (lwp_info *lwp, int step,
        step = 1;
       else
        {
-         internal_error (__FILE__, __LINE__,
-                         "moving out of jump pad single-stepping"
+         internal_error ("moving out of jump pad single-stepping"
                          " not implemented on this target");
        }
     }
@@ -4456,8 +4464,7 @@ linux_process_target::start_step_over (lwp_info *lwp)
 
   if (lwp->suspended != 0)
     {
-      internal_error (__FILE__, __LINE__,
-                     "LWP %ld suspended=%d\n", lwpid_of (thread),
+      internal_error ("LWP %ld suspended=%d\n", lwpid_of (thread),
                      lwp->suspended);
     }
 
@@ -5383,7 +5390,7 @@ proc_xfer_memory (CORE_ADDR memaddr, unsigned char *readbuf,
       if (lseek (fd, memaddr, SEEK_SET) != -1)
        bytes = (readbuf != nullptr
                 ? read (fd, readbuf, len)
-                ? write (fd, writebuf, len));
+                : write (fd, writebuf, len));
 #endif
 
       if (bytes < 0)
@@ -5460,7 +5467,10 @@ linux_process_target::request_interrupt ()
 {
   /* Send a SIGINT to the process group.  This acts just like the user
      typed a ^C on the controlling terminal.  */
-  ::kill (-signal_pid, SIGINT);
+  int res = ::kill (-signal_pid, SIGINT);
+  if (res == -1)
+    warning (_("Sending SIGINT to process group of pid %ld failed: %s"),
+            signal_pid, safe_strerror (errno));
 }
 
 bool
@@ -5473,12 +5483,11 @@ linux_process_target::supports_read_auxv ()
    to debugger memory starting at MYADDR.  */
 
 int
-linux_process_target::read_auxv (CORE_ADDR offset, unsigned char *myaddr,
-                                unsigned int len)
+linux_process_target::read_auxv (int pid, CORE_ADDR offset,
+                                unsigned char *myaddr, unsigned int len)
 {
   char filename[PATH_MAX];
   int fd, n;
-  int pid = lwpid_of (current_thread);
 
   xsnprintf (filename, sizeof filename, "/proc/%d/auxv", pid);
 
@@ -6430,6 +6439,9 @@ struct link_map_offsets
     /* Offset and size of r_debug.r_map.  */
     int r_map_offset;
 
+    /* Offset of r_debug_extended.r_next.  */
+    int r_next_offset;
+
     /* Offset to l_addr field in struct link_map.  */
     int l_addr_offset;
 
@@ -6446,6 +6458,79 @@ struct link_map_offsets
     int l_prev_offset;
   };
 
+static const link_map_offsets lmo_32bit_offsets =
+  {
+    0,     /* r_version offset.  */
+    4,     /* r_debug.r_map offset.  */
+    20,    /* r_debug_extended.r_next.  */
+    0,     /* l_addr offset in link_map.  */
+    4,     /* l_name offset in link_map.  */
+    8,     /* l_ld offset in link_map.  */
+    12,    /* l_next offset in link_map.  */
+    16     /* l_prev offset in link_map.  */
+  };
+
+static const link_map_offsets lmo_64bit_offsets =
+  {
+    0,     /* r_version offset.  */
+    8,     /* r_debug.r_map offset.  */
+    40,    /* r_debug_extended.r_next.  */
+    0,     /* l_addr offset in link_map.  */
+    8,     /* l_name offset in link_map.  */
+    16,    /* l_ld offset in link_map.  */
+    24,    /* l_next offset in link_map.  */
+    32     /* l_prev offset in link_map.  */
+  };
+
+/* Get the loaded shared libraries from one namespace.  */
+
+static void
+read_link_map (std::string &document, CORE_ADDR lmid, CORE_ADDR lm_addr,
+              CORE_ADDR lm_prev, int ptr_size, const link_map_offsets *lmo)
+{
+  CORE_ADDR l_name, l_addr, l_ld, l_next, l_prev;
+
+  while (lm_addr
+        && read_one_ptr (lm_addr + lmo->l_name_offset,
+                         &l_name, ptr_size) == 0
+        && read_one_ptr (lm_addr + lmo->l_addr_offset,
+                         &l_addr, ptr_size) == 0
+        && read_one_ptr (lm_addr + lmo->l_ld_offset,
+                         &l_ld, ptr_size) == 0
+        && read_one_ptr (lm_addr + lmo->l_prev_offset,
+                         &l_prev, ptr_size) == 0
+        && read_one_ptr (lm_addr + lmo->l_next_offset,
+                         &l_next, ptr_size) == 0)
+    {
+      unsigned char libname[PATH_MAX];
+
+      if (lm_prev != l_prev)
+       {
+         warning ("Corrupted shared library list: 0x%s != 0x%s",
+                  paddress (lm_prev), paddress (l_prev));
+         break;
+       }
+
+      /* Not checking for error because reading may stop before we've got
+        PATH_MAX worth of characters.  */
+      libname[0] = '\0';
+      linux_read_memory (l_name, libname, sizeof (libname) - 1);
+      libname[sizeof (libname) - 1] = '\0';
+      if (libname[0] != '\0')
+       {
+         string_appendf (document, "<library name=\"");
+         xml_escape_text_append (document, (char *) libname);
+         string_appendf (document, "\" lm=\"0x%s\" l_addr=\"0x%s\" "
+                         "l_ld=\"0x%s\" lmid=\"0x%s\"/>",
+                         paddress (lm_addr), paddress (l_addr),
+                         paddress (l_ld), paddress (lmid));
+       }
+
+      lm_prev = lm_addr;
+      lm_addr = l_next;
+    }
+}
+
 /* Construct qXfer:libraries-svr4:read reply.  */
 
 int
@@ -6457,34 +6542,8 @@ linux_process_target::qxfer_libraries_svr4 (const char *annex,
   struct process_info_private *const priv = current_process ()->priv;
   char filename[PATH_MAX];
   int pid, is_elf64;
-
-  static const struct link_map_offsets lmo_32bit_offsets =
-    {
-      0,     /* r_version offset. */
-      4,     /* r_debug.r_map offset.  */
-      0,     /* l_addr offset in link_map.  */
-      4,     /* l_name offset in link_map.  */
-      8,     /* l_ld offset in link_map.  */
-      12,    /* l_next offset in link_map.  */
-      16     /* l_prev offset in link_map.  */
-    };
-
-  static const struct link_map_offsets lmo_64bit_offsets =
-    {
-      0,     /* r_version offset. */
-      8,     /* r_debug.r_map offset.  */
-      0,     /* l_addr offset in link_map.  */
-      8,     /* l_name offset in link_map.  */
-      16,    /* l_ld offset in link_map.  */
-      24,    /* l_next offset in link_map.  */
-      32     /* l_prev offset in link_map.  */
-    };
-  const struct link_map_offsets *lmo;
   unsigned int machine;
-  int ptr_size;
-  CORE_ADDR lm_addr = 0, lm_prev = 0;
-  CORE_ADDR l_name, l_addr, l_ld, l_next, l_prev;
-  int header_done = 0;
+  CORE_ADDR lmid = 0, lm_addr = 0, lm_prev = 0;
 
   if (writebuf != NULL)
     return -2;
@@ -6494,8 +6553,18 @@ linux_process_target::qxfer_libraries_svr4 (const char *annex,
   pid = lwpid_of (current_thread);
   xsnprintf (filename, sizeof filename, "/proc/%d/exe", pid);
   is_elf64 = elf_64_file_p (filename, &machine);
-  lmo = is_elf64 ? &lmo_64bit_offsets : &lmo_32bit_offsets;
-  ptr_size = is_elf64 ? 8 : 4;
+  const link_map_offsets *lmo;
+  int ptr_size;
+  if (is_elf64)
+    {
+      lmo = &lmo_64bit_offsets;
+      ptr_size = 8;
+    }
+  else
+    {
+      lmo = &lmo_32bit_offsets;
+      ptr_size = 4;
+    }
 
   while (annex[0] != '\0')
     {
@@ -6508,7 +6577,9 @@ linux_process_target::qxfer_libraries_svr4 (const char *annex,
        break;
 
       name_len = sep - annex;
-      if (name_len == 5 && startswith (annex, "start"))
+      if (name_len == 4 && startswith (annex, "lmid"))
+       addrp = &lmid;
+      else if (name_len == 5 && startswith (annex, "start"))
        addrp = &lm_addr;
       else if (name_len == 4 && startswith (annex, "prev"))
        addrp = &lm_prev;
@@ -6524,104 +6595,109 @@ linux_process_target::qxfer_libraries_svr4 (const char *annex,
       annex = decode_address_to_semicolon (addrp, sep + 1);
     }
 
-  if (lm_addr == 0)
+  std::string document = "<library-list-svr4 version=\"1.0\"";
+
+  /* When the starting LM_ADDR is passed in the annex, only traverse that
+     namespace, which is assumed to be identified by LMID.
+
+     Otherwise, start with R_DEBUG and traverse all namespaces we find.  */
+  if (lm_addr != 0)
+    {
+      document += ">";
+      read_link_map (document, lmid, lm_addr, lm_prev, ptr_size, lmo);
+    }
+  else
     {
-      int r_version = 0;
+      if (lm_prev != 0)
+       warning ("ignoring prev=0x%s without start", paddress (lm_prev));
 
-      if (priv->r_debug == 0)
-       priv->r_debug = get_r_debug (pid, is_elf64);
+      /* We could interpret LMID as 'provide only the libraries for this
+        namespace' but GDB is currently only providing lmid, start, and
+        prev, or nothing.  */
+      if (lmid != 0)
+       warning ("ignoring lmid=0x%s without start", paddress (lmid));
+
+      CORE_ADDR r_debug = priv->r_debug;
+      if (r_debug == 0)
+       r_debug = priv->r_debug = get_r_debug (pid, is_elf64);
 
       /* We failed to find DT_DEBUG.  Such situation will not change
         for this inferior - do not retry it.  Report it to GDB as
         E01, see for the reasons at the GDB solib-svr4.c side.  */
-      if (priv->r_debug == (CORE_ADDR) -1)
+      if (r_debug == (CORE_ADDR) -1)
        return -1;
 
-      if (priv->r_debug != 0)
+      /* Terminate the header if we end up with an empty list.  */
+      if (r_debug == 0)
+       document += ">";
+
+      while (r_debug != 0)
        {
-         if (linux_read_memory (priv->r_debug + lmo->r_version_offset,
+         int r_version = 0;
+         if (linux_read_memory (r_debug + lmo->r_version_offset,
                                 (unsigned char *) &r_version,
-                                sizeof (r_version)) != 0
-             || r_version < 1)
+                                sizeof (r_version)) != 0)
            {
-             warning ("unexpected r_debug version %d", r_version);
+             warning ("unable to read r_version from 0x%s",
+                      paddress (r_debug + lmo->r_version_offset));
+             break;
            }
-         else if (read_one_ptr (priv->r_debug + lmo->r_map_offset,
-                                &lm_addr, ptr_size) != 0)
+
+         if (r_version < 1)
            {
-             warning ("unable to read r_map from 0x%lx",
-                      (long) priv->r_debug + lmo->r_map_offset);
+             warning ("unexpected r_debug version %d", r_version);
+             break;
            }
-       }
-    }
-
-  std::string document = "<library-list-svr4 version=\"1.0\"";
 
-  while (lm_addr
-        && read_one_ptr (lm_addr + lmo->l_name_offset,
-                         &l_name, ptr_size) == 0
-        && read_one_ptr (lm_addr + lmo->l_addr_offset,
-                         &l_addr, ptr_size) == 0
-        && read_one_ptr (lm_addr + lmo->l_ld_offset,
-                         &l_ld, ptr_size) == 0
-        && read_one_ptr (lm_addr + lmo->l_prev_offset,
-                         &l_prev, ptr_size) == 0
-        && read_one_ptr (lm_addr + lmo->l_next_offset,
-                         &l_next, ptr_size) == 0)
-    {
-      unsigned char libname[PATH_MAX];
+         if (read_one_ptr (r_debug + lmo->r_map_offset, &lm_addr,
+                           ptr_size) != 0)
+           {
+             warning ("unable to read r_map from 0x%s",
+                      paddress (r_debug + lmo->r_map_offset));
+             break;
+           }
 
-      if (lm_prev != l_prev)
-       {
-         warning ("Corrupted shared library list: 0x%lx != 0x%lx",
-                  (long) lm_prev, (long) l_prev);
-         break;
-       }
+         /* We read the entire namespace.  */
+         lm_prev = 0;
 
-      /* Ignore the first entry even if it has valid name as the first entry
-        corresponds to the main executable.  The first entry should not be
-        skipped if the dynamic loader was loaded late by a static executable
-        (see solib-svr4.c parameter ignore_first).  But in such case the main
-        executable does not have PT_DYNAMIC present and this function already
-        exited above due to failed get_r_debug.  */
-      if (lm_prev == 0)
-       string_appendf (document, " main-lm=\"0x%lx\"", (unsigned long) lm_addr);
-      else
-       {
-         /* Not checking for error because reading may stop before
-            we've got PATH_MAX worth of characters.  */
-         libname[0] = '\0';
-         linux_read_memory (l_name, libname, sizeof (libname) - 1);
-         libname[sizeof (libname) - 1] = '\0';
-         if (libname[0] != '\0')
+         /* The first entry corresponds to the main executable unless the
+            dynamic loader was loaded late by a static executable.  But
+            in such case the main executable does not have PT_DYNAMIC
+            present and we would not have gotten here.  */
+         if (r_debug == priv->r_debug)
            {
-             if (!header_done)
+             if (lm_addr != 0)
+               string_appendf (document, " main-lm=\"0x%s\">",
+                               paddress (lm_addr));
+             else
+               document += ">";
+
+             lm_prev = lm_addr;
+             if (read_one_ptr (lm_addr + lmo->l_next_offset,
+                               &lm_addr, ptr_size) != 0)
                {
-                 /* Terminate `<library-list-svr4'.  */
-                 document += '>';
-                 header_done = 1;
+                 warning ("unable to read l_next from 0x%s",
+                          paddress (lm_addr + lmo->l_next_offset));
+                 break;
                }
+           }
 
-             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);
+         read_link_map (document, r_debug, lm_addr, lm_prev, ptr_size, lmo);
+
+         if (r_version < 2)
+           break;
+
+         if (read_one_ptr (r_debug + lmo->r_next_offset, &r_debug,
+                           ptr_size) != 0)
+           {
+             warning ("unable to read r_next from 0x%s",
+                      paddress (r_debug + lmo->r_next_offset));
+             break;
            }
        }
-
-      lm_prev = lm_addr;
-      lm_addr = l_next;
     }
 
-  if (!header_done)
-    {
-      /* Empty list; terminate `<library-list-svr4'.  */
-      document += "/>";
-    }
-  else
-    document += "</library-list-svr4>";
+  document += "</library-list-svr4>";
 
   int document_len = document.length ();
   if (offset < document_len)
@@ -6638,6 +6714,12 @@ linux_process_target::qxfer_libraries_svr4 (const char *annex,
 
 #ifdef HAVE_LINUX_BTRACE
 
+bool
+linux_process_target::supports_btrace ()
+{
+  return true;
+}
+
 btrace_target_info *
 linux_process_target::enable_btrace (thread_info *tp,
                                     const btrace_config *conf)
@@ -6659,38 +6741,38 @@ linux_process_target::disable_btrace (btrace_target_info *tinfo)
 /* Encode an Intel Processor Trace configuration.  */
 
 static void
-linux_low_encode_pt_config (struct buffer *buffer,
+linux_low_encode_pt_config (std::string *buffer,
                            const struct btrace_data_pt_config *config)
 {
-  buffer_grow_str (buffer, "<pt-config>\n");
+  *buffer += "<pt-config>\n";
 
   switch (config->cpu.vendor)
     {
     case CV_INTEL:
-      buffer_xml_printf (buffer, "<cpu vendor=\"GenuineIntel\" family=\"%u\" "
-                        "model=\"%u\" stepping=\"%u\"/>\n",
-                        config->cpu.family, config->cpu.model,
-                        config->cpu.stepping);
+      string_xml_appendf (*buffer, "<cpu vendor=\"GenuineIntel\" family=\"%u\" "
+                         "model=\"%u\" stepping=\"%u\"/>\n",
+                         config->cpu.family, config->cpu.model,
+                         config->cpu.stepping);
       break;
 
     default:
       break;
     }
 
-  buffer_grow_str (buffer, "</pt-config>\n");
+  *buffer += "</pt-config>\n";
 }
 
 /* Encode a raw buffer.  */
 
 static void
-linux_low_encode_raw (struct buffer *buffer, const gdb_byte *data,
+linux_low_encode_raw (std::string *buffer, const gdb_byte *data,
                      unsigned int size)
 {
   if (size == 0)
     return;
 
   /* We use hex encoding - see gdbsupport/rsp-low.h.  */
-  buffer_grow_str (buffer, "<raw>\n");
+  *buffer += "<raw>\n";
 
   while (size-- > 0)
     {
@@ -6699,17 +6781,17 @@ linux_low_encode_raw (struct buffer *buffer, const gdb_byte *data,
       elem[0] = tohex ((*data >> 4) & 0xf);
       elem[1] = tohex (*data++ & 0xf);
 
-      buffer_grow (buffer, elem, 2);
+      buffer->append (elem, 2);
     }
 
-  buffer_grow_str (buffer, "</raw>\n");
+  *buffer += "</raw>\n";
 }
 
 /* See to_read_btrace target method.  */
 
 int
 linux_process_target::read_btrace (btrace_target_info *tinfo,
-                                  buffer *buffer,
+                                  std::string *buffer,
                                   enum btrace_read_type type)
 {
   struct btrace_data btrace;
@@ -6719,9 +6801,9 @@ linux_process_target::read_btrace (btrace_target_info *tinfo,
   if (err != BTRACE_ERR_NONE)
     {
       if (err == BTRACE_ERR_OVERFLOW)
-       buffer_grow_str0 (buffer, "E.Overflow.");
+       *buffer += "E.Overflow.";
       else
-       buffer_grow_str0 (buffer, "E.Generic Error.");
+       *buffer += "E.Generic Error.";
 
       return -1;
     }
@@ -6729,36 +6811,36 @@ linux_process_target::read_btrace (btrace_target_info *tinfo,
   switch (btrace.format)
     {
     case BTRACE_FORMAT_NONE:
-      buffer_grow_str0 (buffer, "E.No Trace.");
+      *buffer += "E.No Trace.";
       return -1;
 
     case BTRACE_FORMAT_BTS:
-      buffer_grow_str (buffer, "<!DOCTYPE btrace SYSTEM \"btrace.dtd\">\n");
-      buffer_grow_str (buffer, "<btrace version=\"1.0\">\n");
+      *buffer += "<!DOCTYPE btrace SYSTEM \"btrace.dtd\">\n";
+      *buffer += "<btrace version=\"1.0\">\n";
 
       for (const btrace_block &block : *btrace.variant.bts.blocks)
-       buffer_xml_printf (buffer, "<block begin=\"0x%s\" end=\"0x%s\"/>\n",
-                          paddress (block.begin), paddress (block.end));
+       string_xml_appendf (*buffer, "<block begin=\"0x%s\" end=\"0x%s\"/>\n",
+                           paddress (block.begin), paddress (block.end));
 
-      buffer_grow_str0 (buffer, "</btrace>\n");
+      *buffer += "</btrace>\n";
       break;
 
     case BTRACE_FORMAT_PT:
-      buffer_grow_str (buffer, "<!DOCTYPE btrace SYSTEM \"btrace.dtd\">\n");
-      buffer_grow_str (buffer, "<btrace version=\"1.0\">\n");
-      buffer_grow_str (buffer, "<pt>\n");
+      *buffer += "<!DOCTYPE btrace SYSTEM \"btrace.dtd\">\n";
+      *buffer += "<btrace version=\"1.0\">\n";
+      *buffer += "<pt>\n";
 
       linux_low_encode_pt_config (buffer, &btrace.variant.pt.config);
 
       linux_low_encode_raw (buffer, btrace.variant.pt.data,
                            btrace.variant.pt.size);
 
-      buffer_grow_str (buffer, "</pt>\n");
-      buffer_grow_str0 (buffer, "</btrace>\n");
+      *buffer += "</pt>\n";
+      *buffer += "</btrace>\n";
       break;
 
     default:
-      buffer_grow_str0 (buffer, "E.Unsupported Trace Format.");
+      *buffer += "E.Unsupported Trace Format.";
       return -1;
     }
 
@@ -6769,12 +6851,12 @@ linux_process_target::read_btrace (btrace_target_info *tinfo,
 
 int
 linux_process_target::read_btrace_conf (const btrace_target_info *tinfo,
-                                       buffer *buffer)
+                                       std::string *buffer)
 {
   const struct btrace_config *conf;
 
-  buffer_grow_str (buffer, "<!DOCTYPE btrace-conf SYSTEM \"btrace-conf.dtd\">\n");
-  buffer_grow_str (buffer, "<btrace-conf version=\"1.0\">\n");
+  *buffer += "<!DOCTYPE btrace-conf SYSTEM \"btrace-conf.dtd\">\n";
+  *buffer += "<btrace-conf version=\"1.0\">\n";
 
   conf = linux_btrace_conf (tinfo);
   if (conf != NULL)
@@ -6785,20 +6867,20 @@ linux_process_target::read_btrace_conf (const btrace_target_info *tinfo,
          break;
 
        case BTRACE_FORMAT_BTS:
-         buffer_xml_printf (buffer, "<bts");
-         buffer_xml_printf (buffer, " size=\"0x%x\"", conf->bts.size);
-         buffer_xml_printf (buffer, " />\n");
+         string_xml_appendf (*buffer, "<bts");
+         string_xml_appendf (*buffer, " size=\"0x%x\"", conf->bts.size);
+         string_xml_appendf (*buffer, " />\n");
          break;
 
        case BTRACE_FORMAT_PT:
-         buffer_xml_printf (buffer, "<pt");
-         buffer_xml_printf (buffer, " size=\"0x%x\"", conf->pt.size);
-         buffer_xml_printf (buffer, "/>\n");
+         string_xml_appendf (*buffer, "<pt");
+         string_xml_appendf (*buffer, " size=\"0x%x\"", conf->pt.size);
+         string_xml_appendf (*buffer, "/>\n");
          break;
        }
     }
 
-  buffer_grow_str0 (buffer, "</btrace-conf>\n");
+  *buffer += "</btrace-conf>\n";
   return 0;
 }
 #endif /* HAVE_LINUX_BTRACE */
@@ -6899,14 +6981,15 @@ linux_get_pc_64bit (struct regcache *regcache)
 /* See linux-low.h.  */
 
 int
-linux_get_auxv (int wordsize, CORE_ADDR match, CORE_ADDR *valp)
+linux_get_auxv (int pid, int wordsize, CORE_ADDR match, CORE_ADDR *valp)
 {
   gdb_byte *data = (gdb_byte *) alloca (2 * wordsize);
   int offset = 0;
 
   gdb_assert (wordsize == 4 || wordsize == 8);
 
-  while (the_target->read_auxv (offset, data, 2 * wordsize) == 2 * wordsize)
+  while (the_target->read_auxv (pid, offset, data, 2 * wordsize)
+        == 2 * wordsize)
     {
       if (wordsize == 4)
        {
@@ -6936,20 +7019,20 @@ linux_get_auxv (int wordsize, CORE_ADDR match, CORE_ADDR *valp)
 /* See linux-low.h.  */
 
 CORE_ADDR
-linux_get_hwcap (int wordsize)
+linux_get_hwcap (int pid, int wordsize)
 {
   CORE_ADDR hwcap = 0;
-  linux_get_auxv (wordsize, AT_HWCAP, &hwcap);
+  linux_get_auxv (pid, wordsize, AT_HWCAP, &hwcap);
   return hwcap;
 }
 
 /* See linux-low.h.  */
 
 CORE_ADDR
-linux_get_hwcap2 (int wordsize)
+linux_get_hwcap2 (int pid, int wordsize)
 {
   CORE_ADDR hwcap2 = 0;
-  linux_get_auxv (wordsize, AT_HWCAP2, &hwcap2);
+  linux_get_auxv (pid, wordsize, AT_HWCAP2, &hwcap2);
   return hwcap2;
 }