aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog7
-rw-r--r--gdb/auxv.c5
-rw-r--r--gdb/gdbarch.c32
-rw-r--r--gdb/gdbarch.h11
-rwxr-xr-xgdb/gdbarch.sh6
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.
diff --git a/gdb/auxv.c b/gdb/auxv.c
index ce0a71c..0f322e6 100644
--- a/gdb/auxv.c
+++ b/gdb/auxv.c
@@ -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 (&current_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
}