Per-inferior/Inferior-qualified thread IDs
[binutils-gdb.git] / gdb / remote.c
index 5270bd281d370e16ae85434942f2aba712b1c7c8..4a42da8ec27477149733bfe5c3a254044960d0be 100644 (file)
@@ -1,6 +1,6 @@
 /* Remote target communications for serial-line targets in custom GDB protocol
 
-   Copyright (C) 1988-2015 Free Software Foundation, Inc.
+   Copyright (C) 1988-2016 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -119,12 +119,12 @@ struct remote_state;
 
 static int remote_vkill (int pid, struct remote_state *rs);
 
+static void remote_kill_k (void);
+
 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_send (char **buf, long *sizeof_buf_p);
 
 static int readchar (int timeout);
@@ -139,6 +139,8 @@ static int remote_is_async_p (struct target_ops *);
 
 static void remote_async (struct target_ops *ops, int enable);
 
+static void remote_thread_events (struct target_ops *ops, int enable);
+
 static void sync_remote_interrupt_twice (int signo);
 
 static void interrupt_query (void);
@@ -1390,6 +1392,7 @@ enum {
   PACKET_qSupported,
   PACKET_qTStatus,
   PACKET_QPassSignals,
+  PACKET_QCatchSyscalls,
   PACKET_QProgramSignals,
   PACKET_qCRC,
   PACKET_qSearch_memory,
@@ -1436,6 +1439,9 @@ enum {
   /* Support for the QNonStop packet.  */
   PACKET_QNonStop,
 
+  /* Support for the QThreadEvents packet.  */
+  PACKET_QThreadEvents,
+
   /* Support for multi-process extensions.  */
   PACKET_multiprocess_feature,
 
@@ -1480,6 +1486,12 @@ enum {
   /* Support for query supported vCont actions.  */
   PACKET_vContSupported,
 
+  /* Support remote CTRL-C.  */
+  PACKET_vCtrlC,
+
+  /* Support TARGET_WAITKIND_NO_RESUMED.  */
+  PACKET_no_resumed,
+
   PACKET_MAX
 };
 
@@ -1907,7 +1919,8 @@ demand_private_info (ptid_t ptid)
       info->priv = XNEW (struct private_thread_info);
       info->private_dtor = free_private_thread_info;
       info->priv->core = -1;
-      info->priv->extra = 0;
+      info->priv->extra = NULL;
+      info->priv->name = NULL;
     }
 
   return info->priv;
@@ -1975,6 +1988,93 @@ remote_pass_signals (struct target_ops *self,
     }
 }
 
+/* If 'QCatchSyscalls' is supported, tell the remote stub
+   to report syscalls to GDB.  */
+
+static int
+remote_set_syscall_catchpoint (struct target_ops *self,
+                              int pid, int needed, int any_count,
+                              int table_size, int *table)
+{
+  char *catch_packet;
+  enum packet_result result;
+  int n_sysno = 0;
+
+  if (packet_support (PACKET_QCatchSyscalls) == PACKET_DISABLE)
+    {
+      /* Not supported.  */
+      return 1;
+    }
+
+  if (needed && !any_count)
+    {
+      int i;
+
+      /* Count how many syscalls are to be caught (table[sysno] != 0).  */
+      for (i = 0; i < table_size; i++)
+       {
+         if (table[i] != 0)
+           n_sysno++;
+       }
+    }
+
+  if (remote_debug)
+    {
+      fprintf_unfiltered (gdb_stdlog,
+                         "remote_set_syscall_catchpoint "
+                         "pid %d needed %d any_count %d n_sysno %d\n",
+                         pid, needed, any_count, n_sysno);
+    }
+
+  if (needed)
+    {
+      /* Prepare a packet with the sysno list, assuming max 8+1
+        characters for a sysno.  If the resulting packet size is too
+        big, fallback on the non-selective packet.  */
+      const int maxpktsz = strlen ("QCatchSyscalls:1") + n_sysno * 9 + 1;
+
+      catch_packet = xmalloc (maxpktsz);
+      strcpy (catch_packet, "QCatchSyscalls:1");
+      if (!any_count)
+       {
+         int i;
+         char *p;
+
+         p = catch_packet;
+         p += strlen (p);
+
+         /* Add in catch_packet each syscall to be caught (table[i] != 0).  */
+         for (i = 0; i < table_size; i++)
+           {
+             if (table[i] != 0)
+               p += xsnprintf (p, catch_packet + maxpktsz - p, ";%x", i);
+           }
+       }
+      if (strlen (catch_packet) > get_remote_packet_size ())
+       {
+         /* catch_packet too big.  Fallback to less efficient
+            non selective mode, with GDB doing the filtering.  */
+         catch_packet[sizeof ("QCatchSyscalls:1") - 1] = 0;
+       }
+    }
+  else
+    catch_packet = xstrdup ("QCatchSyscalls:0");
+
+  {
+    struct cleanup *old_chain = make_cleanup (xfree, catch_packet);
+    struct remote_state *rs = get_remote_state ();
+
+    putpkt (catch_packet);
+    getpkt (&rs->buf, &rs->buf_size, 0);
+    result = packet_ok (rs->buf, &remote_protocol_packets[PACKET_QCatchSyscalls]);
+    do_cleanups (old_chain);
+    if (result == PACKET_OK)
+      return 0;
+    else
+      return -1;
+  }
+}
+
 /* If 'QProgramSignals' is supported, tell the remote stub what
    signals it should pass through to the inferior when detaching.  */
 
