Modernize configure.ac's
[deliverable/binutils-gdb.git] / gdb / remote.c
index 528d863762cc5720fc682ca2aba5a97824622631..6d56f1908d69c203c614d467e2f4d86d2e261b8b 100644 (file)
@@ -766,7 +766,6 @@ int
 remote_register_number_and_offset (struct gdbarch *gdbarch, int regnum,
                                   int *pnum, int *poffset)
 {
-  int sizeof_g_packet;
   struct packet_reg *regs;
   struct cleanup *old_chain;
 
@@ -775,7 +774,7 @@ remote_register_number_and_offset (struct gdbarch *gdbarch, int regnum,
   regs = XCNEWVEC (struct packet_reg, gdbarch_num_regs (gdbarch));
   old_chain = make_cleanup (xfree, regs);
 
-  sizeof_g_packet = map_regcache_remote_table (gdbarch, regs);
+  map_regcache_remote_table (gdbarch, regs);
 
   *pnum = regs[regnum].pnum;
   *poffset = regs[regnum].offset;
@@ -1392,6 +1391,7 @@ enum {
   PACKET_qSupported,
   PACKET_qTStatus,
   PACKET_QPassSignals,
+  PACKET_QCatchSyscalls,
   PACKET_QProgramSignals,
   PACKET_qCRC,
   PACKET_qSearch_memory,
@@ -1987,6 +1987,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 = (char *) 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.  */
 
@@ -2114,9 +2201,6 @@ set_general_process (void)
 static int
 remote_thread_always_alive (struct target_ops *ops, ptid_t ptid)
 {
-  struct remote_state *rs = get_remote_state ();
-  char *p, *endp;
-
   if (ptid_equal (ptid, magic_null_ptid))
     /* The main thread is always alive.  */
     return 1;
@@ -3109,7 +3193,6 @@ remote_get_threads_with_qthreadinfo (struct target_ops *ops,
 static void
 remote_update_thread_list (struct target_ops *ops)
 {
-  struct remote_state *rs = get_remote_state ();
   struct threads_listing_context context;
   struct cleanup *old_chain;
   int got_list = 0;
@@ -3865,8 +3948,6 @@ process_initial_stop_replies (int from_tty)
      that as current.  */
   ALL_NON_EXITED_THREADS (thread)
     {
-      struct target_waitstatus *ws;
-
       if (first == NULL)
        first = thread;
 
@@ -3875,13 +3956,13 @@ process_initial_stop_replies (int from_tty)
       else if (thread->state != THREAD_STOPPED)
        continue;
 
-      ws = &thread->suspend.waitstatus;
-
       if (selected == NULL
          && 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)
@@ -4028,10 +4109,6 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
 
   if (!target_is_non_stop_p ())
     {
-      ptid_t ptid;
-      int fake_pid_p = 0;
-      struct inferior *inf;
-
       if (rs->buf[0] == 'W' || rs->buf[0] == 'X')
        {
          if (!extended_p)
@@ -4251,7 +4328,6 @@ remote_check_symbols (void)
 {
   struct remote_state *rs = get_remote_state ();
   char *msg, *reply, *tmp;
-  struct bound_minimal_symbol sym;
   int end;
   struct cleanup *old_chain;
 
@@ -4467,6 +4543,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,
@@ -6132,7 +6210,6 @@ remove_stop_reply_for_inferior (QUEUE (stop_reply_p) *q,
 static void
 discard_pending_stop_replies (struct inferior *inf)
 {
-  int i;
   struct queue_iter_param param;
   struct stop_reply *reply;
   struct remote_state *rs = get_remote_state ();
@@ -6295,16 +6372,6 @@ peek_stop_reply (ptid_t ptid)
                         stop_reply_match_ptid_and_ws, &ptid);
 }
 
-/* Skip PACKET until the next semi-colon (or end of string).  */
-
-static char *
-skip_to_semicolon (char *p)
-{
-  while (*p != '\0' && *p != ';')
-    p++;
-  return p;
-}
-
 /* Helper for remote_parse_stop_reply.  Return nonzero if the substring
    starting with P and ending with PEND matches PREFIX.  */
 
@@ -6371,6 +6438,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"))
@@ -6391,7 +6474,7 @@ Packet: '%s'\n"),
              /* The value part is documented as "must be empty",
                 though we ignore it, in case we ever decide to make
                 use of it in a backward compatible way.  */
-             p = skip_to_semicolon (p1 + 1);
+             p = strchrnul (p1 + 1, ';');
            }
          else if (strprefix (p, p1, "hwbreak"))
            {
@@ -6403,19 +6486,19 @@ Packet: '%s'\n"),
                error (_("Unexpected hwbreak stop reason"));
 
              /* See above.  */
-             p = skip_to_semicolon (p1 + 1);
+             p = strchrnul (p1 + 1, ';');
            }
          else if (strprefix (p, p1, "library"))
            {
              event->ws.kind = TARGET_WAITKIND_LOADED;
-             p = skip_to_semicolon (p1 + 1);
+             p = strchrnul (p1 + 1, ';');
            }
          else if (strprefix (p, p1, "replaylog"))
            {
              event->ws.kind = TARGET_WAITKIND_NO_HISTORY;
              /* p1 will indicate "begin" or "end", but it makes
                 no difference for now, so ignore it.  */
-             p = skip_to_semicolon (p1 + 1);
+             p = strchrnul (p1 + 1, ';');
            }
          else if (strprefix (p, p1, "core"))
            {
@@ -6437,7 +6520,7 @@ Packet: '%s'\n"),
          else if (strprefix (p, p1, "vforkdone"))
            {
              event->ws.kind = TARGET_WAITKIND_VFORK_DONE;
-             p = skip_to_semicolon (p1 + 1);
+             p = strchrnul (p1 + 1, ';');
            }
          else if (strprefix (p, p1, "exec"))
            {
@@ -6466,7 +6549,7 @@ Packet: '%s'\n"),
          else if (strprefix (p, p1, "create"))
            {
              event->ws.kind = TARGET_WAITKIND_THREAD_CREATED;
-             p = skip_to_semicolon (p1 + 1);
+             p = strchrnul (p1 + 1, ';');
            }
          else
            {
@@ -6475,7 +6558,7 @@ Packet: '%s'\n"),
 
              if (skipregs)
                {
-                 p = skip_to_semicolon (p1 + 1);
+                 p = strchrnul (p1 + 1, ';');
                  p++;
                  continue;
                }
@@ -6512,7 +6595,7 @@ Packet: '%s'\n"),
                {
                  /* Not a number.  Silently skip unknown optional
                     info.  */
-                 p = skip_to_semicolon (p1 + 1);
+                 p = strchrnul (p1 + 1, ';');
                }
            }
 
@@ -6713,7 +6796,6 @@ process_stop_reply (struct stop_reply *stop_reply,
       && status->kind != TARGET_WAITKIND_SIGNALLED
       && status->kind != TARGET_WAITKIND_NO_RESUMED)
     {
-      struct remote_state *rs = get_remote_state ();
       struct private_thread_info *remote_thr;
 
       /* Expedited registers.  */
@@ -6886,8 +6968,16 @@ remote_wait_as (ptid_t ptid, struct target_waitstatus *status, int options)
       status->value.sig = GDB_SIGNAL_0;
       break;
     case 'F':          /* File-I/O request.  */
+      /* GDB may access the inferior memory while handling the File-I/O
+        request, but we don't want GDB accessing memory while waiting
+        for a stop reply.  See the comments in putpkt_binary.  Set
+        waiting_for_stop_reply to 0 temporarily.  */
+      rs->waiting_for_stop_reply = 0;
       remote_fileio_request (buf, rs->ctrlc_pending_p);
       rs->ctrlc_pending_p = 0;
+      /* GDB handled the File-I/O request, and the target is running
+        again.  Keep waiting for events.  */
+      rs->waiting_for_stop_reply = 1;
       break;
     case 'N': case 'T': case 'S': case 'X': case 'W':
       {
@@ -8183,7 +8273,6 @@ putpkt_binary (const char *buf, int cnt)
   int ch;
   int tcount = 0;
   char *p;
-  char *message;
 
   /* Catch cases like trying to read memory or listing threads while
      we're waiting for a stop reply.  The remote server wouldn't be
@@ -8563,9 +8652,7 @@ getpkt (char **buf,
        long *sizeof_buf,
        int forever)
 {
-  int timed_out;
-
-  timed_out = getpkt_sane (buf, sizeof_buf, forever);
+  getpkt_sane (buf, sizeof_buf, forever);
 }
 
 
@@ -9128,8 +9215,6 @@ remote_add_target_side_condition (struct gdbarch *gdbarch,
 {
   struct agent_expr *aexpr = NULL;
   int i, ix;
-  char *pkt;
-  char *buf_start = buf;
 
   if (VEC_empty (agent_expr_p, bp_tgt->conditions))
     return 0;
@@ -9201,7 +9286,6 @@ remote_insert_breakpoint (struct target_ops *ops,
       struct remote_state *rs;
       char *p, *endbuf;
       int bpsize;
-      struct condition_list *cond = NULL;
 
       /* Make sure the remote is pointing at the right process, if
         necessary.  */
@@ -9456,8 +9540,6 @@ remote_stopped_by_sw_breakpoint (struct target_ops *ops)
 static int
 remote_supports_stopped_by_sw_breakpoint (struct target_ops *ops)
 {
-  struct remote_state *rs = get_remote_state ();
-
   return (packet_support (PACKET_swbreak_feature) == PACKET_ENABLE);
 }
 
@@ -9478,8 +9560,6 @@ remote_stopped_by_hw_breakpoint (struct target_ops *ops)
 static int
 remote_supports_stopped_by_hw_breakpoint (struct target_ops *ops)
 {
-  struct remote_state *rs = get_remote_state ();
-
   return (packet_support (PACKET_hwbreak_feature) == PACKET_ENABLE);
 }
 
@@ -9945,8 +10025,6 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
   /* Only handle flash writes.  */
   if (writebuf != NULL)
     {
-      LONGEST xfered;
-
       switch (object)
        {
        case TARGET_OBJECT_FLASH:
@@ -12814,7 +12892,6 @@ remote_read_btrace (struct target_ops *self,
                    enum btrace_read_type type)
 {
   struct packet_config *packet = &remote_protocol_packets[PACKET_qXfer_btrace];
-  struct remote_state *rs = get_remote_state ();
   struct cleanup *cleanup;
   const char *annex;
   char *xml;
@@ -12976,6 +13053,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;
@@ -13140,8 +13218,6 @@ static serial_event_ftype remote_async_serial_handler;
 static void
 remote_async_serial_handler (struct serial *scb, void *context)
 {
-  struct remote_state *rs = (struct remote_state *) context;
-
   /* Don't propogate error information up to the client.  Instead let
      the client find out about the error by querying the target.  */
   inferior_event_handler (INF_REG_EVENT, NULL);
@@ -13193,7 +13269,6 @@ 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;
@@ -13359,7 +13434,6 @@ set_range_stepping (char *ignore_args, int from_tty,
 void
 _initialize_remote (void)
 {
-  struct remote_state *rs;
   struct cmd_list_element *cmd;
   const char *cmd_name;
 
@@ -13542,6 +13616,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);
 
This page took 0.033882 seconds and 4 git commands to generate.