From c0154a4a21a3aed01ef53877af05cf0109a0b124 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Mon, 16 Aug 2021 16:17:25 -0700 Subject: gdb: Don't assume r_ldsomap when r_version > 1 on Linux The r_ldsomap field is specific to Solaris (part of librtld_db), and should never be accessed for Linux. glibc is planning to add a field to support multiple namespaces. But there will be no r_ldsomap when r_version is bumped to 2. Add linux_[ilp32|lp64]_fetch_link_map_offsets to set r_ldsomap_offset to -1 and use them for Linux targets. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28236 --- gdb/linux-tdep.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'gdb/linux-tdep.c') diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c index 637d3d3..ae2f7c1 100644 --- a/gdb/linux-tdep.c +++ b/gdb/linux-tdep.c @@ -41,6 +41,7 @@ #include "gdbsupport/gdb_optional.h" #include "gcore.h" #include "gcore-elf.h" +#include "solib-svr4.h" #include @@ -2724,3 +2725,62 @@ more information about this file, refer to the manpage of proc(5) and core(5).") NULL, show_dump_excluded_mappings, &setlist, &showlist); } + +/* Fetch (and possibly build) an appropriate `link_map_offsets' for + ILP32/LP64 Linux systems which don't have the r_ldsomap field. */ + +link_map_offsets * +linux_ilp32_fetch_link_map_offsets () +{ + static link_map_offsets lmo; + static link_map_offsets *lmp = nullptr; + + if (lmp == nullptr) + { + lmp = &lmo; + + lmo.r_version_offset = 0; + lmo.r_version_size = 4; + lmo.r_map_offset = 4; + lmo.r_brk_offset = 8; + lmo.r_ldsomap_offset = -1; + + /* Everything we need is in the first 20 bytes. */ + lmo.link_map_size = 20; + lmo.l_addr_offset = 0; + lmo.l_name_offset = 4; + lmo.l_ld_offset = 8; + lmo.l_next_offset = 12; + lmo.l_prev_offset = 16; + } + + return lmp; +} + +link_map_offsets * +linux_lp64_fetch_link_map_offsets () +{ + static link_map_offsets lmo; + static link_map_offsets *lmp = nullptr; + + if (lmp == nullptr) + { + lmp = &lmo; + + lmo.r_version_offset = 0; + lmo.r_version_size = 4; + lmo.r_map_offset = 8; + lmo.r_brk_offset = 16; + lmo.r_ldsomap_offset = -1; + + /* Everything we need is in the first 40 bytes. */ + lmo.link_map_size = 40; + lmo.l_addr_offset = 0; + lmo.l_name_offset = 8; + lmo.l_ld_offset = 16; + lmo.l_next_offset = 24; + lmo.l_prev_offset = 32; + } + + return lmp; +} -- cgit v1.1