Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [PATCH] auxv support
@ 2004-01-29  2:59 Roland McGrath
  2004-01-29  6:39 ` Eli Zaretskii
  2004-01-30 19:03 ` Daniel Jacobowitz
  0 siblings, 2 replies; 25+ messages in thread
From: Roland McGrath @ 2004-01-29  2:59 UTC (permalink / raw)
  To: gdb-patches

Ok, I think this is looking pretty polished now.  I've tested it on Linux
and Solaris.  On both systems I tested the live process case, the core file
case, and gcore.  I did not test a multithreaded Solaris program, so that
trivial part of the code path has not actually been exercised.

This adds the underlying support we talked about before, implemented
basically the same as my earlier patch.  It also adds the `info auxv'
command as Andrew proposed, but with slightly nicer output.  The function
for reading /proc/PID/auxv, and some of the other code previously
duplicated between the procfs and linux implementations, is now shared code
in auxv.c.  There is also a utility function there that is what's needed
for finding a single known tag's value, as some hook will do to check for
AT_SYSINFO_EHDR.

I would like to add remote protocol and gdbserver support as well, but
someone knowledgeable about gdbserver should ping me.


Solaris example output:

    (gdb) i aux
    2008 AT_SUN_PLATFORM      Platform name string           0xffbfffe1 "SUNW,Ultra-60"
    2014 AT_SUN_EXECNAME      Canonicalized file name given to execve 0xffbfffef "/usr/bin/cat"
    3    AT_PHDR              Program headers for program    0x10034
    4    AT_PHENT             Size of program header entry   32
    5    AT_PHNUM             Number of program headers      6
    9    AT_ENTRY             Entry point of program         0x10b3c
    2016 AT_SUN_LDDATA        Dynamic linker's data segment address 0x7fbf6000
    7    AT_BASE              Base address of interpreter    0x7fbc0000
    8    AT_FLAGS             Flags                          0x300
    6    AT_PAGESZ            System page size               8192
    2000 AT_SUN_UID           Effective user ID              3520
    2001 AT_SUN_RUID          Real user ID                   3520
    2002 AT_SUN_GID           Effective group ID             3520
    2003 AT_SUN_RGID          Real group ID                  3520
    2009 AT_SUN_HWCAP         Machine-dependent CPU capability hints 0x7
    0    AT_NULL              End of vector                  0x0
    0    AT_NULL              End of vector                  0x0
    0    AT_NULL              End of vector                  0x0
    0    AT_NULL              End of vector                  0x0
    (gdb) 

Linux example output:

    (gdb) i aux
    32   AT_SYSINFO           Special system info/entry points 0xffffe400
    33   AT_SYSINFO_EHDR      System-supplied DSO's ELF header 0xffffe000
    16   AT_HWCAP             Machine-dependent CPU capability hints 0x383fbff
    6    AT_PAGESZ            System page size               4096
    17   AT_CLKTCK            Frequency of times()           100
    3    AT_PHDR              Program headers for program    0x8048034
    4    AT_PHENT             Size of program header entry   32
    5    AT_PHNUM             Number of program headers      6
    7    AT_BASE              Base address of interpreter    0x40000000
    8    AT_FLAGS             Flags                          0x0
    9    AT_ENTRY             Entry point of program         0x8048ae0
    11   AT_UID               Real user ID                   5281
    12   AT_EUID              Effective user ID              5281
    13   AT_GID               Real group ID                  5281
    14   AT_EGID              Effective group ID             5281
    23   AT_SECURE            Boolean, was exec setuid-like? 0
    15   AT_PLATFORM          String identifying platform    0xbffffb20 "i686"
    0    AT_NULL              End of vector                  0x0
    (gdb) 

Not shown in either is the output for an unknown value, which there aren't
any since I've added all known values.  But it would look like this:

    99   ???                                                 0x12345678



Approved?


Thanks,
Roland


2004-01-28  Roland McGrath  <roland@redhat.com>

	* sol-thread.c (sol_thread_xfer_partial): New function.
	(init_sol_thread_ops): Use that for to_xfer_partial hook.
	(init_sol_core_ops): Likewise.

	* procfs.c (procfs_xfer_partial): New function.
	(init_procfs_ops): Use that for procfs_ops.to_xfer_partial.
	* Makefile.in (procfs.o): Add $(auxv_h) dep.

	* config/nm-linux.h (NATIVE_XFER_AUXV): New macro, uses auxv.c's
	procfs_xfer_auxv function.

	* procfs.c (procfs_make_note_section): If we can read
	TARGET_OBJECT_AUXV data, add an NT_AUXV note containing it.
	* linux-proc.c (linux_make_note_section): Likewise.

	* auxv.h: New file.
	* auxv.c: New file.
	* Makefile.in (auxv_h): New variable.
	(COMMON_OBS): Add auxv.o here.
	(auxv.o): New target.

	* corelow.c (core_xfer_partial): New function.
	(init_core_ops): Use it for core_ops.to_xfer_partial.

	* target.h (enum target_object): Add TARGET_OBJECT_AUXV.
	* inftarg.c (child_xfer_partial): Support it using NATIVE_XFER_AUXV
	macro if that is defined.

Index: auxv.c
===================================================================
RCS file: auxv.c
diff -N auxv.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ auxv.c	29 Jan 2004 02:48:03 -0000
@@ -0,0 +1,301 @@
+/* Auxiliary vector support for GDB, the GNU debugger.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include "defs.h"
+#include "target.h"
+#include "gdbtypes.h"
+#include "command.h"
+#include "inferior.h"
+#include "valprint.h"
+#include "gdb_assert.h"
+
+#include "auxv.h"
+#include "elf/common.h"
+
+#include <unistd.h>
+#include <fcntl.h>
+
+
+/* This function is called like a to_xfer_partial hook,
+   but must be called with TARGET_OBJECT_AUXV.
+   It handles access via /proc/PID/auxv, which is the common method.
+   This function is appropriate for doing:
+	   #define NATIVE_XFER_AUXV	procfs_xfer_auxv
+   for a native target that uses inftarg.c's child_xfer_partial hook.  */
+
+LONGEST
+procfs_xfer_auxv (struct target_ops *ops,
+		  int /* enum target_object */ object,
+		  const char *annex,
+		  void *readbuf,
+		  const void *writebuf,
+		  ULONGEST offset,
+		  LONGEST len)
+{
+  char *pathname;
+  int fd;
+  LONGEST n;
+
+  gdb_assert (object == TARGET_OBJECT_AUXV);
+  gdb_assert (readbuf || writebuf);
+
+  pathname = xstrprintf ("/proc/%d/auxv", PIDGET (inferior_ptid));
+  fd = open (pathname, writebuf != NULL ? O_WRONLY : O_RDONLY);
+  xfree (pathname);
+  if (fd < 0)
+    return -1;
+
+  if (offset != (ULONGEST) 0
+      && lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset)
+    n = -1;
+  else if (readbuf != NULL)
+    n = read (fd, readbuf, len);
+  else
+    n = write (fd, writebuf, len);
+
+  (void) close (fd);
+
+  return n;
+}
+
+/* Read all the auxv data into a contiguous xmalloc'd buffer,
+   stored in *DATA.  Return the size in bytes of this data.
+   If zero, there is no data and *DATA is null.
+   if < 0, there was an error and *DATA is null.  */
+LONGEST
+target_auxv_read (struct target_ops *ops, char **data)
+{
+  size_t auxv_alloc = 512, auxv_pos = 0;
+  char *auxv = xmalloc (auxv_alloc);
+  int n;
+
+  while (1)
+    {
+      n = target_read_partial (ops, TARGET_OBJECT_AUXV,
+			       NULL, &auxv[auxv_pos], 0,
+			       auxv_alloc - auxv_pos);
+      if (n <= 0)
+	break;
+      auxv_pos += n;
+      if (auxv_pos < auxv_alloc) /* Read all there was.  */
+	break;
+      gdb_assert (auxv_pos == auxv_alloc);
+      auxv_alloc *= 2;
+      auxv = xrealloc (auxv, auxv_alloc);
+    }
+
+  if (auxv_pos == 0)
+    {
+      xfree (auxv);
+      *data = NULL;
+      return n;
+    }
+
+  *data = auxv;
+  return auxv_pos;
+}
+
+/* Read one auxv entry from *READPTR, not reading locations >= ENDPTR.
+   Return 0 if *READPTR is already at the end of the buffer.
+   Return -1 if there is insufficient buffer for a whole entry.
+   Return 1 if an entry was read into *TYPEP and *VALP.  */
+int
+target_auxv_parse (struct target_ops *ops, char **readptr, char *endptr,
+		   CORE_ADDR *typep, CORE_ADDR *valp)
+{
+  const int sizeof_auxv_field = TYPE_LENGTH (builtin_type_void_data_ptr);
+  char *ptr = *readptr;
+
+  if (endptr == ptr)
+    return 0;
+
+  if (endptr - ptr < sizeof_auxv_field * 2)
+    return -1;
+
+  *typep = extract_unsigned_integer (ptr, sizeof_auxv_field);
+  ptr += sizeof_auxv_field;
+  *valp = extract_unsigned_integer (ptr, sizeof_auxv_field);
+  ptr += sizeof_auxv_field;
+
+  *readptr = ptr;
+  return 1;
+}
+
+/* Extract the auxiliary vector entry with a_type matching MATCH.
+   Return zero if no such entry was found, or -1 if there was
+   an error getting the information.  On success, return 1 after
+   storing the entry's value field in *VALP.  */
+int
+target_auxv_search (struct target_ops *ops, CORE_ADDR match, CORE_ADDR *valp)
+{
+  CORE_ADDR type, val;
+  char *data;
+  int n = target_auxv_read (ops, &data);
+  char *ptr = data;
+  int ents = 0;
+
+  if (n <= 0)
+    return n;
+
+  while (1)
+    switch (target_auxv_parse (ops, &ptr, data + n, &type, &val))
+      {
+      case 1:			/* Here's an entry, check it.  */
+	if (type == match)
+	  {
+	    xfree (data);
+	    *valp = val;
+	    return 1;
+	  }
+	break;
+      case 0:			/* End of the vector.  */
+	xfree (data);
+	return 0;
+      default:			/* Bogosity.  */
+	xfree (data);
+	return -1;
+      }
+
+  /*NOTREACHED*/
+}
+
+
+/* Print the contents of the target's AUXV on the specified file. */
+int
+fprint_target_auxv (struct ui_file *file, struct target_ops *ops)
+{
+  CORE_ADDR type, val;
+  char *data;
+  int len = target_auxv_read (ops, &data);
+  char *ptr = data;
+  int ents = 0;
+
+  if (len <= 0)
+    return len;
+
+  while (target_auxv_parse (ops, &ptr, data + len, &type, &val) > 0)
+    {
+      extern int addressprint;
+      const char *name = "???";
+      const char *description = "";
+      enum { dec, hex, str } flavor = hex;
+
+      switch (type)
+	{
+#define TAG(tag, text, kind) \
+	case tag: name = #tag; description = text; flavor = kind; break
+	  TAG (AT_NULL, "End of vector", hex);
+	  TAG (AT_IGNORE, "Entry should be ignored", hex);
+	  TAG (AT_EXECFD, "File descriptor of program", dec);
+	  TAG (AT_PHDR, "Program headers for program", hex);
+	  TAG (AT_PHENT, "Size of program header entry", dec);
+	  TAG (AT_PHNUM, "Number of program headers", dec);
+	  TAG (AT_PAGESZ, "System page size", dec);
+	  TAG (AT_BASE, "Base address of interpreter", hex);
+	  TAG (AT_FLAGS, "Flags", hex);
+	  TAG (AT_ENTRY, "Entry point of program", hex);
+	  TAG (AT_NOTELF, "Program is not ELF", dec);
+	  TAG (AT_UID, "Real user ID", dec);
+	  TAG (AT_EUID, "Effective user ID", dec);
+	  TAG (AT_GID, "Real group ID", dec);
+	  TAG (AT_EGID, "Effective group ID", dec);
+	  TAG (AT_CLKTCK, "Frequency of times()", dec);
+	  TAG (AT_PLATFORM, "String identifying platform", str);
+	  TAG (AT_HWCAP, "Machine-dependent CPU capability hints", hex);
+	  TAG (AT_FPUCW, "Used FPU control word", dec);
+	  TAG (AT_DCACHEBSIZE, "Data cache block size", dec);
+	  TAG (AT_ICACHEBSIZE, "Instruction cache block size", dec);
+	  TAG (AT_UCACHEBSIZE, "Unified cache block size", dec);
+	  TAG (AT_IGNOREPPC, "Entry should be ignored", dec);
+	  TAG (AT_SYSINFO, "Special system info/entry points", hex);
+	  TAG (AT_SYSINFO_EHDR, "System-supplied DSO's ELF header", hex);
+	  TAG (AT_SECURE, "Boolean, was exec setuid-like?", dec);
+	  TAG (AT_SUN_UID, "Effective user ID", dec);
+	  TAG (AT_SUN_RUID, "Real user ID", dec);
+	  TAG (AT_SUN_GID, "Effective group ID", dec);
+	  TAG (AT_SUN_RGID, "Real group ID", dec);
+	  TAG (AT_SUN_LDELF, "Dynamic linker's ELF header", hex);
+	  TAG (AT_SUN_LDSHDR, "Dynamic linker's section headers", hex);
+	  TAG (AT_SUN_LDNAME, "String giving name of dynamic linker", str);
+	  TAG (AT_SUN_LPAGESZ, "Large pagesize", dec);
+	  TAG (AT_SUN_PLATFORM, "Platform name string", str);
+	  TAG (AT_SUN_HWCAP, "Machine-dependent CPU capability hints", hex);
+	  TAG (AT_SUN_IFLUSH, "Should flush icache?", dec);
+	  TAG (AT_SUN_CPU, "CPU name string", str);
+	  TAG (AT_SUN_EMUL_ENTRY, "COFF entry point address", hex);
+	  TAG (AT_SUN_EMUL_EXECFD, "COFF executable file descriptor", dec);
+	  TAG (AT_SUN_EXECNAME,
+	       "Canonicalized file name given to execve", str);
+	  TAG (AT_SUN_MMU, "String for name of MMU module", str);
+	  TAG (AT_SUN_LDDATA, "Dynamic linker's data segment address", hex);
+	}
+
+      fprintf_filtered (file, "%-4s %-20s %-30s ",
+			paddr_d (type), name, description);
+      switch (flavor)
+	{
+	case dec:
+	  fprintf_filtered (file, "%s\n", paddr_d (val));
+	  break;
+	case hex:
+	  fprintf_filtered (file, "0x%s\n", paddr_nz (val));
+	  break;
+	case str:
+	  if (addressprint)
+	    fprintf_filtered (file, "0x%s", paddr_nz (val));
+	  val_print_string (val, -1, 1, file);
+	  fprintf_filtered (file, "\n");
+	  break;
+	}
+      ++ents;
+    }
+
+  xfree (data);
+
+  return ents;
+}
+
+static void
+info_auxv_command (char *cmd, int from_tty)
+{
+
+  if (! target_has_stack)
+    error ("The program has no auxiliary information now.");
+  else
+    {
+      int ents = fprint_target_auxv (gdb_stdout, &current_target);
+      if (ents < 0)
+	error ("No auxilary vector found, or failed reading it.");
+      else if (ents == 0)
+	error ("Auxilary vector is empty.");
+    }
+}
+
+
+extern initialize_file_ftype _initialize_auxv; /* -Wmissing-prototypes; */
+
+void
+_initialize_auxv (void)
+{
+  add_info ("auxv", info_auxv_command,
+	    "Display the inferior's auxiliary vector.\n\
+This is information provided by the operating system at program startup.");
+}
Index: auxv.h
===================================================================
RCS file: auxv.h
diff -N auxv.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ auxv.h	29 Jan 2004 02:48:03 -0000
@@ -0,0 +1,75 @@
+/* Auxiliary vector support for GDB, the GNU debugger.
+
+   Copyright 2004 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef AUXV_H
+#define AUXV_H
+
+/* See "include/elf/common.h" for the definition of valid AT_* values.  */
+
+
+/* Avoid miscellaneous includes in this file, so that it can be
+   included by nm-*.h for the procfs_xfer_auxv decl if that is
+   used in NATIVE_XFER_AUXV.  */
+struct target_ops;		/* Forward declaration.  */
+
+
+/* Read all the auxv data into a contiguous xmalloc'd buffer,
+   stored in *DATA.  Return the size in bytes of this data.
+   If zero, there is no data and *DATA is null.
+   if < 0, there was an error and *DATA is null.  */
+extern LONGEST target_auxv_read (struct target_ops *ops, char **data);
+
+/* Read one auxv entry from *READPTR, not reading locations >= ENDPTR.
+   Return 0 if *READPTR is already at the end of the buffer.
+   Return -1 if there is insufficient buffer for a whole entry.
+   Return 1 if an entry was read into *TYPEP and *VALP.  */
+extern int target_auxv_parse (struct target_ops *ops,
+			      char **readptr, char *endptr,
+			      CORE_ADDR *typep, CORE_ADDR *valp);
+
+/* Extract the auxiliary vector entry with a_type matching MATCH.
+   Return zero if no such entry was found, or -1 if there was
+   an error getting the information.  On success, return 1 after
+   storing the entry's value field in *VALP.  */
+extern int target_auxv_search (struct target_ops *ops,
+			       CORE_ADDR match, CORE_ADDR *valp);
+
+/* Print the contents of the target's AUXV on the specified file. */
+extern int fprint_target_auxv (struct ui_file *file, struct target_ops *ops);
+
+
+/* This function is called like a to_xfer_partial hook,
+   but must be called with TARGET_OBJECT_AUXV.
+   It handles access via /proc/PID/auxv, which is the common method.
+   This function is appropriate for doing:
+	   #define NATIVE_XFER_AUXV	procfs_xfer_auxv
+   for a native target that uses inftarg.c's child_xfer_partial hook.  */
+
+extern LONGEST procfs_xfer_auxv (struct target_ops *ops,
+				 int /* enum target_object */ object,
+				 const char *annex,
+				 void *readbuf,
+				 const void *writebuf,
+				 ULONGEST offset,
+				 LONGEST len);
+
+
+#endif
Index: sol-thread.c
===================================================================
RCS file: /cvs/src/src/gdb/sol-thread.c,v
retrieving revision 1.38
diff -b -p -u -r1.38 sol-thread.c
--- sol-thread.c	21 Sep 2003 01:26:45 -0000	1.38
+++ sol-thread.c	29 Jan 2004 02:44:52 -0000
@@ -750,6 +750,37 @@ sol_thread_xfer_memory (CORE_ADDR memadd
   return retval;
 }
 
+/* Perform partial transfers on OBJECT.  See target_read_partial
+   and target_write_partial for details of each variant.  One, and
+   only one, of readbuf or writebuf must be non-NULL.  */
+
+static LONGEST
+sol_thread_xfer_partial (struct target_ops *ops, enum target_object object,
+			  const char *annex, void *readbuf,
+			  const void *writebuf, ULONGEST offset, LONGEST len)
+{
+  int retval;
+  struct cleanup *old_chain;
+
+  old_chain = save_inferior_ptid ();
+
+  if (is_thread (inferior_ptid) ||	/* A thread */
+      !target_thread_alive (inferior_ptid))	/* An lwp, but not alive */
+    inferior_ptid = procfs_first_available ();	/* Find any live lwp.  */
+  /* Note: don't need to call switch_to_thread; we're just reading memory.  */
+
+  if (target_has_execution)
+    retval = procfs_ops.to_xfer_partial (ops, object, annex,
+					 readbuf, writebuf, offset, len);
+  else
+    retval = orig_core_ops.to_xfer_partial (ops, object, annex,
+					    readbuf, writebuf, offset, len);
+
+  do_cleanups (old_chain);
+
+  return retval;
+}
+
 /* Print status information about what we're accessing.  */
 
 static void
@@ -1549,6 +1580,7 @@ init_sol_thread_ops (void)
   sol_thread_ops.to_store_registers = sol_thread_store_registers;
   sol_thread_ops.to_prepare_to_store = sol_thread_prepare_to_store;
   sol_thread_ops.to_xfer_memory = sol_thread_xfer_memory;
+  sol_thread_ops.to_xfer_partial = sol_thread_xfer_partial;
   sol_thread_ops.to_files_info = sol_thread_files_info;
   sol_thread_ops.to_insert_breakpoint = memory_insert_breakpoint;
   sol_thread_ops.to_remove_breakpoint = memory_remove_breakpoint;
@@ -1592,6 +1624,7 @@ init_sol_core_ops (void)
   sol_core_ops.to_detach = sol_core_detach;
   sol_core_ops.to_fetch_registers = sol_thread_fetch_registers;
   sol_core_ops.to_xfer_memory = sol_thread_xfer_memory;
+  sol_core_ops.to_xfer_partial = sol_thread_xfer_partial;
   sol_core_ops.to_files_info = sol_core_files_info;
   sol_core_ops.to_insert_breakpoint = ignore;
   sol_core_ops.to_remove_breakpoint = ignore;
Index: procfs.c
===================================================================
RCS file: /cvs/src/src/gdb/procfs.c,v
retrieving revision 1.50
diff -b -p -u -r1.50 procfs.c
--- procfs.c	17 Jan 2004 18:24:15 -0000	1.50
+++ procfs.c	29 Jan 2004 02:44:53 -0000
@@ -45,8 +45,10 @@ Inc., 59 Temple Place - Suite 330, Bosto
 #include "gdb_wait.h"
 #include <signal.h>
 #include <ctype.h>
+#include <string.h>
 #include "gdb_assert.h"
 #include "inflow.h"
+#include "auxv.h"
 
 /* 
  * PROCFS.C
@@ -127,6 +129,11 @@ static ptid_t procfs_wait (ptid_t, struc
 static int procfs_xfer_memory (CORE_ADDR, char *, int, int,
 			       struct mem_attrib *attrib,
 			       struct target_ops *);
+static LONGEST procfs_xfer_partial (struct target_ops *ops,
+				    enum target_object object,
+				    const char *annex,
+				    void *readbuf, const void *writebuf,
+				    ULONGEST offset, LONGEST len);
 
 static int procfs_thread_alive (ptid_t);
 
@@ -164,6 +171,7 @@ init_procfs_ops (void)
   procfs_ops.to_prepare_to_store    = procfs_prepare_to_store;
   procfs_ops.to_fetch_registers     = procfs_fetch_registers;
   procfs_ops.to_store_registers     = procfs_store_registers;
+  procfs_ops.to_xfer_partial        = procfs_xfer_partial;
   procfs_ops.to_xfer_memory         = procfs_xfer_memory;
   procfs_ops.to_insert_breakpoint   =  memory_insert_breakpoint;
   procfs_ops.to_remove_breakpoint   =  memory_remove_breakpoint;
@@ -4267,6 +4275,40 @@ wait_again:
   return retval;
 }
 
+/* Perform a partial transfer to/from the specified object.  For
+   memory transfers, fall back to the old memory xfer functions.  */
+
+static LONGEST
+procfs_xfer_partial (struct target_ops *ops, enum target_object object,
+		     const char *annex, void *readbuf,
+		     const void *writebuf, ULONGEST offset, LONGEST len)
+{
+  switch (object)
+    {
+    case TARGET_OBJECT_MEMORY:
+      if (readbuf)
+	return (*ops->to_xfer_memory) (offset, readbuf, len, 0/*write*/,
+				       NULL, ops);
+      if (writebuf)
+	return (*ops->to_xfer_memory) (offset, readbuf, len, 1/*write*/,
+				       NULL, ops);
+      return -1;
+
+#ifdef NEW_PROC_API
+    case TARGET_OBJECT_AUXV:
+      return procfs_xfer_auxv (ops, object, annex, readbuf, writebuf,
+			       offset, len);
+#endif
+
+    default:
+      if (ops->beneath != NULL)
+	return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
+					      readbuf, writebuf, offset, len);
+      return -1;
+    }
+}
+
+
 /* Transfer LEN bytes between GDB address MYADDR and target address
    MEMADDR.  If DOWRITE is non-zero, transfer them to the target,
    otherwise transfer them from the target.  TARGET is unused.
@@ -5849,6 +5891,8 @@ procfs_make_note_section (bfd *obfd, int
   char *note_data = NULL;
   char *inf_args;
   struct procfs_corefile_thread_data thread_args;
+  char *auxv;
+  int auxv_len;
 
   if (get_exec_file (0))
     {
@@ -5895,6 +5939,14 @@ procfs_make_note_section (bfd *obfd, int
   else
     {
       note_data = thread_args.note_data;
+    }
+
+  auxv_len = target_auxv_read (&current_target, &auxv);
+  if (auxv_len > 0)
+    {
+      note_data = elfcore_write_note (obfd, note_data, note_size,
+				      "CORE", NT_AUXV, auxv, auxv_len);
+      xfree (auxv);
     }
 
   make_cleanup (xfree, note_data);
Index: linux-proc.c
===================================================================
RCS file: /cvs/src/src/gdb/linux-proc.c,v
retrieving revision 1.20
diff -b -p -u -r1.20 linux-proc.c
--- linux-proc.c	1 Oct 2003 20:36:56 -0000	1.20
+++ linux-proc.c	29 Jan 2004 02:44:53 -0000
@@ -271,6 +271,8 @@ linux_make_note_section (bfd *obfd, int 
   char psargs[80] = { '\0' };
   char *note_data = NULL;
   ptid_t current_ptid = inferior_ptid;
+  char *auxv;
+  int auxv_len;
 
   if (get_exec_file (0))
     {
@@ -305,6 +307,14 @@ linux_make_note_section (bfd *obfd, int 
       note_data = thread_args.note_data;
     }
 
+  auxv_len = target_auxv_read (&current_target, &auxv);
+  if (auxv_len > 0)
+    {
+      note_data = elfcore_write_note (obfd, note_data, note_size,
+				      "CORE", NT_AUXV, auxv, auxv_len);
+      xfree (auxv);
+    }
+
   make_cleanup (xfree, note_data);
   return note_data;
 }
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.482
diff -b -p -u -r1.482 Makefile.in
--- Makefile.in	25 Jan 2004 11:46:44 -0000	1.482
+++ Makefile.in	29 Jan 2004 02:44:53 -0000
@@ -652,6 +652,7 @@ amd64_nat_h = amd64-nat.h
 annotate_h = annotate.h $(symtab_h) $(gdbtypes_h)
 arch_utils_h = arch-utils.h
 arm_tdep_h = arm-tdep.h
+auxv_h = auxv.h
 ax_gdb_h = ax-gdb.h
 ax_h = ax.h $(doublest_h)
 bcache_h = bcache.h
@@ -891,6 +892,7 @@ TAGFILES_NO_SRCDIR = $(SFILES) $(HFILES_
 TAGFILES_WITH_SRCDIR = $(HFILES_WITH_SRCDIR)
 
 COMMON_OBS = version.o \
+	auxv.o \
 	bfd-target.o \
 	blockframe.o breakpoint.o findvar.o regcache.o \
 	charset.o disasm.o dummy-frame.o \
@@ -1621,6 +1624,8 @@ arm-tdep.o: arm-tdep.c $(defs_h) $(frame
 	$(frame_unwind_h) $(frame_base_h) $(trad_frame_h) $(arm_tdep_h) \
 	$(gdb_sim_arm_h) $(elf_bfd_h) $(coff_internal_h) $(elf_arm_h) \
 	$(gdb_assert_h) $(bfd_in2_h) $(libcoff_h)
+auxv.o: $(defs_h) $(target_h) $(gdbtypes_h) $(command_h) $(gdb_assert_h) \
+	$(auxv_h) $(elf_common_h) $(valprint_h) $(inferior_h)
 avr-tdep.o: avr-tdep.c $(defs_h) $(frame_h) $(frame_unwind_h) \
 	$(frame_base_h) $(trad_frame_h) $(gdbcmd_h) $(gdbcore_h) \
 	$(inferior_h) $(symfile_h) $(arch_utils_h) $(regcache_h) \
@@ -2180,7 +2187,7 @@ proc-flags.o: proc-flags.c $(defs_h)
 procfs.o: procfs.c $(defs_h) $(inferior_h) $(target_h) $(gdbcore_h) \
 	$(elf_bfd_h) $(gdbcmd_h) $(gdbthread_h) $(gdb_wait_h) \
 	$(gdb_assert_h) $(inflow_h) $(gdb_dirent_h) $(X_OK) $(gdb_stat_h) \
-	$(proc_utils_h) $(gregset_h)
+	$(proc_utils_h) $(gregset_h) $(auxv_h)
 proc-service.o: proc-service.c $(defs_h) $(gdb_proc_service_h) $(inferior_h) \
 	$(symtab_h) $(target_h) $(gregset_h)
 proc-why.o: proc-why.c $(defs_h) $(proc_utils_h)
cvs server: I know nothing about auxv.c
cvs server: I know nothing about auxv.h
Index: corelow.c
===================================================================
RCS file: /cvs/src/src/gdb/corelow.c,v
retrieving revision 1.33
diff -b -p -u -r1.33 corelow.c
--- corelow.c	6 Nov 2003 02:52:27 -0000	1.33
+++ corelow.c	29 Jan 2004 02:44:53 -0000
@@ -515,6 +515,63 @@ core_files_info (struct target_ops *t)
   print_section_info (t, core_bfd);
 }
 \f
+static LONGEST
+core_xfer_partial (struct target_ops *ops, enum target_object object,
+		   const char *annex, void *readbuf,
+		   const void *writebuf, ULONGEST offset, LONGEST len)
+{
+  switch (object)
+    {
+    case TARGET_OBJECT_MEMORY:
+      if (readbuf)
+	return (*ops->to_xfer_memory) (offset, readbuf, len, 0/*write*/,
+				       NULL, ops);
+      if (writebuf)
+	return (*ops->to_xfer_memory) (offset, readbuf, len, 1/*write*/,
+				       NULL, ops);
+      return -1;
+
+    case TARGET_OBJECT_AUXV:
+      if (readbuf)
+	{
+	  /* When the aux vector is stored in core file, BFD
+	     represents this with a fake section called ".auxv".  */
+
+	  sec_ptr section;
+	  bfd_size_type size;
+	  char *contents;
+
+	  section = bfd_get_section_by_name (core_bfd, ".auxv");
+	  if (section == NULL)
+	    return -1;
+
+	  size = bfd_section_size (core_bfd, section);
+	  if (offset >= size)
+	    return 0;
+	  size -= offset;
+	  if (size > len)
+	    size = len;
+	  if (size > 0 &&
+	      ! bfd_get_section_contents (core_bfd, section, readbuf,
+					  (file_ptr) offset, size))
+	    {
+	      warning ("Couldn't read NT_AUXV note in core file.");
+	      return -1;
+	    }
+
+	  return size;
+	}
+      return -1;
+
+    default:
+      if (ops->beneath != NULL)
+	return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
+					      readbuf, writebuf, offset, len);
+      return -1;
+    }
+}
+
+\f
 /* If mourn is being called in all the right places, this could be say
    `gdb internal error' (since generic_mourn calls breakpoint_init_inferior).  */
 
