btrace: support Intel(R) Processor Trace
[deliverable/binutils-gdb.git] / gdb / remote.c
index 9be15cb3073bbedf5165c76a58977d3471c2f227..9d97f6b18a6c84d78fd254403ae42ff0c68bd27e 100644 (file)
@@ -104,14 +104,16 @@ static void remote_open_1 (const char *, int, struct target_ops *,
 
 static void remote_close (struct target_ops *self);
 
+struct remote_state;
+
+static int remote_vkill (int pid, struct remote_state *rs);
+
 static void remote_mourn (struct target_ops *ops);
 
 static void extended_remote_restart (void);
 
 static void extended_remote_mourn (struct target_ops *);
 
-static void remote_mourn_1 (struct target_ops *);
-
 static void remote_send (char **buf, long *sizeof_buf_p);
 
 static int readchar (int timeout);
@@ -124,10 +126,7 @@ static int remote_can_async_p (struct target_ops *);
 
 static int remote_is_async_p (struct target_ops *);
 
-static void remote_async (struct target_ops *ops,
-                         void (*callback) (enum inferior_event_type event_type,
-                                           void *context),
-                         void *context);
+static void remote_async (struct target_ops *ops, int enable);
 
 static void sync_remote_interrupt_twice (int signo);
 
@@ -186,7 +185,6 @@ static ptid_t read_ptid (char *buf, char **obuf);
 
 static void remote_set_permissions (struct target_ops *self);
 
-struct remote_state;
 static int remote_get_trace_status (struct target_ops *self,
                                    struct trace_status *ts);
 
@@ -209,6 +207,9 @@ static void push_stop_reply (struct stop_reply *);
 static void discard_pending_stop_replies_in_queue (struct remote_state *);
 static int peek_stop_reply (ptid_t ptid);
 
+struct threads_listing_context;
+static void remove_new_fork_children (struct threads_listing_context *);
+
 static void remote_async_inferior_event_handler (gdb_client_data);
 
 static void remote_terminal_ours (struct target_ops *self);
@@ -221,6 +222,8 @@ static int remote_supports_cond_breakpoints (struct target_ops *self);
 
 static int remote_can_run_breakpoint_commands (struct target_ops *self);
 
+static void remote_btrace_reset (void);
+
 /* For "remote".  */
 
 static struct cmd_list_element *remote_cmdlist;
@@ -354,16 +357,12 @@ struct remote_state
   int use_threadinfo_query;
   int use_threadextra_query;
 
-  void (*async_client_callback) (enum inferior_event_type event_type,
-                                void *context);
-  void *async_client_context;
-
   /* This is set to the data address of the access causing the target
      to stop for a watchpoint.  */
   CORE_ADDR remote_watch_data_address;
 
-  /* This is non-zero if target stopped for a watchpoint.  */
-  int remote_stopped_by_watchpoint_p;
+  /* Whether the target stopped for a breakpoint/watchpoint.  */
+  enum target_stop_reason stop_reason;
 
   threadref echo_nextthread;
   threadref nextthread;
@@ -371,6 +370,15 @@ struct remote_state
 
   /* The state of remote notification.  */
   struct remote_notif_state *notif_state;
+
+  /* The branch trace configuration.  */
+  struct btrace_config btrace_config;
+
+  /* The argument to the last "vFile:setfs:" packet we sent, used
+     to avoid sending repeated unnecessary "vFile:setfs:" packets.
+     Initialized to -1 to indicate that no "vFile:setfs:" packet
+     has yet been sent.  */
+  int fs_pid;
 };
 
 /* Private data that we'll store in (struct thread_info)->private.  */
@@ -413,6 +421,7 @@ new_remote_state (void)
   result->buf = xmalloc (result->buf_size);
   result->remote_traceframe_number = -1;
   result->last_sent_signal = GDB_SIGNAL_0;
+  result->fs_pid = -1;
 
   return result;
 }
