[llvm] d86079f - [llvm-readelf] Print more information for RELR

via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 19 09:22:01 PDT 2024


Author: Fangrui Song
Date: 2024-04-19T09:21:57-07:00
New Revision: d86079f93c9f59d31f2cebb55dce24783070bd77

URL: https://github.com/llvm/llvm-project/commit/d86079f93c9f59d31f2cebb55dce24783070bd77
DIFF: https://github.com/llvm/llvm-project/commit/d86079f93c9f59d31f2cebb55dce24783070bd77.diff

LOG: [llvm-readelf] Print more information for RELR

llvm-readelf/llvm-readobj print RELR as REL relocations with a fixed
type (e.g. `R_*_RELATIVE`). GNU readelf printed only addresses and have
recently switched to a more descritive style that includes a symbolic
address column (symbolized using .symtab/.strtab) (milestone: binutils
2.43).

This patch implements the new GNU style, which seems superior to the
current REL style and essentially obsoletes LLVM-specific --raw-relr
(`printRelrReloc`).

Pull Request: https://github.com/llvm/llvm-project/pull/89162

Added: 
    

Modified: 
    lld/test/ELF/pack-dyn-relocs.s
    lld/test/ELF/partition-pack-dyn-relocs.s
    llvm/test/tools/llvm-readobj/ELF/relr-relocs.test
    llvm/tools/llvm-readobj/ELFDumper.cpp

Removed: 
    


################################################################################
diff  --git a/lld/test/ELF/pack-dyn-relocs.s b/lld/test/ELF/pack-dyn-relocs.s
index dd5d366ae23448..e267147759d4d4 100644
--- a/lld/test/ELF/pack-dyn-relocs.s
+++ b/lld/test/ELF/pack-dyn-relocs.s
@@ -328,31 +328,31 @@
 // RELR64-NEXT:  0000000000030510  0000000200000101 R_AARCH64_ABS64        0000000000000000 zed2 + 0
 // RELR64-EMPTY: 
 // RELR64-NEXT:  Relocation section '.relr.dyn' at offset {{.*}} contains 24 entries:
-// RELR64-NEXT:      Offset             Info             Type               Symbol's Value  Symbol's Name
-// RELR64-NEXT:  0000000000030490  0000000000000403 R_AARCH64_RELATIVE
-// RELR64-NEXT:  0000000000030498  0000000000000403 R_AARCH64_RELATIVE
-// RELR64-NEXT:  00000000000304a0  0000000000000403 R_AARCH64_RELATIVE
-// RELR64-NEXT:  00000000000304a8  0000000000000403 R_AARCH64_RELATIVE
-// RELR64-NEXT:  00000000000304b0  0000000000000403 R_AARCH64_RELATIVE
-// RELR64-NEXT:  00000000000304b8  0000000000000403 R_AARCH64_RELATIVE
-// RELR64-NEXT:  00000000000304c0  0000000000000403 R_AARCH64_RELATIVE
-// RELR64-NEXT:  00000000000304c8  0000000000000403 R_AARCH64_RELATIVE
-// RELR64-NEXT:  00000000000304d8  0000000000000403 R_AARCH64_RELATIVE
-// RELR64-NEXT:  00000000000304e0  0000000000000403 R_AARCH64_RELATIVE
-// RELR64-NEXT:  00000000000304e8  0000000000000403 R_AARCH64_RELATIVE
-// RELR64-NEXT:  00000000000304f0  0000000000000403 R_AARCH64_RELATIVE
-// RELR64-NEXT:  00000000000304f8  0000000000000403 R_AARCH64_RELATIVE
-// RELR64-NEXT:  0000000000030500  0000000000000403 R_AARCH64_RELATIVE
-// RELR64-NEXT:  0000000000030508  0000000000000403 R_AARCH64_RELATIVE
-// RELR64-NEXT:  0000000000030520  0000000000000403 R_AARCH64_RELATIVE
-// RELR64-NEXT:  0000000000030528  0000000000000403 R_AARCH64_RELATIVE
-// RELR64-NEXT:  0000000000030530  0000000000000403 R_AARCH64_RELATIVE
-// RELR64-NEXT:  0000000000030538  0000000000000403 R_AARCH64_RELATIVE
-// RELR64-NEXT:  0000000000030540  0000000000000403 R_AARCH64_RELATIVE
-// RELR64-NEXT:  0000000000030548  0000000000000403 R_AARCH64_RELATIVE
-// RELR64-NEXT:  0000000000030550  0000000000000403 R_AARCH64_RELATIVE
-// RELR64-NEXT:  0000000000030558  0000000000000403 R_AARCH64_RELATIVE
-// RELR64-NEXT:  0000000000030560  0000000000000403 R_AARCH64_RELATIVE
+// RELR64-NEXT:  Symbolic Address
+// RELR64-NEXT:  $d.0{{$}}
+// RELR64-NEXT:  $d.0 + 0x8
+// RELR64-NEXT:  $d.0 + 0x10
+// RELR64-NEXT:  $d.0 + 0x18
+// RELR64-NEXT:  $d.0 + 0x20
+// RELR64-NEXT:  $d.0 + 0x28
+// RELR64-NEXT:  $d.0 + 0x30
+// RELR64-NEXT:  $d.0 + 0x38
+// RELR64-NEXT:  $d.0 + 0x48
+// RELR64-NEXT:  $d.0 + 0x50
+// RELR64-NEXT:  $d.0 + 0x58
+// RELR64-NEXT:  $d.0 + 0x60
+// RELR64-NEXT:  $d.0 + 0x68
+// RELR64-NEXT:  $d.0 + 0x70
+// RELR64-NEXT:  $d.0 + 0x78
+// RELR64-NEXT:  $d.0 + 0x90
+// RELR64-NEXT:  $d.0 + 0x98
+// RELR64-NEXT:  $d.0 + 0xa0
+// RELR64-NEXT:  $d.0 + 0xa8
+// RELR64-NEXT:  $d.0 + 0xb0
+// RELR64-NEXT:  $d.0 + 0xb8
+// RELR64-NEXT:  $d.0 + 0xc0
+// RELR64-NEXT:  $d.0 + 0xc8
+// RELR64-NEXT:  $d.0 + 0xd0
 // RELR64-EMPTY:
 // RELR64-NEXT: Hex dump of section '.data':
 // RELR64-NEXT: 0x00030490 90040300 00000000 91040300 00000000 .