@@ -2086,7 +2186,7 @@ set_general_process (void)
   struct remote_state *rs = get_remote_state ();
 
   /* If the remote can't handle multiple processes, don't bother.  */
-  if (!rs->extended || !remote_multi_process_p (rs))
+  if (!remote_multi_process_p (rs))
     return;
 
   /* We only need to change the remote current thread if it's pointing
@@ -2903,6 +3003,7 @@ remote_newthread_step (threadref *ref, void *data)
 
   item.ptid = ptid_build (pid, threadref_to_int (ref), 0);
   item.core = -1;
+  item.name = NULL;
   item.extra = NULL;
 
   VEC_safe_push (thread_item_t, context->items, &item);
@@ -3068,6 +3169,7 @@ remote_get_threads_with_qthreadinfo (struct target_ops *ops,
 
                  item.ptid = read_ptid (bufp, &bufp);
                  item.core = -1;
+                 item.name = NULL;
                  item.extra = NULL;
 
                  VEC_safe_push (thread_item_t, context->items, &item);
@@ -3867,7 +3969,9 @@ process_initial_stop_replies (int from_tty)
          && thread->suspend.waitstatus_pending_p)
        selected = thread;
 
-      if (lowest_stopped == NULL || thread->num < lowest_stopped->num)
+      if (lowest_stopped == NULL
+         || thread->inf->num < lowest_stopped->inf->num
+         || thread->per_inf_num < lowest_stopped->per_inf_num)
        lowest_stopped = thread;
 
       if (non_stop)
@@ -4453,6 +4557,8 @@ static const struct protocol_feature remote_protocol_features[] = {
     PACKET_qXfer_traceframe_info },
   { "QPassSignals", PACKET_DISABLE, remote_supported_packet,
     PACKET_QPassSignals },
+  { "QCatchSyscalls", PACKET_DISABLE, remote_supported_packet,
+    PACKET_QCatchSyscalls },
   { "QProgramSignals", PACKET_DISABLE, remote_supported_packet,
     PACKET_QProgramSignals },
   { "QStartNoAckMode", PACKET_DISABLE, remote_supported_packet,
@@ -4517,7 +4623,9 @@ static const struct protocol_feature remote_protocol_features[] = {
     PACKET_exec_event_feature },
   { "Qbtrace-conf:pt:size", PACKET_DISABLE, remote_supported_packet,
     PACKET_Qbtrace_conf_pt_size },
-  { "vContSupported", PACKET_DISABLE, remote_supported_packet, PACKET_vContSupported }
+  { "vContSupported", PACKET_DISABLE, remote_supported_packet, PACKET_vContSupported },
+  { "QThreadEvents", PACKET_DISABLE, remote_supported_packet, PACKET_QThreadEvents },
+  { "no-resumed", PACKET_DISABLE, remote_supported_packet, PACKET_no_resumed },
 };
 
 static char *remote_support_xml;
@@ -4594,22 +4702,25 @@ remote_query_supported (void)
 
       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+");
-         if (packet_set_cmd_state (PACKET_exec_event_feature)
-             != AUTO_BOOLEAN_FALSE)
-           q = remote_query_supported_append (q, "exec-events+");
-       }
+      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+");
+      if (packet_set_cmd_state (PACKET_exec_event_feature)
+         != AUTO_BOOLEAN_FALSE)
+       q = remote_query_supported_append (q, "exec-events+");
 
       if (packet_set_cmd_state (PACKET_vContSupported) != AUTO_BOOLEAN_FALSE)
        q = remote_query_supported_append (q, "vContSupported+");
 
+      if (packet_set_cmd_state (PACKET_QThreadEvents) != AUTO_BOOLEAN_FALSE)
+       q = remote_query_supported_append (q, "QThreadEvents+");
+
+      if (packet_set_cmd_state (PACKET_no_resumed) != AUTO_BOOLEAN_FALSE)
+       q = remote_query_supported_append (q, "no-resumed+");
+
       /* Keep this one last to work around a gdbserver <= 7.10 bug in
         the qSupported:xmlRegisters=i386 handling.  */
       if (remote_support_xml != NULL)