@@ -551,6 +608,7 @@ init_core_ops (void)
   core_ops.to_attach = find_default_attach;
   core_ops.to_detach = core_detach;
   core_ops.to_fetch_registers = get_core_registers;
+  core_ops.to_xfer_partial = core_xfer_partial;
   core_ops.to_xfer_memory = xfer_memory;
   core_ops.to_files_info = core_files_info;
   core_ops.to_insert_breakpoint = ignore;
Index: target.h
===================================================================
RCS file: /cvs/src/src/gdb/target.h,v
retrieving revision 1.55
diff -b -p -u -r1.55 target.h
--- target.h	17 Jan 2004 21:56:12 -0000	1.55
+++ target.h	29 Jan 2004 02:44:53 -0000
@@ -226,8 +226,10 @@ enum target_object
   TARGET_OBJECT_MEMORY,
   /* Kernel Unwind Table.  See "ia64-tdep.c".  */
   TARGET_OBJECT_UNWIND_TABLE,
-  /* Possible future objects: TARGET_OBJECT_FILE, TARGET_OBJECT_PROC,
-     TARGET_OBJECT_AUXV, ...  */
+  /* Transfer auxilliary vector.  */
+  TARGET_OBJECT_AUXV,
+
+  /* Possible future objects: TARGET_OBJECT_FILE, TARGET_OBJECT_PROC, ... */
 };
 
 extern LONGEST target_read_partial (struct target_ops *ops,
Index: inftarg.c
===================================================================
RCS file: /cvs/src/src/gdb/inftarg.c,v
retrieving revision 1.21
diff -b -p -u -r1.21 inftarg.c
--- inftarg.c	14 Nov 2003 20:49:23 -0000	1.21
+++ inftarg.c	29 Jan 2004 02:44:53 -0000
@@ -578,11 +578,12 @@ child_xfer_partial (struct target_ops *o
       return NATIVE_XFER_UNWIND_TABLE (ops, object, annex, readbuf, writebuf,
 				       offset, len);
 
-#if 0
     case TARGET_OBJECT_AUXV:
-      return native_xfer_auxv (PIDGET (inferior_ptid), readbuf, writebuf,
-			       offset, len);
+#ifndef NATIVE_XFER_AUXV
+#define NATIVE_XFER_AUXV(OPS,OBJECT,ANNEX,WRITEBUF,READBUF,OFFSET,LEN) (-1)
 #endif
+      return NATIVE_XFER_AUXV (ops, object, annex, readbuf, writebuf,
+			       offset, len);
 
     default:
       return -1;
Index: config/nm-linux.h
===================================================================
RCS file: /cvs/src/src/gdb/config/nm-linux.h,v
retrieving revision 1.19
diff -b -p -u -r1.19 nm-linux.h
--- config/nm-linux.h	17 Aug 2003 18:22:25 -0000	1.19
+++ config/nm-linux.h	29 Jan 2004 02:44:53 -0000
@@ -77,3 +77,6 @@ extern void lin_thread_get_thread_signal
 #define CHILD_POST_ATTACH
 #define CHILD_FOLLOW_FORK
 #define KILL_INFERIOR
+
+#define NATIVE_XFER_AUXV	procfs_xfer_auxv
+#include "auxv.h"		/* Declares it. */


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] auxv support
  2004-01-29  2:59 [PATCH] auxv support Roland McGrath
@ 2004-01-29  6:39 ` Eli Zaretskii
  2004-01-29  8:20   ` Roland McGrath
  2004-01-30 19:03 ` Daniel Jacobowitz
  1 sibling, 1 reply; 25+ messages in thread
From: Eli Zaretskii @ 2004-01-29  6:39 UTC (permalink / raw)
  To: Roland McGrath; +Cc: gdb-patches

> Date: Wed, 28 Jan 2004 18:59:01 -0800
> From: Roland McGrath <roland@redhat.com>
> 
> This adds the underlying support we talked about before, implemented
> basically the same as my earlier patch.  It also adds the `info auxv'
> command as Andrew proposed, but with slightly nicer output.

I'd like to see the manual changed to described `info auxv'.

TIA


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] auxv support
  2004-01-29  6:39 ` Eli Zaretskii
@ 2004-01-29  8:20   ` Roland McGrath
  2004-01-29 20:14     ` Eli Zaretskii
  0 siblings, 1 reply; 25+ messages in thread
From: Roland McGrath @ 2004-01-29  8:20 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches

> I'd like to see the manual changed to described `info auxv'.

