Implement getRelocationAddress for MachO and ET_REL elf files.
authorRafael Espindola <rafael.espindola@gmail.com>
Thu, 3 Apr 2014 23:54:35 +0000 (23:54 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Thu, 3 Apr 2014 23:54:35 +0000 (23:54 +0000)
With that, fix the symbolizer to work with any ELF file.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205588 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Object/ELFObjectFile.h
lib/MC/MCObjectSymbolizer.cpp
lib/Object/MachOObjectFile.cpp
test/Object/Inputs/relocation-dynamic.elf-i386 [new file with mode: 0755]
test/Object/Inputs/relocation-relocatable.elf-i386 [new file with mode: 0644]
test/Object/X86/objdump-disassembly-symbolic.test

index 256f3c7630ca612a827140b8cd3200512ff9138b..302cabaf8eade08fba6655c395368b2eea71b58e 100644 (file)
@@ -555,10 +555,17 @@ ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const {
 template <class ELFT>
 error_code ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel,
                                                      uint64_t &Result) const {
-  assert((EF.getHeader()->e_type == ELF::ET_EXEC ||
-          EF.getHeader()->e_type == ELF::ET_DYN) &&
-         "Only executable and shared objects files have relocation addresses");
-  Result = getROffset(Rel);
+  uint64_t ROffset = getROffset(Rel);
+  const Elf_Ehdr *Header = EF.getHeader();
+
+  if (Header->e_type == ELF::ET_REL) {
+    const Elf_Shdr *RelocationSec = getRelSection(Rel);
+    const Elf_Shdr *RelocatedSec = EF.getSection(RelocationSec->sh_info);
+    Result = ROffset + RelocatedSec->sh_addr;
+  } else {
+    Result = ROffset;
+  }
+
   return object_error::success;
 }
 
index ba80d15653273435a0eadcfa5b7170cbaffb4a04..52d66b8d406cbc951e9fcaeec3f9be027bd962ea 100644 (file)
@@ -257,40 +257,12 @@ void MCObjectSymbolizer::buildSectionList() {
 
 void MCObjectSymbolizer::buildRelocationByAddrMap() {
   for (const SectionRef &Section : Obj->sections()) {
-    section_iterator RelSecI = Section.getRelocatedSection();
-    if (RelSecI == Obj->section_end())
-      continue;
-
-    uint64_t StartAddr; RelSecI->getAddress(StartAddr);
-    uint64_t Size; RelSecI->getSize(Size);
-    bool RequiredForExec;
-    RelSecI->isRequiredForExecution(RequiredForExec);
-    if (RequiredForExec == false || Size == 0)
-      continue;
     for (const RelocationRef &Reloc : Section.relocations()) {
-      // FIXME: libObject is inconsistent regarding error handling. The
-      // overwhelming majority of methods always return object_error::success,
-      // and assert for simple errors.. Here, ELFObjectFile::getRelocationOffset
-      // asserts when the file type isn't ET_REL.
-      // This workaround handles x86-64 elf, the only one that has a relocinfo.
-      uint64_t Offset;
-      if (Obj->isELF()) {
-        const ELF64LEObjectFile *ELFObj = dyn_cast<ELF64LEObjectFile>(Obj);
-        if (ELFObj == 0)
-          break;
-        if (ELFObj->getELFFile()->getHeader()->e_type == ELF::ET_REL) {
-          Reloc.getOffset(Offset);
-          Offset += StartAddr;
-        } else {
-          Reloc.getAddress(Offset);
-        }
-      } else {
-        Reloc.getOffset(Offset);
-        Offset += StartAddr;
-      }
+      uint64_t Address;
+      Reloc.getAddress(Address);
       // At a specific address, only keep the first relocation.
-      if (AddrToReloc.find(Offset) == AddrToReloc.end())
-        AddrToReloc[Offset] = Reloc;
+      if (AddrToReloc.find(Address) == AddrToReloc.end())
+        AddrToReloc[Address] = Reloc;
     }
   }
 }
index dd732aefb0dad61655a85e1a00ab7ab8c9136895..7ce62eb2a4476c8edc7838a63b0675638676f514 100644 (file)
@@ -784,7 +784,15 @@ void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
 
 error_code
 MachOObjectFile::getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const {
-  report_fatal_error("getRelocationAddress not implemented in MachOObjectFile");
+  MachO::any_relocation_info RE = getRelocation(Rel);
+  uint64_t Offset = getAnyRelocationAddress(RE);
+
+  DataRefImpl Sec;
+  Sec.d.a = Rel.d.a;
+  uint64_t SecAddress;
+  getSectionAddress(Sec, SecAddress);
+  Res = SecAddress + Offset;
+  return object_error::success;
 }
 
 error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
diff --git a/test/Object/Inputs/relocation-dynamic.elf-i386 b/test/Object/Inputs/relocation-dynamic.elf-i386
new file mode 100755 (executable)
index 0000000..1548f13
Binary files /dev/null and b/test/Object/Inputs/relocation-dynamic.elf-i386 differ
diff --git a/test/Object/Inputs/relocation-relocatable.elf-i386 b/test/Object/Inputs/relocation-relocatable.elf-i386
new file mode 100644 (file)
index 0000000..b8f375b
Binary files /dev/null and b/test/Object/Inputs/relocation-relocatable.elf-i386 differ
index 858653e95ebc088d17ac458506d51c5fb459f478..95a5fc8e70ac0f53d153ba94b8bd9f3e7630659c 100644 (file)
@@ -46,3 +46,23 @@ MACHO-STUBS-x86-64:     1faa:       e8 09 00 00 00
 MACHO-STUBS-x86-64:     1faf:       8b 44 24 04                                     movl    4(%rsp), %eax
 MACHO-STUBS-x86-64:     1fb3:       48 83 c4 08                                     addq    $8, %rsp
 MACHO-STUBS-x86-64:     1fb7:       c3                                              ret
+
+
+RUN: llvm-objdump -d -symbolize %p/../Inputs/relocation-relocatable.elf-i386 \
+RUN:              | FileCheck %s -check-prefix ELF-i386-REL
+
+ELF-i386-REL: Disassembly of section .text:
+ELF-i386-REL-NEXT: f:
+ELF-i386-REL-NEXT:       0:    e9 fc ff ff ff                  jmp     h
+ELF-i386-REL:      g:
+ELF-i386-REL-NEXT:       5:    e9 fc ff ff ff                  jmp     f
+
+
+RUN: llvm-objdump -d -symbolize %p/../Inputs/relocation-dynamic.elf-i386 \
+RUN:              | FileCheck %s -check-prefix ELF-i386-DYN
+
+ELF-i386-DYN: Disassembly of section .text:
+ELF-i386-DYN-NEXT: f:
+ELF-i386-DYN-NEXT:      1a4:   e9 fc ff ff ff                  jmp     h
+ELF-i386-DYN:      g:
+ELF-i386-DYN-NEXT:      1a9:   e9 fc ff ff ff                  jmp     f