This is the mail archive of the gdb-patches@sourceware.org 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]

[PATCH/RFC] Parsing auxv entries


The diff below adds a gdbarch method to parse auxv entries.  The
parsing code currently lives in the target_ops vector, and this poses
a problem.  Because default_auxv_parse() implements parsing of the
non-standard auxv entries used by Linux (where the type is stored in a
'long' instead of an 'int'), it doesn't work on 64-bit big-endian
targets that do follow the SVR4 layout.  I've worked around this by
overriding to_auxv_parse in inf_ptrace_trace() for native BSD targets,
but that means the core_ops target is still broken.  And as we build
binaries as PIE by default on OpenBSD now, where auxv parsing is
essential to find out the load address of the executable, reading core
dumps on our 64-bit big-endian platforms is pretty much broken right
now.  And overriding to_auxv_parse for the core_ops target is painful.

I believe gdbarch is the right place for this functionality.  On many
platforms the memory layout of the entries is consistent across the
various sources.  But there may be some issues with running 32-bit
binaries on 64-bit systems in relation to things like /proc/*/auxv.  I
suppose to_auxv_parse was designed to solve such problems, although I
fail to see how the current implementation would work in the scenario
of running 32-bit binarie on a platform where /proc/*/auxv provides
the auxv entries in 64-bit format.

Thoughts?  OK?


2014-02-04  Mark Kettenis  <kettenis@gnu.org>
 
	* gdbarch.sh (parse_auxv): New.
	* gdbarch.h: Regenerated.
	* gdbarch.c: Regenerated.
	* auxv.c (target_auxv_parse): Call gdbarch_parse_auxv if provided.

diff --git a/gdb/auxv.c b/gdb/auxv.c
index dd13237..dcc6345 100644
--- a/gdb/auxv.c
+++ b/gdb/auxv.c
@@ -269,8 +269,12 @@ int
 target_auxv_parse (struct target_ops *ops, gdb_byte **readptr,
                   gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp)
 {
+  struct gdbarch *gdbarch = target_gdbarch();
   struct target_ops *t;
 
+  if (gdbarch_parse_auxv_p (gdbarch))
+    return gdbarch_parse_auxv (gdbarch, readptr, endptr, typep, valp);
+
   for (t = ops; t != NULL; t = t->beneath)
     if (t->to_auxv_parse != NULL)
       return t->to_auxv_parse (t, readptr, endptr, typep, valp);
diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
index 36dff57..88f481e 100755
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -1007,6 +1007,12 @@ m:int:insn_is_ret:CORE_ADDR addr:addr::default_insn_is_ret::0
 
 # Return non-zero if the instruction at ADDR is a jump; zero otherwise.
 m:int:insn_is_jump:CORE_ADDR addr:addr::default_insn_is_jump::0
+
+# 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.
+M:int:parse_auxv:gdb_byte **readptr, gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp:readptr, endptr, typep, valp
 EOF
 }
 


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