aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/gdbserver/linux-low.c37
-rw-r--r--gdb/gdbserver/server.c26
-rw-r--r--gdb/gdbserver/target.h8
3 files changed, 62 insertions, 9 deletions
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 501bb58..90efd01 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -597,7 +597,7 @@ linux_wait_for_event (struct thread_info *child)
/* If we were single-stepping, we definitely want to report the
SIGTRAP. The single-step operation has completed, so also
- clear the stepping flag; in general this does not matter,
+ clear the stepping flag; in general this does not matter,
because the SIGTRAP will be reported to the client, which
will give us a new action for this thread, but clear it for
consistency anyway. It's safe to clear the stepping flag
@@ -841,7 +841,7 @@ linux_resume_one_process (struct inferior_list_entry *entry,
check_removed_breakpoint (process);
- if (debug_threads && the_low_target.get_pc != NULL)
+ if (debug_threads && the_low_target.get_pc != NULL)
{
fprintf (stderr, " ");
(long) (*the_low_target.get_pc) ();
@@ -1283,11 +1283,11 @@ linux_read_memory (CORE_ADDR memaddr, char *myaddr, int len)
/* Round starting address down to longword boundary. */
register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE);
/* Round ending address up; get number of longwords that makes. */
- register int count
- = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1)
+ register int count
+ = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1)
/ sizeof (PTRACE_XFER_TYPE);
/* Allocate buffer of that many longwords. */
- register PTRACE_XFER_TYPE *buffer
+ register PTRACE_XFER_TYPE *buffer
= (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE));
/* Read all the longwords */
@@ -1381,6 +1381,32 @@ linux_send_signal (int signum)
kill (signal_pid, signum);
}
+/* Copy LEN bytes from inferior's auxiliary vector starting at OFFSET
+ to debugger memory starting at MYADDR. */
+
+static int
+linux_read_auxv (CORE_ADDR offset, char *myaddr, unsigned int len)
+{
+ char filename[PATH_MAX];
+ int fd, n;
+
+ snprintf (filename, sizeof filename, "/proc/%d/auxv", inferior_pid);
+
+ fd = open (filename, O_RDONLY);
+ if (fd < 0)
+ return -1;
+
+ if (offset != (CORE_ADDR) 0
+ && lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset)
+ n = -1;
+ else
+ n = read (fd, myaddr, len);
+
+ close (fd);
+
+ return n;
+}
+
static struct target_ops linux_target_ops = {
linux_create_inferior,
@@ -1396,6 +1422,7 @@ static struct target_ops linux_target_ops = {
linux_write_memory,
linux_look_up_symbols,
linux_send_signal,
+ linux_read_auxv,
};
static void
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index dffff2e..b45b3f3 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -104,7 +104,7 @@ handle_query (char *own_buf)
thread_ptr = thread_ptr->next;
return;
}
-
+
if (strcmp ("qsThreadInfo", own_buf) == 0)
{
if (thread_ptr != NULL)
@@ -119,7 +119,27 @@ handle_query (char *own_buf)
return;
}
}
-
+
+ if (the_target->read_auxv != NULL
+ && strncmp ("qPart:auxv:read::", own_buf, 17) == 0)
+ {
+ char data[(PBUFSIZ - 1) / 2];
+ CORE_ADDR ofs;
+ unsigned int len;
+ int n;
+ decode_m_packet (&own_buf[17], &ofs, &len); /* "OFS,LEN" */
+ if (len > sizeof data)
+ len = sizeof data;
+ n = (*the_target->read_auxv) (ofs, data, len);
+ if (n == 0)
+ write_ok (own_buf);
+ else if (n < 0)
+ write_enn (own_buf);
+ else
+ convert_int_to_ascii (data, own_buf, n);
+ return;
+ }
+
/* Otherwise we didn't know what packet it was. Say we didn't
understand it. */
own_buf[0] = 0;
@@ -371,7 +391,7 @@ main (int argc, char *argv[])
detach_inferior ();
write_ok (own_buf);
putpkt (own_buf);
- remote_close ();
+ remote_close ();
/* If we are attached, then we can exit. Otherwise, we need to
hang around doing nothing, until the child is gone. */
diff --git a/gdb/gdbserver/target.h b/gdb/gdbserver/target.h
index aa0a44a..f4bc674 100644
--- a/gdb/gdbserver/target.h
+++ b/gdb/gdbserver/target.h
@@ -92,7 +92,7 @@ struct target_ops
If REGNO is -1, fetch all registers; otherwise, fetch at least REGNO. */
void (*fetch_registers) (int regno);
-
+
/* Store registers to the inferior process.
If REGNO is -1, store all registers; otherwise, store at least REGNO. */
@@ -125,6 +125,12 @@ struct target_ops
/* Send a signal to the inferior process, however is appropriate. */
void (*send_signal) (int);
+
+ /* Read auxiliary vector data from the inferior process.
+
+ Read LEN bytes at OFFSET into a buffer at MYADDR. */
+
+ int (*read_auxv) (CORE_ADDR offset, char *myaddr, unsigned int len);
};
extern struct target_ops *the_target;