Where does the description belong?  I tried to follow the model of `info
udot' and `info dcache', which seem similar in general flavor of topic.
But these I cannot find documented anywhere.  `info proc' is documented in
a subsection of `Native'.  That does not seem appropriate, since `info auxv'
works on target core files regardless of host, and probably soon will work
for remote targets.  As written, the `info auxv' is available in all
configurations, just only ever succeeds for certain targets.  So it doesn't
seem like it belongs under @chapter Configuration-Specific Information at all.
Perhaps it should just be a new section in @chapter Examining Data?

How about this?


--- gdb.texinfo.~1.190.~	2004-01-28 16:21:23.000000000 -0800
+++ gdb.texinfo	2004-01-29 00:20:19.000000000 -0800
@@ -4684,6 +4684,7 @@ Table}.
 * Registers::                   Registers
 * Floating Point Hardware::     Floating point hardware
 * Vector Unit::                 Vector Unit
+* Auxiliary Vector::            Auxiliary data provided by operating system
 * Memory Region Attributes::    Memory region attributes
 * Dump/Restore Files::          Copy between memory and a file
 * Character Sets::              Debugging programs that use a different
@@ -5864,6 +5865,32 @@ Display information about the vector uni
 layout vary depending on the hardware.
 @end table
 
+@node Auxiliary Vector
+@section Operating system auxiliary vector
+@cindex auxiliary vector
+@cindex vector, auxiliary
+
+Some operating systems supply an @dfn{auxiliary vector} to programs at
+startup.  This is akin to the arguments and environment that you
+specify for a program, but contains a system-dependent variety of
+binary values that tell system libraries important details about the
+hardware, operating system, and process.  Each value's purpose is
+identified by an integer tag; the meanings are well-known but system-specific.
+Depending on the configuration and operating system facilities,
+@value{GDBN} may be able to show you this information.
+
+@table @code
+@kindex info auxv
+@item info auxv
+Display the auxiliary vector of the inferior, which can be either a
+live process or a core dump file.  @{GDBN} prints each tag value
+numerically, and also shows names and text descriptions for recognized
+tags.  Some values in the vector are numbers, some bit masks, and some
+pointers to strings or other data.  @{GDBN} displays each value in the
+most appropriate form for a recognized tag, and in hexadecimal for
+an unrecognized tag.
+@end table
+
 @node Memory Region Attributes
 @section Memory region attributes 
 @cindex memory region attributes


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] auxv support
  2004-01-29  8:20   ` Roland McGrath