@@ -4954,7 +5065,8 @@ remote_detach_1 (const char *args, int from_tty)
   /* Tell the remote target to detach.  */
   remote_detach_pid (pid);
 
-  if (from_tty && !rs->extended)
+  /* Exit only if this is the only active inferior.  */
+  if (from_tty && !rs->extended && number_of_live_inferiors () == 1)
     puts_filtered (_("Ending remote debugging.\n"));
 
   /* Check to see if we are detaching a fork parent.  Note that if we
@@ -5050,10 +5162,11 @@ remote_disconnect (struct target_ops *target, const char *args, int from_tty)
   if (args)
     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 directly instead of
-     target_mourn_inferior.  */
-  remote_mourn (target);
+  /* Make sure we unpush even the extended remote targets.  Calling
+     target_mourn_inferior won't unpush, and remote_mourn won't
+     unpush if there is more than one inferior left.  */
+  unpush_target (target);
+  generic_mourn_inferior ();
 
   if (from_tty)
     puts_filtered ("Ending remote debugging.\n");
@@ -5581,7 +5694,7 @@ async_remote_interrupt (gdb_client_data arg)
   if (remote_debug)
     fprintf_unfiltered (gdb_stdlog, "async_remote_interrupt called\n");
 
-  target_stop (inferior_ptid);
+  target_interrupt (inferior_ptid);
 }
 
 /* Perform interrupt, if the first attempt did not succeed.  Just give
@@ -5688,7 +5801,7 @@ remote_stop_ns (ptid_t ptid)
    process reports the interrupt.  */
 
 static void
-remote_interrupt_as (ptid_t ptid)
+remote_interrupt_as (void)
 {
   struct remote_state *rs = get_remote_state ();
 
@@ -5704,6 +5817,38 @@ remote_interrupt_as (ptid_t ptid)
   send_interrupt_sequence ();
 }
 
+/* Non-stop version of target_interrupt.  Uses `vCtrlC' to interrupt
+   the remote target.  It is undefined which thread of which process
+   reports the interrupt.  Returns true if the packet is supported by
+   the server, false otherwise.  */
+
+static int
+remote_interrupt_ns (void)
+{
+  struct remote_state *rs = get_remote_state ();
+  char *p = rs->buf;
+  char *endp = rs->buf + get_remote_packet_size ();
+
+  xsnprintf (p, endp - p, "vCtrlC");
+
+  /* In non-stop, we get an immediate OK reply.  The stop reply will
+     come in asynchronously by notification.  */
+  putpkt (rs->buf);
+  getpkt (&rs->buf, &rs->buf_size, 0);
+
+  switch (packet_ok (rs->buf, &remote_protocol_packets[PACKET_vCtrlC]))
+    {
+    case PACKET_OK:
+      break;
+    case PACKET_UNKNOWN:
+      return 0;
+    case PACKET_ERROR:
+      error (_("Interrupting target failed: %s"), rs->buf);
+    }
+
+  return 1;
+}
+
 /* Implement the to_stop function for the remote targets.  */
 
 static void
