Add auxv parsing to the architecture vector.
authorMark Kettenis <kettenis@gnu.org>
Thu, 27 Feb 2014 12:40:15 +0000 (13:40 +0100)
committerMark Kettenis <kettenis@gnu.org>
Thu, 27 Feb 2014 12:40:15 +0000 (13:40 +0100)
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.

gdb/ChangeLog
gdb/auxv.c
gdb/gdbarch.c
gdb/gdbarch.h
gdb/gdbarch.sh

index e55f70fefc4f8e230500d11a595d3c134b5656f3..9f347de99b605db5726c448809bf11bb57c94699 100644 (file)
@@ -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.
index ce0a71c77a99deb5cae22f5543388aabcc020e8e..0f322e6d76e6849caec1f1a81d9c7113e6782c16 100644 (file)
@@ -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);
 }
index ef67680f816b27f69155ca4f967f823d76d69612..9ec586597a059a687e50eb983528658780062e49 100644 (file)
@@ -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)
@@ -690,6 +692,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
   fprintf_unfiltered (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));
@@ -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.  */
index c8fbc6e16aa2886ac7c6613609feeafa1becffb5..9fb27d4412502c9bb66ff934355a324151cf6628 100644 (file)
@@ -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)
 
index 76794b62a5349c74e15e28ae15fde03b3d47e73a..6a47f85331c67f840fbee6fe5610c5564397ed70 100755 (executable)
@@ -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
 }