@ 2004-01-29 20:14     ` Eli Zaretskii
  2004-01-29 21:31       ` Roland McGrath
  0 siblings, 1 reply; 25+ messages in thread
From: Eli Zaretskii @ 2004-01-29 20:14 UTC (permalink / raw)
  To: Roland McGrath; +Cc: gdb-patches

> Date: Thu, 29 Jan 2004 00:20:27 -0800
> From: Roland McGrath <roland@redhat.com>
> 
> Where does the description belong?  I tried to follow the model of `info
> udot' and `info dcache', which seem similar in general flavor of topic.
> But these I cannot find documented anywhere.

Darn! more undocumented commands!  Thanks for pointing this out.

> Perhaps it should just be a new section in @chapter Examining Data?

Yes, that'd be my line of reasoning as well.

In general, the partition of the GDB manual into chapters leaves a
lot to be desired, but until now no one has come up with a good
suggestion to restructure it.  Ideas welcome.

> How about this?

Thanks, I'm happy with this patch.  Pwerhaps just point the user to a
man page or an Info file, if any, where the system-specific details
of the displayed infor could be found.


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] auxv support
  2004-01-29 20:14     ` Eli Zaretskii
@ 2004-01-29 21:31       ` Roland McGrath
  0 siblings, 0 replies; 25+ messages in thread
From: Roland McGrath @ 2004-01-29 21:31 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches

> Thanks, I'm happy with this patch.  Pwerhaps just point the user to a
> man page or an Info file, if any, where the system-specific details
> of the displayed infor could be found.

There isn't one.  These bits are really at the level of implementation
detail.  They are not really part of any spec I'm aware of per se (though
how and where to find them are centrally specified), just part of the local
contract between a kernel and system libraries.


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] auxv support
  2004-01-29  2:59 [PATCH] auxv support Roland McGrath
  2004-01-29  6:39 ` Eli Zaretskii
@ 2004-01-30 19:03 ` Daniel Jacobowitz
  2004-01-30 23:35   ` Andrew Cagney
  1 sibling, 1 reply; 25+ messages in thread
From: Daniel Jacobowitz @ 2004-01-30 19:03 UTC (permalink / raw)
  To: gdb-patches

On Wed, Jan 28, 2004 at 06:59:01PM -0800, Roland McGrath wrote:
> Ok, I think this is looking pretty polished now.  I've tested it on Linux
> and Solaris.  On both systems I tested the live process case, the core file
> case, and gcore.  I did not test a multithreaded Solaris program, so that
> trivial part of the code path has not actually been exercised.
> 
> This adds the underlying support we talked about before, implemented
> basically the same as my earlier patch.  It also adds the `info auxv'
> command as Andrew proposed, but with slightly nicer output.  The function
> for reading /proc/PID/auxv, and some of the other code previously
> duplicated between the procfs and linux implementations, is now shared code
> in auxv.c.  There is also a utility function there that is what's needed
> for finding a single known tag's value, as some hook will do to check for
> AT_SYSINFO_EHDR.

I've reviewed this patch.  I think that it's OK, although I have one
comment:

> +int
> +target_auxv_parse (struct target_ops *ops, char **readptr, char *endptr,
> +		   CORE_ADDR *typep, CORE_ADDR *valp)

I don't see any point in having OPS here, and it's neither used nor
described in the comment.

Since Andrew submitted a previous patch for the same feature, I'd
appreciate it if he would look over this also.

> I would like to add remote protocol and gdbserver support as well, but
> someone knowledgeable about gdbserver should ping me.

Andrew's the remote protocol guru, and I handle gdbserver; feel free to
ask anything.  I imagine that adding a utility function somewhere to
read /proc/%d/auxv and a dispatch point in the target_ops structure is
all that it would take.


-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] auxv support
  2004-01-30 19:03 ` Daniel Jacobowitz
@ 2004-01-30 23:35   ` Andrew Cagney
  2004-01-30 23:51     ` Roland McGrath
  0 siblings, 1 reply; 25+ messages in thread
From: Andrew Cagney @ 2004-01-30 23:35 UTC (permalink / raw)
  To: Daniel Jacobowitz, Roland McGrath; +Cc: gdb-patches

> Since Andrew submitted a previous patch for the same feature, I'd
> appreciate it if he would look over this also.

The target vector update is fine.

Roland,

Would you be able to also knock up an "auxv.exp" test case?  Something 
to run the command and, most notably, fail if "???" comes out as the 
auxv entry name?

Also, just file a bug reports that there isn't an equivalent MI auxv 
command, and that those other commands need need documenting.  I'll (or 
someone) will need to come back to that.

Andrew



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] auxv support
  2004-01-30 23:35   ` Andrew Cagney
@ 2004-01-30 23:51     ` Roland McGrath
  2004-01-31  0:11       ` Andrew Cagney
  0 siblings, 1 reply; 25+ messages in thread
From: Roland McGrath @ 2004-01-30 23:51 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: Daniel Jacobowitz, gdb-patches

> The target vector update is fine.

Sorry, I'm not entirely clear on how to read you.  Should I commit the
whole patch I posted now?  (I'm not sure because you said "target vector
update", and my patch includes to_xfer_partial target updates,
to_make_corefile_notes target updates, and the `info auxv' user command.)

> Would you be able to also knock up an "auxv.exp" test case?  

Sure!  That is, I'd be happy to try.  Is there an especially good existing
test case to take as the canonical template for a test such as this?

To be complete, a test should try a live process, try a real core file, and
also try making a core file with gcore and then seeing that it matches the
real process it was made from.  Can you point me to an example of a test
that elicits core dumps and examines them?

> Something to run the command and, most notably, fail if "???" comes out
> as the auxv entry name?

That's not really a failure if it does.  Some random kernel change that we
have no reason to know or care about could cause that to be the case on
some system.  Do we want to make the gdb test suite complain whenever a new
constant appears in nature that's not in our table?  

If all you intend is a sanity check that we're not reading garbage values,
there are at least one or two AT_FOO tags that I think can be reliably
expected to be seen on every system that has an auxv at all.  So we could
make sure those are there, or just make sure that at least some entries had
names found.

> Also, just file a bug reports that there isn't an equivalent MI auxv 
> command, and that those other commands need need documenting.  I'll (or 
> someone) will need to come back to that.

Will do.  What about the remote protocol issue?  Should I file a bug for
that too?  Conversely, I'd be happy to get that resolved right here and
now, do the implementation work in remote.c and gdbserver.


Thanks,
Roland


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] auxv support
  2004-01-30 23:51     ` Roland McGrath
@ 2004-01-31  0:11       ` Andrew Cagney
  2004-01-31  0:16         ` Roland McGrath
                           ` (2 more replies)
  0 siblings, 3 replies; 25+ messages in thread
From: Andrew Cagney @ 2004-01-31  0:11 UTC (permalink / raw)
  To: Roland McGrath; +Cc: Daniel Jacobowitz, gdb-patches

>> The target vector update is fine.
> 
> 
> Sorry, I'm not entirely clear on how to read you.  Should I commit the
> whole patch I posted now?  (I'm not sure because you said "target vector
> update", and my patch includes to_xfer_partial target updates,
> to_make_corefile_notes target updates, and the `info auxv' user command.)
> 
> 
>> Would you be able to also knock up an "auxv.exp" test case?  
> 
> 
> Sure!  That is, I'd be happy to try.  Is there an especially good existing
> test case to take as the canonical template for a test such as this?
> 
> To be complete, a test should try a live process, try a real core file, and
> also try making a core file with gcore and then seeing that it matches the
> real process it was made from.  Can you point me to an example of a test
> that elicits core dumps and examines them?

I'd start with corefile.exp, and then delete.  Alternatively:
http://sources.redhat.com/ml/gdb-patches/2004-01/msg00610.html
where I've parked my bigcore.exp test - it compares the output from the 
core file with that of the running program (but note, this will have PIE 
have to be re-aranged for pie).

>> Something to run the command and, most notably, fail if "???" comes out
>> as the auxv entry name?
> 
> 
> That's not really a failure if it does.  Some random kernel change that we
> have no reason to know or care about could cause that to be the case on
> some system.  Do we want to make the gdb test suite complain whenever a new
> constant appears in nature that's not in our table?  

Yes, it's a bug - GDB should correctly display the name of all auxv 
entries for the system it is running on (if we don't do this, no one 
will ever notice, and the auxv table will never be updated ;-).

> If all you intend is a sanity check that we're not reading garbage values,
> there are at least one or two AT_FOO tags that I think can be reliably
> expected to be seen on every system that has an auxv at all.  So we could
> make sure those are there, or just make sure that at least some entries had
> names found.

If you can do this wow.

Look at the

>> Also, just file a bug reports that there isn't an equivalent MI auxv 
>> command, and that those other commands need need documenting.  I'll (or 
>> someone) will need to come back to that.
> 
> 
> Will do.  What about the remote protocol issue?  Should I file a bug for
> that too?  Conversely, I'd be happy to get that resolved right here and
> now, do the implementation work in remote.c and gdbserver.
> 
> 
> Thanks,
> Roland
> 



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] auxv support
  2004-01-31  0:11       ` Andrew Cagney
@ 2004-01-31  0:16         ` Roland McGrath
  2004-02-02 14:27           ` Andrew Cagney
  2004-02-17 16:35         ` Andrew Cagney
  2004-02-24  3:50         ` Roland McGrath
  2 siblings, 1 reply; 25+ messages in thread
From: Roland McGrath @ 2004-01-31  0:16 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: Daniel Jacobowitz, gdb-patches

> Yes, it's a bug - GDB should correctly display the name of all auxv 
> entries for the system it is running on (if we don't do this, no one 
> will ever notice, and the auxv table will never be updated ;-).

Ok, I can get behind that rationale.

> If you can do this wow.
> 
> Look at the

Huh?  Did a finger slip before you finished writing this message?


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] auxv support
  2004-01-31  0:16         ` Roland McGrath
@ 2004-02-02 14:27           ` Andrew Cagney
  0 siblings, 0 replies; 25+ messages in thread
From: Andrew Cagney @ 2004-02-02 14:27 UTC (permalink / raw)
  To: Roland McGrath; +Cc: Daniel Jacobowitz, gdb-patches

> Yes, it's a bug - GDB should correctly display the name of all auxv 
>> entries for the system it is running on (if we don't do this, no one 
>> will ever notice, and the auxv table will never be updated ;-).
> 
> 
> Ok, I can get behind that rationale.
> 
> 
>> If you can do this wow.
>> 
>> Look at the
> 
> 
> Huh?  Did a finger slip before you finished writing this message?

Yes, tipo, "Look at the" turned into the earlier paragraph pointing at 
corefile.exp et.al.

Andrew



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] auxv support
  2004-01-31  0:11       ` Andrew Cagney
  2004-01-31  0:16         ` Roland McGrath
@ 2004-02-17 16:35         ` Andrew Cagney
  2004-02-18  2:08           ` Roland McGrath
  2004-02-24  3:50         ` Roland McGrath
  2 siblings, 1 reply; 25+ messages in thread
From: Andrew Cagney @ 2004-02-17 16:35 UTC (permalink / raw)
  To: Andrew Cagney, Roland McGrath; +Cc: gdb-patches


>>> Would you be able to also knock up an "auxv.exp" test case? 
> 
>> 
>> Sure!  That is, I'd be happy to try.  Is there an especially good existing
>> test case to take as the canonical template for a test such as this?
>> 
>> To be complete, a test should try a live process, try a real core file, and
>> also try making a core file with gcore and then seeing that it matches the
>> real process it was made from.  Can you point me to an example of a test
>> that elicits core dumps and examines them?
>> 

> I'd start with corefile.exp, and then delete.  Alternatively:
> http://sources.redhat.com/ml/gdb-patches/2004-01/msg00610.html
> where I've parked my bigcore.exp test - it compares the output from the core file with that of the running program.

Roland, did you have any luck with this?  bigcore.exp is now in the main 
repository so it's easy to find.

Andrew



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] auxv support
  2004-02-17 16:35         ` Andrew Cagney
@ 2004-02-18  2:08           ` Roland McGrath
  0 siblings, 0 replies; 25+ messages in thread
From: Roland McGrath @ 2004-02-18  2:08 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb-patches

> Roland, did you have any luck with this?  bigcore.exp is now in the main 
> repository so it's easy to find.

