FreeBSD: Fix 'Couldn't get registers: Device busy' error (PR gdb/23077)
[deliverable/binutils-gdb.git] / gdb / remote.c
index 61f71698bafd0a6cba7f4454d7d7fdbc95562c07..49013848d5553dd1da0b014d3ef8001bfb65ca89 100644 (file)
@@ -1,6 +1,6 @@
 /* Remote target communications for serial-line targets in custom GDB protocol
 
-   Copyright (C) 1988-2017 Free Software Foundation, Inc.
+   Copyright (C) 1988-2018 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -36,7 +36,7 @@
 #include "remote-notif.h"
 #include "regcache.h"
 #include "value.h"
-#include "observer.h"
+#include "observable.h"
 #include "solib.h"
 #include "cli/cli-decode.h"
 #include "cli/cli-setshow.h"
@@ -439,23 +439,23 @@ struct remote_state
   struct readahead_cache readahead_cache;
 };
 
-/* Private data that we'll store in (struct thread_info)->private.  */
-struct private_thread_info
+/* Private data that we'll store in (struct thread_info)->priv.  */
+struct remote_thread_info : public private_thread_info
 {
-  char *extra;
-  char *name;
-  int core;
+  std::string extra;
+  std::string name;
+  int core = -1;
 
   /* Thread handle, perhaps a pthread_t or thread_t value, stored as a
      sequence of bytes.  */
-  gdb::byte_vector *thread_handle;
+  gdb::byte_vector thread_handle;
 
   /* Whether the target stopped for a breakpoint/watchpoint.  */
-  enum target_stop_reason stop_reason;
+  enum target_stop_reason stop_reason = TARGET_STOPPED_BY_NO_REASON;
 
   /* This is set to the data address of the access causing the target
      to stop for a watchpoint.  */
-  CORE_ADDR watch_data_address;
+  CORE_ADDR watch_data_address = 0;
 
   /* Fields used by the vCont action coalescing implemented in
      remote_resume / remote_commit_resume.  remote_resume stores each
@@ -465,26 +465,17 @@ struct private_thread_info
 
   /* True if the last target_resume call for this thread was a step
      request, false if a continue request.  */
-  int last_resume_step;
+  int last_resume_step = 0;
 
   /* The signal specified in the last target_resume call for this
      thread.  */
-  enum gdb_signal last_resume_sig;
+  gdb_signal last_resume_sig = GDB_SIGNAL_0;
 
   /* Whether this thread was already vCont-resumed on the remote
      side.  */
-  int vcont_resumed;
+  int vcont_resumed = 0;
 };
 
-static void
-free_private_thread_info (struct private_thread_info *info)
-{
-  xfree (info->extra);
-  xfree (info->name);
-  delete info->thread_handle;
-  xfree (info);
-}
-
 /* This data could be associated with a target, but we do not always
    have access to the current target when we need it, so for now it is
    static.  This will be fine for as long as only one target is in use
@@ -718,7 +709,7 @@ set_pspace_remote_exec_file (struct program_space *pspace,
 /* The "set/show remote exec-file" set command hook.  */
 
 static void
-set_remote_exec_file (char *ignored, int from_tty,
+set_remote_exec_file (const char *ignored, int from_tty,
                      struct cmd_list_element *c)
 {
   gdb_assert (remote_exec_file_var != NULL);
@@ -979,7 +970,7 @@ static int interrupt_on_connect = 0;
 static int remote_break;
 
 static void
-set_remotebreak (char *args, int from_tty, struct cmd_list_element *c)
+set_remotebreak (const char *args, int from_tty, struct cmd_list_element *c)
 {
   if (remote_break)
     interrupt_sequence_mode = interrupt_sequence_break;
@@ -1007,11 +998,6 @@ show_remotebreak (struct ui_file *file, int from_tty,
 
 static unsigned int remote_address_size;
 
-/* Temporary to track who currently owns the terminal.  See
-   remote_terminal_* for more details.  */
-
-static int remote_async_terminal_ours_p;
-
 \f
 /* User configurable variables for the number of characters in a
    memory read/write packet.  MIN (rsa->remote_packet_size,
@@ -1613,7 +1599,7 @@ enum Z_packet_type
 static enum auto_boolean remote_Z_packet_detect;
 
 static void
-set_remote_protocol_Z_packet_cmd (char *args, int from_tty,
+set_remote_protocol_Z_packet_cmd (const char *args, int from_tty,
                                  struct cmd_list_element *c)
 {
   int i;
@@ -1831,8 +1817,7 @@ remote_add_inferior (int fake_pid_p, int pid, int attached,
   return inf;
 }
 
-static struct private_thread_info *
-  get_private_info_thread (struct thread_info *info);
+static remote_thread_info *get_remote_thread_info (thread_info *thread);
 
 /* Add thread PTID to GDB's thread list.  Tag it as executing/running
    according to RUNNING.  */
@@ -1854,7 +1839,7 @@ remote_add_thread (ptid_t ptid, int running, int executing)
   else
     thread = add_thread (ptid);
 
-  get_private_info_thread (thread)->vcont_resumed = executing;
+  get_remote_thread_info (thread)->vcont_resumed = executing;
   set_executing (ptid, executing);
   set_running (ptid, running);
 }
@@ -1951,39 +1936,25 @@ remote_notice_new_inferior (ptid_t currthread, int executing)
 
 /* Return THREAD's private thread data, creating it if necessary.  */
 
-static struct private_thread_info *
-get_private_info_thread (struct thread_info *thread)
+static remote_thread_info *
+get_remote_thread_info (thread_info *thread)
 {
   gdb_assert (thread != NULL);
 
   if (thread->priv == NULL)
-    {
-      struct private_thread_info *priv = XNEW (struct private_thread_info);
-
-      thread->private_dtor = free_private_thread_info;
-      thread->priv = priv;
+    thread->priv.reset (new remote_thread_info);
 
-      priv->core = -1;
-      priv->extra = NULL;
-      priv->name = NULL;
-      priv->name = NULL;
-      priv->last_resume_step = 0;
-      priv->last_resume_sig = GDB_SIGNAL_0;
-      priv->vcont_resumed = 0;
-      priv->thread_handle = nullptr;
-    }
-
-  return thread->priv;
+  return static_cast<remote_thread_info *> (thread->priv.get ());
 }
 
 /* Return PTID's private thread data, creating it if necessary.  */
 
-static struct private_thread_info *
-get_private_info_ptid (ptid_t ptid)
+static remote_thread_info *
+get_remote_thread_info (ptid_t ptid)
 {
   struct thread_info *info = find_thread_ptid (ptid);
 
-  return get_private_info_thread (info);
+  return get_remote_thread_info (info);
 }
 
 /* Call this function as a result of
@@ -2053,8 +2024,8 @@ remote_pass_signals (struct target_ops *self,
 
 static int
 remote_set_syscall_catchpoint (struct target_ops *self,
-                              int pid, int needed, int any_count,
-                              int table_size, int *table)
+                              int pid, bool needed, int any_count,
+                              gdb::array_view<const int> syscall_counts)
 {
   const char *catch_packet;
   enum packet_result result;
@@ -2066,14 +2037,12 @@ remote_set_syscall_catchpoint (struct target_ops *self,
       return 1;
     }
 
-  if (needed && !any_count)
+  if (needed && any_count == 0)
     {
-      int i;
-
-      /* Count how many syscalls are to be caught (table[sysno] != 0).  */
-      for (i = 0; i < table_size; i++)
+      /* Count how many syscalls are to be caught.  */
+      for (size_t i = 0; i < syscall_counts.size (); i++)
        {
-         if (table[i] != 0)
+         if (syscall_counts[i] != 0)
            n_sysno++;
        }
     }
@@ -2086,40 +2055,32 @@ remote_set_syscall_catchpoint (struct target_ops *self,
                          pid, needed, any_count, n_sysno);
     }
 
-  gdb::unique_xmalloc_ptr<char> built_packet;
+  std::string built_packet;
   if (needed)
     {
       /* Prepare a packet with the sysno list, assuming max 8+1
         characters for a sysno.  If the resulting packet size is too
         big, fallback on the non-selective packet.  */
       const int maxpktsz = strlen ("QCatchSyscalls:1") + n_sysno * 9 + 1;
-
-      built_packet.reset ((char *) xmalloc (maxpktsz));
-      strcpy (built_packet.get (), "QCatchSyscalls:1");
-      if (!any_count)
+      built_packet.reserve (maxpktsz);
+      built_packet = "QCatchSyscalls:1";
+      if (any_count == 0)
        {
-         int i;
-         char *p;
-
-         p = built_packet.get ();
-         p += strlen (p);
-
-         /* Add in catch_packet each syscall to be caught (table[i] != 0).  */
-         for (i = 0; i < table_size; i++)
+         /* Add in each syscall to be caught.  */
+         for (size_t i = 0; i < syscall_counts.size (); i++)
            {
-             if (table[i] != 0)
-               p += xsnprintf (p, built_packet.get () + maxpktsz - p,
-                               ";%x", i);
+             if (syscall_counts[i] != 0)
+               string_appendf (built_packet, ";%zx", i);
            }
        }
-      if (strlen (built_packet.get ()) > get_remote_packet_size ())
+      if (built_packet.size () > get_remote_packet_size ())
        {
          /* catch_packet too big.  Fallback to less efficient
             non selective mode, with GDB doing the filtering.  */
          catch_packet = "QCatchSyscalls:1";
        }
       else
-       catch_packet = built_packet.get ();
+       catch_packet = built_packet.c_str ();
     }
   else
     catch_packet = "QCatchSyscalls:0";
@@ -2307,7 +2268,10 @@ static const char *
 remote_thread_name (struct target_ops *ops, struct thread_info *info)
 {
   if (info->priv != NULL)
-    return info->priv->name;
+    {
+      const std::string &name = get_remote_thread_info (info)->name;
+      return !name.empty () ? name.c_str () : NULL;
+    }
 
   return NULL;
 }
@@ -2985,25 +2949,32 @@ remote_threadlist_iterator (rmt_thread_action stepfunction, void *context,
 
 /* A thread found on the remote target.  */
 
-typedef struct thread_item
+struct thread_item
 {
+  explicit thread_item (ptid_t ptid_)
+  : ptid (ptid_)
+  {}
+
+  thread_item (thread_item &&other) = default;
+  thread_item &operator= (thread_item &&other) = default;
+
+  DISABLE_COPY_AND_ASSIGN (thread_item);
+
   /* The thread's PTID.  */
   ptid_t ptid;
 
-  /* The thread's extra info.  May be NULL.  */
-  char *extra;
+  /* The thread's extra info.  */
+  std::string extra;
 
-  /* The thread's name.  May be NULL.  */
-  char *name;
+  /* The thread's name.  */
+  std::string name;
 
   /* The core the thread was running on.  -1 if not known.  */
-  int core;
+  int core = -1;
 
   /* The thread handle associated with the thread.  */
-  gdb::byte_vector *thread_handle;
-
-} thread_item_t;
-DEF_VEC_O(thread_item_t);
+  gdb::byte_vector thread_handle;
+};
 
 /* Context passed around to the various methods listing remote
    threads.  As new threads are found, they're added to the ITEMS
@@ -3011,66 +2982,54 @@ DEF_VEC_O(thread_item_t);
 
 struct threads_listing_context
 {
-  /* The threads found on the remote target.  */
-  VEC (thread_item_t) *items;
-};
+  /* Return true if this object contains an entry for a thread with ptid
+     PTID.  */
 
