This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH 5/6] Add a new gdbarch method to print a single AUXV entry.
- From: John Baldwin <jhb at FreeBSD dot org>
- To: gdb-patches at sourceware dot org, binutils at sourceware dot org
- Date: Wed, 15 Jun 2016 23:02:01 -0700
- Subject: [PATCH 5/6] Add a new gdbarch method to print a single AUXV entry.
- Authentication-results: sourceware.org; auth=none
- References: <20160616060202 dot 63470-1-jhb at FreeBSD dot org>
Different platforms have different meanings for auxiliary vector
entries. The 'print_auxv' gdbarch method allows an architecture
to output a suitable description for platform-specific entries.
A fprint_single_auxv function is split out of fprint_target_auxv.
This function outputs the description of a single auxiliary vector
entry to the specified file using caller-supplied formatting and
strings to describe the vector type.
The existing switch on auxiliary vector types is moved out of
fprint_target_auxv into a new default_print_auxv function.
default_print_auxv chooses an appropriate format and description
and calls fprint_single_auxv to describe a single vector entry.
fprint_target_auxv now invokes the gdbarch 'print_auxv' function
on each vector entry. If the function is not present or returns
zero, default_printf_auxv is called to output a description for
the vector.
gdb/ChangeLog:
* auxv.c (fprint_single_auxv): New function.
(default_print_auxv): New function.
(fprint_target_auxv): Use gdbarch_print_auxv and default_print_auxv.
* auxv.h (enum auxv_format): New enum.
(fprint_single_auxv): Declare.
* gdbarch.sh (print_auxv): New.
* gdbarch.c, gdbarch.h: Re-generated.
---
gdb/ChangeLog | 10 +++
gdb/auxv.c | 191 +++++++++++++++++++++++++++++++--------------------------
gdb/auxv.h | 8 +++
gdb/gdbarch.c | 32 ++++++++++
gdb/gdbarch.h | 11 ++++
gdb/gdbarch.sh | 6 ++
6 files changed, 172 insertions(+), 86 deletions(-)
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index b11174c..2426a2f 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,15 @@
2016-06-15 John Baldwin <jhb@FreeBSD.org>
+ * auxv.c (fprint_single_auxv): New function.
+ (default_print_auxv): New function.
+ (fprint_target_auxv): Use gdbarch_print_auxv and default_print_auxv.
+ * auxv.h (enum auxv_format): New enum.
+ (fprint_single_auxv): Declare.
+ * gdbarch.sh (print_auxv): New.
+ * gdbarch.c, gdbarch.h: Re-generated.
+
+2016-06-15 John Baldwin <jhb@FreeBSD.org>
+
* fbsd-nat.c [KERN_PROC_AUXV] New variable super_xfer_partial.
(fbsd_xfer_partial): New function.
(fbsd_nat_add_target) [KERN_PROC_AUXV] Set "to_xfer_partial" to
diff --git a/gdb/auxv.c b/gdb/auxv.c
index 396862e..275c23e 100644
--- a/gdb/auxv.c
+++ b/gdb/auxv.c
@@ -407,10 +407,112 @@ target_auxv_search (struct target_ops *ops, CORE_ADDR match, CORE_ADDR *valp)
}
+/* Print a description of a single AUXV entry on the specified file. */
+void
+fprint_single_auxv (struct ui_file *file, const char *name,
+ const char *description, enum auxv_format flavor,
+ CORE_ADDR type, CORE_ADDR val)
+{
+ fprintf_filtered (file, "%-4s %-20s %-30s ",
+ plongest (type), name, description);
+ switch (flavor)
+ {
+ case dec:
+ fprintf_filtered (file, "%s\n", plongest (val));
+ break;
+ case hex:
+ fprintf_filtered (file, "%s\n", paddress (target_gdbarch (), val));
+ break;
+ case str:
+ {
+ struct value_print_options opts;
+
+ get_user_print_options (&opts);
+ if (opts.addressprint)
+ fprintf_filtered (file, "%s ", paddress (target_gdbarch (), val));
+ val_print_string (builtin_type (target_gdbarch ())->builtin_char,
+ NULL, val, -1, file, &opts);
+ fprintf_filtered (file, "\n");
+ }
+ break;
+ }
+}
+
+static void
+default_print_auxv (struct ui_file *file, CORE_ADDR type, CORE_ADDR val)
+{
+ const char *name = "???";
+ const char *description = "";
+ enum auxv_format flavor = hex;
+
+ switch (type)
+ {
+#define TAG(tag, text, kind) \
+ case tag: name = #tag; description = text; flavor = kind; break
+ TAG (AT_NULL, _("End of vector"), hex);
+ TAG (AT_IGNORE, _("Entry should be ignored"), hex);
+ TAG (AT_EXECFD, _("File descriptor of program"), dec);
+ TAG (AT_PHDR, _("Program headers for program"), hex);
+ TAG (AT_PHENT, _("Size of program header entry"), dec);
+ TAG (AT_PHNUM, _("Number of program headers"), dec);
+ TAG (AT_PAGESZ, _("System page size"), dec);
+ TAG (AT_BASE, _("Base address of interpreter"), hex);
+ TAG (AT_FLAGS, _("Flags"), hex);
+ TAG (AT_ENTRY, _("Entry point of program"), hex);
+ TAG (AT_NOTELF, _("Program is not ELF"), dec);
+ TAG (AT_UID, _("Real user ID"), dec);
+ TAG (AT_EUID, _("Effective user ID"), dec);
+ TAG (AT_GID, _("Real group ID"), dec);
+ TAG (AT_EGID, _("Effective group ID"), dec);
+ TAG (AT_CLKTCK, _("Frequency of times()"), dec);
+ TAG (AT_PLATFORM, _("String identifying platform"), str);
+ TAG (AT_HWCAP, _("Machine-dependent CPU capability hints"), hex);
+ TAG (AT_FPUCW, _("Used FPU control word"), dec);
+ TAG (AT_DCACHEBSIZE, _("Data cache block size"), dec);
+ TAG (AT_ICACHEBSIZE, _("Instruction cache block size"), dec);
+ TAG (AT_UCACHEBSIZE, _("Unified cache block size"), dec);
+ TAG (AT_IGNOREPPC, _("Entry should be ignored"), dec);
+ TAG (AT_BASE_PLATFORM, _("String identifying base platform"), str);
+ TAG (AT_RANDOM, _("Address of 16 random bytes"), hex);
+ TAG (AT_HWCAP2, _("Extension of AT_HWCAP"), hex);
+ TAG (AT_EXECFN, _("File name of executable"), str);
+ TAG (AT_SECURE, _("Boolean, was exec setuid-like?"), dec);
+ TAG (AT_SYSINFO, _("Special system info/entry points"), hex);
+ TAG (AT_SYSINFO_EHDR, _("System-supplied DSO's ELF header"), hex);
+ TAG (AT_L1I_CACHESHAPE, _("L1 Instruction cache information"), hex);
+ TAG (AT_L1D_CACHESHAPE, _("L1 Data cache information"), hex);
+ TAG (AT_L2_CACHESHAPE, _("L2 cache information"), hex);
+ TAG (AT_L3_CACHESHAPE, _("L3 cache information"), hex);
+ TAG (AT_SUN_UID, _("Effective user ID"), dec);
+ TAG (AT_SUN_RUID, _("Real user ID"), dec);
+ TAG (AT_SUN_GID, _("Effective group ID"), dec);
+ TAG (AT_SUN_RGID, _("Real group ID"), dec);
+ TAG (AT_SUN_LDELF, _("Dynamic linker's ELF header"), hex);
+ TAG (AT_SUN_LDSHDR, _("Dynamic linker's section headers"), hex);
+ TAG (AT_SUN_LDNAME, _("String giving name of dynamic linker"), str);
+ TAG (AT_SUN_LPAGESZ, _("Large pagesize"), dec);
+ TAG (AT_SUN_PLATFORM, _("Platform name string"), str);
+ TAG (AT_SUN_HWCAP, _("Machine-dependent CPU capability hints"), hex);
+ TAG (AT_SUN_IFLUSH, _("Should flush icache?"), dec);
+ TAG (AT_SUN_CPU, _("CPU name string"), str);
+ TAG (AT_SUN_EMUL_ENTRY, _("COFF entry point address"), hex);
+ TAG (AT_SUN_EMUL_EXECFD, _("COFF executable file descriptor"), dec);
+ TAG (AT_SUN_EXECNAME,
+ _("Canonicalized file name given to execve"), str);
+ TAG (AT_SUN_MMU, _("String for name of MMU module"), str);
+ TAG (AT_SUN_LDDATA, _("Dynamic linker's data segment address"), hex);
+ TAG (AT_SUN_AUXFLAGS,
+ _("AF_SUN_ flags passed from the kernel"), hex);
+ }
+
+ fprint_single_auxv (file, name, description, flavor, type, val);
+}
+
/* Print the contents of the target's AUXV on the specified file. */
int
fprint_target_auxv (struct ui_file *file, struct target_ops *ops)
{
+ struct gdbarch *gdbarch = target_gdbarch();
CORE_ADDR type, val;
gdb_byte *data;
gdb_byte *ptr;
@@ -426,93 +528,10 @@ fprint_target_auxv (struct ui_file *file, struct target_ops *ops)
while (target_auxv_parse (ops, &ptr, data + info->length, &type, &val) > 0)
{
- const char *name = "???";
- const char *description = "";
- enum { dec, hex, str } flavor = hex;
-
- switch (type)
- {
-#define TAG(tag, text, kind) \
- case tag: name = #tag; description = text; flavor = kind; break
- TAG (AT_NULL, _("End of vector"), hex);
- TAG (AT_IGNORE, _("Entry should be ignored"), hex);
- TAG (AT_EXECFD, _("File descriptor of program"), dec);
- TAG (AT_PHDR, _("Program headers for program"), hex);
- TAG (AT_PHENT, _("Size of program header entry"), dec);
- TAG (AT_PHNUM, _("Number of program headers"), dec);
- TAG (AT_PAGESZ, _("System page size"), dec);
- TAG (AT_BASE, _("Base address of interpreter"), hex);
- TAG (AT_FLAGS, _("Flags"), hex);
- TAG (AT_ENTRY, _("Entry point of program"), hex);
- TAG (AT_NOTELF, _("Program is not ELF"), dec);
- TAG (AT_UID, _("Real user ID"), dec);
- TAG (AT_EUID, _("Effective user ID"), dec);
- TAG (AT_GID, _("Real group ID"), dec);
- TAG (AT_EGID, _("Effective group ID"), dec);
- TAG (AT_CLKTCK, _("Frequency of times()"), dec);
- TAG (AT_PLATFORM, _("String identifying platform"), str);
- TAG (AT_HWCAP, _("Machine-dependent CPU capability hints"), hex);
- TAG (AT_FPUCW, _("Used FPU control word"), dec);
- TAG (AT_DCACHEBSIZE, _("Data cache block size"), dec);
- TAG (AT_ICACHEBSIZE, _("Instruction cache block size"), dec);
- TAG (AT_UCACHEBSIZE, _("Unified cache block size"), dec);
- TAG (AT_IGNOREPPC, _("Entry should be ignored"), dec);
- TAG (AT_BASE_PLATFORM, _("String identifying base platform"), str);
- TAG (AT_RANDOM, _("Address of 16 random bytes"), hex);
- TAG (AT_HWCAP2, _("Extension of AT_HWCAP"), hex);
- TAG (AT_EXECFN, _("File name of executable"), str);
- TAG (AT_SECURE, _("Boolean, was exec setuid-like?"), dec);
- TAG (AT_SYSINFO, _("Special system info/entry points"), hex);
- TAG (AT_SYSINFO_EHDR, _("System-supplied DSO's ELF header"), hex);
- TAG (AT_L1I_CACHESHAPE, _("L1 Instruction cache information"), hex);
- TAG (AT_L1D_CACHESHAPE, _("L1 Data cache information"), hex);
- TAG (AT_L2_CACHESHAPE, _("L2 cache information"), hex);
- TAG (AT_L3_CACHESHAPE, _("L3 cache information"), hex);
- TAG (AT_SUN_UID, _("Effective user ID"), dec);
- TAG (AT_SUN_RUID, _("Real user ID"), dec);
- TAG (AT_SUN_GID, _("Effective group ID"), dec);
- TAG (AT_SUN_RGID, _("Real group ID"), dec);
- TAG (AT_SUN_LDELF, _("Dynamic linker's ELF header"), hex);
- TAG (AT_SUN_LDSHDR, _("Dynamic linker's section headers"), hex);
- TAG (AT_SUN_LDNAME, _("String giving name of dynamic linker"), str);
- TAG (AT_SUN_LPAGESZ, _("Large pagesize"), dec);
- TAG (AT_SUN_PLATFORM, _("Platform name string"), str);
- TAG (AT_SUN_HWCAP, _("Machine-dependent CPU capability hints"), hex);
- TAG (AT_SUN_IFLUSH, _("Should flush icache?"), dec);
- TAG (AT_SUN_CPU, _("CPU name string"), str);
- TAG (AT_SUN_EMUL_ENTRY, _("COFF entry point address"), hex);
- TAG (AT_SUN_EMUL_EXECFD, _("COFF executable file descriptor"), dec);
- TAG (AT_SUN_EXECNAME,
- _("Canonicalized file name given to execve"), str);
- TAG (AT_SUN_MMU, _("String for name of MMU module"), str);
- TAG (AT_SUN_LDDATA, _("Dynamic linker's data segment address"), hex);
- TAG (AT_SUN_AUXFLAGS,
- _("AF_SUN_ flags passed from the kernel"), hex);
- }
+ if (!gdbarch_print_auxv_p (gdbarch)
+ || gdbarch_print_auxv (gdbarch, file, type, val) == 0)
+ default_print_auxv (file, type, val);
- fprintf_filtered (file, "%-4s %-20s %-30s ",
- plongest (type), name, description);
- switch (flavor)
- {
- case dec:
- fprintf_filtered (file, "%s\n", plongest (val));
- break;
- case hex:
- fprintf_filtered (file, "%s\n", paddress (target_gdbarch (), val));
- break;
- case str:
- {
- struct value_print_options opts;
-
- get_user_print_options (&opts);
- if (opts.addressprint)
- fprintf_filtered (file, "%s ", paddress (target_gdbarch (), val));
- val_print_string (builtin_type (target_gdbarch ())->builtin_char,
- NULL, val, -1, file, &opts);
- fprintf_filtered (file, "\n");
- }
- break;
- }
++ents;
if (type == AT_NULL)
break;
diff --git a/gdb/auxv.h b/gdb/auxv.h
index 9efe604..91d94f9 100644
--- a/gdb/auxv.h
+++ b/gdb/auxv.h
@@ -46,6 +46,14 @@ extern int target_auxv_parse (struct target_ops *ops,
extern int target_auxv_search (struct target_ops *ops,
CORE_ADDR match, CORE_ADDR *valp);
+/* Print a description of a single AUXV entry on the specified file. */
+enum auxv_format { dec, hex, str };
+
+extern void fprint_single_auxv (struct ui_file *file, const char *name,
+ const char *description,
+ enum auxv_format flavor, CORE_ADDR type,
+ CORE_ADDR val);
+
/* Print the contents of the target's AUXV on the specified file. */
extern int fprint_target_auxv (struct ui_file *file, struct target_ops *ops);
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index 313502b..15a4a98 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -328,6 +328,7 @@ struct gdbarch
gdbarch_insn_is_ret_ftype *insn_is_ret;
gdbarch_insn_is_jump_ftype *insn_is_jump;
gdbarch_auxv_parse_ftype *auxv_parse;
+ gdbarch_print_auxv_ftype *print_auxv;
gdbarch_vsyscall_range_ftype *vsyscall_range;
gdbarch_infcall_mmap_ftype *infcall_mmap;
gdbarch_infcall_munmap_ftype *infcall_munmap;
@@ -678,6 +679,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
/* 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. */
+ /* Skip verify of print_auxv, has predicate. */
/* Skip verify of vsyscall_range, invalid_p == 0 */
/* Skip verify of infcall_mmap, invalid_p == 0 */
/* Skip verify of infcall_munmap, invalid_p == 0 */
@@ -1167,6 +1169,12 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
"gdbarch_dump: pointer_to_address = <%s>\n",
host_address_to_string (gdbarch->pointer_to_address));
fprintf_unfiltered (file,
+ "gdbarch_dump: gdbarch_print_auxv_p() = %d\n",
+ gdbarch_print_auxv_p (gdbarch));
+ fprintf_unfiltered (file,
+ "gdbarch_dump: print_auxv = <%s>\n",
+ host_address_to_string (gdbarch->print_auxv));
+ fprintf_unfiltered (file,
"gdbarch_dump: print_float_info = <%s>\n",
host_address_to_string (gdbarch->print_float_info));
fprintf_unfiltered (file,
@@ -4770,6 +4778,30 @@ set_gdbarch_auxv_parse (struct gdbarch *gdbarch,
}
int
+gdbarch_print_auxv_p (struct gdbarch *gdbarch)
+{
+ gdb_assert (gdbarch != NULL);
+ return gdbarch->print_auxv != NULL;
+}
+
+int
+gdbarch_print_auxv (struct gdbarch *gdbarch, struct ui_file *file, CORE_ADDR type, CORE_ADDR val)
+{
+ gdb_assert (gdbarch != NULL);
+ gdb_assert (gdbarch->print_auxv != NULL);
+ if (gdbarch_debug >= 2)
+ fprintf_unfiltered (gdb_stdlog, "gdbarch_print_auxv called\n");
+ return gdbarch->print_auxv (gdbarch, file, type, val);
+}
+
+void
+set_gdbarch_print_auxv (struct gdbarch *gdbarch,
+ gdbarch_print_auxv_ftype print_auxv)
+{
+ gdbarch->print_auxv = print_auxv;
+}
+
+int
gdbarch_vsyscall_range (struct gdbarch *gdbarch, struct mem_range *range)
{
gdb_assert (gdbarch != NULL);
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index a6366fc..9cd1175 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -1464,6 +1464,17 @@ typedef int (gdbarch_auxv_parse_ftype) (struct gdbarch *gdbarch, gdb_byte **read
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);
+/* Print the description of a single auxv entry described by TYPE and VAL
+ to FILE. Return 0 and output no description if the TYPE is unknown.
+ Return 0 if the TYPE of the auxv entry is unknown.
+ Return 1 if a description was output. */
+
+extern int gdbarch_print_auxv_p (struct gdbarch *gdbarch);
+
+typedef int (gdbarch_print_auxv_ftype) (struct gdbarch *gdbarch, struct ui_file *file, CORE_ADDR type, CORE_ADDR val);
+extern int gdbarch_print_auxv (struct gdbarch *gdbarch, struct ui_file *file, CORE_ADDR type, CORE_ADDR val);
+extern void set_gdbarch_print_auxv (struct gdbarch *gdbarch, gdbarch_print_auxv_ftype *print_auxv);
+
/* Find the address range of the current inferior's vsyscall/vDSO, and
write it to *RANGE. If the vsyscall's length can't be determined, a
range with zero length is returned. Returns true if the vsyscall is
diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
index f170c10..1b4342f 100755
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -1110,6 +1110,12 @@ m:int:insn_is_jump:CORE_ADDR addr:addr::default_insn_is_jump::0
# 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
+# Print the description of a single auxv entry described by TYPE and VAL
+# to FILE. Return 0 and output no description if the TYPE is unknown.
+# Return 0 if the TYPE of the auxv entry is unknown.
+# Return 1 if a description was output.
+M:int:print_auxv:struct ui_file *file, CORE_ADDR type, CORE_ADDR val:file, type, val
+
# Find the address range of the current inferior's vsyscall/vDSO, and
# write it to *RANGE. If the vsyscall's length can't be determined, a
# range with zero length is returned. Returns true if the vsyscall is
--
2.8.4