Sorry, it's been on the top of my stack, right under the new stuff getting
pushed on top every day. ;-)  I will try to get to it soon.


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] auxv support
  2004-01-31  0:11       ` Andrew Cagney
  2004-01-31  0:16         ` Roland McGrath
  2004-02-17 16:35         ` Andrew Cagney
@ 2004-02-24  3:50         ` Roland McGrath
  2004-02-25  3:59           ` Andrew Cagney
  2004-02-25  4:03           ` [PATCH] auxv support Daniel Jacobowitz
  2 siblings, 2 replies; 25+ messages in thread
From: Roland McGrath @ 2004-02-24  3:50 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: Daniel Jacobowitz, gdb-patches

I've written a new test case for the live process support, grokking native
core files, and gcore.  It works peachy on Linux 2.6 and on Solaris.  It
should work omitting the native core dump part for remote, but I don't know
off hand how to test that.  Are there runtest arguments to make it run
gdbserver for tests?  (I tried --target_board linux-gdbserver, but that
tries to do "rsh linux-gdbserver ../gdbserver/gdbserver ..." instead of
running gdbserver locally.  I can't figure out how to make it not use rsh,
or use a hostname other than "linux-gdbserver".)

However, on a system that does not support getting the auxv data, it shows
three failures.  What is the right thing to do about this?  The difficulty
is that the error from `info auxv' does not distinguish an error/bug in
reading the data from the target code not supporting auxv access or from
the native system not supporting the access even though the gdb target code
does (e.g. Linux < 2.6).


Thanks,
Roland


2004-02-23  Roland McGrath  <roland@redhat.com>

	* gdb.base/auxv.exp: New file.

Index: testsuite/gdb.base/auxv.exp
===================================================================
RCS file: testsuite/gdb.base/auxv.exp
diff -N testsuite/gdb.base/auxv.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.base/auxv.exp	24 Feb 2004 03:06:02 -0000
@@ -0,0 +1,186 @@
+# Test `info auxv' and related functionality.
+
+# Copyright 1992,93,94,95,96,97,98,99,2000,04 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file is based on corefile.exp which was written by Fred
+# Fish. (fnf@cygnus.com)
+
+if $tracelevel then {
+	strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "coremaker2"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+set corefile ${objdir}/${subdir}/${testfile}.corefile
+set gcorefile ${objdir}/${subdir}/${testfile}.gcore
+
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+     gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# Use a fresh directory to confine the native core dumps.
+# Make it the working directory for gdb and its child.
+set coredir "${objdir}/${subdir}/coredir.[getpid]"
+file mkdir $coredir
+set core_works [isnative]
+
+# Run GDB on the coremaker2 program up to where it will dump core.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+gdb_test "set print sevenbit-strings" "" \
+	"set print sevenbit-strings; ${testfile}"
+gdb_test "set width 0" "" \
+	"set width 0; ${testfile}"
+
+if {$core_works} {
+    if {[gdb_test "cd $coredir" ".*Working directory .*" \
+	     "cd to temporary directory for core dumps"]} {
+	set core_works 0
+    }
+}
+
+if { ![runto_main] } then {
+    gdb_suppress_tests;
+}
+set print_core_line [gdb_get_line_number "ABORT;"]
+gdb_test "tbreak $print_core_line"
+gdb_test continue ".*ABORT;.*"
+
+proc fetch_auxv {test} {
+    global gdb_prompt
+
+    set auxv_lines {}
+    set bad -1
+    if {[gdb_test_multiple "info auxv" $test {
+	-re "info auxv\[\r\n\]+" {
+	    exp_continue
+	}
+	-ex "The program has no auxiliary information now" {
+	    set bad 1
+	}
+	-ex "Auxiliary vector is empty" {
+	    set bad 1
+	}
+	-ex "No auxiliary vector found" {
+	    set bad 1
+	}
+	-re "^\[0-9\]+\[ \t\]+(AT_\[^ \t\]+)\[^\r\n\]+\[\r\n\]+" {
+	    lappend auxv_lines $expect_out(0,string)
+	    exp_continue
+	}
+	-re "^\[0-9\]+\[ \t\]+\\?\\?\\?\[^\r\n\]+\[\r\n\]+" {
+	    warning "Unrecognized tag value: $expect_out(0,string)"
+	    set bad 1
+	    lappend auxv_lines $expect_out(0,string)
+	    exp_continue
+	}
+	-re ".*$gdb_prompt $" {
+	    set bad 0
+	}
+	-re "^\[^\r\n\]+\[\r\n\]+" {
+	    warning "Unrecognized output: $expect_out(0,string)"
+	    set bad 1
+	}
+    }] != 0} {
+	return {}
+    }
+
+    if {$bad} {
+	fail $test
+	return {}
+    }
+
+    pass $test
+    return $auxv_lines
+}
+
+set live_data [fetch_auxv "info auxv on live process"]
+
+# Now try gcore.
+set gcore_works 0
+set escapedfilename [string_to_regexp $gcorefile]
+gdb_test_multiple "gcore $gcorefile" "gcore" {
+    -re "Saved corefile ${escapedfilename}\[\r\n\]+$gdb_prompt $" {
+	pass "gcore"
+	set gcore_works 1
+    }
+    -re "Can't create a corefile\[\r\n\]+$gdb_prompt $" {
+	unsupported "gcore"
+    }
+}
+
+# Let the program continue and die.
+gdb_test continue ".*Program received signal.*"
+gdb_test continue ".*Program terminated with signal.*"
+
+# Now collect the core dump it left.
+set test "generate native core dump"
+if {$core_works} {
+    # Find the
+    set names [glob -nocomplain -directory $coredir *core*]
+    if {[llength $names] == 1} {
+	set file [file join $coredir [lindex $names 0]]
+	remote_exec build "mv $file $corefile"
+	pass $test
+    } else {
+	set core_works 0
+	warning "can't generate a core file - core tests suppressed - check ulimit -c"
+	fail $test
+    }
+} else {
+    unsupported $test
+}
+remote_exec build "rm -rf $coredir"
+
+# Now we can examine the core files and check that their data matches what
+# we saw in the process.  Note that the exact data can vary between runs,
+# so it's important that the native core dump file and the gcore-created dump
+# both be from the same run of the program as we examined live.
+
+proc do_core_test {works corefile test1 test2} {
+    if {! $works} {
+	unsupported $test1
+	unsupported $test2
+    } else {
+	gdb_test "core $corefile" "Core was generated by.*" \
+	    "load core file for $test1" \
+	    "A program is being debugged already.*" "y"
+	set core_data [fetch_auxv $test1]
+	global live_data
+	if {$core_data == $live_data} {
+	    pass $test2
+	} else {
+	    fail $test2
+	}
+    }
+}
+
+do_core_test $core_works $corefile \
+    "info auxv on native core dump" "matching auxv data from live and core"
+
+do_core_test $gcore_works $gcorefile \
+    "info auxv on gcore-created dump" "matching auxv data from live and gcore"


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] auxv support
  2004-02-24  3:50         ` Roland McGrath
@ 2004-02-25  3:59           ` Andrew Cagney
  2004-03-19  0:09             ` [COMMITTED PATCH] testsuite for info auxv Roland McGrath
  2004-02-25  4:03           ` [PATCH] auxv support Daniel Jacobowitz
  1 sibling, 1 reply; 25+ messages in thread
From: Andrew Cagney @ 2004-02-25  3:59 UTC (permalink / raw)
  To: Roland McGrath; +Cc: Daniel Jacobowitz, gdb-patches

> I've written a new test case for the live process support, grokking native
> core files, and gcore.  It works peachy on Linux 2.6 and on Solaris.  It
> should work omitting the native core dump part for remote, but I don't know
> off hand how to test that.  Are there runtest arguments to make it run
> gdbserver for tests?  (I tried --target_board linux-gdbserver, but that
> tries to do "rsh linux-gdbserver ../gdbserver/gdbserver ..." instead of
> running gdbserver locally.  I can't figure out how to make it not use rsh,
> or use a hostname other than "linux-gdbserver".)

I'd not worry (I think that should instead use "(gdb) target remote 
|gdbserver").

> However, on a system that does not support getting the auxv data, it shows
> three failures.  What is the right thing to do about this?  The difficulty
> is that the error from `info auxv' does not distinguish an error/bug in
> reading the data from the target code not supporting auxv access or from
> the native system not supporting the access even though the gdb target code
> does (e.g. Linux < 2.6).

Just a few tweaks:

> 2004-02-23  Roland McGrath  <roland@redhat.com>
> 
> 	* gdb.base/auxv.exp: New file.
> 
> Index: testsuite/gdb.base/auxv.exp
> ===================================================================
> RCS file: testsuite/gdb.base/auxv.exp
> diff -N testsuite/gdb.base/auxv.exp
> --- /dev/null	1 Jan 1970 00:00:00 -0000
> +++ testsuite/gdb.base/auxv.exp	24 Feb 2004 03:06:02 -0000
> @@ -0,0 +1,186 @@
> +# Test `info auxv' and related functionality.
> +
> +# Copyright 1992,93,94,95,96,97,98,99,2000,04 Free Software Foundation, Inc.

Just write the years in full.

> +set testfile "coremaker2"
> +set srcfile ${testfile}.c

Here a new file "auxv.c" is prefered for the new test (making a copy of 
coremaker2.c is ok).

Otherwize, remember to post the final patch when committing,

thanks,
Andrew

> +set binfile ${objdir}/${subdir}/${testfile}
> +set corefile ${objdir}/${subdir}/${testfile}.corefile
> +set gcorefile ${objdir}/${subdir}/${testfile}.gcore




^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] auxv support
  2004-02-24  3:50         ` Roland McGrath
  2004-02-25  3:59           ` Andrew Cagney
@ 2004-02-25  4:03           ` Daniel Jacobowitz
  2004-02-25 20:38             ` Roland McGrath
  1 sibling, 1 reply; 25+ messages in thread
From: Daniel Jacobowitz @ 2004-02-25  4:03 UTC (permalink / raw)
  To: Roland McGrath; +Cc: Andrew Cagney, gdb-patches

On Mon, Feb 23, 2004 at 07:50:18PM -0800, Roland McGrath wrote:
> I've written a new test case for the live process support, grokking native
> core files, and gcore.  It works peachy on Linux 2.6 and on Solaris.  It
> should work omitting the native core dump part for remote, but I don't know
> off hand how to test that.  Are there runtest arguments to make it run
> gdbserver for tests?  (I tried --target_board linux-gdbserver, but that
> tries to do "rsh linux-gdbserver ../gdbserver/gdbserver ..." instead of
> running gdbserver locally.  I can't figure out how to make it not use rsh,
> or use a hostname other than "linux-gdbserver".)

Here's the board file I use to run locally, gross hacks and all.

========================
# gdbserver running native.

load_generic_config "gdbserver";

process_multilib_options "";

# The default compiler for this target.
set_board_info compiler  "[find_gcc]";

# We will be using the standard GDB remote protocol
set_board_info gdb_protocol "remote"

# Path to the gdbserver executable, if required.
set_board_info gdb_server_prog \
	"../gdbserver/gdbserver"

# Name of the computer whose socket will be used, if required.
set_board_info sockethost "localhost:"

# Port ID to use for socket connection
# set_board_info gdb,socketport "4004"

# Use techniques appropriate to a stub
set_board_info use_gdb_stub 1;

# This gdbserver can only run a process once per session.
set_board_info gdb,do_reload_on_run 1;

# There's no support for argument-passing (yet).
set_board_info noargs 1

# Can't do input (or output) in the current gdbserver.
set_board_info gdb,noinferiorio 1

# Can't do hardware watchpoints, in general
set_board_info gdb,no_hardware_watchpoints 1;

set_board_info protocol foonevyn

proc foonevyn_download { board host dest } {
  return $host
}
proc foonevyn_spawn { board cmd } {
  global board_info
  set baseboard [lindex [split $board "/"] 0]
  set board_info($baseboard,isremote) 0
  set foo [remote_spawn $board $cmd]
  set board_info($baseboard,isremote) 1
  return $foo
}
========================

> However, on a system that does not support getting the auxv data, it shows
> three failures.  What is the right thing to do about this?  The difficulty
> is that the error from `info auxv' does not distinguish an error/bug in
> reading the data from the target code not supporting auxv access or from
> the native system not supporting the access even though the gdb target code
> does (e.g. Linux < 2.6).

Perhaps arrange to distinguish in the error message?

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] auxv support
  2004-02-25  4:03           ` [PATCH] auxv support Daniel Jacobowitz
@ 2004-02-25 20:38             ` Roland McGrath
  0 siblings, 0 replies; 25+ messages in thread
From: Roland McGrath @ 2004-02-25 20:38 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: Andrew Cagney, gdb-patches

> Here's the board file I use to run locally, gross hacks and all.

I can't figure out where to put this file and how to tell runtest to use it.

> > However, on a system that does not support getting the auxv data, it shows
> > three failures.  What is the right thing to do about this?  The difficulty
> > is that the error from `info auxv' does not distinguish an error/bug in
> > reading the data from the target code not supporting auxv access or from
> > the native system not supporting the access even though the gdb target code
> > does (e.g. Linux < 2.6).
> 
> Perhaps arrange to distinguish in the error message?

