]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Update readelf's display of RELR sections to include the number of locations relocated
authorNick Clifton <nickc@redhat.com>
Wed, 24 Apr 2024 11:45:04 +0000 (12:45 +0100)
committerNick Clifton <nickc@redhat.com>
Wed, 24 Apr 2024 11:45:04 +0000 (12:45 +0100)
14 files changed:
binutils/readelf.c
ld/testsuite/ld-elf/dt-relr-2b.d
ld/testsuite/ld-elf/dt-relr-2c.d
ld/testsuite/ld-elf/dt-relr-2d.d
ld/testsuite/ld-elf/dt-relr-2e.d
ld/testsuite/ld-elf/dt-relr-2i.d
ld/testsuite/ld-i386/dt-relr-1a.d
ld/testsuite/ld-i386/dt-relr-1b.d
ld/testsuite/ld-powerpc/abs-pie-relr.r
ld/testsuite/ld-powerpc/abs-shared-relr.r
ld/testsuite/ld-x86-64/dt-relr-1a-x32.d
ld/testsuite/ld-x86-64/dt-relr-1a.d
ld/testsuite/ld-x86-64/dt-relr-1b-x32.d
ld/testsuite/ld-x86-64/dt-relr-1b.d

index e0cf718aa28d7b43cb0c8d6979b0679332a52084..f8305b4715b8243bb3889e11492daef59e26acdc 100644 (file)
@@ -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;
index f9c688087f940426484298d8511a0fdb504d3101..6c66d56eade8810a4bd9557dc28be1f805f39c7e 100644 (file)
@@ -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]+
index d9e3698a8f09a6ca7e7554a491a36811c81b2a61..cc37375e4e552ca5d1be2bb613660707aed92bc7 100644 (file)
@@ -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]+ +.*
index 69863bddec44bf3a3b0e8046f686bcff120a49a5..d149e77bd68c5e6958ad32e5a0e2d5d8fbb49d3e 100644 (file)
@@ -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]+
index e047c0d65297f13668f69c88a14dc9fbc015a306..e6b478cb5f0d641b168c383007ef5828a081b59f 100644 (file)
@@ -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]+
index a328ccb92e5c3de72894d898f3a4321dd83a2b20..2a07fcb1a711d327a2245a6d52e7d3cbb236ad3d 100644 (file)
@@ -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]+
index 89cc636f4bc18a446be2f66d718f84a454206606..282540b8b50f9f366bf89428f04ecc0d05eb03fe 100644 (file)
@@ -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]+ +.*
index 6e7f3ca0a25d9c5b074902b271693664dd524cbb..ff027257e159dd402c47c256bc8d04b993342cbb 100644 (file)
@@ -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]+ +.*
index e84b0af115bdc4992b481edc6138278f75e9f2f3..37c64f38bc64455918e65b910a61d5c4ff5b4358 100644 (file)
@@ -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
index ce1a7eee339999aaac7470a848a51312c8bece59..3f36c5d877f5ad635d31d332e4d74443ea3e0ad9 100644 (file)
@@ -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
 
index 863e97a79803ff6bb5580f6c373f0b97d0a268fb..dd2b73e1f5e61673ff4b05578f2832e2999fa3c6 100644 (file)
@@ -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]+ +.*
index 30af87535c91efe034b056dbd7c060ddafa396a7..c7a74e398a596fdd6387e26a47cc89ff794c3e86 100644 (file)
@@ -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]+ +.*
index 3c37bcd53586ec58b91cb6de247d27c999f8d4cc..bc582aea1b01a44680c3aee35d00c1a2775eb7de 100644 (file)
@@ -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]+ +.*
index bc07cf89b264c13f1dbc5b545b27c150a3eecd36..c3fddb08e20c7daabd1414f2c0da2d1c4c00e367 100644 (file)
@@ -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]+ +.*