[PATCH v2] readelf: Don't change the symbol table

H.J. Lu hjl.tools@gmail.com
Wed Sep 3 13:05:29 GMT 2025


1. Update dump_relr_relocations not to change the symbol table.
2. Update count_relr_relocations and dump_relr_relocations not to
retrieve the same data twice.

binutils/

	PR binutils/33328
	* readelf.c (count_relr_relocations): Add an argument to return
	the retrieved data and remove the FIXME in comments.
	(dump_relr_relocations): Add an argument for the retrieved data.
	Retrieve the data if needed.  Don't change the symbol table and
	remove the FIXME in comments.
	(display_relocations): Get the data from count_relr_relocations
	and pass it to dump_relr_relocations call.
	(process_relocs): Pass NULL to dump_relr_relocations.

ld/

	PR binutils/33328
	* testsuite/ld-i386/dt-relr-2.d: New file.
	* testsuite/ld-i386/dt-relr-2.s: Likewise.
	* testsuite/ld-x86-64/dt-relr-2-x32.d: Likewise.
	* testsuite/ld-x86-64/dt-relr-2.d: Likewise.
	* testsuite/ld-x86-64/dt-relr-2.s: Likewise.
	* testsuite/ld-i386/i386.exp: Run dt-relr-2.
	* testsuite/ld-x86-64/x86-64.exp: Run dt-relr-2 and dt-relr-2-x32.

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
---
 binutils/readelf.c                     | 37 ++++++++++++++++----------
 ld/testsuite/ld-i386/dt-relr-2.d       | 21 +++++++++++++++
 ld/testsuite/ld-i386/dt-relr-2.s       | 23 ++++++++++++++++
 ld/testsuite/ld-i386/i386.exp          |  1 +
 ld/testsuite/ld-x86-64/dt-relr-2-x32.d | 21 +++++++++++++++
 ld/testsuite/ld-x86-64/dt-relr-2.d     | 21 +++++++++++++++
 ld/testsuite/ld-x86-64/dt-relr-2.s     | 23 ++++++++++++++++
 ld/testsuite/ld-x86-64/x86-64.exp      |  2 ++
 8 files changed, 135 insertions(+), 14 deletions(-)
 create mode 100644 ld/testsuite/ld-i386/dt-relr-2.d
 create mode 100644 ld/testsuite/ld-i386/dt-relr-2.s
 create mode 100644 ld/testsuite/ld-x86-64/dt-relr-2-x32.d
 create mode 100644 ld/testsuite/ld-x86-64/dt-relr-2.d
 create mode 100644 ld/testsuite/ld-x86-64/dt-relr-2.s

diff --git a/binutils/readelf.c b/binutils/readelf.c
index 1514ebc5cb4..ed1dd9f35dc 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -1811,7 +1811,8 @@ update_all_relocations (size_t nentries)
 
 static uint64_t
 count_relr_relocations (Filedata *          filedata,
-			Elf_Internal_Shdr * section)
+			Elf_Internal_Shdr * section,
+			uint64_t         ** relrs_p)
 {
   uint64_t *  relrs;
   uint64_t    nentries;
@@ -1836,9 +1837,6 @@ count_relr_relocations (Filedata *          filedata,
   if (nentries == 0)
     return 0;
 
-  /* FIXME: This call to get_data duplicates one that follows in
-     dump_relr_relocations().  They could be combined into just
-     one call.  */
   relrs = get_data (NULL, filedata, section->sh_offset, 1,
 		    section->sh_size, _("RELR relocation data"));
   if (relrs == NULL)
@@ -1868,7 +1866,8 @@ count_relr_relocations (Filedata *          filedata,
 	}
     }
 
-  free (relrs);
+  *relrs_p = relrs;
+
   return count;
 }
 
@@ -1880,13 +1879,13 @@ dump_relr_relocations (Filedata *          filedata,
 		       uint64_t            relr_size,
 		       int                 relr_entsize,
 		       uint64_t            relr_offset,
-		       Elf_Internal_Sym *  symtab,
+		       uint64_t *          relrs,
+		       const Elf_Internal_Sym * symtab_p,
 		       uint64_t            nsyms,
 		       char *              strtab,
 		       uint64_t            strtablen,
 		       bool                dump_reloc)
 {
-  uint64_t *  relrs;
   uint64_t    nentries, i;
   uint64_t    where = 0;
   int         num_bits_in_entry;
@@ -1911,14 +1910,18 @@ dump_relr_relocations (Filedata *          filedata,
       return false;
     }
 
-  relrs = get_data (NULL, filedata, relr_offset, 1, relr_size, _("RELR relocation data"));
   if (relrs == NULL)
-    return false;
+    {
+      relrs = get_data (NULL, filedata, relr_offset, 1, relr_size,
+			_("RELR relocation data"));
+      if (relrs == NULL)
+	return false;
+    }
 
   /* Paranoia.  */
   if (strtab == NULL)
     strtablen = 0;
-  if (symtab == NULL)
+  if (symtab_p == NULL)
     nsyms = 0;
 
   const char *rtype = NULL;
@@ -2076,12 +2079,14 @@ dump_relr_relocations (Filedata *          filedata,
 	break;
       }
 
-  if (symtab != NULL)
+  Elf_Internal_Sym *symtab = NULL;
+  if (symtab_p != NULL)
     {
       /* Symbol tables are not sorted on address, but we want a quick lookup
 	 for the symbol associated with each address computed below, so sort
-	 the table then filter out unwanted entries. FIXME: This assumes that
-	 the symbol table will not be used later on for some other purpose.  */
+	 the table then filter out unwanted entries.  */
+      symtab = xmalloc (nsyms * sizeof (*symtab));
+      memcpy (symtab, symtab_p, nsyms * sizeof (*symtab));
       qsort (symtab, nsyms, sizeof (Elf_Internal_Sym), symcmp);
       nsyms = filter_display_syms (filedata, symtab, nsyms, strtab, strtablen);
     }
@@ -2185,6 +2190,7 @@ dump_relr_relocations (Filedata *          filedata,
 	}
     }
 
