X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Ffbsd-tdep.c;h=dc5020d92d20bd77c610c23796b934aba13dde02;hb=911e1e795e2496e1a5315601ab89e56afcd10fb0;hp=4da7798544b95a0c1d1739cd382b18e86adeba91;hpb=2a50938ab740296a1d6df67feea9401e57e4d90e;p=binutils-gdb.git diff --git a/gdb/fbsd-tdep.c b/gdb/fbsd-tdep.c index 4da7798544b..dc5020d92d2 100644 --- a/gdb/fbsd-tdep.c +++ b/gdb/fbsd-tdep.c @@ -1,6 +1,6 @@ /* Target-dependent code for FreeBSD, architecture-independent. - Copyright (C) 2002-2021 Free Software Foundation, Inc. + Copyright (C) 2002-2023 Free Software Foundation, Inc. This file is part of GDB. @@ -484,24 +484,21 @@ const struct kinfo_proc_layout kinfo_proc_layout_64 = .ru_majflt = 0x48, }; -static struct gdbarch_data *fbsd_gdbarch_data_handle; - struct fbsd_gdbarch_data { - struct type *siginfo_type; + struct type *siginfo_type = nullptr; }; -static void * -init_fbsd_gdbarch_data (struct gdbarch *gdbarch) -{ - return GDBARCH_OBSTACK_ZALLOC (gdbarch, struct fbsd_gdbarch_data); -} +static const registry::key + fbsd_gdbarch_data_handle; static struct fbsd_gdbarch_data * get_fbsd_gdbarch_data (struct gdbarch *gdbarch) { - return ((struct fbsd_gdbarch_data *) - gdbarch_data (gdbarch, fbsd_gdbarch_data_handle)); + struct fbsd_gdbarch_data *result = fbsd_gdbarch_data_handle.get (gdbarch); + if (result == nullptr) + result = fbsd_gdbarch_data_handle.emplace (gdbarch); + return result; } struct fbsd_pspace_data @@ -510,10 +507,17 @@ struct fbsd_pspace_data LONGEST off_linkmap = 0; LONGEST off_tlsindex = 0; bool rtld_offsets_valid = false; + + /* vDSO mapping range. */ + struct mem_range vdso_range {}; + + /* Zero if the range hasn't been searched for, > 0 if a range was + found, or < 0 if a range was not found. */ + int vdso_range_p = 0; }; /* Per-program-space data for FreeBSD architectures. */ -static const struct program_space_key +static const registry::key fbsd_pspace_data_handle; static struct fbsd_pspace_data * @@ -659,7 +663,7 @@ fbsd_make_note_desc (enum target_object object, uint32_t structsize) gdb::byte_vector desc (sizeof (structsize) + buf->size ()); memcpy (desc.data (), &structsize, sizeof (structsize)); - memcpy (desc.data () + sizeof (structsize), buf->data (), buf->size ()); + std::copy (buf->begin (), buf->end (), desc.data () + sizeof (structsize)); return desc; } @@ -914,8 +918,8 @@ fbsd_print_sockaddr_in (const void *sockaddr) if (inet_ntop (AF_INET, sin->sin_addr, buf, sizeof buf) == nullptr) error (_("Failed to format IPv4 address")); - printf_filtered ("%s:%u", buf, - (sin->sin_port[0] << 8) | sin->sin_port[1]); + gdb_printf ("%s:%u", buf, + (sin->sin_port[0] << 8) | sin->sin_port[1]); } /* Helper function to print out an IPv6 socket address. */ @@ -929,8 +933,8 @@ fbsd_print_sockaddr_in6 (const void *sockaddr) if (inet_ntop (AF_INET6, sin6->sin6_addr, buf, sizeof buf) == nullptr) error (_("Failed to format IPv6 address")); - printf_filtered ("%s.%u", buf, - (sin6->sin6_port[0] << 8) | sin6->sin6_port[1]); + gdb_printf ("%s.%u", buf, + (sin6->sin6_port[0] << 8) | sin6->sin6_port[1]); } /* See fbsd-tdep.h. */ @@ -938,9 +942,9 @@ fbsd_print_sockaddr_in6 (const void *sockaddr) void fbsd_info_proc_files_header () { - printf_filtered (_("Open files:\n\n")); - printf_filtered (" %6s %6s %10s %9s %s\n", - "FD", "Type", "Offset", "Flags ", "Name"); + gdb_printf (_("Open files:\n\n")); + gdb_printf (" %6s %6s %10s %9s %s\n", + "FD", "Type", "Offset", "Flags ", "Name"); } /* See fbsd-tdep.h. */ @@ -952,11 +956,11 @@ fbsd_info_proc_files_entry (int kf_type, int kf_fd, int kf_flags, int kf_sock_protocol, const void *kf_sa_local, const void *kf_sa_peer, const void *kf_path) { - printf_filtered (" %6s %6s %10s %8s ", - fbsd_file_fd (kf_fd), - fbsd_file_type (kf_type, kf_vnode_type), - kf_offset > -1 ? hex_string (kf_offset) : "-", - fbsd_file_flags (kf_flags)); + gdb_printf (" %6s %6s %10s %8s ", + fbsd_file_fd (kf_fd), + fbsd_file_type (kf_type, kf_vnode_type), + kf_offset > -1 ? hex_string (kf_offset) : "-", + fbsd_file_flags (kf_flags)); if (kf_type == KINFO_FILE_TYPE_SOCKET) { switch (kf_sock_domain) @@ -966,16 +970,16 @@ fbsd_info_proc_files_entry (int kf_type, int kf_fd, int kf_flags, switch (kf_sock_type) { case FBSD_SOCK_STREAM: - printf_filtered ("unix stream:"); + gdb_printf ("unix stream:"); break; case FBSD_SOCK_DGRAM: - printf_filtered ("unix dgram:"); + gdb_printf ("unix dgram:"); break; case FBSD_SOCK_SEQPACKET: - printf_filtered ("unix seqpacket:"); + gdb_printf ("unix seqpacket:"); break; default: - printf_filtered ("unix <%d>:", kf_sock_type); + gdb_printf ("unix <%d>:", kf_sock_type); break; } @@ -986,26 +990,26 @@ fbsd_info_proc_files_entry (int kf_type, int kf_fd, int kf_flags, if (saddr_un->sun_path[0] == 0) saddr_un = reinterpret_cast (kf_sa_peer); - printf_filtered ("%s", saddr_un->sun_path); + gdb_printf ("%s", saddr_un->sun_path); break; } case FBSD_AF_INET: - printf_filtered ("%s4 ", fbsd_ipproto (kf_sock_protocol)); + gdb_printf ("%s4 ", fbsd_ipproto (kf_sock_protocol)); fbsd_print_sockaddr_in (kf_sa_local); - printf_filtered (" -> "); + gdb_printf (" -> "); fbsd_print_sockaddr_in (kf_sa_peer); break; case FBSD_AF_INET6: - printf_filtered ("%s6 ", fbsd_ipproto (kf_sock_protocol)); + gdb_printf ("%s6 ", fbsd_ipproto (kf_sock_protocol)); fbsd_print_sockaddr_in6 (kf_sa_local); - printf_filtered (" -> "); + gdb_printf (" -> "); fbsd_print_sockaddr_in6 (kf_sa_peer); break; } } else - printf_filtered ("%s", reinterpret_cast (kf_path)); - printf_filtered ("\n"); + gdb_printf ("%s", reinterpret_cast (kf_path)); + gdb_printf ("\n"); } /* Implement "info proc files" for a corefile. */ @@ -1091,20 +1095,20 @@ fbsd_vm_map_entry_flags (int kve_flags, int kve_protection) void fbsd_info_proc_mappings_header (int addr_bit) { - printf_filtered (_("Mapped address spaces:\n\n")); + gdb_printf (_("Mapped address spaces:\n\n")); if (addr_bit == 64) { - printf_filtered (" %18s %18s %10s %10s %9s %s\n", - "Start Addr", - " End Addr", - " Size", " Offset", "Flags ", "File"); + gdb_printf (" %18s %18s %10s %10s %9s %s\n", + "Start Addr", + " End Addr", + " Size", " Offset", "Flags ", "File"); } else { - printf_filtered ("\t%10s %10s %10s %10s %9s %s\n", - "Start Addr", - " End Addr", - " Size", " Offset", "Flags ", "File"); + gdb_printf ("\t%10s %10s %10s %10s %9s %s\n", + "Start Addr", + " End Addr", + " Size", " Offset", "Flags ", "File"); } } @@ -1118,23 +1122,23 @@ fbsd_info_proc_mappings_entry (int addr_bit, ULONGEST kve_start, { if (addr_bit == 64) { - printf_filtered (" %18s %18s %10s %10s %9s %s\n", - hex_string (kve_start), - hex_string (kve_end), - hex_string (kve_end - kve_start), - hex_string (kve_offset), - fbsd_vm_map_entry_flags (kve_flags, kve_protection), - reinterpret_cast (kve_path)); + gdb_printf (" %18s %18s %10s %10s %9s %s\n", + hex_string (kve_start), + hex_string (kve_end), + hex_string (kve_end - kve_start), + hex_string (kve_offset), + fbsd_vm_map_entry_flags (kve_flags, kve_protection), + reinterpret_cast (kve_path)); } else { - printf_filtered ("\t%10s %10s %10s %10s %9s %s\n", - hex_string (kve_start), - hex_string (kve_end), - hex_string (kve_end - kve_start), - hex_string (kve_offset), - fbsd_vm_map_entry_flags (kve_flags, kve_protection), - reinterpret_cast (kve_path)); + gdb_printf ("\t%10s %10s %10s %10s %9s %s\n", + hex_string (kve_start), + hex_string (kve_end), + hex_string (kve_end - kve_start), + hex_string (kve_offset), + fbsd_vm_map_entry_flags (kve_flags, kve_protection), + reinterpret_cast (kve_path)); } } @@ -1265,11 +1269,11 @@ fbsd_core_fetch_timeval (struct gdbarch *gdbarch, unsigned char *data, static void fbsd_print_sigset (const char *descr, unsigned char *sigset) { - printf_filtered ("%s: ", descr); + gdb_printf ("%s: ", descr); for (int i = 0; i < SIG_WORDS; i++) - printf_filtered ("%08x ", - (unsigned int) bfd_get_32 (core_bfd, sigset + i * 4)); - printf_filtered ("\n"); + gdb_printf ("%08x ", + (unsigned int) bfd_get_32 (core_bfd, sigset + i * 4)); + gdb_printf ("\n"); } /* Implement "info proc status" for a corefile. */ @@ -1329,15 +1333,15 @@ fbsd_core_info_proc_status (struct gdbarch *gdbarch) return; } - printf_filtered ("Name: %.19s\n", descdata + kp->ki_comm); - printf_filtered ("Process ID: %s\n", - pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_pid))); - printf_filtered ("Parent process: %s\n", - pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_ppid))); - printf_filtered ("Process group: %s\n", - pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_pgid))); - printf_filtered ("Session id: %s\n", - pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_sid))); + gdb_printf ("Name: %.19s\n", descdata + kp->ki_comm); + gdb_printf ("Process ID: %s\n", + pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_pid))); + gdb_printf ("Parent process: %s\n", + pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_ppid))); + gdb_printf ("Process group: %s\n", + pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_pgid))); + gdb_printf ("Session id: %s\n", + pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_sid))); /* FreeBSD 12.0 and later store a 64-bit dev_t at 'ki_tdev'. Older kernels store a 32-bit dev_t at 'ki_tdev_freebsd11'. In older @@ -1348,76 +1352,76 @@ fbsd_core_info_proc_status (struct gdbarch *gdbarch) value = bfd_get_64 (core_bfd, descdata + kp->ki_tdev); if (value == 0) value = bfd_get_32 (core_bfd, descdata + kp->ki_tdev_freebsd11); - printf_filtered ("TTY: %s\n", pulongest (value)); - printf_filtered ("TTY owner process group: %s\n", - pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_tpgid))); - printf_filtered ("User IDs (real, effective, saved): %s %s %s\n", - pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_ruid)), - pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_uid)), - pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_svuid))); - printf_filtered ("Group IDs (real, effective, saved): %s %s %s\n", - pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_rgid)), - pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_groups)), - pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_svgid))); - printf_filtered ("Groups: "); + gdb_printf ("TTY: %s\n", pulongest (value)); + gdb_printf ("TTY owner process group: %s\n", + pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_tpgid))); + gdb_printf ("User IDs (real, effective, saved): %s %s %s\n", + pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_ruid)), + pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_uid)), + pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_svuid))); + gdb_printf ("Group IDs (real, effective, saved): %s %s %s\n", + pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_rgid)), + pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_groups)), + pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_svgid))); + gdb_printf ("Groups: "); uint16_t ngroups = bfd_get_16 (core_bfd, descdata + kp->ki_ngroups); for (int i = 0; i < ngroups; i++) - printf_filtered ("%s ", - pulongest (bfd_get_32 (core_bfd, - descdata + kp->ki_groups + i * 4))); - printf_filtered ("\n"); + gdb_printf ("%s ", + pulongest (bfd_get_32 (core_bfd, + descdata + kp->ki_groups + i * 4))); + gdb_printf ("\n"); value = bfd_get (long_bit, core_bfd, descdata + kp->ki_rusage + kp->ru_minflt); - printf_filtered ("Minor faults (no memory page): %s\n", pulongest (value)); + gdb_printf ("Minor faults (no memory page): %s\n", pulongest (value)); value = bfd_get (long_bit, core_bfd, descdata + kp->ki_rusage_ch + kp->ru_minflt); - printf_filtered ("Minor faults, children: %s\n", pulongest (value)); + gdb_printf ("Minor faults, children: %s\n", pulongest (value)); value = bfd_get (long_bit, core_bfd, descdata + kp->ki_rusage + kp->ru_majflt); - printf_filtered ("Major faults (memory page faults): %s\n", - pulongest (value)); + gdb_printf ("Major faults (memory page faults): %s\n", + pulongest (value)); value = bfd_get (long_bit, core_bfd, descdata + kp->ki_rusage_ch + kp->ru_majflt); - printf_filtered ("Major faults, children: %s\n", pulongest (value)); + gdb_printf ("Major faults, children: %s\n", pulongest (value)); fbsd_core_fetch_timeval (gdbarch, descdata + kp->ki_rusage + kp->ru_utime, sec, value); - printf_filtered ("utime: %s.%06d\n", plongest (sec), (int) value); + gdb_printf ("utime: %s.%06d\n", plongest (sec), (int) value); fbsd_core_fetch_timeval (gdbarch, descdata + kp->ki_rusage + kp->ru_stime, sec, value); - printf_filtered ("stime: %s.%06d\n", plongest (sec), (int) value); + gdb_printf ("stime: %s.%06d\n", plongest (sec), (int) value); fbsd_core_fetch_timeval (gdbarch, descdata + kp->ki_rusage_ch + kp->ru_utime, sec, value); - printf_filtered ("utime, children: %s.%06d\n", plongest (sec), (int) value); + gdb_printf ("utime, children: %s.%06d\n", plongest (sec), (int) value); fbsd_core_fetch_timeval (gdbarch, descdata + kp->ki_rusage_ch + kp->ru_stime, sec, value); - printf_filtered ("stime, children: %s.%06d\n", plongest (sec), (int) value); - printf_filtered ("'nice' value: %d\n", - (int) bfd_get_signed_8 (core_bfd, descdata + kp->ki_nice)); + gdb_printf ("stime, children: %s.%06d\n", plongest (sec), (int) value); + gdb_printf ("'nice' value: %d\n", + (int) bfd_get_signed_8 (core_bfd, descdata + kp->ki_nice)); fbsd_core_fetch_timeval (gdbarch, descdata + kp->ki_start, sec, value); - printf_filtered ("Start time: %s.%06d\n", plongest (sec), (int) value); - printf_filtered ("Virtual memory size: %s kB\n", - pulongest (bfd_get (addr_bit, core_bfd, - descdata + kp->ki_size) / 1024)); - printf_filtered ("Data size: %s pages\n", - pulongest (bfd_get (addr_bit, core_bfd, - descdata + kp->ki_dsize))); - printf_filtered ("Stack size: %s pages\n", - pulongest (bfd_get (addr_bit, core_bfd, - descdata + kp->ki_ssize))); - printf_filtered ("Text size: %s pages\n", - pulongest (bfd_get (addr_bit, core_bfd, - descdata + kp->ki_tsize))); - printf_filtered ("Resident set size: %s pages\n", - pulongest (bfd_get (addr_bit, core_bfd, - descdata + kp->ki_rssize))); - printf_filtered ("Maximum RSS: %s pages\n", - pulongest (bfd_get (long_bit, core_bfd, - descdata + kp->ki_rusage - + kp->ru_maxrss))); + gdb_printf ("Start time: %s.%06d\n", plongest (sec), (int) value); + gdb_printf ("Virtual memory size: %s kB\n", + pulongest (bfd_get (addr_bit, core_bfd, + descdata + kp->ki_size) / 1024)); + gdb_printf ("Data size: %s pages\n", + pulongest (bfd_get (addr_bit, core_bfd, + descdata + kp->ki_dsize))); + gdb_printf ("Stack size: %s pages\n", + pulongest (bfd_get (addr_bit, core_bfd, + descdata + kp->ki_ssize))); + gdb_printf ("Text size: %s pages\n", + pulongest (bfd_get (addr_bit, core_bfd, + descdata + kp->ki_tsize))); + gdb_printf ("Resident set size: %s pages\n", + pulongest (bfd_get (addr_bit, core_bfd, + descdata + kp->ki_rssize))); + gdb_printf ("Maximum RSS: %s pages\n", + pulongest (bfd_get (long_bit, core_bfd, + descdata + kp->ki_rusage + + kp->ru_maxrss))); fbsd_print_sigset ("Ignored Signals", descdata + kp->ki_sigignore); fbsd_print_sigset ("Caught Signals", descdata + kp->ki_sigcatch); } @@ -1476,7 +1480,7 @@ fbsd_core_info_proc (struct gdbarch *gdbarch, const char *args, pid = bfd_core_file_pid (core_bfd); if (pid != 0) - printf_filtered (_("process %d\n"), pid); + gdb_printf (_("process %d\n"), pid); if (do_cmdline) { @@ -1484,7 +1488,7 @@ fbsd_core_info_proc (struct gdbarch *gdbarch, const char *args, cmdline = bfd_core_file_failing_command (core_bfd); if (cmdline) - printf_filtered ("cmdline = '%s'\n", cmdline); + gdb_printf ("cmdline = '%s'\n", cmdline); else warning (_("Command line unavailable")); } @@ -1493,7 +1497,7 @@ fbsd_core_info_proc (struct gdbarch *gdbarch, const char *args, gdb::unique_xmalloc_ptr cwd = fbsd_core_vnode_path (gdbarch, KINFO_FILE_FD_TYPE_CWD); if (cwd) - printf_filtered ("cwd = '%s'\n", cwd.get ()); + gdb_printf ("cwd = '%s'\n", cwd.get ()); else warning (_("unable to read current working directory")); } @@ -1502,7 +1506,7 @@ fbsd_core_info_proc (struct gdbarch *gdbarch, const char *args, gdb::unique_xmalloc_ptr exe = fbsd_core_vnode_path (gdbarch, KINFO_FILE_FD_TYPE_TEXT); if (exe) - printf_filtered ("exe = '%s'\n", exe.get ()); + gdb_printf ("exe = '%s'\n", exe.get ()); else warning (_("unable to read executable path name")); } @@ -1565,6 +1569,10 @@ fbsd_print_auxv_entry (struct gdbarch *gdbarch, struct ui_file *file, TAG (ENVC, _("Environment count"), AUXV_FORMAT_DEC); TAG (ENVV, _("Environment vector"), AUXV_FORMAT_HEX); TAG (PS_STRINGS, _("Pointer to ps_strings"), AUXV_FORMAT_HEX); + TAG (FXRNG, _("Pointer to root RNG seed version"), AUXV_FORMAT_HEX); + TAG (KPRELOAD, _("Base address of vDSO"), AUXV_FORMAT_HEX); + TAG (USRSTACKBASE, _("Top of user stack"), AUXV_FORMAT_HEX); + TAG (USRSTACKLIM, _("Grow limit of user stack"), AUXV_FORMAT_HEX); } fprint_auxv_entry (file, name, description, format, type, val); @@ -1586,11 +1594,12 @@ fbsd_get_siginfo_type (struct gdbarch *gdbarch) if (fbsd_gdbarch_data->siginfo_type != NULL) return fbsd_gdbarch_data->siginfo_type; - int_type = arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch), + type_allocator alloc (gdbarch); + int_type = init_integer_type (alloc, gdbarch_int_bit (gdbarch), 0, "int"); - int32_type = arch_integer_type (gdbarch, 32, 0, "int32_t"); - uint32_type = arch_integer_type (gdbarch, 32, 1, "uint32_t"); - long_type = arch_integer_type (gdbarch, gdbarch_long_bit (gdbarch), + int32_type = init_integer_type (alloc, 32, 0, "int32_t"); + uint32_type = init_integer_type (alloc, 32, 1, "uint32_t"); + long_type = init_integer_type (alloc, gdbarch_long_bit (gdbarch), 0, "long"); void_ptr_type = lookup_pointer_type (builtin_type (gdbarch)->builtin_void); @@ -1601,16 +1610,17 @@ fbsd_get_siginfo_type (struct gdbarch *gdbarch) append_composite_type_field (sigval_type, "sival_ptr", void_ptr_type); /* __pid_t */ - pid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF, - TYPE_LENGTH (int32_type) * TARGET_CHAR_BIT, "__pid_t"); - TYPE_TARGET_TYPE (pid_type) = int32_type; + pid_type = alloc.new_type (TYPE_CODE_TYPEDEF, + int32_type->length () * TARGET_CHAR_BIT, + "__pid_t"); + pid_type->set_target_type (int32_type); pid_type->set_target_is_stub (true); /* __uid_t */ - uid_type = arch_type (gdbarch, TYPE_CODE_TYPEDEF, - TYPE_LENGTH (uint32_type) * TARGET_CHAR_BIT, - "__uid_t"); - TYPE_TARGET_TYPE (uid_type) = uint32_type; + uid_type = alloc.new_type (TYPE_CODE_TYPEDEF, + uint32_type->length () * TARGET_CHAR_BIT, + "__uid_t"); + uid_type->set_target_type (uint32_type); pid_type->set_target_is_stub (true); /* _reason */ @@ -1917,7 +1927,7 @@ fbsd_get_syscall_number (struct gdbarch *gdbarch, thread_info *thread) However, system call catching requires this function to be set. */ - internal_error (__FILE__, __LINE__, _("fbsd_get_sycall_number called")); + internal_error (_("fbsd_get_sycall_number called")); } /* Read an integer symbol value from the current target. */ @@ -1930,7 +1940,7 @@ fbsd_read_integer_by_name (struct gdbarch *gdbarch, const char *name) error (_("Unable to resolve symbol '%s'"), name); gdb_byte buf[4]; - if (target_read_memory (BMSYMBOL_VALUE_ADDRESS (ms), buf, sizeof buf) != 0) + if (target_read_memory (ms.value_address (), buf, sizeof buf) != 0) error (_("Unable to read value of '%s'"), name); return extract_signed_integer (buf, gdbarch_byte_order (gdbarch)); @@ -1950,9 +1960,9 @@ fbsd_fetch_rtld_offsets (struct gdbarch *gdbarch, struct fbsd_pspace_data *data) language_c, NULL).symbol; if (obj_entry_sym == NULL) error (_("Unable to find Struct_Obj_Entry symbol")); - data->off_linkmap = lookup_struct_elt (SYMBOL_TYPE (obj_entry_sym), + data->off_linkmap = lookup_struct_elt (obj_entry_sym->type (), "linkmap", 0).offset / 8; - data->off_tlsindex = lookup_struct_elt (SYMBOL_TYPE (obj_entry_sym), + data->off_tlsindex = lookup_struct_elt (obj_entry_sym->type (), "tlsindex", 0).offset / 8; data->rtld_offsets_valid = true; return; @@ -2024,7 +2034,7 @@ fbsd_get_thread_local_address (struct gdbarch *gdbarch, CORE_ADDR dtv_addr, CORE_ADDR addr = gdbarch_pointer_to_address (gdbarch, builtin->builtin_data_ptr, buf); - addr += (tls_index + 1) * TYPE_LENGTH (builtin->builtin_data_ptr); + addr += (tls_index + 1) * builtin->builtin_data_ptr->length (); if (target_read_memory (addr, buf, sizeof buf) != 0) throw_error (TLS_GENERIC_ERROR, _("Cannot find thread-local variables on this target")); @@ -2039,7 +2049,7 @@ CORE_ADDR fbsd_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc) { struct bound_minimal_symbol msym = lookup_bound_minimal_symbol ("_rtld_bind"); - if (msym.minsym != nullptr && BMSYMBOL_VALUE_ADDRESS (msym) == pc) + if (msym.minsym != nullptr && msym.value_address () == pc) return frame_unwind_caller_pc (get_current_frame ()); return 0; @@ -2259,6 +2269,107 @@ fbsd_report_signal_info (struct gdbarch *gdbarch, struct ui_out *uiout, } } +/* Search a list of struct kinfo_vmmap entries in the ENTRIES buffer + of LEN bytes to find the length of the entry starting at ADDR. + Returns the length of the entry or zero if no entry was found. */ + +static ULONGEST +fbsd_vmmap_length (struct gdbarch *gdbarch, unsigned char *entries, size_t len, + CORE_ADDR addr) +{ + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + unsigned char *descdata = entries; + unsigned char *descend = descdata + len; + + /* Skip over the structure size. */ + descdata += 4; + + while (descdata + KVE_PATH < descend) + { + ULONGEST structsize = extract_unsigned_integer (descdata + + KVE_STRUCTSIZE, 4, + byte_order); + if (structsize < KVE_PATH) + return false; + + ULONGEST start = extract_unsigned_integer (descdata + KVE_START, 8, + byte_order); + ULONGEST end = extract_unsigned_integer (descdata + KVE_END, 8, + byte_order); + if (start == addr) + return end - start; + + descdata += structsize; + } + return 0; +} + +/* Helper for fbsd_vsyscall_range that does the real work of finding + the vDSO's address range. */ + +static bool +fbsd_vdso_range (struct gdbarch *gdbarch, struct mem_range *range) +{ + if (target_auxv_search (AT_FREEBSD_KPRELOAD, &range->start) <= 0) + return false; + + if (!target_has_execution ()) + { + /* Search for the ending address in the NT_PROCSTAT_VMMAP note. */ + asection *section = bfd_get_section_by_name (core_bfd, + ".note.freebsdcore.vmmap"); + if (section == nullptr) + return false; + + size_t note_size = bfd_section_size (section); + if (note_size < 4) + return false; + + gdb::def_vector contents (note_size); + if (!bfd_get_section_contents (core_bfd, section, contents.data (), + 0, note_size)) + return false; + + range->length = fbsd_vmmap_length (gdbarch, contents.data (), note_size, + range->start); + } + else + { + /* Fetch the list of address space entries from the running target. */ + gdb::optional buf = + target_read_alloc (current_inferior ()->top_target (), + TARGET_OBJECT_FREEBSD_VMMAP, nullptr); + if (!buf || buf->empty ()) + return false; + + range->length = fbsd_vmmap_length (gdbarch, buf->data (), buf->size (), + range->start); + } + return range->length != 0; +} + +/* Return the address range of the vDSO for the current inferior. */ + +static int +fbsd_vsyscall_range (struct gdbarch *gdbarch, struct mem_range *range) +{ + struct fbsd_pspace_data *data = get_fbsd_pspace_data (current_program_space); + + if (data->vdso_range_p == 0) + { + if (fbsd_vdso_range (gdbarch, &data->vdso_range)) + data->vdso_range_p = 1; + else + data->vdso_range_p = -1; + } + + if (data->vdso_range_p < 0) + return 0; + + *range = data->vdso_range; + return 1; +} + /* To be called from GDB_OSABI_FREEBSD handlers. */ void @@ -2275,16 +2386,9 @@ fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_gdbarch_gdb_signal_to_target (gdbarch, fbsd_gdb_signal_to_target); set_gdbarch_report_signal_info (gdbarch, fbsd_report_signal_info); set_gdbarch_skip_solib_resolver (gdbarch, fbsd_skip_solib_resolver); + set_gdbarch_vsyscall_range (gdbarch, fbsd_vsyscall_range); /* `catch syscall' */ set_xml_syscall_file_name (gdbarch, "syscalls/freebsd.xml"); set_gdbarch_get_syscall_number (gdbarch, fbsd_get_syscall_number); } - -void _initialize_fbsd_tdep (); -void -_initialize_fbsd_tdep () -{ - fbsd_gdbarch_data_handle = - gdbarch_data_register_post_init (init_fbsd_gdbarch_data); -}