]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
readelf: Don't change the symbol table
authorH.J. Lu <hjl.tools@gmail.com>
Wed, 3 Sep 2025 13:48:24 +0000 (06:48 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Wed, 3 Sep 2025 15:22:33 +0000 (08:22 -0700)
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
ld/testsuite/ld-i386/dt-relr-2.d [new file with mode: 0644]
ld/testsuite/ld-i386/dt-relr-2.s [new file with mode: 0644]
ld/testsuite/ld-i386/i386.exp
ld/testsuite/ld-x86-64/dt-relr-2-x32.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/dt-relr-2.d [new file with mode: 0644]
ld/testsuite/ld-x86-64/dt-relr-2.s [new file with mode: 0644]
ld/testsuite/ld-x86-64/x86-64.exp

index 1514ebc5cb4e19eef3ecd9e556d35737d8130b06..705b7761bc8c0254928cf4be39e89adb6460d890 100644 (file)
@@ -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 (file)
index 0000000..7b07d6c
--- /dev/null
@@ -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 (file)
index 0000000..4c2eb1f
--- /dev/null
@@ -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
index 44ba418e5b5f536bb7cc09ee3ef3eca966f314a1..bba0eeda6d8fc1e1aea9fb02b86f6913aee12fa4 100644 (file)
@@ -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 (file)
index 0000000..b3e080e
--- /dev/null
@@ -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 (file)
index 0000000..71e8c73
--- /dev/null
@@ -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 (file)
index 0000000..4e885f9
--- /dev/null
@@ -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
index acdcbaf20a02910ff59afadd93e833a638148767..23e0a98d1cd5da0ad455d700e9da537b0d0fd602 100644 (file)
@@ -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"