You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
139 lines
4.0 KiB
139 lines
4.0 KiB
Implement qXfer:exec-file:read in gdbserver |
|
|
|
From: Gary Benson <gbenson@redhat.com> |
|
|
|
This commit implements the "qXfer:exec-file:read" packet in gdbserver. |
|
|
|
gdb/gdbserver/ChangeLog: |
|
|
|
* target.h (struct target_ops) <pid_to_exec_file>: New field. |
|
* linux-low.c (linux_target_ops): Initialize pid_to_exec_file. |
|
* server.c (handle_qxfer_exec_file): New function. |
|
(qxfer_packets): Add exec-file entry. |
|
(handle_query): Report qXfer:exec-file:read as supported packet. |
|
--- |
|
gdb/gdbserver/linux-low.c | 19 +++++++++++++++++++ |
|
gdb/gdbserver/server.c | 40 ++++++++++++++++++++++++++++++++++++++++ |
|
gdb/gdbserver/target.h | 7 +++++++ |
|
3 files changed, 66 insertions(+) |
|
|
|
Index: gdb-7.6.1/gdb/gdbserver/linux-low.c |
|
=================================================================== |
|
--- gdb-7.6.1.orig/gdb/gdbserver/linux-low.c 2016-03-15 19:04:39.260193747 +0100 |
|
+++ gdb-7.6.1/gdb/gdbserver/linux-low.c 2016-03-15 19:04:48.841256052 +0100 |
|
@@ -5993,6 +5993,24 @@ |
|
} |
|
#endif /* HAVE_LINUX_BTRACE */ |
|
|
|
+// gdb/nat/linux-procfs.c |
|
+static char * |
|
+linux_proc_pid_to_exec_file (int pid) |
|
+{ |
|
+ static char buf[PATH_MAX]; |
|
+ char name[PATH_MAX]; |
|
+ ssize_t len; |
|
+ |
|
+ xsnprintf (name, PATH_MAX, "/proc/%d/exe", pid); |
|
+ len = readlink (name, buf, PATH_MAX - 1); |
|
+ if (len <= 0) |
|
+ strcpy (buf, name); |
|
+ else |
|
+ buf[len] = '\0'; |
|
+ |
|
+ return buf; |
|
+} |
|
+ |
|
static struct target_ops linux_target_ops = { |
|
linux_create_inferior, |
|
linux_attach, |
|
@@ -6070,6 +6088,7 @@ |
|
NULL, |
|
NULL, |
|
#endif |
|
+ linux_proc_pid_to_exec_file, |
|
}; |
|
|
|
static void |
|
Index: gdb-7.6.1/gdb/gdbserver/server.c |
|
=================================================================== |
|
--- gdb-7.6.1.orig/gdb/gdbserver/server.c 2016-03-15 19:04:39.262193760 +0100 |
|
+++ gdb-7.6.1/gdb/gdbserver/server.c 2016-03-15 19:04:48.842256059 +0100 |
|
@@ -1006,6 +1006,42 @@ |
|
return (*the_target->read_auxv) (offset, readbuf, len); |
|
} |
|
|
|
+/* Handle qXfer:exec-file:read. */ |
|
+ |
|
+static int |
|
+handle_qxfer_exec_file (const char *const_annex, |
|
+ gdb_byte *readbuf, const gdb_byte *writebuf, |
|
+ ULONGEST offset, LONGEST len) |
|
+{ |
|
+ char *annex, *file; |
|
+ ULONGEST pid; |
|
+ int total_len; |
|
+ |
|
+ if (the_target->pid_to_exec_file == NULL || writebuf != NULL) |
|
+ return -2; |
|
+ |
|
+ annex = alloca (strlen (const_annex) + 1); |
|
+ strcpy (annex, const_annex); |
|
+ annex = unpack_varlen_hex (annex, &pid); |
|
+ if (annex[0] != '\0' || pid == 0) |
|
+ return -1; |
|
+ |
|
+ file = (*the_target->pid_to_exec_file) (pid); |
|
+ if (file == NULL) |
|
+ return -1; |
|
+ |
|
+ total_len = strlen (file); |
|
+ |
|
+ if (offset > total_len) |
|
+ return -1; |
|
+ |
|
+ if (offset + len > total_len) |
|
+ len = total_len - offset; |
|
+ |
|
+ memcpy (readbuf, file + offset, len); |
|
+ return len; |
|
+} |
|
+ |
|
/* Handle qXfer:features:read. */ |
|
|
|
static int |
|
@@ -1408,6 +1444,7 @@ |
|
{ |
|
{ "auxv", handle_qxfer_auxv }, |
|
{ "btrace", handle_qxfer_btrace }, |
|
+ { "exec-file", handle_qxfer_exec_file}, |
|
{ "fdpic", handle_qxfer_fdpic}, |
|
{ "features", handle_qxfer_features }, |
|
{ "libraries", handle_qxfer_libraries }, |
|
@@ -1828,6 +1865,9 @@ |
|
if (target_supports_stopped_by_hw_breakpoint ()) |
|
strcat (own_buf, ";hwbreak+"); |
|
|
|
+ if (the_target->pid_to_exec_file != NULL) |
|
+ strcat (own_buf, ";qXfer:exec-file:read+"); |
|
+ |
|
return; |
|
} |
|
|
|
Index: gdb-7.6.1/gdb/gdbserver/target.h |
|
=================================================================== |
|
--- gdb-7.6.1.orig/gdb/gdbserver/target.h 2016-03-15 19:04:39.262193760 +0100 |
|
+++ gdb-7.6.1/gdb/gdbserver/target.h 2016-03-15 19:04:48.842256059 +0100 |
|
@@ -421,6 +421,13 @@ |
|
to break a cyclic dependency. */ |
|
void (*read_btrace) (struct btrace_target_info *, struct buffer *, int type); |
|
|
|
+ /* Return the full absolute name of the executable file that was |
|
+ run to create the process PID. If the executable file cannot |
|
+ be determined, NULL is returned. Otherwise, a pointer to a |
|
+ character string containing the pathname is returned. This |
|
+ string should be copied into a buffer by the client if the string |
|
+ will not be immediately used, or if it must persist. */ |
|
+ char *(*pid_to_exec_file) (int pid); |
|
}; |
|
|
|
extern struct target_ops *the_target;
|
|
|