@@ -486,13 +495,13 @@ remote_get_noisy_reply (char **buf_p,
       buf = *buf_p;
       if (buf[0] == 'E')
        trace_error (buf);
-      else if (strncmp (buf, "qRelocInsn:", strlen ("qRelocInsn:")) == 0)
+      else if (startswith (buf, "qRelocInsn:"))
        {
          ULONGEST ul;
          CORE_ADDR from, to, org_to;
          char *p, *pp;
          int adjusted_size = 0;
-         volatile struct gdb_exception ex;
+         int relocated = 0;
 
          p = buf + strlen ("qRelocInsn:");
          pp = unpack_varlen_hex (p, &ul);
@@ -506,34 +515,39 @@ remote_get_noisy_reply (char **buf_p,
 
          org_to = to;
 
-         TRY_CATCH (ex, RETURN_MASK_ALL)
+         TRY
            {
              gdbarch_relocate_instruction (target_gdbarch (), &to, from);
+             relocated = 1;
+           }
+         CATCH (ex, RETURN_MASK_ALL)
+           {
+             if (ex.error == MEMORY_ERROR)
+               {
+                 /* Propagate memory errors silently back to the
+                    target.  The stub may have limited the range of
+                    addresses we can write to, for example.  */
+               }
+             else
+               {
+                 /* Something unexpectedly bad happened.  Be verbose
+                    so we can tell what, and propagate the error back
+                    to the stub, so it doesn't get stuck waiting for
+                    a response.  */
+                 exception_fprintf (gdb_stderr, ex,
+                                    _("warning: relocating instruction: "));
+               }
+             putpkt ("E01");
            }
-         if (ex.reason >= 0)
+         END_CATCH
+
+         if (relocated)
            {
              adjusted_size = to - org_to;
 
              xsnprintf (buf, *sizeof_buf, "qRelocInsn:%x", adjusted_size);
              putpkt (buf);
            }
-         else if (ex.reason < 0 && ex.error == MEMORY_ERROR)
-           {
-             /* Propagate memory errors silently back to the target.
-                The stub may have limited the range of addresses we
-                can write to, for example.  */
-             putpkt ("E01");
-           }
-         else
-           {
-             /* Something unexpectedly bad happened.  Be verbose so
-                we can tell what, and propagate the error back to the
-                stub, so it doesn't get stuck waiting for a
-                response.  */
-             exception_fprintf (gdb_stderr, ex,
-                                _("warning: relocating instruction: "));
-             putpkt ("E01");
-           }
        }
       else if (buf[0] == 'O' && buf[1] != 'K')
        remote_console_output (buf + 1);        /* 'O' message from stub */
@@ -1242,14 +1256,17 @@ enum {
   PACKET_Z2,
   PACKET_Z3,
   PACKET_Z4,
+  PACKET_vFile_setfs,
   PACKET_vFile_open,
   PACKET_vFile_pread,
   PACKET_vFile_pwrite,
   PACKET_vFile_close,
   PACKET_vFile_unlink,
   PACKET_vFile_readlink,
+  PACKET_vFile_fstat,
   PACKET_qXfer_auxv,
   PACKET_qXfer_features,
+  PACKET_qXfer_exec_file,
   PACKET_qXfer_libraries,
   PACKET_qXfer_libraries_svr4,
   PACKET_qXfer_memory_map,
@@ -1305,6 +1322,7 @@ enum {
   PACKET_QTBuffer_size,
   PACKET_Qbtrace_off,
   PACKET_Qbtrace_bts,
+  PACKET_Qbtrace_pt,
   PACKET_qXfer_btrace,
 
   /* Support for the QNonStop packet.  */
@@ -1327,11 +1345,41 @@ enum {
   /* Support for qXfer:libraries-svr4:read with a non-empty annex.  */
   PACKET_augmented_libraries_svr4_read_feature,
 
+  /* Support for the qXfer:btrace-conf:read packet.  */
+  PACKET_qXfer_btrace_conf,
+
+  /* Support for the Qbtrace-conf:bts:size packet.  */
+  PACKET_Qbtrace_conf_bts_size,
+
+  /* Support for swbreak+ feature.  */
+  PACKET_swbreak_feature,
+
+  /* Support for hwbreak+ feature.  */
+  PACKET_hwbreak_feature,
+
+  /* Support for fork events.  */
+  PACKET_fork_event_feature,
+
+  /* Support for vfork events.  */
+  PACKET_vfork_event_feature,
+
+  /* Support for the Qbtrace-conf:pt:size packet.  */
+  PACKET_Qbtrace_conf_pt_size,
+
   PACKET_MAX
 };
 
 static struct packet_config remote_protocol_packets[PACKET_MAX];
 
+/* Returns the packet's corresponding "set remote foo-packet" command
+   state.  See struct packet_config for more details.  */
+
+static enum auto_boolean
+packet_set_cmd_state (int packet)
+{
+  return remote_protocol_packets[packet].detect;
+}
+
 /* Returns whether a given packet or feature is supported.  This takes
    into account the state of the corresponding "set remote foo-packet"
    command, which may be used to bypass auto-detection.  */
@@ -1432,6 +1480,62 @@ remote_multi_process_p (struct remote_state *rs)
   return packet_support (PACKET_multiprocess_feature) == PACKET_ENABLE;
 }
 
+/* Returns true if fork events are supported.  */
+
+static int
+remote_fork_event_p (struct remote_state *rs)
+{
+  return packet_support (PACKET_fork_event_feature) == PACKET_ENABLE;
+}
+
+/* Returns true if vfork events are supported.  */
+
+static int
+remote_vfork_event_p (struct remote_state *rs)
+{
+  return packet_support (PACKET_vfork_event_feature) == PACKET_ENABLE;
+}
+
+/* Insert fork catchpoint target routine.  If fork events are enabled
+   then return success, nothing more to do.  */
+
+static int
+remote_insert_fork_catchpoint (struct target_ops *ops, int pid)
+{
+  struct remote_state *rs = get_remote_state ();
+
+  return !remote_fork_event_p (rs);
+}
+
+/* Remove fork catchpoint target routine.  Nothing to do, just
+   return success.  */
+
+static int
+remote_remove_fork_catchpoint (struct target_ops *ops, int pid)
+{
+  return 0;
+}
+
+/* Insert vfork catchpoint target routine.  If vfork events are enabled
+   then return success, nothing more to do.  */
+
+static int
+remote_insert_vfork_catchpoint (struct target_ops *ops, int pid)
+{
+  struct remote_state *rs = get_remote_state ();
+
+  return !remote_vfork_event_p (rs);
+}
+
+/* Remove vfork catchpoint target routine.  Nothing to do, just
+   return success.  */
+
+static int
+remote_remove_vfork_catchpoint (struct target_ops *ops, int pid)
+{
+  return 0;
+}
+
 /* Tokens for use by the asynchronous signal handlers for SIGINT.  */
 static struct async_signal_handler *async_sigint_remote_twice_token;
 static struct async_signal_handler *async_sigint_remote_token;
@@ -1492,10 +1596,13 @@ remote_query_attached (int pid)
    inferior.  If ATTACHED is 1, then we had just attached to this
    inferior.  If it is 0, then we just created this inferior.  If it
    is -1, then try querying the remote stub to find out if it had
-   attached to the inferior or not.  */
+   attached to the inferior or not.  If TRY_OPEN_EXEC is true then
+   attempt to open this inferior's executable as the main executable
+   if no main executable is open already.  */
 
 static struct inferior *
-remote_add_inferior (int fake_pid_p, int pid, int attached)
+remote_add_inferior (int fake_pid_p, int pid, int attached,
+                    int try_open_exec)
 {
   struct inferior *inf;
 
@@ -1529,6 +1636,11 @@ remote_add_inferior (int fake_pid_p, int pid, int attached)
   inf->attach_flag = attached;
   inf->fake_pid_p = fake_pid_p;
 
+  /* If no main executable is currently open then attempt to
+     open the file that was executed to create this inferior.  */
+  if (try_open_exec && get_exec_file (0) == NULL)
+    exec_file_locate_attach (pid, 1);
+
   return inf;
 }
 
@@ -1619,7 +1731,7 @@ remote_notice_new_inferior (ptid_t currthread, int running)
          int fake_pid_p = !remote_multi_process_p (rs);
 
          inf = remote_add_inferior (fake_pid_p,
-                                    ptid_get_pid (currthread), -1);
+                                    ptid_get_pid (currthread), -1, 1);
        }
 
       /* This is really a new thread.  Add it.  */
@@ -1648,15 +1760,15 @@ demand_private_info (ptid_t ptid)
 
   gdb_assert (info);
 
-  if (!info->private)
+  if (!info->priv)
     {
-      info->private = xmalloc (sizeof (*(info->private)));
+      info->priv = xmalloc (sizeof (*(info->priv)));
       info->private_dtor = free_private_thread_info;
-      info->private->core = -1;
-      info->private->extra = 0;
+      info->priv->core = -1;
+      info->priv->extra = 0;
     }
 
-  return info->private;
+  return info->priv;
 }
 
 /* Call this function as a result of
@@ -2591,6 +2703,27 @@ clear_threads_listing_context (void *p)
   VEC_free (thread_item_t, context->items);
 }
 
+/* Remove the thread specified as the related_pid field of WS
+   from the CONTEXT list.  */
+
+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;
+
+  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;
+       }
+    }
+}
+
 static int
 remote_newthread_step (threadref *ref, void *data)
 {
@@ -2812,8 +2945,8 @@ remote_update_thread_list (struct target_ops *ops)
       /* CONTEXT now holds the current thread list on the remote
         target end.  Delete GDB-side threads no longer found on the
         target.  */
-      ALL_NON_EXITED_THREADS_SAFE (tp, tmp)
-        {
+      ALL_THREADS_SAFE (tp, tmp)
+       {
          for (i = 0;
               VEC_iterate (thread_item_t, context.items, i, item);
               ++i)
@@ -2827,7 +2960,12 @@ remote_update_thread_list (struct target_ops *ops)
              /* Not found.  */
              delete_thread (tp->ptid);
            }
-        }
+       }
+
+      /* Remove any unreported fork child threads from CONTEXT so
+        that we don't interfere with follow fork, which is where
+        creation of such threads is handled.  */
+      remove_new_fork_children (&context);
 
       /* And now add threads we don't know about yet to our list.  */
       for (i = 0;
@@ -2899,8 +3037,8 @@ remote_threads_extra_info (struct target_ops *self, struct thread_info *tp)
     {
       struct thread_info *info = find_thread_ptid (tp->ptid);
 
-      if (info && info->private)
-       return info->private->extra;
+      if (info && info->priv)
+       return info->priv->extra;
       else
        return NULL;
     }
@@ -3131,14 +3269,14 @@ get_offsets (void)
   ptr = buf;
   lose = 0;
 
-  if (strncmp (ptr, "Text=", 5) == 0)
+  if (startswith (ptr, "Text="))
     {
       ptr += 5;
       /* Don't use strtol, could lose on big values.  */
       while (*ptr && *ptr != ';')
        text_addr = (text_addr << 4) + fromhex (*ptr++);
 
-      if (strncmp (ptr, ";Data=", 6) == 0)
+      if (startswith (ptr, ";Data="))
        {
          ptr += 6;
          while (*ptr && *ptr != ';')
@@ -3147,7 +3285,7 @@ get_offsets (void)
       else
        lose = 1;
 
-      if (!lose && strncmp (ptr, ";Bss=", 5) == 0)
+      if (!lose && startswith (ptr, ";Bss="))
        {
          ptr += 5;
          while (*ptr && *ptr != ';')
@@ -3159,7 +3297,7 @@ get_offsets (void)
       else
        lose = 1;
     }
-  else if (strncmp (ptr, "TextSeg=", 8) == 0)
+  else if (startswith (ptr, "TextSeg="))
     {
       ptr += 8;
       /* Don't use strtol, could lose on big values.  */
@@ -3167,7 +3305,7 @@ get_offsets (void)
        text_addr = (text_addr << 4) + fromhex (*ptr++);
       num_segments = 1;
 
-      if (strncmp (ptr, ";DataSeg=", 9) == 0)
+      if (startswith (ptr, ";DataSeg="))
        {
          ptr += 9;
          while (*ptr && *ptr != ';')
@@ -3389,7 +3527,7 @@ add_current_inferior_and_thread (char *wait_status)
       fake_pid_p = 1;
     }
 
-  remote_add_inferior (fake_pid_p, ptid_get_pid (inferior_ptid), -1);
+  remote_add_inferior (fake_pid_p, ptid_get_pid (inferior_ptid), -1, 1);
 
   /* Add the main thread.  */
   add_thread_silent (inferior_ptid);
@@ -3629,7 +3767,7 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
        }
 
       if (target_can_async_p ())
-       target_async (inferior_event_handler, 0);
+       target_async (1);
 
       if (thread_count () == 0)
        {
@@ -3774,7 +3912,7 @@ remote_check_symbols (void)
   packet_ok (rs->buf, &remote_protocol_packets[PACKET_qSymbol]);
   reply = rs->buf;
 
-  while (strncmp (reply, "qSymbol:", 8) == 0)
+  while (startswith (reply, "qSymbol:"))
     {
       struct bound_minimal_symbol sym;
 
@@ -3814,7 +3952,7 @@ remote_serial_open (const char *name)
      of in ser-tcp.c, because it is the remote protocol assuming that the
      serial connection is reliable and not the serial connection promising
      to be.  */
-  if (!udp_warning && strncmp (name, "udp:", 4) == 0)
+  if (!udp_warning && startswith (name, "udp:"))
     {
       warning (_("The remote protocol may be unreliable over UDP.\n"
                 "Some events may be lost, rendering further debugging "
@@ -3940,6 +4078,8 @@ static const struct protocol_feature remote_protocol_features[] = {
   { "PacketSize", PACKET_DISABLE, remote_packet_size, -1 },
   { "qXfer:auxv:read", PACKET_DISABLE, remote_supported_packet,
     PACKET_qXfer_auxv },
+  { "qXfer:exec-file:read", PACKET_DISABLE, remote_supported_packet,
+    PACKET_qXfer_exec_file },
   { "qXfer:features:read", PACKET_DISABLE, remote_supported_packet,
     PACKET_qXfer_features },
   { "qXfer:libraries:read", PACKET_DISABLE, remote_supported_packet,
@@ -4009,8 +4149,21 @@ static const struct protocol_feature remote_protocol_features[] = {
   { "tracenz", PACKET_DISABLE, remote_supported_packet, PACKET_tracenz_feature },
   { "Qbtrace:off", PACKET_DISABLE, remote_supported_packet, PACKET_Qbtrace_off },
   { "Qbtrace:bts", PACKET_DISABLE, remote_supported_packet, PACKET_Qbtrace_bts },
+  { "Qbtrace:pt", PACKET_DISABLE, remote_supported_packet, PACKET_Qbtrace_pt },
   { "qXfer:btrace:read", PACKET_DISABLE, remote_supported_packet,
-    PACKET_qXfer_btrace }
+    PACKET_qXfer_btrace },
+  { "qXfer:btrace-conf:read", PACKET_DISABLE, remote_supported_packet,
+    PACKET_qXfer_btrace_conf },
+  { "Qbtrace-conf:bts:size", PACKET_DISABLE, remote_supported_packet,
+    PACKET_Qbtrace_conf_bts_size },
+  { "swbreak", PACKET_DISABLE, remote_supported_packet, PACKET_swbreak_feature },
+  { "hwbreak", PACKET_DISABLE, remote_supported_packet, PACKET_hwbreak_feature },
+  { "fork-events", PACKET_DISABLE, remote_supported_packet,
+    PACKET_fork_event_feature },
+  { "vfork-events", PACKET_DISABLE, remote_supported_packet,
+    PACKET_vfork_event_feature },
+  { "Qbtrace-conf:pt:size", PACKET_DISABLE, remote_supported_packet,
+    PACKET_Qbtrace_conf_pt_size }
 };
 
 static char *remote_support_xml;
@@ -4079,11 +4232,26 @@ remote_query_supported (void)
 
       q = remote_query_supported_append (q, "multiprocess+");
 
+      if (packet_set_cmd_state (PACKET_swbreak_feature) != AUTO_BOOLEAN_FALSE)
+       q = remote_query_supported_append (q, "swbreak+");
+      if (packet_set_cmd_state (PACKET_hwbreak_feature) != AUTO_BOOLEAN_FALSE)
+       q = remote_query_supported_append (q, "hwbreak+");
+
       if (remote_support_xml)
        q = remote_query_supported_append (q, remote_support_xml);
 
       q = remote_query_supported_append (q, "qRelocInsn+");
 
+      if (rs->extended)
+       {
+         if (packet_set_cmd_state (PACKET_fork_event_feature)
+             != AUTO_BOOLEAN_FALSE)
+           q = remote_query_supported_append (q, "fork-events+");
+         if (packet_set_cmd_state (PACKET_vfork_event_feature)
+             != AUTO_BOOLEAN_FALSE)
+           q = remote_query_supported_append (q, "vfork-events+");
+       }
+
       q = reconcat (q, "qSupported:", q, (char *) NULL);
       putpkt (q);
 
@@ -4265,6 +4433,7 @@ remote_open_1 (const char *name, int from_tty,
        }
     }
 
+  serial_setparity (rs->remote_desc, serial_parity);
   serial_raw (rs->remote_desc);
 
   /* If there is something sitting in the buffer we might take it as a
@@ -4340,13 +4509,12 @@ remote_open_1 (const char *name, int from_tty,
      all the ``target ....'' commands to share a common callback
      function.  See cli-dump.c.  */
   {
-    volatile struct gdb_exception ex;
 
-    TRY_CATCH (ex, RETURN_MASK_ALL)
+    TRY
       {
        remote_start_remote (from_tty, target, extended_p);
       }
-    if (ex.reason < 0)
+    CATCH (ex, RETURN_MASK_ALL)
       {
        /* Pop the partially set up target - unless something else did
           already before throwing the exception.  */
@@ -4356,22 +4524,51 @@ remote_open_1 (const char *name, int from_tty,
          wait_forever_enabled_p = 1;
        throw_exception (ex);
       }
+    END_CATCH
   }
 
+  remote_btrace_reset ();
+
   if (target_async_permitted)
     wait_forever_enabled_p = 1;
 }
 
-/* This takes a program previously attached to and detaches it.  After
-   this is done, GDB can be used to debug some other program.  We
-   better not have left any breakpoints in the target program or it'll
-   die when it hits one.  */
+/* Detach the specified process.  */
+
+static void
+remote_detach_pid (int pid)
+{
+  struct remote_state *rs = get_remote_state ();
+
+  if (remote_multi_process_p (rs))
+    xsnprintf (rs->buf, get_remote_packet_size (), "D;%x", pid);
+  else
+    strcpy (rs->buf, "D");
+
+  putpkt (rs->buf);
+  getpkt (&rs->buf, &rs->buf_size, 0);
+
+  if (rs->buf[0] == 'O' && rs->buf[1] == 'K')
+    ;
+  else if (rs->buf[0] == '\0')
+    error (_("Remote doesn't know how to detach"));
+  else
+    error (_("Can't detach process."));
+}
+
+/* This detaches a program to which we previously attached, using
+   inferior_ptid to identify the process.  After this is done, GDB
+   can be used to debug some other program.  We better not have left
+   any breakpoints in the target program or it'll die when it hits
+   one.  */
 
 static void
-remote_detach_1 (const char *args, int from_tty, int extended)
+remote_detach_1 (const char *args, int from_tty)
 {
   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."));
@@ -4390,37 +4587,76 @@ remote_detach_1 (const char *args, int from_tty, int extended)
     }
 
   /* Tell the remote target to detach.  */
-  if (remote_multi_process_p (rs))
-    xsnprintf (rs->buf, get_remote_packet_size (), "D;%x", pid);
-  else
-    strcpy (rs->buf, "D");
-
-  putpkt (rs->buf);
-  getpkt (&rs->buf, &rs->buf_size, 0);
-
-  if (rs->buf[0] == 'O' && rs->buf[1] == 'K')
-    ;
-  else if (rs->buf[0] == '\0')
-    error (_("Remote doesn't know how to detach"));
-  else
-    error (_("Can't detach process."));
+  remote_detach_pid (pid);
 
-  if (from_tty && !extended)
+  if (from_tty && !rs->extended)
     puts_filtered (_("Ending remote debugging.\n"));
 
-  target_mourn_inferior ();
+  /* Check to see if we are detaching a fork parent.  Note that if we
+     are detaching a fork child, tp == NULL.  */
+  is_fork_parent = (tp != NULL
+                   && tp->pending_follow.kind == TARGET_WAITKIND_FORKED);
+
+  /* If doing detach-on-fork, we don't mourn, because that will delete
+     breakpoints that should be available for the followed inferior.  */
+  if (!is_fork_parent)
+    target_mourn_inferior ();
+  else
+    {
+      inferior_ptid = null_ptid;
+      detach_inferior (pid);
+    }
 }
 
 static void
 remote_detach (struct target_ops *ops, const char *args, int from_tty)
 {
-  remote_detach_1 (args, from_tty, 0);
+  remote_detach_1 (args, from_tty);
 }
 
 static void
 extended_remote_detach (struct target_ops *ops, const char *args, int from_tty)
 {
-  remote_detach_1 (args, from_tty, 1);
+  remote_detach_1 (args, from_tty);
+}
+
+/* Target follow-fork function for remote targets.  On entry, and
+   at return, the current inferior is the fork parent.
+
+   Note that although this is currently only used for extended-remote,
+   it is named remote_follow_fork in anticipation of using it for the
+   remote target as well.  */
+
+static int
+remote_follow_fork (struct target_ops *ops, int follow_child,
+                   int detach_fork)
+{
+  struct remote_state *rs = get_remote_state ();
+  enum target_waitkind kind = inferior_thread ()->pending_follow.kind;
+
+  if ((kind == TARGET_WAITKIND_FORKED && remote_fork_event_p (rs))
+      || (kind == TARGET_WAITKIND_VFORKED && remote_vfork_event_p (rs)))
+    {
+      /* When following the parent and detaching the child, we detach
+        the child here.  For the case of following the child and
+        detaching the parent, the detach is done in the target-
+        independent follow fork code in infrun.c.  We can't use
+        target_detach when detaching an unfollowed child because
+        the client side doesn't know anything about the child.  */
+      if (detach_fork && !follow_child)
+       {
+         /* Detach the fork child.  */
+         ptid_t child_ptid;
+         pid_t child_pid;
+
+         child_ptid = inferior_thread ()->pending_follow.value.related_pid;
+         child_pid = ptid_get_pid (child_ptid);
+
+         remote_detach_pid (child_pid);
+         detach_inferior (child_pid);
+       }
+    }
+  return 0;
 }
 
 /* Same as remote_detach, but don't send the "D" packet; just disconnect.  */
@@ -4432,9 +4668,9 @@ remote_disconnect (struct target_ops *target, const char *args, int from_tty)
     error (_("Argument given to \"disconnect\" when remotely debugging."));
 
   /* Make sure we unpush even the extended remote targets; mourn
-     won't do it.  So call remote_mourn_1 directly instead of
+     won't do it.  So call remote_mourn directly instead of
      target_mourn_inferior.  */
-  remote_mourn_1 (target);
+  remote_mourn (target);
 
   if (from_tty)
     puts_filtered ("Ending remote debugging.\n");
@@ -4444,8 +4680,8 @@ remote_disconnect (struct target_ops *target, const char *args, int from_tty)
    be chatty about it.  */
 
 static void
-extended_remote_attach_1 (struct target_ops *target, const char *args,
-                         int from_tty)
+extended_remote_attach (struct target_ops *target, const char *args,
+                       int from_tty)
 {
   struct remote_state *rs = get_remote_state ();
   int pid;
@@ -4499,7 +4735,7 @@ extended_remote_attach_1 (struct target_ops *target, const char *args,
             target_pid_to_str (pid_to_ptid (pid)));
     }
 
-  set_current_inferior (remote_add_inferior (0, pid, 1));
+  set_current_inferior (remote_add_inferior (0, pid, 1, 0));
 
   inferior_ptid = pid_to_ptid (pid);
 
@@ -4544,7 +4780,7 @@ extended_remote_attach_1 (struct target_ops *target, const char *args,
 
          push_stop_reply ((struct stop_reply *) reply);
 
-         target_async (inferior_event_handler, 0);
+         target_async (1);
        }
       else
        {
@@ -4557,12 +4793,6 @@ extended_remote_attach_1 (struct target_ops *target, const char *args,
     gdb_assert (wait_status == NULL);
 }
 
-static void
-extended_remote_attach (struct target_ops *ops, const char *args, int from_tty)
-{
-  extended_remote_attach_1 (ops, args, from_tty);
-}
-
 /* Implementation of the to_post_attach method.  */
 
 static void
@@ -4592,7 +4822,7 @@ remote_vcont_probe (struct remote_state *rs)
   buf = rs->buf;
 
   /* Make sure that the features we assume are supported.  */
-  if (strncmp (buf, "vCont", 5) == 0)
+  if (startswith (buf, "vCont"))
     {
       char *p = &buf[5];
       int support_s, support_S, support_c, support_C;
@@ -4883,7 +5113,7 @@ remote_resume (struct target_ops *ops,
      into infcmd.c in order to allow inferior function calls to work
      NOT asynchronously.  */
   if (target_can_async_p ())
-    target_async (inferior_event_handler, 0);
+    target_async (1);
 
   /* We've just told the target to resume.  The remote server will
      wait for the inferior to stop, and then send a stop reply.  In
@@ -5185,7 +5415,8 @@ typedef struct stop_reply
      fetch them is avoided).  */
   VEC(cached_reg_t) *regcache;
 
-  int stopped_by_watchpoint_p;
+  enum target_stop_reason stop_reason;
+
   CORE_ADDR watch_data_address;
 
   int core;
@@ -5283,6 +5514,81 @@ struct queue_iter_param
   struct stop_reply *output;
 };
 
+/* Determine if THREAD is a pending fork parent thread.  ARG contains
+   the pid of the process that owns the threads we want to check, or
+   -1 if we want to check all threads.  */
+
+static int
+is_pending_fork_parent (struct target_waitstatus *ws, int event_pid,
+                       ptid_t thread_ptid)
+{
+  if (ws->kind == TARGET_WAITKIND_FORKED
+      || ws->kind == TARGET_WAITKIND_VFORKED)
+    {
+      if (event_pid == -1 || event_pid == ptid_get_pid (thread_ptid))
+       return 1;
+    }
+
+  return 0;
+}
+
+/* Check whether EVENT is a fork event, and if it is, remove the
+   fork child from the context list passed in DATA.  */
+
+static int
+remove_child_of_pending_fork (QUEUE (stop_reply_p) *q,
+                             QUEUE_ITER (stop_reply_p) *iter,
+                             stop_reply_p event,
+                             void *data)
+{
+  struct queue_iter_param *param = data;
+  struct threads_listing_context *context = param->input;
+
+  if (event->ws.kind == TARGET_WAITKIND_FORKED
+      || event->ws.kind == TARGET_WAITKIND_VFORKED)
+    {
+      threads_listing_context_remove (&event->ws, context);
+    }
+
+  return 1;
+}
+
+/* If CONTEXT contains any fork child threads that have not been
+   reported yet, remove them from the CONTEXT list.  If such a
+   thread exists it is because we are stopped at a fork catchpoint
+   and have not yet called follow_fork, which will set up the
+   host-side data structures for the new process.  */
+
+static void
+remove_new_fork_children (struct threads_listing_context *context)
+{
+  struct thread_info * thread;
+  int pid = -1;
+  struct notif_client *notif = &notif_client_stop;
+  struct queue_iter_param param;
+
+  /* For any threads stopped at a fork event, remove the corresponding
+     fork child threads from the CONTEXT list.  */
+  ALL_NON_EXITED_THREADS (thread)
+    {
+      struct target_waitstatus *ws = &thread->pending_follow;
+
+      if (is_pending_fork_parent (ws, pid, thread->ptid))
+       {
+         threads_listing_context_remove (ws, context);
+       }
+    }
+
+  /* Check for any pending fork events (not reported or processed yet)
+     in process PID and remove those fork child threads from the
+     CONTEXT list as well.  */
+  remote_notif_get_pending_events (notif);
+  param.input = context;
+  param.output = NULL;
+  QUEUE_iterate (stop_reply_p, stop_reply_queue,
+                remove_child_of_pending_fork, &param);
+}
+
 /* Remove stop replies in the queue if its pid is equal to the given
    inferior's pid.  */
 
@@ -5472,6 +5778,16 @@ peek_stop_reply (ptid_t ptid)
                         stop_reply_match_ptid_and_ws, &ptid);
 }
 
+/* Skip PACKET until the next semi-colon (or end of string).  */
+
+static char *
+skip_to_semicolon (char *p)
+{
+  while (*p != '\0' && *p != ';')
+    p++;
+  return p;
+}
+
 /* Parse the stop reply in BUF.  Either the function succeeds, and the
    result is stored in EVENT, or throws an error.  */
 
@@ -5486,7 +5802,7 @@ remote_parse_stop_reply (char *buf, struct stop_reply *event)
   event->rs = get_remote_state ();
   event->ws.kind = TARGET_WAITKIND_IGNORE;
   event->ws.value.integer = 0;
-  event->stopped_by_watchpoint_p = 0;
+  event->stop_reason = TARGET_STOPPED_BY_NO_REASON;
   event->regcache = NULL;
   event->core = -1;
 
@@ -5504,107 +5820,134 @@ remote_parse_stop_reply (char *buf, struct stop_reply *event)
       while (*p)
        {
          char *p1;
-         char *p_temp;
          int fieldsize;
-         LONGEST pnum = 0;
 
-         /* If the packet contains a register number, save it in
-            pnum and set p1 to point to the character following it.
-            Otherwise p1 points to p.  */
+         p1 = strchr (p, ':');
+         if (p1 == NULL)
+           error (_("Malformed packet(a) (missing colon): %s\n\
+Packet: '%s'\n"),
+                  p, buf);
+         if (p == p1)
+           error (_("Malformed packet(a) (missing register number): %s\n\
+Packet: '%s'\n"),
+                  p, buf);
 
-         /* If this packet is an awatch packet, don't parse the 'a'
-            as a register number.  */
+         /* Some "registers" are actually extended stop information.
+            Note if you're adding a new entry here: GDB 7.9 and
+            earlier assume that all register "numbers" that start
+            with an hex digit are real register numbers.  Make sure
+            the server only sends such a packet if it knows the
+            client understands it.  */
 
-         if (strncmp (p, "awatch", strlen("awatch")) != 0
-             && strncmp (p, "core", strlen ("core") != 0))
+         if (strncmp (p, "thread", p1 - p) == 0)
+           event->ptid = read_ptid (++p1, &p);
+         else if ((strncmp (p, "watch", p1 - p) == 0)
+                  || (strncmp (p, "rwatch", p1 - p) == 0)
+                  || (strncmp (p, "awatch", p1 - p) == 0))
            {
-             /* Read the ``P'' register number.  */
-             pnum = strtol (p, &p_temp, 16);
-             p1 = p_temp;
+             event->stop_reason = TARGET_STOPPED_BY_WATCHPOINT;
+             p = unpack_varlen_hex (++p1, &addr);
+             event->watch_data_address = (CORE_ADDR) addr;
            }
-         else
-           p1 = p;
-
-         if (p1 == p)  /* No register number present here.  */
+         else if (strncmp (p, "swbreak", p1 - p) == 0)
            {
-             p1 = strchr (p, ':');
-             if (p1 == NULL)
-               error (_("Malformed packet(a) (missing colon): %s\n\
-Packet: '%s'\n"),
-                      p, buf);
-             if (strncmp (p, "thread", p1 - p) == 0)
-               event->ptid = read_ptid (++p1, &p);
-             else if ((strncmp (p, "watch", p1 - p) == 0)
-                      || (strncmp (p, "rwatch", p1 - p) == 0)
-                      || (strncmp (p, "awatch", p1 - p) == 0))
-               {
-                 event->stopped_by_watchpoint_p = 1;
-                 p = unpack_varlen_hex (++p1, &addr);
-                 event->watch_data_address = (CORE_ADDR) addr;
-               }
-             else if (strncmp (p, "library", p1 - p) == 0)
-               {
-                 p1++;
-                 p_temp = p1;
-                 while (*p_temp && *p_temp != ';')
-                   p_temp++;
+             event->stop_reason = TARGET_STOPPED_BY_SW_BREAKPOINT;
 
-                 event->ws.kind = TARGET_WAITKIND_LOADED;
-                 p = p_temp;
-               }
-             else if (strncmp (p, "replaylog", p1 - p) == 0)
-               {
-                 event->ws.kind = TARGET_WAITKIND_NO_HISTORY;
-                 /* p1 will indicate "begin" or "end", but it makes
-                    no difference for now, so ignore it.  */
-                 p_temp = strchr (p1 + 1, ';');
-                 if (p_temp)
-                   p = p_temp;
-               }
-             else if (strncmp (p, "core", p1 - p) == 0)
-               {
-                 ULONGEST c;
+             /* Make sure the stub doesn't forget to indicate support
+                with qSupported.  */
+             if (packet_support (PACKET_swbreak_feature) != PACKET_ENABLE)
+               error (_("Unexpected swbreak stop reason"));
 
-                 p = unpack_varlen_hex (++p1, &c);
-                 event->core = c;
-               }
-             else
-               {
-                 /* Silently skip unknown optional info.  */
-                 p_temp = strchr (p1 + 1, ';');
-                 if (p_temp)
-                   p = p_temp;
-               }
+             /* The value part is documented as "must be empty",
+                though we ignore it, in case we ever decide to make
+                use of it in a backward compatible way.  */
+             p = skip_to_semicolon (p1 + 1);
            }
-         else
+         else if (strncmp (p, "hwbreak", p1 - p) == 0)
            {
-             struct packet_reg *reg = packet_reg_from_pnum (rsa, pnum);
-             cached_reg_t cached_reg;
+             event->stop_reason = TARGET_STOPPED_BY_HW_BREAKPOINT;
 
-             p = p1;
+             /* Make sure the stub doesn't forget to indicate support
+                with qSupported.  */
+             if (packet_support (PACKET_hwbreak_feature) != PACKET_ENABLE)
+               error (_("Unexpected hwbreak stop reason"));
 
-             if (*p != ':')
-               error (_("Malformed packet(b) (missing colon): %s\n\
-Packet: '%s'\n"),
-                      p, buf);
-             ++p;
+             /* See above.  */
+             p = skip_to_semicolon (p1 + 1);
+           }
+         else if (strncmp (p, "library", p1 - p) == 0)
+           {
+             event->ws.kind = TARGET_WAITKIND_LOADED;
+             p = skip_to_semicolon (p1 + 1);
+           }
+         else if (strncmp (p, "replaylog", p1 - p) == 0)
+           {
+             event->ws.kind = TARGET_WAITKIND_NO_HISTORY;
+             /* p1 will indicate "begin" or "end", but it makes
+                no difference for now, so ignore it.  */
+             p = skip_to_semicolon (p1 + 1);
+           }
+         else if (strncmp (p, "core", p1 - p) == 0)
+           {
+             ULONGEST c;
+
+             p = unpack_varlen_hex (++p1, &c);
+             event->core = c;
+           }
+         else if (strncmp (p, "fork", p1 - p) == 0)
+           {
+             event->ws.value.related_pid = read_ptid (++p1, &p);
+             event->ws.kind = TARGET_WAITKIND_FORKED;
+           }
+         else if (strncmp (p, "vfork", p1 - p) == 0)
+           {
+             event->ws.value.related_pid = read_ptid (++p1, &p);
+             event->ws.kind = TARGET_WAITKIND_VFORKED;
+           }
+         else if (strncmp (p, "vforkdone", p1 - p) == 0)
+           {
+             event->ws.kind = TARGET_WAITKIND_VFORK_DONE;
+             p = skip_to_semicolon (p1 + 1);
+           }
+         else
+           {
+             ULONGEST pnum;
+             char *p_temp;
+
+             /* Maybe a real ``P'' register number.  */
+             p_temp = unpack_varlen_hex (p, &pnum);
+             /* If the first invalid character is the colon, we got a
+                register number.  Otherwise, it's an unknown stop
+                reason.  */
+             if (p_temp == p1)
+               {
+                 struct packet_reg *reg = packet_reg_from_pnum (rsa, pnum);
+                 cached_reg_t cached_reg;
 
-             if (reg == NULL)
-               error (_("Remote sent bad register number %s: %s\n\
+                 if (reg == NULL)
+                   error (_("Remote sent bad register number %s: %s\n\
 Packet: '%s'\n"),
-                      hex_string (pnum), p, buf);
+                          hex_string (pnum), p, buf);
 
-             cached_reg.num = reg->regnum;
+                 cached_reg.num = reg->regnum;
 
-             fieldsize = hex2bin (p, cached_reg.data,
-                                  register_size (target_gdbarch (),
-                                                 reg->regnum));
-             p += 2 * fieldsize;
-             if (fieldsize < register_size (target_gdbarch (),
-                                            reg->regnum))
-               warning (_("Remote reply is too short: %s"), buf);
+                 p = p1 + 1;
+                 fieldsize = hex2bin (p, cached_reg.data,
+                                      register_size (target_gdbarch (),
+                                                     reg->regnum));
+                 p += 2 * fieldsize;
+                 if (fieldsize < register_size (target_gdbarch (),
+                                                reg->regnum))
+                   warning (_("Remote reply is too short: %s"), buf);
 
-             VEC_safe_push (cached_reg_t, event->regcache, &cached_reg);
+                 VEC_safe_push (cached_reg_t, event->regcache, &cached_reg);
+               }
+             else
+               {
+                 /* Not a number.  Silently skip unknown optional
+                    info.  */
+                 p = skip_to_semicolon (p1 + 1);
+               }
            }
 
          if (*p != ';')
@@ -5665,10 +6008,9 @@ Packet: '%s'\n"),
          {
            p++;
 
-           if (p == '\0')
+           if (*p == '\0')
              ;
-           else if (strncmp (p,
-                             "process:", sizeof ("process:") - 1) == 0)
+           else if (startswith (p, "process:"))
              {
                ULONGEST upid;
 
@@ -5804,7 +6146,7 @@ process_stop_reply (struct stop_reply *stop_reply,
          VEC_free (cached_reg_t, stop_reply->regcache);
        }
 
-      rs->remote_stopped_by_watchpoint_p = stop_reply->stopped_by_watchpoint_p;
+      rs->stop_reason = stop_reply->stop_reason;
       rs->remote_watch_data_address = stop_reply->watch_data_address;
 
       remote_notice_new_inferior (ptid, 0);
@@ -5931,7 +6273,7 @@ remote_wait_as (ptid_t ptid, struct target_waitstatus *status, int options)
 
   buf = rs->buf;
 
-  rs->remote_stopped_by_watchpoint_p = 0;
+  rs->stop_reason = TARGET_STOPPED_BY_NO_REASON;
 
   /* We got something.  */
   rs->waiting_for_stop_reply = 0;
@@ -6586,51 +6928,74 @@ check_binary_download (CORE_ADDR addr)
     }
 }
 
+/* Helper function to resize the payload in order to try to get a good
+   alignment.  We try to write an amount of data such that the next write will
+   start on an address aligned on REMOTE_ALIGN_WRITES.  */
+
+static int
+align_for_efficient_write (int todo, CORE_ADDR memaddr)
+{
+  return ((memaddr + todo) & ~(REMOTE_ALIGN_WRITES - 1)) - memaddr;
+}
+
 /* Write memory data directly to the remote machine.
    This does not inform the data cache; the data cache uses this.
    HEADER is the starting part of the packet.
    MEMADDR is the address in the remote memory space.
    MYADDR is the address of the buffer in our space.
-   LEN is the number of bytes.
+   LEN_UNITS is the number of addressable units to write.
+   UNIT_SIZE is the length in bytes of an addressable unit.
    PACKET_FORMAT should be either 'X' or 'M', and indicates if we
    should send data as binary ('X'), or hex-encoded ('M').
 
    The function creates packet of the form
        <HEADER><ADDRESS>,<LENGTH>:<DATA>
 
-   where encoding of <DATA> is termined by PACKET_FORMAT.
+   where encoding of <DATA> is terminated by PACKET_FORMAT.
 
    If USE_LENGTH is 0, then the <LENGTH> field and the preceding comma
    are omitted.
 
    Return the transferred status, error or OK (an
-   'enum target_xfer_status' value).  Save the number of bytes
-   transferred in *XFERED_LEN.  Only transfer a single packet.  */
+   'enum target_xfer_status' value).  Save the number of addressable units
+   transferred in *XFERED_LEN_UNITS.  Only transfer a single packet.
+
+   On a platform with an addressable memory size of 2 bytes (UNIT_SIZE == 2), an
+   exchange between gdb and the stub could look like (?? in place of the
+   checksum):
+
+   -> $m1000,4#??
+   <- aaaabbbbccccdddd
+
+   -> $M1000,3:eeeeffffeeee#??
+   <- OK
+
+   -> $m1000,4#??
+   <- eeeeffffeeeedddd  */
 
 static enum target_xfer_status
 remote_write_bytes_aux (const char *header, CORE_ADDR memaddr,
-                       const gdb_byte *myaddr, ULONGEST len,
-                       ULONGEST *xfered_len, char packet_format,
-                       int use_length)
+                       const gdb_byte *myaddr, ULONGEST len_units,
+                       int unit_size, ULONGEST *xfered_len_units,
+                       char packet_format, int use_length)
 {
   struct remote_state *rs = get_remote_state ();
   char *p;
   char *plen = NULL;
   int plenlen = 0;
-  int todo;
-  int nr_bytes;
-  int payload_size;
-  int payload_length;
-  int header_length;
+  int todo_units;
+  int units_written;
+  int payload_capacity_bytes;
+  int payload_length_bytes;
 
   if (packet_format != 'X' && packet_format != 'M')
     internal_error (__FILE__, __LINE__,
                    _("remote_write_bytes_aux: bad packet format"));
 
-  if (len == 0)
+  if (len_units == 0)
     return TARGET_XFER_EOF;
 
-  payload_size = get_memory_write_packet_size ();
+  payload_capacity_bytes = get_memory_write_packet_size ();
 
   /* The packet buffer will be large enough for the payload;
      get_memory_packet_size ensures this.  */
@@ -6639,13 +7004,12 @@ remote_write_bytes_aux (const char *header, CORE_ADDR memaddr,
   /* Compute the size of the actual payload by subtracting out the
      packet header and footer overhead: "$M<memaddr>,<len>:...#nn".  */
 
-  payload_size -= strlen ("$,:#NN");
+  payload_capacity_bytes -= strlen ("$,:#NN");
   if (!use_length)
     /* The comma won't be used.  */
-    payload_size += 1;
-  header_length = strlen (header);
-  payload_size -= header_length;
-  payload_size -= hexnumlen (memaddr);
+    payload_capacity_bytes += 1;
+  payload_capacity_bytes -= strlen (header);
+  payload_capacity_bytes -= hexnumlen (memaddr);
 
   /* Construct the packet excluding the data: "<header><memaddr>,<len>:".  */
 
@@ -6656,28 +7020,28 @@ remote_write_bytes_aux (const char *header, CORE_ADDR memaddr,
   if (packet_format == 'X')
     {
       /* Best guess at number of bytes that will fit.  */
-      todo = min (len, payload_size);
+      todo_units = min (len_units, payload_capacity_bytes / unit_size);
       if (use_length)
-       payload_size -= hexnumlen (todo);
-      todo = min (todo, payload_size);
+       payload_capacity_bytes -= hexnumlen (todo_units);
+      todo_units = min (todo_units, payload_capacity_bytes / unit_size);
     }
   else
     {
-      /* Num bytes that will fit.  */
-      todo = min (len, payload_size / 2);
+      /* Number of bytes that will fit.  */
+      todo_units = min (len_units, (payload_capacity_bytes / unit_size) / 2);
       if (use_length)
-       payload_size -= hexnumlen (todo);
-      todo = min (todo, payload_size / 2);
+       payload_capacity_bytes -= hexnumlen (todo_units);
+      todo_units = min (todo_units, (payload_capacity_bytes / unit_size) / 2);
     }
 
-  if (todo <= 0)
+  if (todo_units <= 0)
     internal_error (__FILE__, __LINE__,
                    _("minimum packet size too small to write data"));
 
   /* If we already need another packet, then try to align the end
      of this packet to a useful boundary.  */
-  if (todo > 2 * REMOTE_ALIGN_WRITES && todo < len)
-    todo = ((memaddr + todo) & ~(REMOTE_ALIGN_WRITES - 1)) - memaddr;
+  if (todo_units > 2 * REMOTE_ALIGN_WRITES && todo_units < len_units)
+    todo_units = align_for_efficient_write (todo_units, memaddr);
 
   /* Append "<memaddr>".  */
   memaddr = remote_address_masked (memaddr);
@@ -6688,10 +7052,10 @@ remote_write_bytes_aux (const char *header, CORE_ADDR memaddr,
       /* Append ",".  */
       *p++ = ',';
 
-      /* Append <len>.  Retain the location/size of <len>.  It may need to
-        be adjusted once the packet body has been created.  */
+      /* Append the length and retain its location and size.  It may need to be
+         adjusted once the packet body has been created.  */
       plen = p;
-      plenlen = hexnumstr (p, (ULONGEST) todo);
+      plenlen = hexnumstr (p, (ULONGEST) todo_units);
       p += plenlen;
     }
 
@@ -6705,32 +7069,35 @@ remote_write_bytes_aux (const char *header, CORE_ADDR memaddr,
       /* Binary mode.  Send target system values byte by byte, in
         increasing byte addresses.  Only escape certain critical
         characters.  */
-      payload_length = remote_escape_output (myaddr, todo, (gdb_byte *) p,
-                                            &nr_bytes, payload_size);
+      payload_length_bytes =
+         remote_escape_output (myaddr, todo_units, unit_size, (gdb_byte *) p,
+                               &units_written, payload_capacity_bytes);
 
-      /* If not all TODO bytes fit, then we'll need another packet.  Make
+      /* If not all TODO units fit, then we'll need another packet.  Make
         a second try to keep the end of the packet aligned.  Don't do
         this if the packet is tiny.  */
-      if (nr_bytes < todo && nr_bytes > 2 * REMOTE_ALIGN_WRITES)
+      if (units_written < todo_units && units_written > 2 * REMOTE_ALIGN_WRITES)
        {
-         int new_nr_bytes;
-
-         new_nr_bytes = (((memaddr + nr_bytes) & ~(REMOTE_ALIGN_WRITES - 1))
-                         - memaddr);
-         if (new_nr_bytes != nr_bytes)
-           payload_length = remote_escape_output (myaddr, new_nr_bytes,
-                                                  (gdb_byte *) p, &nr_bytes,
-                                                  payload_size);
+         int new_todo_units;
+
+         new_todo_units = align_for_efficient_write (units_written, memaddr);
+
+         if (new_todo_units != units_written)
+           payload_length_bytes =
+               remote_escape_output (myaddr, new_todo_units, unit_size,
+                                     (gdb_byte *) p, &units_written,
+                                     payload_capacity_bytes);
        }
 
-      p += payload_length;
-      if (use_length && nr_bytes < todo)
+      p += payload_length_bytes;
+      if (use_length && units_written < todo_units)
        {
          /* Escape chars have filled up the buffer prematurely,
-            and we have actually sent fewer bytes than planned.
+            and we have actually sent fewer units than planned.
             Fix-up the length field of the packet.  Use the same
             number of characters as before.  */
-         plen += hexnumnstr (plen, (ULONGEST) nr_bytes, plenlen);
+         plen += hexnumnstr (plen, (ULONGEST) units_written,
+                             plenlen);
          *plen = ':';  /* overwrite \0 from hexnumnstr() */
        }
     }
@@ -6739,8 +7106,8 @@ remote_write_bytes_aux (const char *header, CORE_ADDR memaddr,
       /* Normal mode: Send target system values byte by byte, in
         increasing byte addresses.  Each byte is encoded as a two hex
         value.  */
-      nr_bytes = bin2hex (myaddr, p, todo);
-      p += 2 * nr_bytes;
+      p += 2 * bin2hex (myaddr, p, todo_units * unit_size);
+      units_written = todo_units;
     }
 
   putpkt_binary (rs->buf, (int) (p - rs->buf));
@@ -6749,9 +7116,9 @@ remote_write_bytes_aux (const char *header, CORE_ADDR memaddr,
   if (rs->buf[0] == 'E')
     return TARGET_XFER_E_IO;
 
-  /* Return NR_BYTES, not TODO, in case escape chars caused us to send
-     fewer bytes than we'd planned.  */
-  *xfered_len = (ULONGEST) nr_bytes;
+  /* 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;
 }
 
@@ -6767,7 +7134,7 @@ remote_write_bytes_aux (const char *header, CORE_ADDR memaddr,
 
 static enum target_xfer_status
 remote_write_bytes (CORE_ADDR memaddr, const gdb_byte *myaddr, ULONGEST len,
-                   ULONGEST *xfered_len)
+                   int unit_size, ULONGEST *xfered_len)
 {
   char *packet_format = 0;
 
@@ -6790,7 +7157,7 @@ remote_write_bytes (CORE_ADDR memaddr, const gdb_byte *myaddr, ULONGEST len,
     }
 
   return remote_write_bytes_aux (packet_format,
-                                memaddr, myaddr, len, xfered_len,
+                                memaddr, myaddr, len, unit_size, xfered_len,
                                 packet_format[0], 1);
 }
 
@@ -6798,28 +7165,32 @@ remote_write_bytes (CORE_ADDR memaddr, const gdb_byte *myaddr, ULONGEST len,
    This does not use the data cache; the data cache uses this.
    MEMADDR is the address in the remote memory space.
    MYADDR is the address of the buffer in our space.
-   LEN is the number of bytes.
+   LEN_UNITS is the number of addressable memory units to read..
+   UNIT_SIZE is the length in bytes of an addressable unit.
 
    Return the transferred status, error or OK (an
    'enum target_xfer_status' value).  Save the number of bytes
-   transferred in *XFERED_LEN.  */
+   transferred in *XFERED_LEN_UNITS.
+
+   See the comment of remote_write_bytes_aux for an example of
+   memory read/write exchange between gdb and the stub.  */
 
 static enum target_xfer_status
-remote_read_bytes_1 (CORE_ADDR memaddr, gdb_byte *myaddr, ULONGEST len,
-                    ULONGEST *xfered_len)
+remote_read_bytes_1 (CORE_ADDR memaddr, gdb_byte *myaddr, ULONGEST len_units,
+                    int unit_size, ULONGEST *xfered_len_units)
 {
   struct remote_state *rs = get_remote_state ();
-  int max_buf_size;            /* Max size of packet output buffer.  */
+  int buf_size_bytes;          /* Max size of packet output buffer.  */
   char *p;
-  int todo;
-  int i;
+  int todo_units;
+  int decoded_bytes;
 
-  max_buf_size = get_memory_read_packet_size ();
+  buf_size_bytes = get_memory_read_packet_size ();
   /* The packet buffer will be large enough for the payload;
      get_memory_packet_size ensures this.  */
 
-  /* Number if bytes that will fit.  */
-  todo = min (len, max_buf_size / 2);
+  /* Number of units that will fit.  */
+  todo_units = min (len_units, (buf_size_bytes / unit_size) / 2);
 
   /* Construct "m"<memaddr>","<len>".  */
   memaddr = remote_address_masked (memaddr);
@@ -6827,7 +7198,7 @@ remote_read_bytes_1 (CORE_ADDR memaddr, gdb_byte *myaddr, ULONGEST len,
   *p++ = 'm';
   p += hexnumstr (p, (ULONGEST) memaddr);
   *p++ = ',';
-  p += hexnumstr (p, (ULONGEST) todo);
+  p += hexnumstr (p, (ULONGEST) todo_units);
   *p = '\0';
   putpkt (rs->buf);
   getpkt (&rs->buf, &rs->buf_size, 0);
@@ -6838,9 +7209,9 @@ remote_read_bytes_1 (CORE_ADDR memaddr, gdb_byte *myaddr, ULONGEST len,
   /* Reply describes memory byte by byte, each byte encoded as two hex
      characters.  */
   p = rs->buf;
-  i = hex2bin (p, myaddr, todo);
+  decoded_bytes = hex2bin (p, myaddr, todo_units * unit_size);
   /* Return what we have.  Let higher layers handle partial reads.  */
-  *xfered_len = (ULONGEST) i;
+  *xfered_len_units = (ULONGEST) (decoded_bytes / unit_size);
   return TARGET_XFER_OK;
 }
 
@@ -6853,7 +7224,7 @@ remote_read_bytes_1 (CORE_ADDR memaddr, gdb_byte *myaddr, ULONGEST len,
 static enum target_xfer_status
 remote_xfer_live_readonly_partial (struct target_ops *ops, gdb_byte *readbuf,
                                   ULONGEST memaddr, ULONGEST len,
-                                  ULONGEST *xfered_len)
+                                  int unit_size, ULONGEST *xfered_len)
 {
   struct target_section *secp;
   struct target_section_table *table;
@@ -6876,7 +7247,7 @@ remote_xfer_live_readonly_partial (struct target_ops *ops, gdb_byte *readbuf,
              if (memend <= p->endaddr)
                {
                  /* Entire transfer is within this section.  */
-                 return remote_read_bytes_1 (memaddr, readbuf, len,
+                 return remote_read_bytes_1 (memaddr, readbuf, len, unit_size,
                                              xfered_len);
                }
              else if (memaddr >= p->endaddr)
@@ -6888,7 +7259,7 @@ remote_xfer_live_readonly_partial (struct target_ops *ops, gdb_byte *readbuf,
                {
                  /* This section overlaps the transfer.  Just do half.  */
                  len = p->endaddr - memaddr;
-                 return remote_read_bytes_1 (memaddr, readbuf, len,
+                 return remote_read_bytes_1 (memaddr, readbuf, len, unit_size,
                                              xfered_len);
                }
            }
@@ -6904,7 +7275,8 @@ remote_xfer_live_readonly_partial (struct target_ops *ops, gdb_byte *readbuf,
 
 static enum target_xfer_status
 remote_read_bytes (struct target_ops *ops, CORE_ADDR memaddr,
-                  gdb_byte *myaddr, ULONGEST len, ULONGEST *xfered_len)
+                  gdb_byte *myaddr, ULONGEST len, int unit_size,
+                  ULONGEST *xfered_len)
 {
   if (len == 0)
     return TARGET_XFER_EOF;
@@ -6942,7 +7314,7 @@ remote_read_bytes (struct target_ops *ops, CORE_ADDR memaddr,
 
              /* This goes through the topmost target again.  */
              res = remote_xfer_live_readonly_partial (ops, myaddr, memaddr,
-                                                      len, xfered_len);
+                                                      len, unit_size, xfered_len);
              if (res == TARGET_XFER_OK)
                return TARGET_XFER_OK;
              else
@@ -6964,7 +7336,7 @@ remote_read_bytes (struct target_ops *ops, CORE_ADDR memaddr,
        }
     }
 
-  return remote_read_bytes_1 (memaddr, myaddr, len, xfered_len);
+  return remote_read_bytes_1 (memaddr, myaddr, len, unit_size, xfered_len);
 }
 
 \f
@@ -6973,6 +7345,9 @@ remote_read_bytes (struct target_ops *ops, CORE_ADDR memaddr,
    FORMAT and the remaining arguments, then gets the reply.  Returns
    whether the packet was a success, a failure, or unknown.  */
 
+static enum packet_result remote_send_printf (const char *format, ...)
+  ATTRIBUTE_PRINTF (1, 2);
+
 static enum packet_result
 remote_send_printf (const char *format, ...)
 {
@@ -7047,7 +7422,7 @@ remote_flash_write (struct target_ops *ops, ULONGEST address,
                                          &saved_remote_timeout);
 
   remote_timeout = remote_flash_timeout;
-  ret = remote_write_bytes_aux ("vFlashWrite:", address, data, length,
+  ret = remote_write_bytes_aux ("vFlashWrite:", address, data, length, 1,
                                xfered_len,'X', 0);
   do_cleanups (back_to);
 
@@ -7762,19 +8137,81 @@ getpkt_or_notif_sane (char **buf, long *sizeof_buf, int forever,
                                 is_notif);
 }
 
+/* Check whether EVENT is a fork event for the process specified
+   by the pid passed in DATA, and if it is, kill the fork child.  */
+
+static int
+kill_child_of_pending_fork (QUEUE (stop_reply_p) *q,
+                           QUEUE_ITER (stop_reply_p) *iter,
+                           stop_reply_p event,
+                           void *data)
+{
+  struct queue_iter_param *param = data;
+  int parent_pid = *(int *) param->input;
+
+  if (is_pending_fork_parent (&event->ws, parent_pid, event->ptid))
+    {
+      struct remote_state *rs = get_remote_state ();
+      int child_pid = ptid_get_pid (event->ws.value.related_pid);
+      int res;
+
+      res = remote_vkill (child_pid, rs);
+      if (res != 0)
+       error (_("Can't kill fork child process %d"), child_pid);
+    }
+
+  return 1;
+}
+
+/* Kill any new fork children of process PID that haven't been
+   processed by follow_fork.  */
+
+static void
+kill_new_fork_children (int pid, struct remote_state *rs)
+{
+  struct thread_info *thread;
+  struct notif_client *notif = &notif_client_stop;
+  struct queue_iter_param param;
+
+  /* Kill the fork child threads of any threads in process PID
+     that are stopped at a fork event.  */
+  ALL_NON_EXITED_THREADS (thread)
+    {
+      struct target_waitstatus *ws = &thread->pending_follow;
+
+      if (is_pending_fork_parent (ws, pid, thread->ptid))
+       {
+         struct remote_state *rs = get_remote_state ();
+         int child_pid = ptid_get_pid (ws->value.related_pid);
+         int res;
+
+         res = remote_vkill (child_pid, rs);
+         if (res != 0)
+           error (_("Can't kill fork child process %d"), child_pid);
+       }
+    }
+
+  /* Check for any pending fork events (not reported or processed yet)
+     in process PID and kill those fork child threads as well.  */
+  remote_notif_get_pending_events (notif);
+  param.input = &pid;
+  param.output = NULL;
+  QUEUE_iterate (stop_reply_p, stop_reply_queue,
+                kill_child_of_pending_fork, &param);
+}
+
 \f
 static void
 remote_kill (struct target_ops *ops)
 {
-  volatile struct gdb_exception ex;
 
   /* Catch errors so the user can quit from gdb even when we
      aren't on speaking terms with the remote system.  */
-  TRY_CATCH (ex, RETURN_MASK_ERROR)
+  TRY
     {
       putpkt ("k");
     }
-  if (ex.reason < 0)
+  CATCH (ex, RETURN_MASK_ERROR)
     {
       if (ex.error == TARGET_CLOSE_ERROR)
        {
@@ -7792,6 +8229,7 @@ remote_kill (struct target_ops *ops)
           user or higher layers decide what to do.  */
        throw_exception (ex);
     }
+  END_CATCH
 
   /* We've killed the remote end, we get to mourn it.  Since this is
      target remote, single-process, mourning the inferior also
@@ -7831,6 +8269,11 @@ extended_remote_kill (struct target_ops *ops)
   int pid = ptid_get_pid (inferior_ptid);
   struct remote_state *rs = get_remote_state ();
 
+  /* If we're stopped while forking and we haven't followed yet, kill the
+     child task.  We need to do this before killing the parent task
+     because if this is a vfork then the parent will be sleeping.  */
+  kill_new_fork_children (pid, rs);
+
   res = remote_vkill (pid, rs);
   if (res == -1 && !(rs->extended && remote_multi_process_p (rs)))
     {
@@ -7856,14 +8299,7 @@ extended_remote_kill (struct target_ops *ops)
 }
 
 static void
-remote_mourn (struct target_ops *ops)
-{
-  remote_mourn_1 (ops);
-}
-
-/* Worker function for remote_mourn.  */
-static void
-remote_mourn_1 (struct target_ops *target)
+remote_mourn (struct target_ops *target)
 {
   unpush_target (target);
 
@@ -7872,7 +8308,7 @@ remote_mourn_1 (struct target_ops *target)
 }
 
 static void
-extended_remote_mourn_1 (struct target_ops *target)
+extended_remote_mourn (struct target_ops *target)
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -7932,12 +8368,6 @@ extended_remote_mourn_1 (struct target_ops *target)
     }
 }
 
-static void
-extended_remote_mourn (struct target_ops *ops)
-{
-  extended_remote_mourn_1 (ops);
-}
-
 static int
 extended_remote_supports_disable_randomization (struct target_ops *self)
 {
@@ -8041,7 +8471,7 @@ extended_remote_create_inferior (struct target_ops *ops,
   /* If running asynchronously, register the target file descriptor
      with the event loop.  */
   if (target_can_async_p ())
-    target_async (inferior_event_handler, 0);
+    target_async (1);
 
   /* Disable address space randomization if requested (and supported).  */
   if (extended_remote_supports_disable_randomization (ops))
@@ -8405,12 +8835,54 @@ remote_check_watch_resources (struct target_ops *self,
   return -1;
 }
 
+/* The to_stopped_by_sw_breakpoint method of target remote.  */
+
+static int
+remote_stopped_by_sw_breakpoint (struct target_ops *ops)
+{
+  struct remote_state *rs = get_remote_state ();
+
+  return rs->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT;
+}
+
+/* The to_supports_stopped_by_sw_breakpoint method of target
+   remote.  */
+
+static int
+remote_supports_stopped_by_sw_breakpoint (struct target_ops *ops)
+{
+  struct remote_state *rs = get_remote_state ();
+
+  return (packet_support (PACKET_swbreak_feature) == PACKET_ENABLE);
+}
+
+/* The to_stopped_by_hw_breakpoint method of target remote.  */
+
+static int
+remote_stopped_by_hw_breakpoint (struct target_ops *ops)
+{
+  struct remote_state *rs = get_remote_state ();
+
+  return rs->stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT;
+}
+
+/* The to_supports_stopped_by_hw_breakpoint method of target
+   remote.  */
+
+static int
+remote_supports_stopped_by_hw_breakpoint (struct target_ops *ops)
+{
+  struct remote_state *rs = get_remote_state ();
+
+  return (packet_support (PACKET_hwbreak_feature) == PACKET_ENABLE);
+}
+
 static int
 remote_stopped_by_watchpoint (struct target_ops *ops)
 {
   struct remote_state *rs = get_remote_state ();
 
-  return rs->remote_stopped_by_watchpoint_p;
+  return rs->stop_reason == TARGET_STOPPED_BY_WATCHPOINT;
 }
 
 static int
@@ -8690,7 +9162,7 @@ remote_write_qxfer (struct target_ops *ops, const char *object_name,
 
   /* Escape as much data as fits into rs->buf.  */
   buf_len = remote_escape_output 
-    (writebuf, len, (gdb_byte *) rs->buf + i, &max_size, max_size);
+    (writebuf, len, 1, (gdb_byte *) rs->buf + i, &max_size, max_size);
 
   if (putpkt_binary (rs->buf, i + buf_len) < 0
       || getpkt_sane (&rs->buf, &rs->buf_size, 0) < 0
@@ -8801,6 +9273,7 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
   int i;
   char *p2;
   char query_type;
+  int unit_size = gdbarch_addressable_memory_unit_size (target_gdbarch ());
 
   set_remote_traceframe ();
   set_general_thread (inferior_ptid);
@@ -8817,9 +9290,11 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
        return TARGET_XFER_EOF;
 
       if (writebuf != NULL)
-       return remote_write_bytes (offset, writebuf, len, xfered_len);
+       return remote_write_bytes (offset, writebuf, len, unit_size,
+                                  xfered_len);
       else
-       return remote_read_bytes (ops, offset, readbuf, len, xfered_len);
+       return remote_read_bytes (ops, offset, readbuf, len, unit_size,
+                                 xfered_len);
     }
 
   /* Handle SPU memory using qxfer packets.  */
@@ -8945,6 +9420,16 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
                                xfered_len,
         &remote_protocol_packets[PACKET_qXfer_btrace]);
 
+    case TARGET_OBJECT_BTRACE_CONF:
+      return remote_read_qxfer (ops, "btrace-conf", annex, readbuf, offset,
+                               len, xfered_len,
+       &remote_protocol_packets[PACKET_qXfer_btrace_conf]);
+
+    case TARGET_OBJECT_EXEC_FILE:
+      return remote_read_qxfer (ops, "exec-file", annex, readbuf, offset,
+                               len, xfered_len,
+       &remote_protocol_packets[PACKET_qXfer_exec_file]);
+
     default:
       return TARGET_XFER_E_IO;
     }
@@ -9047,7 +9532,7 @@ remote_search_memory (struct target_ops* ops,
 
   /* Escape as much data as fits into rs->buf.  */
   escaped_pattern_len =
-    remote_escape_output (pattern, pattern_len, (gdb_byte *) rs->buf + i,
+    remote_escape_output (pattern, pattern_len, 1, (gdb_byte *) rs->buf + i,
                          &used_pattern_len, max_size);
 
   /* Bail if the pattern is too large.  */
@@ -9379,8 +9864,11 @@ remote_pid_to_str (struct target_ops *ops, ptid_t ptid)
       if (ptid_equal (magic_null_ptid, ptid))
        xsnprintf (buf, sizeof buf, "Thread <main>");
       else if (rs->extended && remote_multi_process_p (rs))
-       xsnprintf (buf, sizeof buf, "Thread %d.%ld",
-                  ptid_get_pid (ptid), ptid_get_lwp (ptid));
+       if (ptid_get_lwp (ptid) == 0)
+         return normal_pid_to_str (ptid);
+       else
+         xsnprintf (buf, sizeof buf, "Thread %d.%ld",
+                    ptid_get_pid (ptid), ptid_get_lwp (ptid));
       else
        xsnprintf (buf, sizeof buf, "Thread %ld",
                   ptid_get_lwp (ptid));
@@ -9773,19 +10261,57 @@ remote_hostio_send_command (int command_bytes, int which_packet,
   return ret;
 }
 
-/* Open FILENAME on the remote target, using FLAGS and MODE.  Return a
-   remote file descriptor, or -1 if an error occurs (and set
-   *REMOTE_ERRNO).  */
+/* Set the filesystem remote_hostio functions that take FILENAME
+   arguments will use.  Return 0 on success, or -1 if an error
+   occurs (and set *REMOTE_ERRNO).  */
+
+static int
+remote_hostio_set_filesystem (struct inferior *inf, int *remote_errno)
+{
+  struct remote_state *rs = get_remote_state ();
+  int required_pid = (inf == NULL || inf->fake_pid_p) ? 0 : inf->pid;
+  char *p = rs->buf;
+  int left = get_remote_packet_size () - 1;
+  char arg[9];
+  int ret;
+
+  if (packet_support (PACKET_vFile_setfs) == PACKET_DISABLE)
+    return 0;
+
+  if (rs->fs_pid != -1 && required_pid == rs->fs_pid)
+    return 0;
+
+  remote_buffer_add_string (&p, &left, "vFile:setfs:");
+
+  xsnprintf (arg, sizeof (arg), "%x", required_pid);
+  remote_buffer_add_string (&p, &left, arg);
+
+  ret = remote_hostio_send_command (p - rs->buf, PACKET_vFile_setfs,
+                                   remote_errno, NULL, NULL);
+
+  if (packet_support (PACKET_vFile_setfs) == PACKET_DISABLE)
+    return 0;
+
+  if (ret == 0)
+    rs->fs_pid = required_pid;
+
+  return ret;
+}
+
+/* Implementation of to_fileio_open.  */
 
 static int
 remote_hostio_open (struct target_ops *self,
-                   const char *filename, int flags, int mode,
-                   int *remote_errno)
+                   struct inferior *inf, const char *filename,
+                   int flags, int mode, int *remote_errno)
 {
   struct remote_state *rs = get_remote_state ();
   char *p = rs->buf;
   int left = get_remote_packet_size () - 1;
 
+  if (remote_hostio_set_filesystem (inf, remote_errno) != 0)
+    return -1;
+
   remote_buffer_add_string (&p, &left, "vFile:open:");
 
   remote_buffer_add_bytes (&p, &left, (const gdb_byte *) filename,
@@ -9801,9 +10327,7 @@ remote_hostio_open (struct target_ops *self,
                                     remote_errno, NULL, NULL);
 }
 
-/* Write up to LEN bytes from WRITE_BUF to FD on the remote target.
-   Return the number of bytes written, or -1 if an error occurs (and
-   set *REMOTE_ERRNO).  */
+/* Implementation of to_fileio_pwrite.  */
 
 static int
 remote_hostio_pwrite (struct target_ops *self,
@@ -9823,16 +10347,14 @@ remote_hostio_pwrite (struct target_ops *self,
   remote_buffer_add_int (&p, &left, offset);
   remote_buffer_add_string (&p, &left, ",");
 
-  p += remote_escape_output (write_buf, len, (gdb_byte *) p, &out_len,
+  p += remote_escape_output (write_buf, len, 1, (gdb_byte *) p, &out_len,
                             get_remote_packet_size () - (p - rs->buf));
 
   return remote_hostio_send_command (p - rs->buf, PACKET_vFile_pwrite,
                                     remote_errno, NULL, NULL);
 }
 
-/* Read up to LEN bytes FD on the remote target into READ_BUF
-   Return the number of bytes read, or -1 if an error occurs (and
-   set *REMOTE_ERRNO).  */
+/* Implementation of to_fileio_pread.  */
 
 static int
 remote_hostio_pread (struct target_ops *self,
@@ -9871,8 +10393,7 @@ remote_hostio_pread (struct target_ops *self,
   return ret;
 }
 
-/* Close FD on the remote target.  Return 0, or -1 if an error occurs
-   (and set *REMOTE_ERRNO).  */
+/* Implementation of to_fileio_close.  */
 
 static int
 remote_hostio_close (struct target_ops *self, int fd, int *remote_errno)
@@ -9889,17 +10410,20 @@ remote_hostio_close (struct target_ops *self, int fd, int *remote_errno)
                                     remote_errno, NULL, NULL);
 }
 
-/* Unlink FILENAME on the remote target.  Return 0, or -1 if an error
-   occurs (and set *REMOTE_ERRNO).  */
+/* Implementation of to_fileio_unlink.  */
 
 static int
 remote_hostio_unlink (struct target_ops *self,
-                     const char *filename, int *remote_errno)
+                     struct inferior *inf, const char *filename,
+                     int *remote_errno)
 {
   struct remote_state *rs = get_remote_state ();
   char *p = rs->buf;
   int left = get_remote_packet_size () - 1;
 
+  if (remote_hostio_set_filesystem (inf, remote_errno) != 0)
+    return -1;
+
   remote_buffer_add_string (&p, &left, "vFile:unlink:");
 
   remote_buffer_add_bytes (&p, &left, (const gdb_byte *) filename,
@@ -9909,13 +10433,12 @@ remote_hostio_unlink (struct target_ops *self,
                                     remote_errno, NULL, NULL);
 }
 
-/* Read value of symbolic link FILENAME on the remote target.  Return
-   a null-terminated string allocated via xmalloc, or NULL if an error
-   occurs (and set *REMOTE_ERRNO).  */
+/* Implementation of to_fileio_readlink.  */
 
 static char *
 remote_hostio_readlink (struct target_ops *self,
-                       const char *filename, int *remote_errno)
+                       struct inferior *inf, const char *filename,
+                       int *remote_errno)
 {
   struct remote_state *rs = get_remote_state ();
   char *p = rs->buf;
@@ -9925,6 +10448,9 @@ remote_hostio_readlink (struct target_ops *self,
   int read_len;
   char *ret;
 
+  if (remote_hostio_set_filesystem (inf, remote_errno) != 0)
+    return NULL;
+
   remote_buffer_add_string (&p, &left, "vFile:readlink:");
 
   remote_buffer_add_bytes (&p, &left, (const gdb_byte *) filename,
@@ -9948,6 +10474,117 @@ remote_hostio_readlink (struct target_ops *self,
   return ret;
 }
 
+/* Implementation of to_fileio_fstat.  */
+
+static int
+remote_hostio_fstat (struct target_ops *self,
+                    int fd, struct stat *st,
+                    int *remote_errno)
+{
+  struct remote_state *rs = get_remote_state ();
+  char *p = rs->buf;
+  int left = get_remote_packet_size ();
+  int attachment_len, ret;
+  char *attachment;
+  struct fio_stat fst;
+  int read_len;
+
+  remote_buffer_add_string (&p, &left, "vFile:fstat:");
+
+  remote_buffer_add_int (&p, &left, fd);
+
+  ret = remote_hostio_send_command (p - rs->buf, PACKET_vFile_fstat,
+                                   remote_errno, &attachment,
+                                   &attachment_len);
+  if (ret < 0)
+    {
+      if (*remote_errno != FILEIO_ENOSYS)
+       return ret;
+
+      /* Strictly we should return -1, ENOSYS here, but when
+        "set sysroot remote:" was implemented in August 2008
+        BFD's need for a stat function was sidestepped with
+        this hack.  This was not remedied until March 2015
+        so we retain the previous behavior to avoid breaking
+        compatibility.
+
+        Note that the memset is a March 2015 addition; older
+        GDBs set st_size *and nothing else* so the structure
+        would have garbage in all other fields.  This might
+        break something but retaining the previous behavior
+        here would be just too wrong.  */
+
+      memset (st, 0, sizeof (struct stat));
+      st->st_size = INT_MAX;
+      return 0;
+    }
+
+  read_len = remote_unescape_input ((gdb_byte *) attachment, attachment_len,
+                                   (gdb_byte *) &fst, sizeof (fst));
+
+  if (read_len != ret)
+    error (_("vFile:fstat returned %d, but %d bytes."), ret, read_len);
+
+  if (read_len != sizeof (fst))
+    error (_("vFile:fstat returned %d bytes, but expecting %d."),
+          read_len, (int) sizeof (fst));
+
+  remote_fileio_to_host_stat (&fst, st);
+
+  return 0;
+}
+
+/* Implementation of to_filesystem_is_local.  */
+
+static int
+remote_filesystem_is_local (struct target_ops *self)
+{
+  /* Valgrind GDB presents itself as a remote target but works
+     on the local filesystem: it does not implement remote get
+     and users are not expected to set a sysroot.  To handle
+     this case we treat the remote filesystem as local if the
+     sysroot is exactly TARGET_SYSROOT_PREFIX and if the stub
+     does not support vFile:open.  */
+  if (strcmp (gdb_sysroot, TARGET_SYSROOT_PREFIX) == 0)
+    {
+      enum packet_support ps = packet_support (PACKET_vFile_open);
+
+      if (ps == PACKET_SUPPORT_UNKNOWN)
+       {
+         int fd, remote_errno;
+
+         /* Try opening a file to probe support.  The supplied
+            filename is irrelevant, we only care about whether
+            the stub recognizes the packet or not.  */
+         fd = remote_hostio_open (self, NULL, "just probing",
+                                  FILEIO_O_RDONLY, 0700,
+                                  &remote_errno);
+
+         if (fd >= 0)
+           remote_hostio_close (self, fd, &remote_errno);
+
+         ps = packet_support (PACKET_vFile_open);
+       }
+
+      if (ps == PACKET_DISABLE)
+       {
+         static int warning_issued = 0;
+
+         if (!warning_issued)
+           {
+             warning (_("remote target does not support file"
+                        " transfer, attempting to access files"
+                        " from local filesystem."));
+             warning_issued = 1;
+           }
+
+         return 1;
+       }
+    }
+
+  return 0;
+}
+
 static int
 remote_fileio_errno_to_host (int errnum)
 {
@@ -10019,104 +10656,6 @@ remote_hostio_close_cleanup (void *opaque)
   remote_hostio_close (find_target_at (process_stratum), fd, &remote_errno);
 }
 
-
-static void *
-remote_bfd_iovec_open (struct bfd *abfd, void *open_closure)
-{
-  const char *filename = bfd_get_filename (abfd);
-  int fd, remote_errno;
-  int *stream;
-
-  gdb_assert (remote_filename_p (filename));
-
-  fd = remote_hostio_open (find_target_at (process_stratum),
-                          filename + 7, FILEIO_O_RDONLY, 0, &remote_errno);
-  if (fd == -1)
-    {
-      errno = remote_fileio_errno_to_host (remote_errno);
-      bfd_set_error (bfd_error_system_call);
-      return NULL;
-    }
-
-  stream = xmalloc (sizeof (int));
-  *stream = fd;
-  return stream;
-}
-
-static int
-remote_bfd_iovec_close (struct bfd *abfd, void *stream)
-{
-  int fd = *(int *)stream;
-  int remote_errno;
-
-  xfree (stream);
-
-  /* Ignore errors on close; these may happen if the remote
-     connection was already torn down.  */
-  remote_hostio_close (find_target_at (process_stratum), fd, &remote_errno);
-
-  /* Zero means success.  */
-  return 0;
-}
-
-static file_ptr
-remote_bfd_iovec_pread (struct bfd *abfd, void *stream, void *buf,
-                       file_ptr nbytes, file_ptr offset)
-{
-  int fd = *(int *)stream;
-  int remote_errno;
-  file_ptr pos, bytes;
-
-  pos = 0;
-  while (nbytes > pos)
-    {
-      bytes = remote_hostio_pread (find_target_at (process_stratum),
-                                  fd, (gdb_byte *) buf + pos, nbytes - pos,
-                                  offset + pos, &remote_errno);
-      if (bytes == 0)
-        /* Success, but no bytes, means end-of-file.  */
-        break;
-      if (bytes == -1)
-       {
-         errno = remote_fileio_errno_to_host (remote_errno);
-         bfd_set_error (bfd_error_system_call);
-         return -1;
-       }
-
-      pos += bytes;
-    }
-
-  return pos;
-}
-
-static int
-remote_bfd_iovec_stat (struct bfd *abfd, void *stream, struct stat *sb)
-{
-  /* FIXME: We should probably implement remote_hostio_stat.  */
-  sb->st_size = INT_MAX;
-  return 0;
-}
-
-int
-remote_filename_p (const char *filename)
-{
-  return strncmp (filename,
-                 REMOTE_SYSROOT_PREFIX,
-                 sizeof (REMOTE_SYSROOT_PREFIX) - 1) == 0;
-}
-
-bfd *
-remote_bfd_open (const char *remote_file, const char *target)
-{
-  bfd *abfd = gdb_bfd_openr_iovec (remote_file, target,
-                                  remote_bfd_iovec_open, NULL,
-                                  remote_bfd_iovec_pread,
-                                  remote_bfd_iovec_close,
-                                  remote_bfd_iovec_stat);
-
-  return abfd;
-}
-
 void
 remote_file_put (const char *local_file, const char *remote_file, int from_tty)
 {
@@ -10137,7 +10676,7 @@ remote_file_put (const char *local_file, const char *remote_file, int from_tty)
     perror_with_name (local_file);
   back_to = make_cleanup_fclose (file);
 
-  fd = remote_hostio_open (find_target_at (process_stratum),
+  fd = remote_hostio_open (find_target_at (process_stratum), NULL,
                           remote_file, (FILEIO_O_WRONLY | FILEIO_O_CREAT
                                         | FILEIO_O_TRUNC),
                           0700, &remote_errno);
@@ -10223,7 +10762,7 @@ remote_file_get (const char *remote_file, const char *local_file, int from_tty)
   if (!rs->remote_desc)
     error (_("command can only be used with remote target"));
 
-  fd = remote_hostio_open (find_target_at (process_stratum),
+  fd = remote_hostio_open (find_target_at (process_stratum), NULL,
                           remote_file, FILEIO_O_RDONLY, 0, &remote_errno);
   if (fd == -1)
     remote_hostio_error (remote_errno);
@@ -10278,7 +10817,7 @@ remote_file_delete (const char *remote_file, int from_tty)
     error (_("command can only be used with remote target"));
 
   retcode = remote_hostio_unlink (find_target_at (process_stratum),
-                                 remote_file, &remote_errno);
+                                 NULL, remote_file, &remote_errno);
   if (retcode == -1)
     remote_hostio_error (remote_errno);
 
@@ -10834,7 +11373,6 @@ remote_get_trace_status (struct target_ops *self, struct trace_status *ts)
   char *p = NULL;
   /* FIXME we need to get register block size some other way.  */
   extern int trace_regblock_size;
-  volatile struct gdb_exception ex;
   enum packet_result result;
 
   if (packet_support (PACKET_qTStatus) == PACKET_DISABLE)
@@ -10844,11 +11382,11 @@ remote_get_trace_status (struct target_ops *self, struct trace_status *ts)
 
   putpkt ("qTStatus");
 
-  TRY_CATCH (ex, RETURN_MASK_ERROR)
+  TRY
     {
       p = remote_get_noisy_reply (&target_buf, &target_buf_size);
     }
-  if (ex.reason < 0)
+  CATCH (ex, RETURN_MASK_ERROR)
     {
       if (ex.error != TARGET_CLOSE_ERROR)
        {
@@ -10857,6 +11395,7 @@ remote_get_trace_status (struct target_ops *self, struct trace_status *ts)
        }
       throw_exception (ex);
     }
+  END_CATCH
 
   result = packet_ok (p, &remote_protocol_packets[PACKET_qTStatus]);
 
@@ -11135,8 +11674,8 @@ remote_core_of_thread (struct target_ops *ops, ptid_t ptid)
 {
   struct thread_info *info = find_thread_ptid (ptid);
 
-  if (info && info->private)
-    return info->private->core;
+  if (info && info->priv)
+    return info->priv->core;
   return -1;
 }
 
@@ -11319,37 +11858,158 @@ struct btrace_target_info
 {
   /* The ptid of the traced thread.  */
   ptid_t ptid;
+
+  /* The obtained branch trace configuration.  */
+  struct btrace_config conf;
 };
 
+/* Reset our idea of our target's btrace configuration.  */
+
+static void
+remote_btrace_reset (void)
+{
+  struct remote_state *rs = get_remote_state ();
+
+  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)
+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_Qbtrace_bts) != PACKET_ENABLE)
-    return 0;
   if (packet_support (PACKET_qXfer_btrace) != PACKET_ENABLE)
     return 0;
 
-  return 1;
+  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
+btrace_sync_conf (const struct btrace_config *conf)
+{
+  struct packet_config *packet;
+  struct remote_state *rs;
+  char *buf, *pos, *endbuf;
+
+  rs = get_remote_state ();
+  buf = rs->buf;
+  endbuf = buf + get_remote_packet_size ();
+
+  packet = &remote_protocol_packets[PACKET_Qbtrace_conf_bts_size];
+  if (packet_config_support (packet) == PACKET_ENABLE
+      && conf->bts.size != rs->btrace_config.bts.size)
+    {
+      pos = buf;
+      pos += xsnprintf (pos, endbuf - pos, "%s=0x%x", packet->name,
+                        conf->bts.size);
+
+      putpkt (buf);
+      getpkt (&buf, &rs->buf_size, 0);
+
+      if (packet_ok (buf, packet) == PACKET_ERROR)
+       {
+         if (buf[0] == 'E' && buf[1] == '.')
+           error (_("Failed to configure the BTS buffer size: %s"), buf + 2);
+         else
+           error (_("Failed to configure the BTS buffer size."));
+       }
+
+      rs->btrace_config.bts.size = conf->bts.size;
+    }
+
+  packet = &remote_protocol_packets[PACKET_Qbtrace_conf_pt_size];
+  if (packet_config_support (packet) == PACKET_ENABLE
+      && conf->pt.size != rs->btrace_config.pt.size)
+    {
+      pos = buf;
+      pos += xsnprintf (pos, endbuf - pos, "%s=0x%x", packet->name,
+                        conf->pt.size);
+
+      putpkt (buf);
+      getpkt (&buf, &rs->buf_size, 0);
+
+      if (packet_ok (buf, packet) == PACKET_ERROR)
+       {
+         if (buf[0] == 'E' && buf[1] == '.')
+           error (_("Failed to configure the trace buffer size: %s"), buf + 2);
+         else
+           error (_("Failed to configure the trace buffer size."));
+       }
+
+      rs->btrace_config.pt.size = conf->pt.size;
+    }
+}
+
+/* Read the current thread's btrace configuration from the target and
+   store it into CONF.  */
+
+static void
+btrace_read_config (struct btrace_config *conf)
+{
+  char *xml;
+
+  xml = target_read_stralloc (&current_target,
+                             TARGET_OBJECT_BTRACE_CONF, "");
+  if (xml != NULL)
+    {
+      struct cleanup *cleanup;
+
+      cleanup = make_cleanup (xfree, xml);
+      parse_xml_btrace_conf (conf, xml);
+      do_cleanups (cleanup);
+    }
 }
 
 /* Enable branch tracing.  */
 
 static struct btrace_target_info *
-remote_enable_btrace (struct target_ops *self, ptid_t ptid)
+remote_enable_btrace (struct target_ops *self, ptid_t ptid,
+                     const struct btrace_config *conf)
 {
   struct btrace_target_info *tinfo = NULL;
-  struct packet_config *packet = &remote_protocol_packets[PACKET_Qbtrace_bts];
+  struct packet_config *packet = NULL;
   struct remote_state *rs = get_remote_state ();
   char *buf = rs->buf;
   char *endbuf = rs->buf + get_remote_packet_size ();
 
-  if (packet_config_support (packet) != PACKET_ENABLE)
+  switch (conf->format)
+    {
+      case BTRACE_FORMAT_BTS:
+       packet = &remote_protocol_packets[PACKET_Qbtrace_bts];
+       break;
+
+      case BTRACE_FORMAT_PT:
+       packet = &remote_protocol_packets[PACKET_Qbtrace_pt];
+       break;
+    }
+
+  if (packet == NULL || packet_config_support (packet) != PACKET_ENABLE)
     error (_("Target does not support branch tracing."));
 
+  btrace_sync_conf (conf);
+
   set_general_thread (ptid);
 
   buf += xsnprintf (buf, endbuf - buf, "%s", packet->name);
@@ -11369,6 +12029,19 @@ remote_enable_btrace (struct target_ops *self, ptid_t ptid)
   tinfo = xzalloc (sizeof (*tinfo));
   tinfo->ptid = ptid;
 
+  /* If we fail to read the configuration, we lose some information, but the
+     tracing itself is not impacted.  */
+  TRY
+    {
+      btrace_read_config (&tinfo->conf);
+    }
+  CATCH (err, RETURN_MASK_ERROR)
+    {
+      if (err.message != NULL)
+       warning ("%s", err.message);
+    }
+  END_CATCH
+
   return tinfo;
 }
 
@@ -11419,7 +12092,7 @@ remote_teardown_btrace (struct target_ops *self,
 
 static enum btrace_error
 remote_read_btrace (struct target_ops *self,
-                   VEC (btrace_block_s) **btrace,
+                   struct btrace_data *btrace,
                    struct btrace_target_info *tinfo,
                    enum btrace_read_type type)
 {
@@ -11454,17 +12127,24 @@ remote_read_btrace (struct target_ops *self,
     }
 
   xml = target_read_stralloc (&current_target,
-                              TARGET_OBJECT_BTRACE, annex);
+                             TARGET_OBJECT_BTRACE, annex);
   if (xml == NULL)
     return BTRACE_ERR_UNKNOWN;
 
   cleanup = make_cleanup (xfree, xml);
-  *btrace = parse_xml_btrace (xml);
+  parse_xml_btrace (btrace, xml);
   do_cleanups (cleanup);
 
   return BTRACE_ERR_NONE;
 }
 
+static const struct btrace_config *
+remote_btrace_conf (struct target_ops *self,
+                   const struct btrace_target_info *tinfo)
+{
+  return &tinfo->conf;
+}
+
 static int
 remote_augmented_libraries_svr4_read (struct target_ops *self)
 {
@@ -11480,6 +12160,42 @@ remote_load (struct target_ops *self, const char *name, int from_tty)
   generic_load (name, from_tty);
 }
 
+/* Accepts an integer PID; returns a string representing a file that
+   can be opened on the remote side to get the symbols for the child
+   process.  Returns NULL if the operation is not supported.  */
+
+static char *
+remote_pid_to_exec_file (struct target_ops *self, int pid)
+{
+  static char *filename = NULL;
+  struct inferior *inf;
+  char *annex = NULL;
+
+  if (packet_support (PACKET_qXfer_exec_file) != PACKET_ENABLE)
+    return NULL;
+
+  if (filename != NULL)
+    xfree (filename);
+
+  inf = find_inferior_pid (pid);
+  if (inf == NULL)
+    internal_error (__FILE__, __LINE__,
+                   _("not currently attached to process %d"), pid);
+
+  if (!inf->fake_pid_p)
+    {
+      const int annex_size = 9;
+
+      annex = alloca (annex_size);
+      xsnprintf (annex, annex_size, "%x", pid);
+    }
+
+  filename = target_read_stralloc (&current_target,
+                                  TARGET_OBJECT_EXEC_FILE, annex);
+
+  return filename;
+}
+
 static void
 init_remote_ops (void)
 {
@@ -11501,6 +12217,10 @@ Specify the serial device it is connected to\n\
   remote_ops.to_files_info = remote_files_info;
   remote_ops.to_insert_breakpoint = remote_insert_breakpoint;
   remote_ops.to_remove_breakpoint = remote_remove_breakpoint;
+  remote_ops.to_stopped_by_sw_breakpoint = remote_stopped_by_sw_breakpoint;
+  remote_ops.to_supports_stopped_by_sw_breakpoint = remote_supports_stopped_by_sw_breakpoint;
+  remote_ops.to_stopped_by_hw_breakpoint = remote_stopped_by_hw_breakpoint;
+  remote_ops.to_supports_stopped_by_hw_breakpoint = remote_supports_stopped_by_hw_breakpoint;
   remote_ops.to_stopped_by_watchpoint = remote_stopped_by_watchpoint;
   remote_ops.to_stopped_data_address = remote_stopped_data_address;
   remote_ops.to_watchpoint_addr_within_range =
@@ -11525,6 +12245,7 @@ Specify the serial device it is connected to\n\
   remote_ops.to_stop = remote_stop;
   remote_ops.to_xfer_partial = remote_xfer_partial;
   remote_ops.to_rcmd = remote_rcmd;
+  remote_ops.to_pid_to_exec_file = remote_pid_to_exec_file;
   remote_ops.to_log_command = serial_log_command;
   remote_ops.to_get_thread_local_address = remote_get_thread_local_address;
   remote_ops.to_stratum = process_stratum;
@@ -11550,9 +12271,11 @@ Specify the serial device it is connected to\n\
   remote_ops.to_supports_multi_process = remote_supports_multi_process;
   remote_ops.to_supports_disable_randomization
     = remote_supports_disable_randomization;
+  remote_ops.to_filesystem_is_local = remote_filesystem_is_local;
   remote_ops.to_fileio_open = remote_hostio_open;
   remote_ops.to_fileio_pwrite = remote_hostio_pwrite;
   remote_ops.to_fileio_pread = remote_hostio_pread;
+  remote_ops.to_fileio_fstat = remote_hostio_fstat;
   remote_ops.to_fileio_close = remote_hostio_close;
   remote_ops.to_fileio_unlink = remote_hostio_unlink;
   remote_ops.to_fileio_readlink = remote_hostio_readlink;
@@ -11601,6 +12324,7 @@ Specify the serial device it is connected to\n\
   remote_ops.to_disable_btrace = remote_disable_btrace;
   remote_ops.to_teardown_btrace = remote_teardown_btrace;
   remote_ops.to_read_btrace = remote_read_btrace;
+  remote_ops.to_btrace_conf = remote_btrace_conf;
   remote_ops.to_augmented_libraries_svr4_read =
     remote_augmented_libraries_svr4_read;
 }
@@ -11628,6 +12352,15 @@ Specify the serial device it is connected to (e.g. /dev/ttya).";
   extended_remote_ops.to_kill = extended_remote_kill;
   extended_remote_ops.to_supports_disable_randomization
     = extended_remote_supports_disable_randomization;
+  extended_remote_ops.to_follow_fork = remote_follow_fork;
+  extended_remote_ops.to_insert_fork_catchpoint
+    = remote_insert_fork_catchpoint;
+  extended_remote_ops.to_remove_fork_catchpoint
+    = remote_remove_fork_catchpoint;
+  extended_remote_ops.to_insert_vfork_catchpoint
+    = remote_insert_vfork_catchpoint;
+  extended_remote_ops.to_remove_vfork_catchpoint
+    = remote_remove_vfork_catchpoint;
 }
 
 static int
@@ -11669,7 +12402,7 @@ remote_async_serial_handler (struct serial *scb, void *context)
 
   /* Don't propogate error information up to the client.  Instead let
      the client find out about the error by querying the target.  */
-  rs->async_client_callback (INF_REG_EVENT, rs->async_client_context);
+  inferior_event_handler (INF_REG_EVENT, NULL);
 }
 
 static void
@@ -11679,21 +12412,24 @@ remote_async_inferior_event_handler (gdb_client_data data)
 }
 
 static void
-remote_async (struct target_ops *ops,
-             void (*callback) (enum inferior_event_type event_type,
-                               void *context),
-             void *context)
+remote_async (struct target_ops *ops, int enable)
 {
   struct remote_state *rs = get_remote_state ();
 
-  if (callback != NULL)
+  if (enable)
     {
       serial_async (rs->remote_desc, remote_async_serial_handler, rs);
-      rs->async_client_callback = callback;
-      rs->async_client_context = context;
+
+      /* If there are pending events in the stop reply queue tell the
+        event loop to process them.  */
+      if (!QUEUE_is_empty (stop_reply_p, stop_reply_queue))
+       mark_async_event_handler (remote_async_inferior_event_token);
     }
   else
-    serial_async (rs->remote_desc, NULL, NULL);
+    {
+      serial_async (rs->remote_desc, NULL, NULL);
+      clear_async_event_handler (remote_async_inferior_event_token);
+    }
 }
 
 static void
@@ -12047,6 +12783,9 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
   add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_auxv],
                         "qXfer:auxv:read", "read-aux-vector", 0);
 
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_exec_file],
+                        "qXfer:exec-file:read", "pid-to-exec-file", 0);
+
   add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_features],
                         "qXfer:features:read", "target-features", 0);
 
@@ -12107,6 +12846,9 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
   add_packet_config_cmd (&remote_protocol_packets[PACKET_qTStatus],
                         "qTStatus", "trace-status", 0);
 
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_vFile_setfs],
+                        "vFile:setfs", "hostio-setfs", 0);
+
   add_packet_config_cmd (&remote_protocol_packets[PACKET_vFile_open],
                         "vFile:open", "hostio-open", 0);
 
@@ -12125,6 +12867,9 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
   add_packet_config_cmd (&remote_protocol_packets[PACKET_vFile_readlink],
                         "vFile:readlink", "hostio-readlink", 0);
 
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_vFile_fstat],
+                        "vFile:fstat", "hostio-fstat", 0);
+
   add_packet_config_cmd (&remote_protocol_packets[PACKET_vAttach],
                         "vAttach", "attach", 0);
 
@@ -12186,12 +12931,37 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
        "Qbtrace:off", "disable-btrace", 0);
 
   add_packet_config_cmd (&remote_protocol_packets[PACKET_Qbtrace_bts],
-       "Qbtrace:bts", "enable-btrace", 0);
+       "Qbtrace:bts", "enable-btrace-bts", 0);
+
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_Qbtrace_pt],
+       "Qbtrace:pt", "enable-btrace-pt", 0);
 
   add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_btrace],
        "qXfer:btrace", "read-btrace", 0);
 
-  /* Assert that we've registered commands for all packet configs.  */
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_btrace_conf],
+       "qXfer:btrace-conf", "read-btrace-conf", 0);
+
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_Qbtrace_conf_bts_size],
+       "Qbtrace-conf:bts:size", "btrace-conf-bts-size", 0);
+
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_swbreak_feature],
+                         "swbreak-feature", "swbreak-feature", 0);
+
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_hwbreak_feature],
+                         "hwbreak-feature", "hwbreak-feature", 0);
+
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_fork_event_feature],
+                        "fork-event-feature", "fork-event-feature", 0);
+
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_vfork_event_feature],
+                        "vfork-event-feature", "vfork-event-feature", 0);
+
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_Qbtrace_conf_pt_size],
+       "Qbtrace-conf:pt:size", "btrace-conf-pt-size", 0);
+
+  /* Assert that we've registered "set remote foo-packet" commands
+     for all packet configs.  */
   {
     int i;
 
This page took 0.064127 seconds and 4 git commands to generate.