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.

140 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;