diff options
author | Mark Kettenis <kettenis@gnu.org> | 2014-02-27 13:40:15 +0100 |
---|---|---|
committer | Mark Kettenis <kettenis@gnu.org> | 2014-02-27 13:40:15 +0100 |
commit | 27a48a9223d0c7558f0bfde2d704d4a660f5d4ea (patch) | |
tree | 8fbaa11502a79bb31e17ddd0aab09e980863397d | |
parent | 2e877f5ecb5916d147f91dfad461a8fa5017d8b0 (diff) | |
download | gdb-27a48a9223d0c7558f0bfde2d704d4a660f5d4ea.zip gdb-27a48a9223d0c7558f0bfde2d704d4a660f5d4ea.tar.gz gdb-27a48a9223d0c7558f0bfde2d704d4a660f5d4ea.tar.bz2 |
Add auxv parsing to the architecture vector.
Necessary to fix parsing auxv entries from core files on systems that use
the layout specified by ELF instead of the incompatible variant used by Linux.
gdb/Changelog:
* gdbarch.sh (auxv_parse): New.
* gdbarch.h: Regenerated.
* gdbarch.c: Regenerated.
* auxv.c (target_auxv_parse): Call gdbarch_parse_auxv if provided.
-rw-r--r-- | gdb/ChangeLog | 7 | ||||
-rw-r--r-- | gdb/auxv.c | 5 | ||||
-rw-r--r-- | gdb/gdbarch.c | 32 | ||||
-rw-r--r-- | gdb/gdbarch.h | 11 | ||||
-rwxr-xr-x | gdb/gdbarch.sh | 6 |
5 files changed, 61 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index e55f70f..9f347de 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2014-02-17 Mark Kettenis <kettenis@gnu.org> + + * gdbarch.sh (auxv_parse): New. + * gdbarch.h: Regenerated. + * gdbarch.c: Regenerated. + * auxv.c (target_auxv_parse): Call gdbarch_parse_auxv if provided. + 2014-02-26 Ludovic Courtès <ludo@gnu.org> * guile/scm-value.c (gdbscm_history_append_x): New function. @@ -287,6 +287,11 @@ 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(); + + if (gdbarch_auxv_parse_p (gdbarch)) + return gdbarch_auxv_parse (gdbarch, readptr, endptr, typep, valp); + return current_target.to_auxv_parse (¤t_target, readptr, endptr, typep, valp); } diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index ef67680..9ec5865 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -318,6 +318,7 @@ struct gdbarch gdbarch_insn_is_call_ftype *insn_is_call; gdbarch_insn_is_ret_ftype *insn_is_ret; gdbarch_insn_is_jump_ftype *insn_is_jump; + gdbarch_auxv_parse_ftype *auxv_parse; }; /* Create a new ``struct gdbarch'' based on information provided by @@ -628,6 +629,7 @@ verify_gdbarch (struct gdbarch *gdbarch) /* Skip verify of insn_is_call, invalid_p == 0 */ /* Skip verify of insn_is_ret, invalid_p == 0 */ /* Skip verify of insn_is_jump, invalid_p == 0 */ + /* Skip verify of auxv_parse, has predicate. */ buf = ui_file_xstrdup (log, &length); make_cleanup (xfree, buf); if (length > 0) @@ -691,6 +693,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) "gdbarch_dump: auto_wide_charset = <%s>\n", host_address_to_string (gdbarch->auto_wide_charset)); fprintf_unfiltered (file, + "gdbarch_dump: gdbarch_auxv_parse_p() = %d\n", + gdbarch_auxv_parse_p (gdbarch)); + fprintf_unfiltered (file, + "gdbarch_dump: auxv_parse = <%s>\n", + host_address_to_string (gdbarch->auxv_parse)); + fprintf_unfiltered (file, "gdbarch_dump: gdbarch_ax_pseudo_register_collect_p() = %d\n", gdbarch_ax_pseudo_register_collect_p (gdbarch)); fprintf_unfiltered (file, @@ -4374,6 +4382,30 @@ set_gdbarch_insn_is_jump (struct gdbarch *gdbarch, gdbarch->insn_is_jump = insn_is_jump; } +int +gdbarch_auxv_parse_p (struct gdbarch *gdbarch) +{ + gdb_assert (gdbarch != NULL); + return gdbarch->auxv_parse != NULL; +} + +int +gdbarch_auxv_parse (struct gdbarch *gdbarch, gdb_byte **readptr, gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->auxv_parse != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_auxv_parse called\n"); + return gdbarch->auxv_parse (gdbarch, readptr, endptr, typep, valp); +} + +void +set_gdbarch_auxv_parse (struct gdbarch *gdbarch, + gdbarch_auxv_parse_ftype auxv_parse) +{ + gdbarch->auxv_parse = auxv_parse; +} + /* Keep a registry of per-architecture data-pointers required by GDB modules. */ diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index c8fbc6e..9fb27d4 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -1305,6 +1305,17 @@ typedef int (gdbarch_insn_is_jump_ftype) (struct gdbarch *gdbarch, CORE_ADDR add extern int gdbarch_insn_is_jump (struct gdbarch *gdbarch, CORE_ADDR addr); extern void set_gdbarch_insn_is_jump (struct gdbarch *gdbarch, gdbarch_insn_is_jump_ftype *insn_is_jump); +/* 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 gdbarch_auxv_parse_p (struct gdbarch *gdbarch); + +typedef int (gdbarch_auxv_parse_ftype) (struct gdbarch *gdbarch, gdb_byte **readptr, gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp); +extern int gdbarch_auxv_parse (struct gdbarch *gdbarch, gdb_byte **readptr, gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp); +extern void set_gdbarch_auxv_parse (struct gdbarch *gdbarch, gdbarch_auxv_parse_ftype *auxv_parse); + /* Definition for an unknown syscall, used basically in error-cases. */ #define UNKNOWN_SYSCALL (-1) diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh index 76794b6..6a47f85 100755 --- a/gdb/gdbarch.sh +++ b/gdb/gdbarch.sh @@ -1023,6 +1023,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:auxv_parse:gdb_byte **readptr, gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp:readptr, endptr, typep, valp EOF } |