summaryrefslogtreecommitdiff
path: root/devel/gdb/files/commit-2faa344
diff options
context:
space:
mode:
Diffstat (limited to 'devel/gdb/files/commit-2faa344')
-rw-r--r--devel/gdb/files/commit-2faa344397
1 files changed, 397 insertions, 0 deletions
diff --git a/devel/gdb/files/commit-2faa344 b/devel/gdb/files/commit-2faa344
new file mode 100644
index 000000000000..0d83a6a14813
--- /dev/null
+++ b/devel/gdb/files/commit-2faa344
@@ -0,0 +1,397 @@
+commit 2faa34476d9e6120eaf389b7f91b7227183fa2ce
+Author: John Baldwin <jhb@FreeBSD.org>
+Date: Sat Jun 11 15:51:38 2016 -0700
+
+ Add a new gdbarch method to print a single AUXV entry.
+
+ Different platforms have different meanings for auxiliary vector
+ entries. The 'print_auxv_entry' gdbarch method allows an architecture
+ to output a suitable description for platform-specific entries.
+
+ A fprint_auxv_entry 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_entry function.
+ default_print_auxv_entry chooses an appropriate format and description
+ and calls fprint_single_auxv to describe a single vector entry.
+ This function is used as the default 'print_auxv_entry' gdbarch method.
+
+ fprint_target_auxv now invokes the gdbarch 'print_auxv_entry' method
+ on each vector entry.
+
+ gdb/ChangeLog:
+
+ * auxv.c (fprint_auxv_entry): New function.
+ (default_print_auxv_entry): New function.
+ (fprint_target_auxv): Use gdbarch_print_auxv_entry.
+ * auxv.h (enum auxv_format): New enum.
+ (fprint_auxv_entry): Declare.
+ (default_print_auxv_entry): Declare.
+ * gdbarch.sh (print_auxv_entry): New.
+ * gdbarch.c, gdbarch.h: Re-generated.
+
+diff --git gdb/auxv.c gdb/auxv.c
+index 396862e..de9205d 100644
+--- gdb/auxv.c
++++ gdb/auxv.c
+@@ -407,10 +407,126 @@ target_auxv_search (struct target_ops *ops, CORE_ADDR match, CORE_ADDR *valp)
+ }
+
+
++/* Print the description of a single AUXV entry on the specified file. */
++
++void
++fprint_auxv_entry (struct ui_file *file, const char *name,
++ const char *description, enum auxv_format format,
++ CORE_ADDR type, CORE_ADDR val)
++{
++ fprintf_filtered (file, ("%-4s %-20s %-30s "),
++ plongest (type), name, description);
++ switch (format)
++ {
++ case AUXV_FORMAT_DEC:
++ fprintf_filtered (file, ("%s\n"), plongest (val));
++ break;
++ case AUXV_FORMAT_HEX:
++ fprintf_filtered (file, ("%s\n"), paddress (target_gdbarch (), val));
++ break;
++ case AUXV_FORMAT_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;
++ }
++}
++
++/* The default implementation of gdbarch_print_auxv_entry. */
++
++void
++default_print_auxv_entry (struct gdbarch *gdbarch, struct ui_file *file,
++ CORE_ADDR type, CORE_ADDR val)
++{
++ const char *name = "???";
++ const char *description = "";
++ enum auxv_format format = AUXV_FORMAT_HEX;
++
++ switch (type)
++ {
++#define TAG(tag, text, kind) \
++ case tag: name = #tag; description = text; format = kind; break
++ TAG (AT_NULL, _("End of vector"), AUXV_FORMAT_HEX);
++ TAG (AT_IGNORE, _("Entry should be ignored"), AUXV_FORMAT_HEX);
++ TAG (AT_EXECFD, _("File descriptor of program"), AUXV_FORMAT_DEC);
++ TAG (AT_PHDR, _("Program headers for program"), AUXV_FORMAT_HEX);
++ TAG (AT_PHENT, _("Size of program header entry"), AUXV_FORMAT_DEC);
++ TAG (AT_PHNUM, _("Number of program headers"), AUXV_FORMAT_DEC);
++ TAG (AT_PAGESZ, _("System page size"), AUXV_FORMAT_DEC);
++ TAG (AT_BASE, _("Base address of interpreter"), AUXV_FORMAT_HEX);
++ TAG (AT_FLAGS, _("Flags"), AUXV_FORMAT_HEX);
++ TAG (AT_ENTRY, _("Entry point of program"), AUXV_FORMAT_HEX);
++ TAG (AT_NOTELF, _("Program is not ELF"), AUXV_FORMAT_DEC);
++ TAG (AT_UID, _("Real user ID"), AUXV_FORMAT_DEC);
++ TAG (AT_EUID, _("Effective user ID"), AUXV_FORMAT_DEC);
++ TAG (AT_GID, _("Real group ID"), AUXV_FORMAT_DEC);
++ TAG (AT_EGID, _("Effective group ID"), AUXV_FORMAT_DEC);
++ TAG (AT_CLKTCK, _("Frequency of times()"), AUXV_FORMAT_DEC);
++ TAG (AT_PLATFORM, _("String identifying platform"), AUXV_FORMAT_STR);
++ TAG (AT_HWCAP, _("Machine-dependent CPU capability hints"),
++ AUXV_FORMAT_HEX);
++ TAG (AT_FPUCW, _("Used FPU control word"), AUXV_FORMAT_DEC);
++ TAG (AT_DCACHEBSIZE, _("Data cache block size"), AUXV_FORMAT_DEC);
++ TAG (AT_ICACHEBSIZE, _("Instruction cache block size"), AUXV_FORMAT_DEC);
++ TAG (AT_UCACHEBSIZE, _("Unified cache block size"), AUXV_FORMAT_DEC);
++ TAG (AT_IGNOREPPC, _("Entry should be ignored"), AUXV_FORMAT_DEC);
++ TAG (AT_BASE_PLATFORM, _("String identifying base platform"),
++ AUXV_FORMAT_STR);
++ TAG (AT_RANDOM, _("Address of 16 random bytes"), AUXV_FORMAT_HEX);
++ TAG (AT_HWCAP2, _("Extension of AT_HWCAP"), AUXV_FORMAT_HEX);
++ TAG (AT_EXECFN, _("File name of executable"), AUXV_FORMAT_STR);
++ TAG (AT_SECURE, _("Boolean, was exec setuid-like?"), AUXV_FORMAT_DEC);
++ TAG (AT_SYSINFO, _("Special system info/entry points"), AUXV_FORMAT_HEX);
++ TAG (AT_SYSINFO_EHDR, _("System-supplied DSO's ELF header"),
++ AUXV_FORMAT_HEX);
++ TAG (AT_L1I_CACHESHAPE, _("L1 Instruction cache information"),
++ AUXV_FORMAT_HEX);
++ TAG (AT_L1D_CACHESHAPE, _("L1 Data cache information"), AUXV_FORMAT_HEX);
++ TAG (AT_L2_CACHESHAPE, _("L2 cache information"), AUXV_FORMAT_HEX);
++ TAG (AT_L3_CACHESHAPE, _("L3 cache information"), AUXV_FORMAT_HEX);
++ TAG (AT_SUN_UID, _("Effective user ID"), AUXV_FORMAT_DEC);
++ TAG (AT_SUN_RUID, _("Real user ID"), AUXV_FORMAT_DEC);
++ TAG (AT_SUN_GID, _("Effective group ID"), AUXV_FORMAT_DEC);
++ TAG (AT_SUN_RGID, _("Real group ID"), AUXV_FORMAT_DEC);
++ TAG (AT_SUN_LDELF, _("Dynamic linker's ELF header"), AUXV_FORMAT_HEX);
++ TAG (AT_SUN_LDSHDR, _("Dynamic linker's section headers"),
++ AUXV_FORMAT_HEX);
++ TAG (AT_SUN_LDNAME, _("String giving name of dynamic linker"),
++ AUXV_FORMAT_STR);
++ TAG (AT_SUN_LPAGESZ, _("Large pagesize"), AUXV_FORMAT_DEC);
++ TAG (AT_SUN_PLATFORM, _("Platform name string"), AUXV_FORMAT_STR);
++ TAG (AT_SUN_HWCAP, _("Machine-dependent CPU capability hints"),
++ AUXV_FORMAT_HEX);
++ TAG (AT_SUN_IFLUSH, _("Should flush icache?"), AUXV_FORMAT_DEC);
++ TAG (AT_SUN_CPU, _("CPU name string"), AUXV_FORMAT_STR);
++ TAG (AT_SUN_EMUL_ENTRY, _("COFF entry point address"), AUXV_FORMAT_HEX);
++ TAG (AT_SUN_EMUL_EXECFD, _("COFF executable file descriptor"),
++ AUXV_FORMAT_DEC);
++ TAG (AT_SUN_EXECNAME,
++ _("Canonicalized file name given to execve"), AUXV_FORMAT_STR);
++ TAG (AT_SUN_MMU, _("String for name of MMU module"), AUXV_FORMAT_STR);
++ TAG (AT_SUN_LDDATA, _("Dynamic linker's data segment address"),
++ AUXV_FORMAT_HEX);
++ TAG (AT_SUN_AUXFLAGS,
++ _("AF_SUN_ flags passed from the kernel"), AUXV_FORMAT_HEX);
++ }
++
++ fprint_auxv_entry (file, name, description, format, 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 +542,7 @@ 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);
+- }
+-
+- 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;
+- }
++ gdbarch_print_auxv_entry (gdbarch, file, type, val);
+ ++ents;
+ if (type == AT_NULL)
+ break;
+diff --git gdb/auxv.h gdb/auxv.h
+index 9efe604..916f674 100644
+--- gdb/auxv.h
++++ gdb/auxv.h
+@@ -46,6 +46,20 @@ 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 { AUXV_FORMAT_DEC, AUXV_FORMAT_HEX, AUXV_FORMAT_STR };
++
++extern void fprint_auxv_entry (struct ui_file *file, const char *name,
++ const char *description,
++ enum auxv_format format, CORE_ADDR type,
++ CORE_ADDR val);
++
++/* The default implementation of gdbarch_print_auxv_entry. */
++
++extern void default_print_auxv_entry (struct gdbarch *gdbarch,
++ struct ui_file *file, 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 gdb/gdbarch.c gdb/gdbarch.c
+index 313502b..af7359e 100644
+--- gdb/gdbarch.c
++++ gdb/gdbarch.c
+@@ -47,6 +47,7 @@
+ #include "observer.h"
+ #include "regcache.h"
+ #include "objfiles.h"
++#include "auxv.h"
+
+ /* Static function declarations */
+
+@@ -328,6 +329,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_entry_ftype *print_auxv_entry;
+ gdbarch_vsyscall_range_ftype *vsyscall_range;
+ gdbarch_infcall_mmap_ftype *infcall_mmap;
+ gdbarch_infcall_munmap_ftype *infcall_munmap;
+@@ -432,6 +434,7 @@ gdbarch_alloc (const struct gdbarch_info *info,
+ gdbarch->insn_is_call = default_insn_is_call;
+ gdbarch->insn_is_ret = default_insn_is_ret;
+ gdbarch->insn_is_jump = default_insn_is_jump;
++ gdbarch->print_auxv_entry = default_print_auxv_entry;
+ gdbarch->vsyscall_range = default_vsyscall_range;
+ gdbarch->infcall_mmap = default_infcall_mmap;
+ gdbarch->infcall_munmap = default_infcall_munmap;
+@@ -678,6 +681,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_entry, invalid_p == 0 */
+ /* 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 +1171,9 @@ 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: print_auxv_entry = <%s>\n",
++ host_address_to_string (gdbarch->print_auxv_entry));
++ fprintf_unfiltered (file,
+ "gdbarch_dump: print_float_info = <%s>\n",
+ host_address_to_string (gdbarch->print_float_info));
+ fprintf_unfiltered (file,
+@@ -4769,6 +4776,23 @@ set_gdbarch_auxv_parse (struct gdbarch *gdbarch,
+ gdbarch->auxv_parse = auxv_parse;
+ }
+
++void
++gdbarch_print_auxv_entry (struct gdbarch *gdbarch, struct ui_file *file, CORE_ADDR type, CORE_ADDR val)
++{
++ gdb_assert (gdbarch != NULL);
++ gdb_assert (gdbarch->print_auxv_entry != NULL);
++ if (gdbarch_debug >= 2)
++ fprintf_unfiltered (gdb_stdlog, "gdbarch_print_auxv_entry called\n");
++ gdbarch->print_auxv_entry (gdbarch, file, type, val);
++}
++
++void
++set_gdbarch_print_auxv_entry (struct gdbarch *gdbarch,
++ gdbarch_print_auxv_entry_ftype print_auxv_entry)
++{
++ gdbarch->print_auxv_entry = print_auxv_entry;
++}
++
+ int
+ gdbarch_vsyscall_range (struct gdbarch *gdbarch, struct mem_range *range)
+ {
+diff --git gdb/gdbarch.h gdb/gdbarch.h
+index a6366fc..bc0f692 100644
+--- gdb/gdbarch.h
++++ gdb/gdbarch.h
+@@ -1464,6 +1464,13 @@ 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. */
++
++typedef void (gdbarch_print_auxv_entry_ftype) (struct gdbarch *gdbarch, struct ui_file *file, CORE_ADDR type, CORE_ADDR val);
++extern void gdbarch_print_auxv_entry (struct gdbarch *gdbarch, struct ui_file *file, CORE_ADDR type, CORE_ADDR val);
++extern void set_gdbarch_print_auxv_entry (struct gdbarch *gdbarch, gdbarch_print_auxv_entry_ftype *print_auxv_entry);
++
+ /* 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 gdb/gdbarch.sh gdb/gdbarch.sh
+index f170c10..d8e0eeb 100755
+--- gdb/gdbarch.sh
++++ gdb/gdbarch.sh
+@@ -1110,6 +1110,10 @@ 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.
++m:void:print_auxv_entry:struct ui_file *file, CORE_ADDR type, CORE_ADDR val:file, type, val::default_print_auxv_entry::0
++
+ # 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
+@@ -1616,6 +1620,7 @@ cat <<EOF
+ #include "observer.h"
+ #include "regcache.h"
+ #include "objfiles.h"
++#include "auxv.h"
+
+ /* Static function declarations */
+