This sounds like it should be easy, but it's really not.  The
target-config-never-supports case and error cases are both indicated by
target_read_partial returning -1.  No other details are made available by
the target interfaces.  Even if we addressed the case of there not being
any code around that does it at all, there are still the kernel (or stub)
doesn't support it vs miscellaneous error cases.  The backend or gdbserver
code can potentially distinguish, i.e. failing open with ENOENT vs other
errors or errors on read after open.  But that would require passing back
the failure mode in some distinguished way, rather than just -1.


Thanks,
Roland


^ permalink raw reply	[flat|nested] 25+ messages in thread

* [COMMITTED PATCH] testsuite for info auxv
  2004-03-19  0:09             ` [COMMITTED PATCH] testsuite for info auxv Roland McGrath
@ 2004-03-17 20:46               ` Roland McGrath
  0 siblings, 0 replies; 25+ messages in thread
From: Roland McGrath @ 2004-03-17 20:46 UTC (permalink / raw)
  To: gdb-patches

Sorry this got forgotten on the back burner for a few weeks.  
I've just checked in the test case for the new `info auxv' functionality.
I made some tiny improvements to the tcl code and made the changes that
Andrew requested, but this is almost identical to what I posted before.
As I mentioned in previous discussion, this now produces:

	FAIL: gdb.base/auxv.exp: info auxv on live process
	FAIL: gdb.base/auxv.exp: info auxv on native core dump
	FAIL: gdb.base/auxv.exp: info auxv on gcore-created dump

on any system without auxv access support, i.e. anything but Linux 2.6 or
Solaris.  So don't be surprised by seeing those new failures.


Thanks,
Roland


2004-03-16  Roland McGrath  <roland@redhat.com>

	* gdb.base/auxv.exp: New file.
	* gdb.base/auxv.c: New file, copied verbatim from coremaker2.c.

Index: gdb/testsuite/gdb.base/auxv.c
===================================================================
RCS file: gdb/testsuite/gdb.base/auxv.c
diff -N gdb/testsuite/gdb.base/auxv.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gdb/testsuite/gdb.base/auxv.c	16 Mar 2004 21:41:43 -0000
@@ -0,0 +1,58 @@
+/* Simple little program that just generates a core dump from inside some
+   nested function calls.  Keep this as self contained as possible, I.E.
+   use no environment resources other than possibly abort(). */
+
+#ifndef __STDC__
+#define	const	/**/
+#endif
+
+#ifndef HAVE_ABORT
+#define HAVE_ABORT 1
+#endif
+
+#if HAVE_ABORT
+#define ABORT abort()
+#else
+#define ABORT {char *invalid = 0; *invalid = 0xFF;}
+#endif
+
+/* Don't make these automatic vars or we will have to walk back up the
+   stack to access them. */
+
+char *buf1;
+char *buf2;
+
+int coremaker_data = 1;	/* In Data section */
+int coremaker_bss;	/* In BSS section */
+
+const int coremaker_ro = 201;	/* In Read-Only Data section */
+
+void
+func2 (int x)
+{
+  int coremaker_local[5];
+  int i;
+  static int y;
+
+  /* Make sure that coremaker_local doesn't get optimized away. */
+  for (i = 0; i < 5; i++)
+    coremaker_local[i] = i;
+  coremaker_bss = 0;
+  for (i = 0; i < 5; i++)
+    coremaker_bss += coremaker_local[i];
+  coremaker_data = coremaker_ro + 1;
+  y = 10 * x;
+  ABORT;
+}
+
+void
+func1 (int x)
+{
+  func2 (x * 2);
+}
+
+int main ()
+{
+  func1 (10);
+  return 0;
+}
Index: gdb/testsuite/gdb.base/auxv.exp
===================================================================
RCS file: gdb/testsuite/gdb.base/auxv.exp
diff -N gdb/testsuite/gdb.base/auxv.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gdb/testsuite/gdb.base/auxv.exp	16 Mar 2004 21:41:43 -0000
@@ -0,0 +1,187 @@
+# Test `info auxv' and related functionality.
+
+# Copyright 1992,1993,1994,1995,1996,1997,1998,1999,2000,2004
+#	Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file is based on corefile.exp which was written by Fred
+# Fish. (fnf@cygnus.com)
+
+if $tracelevel then {
+	strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "auxv"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+set corefile ${objdir}/${subdir}/${testfile}.corefile
+set gcorefile ${objdir}/${subdir}/${testfile}.gcore
+
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+     gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# Use a fresh directory to confine the native core dumps.
+# Make it the working directory for gdb and its child.
+set coredir "${objdir}/${subdir}/coredir.[getpid]"
+file mkdir $coredir
+set core_works [isnative]
+
+# Run GDB on the test program up to where it will dump core.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+gdb_test "set print sevenbit-strings" "" \
+	"set print sevenbit-strings; ${testfile}"
+gdb_test "set width 0" "" \
+	"set width 0; ${testfile}"
+
+if {$core_works} {
+    if {[gdb_test "cd $coredir" ".*Working directory .*" \
+	     "cd to temporary directory for core dumps"]} {
+	set core_works 0
+    }
+}
+
+if { ![runto_main] } then {
+    gdb_suppress_tests;
+}
+set print_core_line [gdb_get_line_number "ABORT;"]
+gdb_test "tbreak $print_core_line"
+gdb_test continue ".*ABORT;.*"
+
+proc fetch_auxv {test} {
+    global gdb_prompt
+
+    set auxv_lines {}
+    set bad -1
+    if {[gdb_test_multiple "info auxv" $test {
+	-re "info auxv\[\r\n\]+" {
+	    exp_continue
+	}
+	-ex "The program has no auxiliary information now" {
+	    set bad 1
+	}
+	-ex "Auxiliary vector is empty" {
+	    set bad 1
+	}
+	-ex "No auxiliary vector found" {
+	    set bad 1
+	}
+	-re "^\[0-9\]+\[ \t\]+(AT_\[^ \t\]+)\[^\r\n\]+\[\r\n\]+" {
+	    lappend auxv_lines $expect_out(0,string)
+	    exp_continue
+	}
+	-re "^\[0-9\]+\[ \t\]+\\?\\?\\?\[^\r\n\]+\[\r\n\]+" {
+	    warning "Unrecognized tag value: $expect_out(0,string)"
+	    set bad 1
+	    lappend auxv_lines $expect_out(0,string)
+	    exp_continue
+	}
+	-re ".*$gdb_prompt $" {
+	    incr bad
+	}
+	-re "^\[^\r\n\]+\[\r\n\]+" {
+	    warning "Unrecognized output: $expect_out(0,string)"
+	    set bad 1
+	}
+    }] != 0} {
+	return {}
+    }
+
+    if {$bad} {
+	fail $test
+	return {}
+    }
+
+    pass $test
+    return $auxv_lines
+}
+
+set live_data [fetch_auxv "info auxv on live process"]
+
+# Now try gcore.
+set gcore_works 0
+set escapedfilename [string_to_regexp $gcorefile]
+gdb_test_multiple "gcore $gcorefile" "gcore" {
+    -re "Saved corefile ${escapedfilename}\[\r\n\]+$gdb_prompt $" {
+	pass "gcore"
+	set gcore_works 1
+    }
+    -re "Can't create a corefile\[\r\n\]+$gdb_prompt $" {
+	unsupported "gcore"
+    }
+}
+
+# Let the program continue and die.
+gdb_test continue ".*Program received signal.*"
+gdb_test continue ".*Program terminated with signal.*"
+
+# Now collect the core dump it left.
+set test "generate native core dump"
+if {$core_works} {
+    # Find the
+    set names [glob -nocomplain -directory $coredir *core*]
+    if {[llength $names] == 1} {
+	set file [file join $coredir [lindex $names 0]]
+	remote_exec build "mv $file $corefile"
+	pass $test
+    } else {
+	set core_works 0
+	warning "can't generate a core file - core tests suppressed - check ulimit -c"
+	fail $test
+    }
+} else {
+    unsupported $test
+}
+remote_exec build "rm -rf $coredir"
+
+# Now we can examine the core files and check that their data matches what
+# we saw in the process.  Note that the exact data can vary between runs,
+# so it's important that the native core dump file and the gcore-created dump
+# both be from the same run of the program as we examined live.
+
+proc do_core_test {works corefile test1 test2} {
+    if {! $works} {
+	unsupported $test1
+	unsupported $test2
+    } else {
+	gdb_test "core $corefile" "Core was generated by.*" \
+	    "load core file for $test1" \
+	    "A program is being debugged already.*" "y"
+	set core_data [fetch_auxv $test1]
+	global live_data
+	if {$core_data == $live_data} {
+	    pass $test2
+	} else {
+	    fail $test2
+	}
+    }
+}
+
+do_core_test $core_works $corefile \
+    "info auxv on native core dump" "matching auxv data from live and core"
+
+do_core_test $gcore_works $gcorefile \
+    "info auxv on gcore-created dump" "matching auxv data from live and gcore"
 


^ permalink raw reply	[flat|nested] 25+ messages in thread

* [COMMITTED PATCH] testsuite for info auxv
  2004-02-25  3:59           ` Andrew Cagney
@ 2004-03-19  0:09             ` Roland McGrath
  2004-03-17 20:46               ` Roland McGrath
  0 siblings, 1 reply; 25+ messages in thread
From: Roland McGrath @ 2004-03-19  0:09 UTC (permalink / raw)
  To: gdb-patches

Sorry this got forgotten on the back burner for a few weeks.  
I've just checked in the test case for the new `info auxv' functionality.
I made some tiny improvements to the tcl code and made the changes that
Andrew requested, but this is almost identical to what I posted before.
As I mentioned in previous discussion, this now produces:

	FAIL: gdb.base/auxv.exp: info auxv on live process
	FAIL: gdb.base/auxv.exp: info auxv on native core dump
	FAIL: gdb.base/auxv.exp: info auxv on gcore-created dump

on any system without auxv access support, i.e. anything but Linux 2.6 or
Solaris.  So don't be surprised by seeing those new failures.


Thanks,
Roland


2004-03-16  Roland McGrath  <roland@redhat.com>

	* gdb.base/auxv.exp: New file.
	* gdb.base/auxv.c: New file, copied verbatim from coremaker2.c.

Index: gdb/testsuite/gdb.base/auxv.c
===================================================================
RCS file: gdb/testsuite/gdb.base/auxv.c
diff -N gdb/testsuite/gdb.base/auxv.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gdb/testsuite/gdb.base/auxv.c	16 Mar 2004 21:41:43 -0000
@@ -0,0 +1,58 @@
+/* Simple little program that just generates a core dump from inside some
+   nested function calls.  Keep this as self contained as possible, I.E.
+   use no environment resources other than possibly abort(). */
+
+#ifndef __STDC__
+#define	const	/**/
+#endif
+
+#ifndef HAVE_ABORT
+#define HAVE_ABORT 1
+#endif
+
+#if HAVE_ABORT
+#define ABORT abort()
+#else
+#define ABORT {char *invalid = 0; *invalid = 0xFF;}
+#endif
+
+/* Don't make these automatic vars or we will have to walk back up the
+   stack to access them. */
+
+char *buf1;
+char *buf2;
+
+int coremaker_data = 1;	/* In Data section */
+int coremaker_bss;	/* In BSS section */
+
+const int coremaker_ro = 201;	/* In Read-Only Data section */
+
+void
+func2 (int x)
+{
+  int coremaker_local[5];
+  int i;
+  static int y;
+
+  /* Make sure that coremaker_local doesn't get optimized away. */
+  for (i = 0; i < 5; i++)
+    coremaker_local[i] = i;
+  coremaker_bss = 0;
+  for (i = 0; i < 5; i++)
+    coremaker_bss += coremaker_local[i];
+  coremaker_data = coremaker_ro + 1;
+  y = 10 * x;
+  ABORT;
+}
+
+void
+func1 (int x)
+{
+  func2 (x * 2);
+}
+
+int main ()
+{
+  func1 (10);
+  return 0;
+}
Index: gdb/testsuite/gdb.base/auxv.exp
===================================================================
RCS file: gdb/testsuite/gdb.base/auxv.exp
diff -N gdb/testsuite/gdb.base/auxv.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gdb/testsuite/gdb.base/auxv.exp	16 Mar 2004 21:41:43 -0000
@@ -0,0 +1,187 @@
+# Test `info auxv' and related functionality.
+
+# Copyright 1992,1993,1994,1995,1996,1997,1998,1999,2000,2004
+#	Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file is based on corefile.exp which was written by Fred
+# Fish. (fnf@cygnus.com)
+
+if $tracelevel then {
+	strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "auxv"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+set corefile ${objdir}/${subdir}/${testfile}.corefile
+set gcorefile ${objdir}/${subdir}/${testfile}.gcore
+
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+     gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+
+# Use a fresh directory to confine the native core dumps.
+# Make it the working directory for gdb and its child.
+set coredir "${objdir}/${subdir}/coredir.[getpid]"
+file mkdir $coredir
+set core_works [isnative]
+
+# Run GDB on the test program up to where it will dump core.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+gdb_test "set print sevenbit-strings" "" \
+	"set print sevenbit-strings; ${testfile}"
+gdb_test "set width 0" "" \
+	"set width 0; ${testfile}"
+
+if {$core_works} {
+    if {[gdb_test "cd $coredir" ".*Working directory .*" \
+	     "cd to temporary directory for core dumps"]} {
+	set core_works 0
+    }
+}
+
+if { ![runto_main] } then {
+    gdb_suppress_tests;
+}
+set print_core_line [gdb_get_line_number "ABORT;"]
+gdb_test "tbreak $print_core_line"
+gdb_test continue ".*ABORT;.*"
+
+proc fetch_auxv {test} {
+    global gdb_prompt
+
+    set auxv_lines {}
+    set bad -1
+    if {[gdb_test_multiple "info auxv" $test {
+	-re "info auxv\[\r\n\]+" {
+	    exp_continue
+	}
+	-ex "The program has no auxiliary information now" {
+	    set bad 1
+	}
+	-ex "Auxiliary vector is empty" {
+	    set bad 1
+	}
+	-ex "No auxiliary vector found" {
+	    set bad 1
+	}
+	-re "^\[0-9\]+\[ \t\]+(AT_\[^ \t\]+)\[^\r\n\]+\[\r\n\]+" {
+	    lappend auxv_lines $expect_out(0,string)
+	    exp_continue
+	}
+	-re "^\[0-9\]+\[ \t\]+\\?\\?\\?\[^\r\n\]+\[\r\n\]+" {
+	    warning "Unrecognized tag value: $expect_out(0,string)"
+	    set bad 1
+	    lappend auxv_lines $expect_out(0,string)
+	    exp_continue
+	}
+	-re ".*$gdb_prompt $" {
+	    incr bad
+	}
+	-re "^\[^\r\n\]+\[\r\n\]+" {
+	    warning "Unrecognized output: $expect_out(0,string)"
+	    set bad 1
+	}
+    }] != 0} {
+	return {}
+    }
+
+    if {$bad} {
+	fail $test
+	return {}
+    }
+
+    pass $test
+    return $auxv_lines
+}
+
+set live_data [fetch_auxv "info auxv on live process"]
+
+# Now try gcore.
+set gcore_works 0
+set escapedfilename [string_to_regexp $gcorefile]
+gdb_test_multiple "gcore $gcorefile" "gcore" {
+    -re "Saved corefile ${escapedfilename}\[\r\n\]+$gdb_prompt $" {
+	pass "gcore"
+	set gcore_works 1
+    }
+    -re "Can't create a corefile\[\r\n\]+$gdb_prompt $" {
+	unsupported "gcore"
+    }
+}
+
+# Let the program continue and die.
+gdb_test continue ".*Program received signal.*"
+gdb_test continue ".*Program terminated with signal.*"
+
+# Now collect the core dump it left.
+set test "generate native core dump"
+if {$core_works} {
+    # Find the
+    set names [glob -nocomplain -directory $coredir *core*]
+    if {[llength $names] == 1} {
+	set file [file join $coredir [lindex $names 0]]
+	remote_exec build "mv $file $corefile"
+	pass $test
+    } else {
+	set core_works 0
+	warning "can't generate a core file - core tests suppressed - check ulimit -c"
+	fail $test
+    }
+} else {
+    unsupported $test
+}
+remote_exec build "rm -rf $coredir"
+
+# Now we can examine the core files and check that their data matches what
+# we saw in the process.  Note that the exact data can vary between runs,
+# so it's important that the native core dump file and the gcore-created dump
+# both be from the same run of the program as we examined live.
+
+proc do_core_test {works corefile test1 test2} {
+    if {! $works} {
+	unsupported $test1
+	unsupported $test2
+    } else {
+	gdb_test "core $corefile" "Core was generated by.*" \
+	    "load core file for $test1" \
+	    "A program is being debugged already.*" "y"
+	set core_data [fetch_auxv $test1]
+	global live_data
+	if {$core_data == $live_data} {
+	    pass $test2
+	} else {
+	    fail $test2
+	}
+    }
+}
+
+do_core_test $core_works $corefile \
+    "info auxv on native core dump" "matching auxv data from live and core"
+
+do_core_test $gcore_works $gcorefile \
+    "info auxv on gcore-created dump" "matching auxv data from live and gcore"
 


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] auxv support
  2004-02-01  6:04 ` Daniel Jacobowitz
                     ` (2 preceding siblings ...)
  2004-02-02 14:17   ` Andrew Cagney
@ 2004-02-02 14:25   ` Andrew Cagney
  3 siblings, 0 replies; 25+ messages in thread
From: Andrew Cagney @ 2004-02-02 14:25 UTC (permalink / raw)
  To: Daniel Jacobowitz, Roland McGrath; +Cc: gdb-patches

> 
> Seems reasonable.  Probably the packet will need to be conditionally
> supported (see packet_ok, remote_P_packet or so).  The mechanism for
> doing that at the moment involves a couple of copy/pastes, it needs
> cleaning up eventually.
> 
Daniel, remember, proposals to either change or extend the protocol 
first need to be discussed on gdb@.

Roland, for the remote changes, can you start a new thread on gdb@ 
describing what you're thinking (since it needs doco changes, people 
often present it as a diff to gdb/doc/gdb.texinfo)?

