From e9a743230e514ad897af42a545130e1025354a04 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 21 Jul 2022 15:59:06 -0700 Subject: [PATCH] fbsd-tdep: Add a custom AUXV parser. This returns the address of the entries that pass pointers rather than the first N bytes of the capability. --- gdb/fbsd-tdep.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/gdb/fbsd-tdep.c b/gdb/fbsd-tdep.c index 38337d6e9f0..26e1ea5c12b 100644 --- a/gdb/fbsd-tdep.c +++ b/gdb/fbsd-tdep.c @@ -1541,6 +1541,54 @@ fbsd_core_info_proc (struct gdbarch *gdbarch, const char *args, fbsd_core_info_proc_status (gdbarch); } +/* default_auxv_parse almost works, but we want to parse entries that + pass pointers and extract the address instead of returning just + the first N bytes as an address. */ + +static int +fbsd_auxv_parse (struct gdbarch *gdbarch, gdb_byte **readptr, + gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp) +{ + const int sizeof_auxv_field = gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT; + const int sizeof_long = gdbarch_long_bit (gdbarch) / TARGET_CHAR_BIT; + const enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + gdb_byte *ptr = *readptr; + + if (endptr == ptr) + return 0; + + if (endptr - ptr < sizeof_auxv_field * 2) + return -1; + + *typep = extract_unsigned_integer (ptr, sizeof_long, byte_order); + ptr += sizeof_auxv_field; + + switch (*typep) + { + case AT_PHDR: + case AT_BASE: + case AT_ENTRY: + case AT_FREEBSD_EXECPATH: + case AT_FREEBSD_CANARY: + case AT_FREEBSD_PAGESIZES: + case AT_FREEBSD_TIMEKEEP: + case AT_FREEBSD_ARGV: + case AT_FREEBSD_ENVV: + case AT_FREEBSD_PS_STRINGS: + case AT_FREEBSD_FXRNG: + case AT_FREEBSD_KPRELOAD: + *valp = extract_typed_address (ptr, + builtin_type (gdbarch)->builtin_data_ptr); + break; + default: + *valp = extract_unsigned_integer (ptr, sizeof_long, byte_order); + } + ptr += sizeof_auxv_field; + + *readptr = ptr; + return 1; +} + /* Print descriptions of FreeBSD-specific AUXV entries to FILE. */ static void @@ -2437,6 +2485,7 @@ fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_gdbarch_core_xfer_siginfo (gdbarch, fbsd_core_xfer_siginfo); set_gdbarch_make_corefile_notes (gdbarch, fbsd_make_corefile_notes); set_gdbarch_core_info_proc (gdbarch, fbsd_core_info_proc); + set_gdbarch_auxv_parse (gdbarch, fbsd_auxv_parse); set_gdbarch_print_auxv_entry (gdbarch, fbsd_print_auxv_entry); set_gdbarch_get_siginfo_type (gdbarch, fbsd_get_siginfo_type); set_gdbarch_gdb_signal_from_target (gdbarch, fbsd_gdb_signal_from_target); -- 2.47.2