]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
fbsd-tdep: Add a custom AUXV parser.
authorJohn Baldwin <jhb@FreeBSD.org>
Thu, 21 Jul 2022 22:59:06 +0000 (15:59 -0700)
committerJohn Baldwin <jhb@FreeBSD.org>
Thu, 1 Sep 2022 23:43:06 +0000 (16:43 -0700)
This returns the address of the entries that pass pointers rather
than the first N bytes of the capability.

gdb/fbsd-tdep.c

index 38337d6e9f0de290bc0d5f4c771d81be7f265884..26e1ea5c12b97635941cf2531385f5b3a91840a0 100644 (file)
@@ -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);