Andrew



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] auxv support
  2004-02-01  6:04 ` Daniel Jacobowitz
  2004-02-01 22:36   ` Roland McGrath
  2004-02-02  0:11   ` Roland McGrath
@ 2004-02-02 14:17   ` Andrew Cagney
  2004-02-02 14:25   ` Andrew Cagney
  3 siblings, 0 replies; 25+ messages in thread
From: Andrew Cagney @ 2004-02-02 14:17 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: Roland McGrath, gdb-patches

> On Fri, Jan 30, 2004 at 04:13:49PM -0800, Roland McGrath wrote:
> 
>> For some reason I didn't get your message directly (yet anyway), though
>> I've now seen it in the mailing list archives.
> 
> 
> List reply bites again.  If you are not subscribed to gdb-patches,
> please use a reply-to or something along those lines... otherwise I
> assume it was just mail lag.

Please, no - Reply-to is bad m'kay!  As posters to this list we should 
assume that the people we interact with are not subscribed, and hence, 
we should not (at least in general) trim CC lines.

Andrew



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] auxv support
  2004-02-02  0:11   ` Roland McGrath
@ 2004-02-02  6:24     ` Eli Zaretskii
  0 siblings, 0 replies; 25+ messages in thread
From: Eli Zaretskii @ 2004-02-02  6:24 UTC (permalink / raw)
  To: Roland McGrath; +Cc: drow, gdb-patches

> Date: Sun, 1 Feb 2004 16:11:22 -0800
> From: Roland McGrath <roland@redhat.com>
> 
> Following are three pairs of log entry and patch.  First, docs for info
> auxv and the new qAuxVector remote protocol packet.

Thanks.

> @@ -20363,6 +20390,18 @@ encoded).  @value{GDBN} will continue to
>  (if available), until the target ceases to request them.
>  @end table
>  
> +@item @code{qAuxVector}:@var{offset},@var{length} --- auxiliary vector data
> +
> +Read from the target's @dfn{auxiliary vector}, treated as an
> +uninterpreted block of bytes.  Request @var{length} starting at
> +@var{offset} bytes into the data.

I think it's better to say

   Request @var{length} bytes starting at ...

Also, please add here a cross-reference to the section that explains
what is an auxiliary vector.  (The best place for that xref is after
the @dfn, I think.)


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] auxv support
  2004-02-01  6:04 ` Daniel Jacobowitz
  2004-02-01 22:36   ` Roland McGrath
@ 2004-02-02  0:11   ` Roland McGrath
  2004-02-02  6:24     ` Eli Zaretskii
  2004-02-02 14:17   ` Andrew Cagney
  2004-02-02 14:25   ` Andrew Cagney
  3 siblings, 1 reply; 25+ messages in thread
From: Roland McGrath @ 2004-02-02  0:11 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: gdb-patches

> Seems reasonable.  Probably the packet will need to be conditionally
> supported (see packet_ok, remote_P_packet or so).  The mechanism for
> doing that at the moment involves a couple of copy/pastes, it needs
> cleaning up eventually.

Ok.

> Personally I would prefer a separate packet for each type of aux data. 

Alrighty.  I decided to keep the reply format simple and the request format
matching gdb's usage need (i.e. OFFSET+LEN), since anything more
informative would not be useful unless the way to_xfer_partial is used were
to change.

> Note that you'll need to use LinuxThreads (or no threads) if you want
> to test this with gdbserver; I have NPTL support almost done but it
> needs the remote.c patch I posted today.

I just tested single-threaded cases.  Threads are orthogonal to this support.

Following are three pairs of log entry and patch.  First, docs for info
auxv and the new qAuxVector remote protocol packet.  Second, remote.c
support for using qAuxVector.  Third, gdbserver support for the qAuxVector
packet using a new target hook, implemented in the Linux backend.  

I tested the remote support using gdbserver on Linux, though I have not
tested any of the error cases (just saw "info auxv" work right via gdbserver).


Thanks,
Roland



2004-02-01  Roland McGrath  <roland@redhat.com>

	* gdb.texinfo (Auxiliary Vector): New node (section).
	(Data): Add it to the menu.
	(General Query Packets): Document qAuxVector query packet.

--- doc/gdb.texinfo.~1.190.~	2004-01-28 16:21:23.000000000 -0800
+++ doc/gdb.texinfo	2004-02-01 15:43:20.000000000 -0800
@@ -4684,6 +4684,7 @@ Table}.
 * Registers::                   Registers
 * Floating Point Hardware::     Floating point hardware
 * Vector Unit::                 Vector Unit
+* Auxiliary Vector::            Auxiliary data provided by operating system
 * Memory Region Attributes::    Memory region attributes
 * Dump/Restore Files::          Copy between memory and a file
 * Character Sets::              Debugging programs that use a different
@@ -5864,6 +5865,32 @@ Display information about the vector uni
 layout vary depending on the hardware.
 @end table
 
+@node Auxiliary Vector
+@section Operating system auxiliary vector
+@cindex auxiliary vector
+@cindex vector, auxiliary
+
+Some operating systems supply an @dfn{auxiliary vector} to programs at
+startup.  This is akin to the arguments and environment that you
+specify for a program, but contains a system-dependent variety of
+binary values that tell system libraries important details about the
+hardware, operating system, and process.  Each value's purpose is
+identified by an integer tag; the meanings are well-known but system-specific.
+Depending on the configuration and operating system facilities,
+@value{GDBN} may be able to show you this information.
+
+@table @code
+@kindex info auxv
+@item info auxv
+Display the auxiliary vector of the inferior, which can be either a
+live process or a core dump file.  @{GDBN} prints each tag value
+numerically, and also shows names and text descriptions for recognized
+tags.  Some values in the vector are numbers, some bit masks, and some
+pointers to strings or other data.  @{GDBN} displays each value in the
+most appropriate form for a recognized tag, and in hexadecimal for
+an unrecognized tag.
+@end table
+
 @node Memory Region Attributes
 @section Memory region attributes 
 @cindex memory region attributes
@@ -20363,6 +20390,18 @@ encoded).  @value{GDBN} will continue to
 (if available), until the target ceases to request them.
 @end table
 
+@item @code{qAuxVector}:@var{offset},@var{length} --- auxiliary vector data
+
+Read from the target's @dfn{auxiliary vector}, treated as an
+uninterpreted block of bytes.  Request @var{length} starting at
+@var{offset} bytes into the data.
+
+Reply:
+@table @samp
+@item @code{A=}@var{data}
+@var{data} (hex encoded) contains the data bytes read.
+@end table
+
 @end table
 
 @node Register Packet Format



2004-02-01  Roland McGrath  <roland@redhat.com>

	* remote.c (remote_protocol_qAuxVector): New variable.
	(init_all_packet_configs): Initialize it.
	(set_remote_protocol_qAuxVector_packet_cmd): New function.
	(show_remote_protocol_qAuxVector_packet_cmd): New function.
	(show_remote_cmd): Call it.
	(_initialize_remote): Initialize commands.
	(remote_xfer_partial): If enabled, use qAuxVector query to service
	TARGET_OBJECT_AUXV requests.

Index: remote.c
===================================================================
RCS file: /cvs/src/src/gdb/remote.c,v
retrieving revision 1.128
diff -u -b -p -r1.128 remote.c
--- remote.c	26 Jan 2004 23:07:00 -0000	1.128
+++ remote.c	2 Feb 2004 00:00:39 -0000
@@ -981,6 +981,23 @@ show_remote_protocol_binary_download_cmd
   show_packet_config_cmd (&remote_protocol_binary_download);
 }
 
+/* Should we try the 'qAuxVector' (target auxiliary vector read) request? */
+static struct packet_config remote_protocol_qAuxVector;
+
+static void
+set_remote_protocol_qAuxVector_packet_cmd (char *args, int from_tty,
+					   struct cmd_list_element *c)
+{
+  update_packet_config (&remote_protocol_qAuxVector);
+}
+
+static void
+show_remote_protocol_qAuxVector_packet_cmd (char *args, int from_tty,
+					    struct cmd_list_element *c)
+{
+  show_packet_config_cmd (&remote_protocol_qAuxVector);
+}
+
 
 /* Tokens for use by the asynchronous signal handlers for SIGINT */
 static void *sigint_remote_twice_token;
@@ -2070,6 +2087,7 @@ init_all_packet_configs (void)
   /* Force remote_write_bytes to check whether target supports binary
      downloading. */
   update_packet_config (&remote_protocol_binary_download);
+  update_packet_config (&remote_protocol_qAuxVector);
 }
 
 /* Symbol look-up. */
@@ -4872,6 +4890,42 @@ remote_xfer_partial (struct target_ops *
     case TARGET_OBJECT_AVR:
       query_type = 'R';
       break;
+
+    case TARGET_OBJECT_AUXV:
+      if (remote_protocol_qAuxVector.support != PACKET_DISABLE)
+	{
+	  unsigned int total = 0;
+	  while (len > 0)
+	    {
+	      LONGEST n = min ((rs->remote_packet_size - 2) / 2, len);
+	      snprintf (buf2, rs->remote_packet_size,
+			"qAuxVector:%s,%s",
+			phex_nz (offset, sizeof offset),
+			phex_nz (n, sizeof n));
+	      i = putpkt (buf2);
+	      if (i < 0)
+		return total > 0 ? total : i;
+	      buf2[0] = '\0';
+	      getpkt (buf2, rs->remote_packet_size, 0);
+	      if (packet_ok (buf2, &remote_protocol_qAuxVector) != PACKET_OK)
+		return total > 0 ? total : -1;
+	      if (buf2[0] != 'A' || buf2[1] != '=')
+		{
+		  warning ("Malformed response to qAuxVector: %s", buf2);
+		  return total > 0 ? total : i;
+		}
+	      i = hex2bin (&buf2[2], readbuf, len);
+	      if (i == 0)
+		break;
+	      readbuf = (void *) ((char *) readbuf + i);
+	      offset += i;
+	      len -= i;
+	      total += i;
+	    }
+	  return total;
+	}
+      return -1;
+
     default:
       return -1;
     }
@@ -5369,6 +5423,7 @@ show_remote_cmd (char *args, int from_tt
   show_remote_protocol_qSymbol_packet_cmd (args, from_tty, NULL);
   show_remote_protocol_vcont_packet_cmd (args, from_tty, NULL);
   show_remote_protocol_binary_download_cmd (args, from_tty, NULL);
+  show_remote_protocol_qAuxVector_packet_cmd (args, from_tty, NULL);
 }
 
 static void
@@ -5610,6 +5665,13 @@ in a memory packet.\n",
 			 "Z4", "access-watchpoint",
 			 set_remote_protocol_Z_access_wp_packet_cmd,
 			 show_remote_protocol_Z_access_wp_packet_cmd,
+			 &remote_set_cmdlist, &remote_show_cmdlist,
+			 0);
+
+  add_packet_config_cmd (&remote_protocol_qAuxVector,
+			 "qAuxVector", "read-aux-vector",
+			 set_remote_protocol_qAuxVector_packet_cmd,
+			 show_remote_protocol_qAuxVector_packet_cmd,
 			 &remote_set_cmdlist, &remote_show_cmdlist,
 			 0);



2004-02-01  Roland McGrath  <roland@redhat.com>

	* target.h (struct target_ops): New member `read_auxv'.
	* server.c (handle_query): Handle qAuxVector query using that hook.
	* linux-low.c (linux_read_auxv): New function.
	(linux_target_ops): Initialize `read_auxv' member to that.

Index: gdbserver/linux-low.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/linux-low.c,v
retrieving revision 1.27
diff -b -p -u -r1.27 linux-low.c
--- gdbserver/linux-low.c	31 Jan 2004 22:19:31 -0000	1.27
+++ gdbserver/linux-low.c	2 Feb 2004 00:00:02 -0000
@@ -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_op
   linux_write_memory,
   linux_look_up_symbols,
   linux_send_signal,
+  linux_read_auxv,
 };
 
 static void
Index: gdbserver/server.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/server.c,v
retrieving revision 1.16
diff -b -p -u -r1.16 server.c
--- gdbserver/server.c	13 Oct 2003 16:17:21 -0000	1.16
+++ gdbserver/server.c	2 Feb 2004 00:00:02 -0000
@@ -120,6 +120,32 @@ handle_query (char *own_buf)
 	}
     }
       
+  if (strncmp ("qAuxVector:", own_buf, 11) == 0)
+    {
+      if (the_target->read_auxv == NULL)
+	strcpy (own_buf, "E00");
+      else
+	{
+	  char data[(PBUFSIZ - 3) / 2];
+	  CORE_ADDR ofs;
+	  unsigned int len;
+	  int n;
+	  decode_m_packet (&own_buf[11], &ofs, &len); /* "OFS,LEN" */
+	  if (len > sizeof data)
+	    len = sizeof data;
+	  n = (*the_target->read_auxv) (ofs, data, len);
+	  if (n < 0)
+	    strcpy (own_buf, "E00");
+	  else
+	    {
+	      own_buf[0] = 'A';
+	      own_buf[1] = '=';
+	      convert_int_to_ascii (data, &own_buf[2], n);
+	    }
+	}
+      return;
+    }
+
   /* Otherwise we didn't know what packet it was.  Say we didn't
      understand it.  */
   own_buf[0] = 0;
Index: gdbserver/target.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/target.h,v
retrieving revision 1.8
diff -b -p -u -r1.8 target.h
--- gdbserver/target.h	13 Oct 2003 16:17:21 -0000	1.8
+++ gdbserver/target.h	2 Feb 2004 00:00:02 -0000
@@ -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;


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] auxv support
  2004-02-01  6:04 ` Daniel Jacobowitz
