gdbserver: Handle 'v' packet while processing qSymbol.
[deliverable/binutils-gdb.git] / gdb / gdbserver / remote-utils.c
index c5f4647052c06ad49a8dda3f4715674d96825054..768d2e9711d87c9538d5d963b06e3d145af9e429 100644 (file)
@@ -402,6 +402,11 @@ remote_close (void)
 {
   delete_file_handler (remote_desc);
 
+#ifndef USE_WIN32API
+  /* Remove SIGIO handler.  */
+  signal (SIGIO, SIG_IGN);
+#endif
+
 #ifdef USE_WIN32API
   closesocket (remote_desc);
 #else
@@ -526,7 +531,7 @@ write_ptid (char *buf, ptid_t ptid)
   return buf;
 }
 
-ULONGEST
+static ULONGEST
 hex_or_minus_one (char *buf, char **obuf)
 {
   ULONGEST ret;
@@ -775,19 +780,19 @@ check_remote_input_interrupt_request (void)
   input_interrupt (0);
 }
 
-/* Asynchronous I/O support.  SIGIO must be enabled when waiting, in order to
-   accept Control-C from the client, and must be disabled when talking to
-   the client.  */
+/* Asynchronous I/O support.  SIGIO must be unblocked when waiting,
+   in order to accept Control-C from the client, and must be blocked
+   when talking to the client.  */
 
 static void
-unblock_async_io (void)
+block_unblock_async_io (int block)
 {
 #ifndef USE_WIN32API
   sigset_t sigio_set;
 
   sigemptyset (&sigio_set);
   sigaddset (&sigio_set, SIGIO);
-  sigprocmask (SIG_UNBLOCK, &sigio_set, NULL);
+  sigprocmask (block ? SIG_BLOCK : SIG_UNBLOCK, &sigio_set, NULL);
 #endif
 }
 
@@ -823,9 +828,8 @@ enable_async_io (void)
   if (async_io_enabled)
     return;
 
-#ifndef USE_WIN32API
-  signal (SIGIO, input_interrupt);
-#endif
+  block_unblock_async_io (0);
+
   async_io_enabled = 1;
 #ifdef __QNX__
   nto_comctrl (1);
@@ -839,9 +843,8 @@ disable_async_io (void)
   if (!async_io_enabled)
     return;
 
-#ifndef USE_WIN32API
-  signal (SIGIO, SIG_IGN);
-#endif
+  block_unblock_async_io (1);
+
   async_io_enabled = 0;
 #ifdef __QNX__
   nto_comctrl (0);
@@ -852,12 +855,14 @@ disable_async_io (void)
 void
 initialize_async_io (void)
 {
-  /* Make sure that async I/O starts disabled.  */
+  /* Make sure that async I/O starts blocked.  */
   async_io_enabled = 1;
   disable_async_io ();
 
-  /* Make sure the signal is unblocked.  */
-  unblock_async_io ();
+  /* Install the signal handler.  */
+#ifndef USE_WIN32API
+  signal (SIGIO, input_interrupt);
+#endif
 }
 
 /* Internal buffer used by readchar.
@@ -1041,6 +1046,22 @@ getpkt (char *buf)
        }
     }
 
+  /* The readchar above may have already read a '\003' out of the socket
+     and moved it to the local buffer.  For example, when GDB sends
+     vCont;c immediately followed by interrupt (see
+     gdb.base/interrupt-noterm.exp).  As soon as we see the vCont;c, we'll
+     resume the inferior and wait.  Since we've already moved the '\003'
+     to the local buffer, SIGIO won't help.  In that case, if we don't
+     check for interrupt after the vCont;c packet, the interrupt character
+     would stay in the buffer unattended until after the next (unrelated)
+     stop.  */
+  while (readchar_bufcnt > 0 && *readchar_bufp == '\003')
+    {
+      /* Consume the interrupt character in the buffer.  */
+      readchar ();
+      (*the_target->request_interrupt) ();
+    }
+
   return bp - buf;
 }
 
@@ -1083,39 +1104,6 @@ outreg (struct regcache *regcache, int regno, char *buf)
   return buf;
 }
 
