2008-10-17 Michael Snyder <msnyder@vmware.com>
[deliverable/binutils-gdb.git] / gdb / remote.c
index e71c467b51a7c8d4dda6c92ec06ffe9f761c3c64..f334c0b9b5708e41d9211746a6a25c3dfdda6097 100644 (file)
@@ -59,6 +59,7 @@
 
 #include "remote-fileio.h"
 #include "gdb/fileio.h"
+#include "gdb_stat.h"
 
 #include "memory-map.h"
 
@@ -155,7 +156,7 @@ static void init_remote_ops (void);
 
 static void init_extended_remote_ops (void);
 
-static void remote_stop (void);
+static void remote_stop (ptid_t);
 
 static int ishex (int ch, int *val);
 
@@ -207,34 +208,14 @@ static void show_remote_protocol_packet_cmd (struct ui_file *file,
                                             struct cmd_list_element *c,
                                             const char *value);
 
-void _initialize_remote (void);
-
-/* Controls if async mode is permitted.  */
-static int remote_async_permitted = 0;
+static char *write_ptid (char *buf, const char *endbuf, ptid_t ptid);
+static ptid_t read_ptid (char *buf, char **obuf);
 
-static int remote_async_permitted_set = 0;
+static void remote_query_supported (void);
 
-static void
-set_maintenance_remote_async_permitted (char *args, int from_tty,
-                                       struct cmd_list_element *c)
-{
-  if (target_has_execution)
-    {
-      remote_async_permitted_set = remote_async_permitted; /* revert */
-      error (_("Cannot change this setting while the inferior is running."));
-    }
+static void remote_check_symbols (struct objfile *objfile);
 
-  remote_async_permitted = remote_async_permitted_set;
-}
-
-static void
-show_maintenance_remote_async_permitted (struct ui_file *file, int from_tty,
-                                        struct cmd_list_element *c, const char *value)
-{
-  fprintf_filtered (file, _("\
-Controlling the remote inferior in asynchronous mode is %s.\n"),
-                   value);
-}
+void _initialize_remote (void);
 
 /* For "remote".  */
 
@@ -274,8 +255,35 @@ struct remote_state
      skip calling getpkt.  This flag is set when BUF contains a
      stop reply packet and the target is not waiting.  */
   int cached_wait_status;
+
+  /* True, if in no ack mode.  That is, neither GDB nor the stub will
+     expect acks from each other.  The connection is assumed to be
+     reliable.  */
+  int noack_mode;
+
+  /* True if we're connected in extended remote mode.  */
+  int extended;
+
+  /* True if the stub reported support for multi-process
+     extensions.  */
+  int multi_process_aware;
+
+  /* True if we resumed the target and we're waiting for the target to
+     stop.  In the mean time, we can't start another command/query.
+     The remote server wouldn't be ready to process it, so we'd
+     timeout waiting for a reply that would never come and eventually
+     we'd close the connection.  This can happen in asynchronous mode
+     because we allow GDB commands while the target is running.  */
+  int waiting_for_stop_reply;
 };
 
+/* Returns true if the multi-process extensions are in effect.  */
+static int
+remote_multi_process_p (struct remote_state *rs)
+{
+  return rs->extended && rs->multi_process_aware;
+}
+
 /* This data could be associated with a target, but we do not always
    have access to the current target when we need it, so for now it is
    static.  This will be fine for as long as only one target is in use
@@ -296,9 +304,9 @@ struct packet_reg
   long regnum; /* GDB's internal register number.  */
   LONGEST pnum; /* Remote protocol register number.  */
   int in_g_packet; /* Always part of G packet.  */
-  /* long size in bytes;  == register_size (current_gdbarch, regnum);
+  /* long size in bytes;  == register_size (target_gdbarch, regnum);
      at present.  */
-  /* char *name; == gdbarch_register_name (current_gdbarch, regnum);
+  /* char *name; == gdbarch_register_name (target_gdbarch, regnum);
      at present.  */
 };
 
@@ -331,7 +339,7 @@ static struct gdbarch_data *remote_gdbarch_data_handle;
 static struct remote_arch_state *
 get_remote_arch_state (void)
 {
-  return gdbarch_data (current_gdbarch, remote_gdbarch_data_handle);
+  return gdbarch_data (target_gdbarch, remote_gdbarch_data_handle);
 }
 
 /* Fetch the global remote target state.  */