@ 2004-02-01 22:36   ` Roland McGrath
  2004-02-02  0:11   ` Roland McGrath
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 25+ messages in thread
From: Roland McGrath @ 2004-02-01 22:36 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: Andrew Cagney, gdb-patches

> List reply bites again.  If you are not subscribed to gdb-patches,
> please use a reply-to or something along those lines... otherwise I
> assume it was just mail lag.

Well, we're both explicitly in headers for this thread now, so I'll leave
at that.  Reply-To causes yet more trouble.

> I've approved the rest of the patch, so go ahead and check it in, along
> with the documentation.  Then we can get back to the testcase and
> remote support.

Okey dokey.  I've checked it in.


Thanks,
Roland


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH] auxv support
       [not found] <200401310013.i0V0DnGE018646@magilla.sf.frob.com>
@ 2004-02-01  6:04 ` Daniel Jacobowitz
  2004-02-01 22:36   ` Roland McGrath
                     ` (3 more replies)
  0 siblings, 4 replies; 25+ messages in thread
From: Daniel Jacobowitz @ 2004-02-01  6:04 UTC (permalink / raw)
  To: Roland McGrath; +Cc: Andrew Cagney, gdb-patches

On Fri, Jan 30, 2004 at 04:13:49PM -0800, Roland McGrath wrote:
> For some reason I didn't get your message directly (yet anyway), though
> I've now seen it in the mailing list archives.

List reply bites again.  If you are not subscribed to gdb-patches,
please use a reply-to or something along those lines... otherwise I
assume it was just mail lag.

> As to the OPS argument to target_auxv_parse, I found it consistent and
> originally had in mind that it would be used to know the wordsize and byte
> order, since that seems like the appropriate sort of modularity to me.  But
> then I followed Andrew's code for the implementation, i.e. using
> `extract_unsigned_integer' with its reference to global state.  I presume
> that what Andrew did is the current preferred thing to do.  Frankly, I
> can't figure out which parts of gdb's interface are supposed to be modular
> in what way.  Everything else related to this code uses target_ops pointers
> instead of referring to global variables.  

I'm not sure whether the target is supposed to indicate an architecture
in this fashion (target has-an architecture), but I guess it makes
sense that (someday) it would.  So, fine.

You wrote elsewhere:
>>The target vector update is fine.
>
>
>Sorry, I'm not entirely clear on how to read you.  Should I commit the 
>whole patch I posted now?  (I'm not sure because you said "target vector
>update", and my patch includes to_xfer_partial target updates,
>to_make_corefile_notes target updates, and the `info auxv' user command.)

I've approved the rest of the patch, so go ahead and check it in, along
with the documentation.  Then we can get back to the testcase and
remote support.

> +
> +    case TARGET_OBJECT_AUXV:
> +      sprintf (buf2, "qAuxVector:%lu", (unsigned long int) offset);
> +      i = putpkt (buf2);
> +      if (i < 0)
> +	return i;
> +      buf2[0] = '\0';
> +      getpkt (buf2, rs->remote_packet_size, 0);
> +      if (buf2[0] == '\0')
> +	return -1;
> +      return hex2bin (buf2, readbuf, len);
> +
>      default:
>        return -1;
>      }

Seems reasonable.  Probably the packet will need to be conditionally
supported (see packet_ok, remote_P_packet or so).  The mechanism for
doing that at the moment involves a couple of copy/pastes, it needs
cleaning up eventually.

> A slightly more grandiose idea is to define it as:
> 
> 	qAux:<what>:<offset>:<readsize>
> 
> This is in the target_read_partial vein, giving a <what> string of auxv or
> unwind or suchlike, and decimal values for <offset> and <readsize>.
> The reply packet should perhaps explicitly say whether it's just returning
> a partial response, or if it read all there was, e.g.
> 
> 	<totalsize>:<hexdata>
> 
> I don't know if this is considered more or less desireable than an entirely
> new flavor of packet for each kind of other-than-memory space to be accessed.

Personally I would prefer a separate packet for each type of aux data. 
Gdbserver would end up with a strncmp (buf, "qAux:auxv", 9) versus a
strncmp (buf, "qAuxVector:", 11), and qAuxVector is more
straightforward to probe for the existence of.  Perhaps it should be
qAuxVector:<offset>:<readsize> rather than qAuxVector:<offset>.

Note that you'll need to use LinuxThreads (or no threads) if you want
to test this with gdbserver; I have NPTL support almost done but it
needs the remote.c patch I posted today.

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer


^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2004-03-17 20:46 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-01-29  2:59 [PATCH] auxv support Roland McGrath
2004-01-29  6:39 ` Eli Zaretskii
2004-01-29  8:20   ` Roland McGrath
2004-01-29 20:14     ` Eli Zaretskii
2004-01-29 21:31       ` Roland McGrath
2004-01-30 19:03 ` Daniel Jacobowitz
2004-01-30 23:35   ` Andrew Cagney
2004-01-30 23:51     ` Roland McGrath
2004-01-31  0:11       ` Andrew Cagney
2004-01-31  0:16         ` Roland McGrath
2004-02-02 14:27           ` Andrew Cagney
2004-02-17 16:35         ` Andrew Cagney
2004-02-18  2:08           ` Roland McGrath
2004-02-24  3:50         ` Roland McGrath
2004-02-25  3:59           ` Andrew Cagney
2004-03-19  0:09             ` [COMMITTED PATCH] testsuite for info auxv Roland McGrath
2004-03-17 20:46               ` Roland McGrath
2004-02-25  4:03           ` [PATCH] auxv support Daniel Jacobowitz
2004-02-25 20:38             ` Roland McGrath
     [not found] <200401310013.i0V0DnGE018646@magilla.sf.frob.com>
2004-02-01  6:04 ` Daniel Jacobowitz
2004-02-01 22:36   ` Roland McGrath
2004-02-02  0:11   ` Roland McGrath
2004-02-02  6:24     ` Eli Zaretskii
2004-02-02 14:17   ` Andrew Cagney
2004-02-02 14:25   ` Andrew Cagney

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox