gdbserver: Handle 'v' packet while processing qSymbol.
[deliverable/binutils-gdb.git] / gdb / gdbserver / server.c
index 5e053b39b10b6a9dcb0173a9f8875617cb81a1a9..9c50929703525f25d06b6ab1ec3a74466ea2ac05 100644 (file)
@@ -1,5 +1,5 @@
 /* Main code for remote server for GDB.
-   Copyright (C) 1989-2015 Free Software Foundation, Inc.
+   Copyright (C) 1989-2016 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -49,7 +49,7 @@ ptid_t general_thread;
 
 int server_waiting;
 
-int extended_protocol;
+static int extended_protocol;
 static int response_needed;
 static int exit_requested;
 
@@ -119,7 +119,7 @@ int disable_packet_qfThreadInfo;
 static struct target_waitstatus last_status;
 static ptid_t last_ptid;
 
-static char *own_buf;
+char *own_buf;
 static unsigned char *mem_buf;
 
 /* A sub-class of 'struct notif_event' for stop, holding information
@@ -282,7 +282,7 @@ start_inferior (char **argv)
            }
          while (last_status.value.sig != GDB_SIGNAL_TRAP);
        }
-      target_arch_setup ();
+      target_post_create_inferior ();
       return signal_pid;
     }
 
@@ -290,7 +290,7 @@ start_inferior (char **argv)
      (assuming success).  */
   last_ptid = mywait (pid_to_ptid (signal_pid), &last_status, 0, 0);
 
-  target_arch_setup ();
+  target_post_create_inferior ();
 
   if (last_status.kind != TARGET_WAITKIND_EXITED
       && last_status.kind != TARGET_WAITKIND_SIGNALLED)
@@ -420,7 +420,7 @@ handle_btrace_enable_bts (struct thread_info *thread)
   return NULL;
 }
 
-/* Handle btrace enabling in Intel(R) Processor Trace format.  */
+/* Handle btrace enabling in Intel Processor Trace format.  */
 
 static const char *
 handle_btrace_enable_pt (struct thread_info *thread)
@@ -624,6 +624,54 @@ handle_general_set (char *own_buf)
       return;
     }
 
+  if (startswith (own_buf, "QCatchSyscalls:"))
+    {
+      const char *p = own_buf + sizeof ("QCatchSyscalls:") - 1;
+      int enabled = -1;
+      CORE_ADDR sysno;
+      struct process_info *process;
+
+      if (!target_running () || !target_supports_catch_syscall ())
+       {
+         write_enn (own_buf);
+         return;
+       }
+
+      if (strcmp (p, "0") == 0)
+       enabled = 0;
+      else if (p[0] == '1' && (p[1] == ';' || p[1] == '\0'))
+       enabled = 1;
+      else
+       {
+         fprintf (stderr, "Unknown catch-syscalls mode requested: %s\n",
+                  own_buf);
+         write_enn (own_buf);
+         return;
+       }
+
+      process = current_process ();
+      VEC_truncate (int, process->syscalls_to_catch, 0);
+
+      if (enabled)
+       {
+         p += 1;
+         if (*p == ';')
+           {
+             p += 1;
+             while (*p != '\0')
+               {
+                 p = decode_address_to_semicolon (&sysno, p);
+                 VEC_safe_push (int, process->syscalls_to_catch, (int) sysno);
+               }
+           }
+         else
+           VEC_safe_push (int, process->syscalls_to_catch, ANY_SYSCALL);
+       }
+
+      write_ok (own_buf);
+      return;
+    }
+
   if (strcmp (own_buf, "QStartNoAckMode") == 0)
     {
       if (remote_debug)
@@ -805,7 +853,7 @@ get_features_xml (const char *annex)
   return NULL;
 }
 
-void
+static void
 monitor_show_help (void)
 {
   monitor_output ("The following monitor commands are supported:\n");
@@ -1911,11 +1959,6 @@ handle_qxfer (char *own_buf, int packet_len, int *new_packet_len_p)
   return 0;
 }
 
-/* Table used by the crc32 function to calcuate the checksum.  */
-
-static unsigned int crc32_table[256] =
-{0, 0};
-
 /* Compute 32 bit CRC from inferior memory.
 
    On success, return 32 bit CRC.
@@ -1924,20 +1967,6 @@ static unsigned int crc32_table[256] =
 static unsigned long long
 crc32 (CORE_ADDR base, int len, unsigned int crc)
 {
-  if (!crc32_table[1])
-    {
-      /* Initialize the CRC table and the decoding table.  */
-      int i, j;
-      unsigned int c;
-
-      for (i = 0; i < 256; i++)
-       {
-         for (c = i << 24, j = 8; j > 0; --j)
-           c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
-         crc32_table[i] = c;
-       }
-    }
-
   while (len--)
     {
       unsigned char byte = 0;
@@ -1946,7 +1975,7 @@ crc32 (CORE_ADDR base, int len, unsigned int crc)
       if (read_inferior_memory (base, &byte, 1) != 0)
        return (unsigned long long) -1;
 
-      crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ byte) & 255];
+      crc = xcrc32 (&byte, 1, crc);
       base++;
     }
   return (unsigned long long) crc;