diff  --git a/lld/test/ELF/partition-pack-dyn-relocs.s b/lld/test/ELF/partition-pack-dyn-relocs.s
index 3727bcc21614d8..8127110e348c55 100644
--- a/lld/test/ELF/partition-pack-dyn-relocs.s
+++ b/lld/test/ELF/partition-pack-dyn-relocs.s
@@ -29,9 +29,9 @@
 // CHECK-EMPTY:
 
 // CHECK: Relocation section '.relr.dyn'
-// CHECK-NEXT: Offset
-// PART0-NEXT: 000000000000[[DATA_SEGMENT]]378 {{.*}} R_X86_64_RELATIVE
-// PART1-NEXT: 000000000000[[DATA_SEGMENT]]340 {{.*}} R_X86_64_RELATIVE
+// CHECK-NEXT: Address Symbolic Address
+// PART0-NEXT: 000000000000[[DATA_SEGMENT]]378 p0{{$}}
+// PART1-NEXT: 000000000000[[DATA_SEGMENT]]340 p1{{$}}
 // CHECK-EMPTY:
 
 .section .llvm_sympart,"", at llvm_sympart

diff  --git a/llvm/test/tools/llvm-readobj/ELF/relr-relocs.test b/llvm/test/tools/llvm-readobj/ELF/relr-relocs.test
index 91b148ebb6e3c8..9b59f991c051e2 100644
--- a/llvm/test/tools/llvm-readobj/ELF/relr-relocs.test
+++ b/llvm/test/tools/llvm-readobj/ELF/relr-relocs.test
@@ -47,29 +47,39 @@
 # RAW-GNU1-NEXT: 00000000000f0501
 # RAW-GNU1-NEXT: 000a700550400009
 
-# RUN: llvm-readelf --relocations %t1 | FileCheck --check-prefix=GNU1 %s
-# GNU1:      Relocation section '.relr.dyn' at offset 0x40 contains 21 entries:
-# GNU1:      0000000000010d60  0000000000000008 R_X86_64_RELATIVE
-# GNU1-NEXT: 0000000000010d68  0000000000000008 R_X86_64_RELATIVE
-# GNU1-NEXT: 0000000000010da0  0000000000000008 R_X86_64_RELATIVE
-# GNU1-NEXT: 0000000000020000  0000000000000008 R_X86_64_RELATIVE
-# GNU1-NEXT: 0000000000020040  0000000000000008 R_X86_64_RELATIVE
-# GNU1-NEXT: 0000000000020050  0000000000000008 R_X86_64_RELATIVE
-# GNU1-NEXT: 0000000000020080  0000000000000008 R_X86_64_RELATIVE
-# GNU1-NEXT: 0000000000020088  0000000000000008 R_X86_64_RELATIVE
-# GNU1-NEXT: 0000000000020090  0000000000000008 R_X86_64_RELATIVE
-# GNU1-NEXT: 0000000000020098  0000000000000008 R_X86_64_RELATIVE
-# GNU1-NEXT: 0000000000020210  0000000000000008 R_X86_64_RELATIVE
-# GNU1-NEXT: 00000000000202a8  0000000000000008 R_X86_64_RELATIVE
-# GNU1-NEXT: 00000000000202d8  0000000000000008 R_X86_64_RELATIVE
-# GNU1-NEXT: 00000000000202e8  0000000000000008 R_X86_64_RELATIVE
-# GNU1-NEXT: 00000000000202f8  0000000000000008 R_X86_64_RELATIVE
-# GNU1-NEXT: 0000000000020308  0000000000000008 R_X86_64_RELATIVE
-# GNU1-NEXT: 0000000000020358  0000000000000008 R_X86_64_RELATIVE
-# GNU1-NEXT: 0000000000020360  0000000000000008 R_X86_64_RELATIVE
-# GNU1-NEXT: 0000000000020368  0000000000000008 R_X86_64_RELATIVE
-# GNU1-NEXT: 0000000000020380  0000000000000008 R_X86_64_RELATIVE
-# GNU1-NEXT: 0000000000020390  0000000000000008 R_X86_64_RELATIVE
+# RUN: llvm-readelf --relocations %t1 | FileCheck --check-prefix=GNU1 --match-full-lines --strict-whitespace %s
+#      GNU1:Relocation section '.relr.dyn' at offset 0x40 contains 21 entries:
+# GNU1-NEXT:Index: Entry            Address           Symbolic Address
+# GNU1-NEXT:0000:  0000000000010d60 0000000000010d60
+# GNU1-NEXT:0001:  0000000000000103 0000000000010d68
+# GNU1-NEXT:                        0000000000010da0  base + 0x30
+# GNU1-NEXT:0002:  0000000000020000 0000000000020000  foo
+# GNU1-NEXT:0003:  00000000000f0501 0000000000020040  foo + 0x40
+# GNU1-NEXT:                        0000000000020050  foo + 0x50
+# GNU1-NEXT:                        0000000000020080  foo + 0x80
+# GNU1-NEXT:                        0000000000020088  foo + 0x88
+# GNU1-NEXT:                        0000000000020090  foo + 0x90
+# GNU1-NEXT:                        0000000000020098  foo + 0x98
+# GNU1-NEXT:0004:  000a700550400009 0000000000020210  bar + 0x10
+# GNU1-NEXT:                        00000000000202a8  bar + 0xa8
+# GNU1-NEXT:                        00000000000202d8  bar + 0xd8
+# GNU1-NEXT:                        00000000000202e8  bar + 0xe8
+# GNU1-NEXT:                        00000000000202f8  bar + 0xf8
+# GNU1-NEXT:                        0000000000020308  bar + 0x108
+# GNU1-NEXT:                        0000000000020358  bar + 0x158
+# GNU1-NEXT:                        0000000000020360  bar + 0x160
+# GNU1-NEXT:                        0000000000020368  bar + 0x168
+# GNU1-NEXT:                        0000000000020380  bar + 0x180
+# GNU1-NEXT:                        0000000000020390  bar + 0x190
+#  GNU1-NOT:{{.}}
+
+## The addresses are not symbolized in the absence of .symtab.
+# RUN: llvm-objcopy --strip-all %t1 %t1.stripped
+# RUN: llvm-readelf --relocations %t1.stripped | FileCheck --check-prefix=GNU1S --match-full-lines --strict-whitespace %s
+#      GNU1S:Relocation section '.relr.dyn' at offset 0x40 contains 21 entries:
+# GNU1S-NEXT:Index: Entry            Address           Symbolic Address
+# GNU1S-NEXT:0000:  0000000000010d60 0000000000010d60
+# GNU1S-NEXT:0001:  0000000000000103 0000000000010d68
 
 --- !ELF
 FileHeader:
@@ -83,6 +93,18 @@ Sections:
     Flags: [ SHF_ALLOC ]
     Entries: [ 0x0000000000010D60, 0x0000000000000103, 0x0000000000020000,
                0x00000000000F0501, 0x000A700550400009 ]
+Symbols:
+  - Name:    bar
+    Value:   0x20200
+    Section: .relr.dyn
+  - Name:    foo
+    Value:   0x20000
+    Section: .relr.dyn
+  - Name:    base
+    Value:   0x10d70
+    Section: .relr.dyn
+  - Name:    ignored
+    Value:   0x20210
 
 # RUN: yaml2obj --docnum=2 %s -o %t2
 # RUN: llvm-readobj --relocations --raw-relr %t2 | \
@@ -124,22 +146,24 @@ Sections:
 # RAW-GNU2-NEXT: 000f0501
 # RAW-GNU2-NEXT: 50400009
 
-# RUN: llvm-readelf --relocations %t2 | FileCheck --check-prefix=GNU2 %s
-# GNU2:      Relocation section '.relr.dyn' at offset 0x34 contains 14 entries:
-# GNU2:      00010d60  00000008 R_386_RELATIVE
-# GNU2-NEXT: 00010d64  00000008 R_386_RELATIVE
-# GNU2-NEXT: 00010d80  00000008 R_386_RELATIVE
-# GNU2-NEXT: 00020000  00000008 R_386_RELATIVE
-# GNU2-NEXT: 00020020  00000008 R_386_RELATIVE
-# GNU2-NEXT: 00020028  00000008 R_386_RELATIVE
-# GNU2-NEXT: 00020040  00000008 R_386_RELATIVE
-# GNU2-NEXT: 00020044  00000008 R_386_RELATIVE
-# GNU2-NEXT: 00020048  00000008 R_386_RELATIVE
-# GNU2-NEXT: 0002004c  00000008 R_386_RELATIVE
-# GNU2-NEXT: 00020088  00000008 R_386_RELATIVE
-# GNU2-NEXT: 000200d4  00000008 R_386_RELATIVE
-# GNU2-NEXT: 000200ec  00000008 R_386_RELATIVE
-# GNU2-NEXT: 000200f4  00000008 R_386_RELATIVE
+# RUN: llvm-readelf --relocations %t2 | FileCheck --check-prefix=GNU2 --match-full-lines --strict-whitespace %s
+#      GNU2:Relocation section '.relr.dyn' at offset 0x34 contains 14 entries:
+# GNU2-NEXT:Index: Entry    Address   Symbolic Address
+# GNU2-NEXT:0000:  00010d60 00010d60  .relr.dyn
+# GNU2-NEXT:0001:  00000103 00010d64  .relr.dyn + 0x4
+# GNU2-NEXT:                00010d80  .relr.dyn + 0x20
+# GNU2-NEXT:0002:  00020000 00020000  .relr.dyn + 0xf2a0
+# GNU2-NEXT:0003:  000f0501 00020020  .relr.dyn + 0xf2c0
+# GNU2-NEXT:                00020028  .relr.dyn + 0xf2c8
+# GNU2-NEXT:                00020040  .relr.dyn + 0xf2e0
+# GNU2-NEXT:                00020044  .relr.dyn + 0xf2e4
+# GNU2-NEXT:                00020048  .relr.dyn + 0xf2e8
+# GNU2-NEXT:                0002004c  .relr.dyn + 0xf2ec
+# GNU2-NEXT:0004:  50400009 00020088  .relr.dyn + 0xf328
+# GNU2-NEXT:                000200d4  .relr.dyn + 0xf374
+# GNU2-NEXT:                000200ec  .relr.dyn + 0xf38c
+# GNU2-NEXT:                000200f4  .relr.dyn + 0xf394
+# GNU2-NOT:{{.}}
 
 --- !ELF
 FileHeader:
@@ -156,6 +180,11 @@ Sections:
     EntSize: [[ENTSIZE=<none>]]
     ShType:  [[SHTYPE=<none>]]
     Link:    [[LINK=<none>]]
