gdb: Don't assume r_ldsomap when r_version > 1 on Linux

Message ID 20210816233615.592492-1-hjl.tools@gmail.com
State New
Headers show
Series
  • gdb: Don't assume r_ldsomap when r_version > 1 on Linux
Related show

Commit Message

Alan Modra via Binutils Aug. 16, 2021, 11:36 p.m.
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.

	PR gdb/28236
	* aarch64-linux-tdep.c (aarch64_linux_init_abi): Replace
	svr4_[ilp32|lp64]_fetch_link_map_offsets with
	linux_[ilp32|lp64]_fetch_link_map_offsets.
	* alpha-linux-tdep.c (alpha_linux_init_abi): Likewise.
	* amd64-linux-tdep.c (amd64_linux_init_abi): Likewise.
	(amd64_x32_linux_init_abi): Likewise.
	* ia64-linux-tdep.c (ia64_linux_init_abi): Likewise.
	* mips-linux-tdep.c (mips_linux_init_abi): Likewise.
	* ppc-linux-tdep.c (ppc_linux_init_abi): Likewise.
	* riscv-linux-tdep.c (riscv_linux_init_abi): Likewise.
	* s390-linux-tdep.c (s390_linux_init_abi_31): Likewise.
	(s390_linux_init_abi_64): Likewise.
	* sparc64-linux-tdep.c (sparc64_linux_init_abi): Likewise.
	* tilegx-linux-tdep.c (tilegx_linux_init_abi): Likewise.
	* linux-tdep.c: Include "solib-svr4.h".
	(linux_ilp32_fetch_link_map_offsets): New.
	(linux_lp64_fetch_link_map_offsets): Likewise.
	* linux-tdep.h (linux_ilp32_fetch_link_map_offsets): New.
	(linux_lp64_fetch_link_map_offsets): Likewise.
---
 gdb/aarch64-linux-tdep.c |  2 +-
 gdb/alpha-linux-tdep.c   |  2 +-
 gdb/amd64-linux-tdep.c   |  4 +--
 gdb/ia64-linux-tdep.c    |  2 +-
 gdb/linux-tdep.c         | 60 ++++++++++++++++++++++++++++++++++++++++
 gdb/linux-tdep.h         |  5 ++++
 gdb/mips-linux-tdep.c    |  6 ++--
 gdb/ppc-linux-tdep.c     |  4 +--
 gdb/riscv-linux-tdep.c   |  4 +--
 gdb/s390-linux-tdep.c    |  4 +--
 gdb/sparc64-linux-tdep.c |  2 +-
 gdb/tilegx-linux-tdep.c  |  4 +--
 12 files changed, 82 insertions(+), 17 deletions(-)

-- 
2.31.1

Patch

diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c
index 63c200b47f7..b1225438d9d 100644
--- a/gdb/aarch64-linux-tdep.c
+++ b/gdb/aarch64-linux-tdep.c
@@ -1795,7 +1795,7 @@  aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   linux_init_abi (info, gdbarch, 1);
 
   set_solib_svr4_fetch_link_map_offsets (gdbarch,
-					 svr4_lp64_fetch_link_map_offsets);
+					 linux_lp64_fetch_link_map_offsets);
 
   /* Enable TLS support.  */
   set_gdbarch_fetch_tls_load_module_address (gdbarch,
diff --git a/gdb/alpha-linux-tdep.c b/gdb/alpha-linux-tdep.c
index c2cffc13c20..0a00fc1f310 100644
--- a/gdb/alpha-linux-tdep.c
+++ b/gdb/alpha-linux-tdep.c
@@ -374,7 +374,7 @@  alpha_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
 
   set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, svr4_lp64_fetch_link_map_offsets);
+    (gdbarch, linux_lp64_fetch_link_map_offsets);
 
   /* Enable TLS support.  */
   set_gdbarch_fetch_tls_load_module_address (gdbarch,
diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c
index ac6843c1fdd..715add8a7b0 100644
--- a/gdb/amd64-linux-tdep.c
+++ b/gdb/amd64-linux-tdep.c
@@ -2042,7 +2042,7 @@  amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   /* GNU/Linux uses SVR4-style shared libraries.  */
   set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, svr4_lp64_fetch_link_map_offsets);
+    (gdbarch, linux_lp64_fetch_link_map_offsets);
 
   /* Register DTrace handlers.  */
   set_gdbarch_dtrace_parse_probe_argument (gdbarch, amd64_dtrace_parse_probe_argument);