@@ -1985,7 +2014,7 @@ supported_btrace_packets (char *buf)
 
 /* Handle all of the extended 'q' packets.  */
 
-void
+static void
 handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
 {
   static struct inferior_list_entry *thread_ptr;
@@ -2219,6 +2248,9 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
               "PacketSize=%x;QPassSignals+;QProgramSignals+",
               PBUFSIZ - 1);
 
+      if (target_supports_catch_syscall ())
+       strcat (own_buf, ";QCatchSyscalls+");
+
       if (the_target->qxfer_libraries_svr4 != NULL)
        strcat (own_buf, ";qXfer:libraries-svr4:read+"
                ";augmented-libraries-svr4-read+");
@@ -2290,13 +2322,9 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
          strcat (own_buf, ";tracenz+");
        }
 
-      if (target_supports_hardware_single_step ())
+      if (target_supports_hardware_single_step ()
+         || target_supports_software_single_step () )
        {
-         /* Support target-side breakpoint conditions and commands.
-            GDBserver needs to step over the breakpoint if the condition
-            is false.  GDBserver software single step is too simple, so
-            disable conditional breakpoints if the target doesn't have
-            hardware single step.  */
          strcat (own_buf, ";ConditionalBreakpoints+");
        }
       strcat (own_buf, ";BreakpointCommands+");
@@ -2591,7 +2619,7 @@ handle_pending_status (const struct thread_resume *resumption,
 }
 
 /* Parse vCont packets.  */
-void
+static void
 handle_v_cont (char *own_buf)
 {
   char *p, *q;
@@ -2758,7 +2786,7 @@ resume (struct thread_resume *actions, size_t num_actions)
 }
 
 /* Attach to a new program.  Return 1 if successful, 0 if failure.  */
-int
+static int
 handle_v_attach (char *own_buf)
 {
   int pid;
@@ -2881,7 +2909,7 @@ handle_v_run (char *own_buf)
 }
 
 /* Kill process.  Return 1 if successful, 0 if failure.  */
-int
+static int
 handle_v_kill (char *own_buf)
 {
   int pid;
@@ -3241,7 +3269,7 @@ static void
 gdbserver_version (void)
 {
   printf ("GNU gdbserver %s%s\n"
-         "Copyright (C) 2015 Free Software Foundation, Inc.\n"
+         "Copyright (C) 2016 Free Software Foundation, Inc.\n"
          "gdbserver is free software, covered by the "
          "GNU General Public License.\n"
          "This gdbserver was configured as \"%s\"\n",
@@ -3792,15 +3820,6 @@ main (int argc, char *argv[])
   gdb_assert_not_reached ("captured_main should never return");
 }
 
-/* Skip PACKET until the next semi-colon (or end of string).  */
-
-static void
-skip_to_semicolon (char **packet)
-{
-  while (**packet != '\0' && **packet != ';')
-    (*packet)++;
-}
-
 /* Process options coming from Z packets for a breakpoint.  PACKET is
    the packet buffer.  *PACKET is updated to point to the first char
    after the last processed option.  */
@@ -3828,7 +3847,7 @@ process_point_options (struct breakpoint *bp, char **packet)
          if (debug_threads)
            debug_printf ("Found breakpoint condition.\n");
          if (!add_breakpoint_condition (bp, &dataptr))
-           skip_to_semicolon (&dataptr);
+           dataptr = strchrnul (dataptr, ';');
        }
       else if (startswith (dataptr, "cmds:"))
        {
@@ -3838,14 +3857,14 @@ process_point_options (struct breakpoint *bp, char **packet)
          persist = (*dataptr == '1');
          dataptr += 2;
          if (add_breakpoint_commands (bp, &dataptr, persist))
-           skip_to_semicolon (&dataptr);
+           dataptr = strchrnul (dataptr, ';');
        }
       else
        {
          fprintf (stderr, "Unknown token %c, ignoring.\n",
                   *dataptr);
          /* Skip tokens until we find one that we recognize.  */
-         skip_to_semicolon (&dataptr);
+         dataptr = strchrnul (dataptr, ';');
        }
     }
   *packet = dataptr;
@@ -3959,9 +3978,11 @@ process_serial_event (void)
          discard_queued_stop_replies (pid_to_ptid (pid));
          write_ok (own_buf);
 
-         if (extended_protocol)
+         if (extended_protocol || target_running ())
            {
-             /* Treat this like a normal program exit.  */
+             /* There is still at least one inferior remaining or
+                we are in extended mode, so don't terminate gdbserver,
+                and instead treat this like a normal program exit.  */
              last_status.kind = TARGET_WAITKIND_EXITED;
              last_status.value.integer = 0;
              last_ptid = pid_to_ptid (pid);
This page took 0.033937 seconds and 4 git commands to generate.