From f851bc2ecd878a24e9ace0d42859d114d2bb8bc7 Mon Sep 17 00:00:00 2001 From: Philippe Waroquiers Date: Thu, 14 May 2015 19:56:47 +0000 Subject: [PATCH] Implement 'qXfer:exec-file:read' packet in Valgrind gdbserver. Thanks to this packet, with recent GDB (>= 7.9.50.20150514-cvs), the command 'target remote' will automatically load the executable file of the process running under Valgrind. This means you do not need to specify the executable file yourself, GDB will discover it itself. See GDB documentation about 'qXfer:exec-file:read' packet for more info. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15230 --- NEWS | 8 +++++ coregrind/m_gdbserver/server.c | 60 +++++++++++++++++++++++++++++++++- 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index b702d0ade2..40cf7ce75d 100644 --- a/NEWS +++ b/NEWS @@ -48,6 +48,14 @@ Release 3.11.0 is under development, not yet released. * Valgrind can be built with Intel's ICC compiler. The required compiler version is 14.0 or later. +* New and modified GDB server monitor features: + + - With recent GDB (>= 7.9.50.20150514-cvs), the command 'target remote' + will automatically load the executable file of the process running + under Valgrind. This means you do not need to specify the executable + file yourself, GDB will discover it itself. + See GDB documentation about 'qXfer:exec-file:read' packet for more info. + * ==================== FIXED BUGS ==================== The following bugs have been fixed or resolved. Note that "n-i-bz" diff --git a/coregrind/m_gdbserver/server.c b/coregrind/m_gdbserver/server.c index deedddf118..6fb507ddc3 100644 --- a/coregrind/m_gdbserver/server.c +++ b/coregrind/m_gdbserver/server.c @@ -916,6 +916,63 @@ void handle_query (char *arg_own_buf, int *new_packet_len_p) return; } + if (strncmp ("qXfer:exec-file:read:", arg_own_buf, 21) == 0) { + unsigned char *data; + int n; + CORE_ADDR ofs; + unsigned int len; + const char *annex; + unsigned long pid; + const HChar *name; + + /* Reject any annex; grab the offset and length. */ + if (decode_xfer_read (arg_own_buf + 21, &annex, &ofs, &len) < 0) { + strcpy (arg_own_buf, "E00"); + return; + } + + if (strlen(annex) > 0) + pid = strtoul (annex, NULL, 16); + else + pid = 0; + if ((int)pid != VG_(getpid)() && pid != 0) { + VG_(sprintf) (arg_own_buf, + "E.Valgrind gdbserver pid is %d." + " Cannot give info for pid %d", + VG_(getpid)(), (int) pid); + return; + } + + if (len > PBUFSIZ - 2) + len = PBUFSIZ - 2; + data = malloc (len); + + if (!VG_(resolve_filename)(VG_(cl_exec_fd), &name)) { + VG_(sprintf) (arg_own_buf, + "E.Valgrind gdbserver could not" + " resolve pid %d exec filename.", + VG_(getpid)()); + return; + } + + if (ofs >= strlen(name)) + n = -1; + else { + n = strlen(name) - ofs; + VG_(memcpy) (data, name, n); + } + + if (n < 0) + write_enn (arg_own_buf); + else if (n > len) + *new_packet_len_p = write_qxfer_response (arg_own_buf, data, len, 1); + else + *new_packet_len_p = write_qxfer_response (arg_own_buf, data, n, 0); + + free (data); + + return; + } /* Protocol features query. */ if (strncmp ("qSupported", arg_own_buf, 10) == 0 @@ -923,7 +980,7 @@ void handle_query (char *arg_own_buf, int *new_packet_len_p) VG_(sprintf) (arg_own_buf, "PacketSize=%x", PBUFSIZ - 1); /* Note: max packet size including frame and checksum, but without trailing null byte, which is not sent/received. */ - + strcat (arg_own_buf, ";QStartNoAckMode+"); strcat (arg_own_buf, ";QPassSignals+"); if (VG_(client_auxv)) @@ -942,6 +999,7 @@ void handle_query (char *arg_own_buf, int *new_packet_len_p) not properly connect. */ initialize_shadow_low(False); } + strcat (arg_own_buf, ";qXfer:exec-file:read+"); return; } -- 2.47.3