@@ -2256,7 +2256,7 @@  amd64_x32_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   /* GNU/Linux uses SVR4-style shared libraries.  */
   set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+    (gdbarch, linux_ilp32_fetch_link_map_offsets);
 }
 
 void _initialize_amd64_linux_tdep ();
diff --git a/gdb/ia64-linux-tdep.c b/gdb/ia64-linux-tdep.c
index a17ec590002..71767ddf83e 100644
--- a/gdb/ia64-linux-tdep.c
+++ b/gdb/ia64-linux-tdep.c
@@ -237,7 +237,7 @@  ia64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
 
   set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, svr4_lp64_fetch_link_map_offsets);
+    (gdbarch, linux_lp64_fetch_link_map_offsets);
 
   /* Enable TLS support.  */
   set_gdbarch_fetch_tls_load_module_address (gdbarch,
diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c
index 637d3d36a0b..92ecedfd1cf 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 `struct link_map_offsets'
+   for ILP32/LP64 Linux systems which don't have the r_ldsomap field.  */
+
+struct link_map_offsets *
+linux_ilp32_fetch_link_map_offsets (void)
+{
+  static struct link_map_offsets lmo;
+  static struct link_map_offsets *lmp = NULL;
+
+  if (lmp == NULL)
+    {
+      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;
+}
+
+struct link_map_offsets *
+linux_lp64_fetch_link_map_offsets (void)
+{
+  static struct link_map_offsets lmo;
+  static struct link_map_offsets *lmp = NULL;
+
+  if (lmp == NULL)
+    {
+      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;
+}
diff --git a/gdb/linux-tdep.h b/gdb/linux-tdep.h
index 28b60e46579..26873a989d2 100644
--- a/gdb/linux-tdep.h
+++ b/gdb/linux-tdep.h
@@ -98,4 +98,9 @@  extern CORE_ADDR linux_get_hwcap (struct target_ops *target);
    error, 0 is returned.  */
 extern CORE_ADDR linux_get_hwcap2 (struct target_ops *target);
 
+/* Fetch (and possibly build) an appropriate `struct link_map_offsets'
+   for ILP32 and LP64 Linux systems.  */
+extern struct link_map_offsets *linux_ilp32_fetch_link_map_offsets (void);
+extern struct link_map_offsets *linux_lp64_fetch_link_map_offsets (void);
+
 #endif /* linux-tdep.h */
diff --git a/gdb/mips-linux-tdep.c b/gdb/mips-linux-tdep.c
index 1ceed5250fe..ce287f6a354 100644
--- a/gdb/mips-linux-tdep.c
+++ b/gdb/mips-linux-tdep.c
@@ -1542,7 +1542,7 @@  mips_linux_init_abi (struct gdbarch_info info,
 	set_gdbarch_get_longjmp_target (gdbarch,
 					mips_linux_get_longjmp_target);
 	set_solib_svr4_fetch_link_map_offsets
-	  (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+	  (gdbarch, linux_ilp32_fetch_link_map_offsets);
 	tramp_frame_prepend_unwinder (gdbarch, &micromips_linux_o32_sigframe);
 	tramp_frame_prepend_unwinder (gdbarch,
 				      &micromips_linux_o32_rt_sigframe);
@@ -1554,7 +1554,7 @@  mips_linux_init_abi (struct gdbarch_info info,
 	set_gdbarch_get_longjmp_target (gdbarch,
 					mips_linux_get_longjmp_target);
 	set_solib_svr4_fetch_link_map_offsets
-	  (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+	  (gdbarch, linux_ilp32_fetch_link_map_offsets);
 	set_gdbarch_long_double_bit (gdbarch, 128);
 	/* These floatformats should probably be renamed.  MIPS uses
 	   the same 128-bit IEEE floating point format that IA-64 uses,
@@ -1570,7 +1570,7 @@  mips_linux_init_abi (struct gdbarch_info info,
 	set_gdbarch_get_longjmp_target (gdbarch,
 					mips64_linux_get_longjmp_target);
 	set_solib_svr4_fetch_link_map_offsets
-	  (gdbarch, svr4_lp64_fetch_link_map_offsets);
+	  (gdbarch, linux_lp64_fetch_link_map_offsets);
 	set_gdbarch_long_double_bit (gdbarch, 128);
 	/* These floatformats should probably be renamed.  MIPS uses
 	   the same 128-bit IEEE floating point format that IA-64 uses,
diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c
index 1e94922f25a..e62f45a35d8 100644
--- a/gdb/ppc-linux-tdep.c
+++ b/gdb/ppc-linux-tdep.c
@@ -2035,7 +2035,7 @@  ppc_linux_init_abi (struct gdbarch_info info,
       /* Shared library handling.  */
       set_gdbarch_skip_trampoline_code (gdbarch, ppc_skip_trampoline_code);
       set_solib_svr4_fetch_link_map_offsets
-	(gdbarch, svr4_ilp32_fetch_link_map_offsets);
+	(gdbarch, linux_ilp32_fetch_link_map_offsets);
 
       /* Setting the correct XML syscall filename.  */
       set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_PPC);
@@ -2087,7 +2087,7 @@  ppc_linux_init_abi (struct gdbarch_info info,
       /* Shared library handling.  */
       set_gdbarch_skip_trampoline_code (gdbarch, ppc64_skip_trampoline_code);
       set_solib_svr4_fetch_link_map_offsets
-	(gdbarch, svr4_lp64_fetch_link_map_offsets);
+	(gdbarch, linux_lp64_fetch_link_map_offsets);
 
       /* Setting the correct XML syscall filename.  */
       set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_PPC64);
diff --git a/gdb/riscv-linux-tdep.c b/gdb/riscv-linux-tdep.c
index 49dc75bb618..7351e1901d6 100644
--- a/gdb/riscv-linux-tdep.c
+++ b/gdb/riscv-linux-tdep.c
@@ -187,8 +187,8 @@  riscv_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   set_solib_svr4_fetch_link_map_offsets (gdbarch,
 					 (riscv_isa_xlen (gdbarch) == 4
-					  ? svr4_ilp32_fetch_link_map_offsets
-					  : svr4_lp64_fetch_link_map_offsets));
+					  ? linux_ilp32_fetch_link_map_offsets
+					  : linux_lp64_fetch_link_map_offsets));
 
   /* GNU/Linux uses SVR4-style shared libraries.  */
   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
diff --git a/gdb/s390-linux-tdep.c b/gdb/s390-linux-tdep.c
index 1f40e10e3d3..04e3fc640d2 100644
--- a/gdb/s390-linux-tdep.c
+++ b/gdb/s390-linux-tdep.c
@@ -1158,7 +1158,7 @@  s390_linux_init_abi_31 (struct gdbarch_info info, struct gdbarch *gdbarch)
   s390_linux_init_abi_any (info, gdbarch);
 
   set_solib_svr4_fetch_link_map_offsets (gdbarch,
-					 svr4_ilp32_fetch_link_map_offsets);
+					 linux_ilp32_fetch_link_map_offsets);
   set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_S390);
 }
 
