This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[wip] "info auxv"


This work-in-progress is more questions than answers.

- Common code in "procfs.c" (tested) and "inftarg.c"
It makes me wonder if the native inferior code should be re-arranged (has this come up before?).


- The new files "auxv.[hc]" for parsing the file.
Perhaphs it belongs in "procfs.c" but that gets me back to the first question - could the native inferior code be better structured?


Andrew

(gdb) info auxv
2008 ???                            0xffbeff88
2014 ???                            0xffbeff96
3  Program headers for program    0x10034
4  Size of program header entry   0x20
5  Number of program headers      0x5
9  Entry point of program         0x10510
7  Base address of interpreter    0xff3c0000
8  Flags                          0x300
6  System page size               0x2000
2000 ???                            0x9f4
2001 ???                            0x9f4
2002 ???                            0x9f9
2003 ???                            0x9f9
2009 ???                            0x7
0  End of vector                  0x0
0  End of vector                  0x0
0  End of vector                  0x0
0  End of vector                  0x0
0  End of vector                  0x0
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.469
diff -u -r1.469 Makefile.in
--- Makefile.in	9 Nov 2003 17:28:07 -0000	1.469
+++ Makefile.in	10 Nov 2003 23:14:47 -0000
@@ -635,6 +635,7 @@
 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
@@ -874,6 +875,7 @@
 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 \
@@ -1599,6 +1601,7 @@
 	$(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)
 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) \
