This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[wip] "info auxv"
- From: Andrew Cagney <ac131313 at redhat dot com>
- To: gdb-patches at sources dot redhat dot com
- Date: Mon, 10 Nov 2003 18:16:23 -0500
- Subject: [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 (¤t_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, ¤t_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,