aboutsummaryrefslogtreecommitdiff
path: root/gdb/linux-tdep.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2021-08-16 16:17:25 -0700
committerH.J. Lu <hjl.tools@gmail.com>2021-08-17 07:05:57 -0700
commitc0154a4a21a3aed01ef53877af05cf0109a0b124 (patch)
tree206fc433b66b3caa20711524ec3beff97a4c8eb3 /gdb/linux-tdep.c
parent4eb629d50d449a079d3f5e22f26f45855939164f (diff)
downloadgdb-c0154a4a21a3aed01ef53877af05cf0109a0b124.zip
gdb-c0154a4a21a3aed01ef53877af05cf0109a0b124.tar.gz
gdb-c0154a4a21a3aed01ef53877af05cf0109a0b124.tar.bz2
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
Diffstat (limited to 'gdb/linux-tdep.c')
-rw-r--r--gdb/linux-tdep.c60
1 files changed, 60 insertions, 0 deletions
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 <ctype.h>
@@ -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;
+}