Index: auxv.c
===================================================================
RCS file: auxv.c
diff -N auxv.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ auxv.c	10 Nov 2003 23:14:47 -0000
@@ -0,0 +1,222 @@
+/* /proc auxilary vector support for GDB, the GNU debugger.
+
+   Copyright 2003 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 "elf/common.h"
+
+#include <unistd.h>
+#include <fcntl.h>
+
+struct gdb_auxv
+{
+  CORE_ADDR type;
+  CORE_ADDR val;
+};
+
+static int
+read_auxv_entry (struct target_ops *ops, unsigned nr,
+		 struct gdb_auxv *entry)
+{
+  const int sizeof_auxv_field = TYPE_LENGTH (builtin_type_void_data_ptr);
+  const int sizeof_auxv_entry = 2 * sizeof_auxv_field;
+  bfd_byte *auxp = alloca (sizeof_auxv_entry);
+  LONGEST status = target_read (ops, TARGET_OBJECT_AUXV, NULL, auxp,
+				nr * sizeof_auxv_entry, sizeof_auxv_entry);
+
+  if (status < 0)
+    return -1;
+  if (status < 2 * sizeof_auxv_field)
+    return 0;
+  
+  /* Extract the relevant values.  */
+  entry->type = extract_unsigned_integer (auxp + 0 * sizeof_auxv_field,
+					  sizeof_auxv_field);
+  entry->val = extract_unsigned_integer (auxp + 1 * sizeof_auxv_field,
+					 sizeof_auxv_field);
+
+  return 1;
+}
+
+/* Extract/return the auxilary vector value AT.  Return zero if the
+   value isn't available.  */
+
+CORE_ADDR
+target_auxv_read (struct target_ops *ops, int at)
+{
+  struct gdb_auxv auxv;
+  int ent;
+
+  for (ent = 0; read_auxv_entry (ops, ent, &auxv); ent++)
+    {
+      if (auxv.type == at)
+	return auxv.val;
+    }
+  return 0;
+}
+
+/* Print the contents of the target's AUXV on the specified file. */
+
+int
+fprint_target_auxv (struct ui_file *file, struct target_ops *ops)
+{
+  struct gdb_auxv auxv;
+  int ent;
+
+  for (ent = 0; read_auxv_entry (&current_target, ent, &auxv) > 0; ent++)
+    {
+      const char *name;
+      switch (auxv.type)
+	{
+	case AT_NULL:
+	  name = "End of vector";
+	  break;
+	case AT_IGNORE:
+	  name = "Entry should be ignored";
+	  break;
+	case AT_EXECFD:
+	  name = "File descriptor of program";
+	  break;
+	case AT_PHDR:
+	  name = "Program headers for program";
+	  break;
+	case AT_PHENT:
+	  name = "Size of program header entry";
+	  break;
+	case AT_PHNUM:
+	  name = "Number of program headers";
+	  break;
+	case AT_PAGESZ:
+	  name = "System page size";
+	  break;
+	case AT_BASE:
+	  name = "Base address of interpreter";
+	  break;
+	case AT_FLAGS:
+	  name = "Flags";
+	  break;
+	case AT_ENTRY:
+	  name = "Entry point of program";
+	  break;
+	case AT_NOTELF:
+	  name = "Program is not ELF";
+	  break;
+	case AT_UID:
+	  name = "Real uid";
+	  break;
+	case AT_EUID:
+	  name = "Effective uid";
+	  break;
+	case AT_GID:
+	  name = "Real gid";
+	  break;
+	case AT_EGID:
+	  name = "Effective gid";
+	  break;
+	case AT_CLKTCK:
+	  name = "Frequency of times()";
+	  break;
+	case AT_PLATFORM:
+	  name = "String identifying platform";
+	  break;
+	case AT_HWCAP:
+	  name = "Machine dependent hints about processor capabilities";
+	  break;
+	case AT_FPUCW:
+	  name = "Used FPU control word";
+	  break;
+	case AT_DCACHEBSIZE:
+	  name = "Data cache block size";
+	  break;
+	case AT_ICACHEBSIZE:
+	  name = "Instruction cache block size";
+	  break;
+	case AT_UCACHEBSIZE:
+	  name = "Unified cache block size";
+	  break;
+	case AT_IGNOREPPC:
+	  name = "Entry should be ignored";
+	  break;
+	case AT_SYSINFO:
+	  name = "";
+	  break;
+	case AT_SYSINFO_EHDR:
+	  name = "";
+	  break;
+	default:
+	  name = "???";
+	}
+      fprintf_filtered (file, "%-2s %-30s 0x%s\n", paddr_d (auxv.type),
+			name, paddr_nz (auxv.val));
+    }
+  return ent;
+}
+
+static void
+info_auxv_command (char *cmd, int from_tty)
+{
+  if (fprint_target_auxv (gdb_stdout, &current_target) == 0)
+    error ("No auxilary vector");
+}
+
+
+LONGEST
+native_xfer_auxv (int pid, void *readbuf, const void *writebuf,
+		  CORE_ADDR offset, LONGEST len)
+{
+  int fd = -1;
+  int nr = -1;
+
+  /* Try to open the thing.  */
+  {
+    char *auxv = xstrprintf ("/proc/%d/auxv", pid);
+    if (readbuf)
+      fd = open (auxv, O_RDONLY, 0);
+    if (writebuf)
+      fd = open (auxv, O_WRONLY, 0);
+    xfree (auxv);
+    if (fd < 0)
+      return -1;
+  }
+
+  /* Try to do an xfer, return the amount xfered.  */
+  errno = 0;
+  if (readbuf)
+    nr = pread (fd, readbuf, (long) len, (long) offset);
+  if (writebuf)
+    nr = pwrite (fd, writebuf, (long) len, (long) offset);
+  if (nr < 0 && errno == EOF)
+    nr = 0;
+  close (fd);
+  return nr;
+}
+
+extern initialize_file_ftype _initialize_remote_mips; /* -Wmissing-prototypes; */
+
+void
+_initialize_auxv (void)
+{
+  add_info ("auxv", info_auxv_command, "\
+All about the inferiors auxilary vector.");
+}
Index: auxv.h
===================================================================
RCS file: auxv.h
diff -N auxv.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ auxv.h	10 Nov 2003 23:14:47 -0000
@@ -0,0 +1,38 @@
+/* /proc auxilary vector support for GDB, the GNU debugger.
+
+   Copyright 2003 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.  */
+
+/* Extract/return the auxilary vector value AT.  Return zero if the
+   value isn't available.  */
+extern CORE_ADDR target_auxv_read (struct target_ops *ops, int at);
+
+/* Print the target's auxv to the specifed FILE.  */
+extern void fprint_target_auxv (struct ui_file *file, struct target_ops *ops);
+
+/* Use ptrace to xfer the auxv - for native targets.  */
+extern LONGEST native_xfer_auxv (int pid, void *readbuf, const void *writebuf,
+				 CORE_ADDR offset, LONGEST len);
+
+#endif
Index: inftarg.c
===================================================================
RCS file: /cvs/src/src/gdb/inftarg.c,v
retrieving revision 1.20
diff -u -r1.20 inftarg.c
--- inftarg.c	10 Nov 2003 21:20:44 -0000	1.20
+++ inftarg.c	10 Nov 2003 23:14:47 -0000
@@ -34,7 +34,7 @@
 #include <signal.h>
 #include <sys/types.h>
 #include <fcntl.h>
-
+#include "auxv.h"
 #include "gdb_wait.h"
 #include "inflow.h"
 