+Symbols:
+  - Name:    .relr.dyn
+    Type:    STT_SECTION
+    Value:   0x10D60
+    Section: .relr.dyn
 
 ## Check we report a warning when we are unable to dump relocations
 ## for a SHT_RELR/SHT_ANDROID_RELR/SHT_AARCH64_AUTH_RELR section.
@@ -175,7 +204,6 @@ Sections:
 
 # BROKEN-GNU:      warning: '[[FILE]]': unable to get the number of relocations in [[SECNAME]] section with index 1: section [index 1] has invalid sh_entsize: expected 4, but got 1
 # BROKEN-GNU:      Relocation section '.relr.dyn' at offset 0x34 contains <?> entries:
-# BROKEN-GNU-NEXT:  Offset     Info    Type                Sym. Value  Symbol's Name
 # BROKEN-GNU-NEXT: warning: '[[FILE]]': unable to read relocations from [[SECNAME]] section with index 1: section [index 1] has invalid sh_entsize: expected 4, but got 1
 
 ## Case B: check the case when relocations can't be read from an SHT_ANDROID_RELR section.
@@ -218,3 +246,36 @@ Sections:
 # RUN:   FileCheck -DFILE=%t2.has.link --check-prefix=RAW-LLVM2 %s
 # RUN: llvm-readelf --relocations --raw-relr %t2.has.link 2>&1 | \
 # RUN:   FileCheck -DFILE=%t2.has.link --check-prefix=RAW-GNU2 %s
+
+## .symtab is invalid. Check we report a warning and print entries without symbolization.
+# RUN: yaml2obj --docnum=3 -DENTSIZE=1 %s -o %t3.err1
+# RUN: llvm-readelf -r %t3.err1 2>&1 | FileCheck -DFILE=%t3.err1 --check-prefixes=GNU3,GNU3-ERR1 --match-full-lines %s
+# RUN: yaml2obj --docnum=3 -DLINK=0xff %s -o %t3.err2
+# RUN: llvm-readelf -r %t3.err2 2>&1 | FileCheck -DFILE=%t3.err2 --check-prefixes=GNU3,GNU3-ERR2 --match-full-lines %s
+
+#      GNU3:Index: Entry            Address           Symbolic Address
+# GNU3-ERR1-NEXT:{{.*}}warning: '[[FILE]]': unable to read symbols from the SHT_SYMTAB section: section [index 2] has invalid sh_entsize: expected 24, but got 1
+# GNU3-ERR2-NEXT:{{.*}}warning: '[[FILE]]': unable to get the string table for the SHT_SYMTAB section: invalid section index: 255
+# GNU3-NEXT:0000:  0000000000010d60 0000000000010d60
+# GNU3-NEXT:0001:  0000000000000103 0000000000010d68
+# GNU3-NEXT:                        0000000000010da0
+#  GNU3-NOT:{{.}}
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_DYN
+  Machine: EM_X86_64
+Sections:
+  - Name:  .relr.dyn
+    Type:  SHT_RELR
+    Flags: [ SHF_ALLOC ]
+    Entries: [ 0x0000000000010D60, 0x0000000000000103 ]
+  - Name:    .symtab
+    Type:    SHT_SYMTAB
+    Link:    [[LINK=.strtab]]
+    EntSize: [[ENTSIZE=0x18]]
+Symbols:
+  - Name:  bar
+    Value: 0x10D60

