diff options
-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 } |