@@ -1174,7 +1174,7 @@  s390_linux_init_abi_64 (struct gdbarch_info info, struct gdbarch *gdbarch)
   s390_linux_init_abi_any (info, gdbarch);
 
   set_solib_svr4_fetch_link_map_offsets (gdbarch,
-					 svr4_lp64_fetch_link_map_offsets);
+					 linux_lp64_fetch_link_map_offsets);
   set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_S390X);
 }
 
diff --git a/gdb/sparc64-linux-tdep.c b/gdb/sparc64-linux-tdep.c
index ea692ac00ef..e63fa87c69b 100644
--- a/gdb/sparc64-linux-tdep.c
+++ b/gdb/sparc64-linux-tdep.c
@@ -383,7 +383,7 @@  sparc64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   /* GNU/Linux has SVR4-style shared libraries...  */
   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
   set_solib_svr4_fetch_link_map_offsets
-    (gdbarch, svr4_lp64_fetch_link_map_offsets);
+    (gdbarch, linux_lp64_fetch_link_map_offsets);
 
   /* ...which means that we need some special handling when doing
      prologue analysis.  */
diff --git a/gdb/tilegx-linux-tdep.c b/gdb/tilegx-linux-tdep.c
index 382e7f6d908..353497a3434 100644
--- a/gdb/tilegx-linux-tdep.c
+++ b/gdb/tilegx-linux-tdep.c
@@ -121,10 +121,10 @@  tilegx_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   /* GNU/Linux uses SVR4-style shared libraries.  */
   if (arch_size == 32)
     set_solib_svr4_fetch_link_map_offsets (gdbarch,
-					   svr4_ilp32_fetch_link_map_offsets);
+					   linux_ilp32_fetch_link_map_offsets);
   else
     set_solib_svr4_fetch_link_map_offsets (gdbarch,
-					   svr4_lp64_fetch_link_map_offsets);
+					   linux_lp64_fetch_link_map_offsets);
 
   /* Enable TLS support.  */
   set_gdbarch_fetch_tls_load_module_address (gdbarch,