aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2024-04-24 12:45:04 +0100
committerNick Clifton <nickc@redhat.com>2024-04-24 12:45:04 +0100
commit3b3e2090118966e3b885ae578440e380dc90e648 (patch)
treee757ee01a9713071af42cbf76a7bca90b9e46d89
parent1a7f925ea20c82fc9899f41d21df8e21dcae3169 (diff)
downloadgdb-3b3e2090118966e3b885ae578440e380dc90e648.zip
gdb-3b3e2090118966e3b885ae578440e380dc90e648.tar.gz
gdb-3b3e2090118966e3b885ae578440e380dc90e648.tar.bz2
Update readelf's display of RELR sections to include the number of locations relocated
-rw-r--r--binutils/readelf.c135
-rw-r--r--ld/testsuite/ld-elf/dt-relr-2b.d2
-rw-r--r--ld/testsuite/ld-elf/dt-relr-2c.d2
-rw-r--r--ld/testsuite/ld-elf/dt-relr-2d.d2
-rw-r--r--ld/testsuite/ld-elf/dt-relr-2e.d2
-rw-r--r--ld/testsuite/ld-elf/dt-relr-2i.d2
-rw-r--r--ld/testsuite/ld-i386/dt-relr-1a.d2
-rw-r--r--ld/testsuite/ld-i386/dt-relr-1b.d2
-rw-r--r--ld/testsuite/ld-powerpc/abs-pie-relr.r2
-rw-r--r--ld/testsuite/ld-powerpc/abs-shared-relr.r2
-rw-r--r--ld/testsuite/ld-x86-64/dt-relr-1a-x32.d2
-rw-r--r--ld/testsuite/ld-x86-64/dt-relr-1a.d2
-rw-r--r--ld/testsuite/ld-x86-64/dt-relr-1b-x32.d2
-rw-r--r--ld/testsuite/ld-x86-64/dt-relr-1b.d2
14 files changed, 128 insertions, 33 deletions
diff --git a/binutils/readelf.c b/binutils/readelf.c
index e0cf718..f8305b4 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -1548,6 +1548,10 @@ get_symbol_at (Elf_Internal_Sym * symtab,
Elf_Internal_Sym * best = NULL;
uint64_t dist = 0x100000;
+ /* Paranoia. */
+ if (symtab == NULL || nsyms == 0 || strtab == NULL || strtablen == 0)
+ return NULL;
+
/* FIXME: Since this function is likely to be called repeatedly with
slightly increasing addresses each time, we could speed things up by
caching the last returned value and starting our search from there. */
@@ -1624,6 +1628,69 @@ symcmp (const void *p, const void *q)
return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
}
+static uint64_t
+count_relr_relocations (Filedata * filedata,
+ Elf_Internal_Shdr * section)
+{
+ uint64_t * relrs;
+ uint64_t nentries;
+ uint64_t i;
+ uint64_t count;
+ int entsize;
+
+ if (section == NULL
+ || section->sh_type != SHT_RELR
+ || section->sh_size == 0)
+ return 0;
+
+ entsize = section->sh_entsize;
+ if (entsize == 0)
+ entsize = is_32bit_elf
+ ? sizeof (Elf32_External_Relr) : sizeof (Elf64_External_Relr);
+ else if (entsize != sizeof (Elf32_External_Relr)
+ && entsize != sizeof (Elf64_External_Relr))
+ return 0;
+
+ nentries = section->sh_size / entsize;
+ 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)
+ return 0;
+
+ for (count = i = 0; i < nentries; i++)
+ {
+ uint64_t entry;
+
+ if (entsize == sizeof (Elf32_External_Relr))
+ entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
+ else
+ entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
+
+ if ((entry & 1) == 0)
+ {
+ ++ count;
+ }
+ else
+ {
+ if (entry == 1)
+ continue;
+
+ for (; entry >>= 1;)
+ if ((entry & 1) == 1)
+ ++ count;
+ }
+ }
+
+ free (relrs);
+ return count;
+}
+
static bool
dump_relr_relocations (Filedata * filedata,
Elf_Internal_Shdr * section,
@@ -1640,15 +1707,15 @@ dump_relr_relocations (Filedata * filedata,
uint64_t where = 0;
int num_bits_in_entry;
- relrs = get_data (NULL, filedata, relr_offset, 1, relr_size, _("RELR relocation data"));
- if (relrs == NULL)
- return false;
-
if (relr_entsize == 0)
- relr_entsize = is_32bit_elf ? 4 : 8;
+ relr_entsize = is_32bit_elf
+ ? sizeof (Elf32_External_Relr) : sizeof (Elf64_External_Relr);
nentries = relr_size / relr_entsize;
+ if (nentries == 0)
+ return true;
+
if (relr_entsize == sizeof (Elf32_External_Relr))
num_bits_in_entry = 31;
else if (relr_entsize == sizeof (Elf64_External_Relr))
@@ -1658,14 +1725,21 @@ dump_relr_relocations (Filedata * filedata,
warn (_("Unexpected entsize for RELR section\n"));
return false;
}
-
- /* 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 now. FIXME: This assumes that the symbol table will not
- be used later on for some other purpose. */
- qsort (symtab, nsyms, sizeof (Elf_Internal_Sym), symcmp);
- if (relr_entsize == 4)
+ relrs = get_data (NULL, filedata, relr_offset, 1, relr_size, _("RELR relocation data"));
+ if (relrs == NULL)
+ return false;
+
+ if (symtab != 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 now. FIXME: This assumes that the symbol table will not
+ be used later on for some other purpose. */
+ qsort (symtab, nsyms, sizeof (Elf_Internal_Sym), symcmp);
+ }
+
+ if (relr_entsize == sizeof (Elf32_External_Relr))
printf (_ ("Index: Entry Address Symbolic Address\n"));
else
printf (_ ("Index: Entry Address Symbolic Address\n"));
@@ -1674,7 +1748,7 @@ dump_relr_relocations (Filedata * filedata,
{
uint64_t entry;
- if (relr_entsize == 4)
+ if (relr_entsize == sizeof (Elf32_External_Relr))
entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
else
entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
@@ -1698,7 +1772,9 @@ dump_relr_relocations (Filedata * filedata,
/* The least significant bit is ignored. */
if (entry == 1)
- warn (_("Malformed RELR bitmap - no significant bits are set\n"));
+ /* This can actually happen when the linker is allowed to shrink
+ RELR sections. For more details see: https://reviews.llvm.org/D67164. */
+ continue;
else if (i == 0)
warn (_("Unusual RELR bitmap - no previous entry to set the base address\n"));
@@ -9077,12 +9153,31 @@ display_relocations (Elf_Internal_Shdr * section,
uint64_t num_rela = rel_size / section->sh_entsize;
uint64_t rel_offset = section->sh_offset;
- printf (ngettext (" at offset %#" PRIx64
- " contains %" PRIu64 " entry:\n",
- " at offset %#" PRIx64
- " contains %" PRId64 " entries:\n",
- num_rela),
- rel_offset, num_rela);
+ if (rel_type == reltype_relr)
+ {
+ /* Just stating the 'number of entries' in a RELR section can be
+ misleading, since this is not the number of locations relocated, but
+ the number of words in the compressed RELR format. So also provide
+ the number of locations affected. */
+ if (num_rela == 1)
+ /* This is unlikely, but possible. */
+ printf (_(" at offset %#" PRIx64
+ " contains 1 entry which relocates 1 location:\n"),
+ rel_offset);
+ else
+ printf (_(" at offset %#" PRIx64 " contains %" PRIu64
+ " entries which relocate %" PRIu64 " locations:\n"),
+ rel_offset, num_rela, count_relr_relocations (filedata, section));
+ }
+ else
+ {
+ printf (ngettext (" at offset %#" PRIx64
+ " contains %" PRIu64 " entry:\n",
+ " at offset %#" PRIx64
+ " contains %" PRIu64 " entries:\n",
+ num_rela),
+ rel_offset, num_rela);
+ }
Elf_Internal_Shdr * symsec;
Elf_Internal_Sym * symtab = NULL;
diff --git a/ld/testsuite/ld-elf/dt-relr-2b.d b/ld/testsuite/ld-elf/dt-relr-2b.d
index f9c6880..6c66d56 100644
--- a/ld/testsuite/ld-elf/dt-relr-2b.d
+++ b/ld/testsuite/ld-elf/dt-relr-2b.d
@@ -12,7 +12,7 @@ Relocation section '\.rel(a|)\.dyn' at offset 0x[0-9a-f]+ contains 1 entry:
#...
[0-9a-f]+ +[0-9a-f]+ +R_.*_(RELATIVE|UADDR.*) .*
#...
-Relocation section '\.relr\.dyn' at offset 0x[0-9a-f]+ contains 2 entries:
+Relocation section '\.relr\.dyn' at offset 0x[0-9a-f]+ contains 2 entries which relocate [0-9]+ locations:
#...
0000: +[0-9a-f]+ [0-9a-f]+ +data
0001: +[0-9a-f]+ [0-9a-f]+ +data \+ 0x[0-9a-f]+
diff --git a/ld/testsuite/ld-elf/dt-relr-2c.d b/ld/testsuite/ld-elf/dt-relr-2c.d
index d9e3698..cc37375 100644
--- a/ld/testsuite/ld-elf/dt-relr-2c.d
+++ b/ld/testsuite/ld-elf/dt-relr-2c.d
@@ -12,7 +12,7 @@ Relocation section '\.rel(a|)\.dyn' at offset 0x[0-9a-f]+ contains 2 entries:
#...
[0-9a-f]+ +[0-9a-f]+ +R_.*_(RELATIVE|UADDR.*) .*
#...
-Relocation section '\.relr\.dyn' at offset 0x[0-9a-f]+ contains 2 entries:
+Relocation section '\.relr\.dyn' at offset 0x[0-9a-f]+ contains 2 entries which relocate [0-9]+ locations:
#...
0000: +[0-9a-f]+ [0-9a-f]+ +.*
0001: +[0-9a-f]+ [0-9a-f]+ +.*
diff --git a/ld/testsuite/ld-elf/dt-relr-2d.d b/ld/testsuite/ld-elf/dt-relr-2d.d
index 69863bd..d149e77 100644
--- a/ld/testsuite/ld-elf/dt-relr-2d.d
+++ b/ld/testsuite/ld-elf/dt-relr-2d.d
@@ -12,7 +12,7 @@ Relocation section '\.rel(a|)\.dyn' at offset 0x[0-9a-f]+ contains 1 entry:
#...
[0-9a-f]+ +[0-9a-f]+ +R_.*_(RELATIVE|UADDR.*) .*
#...
-Relocation section '\.relr\.dyn' at offset 0x[0-9a-f]+ contains 2 entries:
+Relocation section '\.relr\.dyn' at offset 0x[0-9a-f]+ contains 2 entries which relocate [0-9]+ locations:
#...
0000: +[0-9a-f]+ [0-9a-f]+ +data
0001: +[0-9a-f]+ [0-9a-f]+ +data \+ 0x[0-9a-f]+
diff --git a/ld/testsuite/ld-elf/dt-relr-2e.d b/ld/testsuite/ld-elf/dt-relr-2e.d
index e047c0d..e6b478c 100644
--- a/ld/testsuite/ld-elf/dt-relr-2e.d
+++ b/ld/testsuite/ld-elf/dt-relr-2e.d
@@ -12,7 +12,7 @@ Relocation section '\.rel(a|)\.data' at offset 0x[0-9a-f]+ contains 1 entry:
#...
[0-9a-f]+ +[0-9a-f]+ +R_.*_(RELATIVE|UADDR.*) .*
#...
-Relocation section '\.relr\.dyn' at offset 0x[0-9a-f]+ contains 2 entries:
+Relocation section '\.relr\.dyn' at offset 0x[0-9a-f]+ contains 2 entries which relocate [0-9]+ locations:
#...
0000: +[0-9a-f]+ [0-9a-f]+ +data
0001: +[0-9a-f]+ [0-9a-f]+ +data \+ 0x[0-9a-f]+
diff --git a/ld/testsuite/ld-elf/dt-relr-2i.d b/ld/testsuite/ld-elf/dt-relr-2i.d
index a328ccb..2a07fcb 100644
--- a/ld/testsuite/ld-elf/dt-relr-2i.d
+++ b/ld/testsuite/ld-elf/dt-relr-2i.d
@@ -12,7 +12,7 @@ Relocation section '\.rel(a|)\.dyn' at offset 0x[0-9a-f]+ contains 1 entry:
#...
[0-9a-f]+ +[0-9a-f]+ +R_.*_(RELATIVE|UADDR.*) .*
#...
-Relocation section '\.relr\.dyn' at offset 0x[0-9a-f]+ contains 2 entries:
+Relocation section '\.relr\.dyn' at offset 0x[0-9a-f]+ contains 2 entries which relocate [0-9]+ locations:
#...
0000: +[0-9a-f]+ [0-9a-f]+ +data
0001: +[0-9a-f]+ [0-9a-f]+ +data \+ 0x[0-9a-f]+
diff --git a/ld/testsuite/ld-i386/dt-relr-1a.d b/ld/testsuite/ld-i386/dt-relr-1a.d
index 89cc636..282540b 100644
--- a/ld/testsuite/ld-i386/dt-relr-1a.d
+++ b/ld/testsuite/ld-i386/dt-relr-1a.d
@@ -13,7 +13,7 @@ Relocation section '\.rel\.plt' at offset 0x[0-9a-f]+ contains 1 entry:
+Offset +Info +Type +Sym. Value +Symbol's Name
[0-9a-f]+ +[0-9a-f]+ +R_386_JUMP_SLOT +0+ +func1
-Relocation section '.relr.dyn' at offset 0x[a-f0-9]+ contains 2 entries:
+Relocation section '.relr.dyn' at offset 0x[a-f0-9]+ contains 2 entries which relocate [0-9]+ locations:
#...
0000: +[0-9a-f]+ [0-9a-f]+ +.*
0001: +[0-9a-f]+ [0-9a-f]+ +.*
diff --git a/ld/testsuite/ld-i386/dt-relr-1b.d b/ld/testsuite/ld-i386/dt-relr-1b.d
index 6e7f3ca..ff02725 100644
--- a/ld/testsuite/ld-i386/dt-relr-1b.d
+++ b/ld/testsuite/ld-i386/dt-relr-1b.d
@@ -16,7 +16,7 @@ Relocation section '\.rel\.plt' at offset 0x[0-9a-f]+ contains 1 entry:
+Offset +Info +Type +Sym. Value +Symbol's Name
[0-9a-f]+ +[0-9a-f]+ +R_386_JUMP_SLOT +0+ +func1
-Relocation section '.relr.dyn' at offset 0x[a-f0-9]+ contains 2 entries:
+Relocation section '.relr.dyn' at offset 0x[a-f0-9]+ contains 2 entries which relocate [0-9]+ locations:
#...
0000: +[0-9a-f]+ [0-9a-f]+ +.*
0001: +[0-9a-f]+ [0-9a-f]+ +.*
diff --git a/ld/testsuite/ld-powerpc/abs-pie-relr.r b/ld/testsuite/ld-powerpc/abs-pie-relr.r
index e84b0af..37c64f3 100644
--- a/ld/testsuite/ld-powerpc/abs-pie-relr.r
+++ b/ld/testsuite/ld-powerpc/abs-pie-relr.r
@@ -3,6 +3,6 @@
#ld: -melf64ppc -pie --hash-style=sysv -z pack-relative-relocs --defsym a=1 --defsym 'HIDDEN(b=2)' --defsym c=0x123456789abcdef0
#readelf: -rW
-Relocation section '\.relr\.dyn' at offset .* contains 1 entry:
+Relocation section '\.relr\.dyn' at offset .* contains 1 entry which relocates 1 location:
Index: Entry Address Symbolic Address
0000: +[0-9a-f]+ [0-9a-f]+ +x
diff --git a/ld/testsuite/ld-powerpc/abs-shared-relr.r b/ld/testsuite/ld-powerpc/abs-shared-relr.r
index ce1a7ee..3f36c5d 100644
--- a/ld/testsuite/ld-powerpc/abs-shared-relr.r
+++ b/ld/testsuite/ld-powerpc/abs-shared-relr.r
@@ -12,7 +12,7 @@ Relocation section '\.rela\.dyn' at offset .* contains 6 entries:
0+10428 0+400000014 R_PPC64_GLOB_DAT 123456789abcdef0 c \+ 0
0+10450 0+400000026 R_PPC64_ADDR64 123456789abcdef0 c \+ 0
-Relocation section '\.relr\.dyn' at offset .* contains 1 entry:
+Relocation section '\.relr\.dyn' at offset .* contains 1 entry which relocates 1 location:
Index: Entry Address Symbolic Address
0000: +[0-9a-f]+ [0-9a-f]+ +x
diff --git a/ld/testsuite/ld-x86-64/dt-relr-1a-x32.d b/ld/testsuite/ld-x86-64/dt-relr-1a-x32.d
index 863e97a..dd2b73e 100644
--- a/ld/testsuite/ld-x86-64/dt-relr-1a-x32.d
+++ b/ld/testsuite/ld-x86-64/dt-relr-1a-x32.d
@@ -13,7 +13,7 @@ Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entry:
+Offset +Info +Type +Sym. Value +Symbol's Name \+ Addend
[0-9a-f]+ +[0-9a-f]+ +R_X86_64_JUMP_SLOT +0+ +func1 \+ 0
-Relocation section '.relr.dyn' at offset 0x[a-f0-9]+ contains 2 entries:
+Relocation section '.relr.dyn' at offset 0x[a-f0-9]+ contains 2 entries which relocate [0-9]+ locations:
#...
0000: +[0-9a-f]+ [0-9a-f]+ +.*
0001: +[0-9a-f]+ [0-9a-f]+ +.*
diff --git a/ld/testsuite/ld-x86-64/dt-relr-1a.d b/ld/testsuite/ld-x86-64/dt-relr-1a.d
index 30af875..c7a74e3 100644
--- a/ld/testsuite/ld-x86-64/dt-relr-1a.d
+++ b/ld/testsuite/ld-x86-64/dt-relr-1a.d
@@ -13,7 +13,7 @@ Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entry:
+Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
[0-9a-f]+ +[0-9a-f]+ +R_X86_64_JUMP_SLOT +0+ +func1 \+ 0
-Relocation section '.relr.dyn' at offset 0x[a-f0-9]+ contains 2 entries:
+Relocation section '.relr.dyn' at offset 0x[a-f0-9]+ contains 2 entries which relocate [0-9]+ locations:
#...
0000: +[0-9a-f]+ [0-9a-f]+ +.*
0001: +[0-9a-f]+ [0-9a-f]+ +.*
diff --git a/ld/testsuite/ld-x86-64/dt-relr-1b-x32.d b/ld/testsuite/ld-x86-64/dt-relr-1b-x32.d
index 3c37bcd..bc582ae 100644
--- a/ld/testsuite/ld-x86-64/dt-relr-1b-x32.d
+++ b/ld/testsuite/ld-x86-64/dt-relr-1b-x32.d
@@ -16,7 +16,7 @@ Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entry:
+Offset +Info +Type +Sym. Value +Symbol's Name \+ Addend
[0-9a-f]+ +[0-9a-f]+ +R_X86_64_JUMP_SLOT +0+ +func1 \+ 0
-Relocation section '.relr.dyn' at offset 0x[a-f0-9]+ contains 2 entries:
+Relocation section '.relr.dyn' at offset 0x[a-f0-9]+ contains 2 entries which relocate [0-9]+ locations:
#...
0000: +[0-9a-f]+ [0-9a-f]+ +.*
0001: +[0-9a-f]+ [0-9a-f]+ +.*
diff --git a/ld/testsuite/ld-x86-64/dt-relr-1b.d b/ld/testsuite/ld-x86-64/dt-relr-1b.d
index bc07cf8..c3fddb0 100644
--- a/ld/testsuite/ld-x86-64/dt-relr-1b.d
+++ b/ld/testsuite/ld-x86-64/dt-relr-1b.d
@@ -16,7 +16,7 @@ Relocation section '.rela.plt' at offset 0x[0-9a-f]+ contains 1 entry:
+Offset +Info +Type +Symbol's Value +Symbol's Name \+ Addend
[0-9a-f]+ +[0-9a-f]+ +R_X86_64_JUMP_SLOT +0+ +func1 \+ 0
-Relocation section '.relr.dyn' at offset 0x[a-f0-9]+ contains 2 entries:
+Relocation section '.relr.dyn' at offset 0x[a-f0-9]+ contains 2 entries which relocate [0-9]+ locations:
#...
0000: +[0-9a-f]+ [0-9a-f]+ +.*
0001: +[0-9a-f]+ [0-9a-f]+ +.*