From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1936) id B40EC3858D39; Wed, 2 Mar 2022 22:03:39 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B40EC3858D39 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: John Baldwin To: gdb-cvs@sourceware.org Subject: [binutils-gdb] fbsd-tdep: Implement the vsyscall_range gdbarch hook. X-Act-Checkin: binutils-gdb X-Git-Author: John Baldwin X-Git-Refname: refs/heads/master X-Git-Oldrev: fb079cb5c419e03d400a0a139c3ccc4eedc33bef X-Git-Newrev: c1dae0a6a0ab03a778221a0f88048395d1d0796c Message-Id: <20220302220339.B40EC3858D39@sourceware.org> Date: Wed, 2 Mar 2022 22:03:39 +0000 (GMT) X-BeenThere: gdb-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 02 Mar 2022 22:03:39 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3Dc1dae0a6a0ab= 03a778221a0f88048395d1d0796c commit c1dae0a6a0ab03a778221a0f88048395d1d0796c Author: John Baldwin Date: Wed Mar 2 14:00:36 2022 -0800 fbsd-tdep: Implement the vsyscall_range gdbarch hook. =20 FreeBSD recently added a real vDSO in its shared page for the amd64 architecture. The vDSO is mapped at the address given by the AT_KPRELOAD ELF auxiliary vector entry. To find the end of the mapping range, parse the list of virtual map entries used by 'info proc mappings' either from the NT_PROCSTAT_VMMAP core dump note, or via the kinfo_getvmmap function for native targets (fetched from the native target as the TARGET_OBJECT_FREEBSD_VMMAP object). =20 This silences warnings on recent FreeBSD/amd64 kernels due to not finding symbols for the vdso: =20 warning: Could not load shared library symbols for [vdso]. Do you need "set solib-search-path" or "set sysroot"? Diff: --- gdb/fbsd-tdep.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 110 insertions(+) diff --git a/gdb/fbsd-tdep.c b/gdb/fbsd-tdep.c index 47c98ab9793..744fa6dad72 100644 --- a/gdb/fbsd-tdep.c +++ b/gdb/fbsd-tdep.c @@ -510,6 +510,13 @@ struct fbsd_pspace_data LONGEST off_linkmap =3D 0; LONGEST off_tlsindex =3D 0; bool rtld_offsets_valid =3D 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 =3D 0; }; =20 /* Per-program-space data for FreeBSD architectures. */ @@ -2261,6 +2268,108 @@ fbsd_report_signal_info (struct gdbarch *gdbarch, s= truct ui_out *uiout, } } =20 +/* 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 =3D gdbarch_byte_order (gdbarch); + unsigned char *descdata =3D entries; + unsigned char *descend =3D descdata + len; + + /* Skip over the structure size. */ + descdata +=3D 4; + + while (descdata + KVE_PATH < descend) + { + ULONGEST structsize =3D extract_unsigned_integer (descdata + + KVE_STRUCTSIZE, 4, + byte_order); + if (structsize < KVE_PATH) + return false; + + ULONGEST start =3D extract_unsigned_integer (descdata + KVE_START, 8, + byte_order); + ULONGEST end =3D extract_unsigned_integer (descdata + KVE_END, 8, + byte_order); + if (start =3D=3D addr) + return end - start; + + descdata +=3D 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) +{ + struct target_ops *ops =3D current_inferior ()->top_target (); + + if (target_auxv_search (ops, AT_FREEBSD_KPRELOAD, &range->start) <=3D 0) + return false; + + if (!target_has_execution ()) + { + /* Search for the ending address in the NT_PROCSTAT_VMMAP note. */ + asection *section =3D bfd_get_section_by_name (core_bfd, + ".note.freebsdcore.vmmap"); + if (section =3D=3D nullptr) + return false; + + size_t note_size =3D 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 =3D 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 =3D + target_read_alloc (ops, TARGET_OBJECT_FREEBSD_VMMAP, nullptr); + if (!buf || buf->empty ()) + return false; + + range->length =3D fbsd_vmmap_length (gdbarch, buf->data (), buf->siz= e (), + range->start); + } + return range->length !=3D 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 =3D get_fbsd_pspace_data (current_program_= space); + + if (data->vdso_range_p =3D=3D 0) + { + if (fbsd_vdso_range (gdbarch, &data->vdso_range)) + data->vdso_range_p =3D 1; + else + data->vdso_range_p =3D -1; + } + + if (data->vdso_range_p < 0) + return 0; + + *range =3D data->vdso_range; + return 1; +} + /* To be called from GDB_OSABI_FREEBSD handlers. */ =20 void @@ -2277,6 +2386,7 @@ fbsd_init_abi (struct gdbarch_info info, struct gdbar= ch *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); =20 /* `catch syscall' */ set_xml_syscall_file_name (gdbarch, "syscalls/freebsd.xml");