@@ -564,10 +564,10 @@
     {
     case TARGET_OBJECT_MEMORY:
       if (readbuf)
-	return child_xfer_memory (offset, readbuf, len, 0/*write*/,
+	return child_xfer_memory (offset, readbuf, len, 0/*!write*/,
 				  NULL, ops);
       if (writebuf)
-	return child_xfer_memory (offset, readbuf, len, 1/*write*/,
+	return child_xfer_memory (offset, (void *) writebuf, len, 1/*write*/,
 				  NULL, ops);
       return -1;
 
@@ -580,11 +580,9 @@
 				       offset, len);
 #endif
 
-#if 0
     case TARGET_OBJECT_AUXV:
       return native_xfer_auxv (PIDGET (inferior_ptid), readbuf, writebuf,
 			       offset, len);
-#endif
 
     default:
       return -1;
Index: procfs.c
===================================================================
RCS file: /cvs/src/src/gdb/procfs.c,v
retrieving revision 1.48
diff -u -r1.48 procfs.c
--- procfs.c	21 Sep 2003 01:26:45 -0000	1.48
+++ procfs.c	10 Nov 2003 23:14:48 -0000
@@ -47,6 +47,7 @@
 #include <ctype.h>
 #include "gdb_assert.h"
 #include "inflow.h"
+#include "auxv.h"
 
 /* 
  * PROCFS.C
@@ -127,7 +128,11 @@
 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);
 
 void procfs_find_new_threads (void);
@@ -165,6 +170,7 @@
   procfs_ops.to_fetch_registers     = procfs_fetch_registers;
   procfs_ops.to_store_registers     = procfs_store_registers;
   procfs_ops.to_xfer_memory         = procfs_xfer_memory;
+  procfs_ops.to_xfer_partial        = procfs_xfer_partial;
   procfs_ops.to_insert_breakpoint   =  memory_insert_breakpoint;
   procfs_ops.to_remove_breakpoint   =  memory_remove_breakpoint;
   procfs_ops.to_notice_signals      = procfs_notice_signals;
@@ -4317,6 +4323,44 @@
 	}
     }
   return nbytes;
+}
+
+/* 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 procfs_xfer_memory (offset, readbuf, len, 0/*write*/,
+				   NULL, ops);
+      if (writebuf)
+	return procfs_xfer_memory (offset, writebuf, len, 1/*write*/,
+				   NULL, ops);
+      return -1;
+
+#if 0
+    case TARGET_OBJECT_UNWIND_TABLE:
+#ifndef NATIVE_XFER_UNWIND_TABLE
+#define NATIVE_XFER_UNWIND_TABLE(OPS,OBJECT,ANNEX,WRITEBUF,READBUF,OFFSET,LEN) (-1)
+#endif
+      return NATIVE_XFER_UNWIND_TABLE (ops, object, annex, readbuf,
+				       writebuf, offset, len);
+#endif
+
+    case TARGET_OBJECT_AUXV:
+      return native_xfer_auxv (PIDGET (inferior_ptid), readbuf, writebuf,
+			       offset, len);
+
+    default:
+      return -1;
+    }
 }
 
 /*
Index: target.h
===================================================================
RCS file: /cvs/src/src/gdb/target.h,v
retrieving revision 1.53
diff -u -r1.53 target.h
--- target.h	10 Nov 2003 21:20:44 -0000	1.53
+++ target.h	10 Nov 2003 23:14:48 -0000
@@ -218,14 +218,19 @@
 
 enum target_object
 {
-  /* Kernel Object Display transfer.  See "kod.c" and "remote.c".  */
+  /* Target's Auxilary Vector (see svr4).  Call with a zero OFFSET /
+     LENGTH to obtain the total vector size.  */
+  TARGET_OBJECT_AUXV,
+  /* Kernel Object Display transfer.  See "kod.c" and "remote.c".
+     Call with a zero OFFSET / LENGTH to obtain the minimum required
+     size of the read buffer.  */
   TARGET_OBJECT_KOD,
   /* AVR target specific transfer.  See "avr-tdep.c" and "remote.c".  */
   TARGET_OBJECT_AVR,
   /* Transfer up-to LEN bytes of memory starting at OFFSET.  */
   TARGET_OBJECT_MEMORY
   /* Possible future ojbects: TARGET_OJBECT_FILE, TARGET_OBJECT_PROC,
-     TARGET_OBJECT_AUXV, ...  */
+     ...  */
 };
 
 extern LONGEST target_read_partial (struct target_ops *ops,

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]