@@ -5718,7 +5863,7 @@ remote_stop (struct target_ops *self, ptid_t ptid)
     {
       /* We don't currently have a way to transparently pause the
         remote target in all-stop mode.  Interrupt it instead.  */
-      remote_interrupt_as (ptid);
+      remote_interrupt_as ();
     }
 }
 
@@ -5730,14 +5875,27 @@ remote_interrupt (struct target_ops *self, ptid_t ptid)
   if (remote_debug)
     fprintf_unfiltered (gdb_stdlog, "remote_interrupt called\n");
 
-  if (target_is_non_stop_p ())
+  if (non_stop)
     {
-      /* We don't currently have a way to ^C the remote target in
-        non-stop mode.  Stop it (with no signal) instead.  */
+      /* In non-stop mode, we always stop with no signal instead.  */
       remote_stop_ns (ptid);
     }
   else
-    remote_interrupt_as (ptid);
+    {
+      /* In all-stop, we emulate ^C-ing the remote target's
+        terminal.  */
+      if (target_is_non_stop_p ())
+       {
+         if (!remote_interrupt_ns ())
+           {
+             /* No support for ^C-ing the remote target.  Stop it
+                (with no signal) instead.  */
+             remote_stop_ns (ptid);
+           }
+       }
+      else
+       remote_interrupt_as ();
+    }
 }
 
 /* Ask the user what to do when an interrupt is received.  */
@@ -5997,10 +6155,9 @@ remove_child_of_pending_fork (QUEUE (stop_reply_p) *q,
     = (struct threads_listing_context *) param->input;
 
   if (event->ws.kind == TARGET_WAITKIND_FORKED
-      || event->ws.kind == TARGET_WAITKIND_VFORKED)
-    {
-      threads_listing_context_remove (&event->ws, context);
-    }
+      || event->ws.kind == TARGET_WAITKIND_VFORKED
+      || event->ws.kind == TARGET_WAITKIND_THREAD_EXITED)
+    threads_listing_context_remove (&event->ws, context);
 
   return 1;
 }
@@ -6306,6 +6463,22 @@ Packet: '%s'\n"),
 
          if (strprefix (p, p1, "thread"))
            event->ptid = read_ptid (++p1, &p);
+         else if (strprefix (p, p1, "syscall_entry"))
+           {
+             ULONGEST sysno;
+
+             event->ws.kind = TARGET_WAITKIND_SYSCALL_ENTRY;
+             p = unpack_varlen_hex (++p1, &sysno);
+             event->ws.value.syscall_number = (int) sysno;
+           }
+         else if (strprefix (p, p1, "syscall_return"))
+           {
+             ULONGEST sysno;
+
+             event->ws.kind = TARGET_WAITKIND_SYSCALL_RETURN;
+             p = unpack_varlen_hex (++p1, &sysno);
+             event->ws.value.syscall_number = (int) sysno;
+           }
          else if (strprefix (p, p1, "watch")
                   || strprefix (p, p1, "rwatch")
                   || strprefix (p, p1, "awatch"))
@@ -6398,6 +6571,11 @@ Packet: '%s'\n"),
                 one used by the original program.  */
              skipregs = 1;
            }
+         else if (strprefix (p, p1, "create"))
+           {
+             event->ws.kind = TARGET_WAITKIND_THREAD_CREATED;
+             p = skip_to_semicolon (p1 + 1);
+           }
          else
            {
              ULONGEST pnum;
@@ -6468,6 +6646,19 @@ Packet: '%s'\n"),
          event->ws.value.sig = GDB_SIGNAL_UNKNOWN;
       }
       break;
+    case 'w':          /* Thread exited.  */
+      {
+       char *p;
+       ULONGEST value;
+
+       event->ws.kind = TARGET_WAITKIND_THREAD_EXITED;
+       p = unpack_varlen_hex (&buf[1], &value);
+       event->ws.value.integer = value;
+       if (*p != ';')
+         error (_("stop reply packet badly formatted: %s"), buf);
+       event->ptid = read_ptid (++p, NULL);
+       break;
+      }
     case 'W':          /* Target exited.  */
     case 'X':
       {
@@ -6522,6 +6713,10 @@ Packet: '%s'\n"),
        event->ptid = pid_to_ptid (pid);
       }
       break;
+    case 'N':
+      event->ws.kind = TARGET_WAITKIND_NO_RESUMED;
+      event->ptid = minus_one_ptid;
+      break;
     }
 
   if (target_is_non_stop_p () && ptid_equal (event->ptid, null_ptid))
@@ -6623,7 +6818,8 @@ process_stop_reply (struct stop_reply *stop_reply,
     ptid = inferior_ptid;
 
   if (status->kind != TARGET_WAITKIND_EXITED
-      && status->kind != TARGET_WAITKIND_SIGNALLED)
+      && status->kind != TARGET_WAITKIND_SIGNALLED
+      && status->kind != TARGET_WAITKIND_NO_RESUMED)
     {
       struct remote_state *rs = get_remote_state ();
       struct private_thread_info *remote_thr;
@@ -6801,7 +6997,7 @@ remote_wait_as (ptid_t ptid, struct target_waitstatus *status, int options)
       remote_fileio_request (buf, rs->ctrlc_pending_p);
       rs->ctrlc_pending_p = 0;
       break;
-    case 'T': case 'S': case 'X': case 'W':
+    case 'N': case 'T': case 'S': case 'X': case 'W':
       {
        struct stop_reply *stop_reply;
 
@@ -6840,7 +7036,9 @@ remote_wait_as (ptid_t ptid, struct target_waitstatus *status, int options)
       break;
     }
 
-  if (status->kind == TARGET_WAITKIND_IGNORE)
+  if (status->kind == TARGET_WAITKIND_NO_RESUMED)
+    return minus_one_ptid;
+  else if (status->kind == TARGET_WAITKIND_IGNORE)
     {
       /* Nothing interesting happened.  If we're doing a non-blocking
         poll, we're done.  Otherwise, go back to waiting.  */
@@ -8710,42 +8908,53 @@ kill_new_fork_children (int pid, struct remote_state *rs)
 }
 
 \f
+/* Target hook to kill the current inferior.  */
+
 static void
 remote_kill (struct target_ops *ops)
 {
+  int res = -1;
+  int pid = ptid_get_pid (inferior_ptid);
+  struct remote_state *rs = get_remote_state ();
 
-  /* Catch errors so the user can quit from gdb even when we
-     aren't on speaking terms with the remote system.  */
-  TRY
+  if (packet_support (PACKET_vKill) != PACKET_DISABLE)
     {
-      putpkt ("k");
-    }
-  CATCH (ex, RETURN_MASK_ERROR)
-    {
-      if (ex.error == TARGET_CLOSE_ERROR)
+      /* 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 == 0)
        {
-         /* If we got an (EOF) error that caused the target
-            to go away, then we're done, that's what we wanted.
-            "k" is susceptible to cause a premature EOF, given
-            that the remote server isn't actually required to
-            reply to "k", and it can happen that it doesn't
-            even get to reply ACK to the "k".  */
+         target_mourn_inferior ();
          return;
        }
+    }
 
-       /* Otherwise, something went wrong.  We didn't actually kill
-          the target.  Just propagate the exception, and let the
-          user or higher layers decide what to do.  */
-       throw_exception (ex);
+  /* If we are in 'target remote' mode and we are killing the only
+     inferior, then we will tell gdbserver to exit and unpush the
+     target.  */
+  if (res == -1 && !remote_multi_process_p (rs)
+      && number_of_live_inferiors () == 1)
+    {
+      remote_kill_k ();
+
+      /* We've killed the remote end, we get to mourn it.  If we are
+        not in extended mode, mourning the inferior also unpushes
+        remote_ops from the target stack, which closes the remote
+        connection.  */
+      target_mourn_inferior ();
+
+      return;
     }
-  END_CATCH
 
-  /* We've killed the remote end, we get to mourn it.  Since this is
-     target remote, single-process, mourning the inferior also
-     unpushes remote_ops.  */
-  target_mourn_inferior ();
+  error (_("Can't kill process"));
 }
 
+/* Send a kill request to the target using the 'vKill' packet.  */
+
 static int
 remote_vkill (int pid, struct remote_state *rs)
 {
@@ -8771,55 +8980,52 @@ remote_vkill (int pid, struct remote_state *rs)
     }
 }
 
+/* Send a kill request to the target using the 'k' packet.  */
+
 static void
-extended_remote_kill (struct target_ops *ops)
+remote_kill_k (void)
 {
-  int res;
-  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)))
+  /* Catch errors so the user can quit from gdb even when we
+     aren't on speaking terms with the remote system.  */
+  TRY
     {
-      /* 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
     }
+  CATCH (ex, RETURN_MASK_ERROR)
+    {
+      if (ex.error == TARGET_CLOSE_ERROR)
+       {
+         /* If we got an (EOF) error that caused the target
+            to go away, then we're done, that's what we wanted.
+            "k" is susceptible to cause a premature EOF, given
+            that the remote server isn't actually required to
+            reply to "k", and it can happen that it doesn't
+            even get to reply ACK to the "k".  */
+         return;
+       }
 
-  if (res != 0)
-    error (_("Can't kill process"));
-
-  target_mourn_inferior ();
+      /* Otherwise, something went wrong.  We didn't actually kill
+        the target.  Just propagate the exception, and let the
+        user or higher layers decide what to do.  */
+      throw_exception (ex);
+    }
+  END_CATCH
 }
 
 static void
 remote_mourn (struct target_ops *target)
 {
-  unpush_target (target);
+  struct remote_state *rs = get_remote_state ();
 
-  /* remote_close takes care of doing most of the clean up.  */
-  generic_mourn_inferior ();
-}
+  /* In 'target remote' mode with one inferior, we close the connection.  */
+  if (!rs->extended && number_of_live_inferiors () <= 1)
+    {
+      unpush_target (target);
 
-static void
-extended_remote_mourn (struct target_ops *target)
-{
-  struct remote_state *rs = get_remote_state ();
+      /* remote_close takes care of doing most of the clean up.  */
+      generic_mourn_inferior ();
+      return;
+    }
 
   /* In case we got here due to an error, but we're going to stay
      connected.  */
@@ -8850,10 +9056,7 @@ extended_remote_mourn (struct target_ops *target)
      current thread.  */
   record_currthread (rs, minus_one_ptid);
 
-  /* 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.     */
+  /* Call common code to mark the inferior as not running.  */
   generic_mourn_inferior ();
 
   if (!have_inferiors ())
@@ -10375,7 +10578,7 @@ 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))
+      else if (remote_multi_process_p (rs))
        if (ptid_get_lwp (ptid) == 0)
          return normal_pid_to_str (ptid);
        else
@@ -11545,11 +11748,7 @@ remote_supports_multi_process (struct target_ops *self)
 {
   struct remote_state *rs = get_remote_state ();
 
-  /* Only extended-remote handles being attached to multiple
-     processes, even though plain remote can use the multi-process
-     thread id extensions, so that GDB knows the target process's
-     PID.  */
-  return rs->extended && remote_multi_process_p (rs);
+  return remote_multi_process_p (rs);
 }
 
 static int
@@ -12885,6 +13084,7 @@ Specify the serial device it is connected to\n\
   remote_ops.to_load = remote_load;
   remote_ops.to_mourn_inferior = remote_mourn;
   remote_ops.to_pass_signals = remote_pass_signals;
+  remote_ops.to_set_syscall_catchpoint = remote_set_syscall_catchpoint;
   remote_ops.to_program_signals = remote_program_signals;
   remote_ops.to_thread_alive = remote_thread_alive;
   remote_ops.to_thread_name = remote_thread_name;
@@ -12917,6 +13117,7 @@ Specify the serial device it is connected to\n\
   remote_ops.to_can_async_p = remote_can_async_p;
   remote_ops.to_is_async_p = remote_is_async_p;
   remote_ops.to_async = remote_async;
+  remote_ops.to_thread_events = remote_thread_events;
   remote_ops.to_can_do_single_step = remote_can_do_single_step;
   remote_ops.to_terminal_inferior = remote_terminal_inferior;
   remote_ops.to_terminal_ours = remote_terminal_ours;
@@ -12980,6 +13181,14 @@ Specify the serial device it is connected to\n\
   remote_ops.to_btrace_conf = remote_btrace_conf;
   remote_ops.to_augmented_libraries_svr4_read =
     remote_augmented_libraries_svr4_read;
+  remote_ops.to_follow_fork = remote_follow_fork;
+  remote_ops.to_follow_exec = remote_follow_exec;
+  remote_ops.to_insert_fork_catchpoint = remote_insert_fork_catchpoint;
+  remote_ops.to_remove_fork_catchpoint = remote_remove_fork_catchpoint;
+  remote_ops.to_insert_vfork_catchpoint = remote_insert_vfork_catchpoint;
+  remote_ops.to_remove_vfork_catchpoint = remote_remove_vfork_catchpoint;
+  remote_ops.to_insert_exec_catchpoint = remote_insert_exec_catchpoint;
+  remote_ops.to_remove_exec_catchpoint = remote_remove_exec_catchpoint;
 }
 
 /* Set up the extended remote vector by making a copy of the standard
@@ -12998,27 +13207,11 @@ init_extended_remote_ops (void)
 Specify the serial device it is connected to (e.g. /dev/ttya).";
   extended_remote_ops.to_open = extended_remote_open;
   extended_remote_ops.to_create_inferior = extended_remote_create_inferior;
-  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_post_attach = extended_remote_post_attach;
-  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_follow_exec = remote_follow_exec;
-  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;
-  extended_remote_ops.to_insert_exec_catchpoint
-    = remote_insert_exec_catchpoint;
-  extended_remote_ops.to_remove_exec_catchpoint
-    = remote_remove_exec_catchpoint;
 }
 
 static int
@@ -13102,6 +13295,37 @@ remote_async (struct target_ops *ops, int enable)
     }
 }
 
+/* Implementation of the to_thread_events method.  */
+
+static void
+remote_thread_events (struct target_ops *ops, int enable)
+{
+  struct remote_state *rs = get_remote_state ();
+  size_t size = get_remote_packet_size ();
+  char *p = rs->buf;
+
+  if (packet_support (PACKET_QThreadEvents) == PACKET_DISABLE)
+    return;
+
+  xsnprintf (rs->buf, size, "QThreadEvents:%x", enable ? 1 : 0);
+  putpkt (rs->buf);
+  getpkt (&rs->buf, &rs->buf_size, 0);
+
+  switch (packet_ok (rs->buf,
+                    &remote_protocol_packets[PACKET_QThreadEvents]))
+    {
+    case PACKET_OK:
+      if (strcmp (rs->buf, "OK") != 0)
+       error (_("Remote refused setting thread events: %s"), rs->buf);
+      break;
+    case PACKET_ERROR:
+      warning (_("Remote failure reply: %s"), rs->buf);
+      break;
+    case PACKET_UNKNOWN:
+      break;
+    }
+}
+
 static void
 set_remote_cmd (char *args, int from_tty)
 {
@@ -13427,6 +13651,9 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
   add_packet_config_cmd (&remote_protocol_packets[PACKET_QPassSignals],
                         "QPassSignals", "pass-signals", 0);
 
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_QCatchSyscalls],
+                        "QCatchSyscalls", "catch-syscalls", 0);
+
   add_packet_config_cmd (&remote_protocol_packets[PACKET_QProgramSignals],
                         "QProgramSignals", "program-signals", 0);
 
@@ -13643,6 +13870,15 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
   add_packet_config_cmd (&remote_protocol_packets[PACKET_exec_event_feature],
                         "exec-event-feature", "exec-event-feature", 0);
 
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_vCtrlC],
+                        "vCtrlC", "ctrl-c", 0);
+
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_QThreadEvents],
+                        "QThreadEvents", "thread-events", 0);
+
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_no_resumed],
+                        "N stop reply", "no-resumed-stop-reply", 0);
+
   /* Assert that we've registered "set remote foo-packet" commands
      for all packet configs.  */
   {