diff  --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index 1108672003fc76..f145653ac743c5 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -411,6 +411,7 @@ template <typename ELFT> class ELFDumper : public ObjDumper {
   std::string getStaticSymbolName(uint32_t Index) const;
   StringRef getDynamicString(uint64_t Value) const;
 
+  std::pair<Elf_Sym_Range, std::optional<StringRef>> getSymtabAndStrtab() const;
   void printSymbolsHelper(bool IsDynamic, bool ExtraSymInfo) const;
   std::string getDynamicEntry(uint64_t Type, uint64_t Value) const;
 
@@ -512,6 +513,28 @@ ELFDumper<ELFT>::getVersionTable(const Elf_Shdr &Sec, ArrayRef<Elf_Sym> *SymTab,
   return *VersionsOrErr;
 }
 
+template <class ELFT>
+std::pair<typename ELFDumper<ELFT>::Elf_Sym_Range, std::optional<StringRef>>
+ELFDumper<ELFT>::getSymtabAndStrtab() const {
+  assert(DotSymtabSec);
+  Elf_Sym_Range Syms(nullptr, nullptr);
+  std::optional<StringRef> StrTable;
+  if (Expected<StringRef> StrTableOrErr =
+          Obj.getStringTableForSymtab(*DotSymtabSec))
+    StrTable = *StrTableOrErr;
+  else
+    reportUniqueWarning(
+        "unable to get the string table for the SHT_SYMTAB section: " +
+        toString(StrTableOrErr.takeError()));
+
+  if (Expected<Elf_Sym_Range> SymsOrErr = Obj.symbols(DotSymtabSec))
+    Syms = *SymsOrErr;
+  else
+    reportUniqueWarning("unable to read symbols from the SHT_SYMTAB section: " +
+                        toString(SymsOrErr.takeError()));
+  return {Syms, StrTable};
+}
+
 template <class ELFT>
 void ELFDumper<ELFT>::printSymbolsHelper(bool IsDynamic,
                                          bool ExtraSymInfo) const {
@@ -525,20 +548,7 @@ void ELFDumper<ELFT>::printSymbolsHelper(bool IsDynamic,
     Syms = dynamic_symbols();
     Entries = Syms.size();
   } else if (DotSymtabSec) {
-    if (Expected<StringRef> StrTableOrErr =
-            Obj.getStringTableForSymtab(*DotSymtabSec))
-      StrTable = *StrTableOrErr;
-    else
-      reportUniqueWarning(
-          "unable to get the string table for the SHT_SYMTAB section: " +
-          toString(StrTableOrErr.takeError()));
-
-    if (Expected<Elf_Sym_Range> SymsOrErr = Obj.symbols(DotSymtabSec))
-      Syms = *SymsOrErr;
-    else
-      reportUniqueWarning(
-          "unable to read symbols from the SHT_SYMTAB section: " +
-          toString(SymsOrErr.takeError()));
+    std::tie(Syms, StrTable) = getSymtabAndStrtab();
     Entries = DotSymtabSec->getEntityCount();
   }
   if (Syms.empty())
@@ -658,6 +668,7 @@ template <typename ELFT> class GNUELFDumper : public ELFDumper<ELFT> {
   void printHashedSymbol(const Elf_Sym *Sym, unsigned SymIndex,
                          DataRegion<Elf_Word> ShndxTable, StringRef StrTable,
                          uint32_t Bucket);
+  void printRelr(const Elf_Shdr &Sec);
   void printRelrReloc(const Elf_Relr &R) override;
   void printRelRelaReloc(const Relocation<ELFT> &R,
                          const RelSymbol<ELFT> &RelSym) override;
@@ -3882,6 +3893,12 @@ static bool isRelocationSec(const typename ELFT::Shdr &Sec,
 }
 
 template <class ELFT> void GNUELFDumper<ELFT>::printRelocations() {
+  auto PrintAsRelr = [&](const Elf_Shdr &Sec) {
+    return !opts::RawRelr && (Sec.sh_type == ELF::SHT_RELR ||
+                              Sec.sh_type == ELF::SHT_ANDROID_RELR ||
+                              (this->Obj.getHeader().e_machine == EM_AARCH64 &&
+                               Sec.sh_type == ELF::SHT_AARCH64_AUTH_RELR));
+  };
   auto GetEntriesNum = [&](const Elf_Shdr &Sec) -> Expected<size_t> {
     // Android's packed relocation section needs to be unpacked first
     // to get the actual number of entries.
@@ -3894,10 +3911,7 @@ template <class ELFT> void GNUELFDumper<ELFT>::printRelocations() {
       return RelasOrErr->size();
     }
 
-    if (!opts::RawRelr &&
-        (Sec.sh_type == ELF::SHT_RELR || Sec.sh_type == ELF::SHT_ANDROID_RELR ||
-         (this->Obj.getHeader().e_machine == EM_AARCH64 &&
-          Sec.sh_type == ELF::SHT_AARCH64_AUTH_RELR))) {
+    if (PrintAsRelr(Sec)) {
       Expected<Elf_Relr_Range> RelrsOrErr = this->Obj.relrs(Sec);
       if (!RelrsOrErr)
         return RelrsOrErr.takeError();
@@ -3926,13 +3940,89 @@ template <class ELFT> void GNUELFDumper<ELFT>::printRelocations() {
     OS << "\nRelocation section '" << Name << "' at offset 0x"
        << utohexstr(Offset, /*LowerCase=*/true) << " contains " << EntriesNum
        << " entries:\n";
-    printRelocHeaderFields<ELFT>(OS, Sec.sh_type, this->Obj.getHeader());
-    this->printRelocationsHelper(Sec);
+
+    if (PrintAsRelr(Sec)) {
+      printRelr(Sec);
+    } else {
+      printRelocHeaderFields<ELFT>(OS, Sec.sh_type, this->Obj.getHeader());
+      this->printRelocationsHelper(Sec);
+    }
   }
   if (!HasRelocSections)
     OS << "\nThere are no relocations in this file.\n";
 }
 
+template <class ELFT> void GNUELFDumper<ELFT>::printRelr(const Elf_Shdr &Sec) {
+  Expected<Elf_Relr_Range> RangeOrErr = this->Obj.relrs(Sec);
+  if (!RangeOrErr) {
+    this->reportUniqueWarning("unable to read relocations from " +
+                              this->describe(Sec) + ": " +
+                              toString(RangeOrErr.takeError()));
+    return;
+  }
+  if (ELFT::Is64Bits)
+    OS << "Index: Entry            Address           Symbolic Address\n";
+  else
+    OS << "Index: Entry    Address   Symbolic Address\n";
+
+  // If .symtab is available, collect its defined symbols and sort them by
+  // st_value.
+  SmallVector<std::pair<uint64_t, std::string>, 0> Syms;
+  if (this->DotSymtabSec) {
+    Elf_Sym_Range Symtab;
+    std::optional<StringRef> Strtab;
+    std::tie(Symtab, Strtab) = this->getSymtabAndStrtab();
+    if (Symtab.size() && Strtab) {
+      for (auto [I, Sym] : enumerate(Symtab)) {
+        if (!Sym.st_shndx)
+          continue;
+        Syms.emplace_back(Sym.st_value,
+                          this->getFullSymbolName(Sym, I, ArrayRef<Elf_Word>(),
+                                                  *Strtab, false));
+      }
+    }
+  }
+  llvm::stable_sort(Syms);
+
+  typename ELFT::uint Base = 0;
+  size_t I = 0;
+  auto Print = [&](uint64_t Where) {
+    OS << format_hex_no_prefix(Where, ELFT::Is64Bits ? 16 : 8);
+    for (; I < Syms.size() && Syms[I].first <= Where; ++I)
+      ;
+    // Try symbolizing the address. Find the nearest symbol before or at the
+    // address and print the symbol and the address 
diff erence.
+    if (I) {
+      OS << "  " << Syms[I - 1].second;
+      if (Syms[I - 1].first < Where)
+        OS << " + 0x" << Twine::utohexstr(Where - Syms[I - 1].first);
+    }
+    OS << '\n';
+  };
+  for (auto [Index, R] : enumerate(*RangeOrErr)) {
+    typename ELFT::uint Entry = R;
+    OS << formatv("{0:4}:  ", Index)
+       << format_hex_no_prefix(Entry, ELFT::Is64Bits ? 16 : 8) << ' ';
+    if ((Entry & 1) == 0) {
+      Print(Entry);
+      Base = Entry + sizeof(typename ELFT::uint);
+    } else {
+      bool First = true;
+      for (auto Where = Base; Entry >>= 1;
+           Where += sizeof(typename ELFT::uint)) {
+        if (Entry & 1) {
+          if (First)
+            First = false;
+          else
+            OS.indent(ELFT::Is64Bits ? 24 : 16);
+          Print(Where);
+        }
+      }
+      Base += (CHAR_BIT * sizeof(Entry) - 1) * sizeof(typename ELFT::uint);
+    }
+  }
+}
+
 // Print the offset of a particular section from anyone of the ranges:
 // [SHT_LOOS, SHT_HIOS], [SHT_LOPROC, SHT_HIPROC], [SHT_LOUSER, SHT_HIUSER].
 // If 'Type' does not fall within any of those ranges, then a string is


        


More information about the llvm-commits mailing list