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 +#include + +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 #include #include - +#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 #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,