gdbserver: Handle 'v' packet while processing qSymbol.
authorMarcin Kościelnicki <koriakin@0x04.net>
Sat, 12 Mar 2016 13:03:26 +0000 (14:03 +0100)
committerMarcin Kościelnicki <koriakin@0x04.net>
Tue, 29 Mar 2016 23:51:06 +0000 (01:51 +0200)
On powerpc64, qSymbol query may require gdb to read a function
descriptor, sending a vFile packet to gdbserver.  Thus, we need
to handle 'v' packet in look_up_one_symbol.

vFile replies may be quite long, and require reallocating own_buf.
Since handle_v_requests assumes the buffer is the static global own_buf
from server.c and reallocates it, we need to make own_buf global and
use it from look_up_one_symbol instead of using our own auto variable.
I've also done the same change in relocate_instruction, just in case.

On gdb side, in remote_check_symbols, rs->buf may be clobbered by vFile
handling, yet we need its contents for the reply (the symbol name is
stored there).  Allocate a new buffer instead.

This broke fast tracepoints on powerpc64, due to errors in reading IPA
symbols.

gdb/ChangeLog:

* remote.c (remote_check_symbols): Allocate own buffer for reply.

gdbserver/ChangeLog:

* remote-utils.c (look_up_one_symbol): Remove own_buf, handle 'v'
packets.
(relocate_instruction): Remove own_buf.
* server.c (own_buf): Make global.
(handle_v_requests): Make global.
* server.h (own_buf): New declaration.
(handle_v_requests): New prototype.

gdb/ChangeLog
gdb/gdbserver/ChangeLog
gdb/gdbserver/remote-utils.c
gdb/gdbserver/server.c
gdb/gdbserver/server.h
gdb/remote.c

index 0c76434ccf4ea1efd3ccb92a1f80e3b3c81af9c1..f69458b82279a1e69bfbb93c376aa97a72f5e4c4 100644 (file)
@@ -1,3 +1,7 @@
+2016-03-30  Marcin Kościelnicki  <koriakin@0x04.net>
+
+       * remote.c (remote_check_symbols): Allocate own buffer for reply.
+
 2016-03-29  Max Filippov  <jcmvbkbc@gmail.com>
 
        * xtensa-tdep.c (xtensa_frame_cache): Change op1 type to LONGEST.
index 6c6784fe3520644bca5b3f90477d9ccc6839a612..afc4bfcb9f7f83e903ed138419301d57191bc830 100644 (file)
@@ -1,3 +1,13 @@
+2016-03-30  Marcin Kościelnicki  <koriakin@0x04.net>
+
+       * remote-utils.c (look_up_one_symbol): Remove own_buf, handle 'v'
+       packets.
+       (relocate_instruction): Remove own_buf.
+       * server.c (own_buf): Make global.
+       (handle_v_requests): Make global.
+       * server.h (own_buf): New declaration.
+       (handle_v_requests): New prototype.
+
 2016-03-29  Marcin Kościelnicki  <koriakin@0x04.net>
 
        PR 18377
index e7514735621140ead31a198e1a0fc14a0162789a..768d2e9711d87c9538d5d963b06e3d145af9e429 100644 (file)
@@ -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;
 
index ef715e79db6b1dad3cdd0a7d23080327afad423e..9c50929703525f25d06b6ab1ec3a74466ea2ac05 100644 (file)
@@ -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
@@ -2935,7 +2935,7 @@ handle_v_kill (char *own_buf)
 }
 
 /* Handle all of the extended 'v' packets.  */
-static void
+void
 handle_v_requests (char *own_buf, int packet_len, int *new_packet_len)
 {
   if (!disable_packet_vCont)
index 3d78fb319514da258e3bd03dabf3abaf1a04cf2d..51b219153f565568016e145c02dcd74ac8347b12 100644 (file)
@@ -82,6 +82,8 @@ extern int disable_packet_Tthread;
 extern int disable_packet_qC;
 extern int disable_packet_qfThreadInfo;
 
+extern char *own_buf;
+
 extern int run_once;
 extern int multi_process;
 extern int report_fork_events;
@@ -113,6 +115,8 @@ typedef int gdb_fildes_t;
 #include "event-loop.h"
 
 /* Functions from server.c.  */
+extern void handle_v_requests (char *own_buf, int packet_len,
+                              int *new_packet_len);
 extern int handle_serial_event (int err, gdb_client_data client_data);
 extern int handle_target_event (int err, gdb_client_data client_data);
 
index af0a08a2c533f0305970c6e79c54e3c2871118b0..5c407b6bb9cd69a92fa38270fe2407ff0477f19c 100644 (file)
@@ -4335,6 +4335,7 @@ remote_check_symbols (void)
   struct remote_state *rs = get_remote_state ();
   char *msg, *reply, *tmp;
   int end;
+  long reply_size;
   struct cleanup *old_chain;
 
   /* The remote side has no concept of inferiors that aren't running
@@ -4356,13 +4357,15 @@ remote_check_symbols (void)
      because we need both at the same time.  */
   msg = (char *) xmalloc (get_remote_packet_size ());
   old_chain = make_cleanup (xfree, msg);
+  reply = (char *) xmalloc (get_remote_packet_size ());
+  make_cleanup (free_current_contents, &reply);
+  reply_size = get_remote_packet_size ();
 
   /* Invite target to request symbol lookups.  */
 
   putpkt ("qSymbol::");
-  getpkt (&rs->buf, &rs->buf_size, 0);
-  packet_ok (rs->buf, &remote_protocol_packets[PACKET_qSymbol]);
-  reply = rs->buf;
+  getpkt (&reply, &reply_size, 0);
+  packet_ok (reply, &remote_protocol_packets[PACKET_qSymbol]);
 
   while (startswith (reply, "qSymbol:"))
     {
@@ -4390,8 +4393,7 @@ remote_check_symbols (void)
        }
   
       putpkt (msg);
-      getpkt (&rs->buf, &rs->buf_size, 0);
-      reply = rs->buf;
+      getpkt (&reply, &reply_size, 0);
     }
 
   do_cleanups (old_chain);