/* 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.
.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<gdbarch>::key<fbsd_gdbarch_data>
+ 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
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<fbsd_pspace_data>
+static const registry<program_space>::key<fbsd_pspace_data>
fbsd_pspace_data_handle;
static struct fbsd_pspace_data *
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;
}
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. */
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. */
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. */
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)
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;
}
if (saddr_un->sun_path[0] == 0)
saddr_un = reinterpret_cast<const struct fbsd_sockaddr_un *>
(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<const char *> (kf_path));
- printf_filtered ("\n");
+ gdb_printf ("%s", reinterpret_cast<const char *> (kf_path));
+ gdb_printf ("\n");
}
/* Implement "info proc files" for a corefile. */
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");
}
}
{
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<const char *> (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<const char *> (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<const char *> (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<const char *> (kve_path));
}
}
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. */
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
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);
}
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)
{
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"));
}
gdb::unique_xmalloc_ptr<char> 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"));
}
gdb::unique_xmalloc_ptr<char> 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"));
}
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);
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);
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 */
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. */
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));
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;
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"));
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;
}
}
+/* 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<unsigned char> 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<gdb::byte_vector> 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
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);
-}