From aa691b87c2317cc90bbe4964d79e5a29c29f348e Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 25 Feb 2004 20:41:29 +0000 Subject: [PATCH] 2004-02-25 Roland McGrath * target.h (struct target_ops): New member `read_auxv'. * server.c (handle_query): Handle qPart:auxv:read: query using that. * linux-low.c (linux_read_auxv): New function. (linux_target_ops): Initialize `read_auxv' member to that. --- gdb/gdbserver/linux-low.c | 37 ++++++++++++++++++++++++++++++++----- gdb/gdbserver/server.c | 26 +++++++++++++++++++++++--- gdb/gdbserver/target.h | 8 +++++++- 3 files changed, 62 insertions(+), 9 deletions(-) diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index 501bb581956..90efd01ebeb 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 dffff2e1e61..b45b3f3c49c 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 aa0a44afd61..f4bc6747487 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; -- 2.39.2