-/* Discard the contents of the constructed thread listing context.  */
+  bool contains_thread (ptid_t ptid) const
+  {
+    auto match_ptid = [&] (const thread_item &item)
+      {
+       return item.ptid == ptid;
+      };
 
-static void
-clear_threads_listing_context (void *p)
-{
-  struct threads_listing_context *context
-    = (struct threads_listing_context *) p;
-  int i;
-  struct thread_item *item;
+    auto it = std::find_if (this->items.begin (),
+                           this->items.end (),
+                           match_ptid);
 
-  for (i = 0; VEC_iterate (thread_item_t, context->items, i, item); ++i)
-    {
-      xfree (item->extra);
-      xfree (item->name);
-      delete item->thread_handle;
-    }
+    return it != this->items.end ();
+  }
 
-  VEC_free (thread_item_t, context->items);
-}
+  /* Remove the thread with ptid PTID.  */
 
-/* Remove the thread specified as the related_pid field of WS
-   from the CONTEXT list.  */
+  void remove_thread (ptid_t ptid)
+  {
+    auto match_ptid = [&] (const thread_item &item)
+      {
+        return item.ptid == ptid;
+      };
 
-static void
-threads_listing_context_remove (struct target_waitstatus *ws,
-                               struct threads_listing_context *context)
-{
-  struct thread_item *item;
-  int i;
-  ptid_t child_ptid = ws->value.related_pid;
+    auto it = std::remove_if (this->items.begin (),
+                             this->items.end (),
+                             match_ptid);
 
-  for (i = 0; VEC_iterate (thread_item_t, context->items, i, item); ++i)
-    {
-      if (ptid_equal (item->ptid, child_ptid))
-       {
-         VEC_ordered_remove (thread_item_t, context->items, i);
-         break;
-       }
-    }
-}
+    if (it != this->items.end ())
+      this->items.erase (it);
+  }
+
+  /* The threads found on the remote target.  */
+  std::vector<thread_item> items;
+};
 
 static int
 remote_newthread_step (threadref *ref, void *data)
 {
   struct threads_listing_context *context
     = (struct threads_listing_context *) data;
-  struct thread_item item;
-  int pid = ptid_get_pid (inferior_ptid);
+  int pid = inferior_ptid.pid ();
+  int lwp = threadref_to_int (ref);
+  ptid_t ptid (pid, lwp);
 
-  item.ptid = ptid_build (pid, threadref_to_int (ref), 0);
-  item.core = -1;
-  item.name = NULL;
-  item.extra = NULL;
-  item.thread_handle = nullptr;
-
-  VEC_safe_push (thread_item_t, context->items, &item);
+  context->items.emplace_back (ptid);
 
   return 1;                    /* continue iterator */
 }
@@ -3118,41 +3077,30 @@ remote_get_threads_with_ql (struct target_ops *ops,
 static void
 start_thread (struct gdb_xml_parser *parser,
              const struct gdb_xml_element *element,
-             void *user_data, VEC(gdb_xml_value_s) *attributes)
+             void *user_data,
+             std::vector<gdb_xml_value> &attributes)
 {
   struct threads_listing_context *data
     = (struct threads_listing_context *) user_data;
-
-  struct thread_item item;
-  char *id;
   struct gdb_xml_value *attr;
 
-  id = (char *) xml_find_attribute (attributes, "id")->value;
-  item.ptid = read_ptid (id, NULL);
+  char *id = (char *) xml_find_attribute (attributes, "id")->value.get ();
+  ptid_t ptid = read_ptid (id, NULL);
+
+  data->items.emplace_back (ptid);
+  thread_item &item = data->items.back ();
 
   attr = xml_find_attribute (attributes, "core");
   if (attr != NULL)
-    item.core = *(ULONGEST *) attr->value;
-  else
-    item.core = -1;
+    item.core = *(ULONGEST *) attr->value.get ();
 
   attr = xml_find_attribute (attributes, "name");
-  item.name = attr != NULL ? xstrdup ((const char *) attr->value) : NULL;
+  if (attr != NULL)
+    item.name = (const char *) attr->value.get ();
 
   attr = xml_find_attribute (attributes, "handle");
   if (attr != NULL)
-    {
-      item.thread_handle = new gdb::byte_vector
-                             (strlen ((const char *) attr->value) / 2);
-      hex2bin ((const char *) attr->value, item.thread_handle->data (),
-               item.thread_handle->size ());
-    }
-  else
-    item.thread_handle = nullptr;
-
-  item.extra = 0;
-
-  VEC_safe_push (thread_item_t, data->items, &item);
+    item.thread_handle = hex2bin ((const char *) attr->value.get ());
 }
 
 static void