-void
-new_thread_notify (int id)
-{
-  char own_buf[256];
-
-  /* The `n' response is not yet part of the remote protocol.  Do nothing.  */
-  if (1)
-    return;
-
-  if (server_waiting == 0)
-    return;
-
-  sprintf (own_buf, "n%x", id);
-  disable_async_io ();
-  putpkt (own_buf);
-  enable_async_io ();
-}
-
-void
-dead_thread_notify (int id)
-{
-  char own_buf[256];
-
-  /* The `x' response is not yet part of the remote protocol.  Do nothing.  */
-  if (1)
-    return;
-
-  sprintf (own_buf, "x%x", id);
-  disable_async_io ();
-  putpkt (own_buf);
-  enable_async_io ();
-}
-
 void
 prepare_resume_reply (char *buf, ptid_t ptid,
                      struct target_waitstatus *status)
@@ -1132,6 +1120,8 @@ prepare_resume_reply (char *buf, ptid_t ptid,
     case TARGET_WAITKIND_VFORK_DONE:
     case TARGET_WAITKIND_EXECD:
     case TARGET_WAITKIND_THREAD_CREATED:
+    case TARGET_WAITKIND_SYSCALL_ENTRY:
+    case TARGET_WAITKIND_SYSCALL_RETURN:
       {
        struct thread_info *saved_thread;
        const char **regp;
@@ -1181,6 +1171,16 @@ prepare_resume_reply (char *buf, ptid_t ptid,
 
            sprintf (buf, "T%02xcreate:;", signal);
          }
+       else if (status->kind == TARGET_WAITKIND_SYSCALL_ENTRY
+                || status->kind == TARGET_WAITKIND_SYSCALL_RETURN)
+         {
+           enum gdb_signal signal = GDB_SIGNAL_TRAP;
+           const char *event = (status->kind == TARGET_WAITKIND_SYSCALL_ENTRY
+                                ? "syscall_entry" : "syscall_return");
+
+           sprintf (buf, "T%02x%s:%x;", signal, event,
+                    status->value.syscall_number);
+         }
        else
          sprintf (buf, "T%02x", status->value.sig);
 
@@ -1462,7 +1462,7 @@ clear_symbol_cache (struct sym_cache **symcache_p)
 int
 look_up_one_symbol (const char *name, CORE_ADDR *addrp, int may_ask_gdb)
 {
-  char own_buf[266], *p, *q;
+  char *p, *q;
   int len;
   struct sym_cache *sym;
   struct process_info *proc;
@@ -1497,23 +1497,37 @@ look_up_one_symbol (const char *name, CORE_ADDR *addrp, int may_ask_gdb)
   /* We ought to handle pretty much any packet at this point while we
      wait for the qSymbol "response".  That requires re-entering the
      main loop.  For now, this is an adequate approximation; allow
-     GDB to read from memory while it figures out the address of the
-     symbol.  */
-  while (own_buf[0] == 'm')
+     GDB to read from memory and handle 'v' packets (for vFile transfers)
+     while it figures out the address of the symbol.  */
+  while (1)
     {
-      CORE_ADDR mem_addr;
-      unsigned char *mem_buf;
-      unsigned int mem_len;
+      if (own_buf[0] == 'm')
+       {
+         CORE_ADDR mem_addr;
+         unsigned char *mem_buf;
+         unsigned int mem_len;
 
-      decode_m_packet (&own_buf[1], &mem_addr, &mem_len);
-      mem_buf = (unsigned char *) xmalloc (mem_len);
-      if (read_inferior_memory (mem_addr, mem_buf, mem_len) == 0)
-       bin2hex (mem_buf, own_buf, mem_len);
+         decode_m_packet (&own_buf[1], &mem_addr, &mem_len);
+         mem_buf = (unsigned char *) xmalloc (mem_len);
+         if (read_inferior_memory (mem_addr, mem_buf, mem_len) == 0)
+           bin2hex (mem_buf, own_buf, mem_len);
+         else
+           write_enn (own_buf);
+         free (mem_buf);
+         if (putpkt (own_buf) < 0)
+           return -1;
+       }
+      else if (own_buf[0] == 'v')
+       {
+         int new_len = -1;
+         handle_v_requests (own_buf, len, &new_len);
+         if (new_len != -1)
+           putpkt_binary (own_buf, new_len);
+         else
+           putpkt (own_buf);
+       }
       else
-       write_enn (own_buf);
-      free (mem_buf);
-      if (putpkt (own_buf) < 0)
-       return -1;
+       break;
       len = getpkt (own_buf);
       if (len < 0)
        return -1;
@@ -1561,7 +1575,6 @@ look_up_one_symbol (const char *name, CORE_ADDR *addrp, int may_ask_gdb)
 int
 relocate_instruction (CORE_ADDR *to, CORE_ADDR oldloc)
 {
-  char own_buf[266];
   int len;
   ULONGEST written = 0;
 
This page took 0.028079 seconds and 4 git commands to generate.