+  free (symtab);
   free (relrs);
   return true;
 }
@@ -9783,6 +9789,7 @@ display_relocations (Elf_Internal_Shdr *  section,
   uint64_t rel_offset = section->sh_offset;
   uint64_t num_rela = rel_size / section->sh_entsize;
   uint64_t num_reloc;
+  uint64_t *relrs = NULL;
 
   if (rel_type == reltype_relr)
     {
@@ -9791,7 +9798,7 @@ display_relocations (Elf_Internal_Shdr *  section,
 	 the number of words in the compressed RELR format.  So also provide
 	 the number of locations affected.  */
 
-      num_reloc = count_relr_relocations (filedata, section);
+      num_reloc = count_relr_relocations (filedata, section, &relrs);
 
       if (dump_reloc)
 	{
@@ -9852,6 +9859,7 @@ display_relocations (Elf_Internal_Shdr *  section,
     res = dump_relr_relocations (filedata, section->sh_size,
 				 section->sh_entsize,
 				 section->sh_offset,
+				 relrs,
 				 symtab, nsyms, strtab, strtablen,
 				 dump_reloc);
   else
@@ -9954,6 +9962,7 @@ process_relocs (Filedata * filedata)
 				   filedata->dynamic_info[DT_RELRSZ],
 				   filedata->dynamic_info[DT_RELRENT],
 				   filedata->dynamic_info[DT_RELR],
+				   NULL,
 				   filedata->dynamic_symbols,
 				   filedata->num_dynamic_syms,
 				   filedata->dynamic_strings,
diff --git a/ld/testsuite/ld-i386/dt-relr-2.d b/ld/testsuite/ld-i386/dt-relr-2.d
new file mode 100644
index 00000000000..7b07d6c5dc4
--- /dev/null
+++ b/ld/testsuite/ld-i386/dt-relr-2.d
@@ -0,0 +1,21 @@
+#source: dt-relr-2.s
+#as: --32
+#ld: -shared -melf_i386 $DT_RELR_LDFLAGS --hash-style=sysv
+#readelf: -D -r --wide
+#target: x86_64-*-linux* i?86-*-linux-gnu i?86-*-gnu*
+
+'REL' relocation section at offset [0x0-9a-f]+ contains 16 bytes:
+ +Offset +Info +Type +Sym. Value +Symbol's Name
+[0-9a-f]+ +[0-9a-f]+ +R_386_32 +0+ +data1
+[0-9a-f]+ +[0-9a-f]+ +R_386_32 +0+ +data1
+
+'RELR' relocation section at offset 0x[a-f0-9]+ contains 8 bytes:
+#...
+0000: +[0-9a-f]+ [0-9a-f]+ +.*
+0001: +[0-9a-f]+ [0-9a-f]+ +.*
+ +[0-9a-f]+ +.*
+#...
+'PLT' relocation section at offset 0x[0-9a-f]+ contains 16 bytes:
+ +Offset +Info +Type +Sym. Value +Symbol's Name
+[0-9a-f]+ +[0-9a-f]+ +R_386_JUMP_SLOT +[0-9a-f]+ +func1
+[0-9a-f]+ +[0-9a-f]+ +R_386_JUMP_SLOT +[0-9a-f]+ +func2
diff --git a/ld/testsuite/ld-i386/dt-relr-2.s b/ld/testsuite/ld-i386/dt-relr-2.s
new file mode 100644
index 00000000000..4c2eb1f2ab0
--- /dev/null
+++ b/ld/testsuite/ld-i386/dt-relr-2.s
@@ -0,0 +1,23 @@
+	.text
+	.globl func1
+func1:
+	ret
+foo:
+	call	func1@PLT
+	call	func2@PLT
+	pushl	__ehdr_start@GOT(%ebx)
+	.globl func2
+func2:
+	ret
+	.globl func3
+func3:
+	ret
+	.section .bar,"aw",@progbits
+	.p2align 2
+	.dc.a	data1
+	.dc.a	__ehdr_start
+
+	.section .foo,"aw",@progbits
+	.p2align 2
+	.dc.a	data1
+	.dc.a	__ehdr_start
diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
index 44ba418e5b5..bba0eeda6d8 100644
--- a/ld/testsuite/ld-i386/i386.exp
+++ b/ld/testsuite/ld-i386/i386.exp
@@ -517,6 +517,7 @@ run_dump_test "dt-relr-1a"
 run_dump_test "dt-relr-1b"
 run_dump_test "dt-relr-1c"
 run_dump_test "dt-relr-1d"
+run_dump_test "dt-relr-2"
 run_dump_test "pr28870"
 run_dump_test "pr28894"
 run_dump_test "pr30787"
diff --git a/ld/testsuite/ld-x86-64/dt-relr-2-x32.d b/ld/testsuite/ld-x86-64/dt-relr-2-x32.d
new file mode 100644
index 00000000000..b3e080e01c8
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/dt-relr-2-x32.d
@@ -0,0 +1,21 @@
+#source: dt-relr-2.s
+#as: --x32
+#ld: -shared -melf32_x86_64 $DT_RELR_LDFLAGS -z nomark-plt --hash-style=sysv
+#readelf: -D -r --wide
+#target: x86_64-*-linux*
+
+'RELA' relocation section at offset 0x[0-9a-f]+ contains 24 bytes:
+ +Offset +Info +Type +Sym. Value +Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_32 +0+ +data1 \+ 0
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_32 +0+ +data1 \+ 0
+
+'RELR' relocation section at offset 0x[a-f0-9]+ contains 8 bytes:
+#...
+0000: +[0-9a-f]+ [0-9a-f]+ +.*
+0001: +[0-9a-f]+ [0-9a-f]+ +.*
+ +[0-9a-f]+ +.*
+#...
+'PLT' relocation section at offset 0x[0-9a-f]+ contains 24 bytes:
+ +Offset +Info +Type +Sym. Value +Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_JUMP_SLOT +[0-9a-f]+ +func1 \+ 0
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_JUMP_SLOT +[0-9a-f]+ +func2 \+ 0
diff --git a/ld/testsuite/ld-x86-64/dt-relr-2.d b/ld/testsuite/ld-x86-64/dt-relr-2.d
new file mode 100644
index 00000000000..71e8c73d9c7
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/dt-relr-2.d
@@ -0,0 +1,21 @@
+#source: dt-relr-2.s
+#as: --64
+#ld: -shared -melf_x86_64 $DT_RELR_LDFLAGS -z nomark-plt --hash-style=sysv
+#readelf: -D -r --wide
+#target: x86_64-*-linux*
+
+'RELA' relocation section at offset 0x[0-9a-f]+ contains 48 bytes:
+ +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_64 +0+ +data1 \+ 0
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_64 +0+ +data1 \+ 0
+
+'RELR' relocation section at offset 0x[a-f0-9]+ contains 16 bytes:
+#...
+0000: +[0-9a-f]+ [0-9a-f]+ +.*
+0001: +[0-9a-f]+ [0-9a-f]+ +.*
+ +[0-9a-f]+ +.*
+#...
+'PLT' relocation section at offset 0x[0-9a-f]+ contains 48 bytes:
+ +Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_JUMP_SLOT +[0-9a-f]+ +func1 \+ 0
+[0-9a-f]+ +[0-9a-f]+ +R_X86_64_JUMP_SLOT +[0-9a-f]+ +func2 \+ 0
diff --git a/ld/testsuite/ld-x86-64/dt-relr-2.s b/ld/testsuite/ld-x86-64/dt-relr-2.s
new file mode 100644
index 00000000000..4e885f9e05d
--- /dev/null
+++ b/ld/testsuite/ld-x86-64/dt-relr-2.s
@@ -0,0 +1,23 @@
+	.text
+	.globl func1
+func1:
+	ret
+foo:
+	call	func1@PLT
+	call	func2@PLT
+	add	__ehdr_start@GOTPCREL(%rip), %rax
+	.globl func2
+func2:
+	ret
+	.globl func3
+func3:
+	ret
+	.section .bar,"aw",@progbits
+	.p2align 3
+	.dc.a	data1
+	.dc.a	__ehdr_start
+
+	.section .foo,"aw",@progbits
+	.p2align 3
+	.dc.a	data1
+	.dc.a	__ehdr_start
diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp
index acdcbaf20a0..23e0a98d1cd 100644
--- a/ld/testsuite/ld-x86-64/x86-64.exp
+++ b/ld/testsuite/ld-x86-64/x86-64.exp
@@ -538,6 +538,8 @@ run_dump_test "dt-relr-1c"
 run_dump_test "dt-relr-1c-x32"
 run_dump_test "dt-relr-1d"
 run_dump_test "dt-relr-1d-x32"
+run_dump_test "dt-relr-2"
+run_dump_test "dt-relr-2-x32"
 run_dump_test "pr30787"
 run_dump_test "pr31047"
 run_dump_test "pr31047-x32"
-- 
2.51.0



More information about the Binutils mailing list