@@ -467,7 +475,7 @@ get_remote_packet_size (void)
 static struct packet_reg *
 packet_reg_from_regnum (struct remote_arch_state *rsa, long regnum)
 {
-  if (regnum < 0 && regnum >= gdbarch_num_regs (current_gdbarch))
+  if (regnum < 0 && regnum >= gdbarch_num_regs (target_gdbarch))
     return NULL;
   else
     {
@@ -481,7 +489,7 @@ static struct packet_reg *
 packet_reg_from_pnum (struct remote_arch_state *rsa, LONGEST pnum)
 {
   int i;
-  for (i = 0; i < gdbarch_num_regs (current_gdbarch); i++)
+  for (i = 0; i < gdbarch_num_regs (target_gdbarch); i++)
     {
       struct packet_reg *r = &rsa->regs[i];
       if (r->pnum == pnum)
@@ -960,6 +968,8 @@ enum {
   PACKET_qSearch_memory,
   PACKET_vAttach,
   PACKET_vRun,
+  PACKET_QStartNoAckMode,
+  PACKET_vKill,
   PACKET_MAX
 };
 
@@ -1086,8 +1096,24 @@ record_currthread (ptid_t currthread)
 {
   general_thread = currthread;
 
+  /* When connecting to a target remote, or to a target
+     extended-remote which already was debugging an inferior, we may
+     not know about it yet.  Add it before adding its child thread, so
+     notifications are emitted in a sensible order.  */
+  if (!in_inferior_list (ptid_get_pid (currthread)))
+    add_inferior (ptid_get_pid (currthread));
+
   /* If this is a new thread, add it to GDB's thread list.
      If we leave it up to WFI to do this, bad things will happen.  */
+
+  if (in_thread_list (currthread) && is_exited (currthread))
+    {
+      /* We're seeing an event on a thread id we knew had exited.
+        This has to be a new thread reusing the old id.  Add it.  */
+      add_thread (currthread);
+      return;
+    }
+
   if (!in_thread_list (currthread))
     {
       if (ptid_equal (pid_to_ptid (ptid_get_pid (currthread)), inferior_ptid))
@@ -1097,22 +1123,23 @@ record_currthread (ptid_t currthread)
             stub doesn't support qC.  This is the first stop reported
             after an attach, so this is the main thread.  Update the
             ptid in the thread list.  */
-         struct thread_info *th = find_thread_pid (inferior_ptid);
-         inferior_ptid = th->ptid = currthread;
+         thread_change_ptid (inferior_ptid, currthread);
+         return;
        }
-      else if (ptid_equal (magic_null_ptid, inferior_ptid))
+
+      if (ptid_equal (magic_null_ptid, inferior_ptid))
        {
          /* inferior_ptid is not set yet.  This can happen with the
             vRun -> remote_wait,"TAAthread:" path if the stub
             doesn't support qC.  This is the first stop reported
             after an attach, so this is the main thread.  Update the
             ptid in the thread list.  */
-         struct thread_info *th = find_thread_pid (inferior_ptid);
-         inferior_ptid = th->ptid = currthread;
+         thread_change_ptid (inferior_ptid, currthread);
+         return;
        }
-      else
-       /* This is really a new thread.  Add it.  */
-       add_thread (currthread);
+
+      /* This is really a new thread.  Add it.  */
+      add_thread (currthread);
     }
 }
 
@@ -1199,13 +1226,7 @@ set_thread (struct ptid ptid, int gen)
   else if (ptid_equal (ptid, minus_one_ptid))
     xsnprintf (buf, endbuf - buf, "-1");
   else
-    {
-      int tid = ptid_get_tid (ptid);
-      if (tid < 0)
-       xsnprintf (buf, endbuf - buf, "-%x", -tid);
-      else
-       xsnprintf (buf, endbuf - buf, "%x", tid);
-    }
+    write_ptid (buf, endbuf, ptid);
   putpkt (rs->buf);
   getpkt (&rs->buf, &rs->buf_size, 0);
   if (gen)
@@ -1226,6 +1247,30 @@ set_continue_thread (struct ptid ptid)
   set_thread (ptid, 0);
 }
 
+/* Change the remote current process.  Which thread within the process
+   ends up selected isn't important, as long as it is the same process
+   as what INFERIOR_PTID points to.
+
+   This comes from that fact that there is no explicit notion of
+   "selected process" in the protocol.  The selected process for
+   general operations is the process the selected general thread
+   belongs to.  */
+
+static void
+set_general_process (void)
+{
+  struct remote_state *rs = get_remote_state ();
+
+  /* If the remote can't handle multiple processes, don't bother.  */
+  if (!remote_multi_process_p (rs))
+    return;
+
+  /* We only need to change the remote current thread if it's pointing
+     at some other process.  */
+  if (ptid_get_pid (general_thread) != ptid_get_pid (inferior_ptid))
+    set_general_thread (inferior_ptid);
+}
+
 \f
 /*  Return nonzero if the thread PTID is still alive on the remote
     system.  */
@@ -1235,6 +1280,7 @@ remote_thread_alive (ptid_t ptid)
 {
   struct remote_state *rs = get_remote_state ();
   int tid = ptid_get_tid (ptid);
+  char *p, *endp;
 
   if (ptid_equal (ptid, magic_null_ptid))
     /* The main thread is always alive.  */
@@ -1246,10 +1292,12 @@ remote_thread_alive (ptid_t ptid)
        multi-threading.  */
     return 1;
 
-  if (tid < 0)
-    xsnprintf (rs->buf, get_remote_packet_size (), "T-%08x", -tid);
-  else
-    xsnprintf (rs->buf, get_remote_packet_size (), "T%08x", tid);
+  p = rs->buf;
+  endp = rs->buf + get_remote_packet_size ();
+
+  *p++ = 'T';
+  write_ptid (p, endp, ptid);
+
   putpkt (rs->buf);
   getpkt (&rs->buf, &rs->buf_size, 0);
   return (rs->buf[0] == 'O' && rs->buf[1] == 'K');
@@ -1370,6 +1418,71 @@ static int remote_threadlist_iterator (rmt_thread_action stepfunction,
 
 static int remote_newthread_step (threadref *ref, void *context);
 
+
+/* Write a PTID to BUF.  ENDBUF points to one-passed-the-end of the
+   buffer we're allowed to write to.  Returns
+   BUF+CHARACTERS_WRITTEN.  */
+
+static char *
+write_ptid (char *buf, const char *endbuf, ptid_t ptid)
+{
+  int pid, tid;
+  struct remote_state *rs = get_remote_state ();
+
+  if (remote_multi_process_p (rs))
+    {
+      pid = ptid_get_pid (ptid);
+      if (pid < 0)
+       buf += xsnprintf (buf, endbuf - buf, "p-%x.", -pid);
+      else
+       buf += xsnprintf (buf, endbuf - buf, "p%x.", pid);
+    }
+  tid = ptid_get_tid (ptid);
+  if (tid < 0)
+    buf += xsnprintf (buf, endbuf - buf, "-%x", -tid);
+  else
+    buf += xsnprintf (buf, endbuf - buf, "%x", tid);
+
+  return buf;
+}
+
+/* Extract a PTID from BUF.  If non-null, OBUF is set to the to one
+   passed the last parsed char.  Returns null_ptid on error.  */
+
+static ptid_t
+read_ptid (char *buf, char **obuf)
+{
+  char *p = buf;
+  char *pp;
+  ULONGEST pid = 0, tid = 0;
+  ptid_t ptid;
+
+  if (*p == 'p')
+    {
+      /* Multi-process ptid.  */
+      pp = unpack_varlen_hex (p + 1, &pid);
+      if (*pp != '.')
+       error (_("invalid remote ptid: %s\n"), p);
+
+      p = pp;
+      pp = unpack_varlen_hex (p + 1, &tid);
+      if (obuf)
+       *obuf = pp;
+      return ptid_build (pid, 0, tid);
+    }
+
+  /* No multi-process.  Just a tid.  */
+  pp = unpack_varlen_hex (p, &tid);
+
+  /* Since the stub is not sending a process id, then default to
+     what's in inferior_ptid.  */
+  pid = ptid_get_pid (inferior_ptid);
+
+  if (obuf)
+    *obuf = pp;
+  return ptid_build (pid, 0, tid);
+}
+
 /* Encode 64 bits in 16 chars of hex.  */
 
 static const char hexchars[] = "0123456789abcdef";
@@ -1755,6 +1868,10 @@ remote_get_threadinfo (threadref *threadid, int fieldset,        /* TAG mask */
   pack_threadinfo_request (rs->buf, fieldset, threadid);
   putpkt (rs->buf);
   getpkt (&rs->buf, &rs->buf_size, 0);
+
+  if (rs->buf[0] == '\0')
+    return 0;
+
   result = remote_unpack_thread_info_response (rs->buf + 2,
                                               threadid, info);
   return result;
@@ -1936,16 +2053,7 @@ remote_current_thread (ptid_t oldpid)
   putpkt ("qC");
   getpkt (&rs->buf, &rs->buf_size, 0);
   if (rs->buf[0] == 'Q' && rs->buf[1] == 'C')
-    {
-      /* Use strtoul here, so we'll correctly parse values whose
-        highest bit is set.  The protocol carries them as a simple
-        series of hex digits; in the absence of a sign, strtol will
-        see such values as positive numbers out of range for signed
-        'long', and return LONG_MAX to indicate an overflow.  */
-      tid = strtoul (&rs->buf[2], NULL, 16);
-      pid = ptid_get_pid (oldpid);
-      return ptid_build (pid, 0, tid);
-    }
+    return read_ptid (&rs->buf[2], NULL);
   else
     return oldpid;
 }
@@ -1973,8 +2081,6 @@ remote_threads_info (void)
 {
   struct remote_state *rs = get_remote_state ();
   char *bufp;
-  int tid;
-  int pid;
   ptid_t new_thread;
 
   if (remote_desc == 0)                /* paranoia */
@@ -1991,17 +2097,22 @@ remote_threads_info (void)
            {
              do
                {
-                 /* Use strtoul here, so we'll correctly parse values
-                    whose highest bit is set.  The protocol carries
-                    them as a simple series of hex digits; in the
-                    absence of a sign, strtol will see such values as
-                    positive numbers out of range for signed 'long',
-                    and return LONG_MAX to indicate an overflow.  */
-                 tid = strtoul (bufp, &bufp, 16);
-                 pid = ptid_get_pid (inferior_ptid);
-                 new_thread = ptid_build (pid, 0, tid);
-                 if (tid != 0 && !in_thread_list (new_thread))
-                   add_thread (new_thread);
+                 new_thread = read_ptid (bufp, &bufp);
+                 if (!ptid_equal (new_thread, null_ptid)
+                     && (!in_thread_list (new_thread)
+                         || is_exited (new_thread)))
+                   {
+                     /* When connected to a multi-process aware stub,
+                        "info threads" may show up threads of
+                        inferiors we didn't know about yet.  Add them
+                        now, and before adding any of its child
+                        threads, so notifications are emitted in a
+                        sensible order.  */
+                     if (!in_inferior_list (ptid_get_pid (new_thread)))
+                       add_inferior (ptid_get_pid (new_thread));
+
+                     add_thread (new_thread);
+                   }
                }
              while (*bufp++ == ',');   /* comma-separated list */
              putpkt ("qsThreadInfo");
@@ -2042,10 +2153,21 @@ remote_threads_extra_info (struct thread_info *tp)
     internal_error (__FILE__, __LINE__,
                    _("remote_threads_extra_info"));
 
+  if (ptid_equal (tp->ptid, magic_null_ptid)
+      || (ptid_get_pid (tp->ptid) != 0 && ptid_get_tid (tp->ptid) == 0))
+    /* This is the main thread which was added by GDB.  The remote
+       server doesn't know about it.  */
+    return NULL;
+
   if (use_threadextra_query)
     {
-      xsnprintf (rs->buf, get_remote_packet_size (), "qThreadExtraInfo,%lx",
-                ptid_get_tid (tp->ptid));
+      char *b = rs->buf;
+      char *endb = rs->buf + get_remote_packet_size ();
+
+      xsnprintf (b, endb - b, "qThreadExtraInfo,");
+      b += strlen (b);
+      write_ptid (b, endb, tp->ptid);
+
       putpkt (rs->buf);
       getpkt (&rs->buf, &rs->buf_size, 0);
       if (rs->buf[0] != 0)
@@ -2108,8 +2230,23 @@ static void
 remote_close (int quitting)
 {
   if (remote_desc)
-    serial_close (remote_desc);
-  remote_desc = NULL;
+    {
+      /* Unregister the file descriptor from the event loop.  */
+      if (target_is_async_p ())
+       target_async (NULL, 0);
+      serial_close (remote_desc);
+      remote_desc = NULL;
+    }
+
+  /* Make sure we don't leave the async SIGINT signal handler
+     installed.  */
+  signal (SIGINT, handle_sigint);
+
+  /* We don't have a connection to the remote stub anymore.  Get rid
+     of all the inferiors and their threads we were controlling.  */
+  discard_all_inferiors ();
+
+  generic_mourn_inferior ();
 }
 
 /* Query the remote side for the text, data and bss offsets.  */
@@ -2285,8 +2422,9 @@ struct start_remote_args
 static void
 remote_start_remote (struct ui_out *uiout, void *opaque)
 {
-  struct remote_state *rs = get_remote_state ();
   struct start_remote_args *args = opaque;
+  struct remote_state *rs = get_remote_state ();
+  struct packet_config *noack_config;
   char *wait_status = NULL;
 
   immediate_quit++;            /* Allow user to interrupt it.  */
@@ -2294,6 +2432,47 @@ remote_start_remote (struct ui_out *uiout, void *opaque)
   /* Ack any packet which the remote side has already sent.  */
   serial_write (remote_desc, "+", 1);
 
+  /* The first packet we send to the target is the optional "supported
+     packets" request.  If the target can answer this, it will tell us
+     which later probes to skip.  */
+  remote_query_supported ();
+
+  /* Next, we possibly activate noack mode.
+
+     If the QStartNoAckMode packet configuration is set to AUTO,
+     enable noack mode if the stub reported a wish for it with
+     qSupported.
+
+     If set to TRUE, then enable noack mode even if the stub didn't
+     report it in qSupported.  If the stub doesn't reply OK, the
+     session ends with an error.
+
+     If FALSE, then don't activate noack mode, regardless of what the
+     stub claimed should be the default with qSupported.  */
+
+  noack_config = &remote_protocol_packets[PACKET_QStartNoAckMode];
+
+  if (noack_config->detect == AUTO_BOOLEAN_TRUE
+      || (noack_config->detect == AUTO_BOOLEAN_AUTO
+         && noack_config->support == PACKET_ENABLE))
+    {
+      putpkt ("QStartNoAckMode");
+      getpkt (&rs->buf, &rs->buf_size, 0);
+      if (packet_ok (rs->buf, noack_config) == PACKET_OK)
+       rs->noack_mode = 1;
+    }
+
+  if (args->extended_p)
+    {
+      /* Tell the remote that we are using the extended protocol.  */
+      putpkt ("!");
+      getpkt (&rs->buf, &rs->buf_size, 0);
+    }
+
+  /* Next, if the target can specify a description, read it.  We do
+     this before anything involving memory or registers.  */
+  target_find_description ();
+
   /* Check whether the target is running now.  */
   putpkt ("?");
   getpkt (&rs->buf, &rs->buf_size, 0);
@@ -2338,6 +2517,8 @@ remote_start_remote (struct ui_out *uiout, void *opaque)
   /* Now, if we have thread information, update inferior_ptid.  */
   inferior_ptid = remote_current_thread (inferior_ptid);
 
+  add_inferior (ptid_get_pid (inferior_ptid));
+
   /* Always add the main thread.  */
   add_thread_silent (inferior_ptid);
 
@@ -2350,6 +2531,13 @@ remote_start_remote (struct ui_out *uiout, void *opaque)
 
   immediate_quit--;
   start_remote (args->from_tty); /* Initialize gdb process mechanisms.  */
+
+  /* If we connected to a live target, do some additional setup.  */
+  if (target_has_execution)
+    {
+      if (exec_bfd)    /* No use without an exec file.  */
+       remote_check_symbols (symfile_objfile);
+    }
 }
 
 /* Open a connection to a remote debugger.
@@ -2393,6 +2581,9 @@ remote_check_symbols (struct objfile *objfile)
   if (remote_protocol_packets[PACKET_qSymbol].support == PACKET_DISABLE)
     return;
 
+  /* Make sure the remote is pointing at the right process.  */
+  set_general_process ();
+
   /* Allocate a message buffer.  We can't reuse the input buffer in RS,
      because we need both at the same time.  */
   msg = alloca (get_remote_packet_size ());
@@ -2418,7 +2609,7 @@ remote_check_symbols (struct objfile *objfile)
 
          /* If this is a function address, return the start of code
             instead of any data function descriptor.  */
-         sym_addr = gdbarch_convert_from_func_ptr_addr (current_gdbarch,
+         sym_addr = gdbarch_convert_from_func_ptr_addr (target_gdbarch,
                                                         sym_addr,
                                                         &current_target);
 
@@ -2535,6 +2726,14 @@ remote_packet_size (const struct protocol_feature *feature,
   rs->explicit_packet_size = packet_size;
 }
 
+static void
+remote_multi_process_feature (const struct protocol_feature *feature,
+                             enum packet_support support, const char *value)
+{
+  struct remote_state *rs = get_remote_state ();
+  rs->multi_process_aware = (support == PACKET_ENABLE);
+}
+
 static struct protocol_feature remote_protocol_features[] = {
   { "PacketSize", PACKET_DISABLE, remote_packet_size, -1 },
   { "qXfer:auxv:read", PACKET_DISABLE, remote_supported_packet,
@@ -2551,6 +2750,9 @@ static struct protocol_feature remote_protocol_features[] = {
     PACKET_qXfer_spu_write },
   { "QPassSignals", PACKET_DISABLE, remote_supported_packet,
     PACKET_QPassSignals },
+  { "QStartNoAckMode", PACKET_DISABLE, remote_supported_packet,
+    PACKET_QStartNoAckMode },
+  { "multiprocess", PACKET_DISABLE, remote_multi_process_feature, -1 },
 };
 
 static void
@@ -2571,7 +2773,11 @@ remote_query_supported (void)
   rs->buf[0] = 0;
   if (remote_protocol_packets[PACKET_qSupported].support != PACKET_DISABLE)
     {
-      putpkt ("qSupported");
+      if (rs->extended)
+       putpkt ("qSupported:multiprocess+");
+      else
+       putpkt ("qSupported");
+
       getpkt (&rs->buf, &rs->buf_size, 0);
 
       /* If an error occured, warn, but do not return - just reset the
@@ -2684,13 +2890,14 @@ static void
 remote_open_1 (char *name, int from_tty, struct target_ops *target, int extended_p)
 {
   struct remote_state *rs = get_remote_state ();
+
   if (name == 0)
     error (_("To open a remote debug connection, you need to specify what\n"
           "serial device is attached to the remote system\n"
           "(e.g. /dev/ttyS0, /dev/ttya, COM1, etc.)."));
 
   /* See FIXME above.  */
-  if (!remote_async_permitted)
+  if (!target_async_permitted)
     wait_forever_enabled_p = 1;
 
   /* If we're connected to a running target, target_preopen will kill it.
@@ -2765,6 +2972,10 @@ remote_open_1 (char *name, int from_tty, struct target_ops *target, int extended
      remote_query_supported or as they are needed.  */
   init_all_packet_configs ();
   rs->explicit_packet_size = 0;
+  rs->noack_mode = 0;
+  rs->multi_process_aware = 0;
+  rs->extended = extended_p;
+  rs->waiting_for_stop_reply = 0;
 
   general_thread = not_sent_ptid;
   continue_thread = not_sent_ptid;
@@ -2773,16 +2984,7 @@ remote_open_1 (char *name, int from_tty, struct target_ops *target, int extended
   use_threadinfo_query = 1;
   use_threadextra_query = 1;
 
-  /* The first packet we send to the target is the optional "supported
-     packets" request.  If the target can answer this, it will tell us
-     which later probes to skip.  */
-  remote_query_supported ();
-
-  /* Next, if the target can specify a description, read it.  We do
-     this before anything involving memory or registers.  */
-  target_find_description ();
-
-  if (remote_async_permitted)
+  if (target_async_permitted)
     {
       /* With this target we start out by owning the terminal.  */
       remote_async_terminal_ours_p = 1;
@@ -2826,29 +3028,18 @@ remote_open_1 (char *name, int from_tty, struct target_ops *target, int extended
     ex = catch_exception (uiout, remote_start_remote, &args, RETURN_MASK_ALL);
     if (ex.reason < 0)
       {
-       pop_target ();
-       if (remote_async_permitted)
+       /* Pop the partially set up target - unless something else did
+          already before throwing the exception.  */
+       if (remote_desc != NULL)
+         pop_target ();
+       if (target_async_permitted)
          wait_forever_enabled_p = 1;
        throw_exception (ex);
       }
   }
 
-  if (remote_async_permitted)
+  if (target_async_permitted)
     wait_forever_enabled_p = 1;
-
-  if (extended_p)
-    {
-      /* Tell the remote that we are using the extended protocol.  */
-      putpkt ("!");
-      getpkt (&rs->buf, &rs->buf_size, 0);
-    }
-
-  /* If we connected to a live target, do some additional setup.  */
-  if (target_has_execution)
-    {
-      if (exec_bfd)    /* No use without an exec file.  */
-       remote_check_symbols (symfile_objfile);
-    }
 }
 
 /* This takes a program previously attached to and detaches it.  After
@@ -2859,6 +3050,7 @@ remote_open_1 (char *name, int from_tty, struct target_ops *target, int extended
 static void
 remote_detach_1 (char *args, int from_tty, int extended)
 {
+  int pid = ptid_get_pid (inferior_ptid);
   struct remote_state *rs = get_remote_state ();
 
   if (args)
@@ -2868,25 +3060,37 @@ remote_detach_1 (char *args, int from_tty, int extended)
     error (_("No process to detach from."));
 
   /* Tell the remote target to detach.  */
-  strcpy (rs->buf, "D");
+  if (remote_multi_process_p (rs))
+    sprintf (rs->buf, "D;%x", pid);
+  else
+    strcpy (rs->buf, "D");
+
   putpkt (rs->buf);
   getpkt (&rs->buf, &rs->buf_size, 0);
 
-  if (rs->buf[0] == 'E')
+  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."));
 
-  /* Unregister the file descriptor from the event loop.  */
-  if (target_is_async_p ())
-    serial_async (remote_desc, NULL, 0);
-
-  target_mourn_inferior ();
   if (from_tty)
     {
-      if (extended)
-       puts_filtered ("Detached from remote process.\n");
+      if (remote_multi_process_p (rs))
+       printf_filtered (_("Detached from remote %s.\n"),
+                        target_pid_to_str (pid_to_ptid (pid)));
       else
-       puts_filtered ("Ending remote debugging.\n");
+       {
+         if (extended)
+           puts_filtered (_("Detached from remote process.\n"));
+         else
+           puts_filtered (_("Ending remote debugging.\n"));
+       }
     }
+
+  detach_inferior (pid);
+  target_mourn_inferior ();
 }
 
 static void
@@ -2909,10 +3113,6 @@ remote_disconnect (struct target_ops *target, char *args, int from_tty)
   if (args)
     error (_("Argument given to \"disconnect\" when remotely debugging."));
 
-  /* Unregister the file descriptor from the event loop.  */
-  if (target_is_async_p ())
-    serial_async (remote_desc, NULL, 0);
-
   /* Make sure we unpush even the extended remote targets; mourn
      won't do it.  So call remote_mourn_1 directly instead of
      target_mourn_inferior.  */
@@ -2932,6 +3132,7 @@ extended_remote_attach_1 (struct target_ops *target, char *args, int from_tty)
   int pid;
   char *dummy;
   char *wait_status = NULL;
+  struct inferior *inf;
 
   if (!args)
     error_no_arg (_("process-id to attach"));
@@ -2971,11 +3172,12 @@ extended_remote_attach_1 (struct target_ops *target, char *args, int from_tty)
   /* Now, if we have thread information, update inferior_ptid.  */
   inferior_ptid = remote_current_thread (inferior_ptid);
 
+  inf = add_inferior (pid);
+  inf->attach_flag = 1;
+
   /* Now, add the main thread to the thread list.  */
   add_thread_silent (inferior_ptid);
 
-  attach_flag = 1;
-
   /* Next, if the target can specify a description, read it.  We do
      this before anything involving memory or registers.  */
   target_find_description ();
@@ -3115,8 +3317,8 @@ static int
 remote_vcont_resume (ptid_t ptid, int step, enum target_signal siggnal)
 {
   struct remote_state *rs = get_remote_state ();
-  char *outbuf;
-  struct cleanup *old_cleanup;
+  char *p;
+  char *endp;
 
   if (remote_protocol_packets[PACKET_vCont].support == PACKET_SUPPORT_UNKNOWN)
     remote_vcont_probe (rs);
@@ -3124,6 +3326,9 @@ remote_vcont_resume (ptid_t ptid, int step, enum target_signal siggnal)
   if (remote_protocol_packets[PACKET_vCont].support == PACKET_DISABLE)
     return 0;
 
+  p = rs->buf;
+  endp = rs->buf + get_remote_packet_size ();
+
   /* If we could generate a wider range of packets, we'd have to worry
      about overflowing BUF.  Should there be a generic
      "multi-part-packet" packet?  */
@@ -3135,47 +3340,75 @@ remote_vcont_resume (ptid_t ptid, int step, enum target_signal siggnal)
         understand.  Make sure to only send forms that do not specify
         a TID.  */
       if (step && siggnal != TARGET_SIGNAL_0)
-       outbuf = xstrprintf ("vCont;S%02x", siggnal);
+       xsnprintf (p, endp - p, "vCont;S%02x", siggnal);
       else if (step)
-       outbuf = xstrprintf ("vCont;s");
+       xsnprintf (p, endp - p, "vCont;s");
       else if (siggnal != TARGET_SIGNAL_0)
-       outbuf = xstrprintf ("vCont;C%02x", siggnal);
+       xsnprintf (p, endp - p, "vCont;C%02x", siggnal);
       else
-       outbuf = xstrprintf ("vCont;c");
+       xsnprintf (p, endp - p, "vCont;c");
     }
   else if (ptid_equal (ptid, minus_one_ptid))
     {
       /* Resume all threads, with preference for INFERIOR_PTID.  */
-      int tid = ptid_get_tid (inferior_ptid);
       if (step && siggnal != TARGET_SIGNAL_0)
-       outbuf = xstrprintf ("vCont;S%02x:%x;c", siggnal, tid);
+       {
+         /* Step inferior_ptid with signal.  */
+         p += xsnprintf (p, endp - p, "vCont;S%02x:", siggnal);
+         p = write_ptid (p, endp, inferior_ptid);
+         /* And continue others.  */
+         p += xsnprintf (p, endp - p, ";c");
+       }
       else if (step)
-       outbuf = xstrprintf ("vCont;s:%x;c", tid);
+       {
+         /* Step inferior_ptid.  */
+         p += xsnprintf (p, endp - p, "vCont;s:");
+         p = write_ptid (p, endp, inferior_ptid);
+         /* And continue others.  */
+         p += xsnprintf (p, endp - p, ";c");
+       }
       else if (siggnal != TARGET_SIGNAL_0)
-       outbuf = xstrprintf ("vCont;C%02x:%x;c", siggnal, tid);
+       {
+         /* Continue inferior_ptid with signal.  */
+         p += xsnprintf (p, endp - p, "vCont;C%02x:", siggnal);
+         p = write_ptid (p, endp, inferior_ptid);
+         /* And continue others.  */
+         p += xsnprintf (p, endp - p, ";c");
+       }
       else
-       outbuf = xstrprintf ("vCont;c");
+       xsnprintf (p, endp - p, "vCont;c");
     }
   else
     {
       /* Scheduler locking; resume only PTID.  */
-      int tid = ptid_get_tid (ptid);
       if (step && siggnal != TARGET_SIGNAL_0)
-       outbuf = xstrprintf ("vCont;S%02x:%x", siggnal, tid);
+       {
+         /* Step ptid with signal.  */
+         p += xsnprintf (p, endp - p, "vCont;S%02x:", siggnal);
+         p = write_ptid (p, endp, ptid);
+       }
       else if (step)
-       outbuf = xstrprintf ("vCont;s:%x", tid);
+       {
+         /* Step ptid.  */
+         p += xsnprintf (p, endp - p, "vCont;s:");
+         p = write_ptid (p, endp, ptid);
+       }
       else if (siggnal != TARGET_SIGNAL_0)
-       outbuf = xstrprintf ("vCont;C%02x:%x", siggnal, tid);
+       {
+         /* Continue ptid with signal.  */
+         p += xsnprintf (p, endp - p, "vCont;C%02x:", siggnal);
+         p = write_ptid (p, endp, ptid);
+       }
       else
-       outbuf = xstrprintf ("vCont;c:%x", tid);
+       {
+         /* Continue ptid.  */
+         p += xsnprintf (p, endp - p, "vCont;c:");
+         p = write_ptid (p, endp, ptid);
+       }
     }
 
-  gdb_assert (outbuf && strlen (outbuf) < get_remote_packet_size ());
-  old_cleanup = make_cleanup (xfree, outbuf);
-
-  putpkt (outbuf);
-
-  do_cleanups (old_cleanup);
+  gdb_assert (strlen (rs->buf) < get_remote_packet_size ());
+  putpkt (rs->buf);
 
   return 1;
 }
@@ -3210,7 +3443,15 @@ remote_resume (ptid_t ptid, int step, enum target_signal siggnal)
     set_continue_thread (ptid);
 
   buf = rs->buf;
-  if (siggnal != TARGET_SIGNAL_0)
+  if (execution_direction == EXEC_REVERSE)
+    {
+      /* We don't pass signals to the target in reverse exec mode.  */
+      if (info_verbose && siggnal != TARGET_SIGNAL_0)
+       warning (" - Can't pass signal %d to target in reverse: ignored.\n",
+                siggnal);
+      strcpy (buf, step ? "bs" : "bc");
+    }
+  else if (siggnal != TARGET_SIGNAL_0)
     {
       buf[0] = step ? 'S' : 'C';
       buf[1] = tohex (((int) siggnal >> 4) & 0xf);
@@ -3232,13 +3473,12 @@ remote_resume (ptid_t ptid, int step, enum target_signal siggnal)
      NOT asynchronously.  */
   if (target_can_async_p ())
     target_async (inferior_event_handler, 0);
-  /* Tell the world that the target is now executing.  */
-  /* FIXME: cagney/1999-09-23: Is it the targets responsibility to set
-     this?  Instead, should the client of target just assume (for
-     async targets) that the target is going to start executing?  Is
-     this information already found in the continuation block?  */
-  if (target_is_async_p ())
-    target_executing = 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
+     the mean time, we can't start another command/query ourselves
+     because the stub wouldn't be ready to process it.  */
+  rs->waiting_for_stop_reply = 1;
 }
 \f
 
@@ -3276,7 +3516,7 @@ async_remote_interrupt (gdb_client_data arg)
   if (remote_debug)
     fprintf_unfiltered (gdb_stdlog, "remote_interrupt called\n");
 
-  target_stop ();
+  target_stop (inferior_ptid);
 }
 
 /* Perform interrupt, if the first attempt did not succeed. Just give
@@ -3330,7 +3570,7 @@ remote_interrupt_twice (int signo)
    interrupt is requested, either by the command line or the GUI, we
    will eventually end up here.  */
 static void
-remote_stop (void)
+remote_stop (ptid_t ptid)
 {
   /* Send a break or a ^C, depending on user preference.  */
   if (remote_debug)
@@ -3352,8 +3592,7 @@ interrupt_query (void)
   if (query ("Interrupted while waiting for the program.\n\
 Give up (and stop debugging it)? "))
     {
-      target_mourn_inferior ();
-      signal (SIGINT, handle_sigint);
+      pop_target ();
       deprecated_throw_reason (RETURN_QUIT);
     }
 
@@ -3368,7 +3607,7 @@ Give up (and stop debugging it)? "))
 static void
 remote_terminal_inferior (void)
 {
-  if (!remote_async_permitted)
+  if (!target_async_permitted)
     /* Nothing to do.  */
     return;
 
@@ -3398,7 +3637,7 @@ remote_terminal_inferior (void)
 static void
 remote_terminal_ours (void)
 {
-  if (!remote_async_permitted)
+  if (!target_async_permitted)
     /* Nothing to do.  */
     return;
 
@@ -3433,236 +3672,316 @@ remote_console_output (char *msg)
    storing status in STATUS just as `wait' would.  */
 
 static ptid_t
-remote_wait (ptid_t ptid, struct target_waitstatus *status)
+remote_wait_as (ptid_t ptid, struct target_waitstatus *status)
 {
   struct remote_state *rs = get_remote_state ();
   struct remote_arch_state *rsa = get_remote_arch_state ();
-  ULONGEST thread_num = -1;
-  ULONGEST process_num = -1;
+  ptid_t event_ptid = null_ptid;
   ULONGEST addr;
   int solibs_changed = 0;
+  int replay_event = 0;
+  char *buf, *p;
 
-  status->kind = TARGET_WAITKIND_EXITED;
+  status->kind = TARGET_WAITKIND_IGNORE;
   status->value.integer = 0;
 
-  while (1)
+  if (rs->cached_wait_status)
+    /* Use the cached wait status, but only once.  */
+    rs->cached_wait_status = 0;
+  else
     {
-      char *buf, *p;
-
-      if (rs->cached_wait_status)
-       /* Use the cached wait status, but only once.  */
-       rs->cached_wait_status = 0;
-      else
+      if (!target_is_async_p ())
        {
-         if (!target_is_async_p ())
+         ofunc = signal (SIGINT, remote_interrupt);
+         /* If the user hit C-c before this packet, or between
+            packets, pretend that it was hit right here.  */
+         if (quit_flag)
            {
-             ofunc = signal (SIGINT, remote_interrupt);
-             /* If the user hit C-c before this packet, or between packets,
-                pretend that it was hit right here.  */
-             if (quit_flag)
-               {
-                 quit_flag = 0;
-                 remote_interrupt (SIGINT);
-               }
+             quit_flag = 0;
+             remote_interrupt (SIGINT);
            }
-         /* FIXME: cagney/1999-09-27: If we're in async mode we should
-            _never_ wait for ever -> test on target_is_async_p().
-            However, before we do that we need to ensure that the caller
-            knows how to take the target into/out of async mode.  */
-         getpkt (&rs->buf, &rs->buf_size, wait_forever_enabled_p);
-         if (!target_is_async_p ())
-           signal (SIGINT, ofunc);
        }
+      /* FIXME: cagney/1999-09-27: If we're in async mode we should
+        _never_ wait for ever -> test on target_is_async_p().
+        However, before we do that we need to ensure that the caller
+        knows how to take the target into/out of async mode.  */
+      getpkt (&rs->buf, &rs->buf_size, wait_forever_enabled_p);
+      if (!target_is_async_p ())
+       signal (SIGINT, ofunc);
+    }
 
-      buf = rs->buf;
+  buf = rs->buf;
 
-      remote_stopped_by_watchpoint_p = 0;
+  remote_stopped_by_watchpoint_p = 0;
 
-      switch (buf[0])
-       {
-       case 'E':               /* Error of some sort.  */
-         /* We're out of sync with the target now.  Did it continue or not?
-            Not is more likely, so report a stop.  */
-         warning (_("Remote failure reply: %s"), buf);
-         status->kind = TARGET_WAITKIND_STOPPED;
-         status->value.sig = TARGET_SIGNAL_0;
-         goto got_status;
-       case 'F':               /* File-I/O request.  */
-         remote_fileio_request (buf);
-         continue;
-       case 'T':               /* Status with PC, SP, FP, ...  */
-         {
-           gdb_byte regs[MAX_REGISTER_SIZE];
+  /* We got something.  */
+  rs->waiting_for_stop_reply = 0;
 
-           /* Expedited reply, containing Signal, {regno, reg} repeat.  */
-           /*  format is:  'Tssn...:r...;n...:r...;n...:r...;#cc', where
-              ss = signal number
-              n... = register number
-              r... = register contents
-            */
-           p = &buf[3];        /* after Txx */
+  switch (buf[0])
+    {
+    case 'E':          /* Error of some sort.  */
+      /* We're out of sync with the target now.  Did it continue or
+        not?  Not is more likely, so report a stop.  */
+      warning (_("Remote failure reply: %s"), buf);
+      status->kind = TARGET_WAITKIND_STOPPED;
+      status->value.sig = TARGET_SIGNAL_0;
+      break;
+    case 'F':          /* File-I/O request.  */
+      remote_fileio_request (buf);
 
-           while (*p)
-             {
-               char *p1;
-               char *p_temp;
-               int fieldsize;
-               LONGEST pnum = 0;
+      /* This stop reply is special.  We reply back to the stub,
+        and keep waiting for the target to stop.  */
+      rs->waiting_for_stop_reply = 1;
+      break;
+    case 'T':          /* Status with PC, SP, FP, ...  */
+      {
+       gdb_byte regs[MAX_REGISTER_SIZE];
 
-               /* 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.  */
+       /* Expedited reply, containing Signal, {regno, reg} repeat.  */
+       /*  format is:  'Tssn...:r...;n...:r...;n...:r...;#cc', where
+           ss = signal number
+           n... = register number
+           r... = register contents
+       */
+       p = &buf[3];    /* after Txx */
+
+       while (*p)
+         {
+           char *p1;
+           char *p_temp;
+           int fieldsize;
+           LONGEST pnum = 0;
 
-               /* If this packet is an awatch packet, don't parse the
-                  'a' as a register number.  */
+           /* 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.  */
 
-               if (strncmp (p, "awatch", strlen("awatch")) != 0)
+           /* If this packet is an awatch packet, don't parse the
+              'a' as a register number.  */
+
+           if (strncmp (p, "awatch", strlen("awatch")) != 0)
+             {
+               /* Read the ``P'' register number.  */
+               pnum = strtol (p, &p_temp, 16);
+               p1 = p_temp;
+             }
+           else
+             p1 = p;
+
+           if (p1 == p)        /* No register number present here.  */
+             {
+               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))
                  {
-                   /* Read the ``P'' register number.  */
-                   pnum = strtol (p, &p_temp, 16);
-                   p1 = p_temp;
+                   remote_stopped_by_watchpoint_p = 1;
+                   p = unpack_varlen_hex (++p1, &addr);
+                   remote_watch_data_address = (CORE_ADDR)addr;
                  }
-               else
-                 p1 = p;
+               else if (strncmp (p, "library", p1 - p) == 0)
+                 {
+                   p1++;
+                   p_temp = p1;
+                   while (*p_temp && *p_temp != ';')
+                     p_temp++;
 
-               if (p1 == p)    /* No register number present here.  */
+                   solibs_changed = 1;
+                   p = p_temp;
+                 }
+               else if (strncmp (p, "replaylog", 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)
-                     {
-                       p_temp = unpack_varlen_hex (++p1, &thread_num);
-                       p = p_temp;
-                     }
-                   else if ((strncmp (p, "watch", p1 - p) == 0)
-                            || (strncmp (p, "rwatch", p1 - p) == 0)
-                            || (strncmp (p, "awatch", p1 - p) == 0))
-                     {
-                       remote_stopped_by_watchpoint_p = 1;
-                       p = unpack_varlen_hex (++p1, &addr);
-                       remote_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++;
-
-                       solibs_changed = 1;
-                       p = p_temp;
-                     }
-                   else
-                     {
-                       /* Silently skip unknown optional info.  */
-                       p_temp = strchr (p1 + 1, ';');
-                       if (p_temp)
-                         p = p_temp;
-                     }
+                   /* NO_HISTORY event.
+                      p1 will indicate "begin" or "end", but
+                      it makes no difference for now, so ignore it.  */
+                   replay_event = 1;
+                   p_temp = strchr (p1 + 1, ';');
+                   if (p_temp)
+                     p = p_temp;
                  }
                else
                  {
-                   struct packet_reg *reg = packet_reg_from_pnum (rsa, pnum);
-                   p = p1;
+                   /* Silently skip unknown optional info.  */
+                   p_temp = strchr (p1 + 1, ';');
+                   if (p_temp)
+                     p = p_temp;
+                 }
+             }
+           else
+             {
+               struct packet_reg *reg = packet_reg_from_pnum (rsa, pnum);
+               p = p1;
 
-                   if (*p != ':')
-                     error (_("Malformed packet(b) (missing colon): %s\n\
+               if (*p != ':')
+                 error (_("Malformed packet(b) (missing colon): %s\n\
 Packet: '%s'\n"),
-                            p, buf);
-                    ++p;
+                        p, buf);
+               ++p;
 
-                   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"),
-                            phex_nz (pnum, 0), p, buf);
-
-                   fieldsize = hex2bin (p, regs,
-                                        register_size (current_gdbarch,
-                                                       reg->regnum));
-                   p += 2 * fieldsize;
-                   if (fieldsize < register_size (current_gdbarch,
-                                                  reg->regnum))
-                     warning (_("Remote reply is too short: %s"), buf);
-                   regcache_raw_supply (get_current_regcache (),
-                                        reg->regnum, regs);
-                 }
-
-               if (*p != ';')
-                 error (_("Remote register badly formatted: %s\nhere: %s"),
-                        buf, p);
-                ++p;
+                        phex_nz (pnum, 0), p, buf);
+
+               fieldsize = hex2bin (p, regs,
+                                    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);
+               regcache_raw_supply (get_current_regcache (),
+                                    reg->regnum, regs);
              }
+
+           if (*p != ';')
+             error (_("Remote register badly formatted: %s\nhere: %s"),
+                    buf, p);
+           ++p;
          }
-         /* fall through */
-       case 'S':               /* Old style status, just signal only.  */
-         if (solibs_changed)
-           status->kind = TARGET_WAITKIND_LOADED;
-         else
-           {
-             status->kind = TARGET_WAITKIND_STOPPED;
-             status->value.sig = (enum target_signal)
-               (((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
-           }
-         goto got_status;
-       case 'W':               /* Target exited.  */
+      }
+      /* fall through */
+    case 'S':          /* Old style status, just signal only.  */
+      if (solibs_changed)
+       status->kind = TARGET_WAITKIND_LOADED;
+      else if (replay_event)
+            status->kind = TARGET_WAITKIND_NO_HISTORY;
+      else
+       {
+         status->kind = TARGET_WAITKIND_STOPPED;
+         status->value.sig = (enum target_signal)
+           (((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
+       }
+      break;
+    case 'W':          /* Target exited.  */
+    case 'X':
+      {
+       char *p;
+       int pid;
+       ULONGEST value;
+
+       /* GDB used to accept only 2 hex chars here.  Stubs should
+          only send more if they detect GDB supports multi-process
+          support.  */
+       p = unpack_varlen_hex (&buf[1], &value);
+
+       if (buf[0] == 'W')
          {
            /* The remote process exited.  */
            status->kind = TARGET_WAITKIND_EXITED;
-           status->value.integer = (fromhex (buf[1]) << 4) + fromhex (buf[2]);
-           goto got_status;
+           status->value.integer = value;
+         }
+       else
+         {
+           /* The remote process exited with a signal.  */
+           status->kind = TARGET_WAITKIND_SIGNALLED;
+           status->value.sig = (enum target_signal) value;
          }
-       case 'X':
-         status->kind = TARGET_WAITKIND_SIGNALLED;
-         status->value.sig = (enum target_signal)
-           (((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
 
-         goto got_status;
-       case 'O':               /* Console output.  */
-         remote_console_output (buf + 1);
-         if (target_can_async_p ())
-           {
-             /* Return immediately to the event loop. The event loop
-                will still be waiting on the inferior afterwards.  */
-             status->kind = TARGET_WAITKIND_IGNORE;
-             goto got_status;
-           }
-         else
-           continue;
-       case '\0':
-         if (last_sent_signal != TARGET_SIGNAL_0)
-           {
-             /* Zero length reply means that we tried 'S' or 'C' and
-                the remote system doesn't support it.  */
-             target_terminal_ours_for_output ();
-             printf_filtered
-               ("Can't send signals to this remote system.  %s not sent.\n",
-                target_signal_to_name (last_sent_signal));
-             last_sent_signal = TARGET_SIGNAL_0;
-             target_terminal_inferior ();
-
-             strcpy ((char *) buf, last_sent_step ? "s" : "c");
-             putpkt ((char *) buf);
-             continue;
-           }
-         /* else fallthrough */
-       default:
-         warning (_("Invalid remote reply: %s"), buf);
-         continue;
+       /* If no process is specified, assume inferior_ptid.  */
+       pid = ptid_get_pid (inferior_ptid);
+       if (*p == '\0')
+         ;
+       else if (*p == ';')
+         {
+           p++;
+
+           if (p == '\0')
+             ;
+           else if (strncmp (p,
+                             "process:", sizeof ("process:") - 1) == 0)
+             {
+               ULONGEST upid;
+               p += sizeof ("process:") - 1;
+               unpack_varlen_hex (p, &upid);
+               pid = upid;
+             }
+           else
+             error (_("unknown stop reply packet: %s"), buf);
+         }
+       else
+         error (_("unknown stop reply packet: %s"), buf);
+       event_ptid = pid_to_ptid (pid);
+       break;
+      }
+    case 'O':          /* Console output.  */
+      remote_console_output (buf + 1);
+
+      /* The target didn't really stop; keep waiting.  */
+      rs->waiting_for_stop_reply = 1;
+
+      break;
+    case '\0':
+      if (last_sent_signal != TARGET_SIGNAL_0)
+       {
+         /* Zero length reply means that we tried 'S' or 'C' and the
+            remote system doesn't support it.  */
+         target_terminal_ours_for_output ();
+         printf_filtered
+           ("Can't send signals to this remote system.  %s not sent.\n",
+            target_signal_to_name (last_sent_signal));
+         last_sent_signal = TARGET_SIGNAL_0;
+         target_terminal_inferior ();
+
+         strcpy ((char *) buf, last_sent_step ? "s" : "c");
+         putpkt ((char *) buf);
+
+         /* We just told the target to resume, so a stop reply is in
+            order.  */
+         rs->waiting_for_stop_reply = 1;
+         break;
        }
+      /* else fallthrough */
+    default:
+      warning (_("Invalid remote reply: %s"), buf);
+      /* Keep waiting.  */
+      rs->waiting_for_stop_reply = 1;
+      break;
+    }
+
+  /* Nothing interesting happened.  */
+  if (status->kind == TARGET_WAITKIND_IGNORE)
+    return minus_one_ptid;
+
+  if (status->kind == TARGET_WAITKIND_EXITED
+      || status->kind == TARGET_WAITKIND_SIGNALLED)
+    {
+      int pid = ptid_get_pid (event_ptid);
+      delete_inferior (pid);
     }
-got_status:
-  if (thread_num != -1)
+  else
+    {
+      if (!ptid_equal (event_ptid, null_ptid))
+       record_currthread (event_ptid);
+      else
+       event_ptid = inferior_ptid;
+    }
+
+  return event_ptid;
+}
+
+static ptid_t
+remote_wait (ptid_t ptid, struct target_waitstatus *status)
+{
+  ptid_t event_ptid;
+
+  /* In synchronous mode, keep waiting until the target stops.  In
+     asynchronous mode, always return to the event loop.  */
+
+  do
     {
-      ptid_t ptid;
-      ptid = ptid_build (ptid_get_pid (inferior_ptid), 0, thread_num);
-      record_currthread (ptid);
-      return ptid;
+      event_ptid = remote_wait_as (ptid, status);
     }
+  while (status->kind == TARGET_WAITKIND_IGNORE
+        && !target_can_async_p ());
 
-  return inferior_ptid;
+  return event_ptid;
 }
 
 /* Fetch a single register using a 'p' packet.  */
@@ -4097,7 +4416,7 @@ remote_address_masked (CORE_ADDR addr)
   int address_size = remote_address_size;
   /* If "remoteaddresssize" was not set, default to target address size.  */
   if (!address_size)
-    address_size = gdbarch_addr_bit (current_gdbarch);
+    address_size = gdbarch_addr_bit (target_gdbarch);
 
   if (address_size > 0
       && address_size < (sizeof (ULONGEST) * 8))
@@ -4554,6 +4873,8 @@ remote_xfer_memory (CORE_ADDR mem_addr, gdb_byte *buffer, int mem_len,
 {
   int res;
 
+  set_general_thread (inferior_ptid);
+
   if (should_write)
     res = remote_write_bytes (mem_addr, buffer, mem_len);
   else
@@ -4691,7 +5012,7 @@ readchar (int timeout)
   switch ((enum serial_rc) ch)
     {
     case SERIAL_EOF:
-      target_mourn_inferior ();
+      pop_target ();
       error (_("Remote connection closed"));
       /* no return */
     case SERIAL_ERROR:
@@ -4754,6 +5075,15 @@ putpkt_binary (char *buf, int cnt)
   int tcount = 0;
   char *p;
 
+  /* Catch cases like trying to read memory or listing threads while
+     we're waiting for a stop reply.  The remote server wouldn't be
+     ready to handle this request, so we'd hang and timeout.  We don't
+     have to worry about this in synchronous mode, because in that
+     case it's not possible to issue a command while the target is
+     running.  */
+  if (target_can_async_p () && rs->waiting_for_stop_reply)
+    error (_("Cannot execute this command while the target is running."));
+
   /* We're sending out a new packet.  Make sure we don't look at a
      stale cached response.  */
   rs->cached_wait_status = 0;
@@ -4790,6 +5120,11 @@ putpkt_binary (char *buf, int cnt)
       if (serial_write (remote_desc, buf2, p - buf2))
        perror_with_name (_("putpkt: write failed"));
 
+      /* If this is a no acks version of the remote protocol, send the
+        packet and move on.  */
+      if (rs->noack_mode)
+        break;
+
       /* Read until either a timeout occurs (-2) or '+' is read.  */
       while (1)
        {
@@ -4866,6 +5201,7 @@ putpkt_binary (char *buf, int cnt)
        }
 #endif
     }
+  return 0;
 }
 
 /* Come here after finding the start of a frame when we expected an
@@ -4921,6 +5257,7 @@ read_frame (char **buf_p,
   long bc;
   int c;
   char *buf = *buf_p;
+  struct remote_state *rs = get_remote_state ();
 
   csum = 0;
   bc = 0;
@@ -4966,6 +5303,12 @@ read_frame (char **buf_p,
                return -1;
              }
 
+           /* Don't recompute the checksum; with no ack packets we
+              don't have any way to indicate a packet retransmission
+              is necessary.  */
+           if (rs->noack_mode)
+             return bc;
+
            pktcsum = (fromhex (check_0) << 4) | fromhex (check_1);
            if (csum == pktcsum)
               return bc;
@@ -5102,7 +5445,7 @@ getpkt_sane (char **buf, long *sizeof_buf, int forever)
              if (forever)      /* Watchdog went off?  Kill the target.  */
                {
                  QUIT;
-                 target_mourn_inferior ();
+                 pop_target ();
                  error (_("Watchdog timeout has expired.  Target detached."));
                }
              if (remote_debug)
@@ -5124,30 +5467,34 @@ getpkt_sane (char **buf, long *sizeof_buf, int forever)
              fputstrn_unfiltered (*buf, val, 0, gdb_stdlog);
              fprintf_unfiltered (gdb_stdlog, "\n");
            }
-         serial_write (remote_desc, "+", 1);
+
+         /* Skip the ack char if we're in no-ack mode.  */
+         if (!rs->noack_mode)
+           serial_write (remote_desc, "+", 1);
          return val;
        }
 
       /* Try the whole thing again.  */
     retry:
-      serial_write (remote_desc, "-", 1);
+      /* Skip the nack char if we're in no-ack mode.  */
+      if (!rs->noack_mode)
+       serial_write (remote_desc, "-", 1);
     }
 
   /* We have tried hard enough, and just can't receive the packet.
      Give up.  */
 
   printf_unfiltered (_("Ignoring packet error, continuing...\n"));
-  serial_write (remote_desc, "+", 1);
+
+  /* Skip the ack char if we're in no-ack mode.  */
+  if (!rs->noack_mode)
+    serial_write (remote_desc, "+", 1);
   return -1;
 }
 \f
 static void
 remote_kill (void)
 {
-  /* Unregister the file descriptor from the event loop.  */
-  if (target_is_async_p ())
-    serial_async (remote_desc, NULL, 0);
-
   /* Use catch_errors so the user can quit from gdb even when we
      aren't on speaking terms with the remote system.  */
   catch_errors ((catch_errors_ftype *) putpkt, "k", "", RETURN_MASK_ERROR);
@@ -5157,6 +5504,58 @@ remote_kill (void)
   target_mourn_inferior ();
 }
 
+static int
+remote_vkill (int pid, struct remote_state *rs)
+{
+  if (remote_protocol_packets[PACKET_vKill].support == PACKET_DISABLE)
+    return -1;
+
+  /* Tell the remote target to detach.  */
+  sprintf (rs->buf, "vKill;%x", pid);
+  putpkt (rs->buf);
+  getpkt (&rs->buf, &rs->buf_size, 0);
+
+  if (packet_ok (rs->buf,
+                &remote_protocol_packets[PACKET_vKill]) == PACKET_OK)
+    return 0;
+  else if (remote_protocol_packets[PACKET_vKill].support == PACKET_DISABLE)
+    return -1;
+  else
+    return 1;
+}
+
+static void
+extended_remote_kill (void)
+{
+  int res;
+  int pid = ptid_get_pid (inferior_ptid);
+  struct remote_state *rs = get_remote_state ();
+
+  res = remote_vkill (pid, rs);
+  if (res == -1 && !remote_multi_process_p (rs))
+    {
+      /* Don't try 'k' on a multi-process aware stub -- it has no way
+        to specify the pid.  */
+
+      putpkt ("k");
+#if 0
+      getpkt (&rs->buf, &rs->buf_size, 0);
+      if (rs->buf[0] != 'O' || rs->buf[0] != 'K')
+       res = 1;
+#else
+      /* Don't wait for it to die.  I'm not really sure it matters whether
+        we do or not.  For the existing stubs, kill is a noop.  */
+      res = 0;
+#endif
+    }
+
+  if (res != 0)
+    error (_("Can't kill process"));
+
+  delete_inferior (pid);
+  target_mourn_inferior ();
+}
+
 static void
 remote_mourn (void)
 {
@@ -5168,7 +5567,21 @@ static void
 remote_mourn_1 (struct target_ops *target)
 {
   unpush_target (target);
-  generic_mourn_inferior ();
+
+  /* remote_close takes care of cleaning up.  */
+}
+
+static int
+select_new_thread_callback (struct thread_info *th, void* data)
+{
+  if (!ptid_equal (th->ptid, minus_one_ptid))
+    {
+      switch_to_thread (th->ptid);
+      printf_filtered (_("[Switching to %s]\n"),
+                      target_pid_to_str (inferior_ptid));
+      return 1;
+    }
+  return 0;
 }
 
 static void
@@ -5176,30 +5589,52 @@ extended_remote_mourn_1 (struct target_ops *target)
 {
   struct remote_state *rs = get_remote_state ();
 
+  /* In case we got here due to an error, but we're going to stay
+     connected.  */
+  rs->waiting_for_stop_reply = 0;
+
   /* Unlike "target remote", we do not want to unpush the target; then
      the next time the user says "run", we won't be connected.  */
 
-  /* Call common code to mark the inferior as not running.  */
-  generic_mourn_inferior ();
-
-  /* Check whether the target is running now - some remote stubs
-     automatically restart after kill.  */
-  putpkt ("?");
-  getpkt (&rs->buf, &rs->buf_size, 0);
-
-  if (rs->buf[0] == 'S' || rs->buf[0] == 'T')
+  if (have_inferiors ())
     {
-      /* Assume that the target has been restarted.  Set inferior_ptid
-        so that bits of core GDB realizes there's something here, e.g.,
-        so that the user can say "kill" again.  */
-      inferior_ptid = remote_current_thread (magic_null_ptid);
-      add_thread_silent (inferior_ptid);
+      extern void nullify_last_target_wait_ptid ();
+      /* Multi-process case.  The current process has exited, but
+        there are other processes to debug.  Switch to the first
+        available.  */
+      iterate_over_threads (select_new_thread_callback, NULL);
+      nullify_last_target_wait_ptid ();
     }
   else
     {
-      /* Mark this (still pushed) target as not executable until we
-        restart it.  */
-      target_mark_exited (target);
+      struct remote_state *rs = get_remote_state ();
+
+      /* Call common code to mark the inferior as not running. */
+      generic_mourn_inferior ();
+      if (!remote_multi_process_p (rs))
+       {
+         /* Check whether the target is running now - some remote stubs
+            automatically restart after kill.  */
+         putpkt ("?");
+         getpkt (&rs->buf, &rs->buf_size, 0);
+
+         if (rs->buf[0] == 'S' || rs->buf[0] == 'T')
+           {
+             /* Assume that the target has been restarted.  Set inferior_ptid
+                so that bits of core GDB realizes there's something here, e.g.,
+                so that the user can say "kill" again.  */
+             inferior_ptid = magic_null_ptid;
+           }
+         else
+           {
+             /* Mark this (still pushed) target as not executable until we
+                restart it.  */
+             target_mark_exited (target);
+           }
+       }
+      else
+       /* Always remove execution if this was the last process.  */
+       target_mark_exited (target);
     }
 }
 
@@ -5228,13 +5663,14 @@ extended_remote_run (char *args)
     error (_("Remote file name too long for run packet"));
   len += 2 * bin2hex ((gdb_byte *) remote_exec_file, rs->buf + len, 0);
 
+  gdb_assert (args != NULL);
   if (*args)
     {
       struct cleanup *back_to;
       int i;
       char **argv;
 
-      argv = buildargv (args);
+      argv = gdb_buildargv (args);
       back_to = make_cleanup ((void (*) (void *)) freeargv, argv);
       for (i = 0; argv[i] != NULL; i++)
        {
@@ -5306,9 +5742,9 @@ extended_remote_create_inferior_1 (char *exec_file, char *args,
   init_wait_for_inferior ();
 
   /* Now mark the inferior as running before we do anything else.  */
-  attach_flag = 0;
   inferior_ptid = magic_null_ptid;
 
+  add_inferior (ptid_get_pid (inferior_ptid));
   add_thread_silent (inferior_ptid);
 
   target_mark_running (&extended_remote_ops);
@@ -5344,8 +5780,7 @@ remote_insert_breakpoint (struct bp_target_info *bp_tgt)
       char *p;
       int bpsize;
 
-      gdbarch_breakpoint_from_pc
-       (current_gdbarch, &addr, &bpsize);
+      gdbarch_breakpoint_from_pc (target_gdbarch, &addr, &bpsize);
 
       rs = get_remote_state ();
       p = rs->buf;
@@ -5519,7 +5954,7 @@ remote_check_watch_resources (int type, int cnt, int ot)
 static int
 remote_stopped_by_watchpoint (void)
 {
-    return remote_stopped_by_watchpoint_p;
+  return remote_stopped_by_watchpoint_p;
 }
 
 static int
@@ -5547,7 +5982,7 @@ remote_insert_hw_breakpoint (struct bp_target_info *bp_tgt)
      instruction, even though we aren't inserting one ourselves.  */
 
   gdbarch_breakpoint_from_pc
-    (current_gdbarch, &bp_tgt->placed_address, &bp_tgt->placed_size);
+    (target_gdbarch, &bp_tgt->placed_address, &bp_tgt->placed_size);
 
   if (remote_protocol_packets[PACKET_Z1].support == PACKET_DISABLE)
     return -1;
@@ -5612,23 +6047,6 @@ remote_remove_hw_breakpoint (struct bp_target_info *bp_tgt)
                  _("remote_remove_hw_breakpoint: reached end of function"));
 }
 
-/* Some targets are only capable of doing downloads, and afterwards
-   they switch to the remote serial protocol.  This function provides
-   a clean way to get from the download target to the remote target.
-   It's basically just a wrapper so that we don't have to expose any
-   of the internal workings of remote.c.
-
-   Prior to calling this routine, you should shutdown the current
-   target code, else you will get the "A program is being debugged
-   already..." message.  Usually a call to pop_target() suffices.  */
-
-void
-push_remote_target (char *name, int from_tty)
-{
-  printf_filtered (_("Switching to remote protocol\n"));
-  remote_open (name, from_tty);
-}
-
 /* Table used by the crc32 function to calcuate the checksum.  */
 
 static unsigned long crc32_table[256] =
@@ -5877,11 +6295,15 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
                     const char *annex, gdb_byte *readbuf,
                     const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
 {
-  struct remote_state *rs = get_remote_state ();
+  struct remote_state *rs;
   int i;
   char *p2;
   char query_type;
 
+  set_general_thread (inferior_ptid);
+
+  rs = get_remote_state ();
+
   /* Handle memory using the standard memory routines.  */
   if (object == TARGET_OBJECT_MEMORY)
     {
@@ -6360,12 +6782,20 @@ static char *
 remote_pid_to_str (ptid_t ptid)
 {
   static char buf[64];
+  struct remote_state *rs = get_remote_state ();
 
   if (ptid_equal (magic_null_ptid, ptid))
     {
       xsnprintf (buf, sizeof buf, "Thread <main>");
       return buf;
     }
+  else if (remote_multi_process_p (rs)
+          && ptid_get_tid (ptid) != 0 && ptid_get_pid (ptid) != 0)
+    {
+      xsnprintf (buf, sizeof buf, "Thread %d.%ld",
+                ptid_get_pid (ptid), ptid_get_tid (ptid));
+      return buf;
+    }
   else if (ptid_get_tid (ptid) != 0)
     {
       xsnprintf (buf, sizeof buf, "Thread %ld",
@@ -6386,11 +6816,12 @@ remote_get_thread_local_address (ptid_t ptid, CORE_ADDR lm, CORE_ADDR offset)
     {
       struct remote_state *rs = get_remote_state ();
       char *p = rs->buf;
+      char *endp = rs->buf + get_remote_packet_size ();
       enum packet_result result;
 
       strcpy (p, "qGetTLSAddr:");
       p += strlen (p);
-      p += hexnumstr (p, ptid_get_tid (ptid));
+      p = write_ptid (p, endp, ptid);
       *p++ = ',';
       p += hexnumstr (p, offset);
       *p++ = ',';
@@ -6476,7 +6907,7 @@ static const struct target_desc *
 remote_read_description (struct target_ops *target)
 {
   struct remote_g_packet_data *data
-    = gdbarch_data (current_gdbarch, remote_g_packet_data_handle);
+    = gdbarch_data (target_gdbarch, remote_g_packet_data_handle);
 
   if (!VEC_empty (remote_g_packet_guess_s, data->guesses))
     {
@@ -6640,7 +7071,8 @@ remote_hostio_send_command (int command_bytes, int which_packet,
   int ret, bytes_read;
   char *attachment_tmp;
 
-  if (remote_protocol_packets[which_packet].support == PACKET_DISABLE)
+  if (!remote_desc
+      || remote_protocol_packets[which_packet].support == PACKET_DISABLE)
     {
       *remote_errno = FILEIO_ENOSYS;
       return -1;
@@ -6904,6 +7336,97 @@ remote_hostio_close_cleanup (void *opaque)
   remote_hostio_close (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 (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 (fd, &remote_errno);
+
+  return 1;
+}
+
+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 (fd, (char *)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:", 7) == 0;
+}
+
+bfd *
+remote_bfd_open (const char *remote_file, const char *target)
+{
+  return bfd_openr_iovec (remote_file, target,
+                         remote_bfd_iovec_open, NULL,
+                         remote_bfd_iovec_pread,
+                         remote_bfd_iovec_close,
+                         remote_bfd_iovec_stat);
+}
+
 void
 remote_file_put (const char *local_file, const char *remote_file, int from_tty)
 {
@@ -7069,9 +7592,10 @@ remote_put_command (char *args, int from_tty)
   struct cleanup *back_to;
   char **argv;
 
-  argv = buildargv (args);
-  if (argv == NULL)
-    nomem (0);
+  if (args == NULL)
+    error_no_arg (_("file to put"));
+
+  argv = gdb_buildargv (args);
   back_to = make_cleanup_freeargv (argv);
   if (argv[0] == NULL || argv[1] == NULL || argv[2] != NULL)
     error (_("Invalid parameters to remote put"));
@@ -7087,9 +7611,10 @@ remote_get_command (char *args, int from_tty)
   struct cleanup *back_to;
   char **argv;
 
-  argv = buildargv (args);
-  if (argv == NULL)
-    nomem (0);
+  if (args == NULL)
+    error_no_arg (_("file to get"));
+
+  argv = gdb_buildargv (args);
   back_to = make_cleanup_freeargv (argv);
   if (argv[0] == NULL || argv[1] == NULL || argv[2] != NULL)
     error (_("Invalid parameters to remote get"));
@@ -7105,9 +7630,10 @@ remote_delete_command (char *args, int from_tty)
   struct cleanup *back_to;
   char **argv;
 
-  argv = buildargv (args);
-  if (argv == NULL)
-    nomem (0);
+  if (args == NULL)
+    error_no_arg (_("file to delete"));
+
+  argv = gdb_buildargv (args);
   back_to = make_cleanup_freeargv (argv);
   if (argv[0] == NULL || argv[1] != NULL)
     error (_("Invalid parameters to remote delete"));
@@ -7123,6 +7649,14 @@ remote_command (char *args, int from_tty)
   help_list (remote_cmdlist, "remote ", -1, gdb_stdout);
 }
 
+static int remote_target_can_reverse = 1;
+
+static int
+remote_can_execute_reverse (void)
+{
+  return remote_target_can_reverse;
+}
+
 static void
 init_remote_ops (void)
 {
@@ -7171,6 +7705,7 @@ Specify the serial device it is connected to\n\
   remote_ops.to_has_registers = 1;
   remote_ops.to_has_execution = 1;
   remote_ops.to_has_thread_control = tc_schedlock;     /* can lock scheduler */
+  remote_ops.to_can_execute_reverse = remote_can_execute_reverse;
   remote_ops.to_magic = OPS_MAGIC;
   remote_ops.to_memory_map = remote_memory_map;
   remote_ops.to_flash_erase = remote_flash_erase;
@@ -7204,12 +7739,13 @@ Specify the serial device it is connected to (e.g. /dev/ttya).";
   extended_remote_ops.to_mourn_inferior = extended_remote_mourn;
   extended_remote_ops.to_detach = extended_remote_detach;
   extended_remote_ops.to_attach = extended_remote_attach;
+  extended_remote_ops.to_kill = extended_remote_kill;
 }
 
 static int
 remote_can_async_p (void)
 {
-  if (!remote_async_permitted)
+  if (!target_async_permitted)
     /* We only enable async when the user specifically asks for it.  */
     return 0;
 
@@ -7220,7 +7756,7 @@ remote_can_async_p (void)
 static int
 remote_is_async_p (void)
 {
-  if (!remote_async_permitted)
+  if (!target_async_permitted)
     /* We only enable async when the user specifically asks for it.  */
     return 0;
 
@@ -7532,6 +8068,12 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
   add_packet_config_cmd (&remote_protocol_packets[PACKET_vRun],
                         "vRun", "run", 0);
 
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_QStartNoAckMode],
+                        "QStartNoAckMode", "noack", 0);
+
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_vKill],
+                        "vKill", "kill", 0);
+
   /* Keep the old ``set remote Z-packet ...'' working.  Each individual
      Z sub-packet has its own set and show commands, but users may
      have sets to this variable in their .gdbinit files (or in their
@@ -7571,23 +8113,12 @@ Set the remote pathname for \"run\""), _("\
 Show the remote pathname for \"run\""), NULL, NULL, NULL,
                                   &remote_set_cmdlist, &remote_show_cmdlist);
 
-  add_setshow_boolean_cmd ("remote-async", class_maintenance,
-                          &remote_async_permitted_set, _("\
-Set whether gdb controls the remote inferior in asynchronous mode."), _("\
-Show whether gdb controls the remote inferior in asynchronous mode."), _("\
-Tells gdb whether to control the remote inferior in asynchronous mode."),
-                          set_maintenance_remote_async_permitted,
-                          show_maintenance_remote_async_permitted,
-                          &maintenance_set_cmdlist,
-                          &maintenance_show_cmdlist);
-
-
   /* Eventually initialize fileio.  See fileio.c */
   initialize_remote_fileio (remote_set_cmdlist, remote_show_cmdlist);
 
   /* Take advantage of the fact that the LWP field is not used, to tag
      special ptids with it set to != 0.  */
-  magic_null_ptid = ptid_build (0, 1, -1);
-  not_sent_ptid = ptid_build (0, 1, -2);
-  any_thread_ptid = ptid_build (0, 1, 0);
+  magic_null_ptid = ptid_build (42000, 1, -1);
+  not_sent_ptid = ptid_build (42000, 1, -2);
+  any_thread_ptid = ptid_build (42000, 1, 0);
 }
This page took 0.057182 seconds and 4 git commands to generate.