OSDN Git Service

[llvm-readobj] - Don't abort when dumping dynamic relocations when an object has...
authorGeorgii Rymar <grimar@accesssoftek.com>
Mon, 6 Jul 2020 15:07:35 +0000 (18:07 +0300)
committerGeorgii Rymar <grimar@accesssoftek.com>
Tue, 7 Jul 2020 13:14:51 +0000 (16:14 +0300)
Currently, llvm-readobj calls `report_fatal_error` when an object has
both REL and RELA dynamic relocations.

llvm-readelf is able to handle this case properly. This patch adds such a test case
and adjusts the llvm-readobj code to follow (and be consistent with its own RELR and PLTREL cases).

Differential revision: https://reviews.llvm.org/D83232

llvm/test/tools/llvm-readobj/ELF/broken-dynamic-reloc.test
llvm/tools/llvm-readobj/ELFDumper.cpp

index e13492e..5313ae7 100644 (file)
@@ -463,3 +463,64 @@ ProgramHeaders:
     Sections:
       - Section: .rela.dyn
       - Section: .dynamic
+
+## Show that when we have both REL and RELA relocations, we dump both sets.
+# RUN: yaml2obj --docnum=13 %s -o %t13
+# RUN: llvm-readobj --dyn-relocations %t13 2>&1 | FileCheck %s -DFILE=%t13 --check-prefix=BOTH-RELA-REL-LLVM
+# RUN: llvm-readelf --dyn-relocations %t13 2>&1 | FileCheck %s -DFILE=%t13 --check-prefix=BOTH-RELA-REL-GNU
+
+# BOTH-RELA-REL-LLVM:      Dynamic Relocations {
+# BOTH-RELA-REL-LLVM-NEXT:   0x1 R_X86_64_NONE - 0x0
+# BOTH-RELA-REL-LLVM-NEXT:   0x2 R_X86_64_NONE - 0x0
+# BOTH-RELA-REL-LLVM-NEXT: }
+
+# BOTH-RELA-REL-GNU:       'RELA' relocation section at offset 0x78 contains 24 bytes:
+# BOTH-RELA-REL-GNU-NEXT:    Offset             Info             Type               Symbol's Value  Symbol's Name + Addend
+# BOTH-RELA-REL-GNU-NEXT:  0000000000000001  0000000000000000 R_X86_64_NONE                     0
+# BOTH-RELA-REL-GNU-EMPTY:
+# BOTH-RELA-REL-GNU:       'REL' relocation section at offset 0x90 contains 16 bytes:
+# BOTH-RELA-REL-GNU-NEXT:    Offset             Info             Type               Symbol's Value  Symbol's Name
+# BOTH-RELA-REL-GNU-NEXT:  0000000000000002  0000000000000000 R_X86_64_NONE
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_DYN
+  Machine: EM_X86_64
+Sections:
+  - Name: .rela.dyn
+    Type: SHT_RELA
+    Relocations:
+      - Type:   R_X86_64_NONE
+        Offset: 0x1
+  - Name: .rel.dyn
+    Type: SHT_REL
+    Relocations:
+      - Type: R_X86_64_NONE
+        Offset: 0x2
+  - Name: .dynamic
+    Type: SHT_DYNAMIC
+    Entries:
+      - Tag:   DT_RELA
+        Value: 0x0
+      - Tag:   DT_RELASZ
+        Value: 0x18
+      - Tag:   DT_RELAENT
+        Value: 0x18
+## 0x18 == offset of .rel.dyn == size of .rela.dyn section.
+      - Tag:   DT_REL
+        Value: 0x18
+      - Tag:   DT_RELSZ
+        Value: 0x10
+      - Tag:   DT_RELENT
+        Value: 0x10
+      - Tag:   DT_NULL
+        Value: 0x0
+DynamicSymbols: []
+ProgramHeaders:
+  - Type:  PT_LOAD
+    Sections:
+      - Section: .rela.dyn
+      - Section: .rel.dyn
+      - Section: .dynamic
index 247dfd9..7b19cfd 100644 (file)
@@ -6401,14 +6401,14 @@ void LLVMStyle<ELFT>::printDynamicRelocations(const ELFO *Obj) {
   const DynRegionInfo &DynRelaRegion = this->dumper()->getDynRelaRegion();
   const DynRegionInfo &DynRelrRegion = this->dumper()->getDynRelrRegion();
   const DynRegionInfo &DynPLTRelRegion = this->dumper()->getDynPLTRelRegion();
-  if (DynRelRegion.Size && DynRelaRegion.Size)
-    report_fatal_error("There are both REL and RELA dynamic relocations");
+
   W.startLine() << "Dynamic Relocations {\n";
   W.indent();
-  if (DynRelaRegion.Size > 0)
+  if (DynRelaRegion.Size > 0) {
     for (const Elf_Rela &Rela : this->dumper()->dyn_relas())
       printDynamicRelocation(Obj, Rela);
-  else
+  }
+  if (DynRelRegion.Size > 0) {
     for (const Elf_Rel &Rel : this->dumper()->dyn_rels()) {
       Elf_Rela Rela;
       Rela.r_offset = Rel.r_offset;
@@ -6416,6 +6416,8 @@ void LLVMStyle<ELFT>::printDynamicRelocations(const ELFO *Obj) {
       Rela.r_addend = 0;
       printDynamicRelocation(Obj, Rela);
     }
+  }
+
   if (DynRelrRegion.Size > 0) {
     Elf_Relr_Range Relrs = this->dumper()->dyn_relrs();
     std::vector<Elf_Rela> RelrRelas =