2004-02-25 Roland McGrath <roland@redhat.com>
authorRoland McGrath <roland@gnu.org>
Wed, 25 Feb 2004 20:41:29 +0000 (20:41 +0000)
committerRoland McGrath <roland@gnu.org>
Wed, 25 Feb 2004 20:41:29 +0000 (20:41 +0000)
* 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
gdb/gdbserver/server.c
gdb/gdbserver/target.h

index 501bb581956697a9a51c1c740350bb1f79ad4c08..90efd01ebeb78c897b5ad6f0878393fa4a8a5daa 100644 (file)
@@ -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;
+}
+
 \f
 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
index dffff2e1e61e71e185459a02e1a335af8a14de5c..b45b3f3c49cd72cf40e33296ce61368a0f7d5636 100644 (file)
@@ -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.  */
index aa0a44afd61a317feb50917e01800346b18de3d8..f4bc674748732af3d37d58c42f4e4fef527eef68 100644 (file)
@@ -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;