@@ -3163,8 +3111,8 @@ end_thread (struct gdb_xml_parser *parser,
   struct threads_listing_context *data
     = (struct threads_listing_context *) user_data;
 
-  if (body_text && *body_text)
-    VEC_last (thread_item_t, data->items)->extra = xstrdup (body_text);
+  if (body_text != NULL && *body_text != '\0')
+    data->items.back ().extra = body_text;
 }
 
 const struct gdb_xml_attribute thread_attributes[] = {
@@ -3203,13 +3151,13 @@ remote_get_threads_with_qxfer (struct target_ops *ops,
 #if defined(HAVE_LIBEXPAT)
   if (packet_support (PACKET_qXfer_threads) == PACKET_ENABLE)
     {
-      gdb::unique_xmalloc_ptr<char> xml
+      gdb::optional<gdb::char_vector> xml
        = target_read_stralloc (ops, TARGET_OBJECT_THREADS, NULL);
 
-      if (xml != NULL && *xml != '\0')
+      if (xml && (*xml)[0] != '\0')
        {
          gdb_xml_parse_quick (_("threads"), "threads.dtd",
-                              threads_elements, xml.get (), context);
+                              threads_elements, xml->data (), context);
        }
 
       return 1;
@@ -3240,15 +3188,8 @@ remote_get_threads_with_qthreadinfo (struct target_ops *ops,
            {
              do
                {
-                 struct thread_item item;
-
-                 item.ptid = read_ptid (bufp, &bufp);
-                 item.core = -1;
-                 item.name = NULL;
-                 item.extra = NULL;
-                 item.thread_handle = nullptr;
-
-                 VEC_safe_push (thread_item_t, context->items, &item);
+                 ptid_t ptid = read_ptid (bufp, &bufp);
+                 context->items.emplace_back (ptid);
                }
              while (*bufp++ == ',');   /* comma-separated list */
              putpkt ("qsThreadInfo");
@@ -3274,12 +3215,8 @@ static void
 remote_update_thread_list (struct target_ops *ops)
 {
   struct threads_listing_context context;
-  struct cleanup *old_chain;
   int got_list = 0;
 
-  context.items = NULL;
-  old_chain = make_cleanup (clear_threads_listing_context, &context);
-
   /* We have a few different mechanisms to fetch the thread list.  Try
      them all, starting with the most preferred one first, falling
      back to older methods.  */
@@ -3287,13 +3224,11 @@ remote_update_thread_list (struct target_ops *ops)
       || remote_get_threads_with_qthreadinfo (ops, &context)
       || remote_get_threads_with_ql (ops, &context))
     {
-      int i;
-      struct thread_item *item;
       struct thread_info *tp, *tmp;
 
       got_list = 1;
 
-      if (VEC_empty (thread_item_t, context.items)
+      if (context.items.empty ()
          && remote_thread_always_alive (ops, inferior_ptid))
        {
          /* Some targets don't really support threads, but still
@@ -3301,7 +3236,6 @@ remote_update_thread_list (struct target_ops *ops)
             listing packets, instead of replying "packet not
             supported".  Exit early so we don't delete the main
             thread.  */
-         do_cleanups (old_chain);
          return;
        }
 
@@ -3310,15 +3244,7 @@ remote_update_thread_list (struct target_ops *ops)
         target.  */
       ALL_THREADS_SAFE (tp, tmp)
        {
-         for (i = 0;
-              VEC_iterate (thread_item_t, context.items, i, item);
-              ++i)
-           {
-             if (ptid_equal (item->ptid, tp->ptid))
-               break;
-           }
-
-         if (i == VEC_length (thread_item_t, context.items))
+         if (!context.contains_thread (tp->ptid))
            {
              /* Not found.  */
              delete_thread (tp->ptid);
@@ -3331,29 +3257,23 @@ remote_update_thread_list (struct target_ops *ops)
       remove_new_fork_children (&context);
 
       /* And now add threads we don't know about yet to our list.  */
-      for (i = 0;
-          VEC_iterate (thread_item_t, context.items, i, item);
-          ++i)
+      for (thread_item &item : context.items)
        {
-         if (!ptid_equal (item->ptid, null_ptid))
+         if (item.ptid != null_ptid)
            {
-             struct private_thread_info *info;
              /* In non-stop mode, we assume new found threads are
                 executing until proven otherwise with a stop reply.
                 In all-stop, we can only get here if all threads are
                 stopped.  */
              int executing = target_is_non_stop_p () ? 1 : 0;
 
-             remote_notice_new_inferior (item->ptid, executing);
+             remote_notice_new_inferior (item.ptid, executing);
 
-             info = get_private_info_ptid (item->ptid);
-             info->core = item->core;
-             info->extra = item->extra;
-             item->extra = NULL;
-             info->name = item->name;
-             item->name = NULL;
-             info->thread_handle = item->thread_handle;
-             item->thread_handle = nullptr;
+             remote_thread_info *info = get_remote_thread_info (item.ptid);
+             info->core = item.core;
+             info->extra = std::move (item.extra);
+             info->name = std::move (item.name);
+             info->thread_handle = std::move (item.thread_handle);
            }
        }
     }
@@ -3366,8 +3286,6 @@ remote_update_thread_list (struct target_ops *ops)
         no-op.  See remote_thread_alive.  */
       prune_threads ();
     }
-
-  do_cleanups (old_chain);
 }
 
 /*
@@ -3404,8 +3322,11 @@ remote_threads_extra_info (struct target_ops *self, struct thread_info *tp)
     {
       struct thread_info *info = find_thread_ptid (tp->ptid);
 
-      if (info && info->priv)
-       return info->priv->extra;
+      if (info != NULL && info->priv != NULL)
+       {
+         const std::string &extra = get_remote_thread_info (info)->extra;
+         return !extra.empty () ? extra.c_str () : NULL;
+       }
       else
        return NULL;
     }
@@ -3460,7 +3381,7 @@ remote_threads_extra_info (struct target_ops *self, struct thread_info *tp)
 }
 \f
 
-static int
+static bool
 remote_static_tracepoint_marker_at (struct target_ops *self, CORE_ADDR addr,
                                    struct static_tracepoint_marker *marker)
 {
@@ -3480,21 +3401,20 @@ remote_static_tracepoint_marker_at (struct target_ops *self, CORE_ADDR addr,
   if (*p++ == 'm')
     {
       parse_static_tracepoint_marker_definition (p, NULL, marker);
-      return 1;
+      return true;
     }
 
-  return 0;
+  return false;
 }
 
-static VEC(static_tracepoint_marker_p) *
+static std::vector<static_tracepoint_marker>
 remote_static_tracepoint_markers_by_strid (struct target_ops *self,
                                           const char *strid)
 {
   struct remote_state *rs = get_remote_state ();
-  VEC(static_tracepoint_marker_p) *markers = NULL;
-  struct static_tracepoint_marker *marker = NULL;
-  struct cleanup *old_chain;
+  std::vector<static_tracepoint_marker> markers;
   const char *p;
+  static_tracepoint_marker marker;
 
   /* Ask for a first packet of static tracepoint marker
      definition.  */
@@ -3504,28 +3424,14 @@ remote_static_tracepoint_markers_by_strid (struct target_ops *self,
   if (*p == 'E')
     error (_("Remote failure reply: %s"), p);
 
-  old_chain = make_cleanup (free_current_marker, &marker);
-
   while (*p++ == 'm')
     {
-      if (marker == NULL)
-       marker = XCNEW (struct static_tracepoint_marker);
-
       do
        {
-         parse_static_tracepoint_marker_definition (p, &p, marker);
+         parse_static_tracepoint_marker_definition (p, &p, &marker);
 
-         if (strid == NULL || strcmp (strid, marker->str_id) == 0)
-           {
-             VEC_safe_push (static_tracepoint_marker_p,
-                            markers, marker);
-             marker = NULL;
-           }
-         else
-           {
-             release_static_tracepoint_marker (marker);
-             memset (marker, 0, sizeof (*marker));
-           }
+         if (strid == NULL || marker.str_id == strid)
+           markers.push_back (std::move (marker));
        }
       while (*p++ == ',');     /* comma-separated list */
       /* Ask for another packet of static tracepoint definition.  */
@@ -3534,7 +3440,6 @@ remote_static_tracepoint_markers_by_strid (struct target_ops *self,
       p = rs->buf;
     }
 
-  do_cleanups (old_chain);
   return markers;
 }
 
@@ -3903,9 +3808,9 @@ print_one_stopped_thread (struct thread_info *thread)
       enum gdb_signal sig = ws->value.sig;
 
       if (signal_print_state (sig))
-       observer_notify_signal_received (sig);
+       gdb::observers::signal_received.notify (sig);
     }
-  observer_notify_normal_stop (NULL, 1);
+  gdb::observers::normal_stop.notify (NULL, 1);
 }
 
 /* Process all initial stop replies the remote side sent in response
@@ -3981,7 +3886,7 @@ process_initial_stop_replies (int from_tty)
 
       set_executing (event_ptid, 0);
       set_running (event_ptid, 0);
-      thread->priv->vcont_resumed = 0;
+      get_remote_thread_info (thread)->vcont_resumed = 0;
     }
 
   /* "Notice" the new inferiors before anything related to
@@ -4435,7 +4340,6 @@ init_all_packet_configs (void)
 static void
 remote_check_symbols (void)
 {
-  struct remote_state *rs = get_remote_state ();
   char *msg, *reply, *tmp;
   int end;
   long reply_size;
@@ -4830,7 +4734,8 @@ remote_query_supported (void)
 
       /* Keep this one last to work around a gdbserver <= 7.10 bug in
         the qSupported:xmlRegisters=i386 handling.  */
-      if (remote_support_xml != NULL)
+      if (remote_support_xml != NULL
+         && packet_support (PACKET_qXfer_features) != PACKET_DISABLE)
        q = remote_query_supported_append (q, remote_support_xml);
 
       q = reconcat (q, "qSupported:", q, (char *) NULL);
@@ -4992,7 +4897,7 @@ remote_serial_quit_handler (void)
       /* All-stop protocol, and blocked waiting for stop reply.  Send
         an interrupt request.  */
       else if (!target_terminal::is_ours () && rs->waiting_for_stop_reply)
-       target_interrupt (inferior_ptid);
+       target_interrupt ();
       else
        rs->got_ctrlc_during_io = 1;
     }
@@ -5117,9 +5022,6 @@ remote_open_1 (const char *name, int from_tty,
 
   readahead_cache_invalidate ();
 
-  /* Start out by owning the terminal.  */
-  remote_async_terminal_ours_p = 1;
-
   if (target_async_permitted)
     {
       /* FIXME: cagney/1999-09-23: During the initial connection it is
@@ -5208,16 +5110,13 @@ remote_detach_pid (int pid)
    one.  */
 
 static void
-remote_detach_1 (const char *args, int from_tty)
+remote_detach_1 (int from_tty, inferior *inf)
 {
   int pid = ptid_get_pid (inferior_ptid);
   struct remote_state *rs = get_remote_state ();
   struct thread_info *tp = find_thread_ptid (inferior_ptid);
   int is_fork_parent;
 
-  if (args)
-    error (_("Argument given to \"detach\" when remotely debugging."));
-
   if (!target_has_execution)
     error (_("No process to detach from."));
 
@@ -5247,15 +5146,15 @@ remote_detach_1 (const char *args, int from_tty)
 }
 
 static void
-remote_detach (struct target_ops *ops, const char *args, int from_tty)
+remote_detach (struct target_ops *ops, inferior *inf, int from_tty)
 {
-  remote_detach_1 (args, from_tty);
+  remote_detach_1 (from_tty, inf);
 }
 
 static void
-extended_remote_detach (struct target_ops *ops, const char *args, int from_tty)
+extended_remote_detach (struct target_ops *ops, inferior *inf, int from_tty)
 {
-  remote_detach_1 (args, from_tty);
+  remote_detach_1 (from_tty, inf);
 }
 
 /* Target follow-fork function for remote targets.  On entry, and
@@ -5291,7 +5190,6 @@ remote_follow_fork (struct target_ops *ops, int follow_child,
          child_pid = ptid_get_pid (child_ptid);
 
          remote_detach_pid (child_pid);
-         detach_inferior (child_pid);
        }
     }
   return 0;
@@ -5418,7 +5316,10 @@ extended_remote_attach (struct target_ops *target, const char *args,
       inferior_ptid = remote_current_thread (inferior_ptid);
 
       /* Add the main thread to the thread list.  */
-      add_thread_silent (inferior_ptid);
+      thread_info *thr = add_thread_silent (inferior_ptid);
+      /* Don't consider the thread stopped until we've processed the
+        saved stop reply.  */
+      set_executing (thr->ptid, true);
     }
 
   /* Next, if the target can specify a description, read it.  We do
@@ -5608,8 +5509,10 @@ resume_clear_thread_private_info (struct thread_info *thread)
 {
   if (thread->priv != NULL)
     {
-      thread->priv->stop_reason = TARGET_STOPPED_BY_NO_REASON;
-      thread->priv->watch_data_address = 0;
+      remote_thread_info *priv = get_remote_thread_info (thread);
+
+      priv->stop_reason = TARGET_STOPPED_BY_NO_REASON;
+      priv->watch_data_address = 0;
     }
 }
 
@@ -5789,12 +5692,13 @@ remote_resume (struct target_ops *ops,
      to do vCont action coalescing.  */
   if (target_is_non_stop_p () && execution_direction != EXEC_REVERSE)
     {
-      struct private_thread_info *remote_thr;
+      remote_thread_info *remote_thr;
 
       if (ptid_equal (minus_one_ptid, ptid) || ptid_is_pid (ptid))
-       remote_thr = get_private_info_ptid (inferior_ptid);
+       remote_thr = get_remote_thread_info (inferior_ptid);
       else
-       remote_thr = get_private_info_ptid (ptid);
+       remote_thr = get_remote_thread_info (ptid);
+
       remote_thr->last_resume_step = step;
       remote_thr->last_resume_sig = siggnal;
       return;
@@ -5842,12 +5746,23 @@ static int is_pending_fork_parent_thread (struct thread_info *thread);
 
 /* Private per-inferior info for target remote processes.  */
 
-struct private_inferior
+struct remote_inferior : public private_inferior
 {
   /* Whether we can send a wildcard vCont for this process.  */
-  int may_wildcard_vcont;
+  bool may_wildcard_vcont = true;
 };
 
+/* Get the remote private inferior data associated to INF.  */
+
+static remote_inferior *
+get_remote_inferior (inferior *inf)
+{
+  if (inf->priv == NULL)
+    inf->priv.reset (new remote_inferior);
+
+  return static_cast<remote_inferior *> (inf->priv.get ());
+}
+
 /* Structure used to track the construction of a vCont packet in the
    outgoing packet buffer.  This is used to send multiple vCont
    packets if we have more actions than would fit a single packet.  */
@@ -5941,7 +5856,6 @@ vcont_builder_push_action (struct vcont_builder *builder,
 static void
 remote_commit_resume (struct target_ops *ops)
 {
-  struct remote_state *rs = get_remote_state ();
   struct inferior *inf;
   struct thread_info *tp;
   int any_process_wildcard;
@@ -6009,9 +5923,9 @@ remote_commit_resume (struct target_ops *ops)
   /* And assume every process is individually wildcard-able too.  */
   ALL_NON_EXITED_INFERIORS (inf)
     {
-      if (inf->priv == NULL)
-       inf->priv = XNEW (struct private_inferior);
-      inf->priv->may_wildcard_vcont = 1;
+      remote_inferior *priv = get_remote_inferior (inf);
+
+      priv->may_wildcard_vcont = true;
     }
 
   /* Check for any pending events (not reported or processed yet) and
@@ -6024,7 +5938,7 @@ remote_commit_resume (struct target_ops *ops)
         can't wildcard that process.  */
       if (!tp->executing)
        {
-         tp->inf->priv->may_wildcard_vcont = 0;
+         get_remote_inferior (tp->inf)->may_wildcard_vcont = false;
 
          /* And if we can't wildcard a process, we can't wildcard
             everything either.  */
@@ -6049,7 +5963,7 @@ remote_commit_resume (struct target_ops *ops)
   /* Threads first.  */
   ALL_NON_EXITED_THREADS (tp)
     {
-      struct private_thread_info *remote_thr = tp->priv;
+      remote_thread_info *remote_thr = get_remote_thread_info (tp);
 
       if (!tp->executing || remote_thr->vcont_resumed)
        continue;
@@ -6058,7 +5972,7 @@ remote_commit_resume (struct target_ops *ops)
 
       if (!remote_thr->last_resume_step
          && remote_thr->last_resume_sig == GDB_SIGNAL_0
-         && tp->inf->priv->may_wildcard_vcont)
+         && get_remote_inferior (tp->inf)->may_wildcard_vcont)
        {
          /* We'll send a wildcard resume instead.  */
          remote_thr->vcont_resumed = 1;
@@ -6078,7 +5992,7 @@ remote_commit_resume (struct target_ops *ops)
 
   ALL_NON_EXITED_INFERIORS (inf)
     {
-      if (inf->priv->may_wildcard_vcont)
+      if (get_remote_inferior (inf)->may_wildcard_vcont)
        {
          any_process_wildcard = 1;
          break;
@@ -6099,7 +6013,7 @@ remote_commit_resume (struct target_ops *ops)
        {
          ALL_NON_EXITED_INFERIORS (inf)
            {
-             if (inf->priv->may_wildcard_vcont)
+             if (get_remote_inferior (inf)->may_wildcard_vcont)
                {
                  vcont_builder_push_action (&vcont_builder,
                                             pid_to_ptid (inf->pid),
@@ -6237,10 +6151,8 @@ remote_stop (struct target_ops *self, ptid_t ptid)
 /* Implement the to_interrupt function for the remote targets.  */
 
 static void
-remote_interrupt (struct target_ops *self, ptid_t ptid)
+remote_interrupt (struct target_ops *self)
 {
-  struct remote_state *rs = get_remote_state ();
-
   if (remote_debug)
     fprintf_unfiltered (gdb_stdlog, "remote_interrupt called\n");
 
@@ -6268,7 +6180,7 @@ remote_pass_ctrlc (struct target_ops *self)
   else if (rs->ctrlc_pending_p)
     interrupt_query ();
   else
-    target_interrupt (inferior_ptid);
+    target_interrupt ();
 }
 
 /* Ask the user what to do when an interrupt is received.  */
@@ -6303,15 +6215,6 @@ interrupt_query (void)
 static void
 remote_terminal_inferior (struct target_ops *self)
 {
-  /* FIXME: cagney/1999-09-27: Make calls to target_terminal::*()
-     idempotent.  The event-loop GDB talking to an asynchronous target
-     with a synchronous command calls this function from both
-     event-top.c and infrun.c/infcmd.c.  Once GDB stops trying to
-     transfer the terminal to the target when it shouldn't this guard
-     can go away.  */
-  if (!remote_async_terminal_ours_p)
-    return;
-  remote_async_terminal_ours_p = 0;
   /* NOTE: At this point we could also register our selves as the
      recipient of all input.  Any characters typed could then be
      passed on down to the target.  */
@@ -6320,10 +6223,6 @@ remote_terminal_inferior (struct target_ops *self)
 static void
 remote_terminal_ours (struct target_ops *self)
 {
-  /* See FIXME in remote_terminal_inferior.  */
-  if (remote_async_terminal_ours_p)
-    return;
-  remote_async_terminal_ours_p = 1;
 }
 
 static void
@@ -6539,7 +6438,7 @@ remove_child_of_pending_fork (QUEUE (stop_reply_p) *q,
   if (event->ws.kind == TARGET_WAITKIND_FORKED
       || event->ws.kind == TARGET_WAITKIND_VFORKED
       || event->ws.kind == TARGET_WAITKIND_THREAD_EXITED)
-    threads_listing_context_remove (&event->ws, context);
+    context->remove_thread (event->ws.value.related_pid);
 
   return 1;
 }
@@ -6565,9 +6464,7 @@ remove_new_fork_children (struct threads_listing_context *context)
       struct target_waitstatus *ws = thread_pending_fork_status (thread);
 
       if (is_pending_fork_parent (ws, pid, thread->ptid))
-       {
-         threads_listing_context_remove (ws, context);
-       }
+       context->remove_thread (ws->value.related_pid);
     }
 
   /* Check for any pending fork events (not reported or processed yet)
@@ -6608,7 +6505,7 @@ check_pending_event_prevents_wildcard_vcont_callback
      we'd resume this process too.  */
   *may_global_wildcard_vcont = 0;
   if (inf != NULL)
-    inf->priv->may_wildcard_vcont = 0;
+    get_remote_inferior (inf)->may_wildcard_vcont = false;
 
   return 1;
 }
@@ -7026,7 +6923,13 @@ Packet: '%s'\n"),
                        event->ptid = read_ptid (thr + strlen (";thread:"),
                                                 NULL);
                      else
-                       event->ptid = magic_null_ptid;
+                       {
+                         /* Either the current thread hasn't changed,
+                            or the inferior is not multi-threaded.
+                            The event must be for the thread we last
+                            set as (or learned as being) current.  */
+                         event->ptid = event->rs->general_thread;
+                       }
                    }
 
                  if (rsa == NULL)
@@ -7281,8 +7184,6 @@ process_stop_reply (struct stop_reply *stop_reply,
       && status->kind != TARGET_WAITKIND_SIGNALLED
       && status->kind != TARGET_WAITKIND_NO_RESUMED)
     {
-      struct private_thread_info *remote_thr;
-
       /* Expedited registers.  */
       if (stop_reply->regcache)
        {
@@ -7303,7 +7204,7 @@ process_stop_reply (struct stop_reply *stop_reply,
        }
 
       remote_notice_new_inferior (ptid, 0);
-      remote_thr = get_private_info_ptid (ptid);
+      remote_thread_info *remote_thr = get_remote_thread_info (ptid);
       remote_thr->core = stop_reply->core;
       remote_thr->stop_reason = stop_reply->stop_reason;
       remote_thr->watch_data_address = stop_reply->watch_data_address;
@@ -7549,7 +7450,7 @@ remote_wait (struct target_ops *ops,
 static int
 fetch_register_using_p (struct regcache *regcache, struct packet_reg *reg)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   struct remote_state *rs = get_remote_state ();
   char *buf, *p;
   gdb_byte *regp = (gdb_byte *) alloca (register_size (gdbarch, reg->regnum));
@@ -7578,7 +7479,7 @@ fetch_register_using_p (struct regcache *regcache, struct packet_reg *reg)
       return 0;
     case PACKET_ERROR:
       error (_("Could not fetch register \"%s\"; remote failure reply '%s'"),
-            gdbarch_register_name (get_regcache_arch (regcache), 
+            gdbarch_register_name (regcache->arch (), 
                                    reg->regnum), 
             buf);
     }
@@ -7642,7 +7543,7 @@ send_g_packet (void)
 static void
 process_g_packet (struct regcache *regcache)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   struct remote_state *rs = get_remote_state ();
   remote_arch_state *rsa = get_remote_arch_state (gdbarch);
   int i, buf_len;
@@ -7778,7 +7679,7 @@ static void
 remote_fetch_registers (struct target_ops *ops,
                        struct regcache *regcache, int regnum)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   remote_arch_state *rsa = get_remote_arch_state (gdbarch);
   int i;
 
@@ -7838,7 +7739,7 @@ remote_prepare_to_store (struct target_ops *self, struct regcache *regcache)
     case PACKET_DISABLE:
     case PACKET_SUPPORT_UNKNOWN:
       /* Make sure all the necessary registers are cached.  */
-      for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++)
+      for (i = 0; i < gdbarch_num_regs (regcache->arch ()); i++)
        if (rsa->regs[i].in_g_packet)
          regcache_raw_update (regcache, rsa->regs[i].regnum);
       break;
@@ -7854,7 +7755,7 @@ static int
 store_register_using_P (const struct regcache *regcache, 
                        struct packet_reg *reg)
 {
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  struct gdbarch *gdbarch = regcache->arch ();
   struct remote_state *rs = get_remote_state ();
   /* Try storing a single register.  */
   char *buf = rs->buf;
@@ -7906,7 +7807,7 @@ store_registers_using_G (const struct regcache *regcache)
 
     regs = (gdb_byte *) alloca (rsa->sizeof_g_packet);
     memset (regs, 0, rsa->sizeof_g_packet);
-    for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++)
+    for (i = 0; i < gdbarch_num_regs (regcache->arch ()); i++)
       {
        struct packet_reg *r = &rsa->regs[i];
 
@@ -8293,7 +8194,7 @@ remote_write_bytes_aux (const char *header, CORE_ADDR memaddr,
   /* Return UNITS_WRITTEN, not TODO_UNITS, in case escape chars caused us to
      send fewer units than we'd planned.  */
   *xfered_len_units = (ULONGEST) units_written;
-  return TARGET_XFER_OK;
+  return (*xfered_len_units != 0) ? TARGET_XFER_OK : TARGET_XFER_EOF;
 }
 
 /* Write memory data directly to the remote machine.
@@ -8387,7 +8288,7 @@ remote_read_bytes_1 (CORE_ADDR memaddr, gdb_byte *myaddr, ULONGEST len_units,
   decoded_bytes = hex2bin (p, myaddr, todo_units * unit_size);
   /* Return what we have.  Let higher layers handle partial reads.  */
   *xfered_len_units = (ULONGEST) (decoded_bytes / unit_size);
-  return TARGET_XFER_OK;
+  return (*xfered_len_units != 0) ? TARGET_XFER_OK : TARGET_XFER_EOF;
 }
 
 /* Using the set of read-only target sections of remote, read live
@@ -8490,7 +8391,8 @@ remote_read_bytes (struct target_ops *ops, CORE_ADDR memaddr,
                  /* No use trying further, we know some memory starting
                     at MEMADDR isn't available.  */
                  *xfered_len = len;
-                 return TARGET_XFER_UNAVAILABLE;
+                 return (*xfered_len != 0) ?
+                   TARGET_XFER_UNAVAILABLE : TARGET_XFER_EOF;
                }
            }
 
@@ -8805,11 +8707,9 @@ putpkt_binary (const char *buf, int cnt)
 
          fprintf_unfiltered (gdb_stdlog, "Sending packet: %s", str.c_str ());
 
-         if (str.length () > REMOTE_DEBUG_MAX_CHAR)
-           {
-             fprintf_unfiltered (gdb_stdlog, "[%zu bytes omitted]",
-                                 str.length () - REMOTE_DEBUG_MAX_CHAR);
-           }
+         if (len > REMOTE_DEBUG_MAX_CHAR)
+           fprintf_unfiltered (gdb_stdlog, "[%d bytes omitted]",
+                               len - REMOTE_DEBUG_MAX_CHAR);
 
          fprintf_unfiltered (gdb_stdlog, "...");
 
@@ -9242,11 +9142,9 @@ getpkt_or_notif_sane_1 (char **buf, long *sizeof_buf, int forever,
              fprintf_unfiltered (gdb_stdlog, "Packet received: %s",
                                  str.c_str ());
 
-             if (str.length () >  REMOTE_DEBUG_MAX_CHAR)
-               {
-                 fprintf_unfiltered (gdb_stdlog, "[%zu bytes omitted]",
-                                     str.length () - REMOTE_DEBUG_MAX_CHAR);
-               }
+             if (val > REMOTE_DEBUG_MAX_CHAR)
+               fprintf_unfiltered (gdb_stdlog, "[%d bytes omitted]",
+                                   val - REMOTE_DEBUG_MAX_CHAR);
 
              fprintf_unfiltered (gdb_stdlog, "\n");
            }
@@ -9856,7 +9754,6 @@ remote_insert_breakpoint (struct target_ops *ops,
       CORE_ADDR addr = bp_tgt->reqstd_address;
       struct remote_state *rs;
       char *p, *endbuf;
-      int bpsize;
 
       /* Make sure the remote is pointing at the right process, if
         necessary.  */
@@ -10099,7 +9996,8 @@ remote_stopped_by_sw_breakpoint (struct target_ops *ops)
   struct thread_info *thread = inferior_thread ();
 
   return (thread->priv != NULL
-         && thread->priv->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT);
+         && (get_remote_thread_info (thread)->stop_reason
+             == TARGET_STOPPED_BY_SW_BREAKPOINT));
 }
 
 /* The to_supports_stopped_by_sw_breakpoint method of target
@@ -10119,7 +10017,8 @@ remote_stopped_by_hw_breakpoint (struct target_ops *ops)
   struct thread_info *thread = inferior_thread ();
 
   return (thread->priv != NULL
-         && thread->priv->stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT);
+         && (get_remote_thread_info (thread)->stop_reason
+             == TARGET_STOPPED_BY_HW_BREAKPOINT));
 }
 
 /* The to_supports_stopped_by_hw_breakpoint method of target
@@ -10137,7 +10036,8 @@ remote_stopped_by_watchpoint (struct target_ops *ops)
   struct thread_info *thread = inferior_thread ();
 
   return (thread->priv != NULL
-         && thread->priv->stop_reason == TARGET_STOPPED_BY_WATCHPOINT);
+         && (get_remote_thread_info (thread)->stop_reason
+             == TARGET_STOPPED_BY_WATCHPOINT));
 }
 
 static int
@@ -10146,9 +10046,10 @@ remote_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p)
   struct thread_info *thread = inferior_thread ();
 
   if (thread->priv != NULL
-      && thread->priv->stop_reason == TARGET_STOPPED_BY_WATCHPOINT)
+      && (get_remote_thread_info (thread)->stop_reason
+         == TARGET_STOPPED_BY_WATCHPOINT))
     {
-      *addr_p = thread->priv->watch_data_address;
+      *addr_p = get_remote_thread_info (thread)->watch_data_address;
       return 1;
     }
 
@@ -10310,7 +10211,6 @@ static void
 compare_sections_command (const char *args, int from_tty)
 {
   asection *s;
-  gdb_byte *sectdata;
   const char *sectname;
   bfd_size_type size;
   bfd_vma lma;
@@ -10393,7 +10293,7 @@ remote_write_qxfer (struct target_ops *ops, const char *object_name,
   struct remote_state *rs = get_remote_state ();
   int max_size = get_memory_write_packet_size (); 
 
-  if (packet->support == PACKET_DISABLE)
+  if (packet_config_support (packet) == PACKET_DISABLE)
     return TARGET_XFER_E_IO;
 
   /* Insert header.  */
@@ -10415,7 +10315,7 @@ remote_write_qxfer (struct target_ops *ops, const char *object_name,
   unpack_varlen_hex (rs->buf, &n);
 
   *xfered_len = n;
-  return TARGET_XFER_OK;
+  return (*xfered_len != 0) ? TARGET_XFER_OK : TARGET_XFER_EOF;
 }
 
 /* Read OBJECT_NAME/ANNEX from the remote target using a qXfer packet.
@@ -10435,7 +10335,7 @@ remote_read_qxfer (struct target_ops *ops, const char *object_name,
   struct remote_state *rs = get_remote_state ();
   LONGEST i, n, packet_len;
 
-  if (packet->support == PACKET_DISABLE)
+  if (packet_config_support (packet) == PACKET_DISABLE)
     return TARGET_XFER_E_IO;
 
   /* Check whether we've cached an end-of-object packet that matches
@@ -10716,7 +10616,7 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
   strcpy ((char *) readbuf, rs->buf);
 
   *xfered_len = strlen ((char *) readbuf);
-  return TARGET_XFER_OK;
+  return (*xfered_len != 0) ? TARGET_XFER_OK : TARGET_XFER_EOF;
 }
 
 /* Implementation of to_get_memory_xfer_limit.  */
@@ -10747,9 +10647,10 @@ remote_search_memory (struct target_ops* ops,
   int found;
   ULONGEST found_addr;
 
-  /* Don't go to the target if we don't have to.
-     This is done before checking packet->support to avoid the possibility that
-     a success for this edge case means the facility works in general.  */
+  /* Don't go to the target if we don't have to.  This is done before
+     checking packet_config_support to avoid the possibility that a
+     success for this edge case means the facility works in
+     general.  */
   if (pattern_len > search_space_len)
     return 0;
   if (pattern_len == 0)
@@ -10794,7 +10695,7 @@ remote_search_memory (struct target_ops* ops,
     {
       /* The request may not have worked because the command is not
         supported.  If so, fall back to the simple way.  */
-      if (packet->support == PACKET_DISABLE)
+      if (packet_config_support (packet) == PACKET_DISABLE)
        {
          return simple_search_memory (ops, start_addr, search_space_len,
                                       pattern, pattern_len, found_addrp);
@@ -10892,11 +10793,11 @@ static std::vector<mem_region>
 remote_memory_map (struct target_ops *ops)
 {
   std::vector<mem_region> result;
-  gdb::unique_xmalloc_ptr<char> text
+  gdb::optional<gdb::char_vector> text
     = target_read_stralloc (&current_target, TARGET_OBJECT_MEMORY_MAP, NULL);
 
   if (text)
-    result = parse_memory_map (text.get ());
+    result = parse_memory_map (text->data ());
 
   return result;
 }
@@ -10947,7 +10848,7 @@ static void init_remote_threadtests (void);
 #define SAMPLE_THREAD  0x05060708      /* Truncated 64 bit threadid.  */
 
 static void
-threadset_test_cmd (char *cmd, int tty)
+threadset_test_cmd (const char *cmd, int tty)
 {
   int sample_thread = SAMPLE_THREAD;
 
@@ -10957,7 +10858,7 @@ threadset_test_cmd (char *cmd, int tty)
 
 
 static void
-threadalive_test (char *cmd, int tty)
+threadalive_test (const char *cmd, int tty)
 {
   int sample_thread = SAMPLE_THREAD;
   int pid = ptid_get_pid (inferior_ptid);
@@ -10982,7 +10883,7 @@ output_threadid (char *title, threadref *ref)
 }
 
 static void
-threadlist_test_cmd (char *cmd, int tty)
+threadlist_test_cmd (const char *cmd, int tty)
 {
   int startflag = 1;
   threadref nextthread;
@@ -11027,7 +10928,7 @@ get_and_display_threadinfo (threadref *ref)
 }
 
 static void
-threadinfo_test_cmd (char *cmd, int tty)
+threadinfo_test_cmd (const char *cmd, int tty)
 {
   int athread = SAMPLE_THREAD;
   threadref thread;
@@ -11047,7 +10948,7 @@ thread_display_step (threadref *ref, void *context)
 }
 
 static void
-threadlist_update_test_cmd (char *cmd, int tty)
+threadlist_update_test_cmd (const char *cmd, int tty)
 {
   printf_filtered ("Remote Threadlist update test\n");
   remote_threadlist_iterator (thread_display_step, 0, CRAZY_MAX_THREADS);
@@ -11452,8 +11353,7 @@ remote_hostio_send_command (int command_bytes, int which_packet,
   int ret, bytes_read;
   char *attachment_tmp;
 
-  if (!rs->remote_desc
-      || packet_support (which_packet) == PACKET_DISABLE)
+  if (packet_support (which_packet) == PACKET_DISABLE)
     {
       *remote_errno = FILEIO_ENOSYS;
       return -1;
@@ -11795,7 +11695,7 @@ remote_hostio_unlink (struct target_ops *self,
 
 /* Implementation of to_fileio_readlink.  */
 
-static char *
+static gdb::optional<std::string>
 remote_hostio_readlink (struct target_ops *self,
                        struct inferior *inf, const char *filename,
                        int *remote_errno)
@@ -11806,10 +11706,9 @@ remote_hostio_readlink (struct target_ops *self,
   int left = get_remote_packet_size ();
   int len, attachment_len;
   int read_len;
-  char *ret;
 
   if (remote_hostio_set_filesystem (inf, remote_errno) != 0)
-    return NULL;
+    return {};
 
   remote_buffer_add_string (&p, &left, "vFile:readlink:");
 
@@ -11821,16 +11720,15 @@ remote_hostio_readlink (struct target_ops *self,
                                    &attachment_len);
 
   if (len < 0)
-    return NULL;
+    return {};
 
-  ret = (char *) xmalloc (len + 1);
+  std::string ret (len, '\0');
 
   read_len = remote_unescape_input ((gdb_byte *) attachment, attachment_len,
-                                   (gdb_byte *) ret, len);
+                                   (gdb_byte *) &ret[0], len);
   if (read_len != len)
     error (_("Readlink returned %d, but %d bytes."), len, read_len);
 
-  ret[len] = '\0';
   return ret;
 }
 
@@ -12318,28 +12216,6 @@ remote_trace_init (struct target_ops *self)
     error (_("Target does not support this command."));
 }
 
-static void free_actions_list (char **actions_list);
-static void free_actions_list_cleanup_wrapper (void *);
-static void
-free_actions_list_cleanup_wrapper (void *al)
-{
-  free_actions_list ((char **) al);
-}
-
-static void
-free_actions_list (char **actions_list)
-{
-  int ndx;
-
-  if (actions_list == 0)
-    return;
-
-  for (ndx = 0; actions_list[ndx]; ndx++)
-    xfree (actions_list[ndx]);
-
-  xfree (actions_list);
-}
-
 /* Recursive routine to walk through command list including loops, and
    download packets for each command.  */
 
@@ -12388,20 +12264,14 @@ remote_download_tracepoint (struct target_ops *self, struct bp_location *loc)
   CORE_ADDR tpaddr;
   char addrbuf[40];
   char buf[BUF_SIZE];
-  char **tdp_actions;
-  char **stepping_actions;
-  int ndx;
-  struct cleanup *old_chain = NULL;
+  std::vector<std::string> tdp_actions;
+  std::vector<std::string> stepping_actions;
   char *pkt;
   struct breakpoint *b = loc->owner;
   struct tracepoint *t = (struct tracepoint *) b;
   struct remote_state *rs = get_remote_state ();
 
   encode_actions_rsp (loc, &tdp_actions, &stepping_actions);
-  old_chain = make_cleanup (free_actions_list_cleanup_wrapper,
-                           tdp_actions);
-  (void) make_cleanup (free_actions_list_cleanup_wrapper,
-                      stepping_actions);
 
   tpaddr = loc->address;
   sprintf_vma (addrbuf, tpaddr);
@@ -12467,7 +12337,7 @@ remote_download_tracepoint (struct target_ops *self, struct bp_location *loc)
          xsnprintf (buf + strlen (buf), BUF_SIZE - strlen (buf), ":X%x,",
                     aexpr->len);
          pkt = buf + strlen (buf);
-         for (ndx = 0; ndx < aexpr->len; ++ndx)
+         for (int ndx = 0; ndx < aexpr->len; ++ndx)
            pkt = pack_hex_byte (pkt, aexpr->buf[ndx]);
          *pkt = '\0';
        }
@@ -12484,39 +12354,43 @@ remote_download_tracepoint (struct target_ops *self, struct bp_location *loc)
     error (_("Target does not support tracepoints."));
 
   /* do_single_steps (t); */
-  if (tdp_actions)
-    {
-      for (ndx = 0; tdp_actions[ndx]; ndx++)
-       {
-         QUIT; /* Allow user to bail out with ^C.  */
-         xsnprintf (buf, BUF_SIZE, "QTDP:-%x:%s:%s%c",
-                    b->number, addrbuf, /* address */
-                    tdp_actions[ndx],
-                    ((tdp_actions[ndx + 1] || stepping_actions)
-                     ? '-' : 0));
-         putpkt (buf);
-         remote_get_noisy_reply ();
-         if (strcmp (rs->buf, "OK"))
-           error (_("Error on target while setting tracepoints."));
-       }
-    }
-  if (stepping_actions)
+  for (auto action_it = tdp_actions.begin ();
+       action_it != tdp_actions.end (); action_it++)
     {
-      for (ndx = 0; stepping_actions[ndx]; ndx++)
-       {
-         QUIT; /* Allow user to bail out with ^C.  */
-         xsnprintf (buf, BUF_SIZE, "QTDP:-%x:%s:%s%s%s",
-                    b->number, addrbuf, /* address */
-                    ((ndx == 0) ? "S" : ""),
-                    stepping_actions[ndx],
-                    (stepping_actions[ndx + 1] ? "-" : ""));
-         putpkt (buf);
-         remote_get_noisy_reply ();
-         if (strcmp (rs->buf, "OK"))
-           error (_("Error on target while setting tracepoints."));
-       }
+      QUIT;    /* Allow user to bail out with ^C.  */
+
+      bool has_more = (action_it != tdp_actions.end ()
+                      || !stepping_actions.empty ());
+
+      xsnprintf (buf, BUF_SIZE, "QTDP:-%x:%s:%s%c",
+                b->number, addrbuf, /* address */
+                action_it->c_str (),
+                has_more ? '-' : 0);
+      putpkt (buf);
+      remote_get_noisy_reply ();
+      if (strcmp (rs->buf, "OK"))
+       error (_("Error on target while setting tracepoints."));
     }
 
+    for (auto action_it = stepping_actions.begin ();
+        action_it != stepping_actions.end (); action_it++)
+      {
+       QUIT;   /* Allow user to bail out with ^C.  */
+
+       bool is_first = action_it == stepping_actions.begin ();
+       bool has_more = action_it != stepping_actions.end ();
+
+       xsnprintf (buf, BUF_SIZE, "QTDP:-%x:%s:%s%s%s",
+                  b->number, addrbuf, /* address */
+                  is_first ? "S" : "",
+                  action_it->c_str (),
+                  has_more ? "-" : "");
+       putpkt (buf);
+       remote_get_noisy_reply ();
+       if (strcmp (rs->buf, "OK"))
+         error (_("Error on target while setting tracepoints."));
+      }
+
   if (packet_support (PACKET_TracepointSource) == PACKET_ENABLE)
     {
       if (b->location != NULL)
@@ -12544,8 +12418,6 @@ remote_download_tracepoint (struct target_ops *self, struct bp_location *loc)
       remote_download_command_source (b->number, loc->address,
                                      breakpoint_commands (b));
     }
-
-  do_cleanups (old_chain);
 }
 
 static int
@@ -12578,18 +12450,18 @@ remote_can_download_tracepoint (struct target_ops *self)
 
 static void
 remote_download_trace_state_variable (struct target_ops *self,
-                                     struct trace_state_variable *tsv)
+                                     const trace_state_variable &tsv)
 {
   struct remote_state *rs = get_remote_state ();
   char *p;
 
   xsnprintf (rs->buf, get_remote_packet_size (), "QTDV:%x:%s:%x:",
-            tsv->number, phex ((ULONGEST) tsv->initial_value, 8),
-            tsv->builtin);
+            tsv.number, phex ((ULONGEST) tsv.initial_value, 8),
+            tsv.builtin);
   p = rs->buf + strlen (rs->buf);
-  if ((p - rs->buf) + strlen (tsv->name) * 2 >= get_remote_packet_size ())
+  if ((p - rs->buf) + tsv.name.length () * 2 >= get_remote_packet_size ())
     error (_("Trace state variable name too long for tsv definition packet"));
-  p += 2 * bin2hex ((gdb_byte *) (tsv->name), p, strlen (tsv->name));
+  p += 2 * bin2hex ((gdb_byte *) (tsv.name.data ()), p, tsv.name.length ());
   *p++ = '\0';
   putpkt (rs->buf);
   remote_get_noisy_reply ();
@@ -13011,8 +12883,9 @@ remote_core_of_thread (struct target_ops *ops, ptid_t ptid)
 {
   struct thread_info *info = find_thread_ptid (ptid);
 
-  if (info && info->priv)
-    return info->priv->core;
+  if (info != NULL && info->priv != NULL)
+    return get_remote_thread_info (info)->core;
+
   return -1;
 }
 
@@ -13034,11 +12907,11 @@ remote_set_circular_trace_buffer (struct target_ops *self, int val)
 static traceframe_info_up
 remote_traceframe_info (struct target_ops *self)
 {
-  gdb::unique_xmalloc_ptr<char> text
+  gdb::optional<gdb::char_vector> text
     = target_read_stralloc (&current_target, TARGET_OBJECT_TRACEFRAME_INFO,
                            NULL);
-  if (text != NULL)
-    return parse_traceframe_info (text.get ());
+  if (text)
+    return parse_traceframe_info (text->data ());
 
   return NULL;
 }
@@ -13202,37 +13075,6 @@ remote_btrace_reset (void)
   memset (&rs->btrace_config, 0, sizeof (rs->btrace_config));
 }
 
-/* Check whether the target supports branch tracing.  */
-
-static int
-remote_supports_btrace (struct target_ops *self, enum btrace_format format)
-{
-  if (packet_support (PACKET_Qbtrace_off) != PACKET_ENABLE)
-    return 0;
-  if (packet_support (PACKET_qXfer_btrace) != PACKET_ENABLE)
-    return 0;
-
-  switch (format)
-    {
-      case BTRACE_FORMAT_NONE:
-       return 0;
-
-      case BTRACE_FORMAT_BTS:
-       return (packet_support (PACKET_Qbtrace_bts) == PACKET_ENABLE);
-
-      case BTRACE_FORMAT_PT:
-       /* The trace is decoded on the host.  Even if our target supports it,
-          we still need to have libipt to decode the trace.  */
-#if defined (HAVE_LIBIPT)
-       return (packet_support (PACKET_Qbtrace_pt) == PACKET_ENABLE);
-#else /* !defined (HAVE_LIBIPT)  */
-       return 0;
-#endif /* !defined (HAVE_LIBIPT)  */
-    }
-
-  internal_error (__FILE__, __LINE__, _("Unknown branch trace format"));
-}
-
 /* Synchronize the configuration with the target.  */
 
 static void
@@ -13297,10 +13139,10 @@ btrace_sync_conf (const struct btrace_config *conf)
 static void
 btrace_read_config (struct btrace_config *conf)
 {
-  gdb::unique_xmalloc_ptr<char> xml
+  gdb::optional<gdb::char_vector> xml
     = target_read_stralloc (&current_target, TARGET_OBJECT_BTRACE_CONF, "");
-  if (xml != NULL)
-    parse_xml_btrace_conf (conf, xml.get ());
+  if (xml)
+    parse_xml_btrace_conf (conf, xml->data ());
 }
 
 /* Maybe reopen target btrace.  */
@@ -13331,8 +13173,8 @@ remote_btrace_maybe_reopen (void)
          if (!warned)
            {
              warned = 1;
-             warning (_("GDB does not support Intel Processor Trace. "
-                        "\"record\" will not work in this session."));
+             warning (_("Target is recording using Intel Processor Trace "
+                        "but support was disabled at compile time."));
            }
 
          continue;
@@ -13497,12 +13339,12 @@ remote_read_btrace (struct target_ops *self,
                      (unsigned int) type);
     }
 
-  gdb::unique_xmalloc_ptr<char> xml
+  gdb::optional<gdb::char_vector> xml
     = target_read_stralloc (&current_target, TARGET_OBJECT_BTRACE, annex);
-  if (xml == NULL)
+  if (!xml)
     return BTRACE_ERR_UNKNOWN;
 
-  parse_xml_btrace (btrace, xml.get ());
+  parse_xml_btrace (btrace, xml->data ());
 
   return BTRACE_ERR_NONE;
 }
@@ -13536,7 +13378,7 @@ remote_load (struct target_ops *self, const char *name, int from_tty)
 static char *
 remote_pid_to_exec_file (struct target_ops *self, int pid)
 {
-  static gdb::unique_xmalloc_ptr<char> filename;
+  static gdb::optional<gdb::char_vector> filename;
   struct inferior *inf;
   char *annex = NULL;
 
@@ -13559,7 +13401,7 @@ remote_pid_to_exec_file (struct target_ops *self, int pid)
   filename = target_read_stralloc (&current_target,
                                   TARGET_OBJECT_EXEC_FILE, annex);
 
-  return filename.get ();
+  return filename ? filename->data () : nullptr;
 }
 
 /* Implement the to_can_do_single_step target_ops method.  */
@@ -13609,14 +13451,14 @@ remote_thread_handle_to_thread_info (struct target_ops *ops,
 
   ALL_NON_EXITED_THREADS (tp)
     {
-      struct private_thread_info *priv = get_private_info_thread (tp);
+      remote_thread_info *priv = get_remote_thread_info (tp);
 
       if (tp->inf == inf && priv != NULL)
         {
-         if (handle_len != priv->thread_handle->size ())
+         if (handle_len != priv->thread_handle.size ())
            error (_("Thread handle size mismatch: %d vs %zu (from remote)"),
-                  handle_len, priv->thread_handle->size ());
-         if (memcmp (thread_handle, priv->thread_handle->data (),
+                  handle_len, priv->thread_handle.size ());
+         if (memcmp (thread_handle, priv->thread_handle.data (),
                      handle_len) == 0)
            return tp;
        }
@@ -13756,7 +13598,6 @@ Specify the serial device it is connected to\n\
   remote_ops.to_traceframe_info = remote_traceframe_info;
   remote_ops.to_use_agent = remote_use_agent;
   remote_ops.to_can_use_agent = remote_can_use_agent;
-  remote_ops.to_supports_btrace = remote_supports_btrace;
   remote_ops.to_enable_btrace = remote_enable_btrace;
   remote_ops.to_disable_btrace = remote_disable_btrace;
   remote_ops.to_teardown_btrace = remote_teardown_btrace;
@@ -14019,7 +13860,7 @@ show_range_stepping (struct ui_file *file, int from_tty,
 /* The "set/show range-stepping" set hook.  */
 
 static void
-set_range_stepping (char *ignore_args, int from_tty,
+set_range_stepping (const char *ignore_args, int from_tty,
                    struct cmd_list_element *c)
 {
   struct remote_state *rs = get_remote_state ();
@@ -14070,10 +13911,10 @@ _initialize_remote (void)
   add_target (&extended_remote_ops);
 
   /* Hook into new objfile notification.  */
-  observer_attach_new_objfile (remote_new_objfile);
+  gdb::observers::new_objfile.attach (remote_new_objfile);
   /* We're no longer interested in notification events of an inferior
      when it exits.  */
-  observer_attach_inferior_exit (discard_pending_stop_replies);
+  gdb::observers::inferior_exit.attach (discard_pending_stop_replies);
 
 #if 0
   init_remote_threadtests ();
This page took 0.052347 seconds and 4 git commands to generate.