[binutils-gdb] readelf: Don't change the symbol table
H.J. Lu
hjl@sourceware.org
Wed Sep 3 15:25:14 GMT 2025
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=955b8e0939701b9d150556a300558fa0fb8f6ba8
commit 955b8e0939701b9d150556a300558fa0fb8f6ba8
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Wed Sep 3 06:48:24 2025 -0700
readelf: Don't change the symbol table
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>
Diff:
---
binutils/readelf.c | 51 +++++++++++++++++++++-------------
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, 144 insertions(+), 19 deletions(-)
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 1514ebc5cb4..705b7761bc8 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. */
+ size_t sz = nsyms * sizeof (*symtab);
+ symtab = xmemdup (symtab_p, sz, sz);
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)
{
@@ -9849,11 +9856,16 @@ display_relocations (Elf_Internal_Shdr * section,
bool res;
if (rel_type == reltype_relr)
- res = dump_relr_relocations (filedata, section->sh_size,
- section->sh_entsize,
- section->sh_offset,
- symtab, nsyms, strtab, strtablen,
- dump_reloc);
+ {
+ res = dump_relr_relocations (filedata, section->sh_size,
+ section->sh_entsize,
+ section->sh_offset,
+ relrs,
+ symtab, nsyms, strtab, strtablen,
+ dump_reloc);
+ /* RELRS has been freed by dump_relr_relocations. */
+ relrs = NULL;
+ }
else
res = dump_relocations (filedata, rel_offset, rel_size,
symtab, nsyms, strtab, strtablen,
@@ -9954,6 +9966,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"
More information about the Binutils-cvs
mailing list