From: H.J. Lu Date: Wed, 3 Sep 2025 13:48:24 +0000 (-0700) Subject: readelf: Don't change the symbol table X-Git-Tag: gdb-17-branchpoint~55 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=955b8e0939701b9d150556a300558fa0fb8f6ba8;p=thirdparty%2Fbinutils-gdb.git 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 --- 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"