Clarify getRelocationAddress x getRelocationOffset a bit.
authorRafael Espindola <rafael.espindola@gmail.com>
Thu, 25 Apr 2013 12:28:45 +0000 (12:28 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Thu, 25 Apr 2013 12:28:45 +0000 (12:28 +0000)
getRelocationAddress is for dynamic libraries and executables,
getRelocationOffset for relocatable objects.

Mark the getRelocationAddress of COFF and MachO as not implemented yet. Add a
test of ELF's. llvm-readobj -r now prints the same values as readelf -r.

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

include/llvm/Object/ELF.h
include/llvm/Object/RelocVisitor.h
lib/DebugInfo/DWARFContext.cpp
lib/Object/COFFObjectFile.cpp
lib/Object/MachOObjectFile.cpp
test/Object/Inputs/hello-world.elf-x86-64 [new file with mode: 0755]
test/Object/relocation-executable.test [new file with mode: 0644]
tools/llvm-objdump/MachODump.cpp
tools/llvm-objdump/llvm-objdump.cpp
tools/llvm-readobj/ELFDumper.cpp
tools/llvm-readobj/llvm-readobj.cpp

index 02840230f5c03e64d07c76890e1d1e5a138ea224..4f0e5b8db8ff80818ff77c953ea9a7c5761e1b1b 100644 (file)
@@ -607,6 +607,8 @@ private:
   mutable const char *dt_soname;
 
 private:
+  uint64_t getROffset(DataRefImpl Rel) const;
+
   // Records for each version index the corresponding Verdef or Vernaux entry.
   // This is filled the first time LoadVersionMap() is called.
   class VersionMapEntry : public PointerIntPair<const void*, 1> {
@@ -1521,45 +1523,32 @@ error_code ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel,
 template<class ELFT>
 error_code ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel,
                                                      uint64_t &Result) const {
-  uint64_t offset;
-  const Elf_Shdr *sec = getSection(Rel.w.b);
-  switch (sec->sh_type) {
-    default :
-      report_fatal_error("Invalid section type in Rel!");
-    case ELF::SHT_REL : {
-      offset = getRel(Rel)->r_offset;
-      break;
-    }
-    case ELF::SHT_RELA : {
-      offset = getRela(Rel)->r_offset;
-      break;
-    }
-  }
-
-  Result = offset;
+  assert((Header->e_type == ELF::ET_EXEC || Header->e_type == ELF::ET_DYN) &&
+         "Only executable and shared objects files have addresses");
+  Result = getROffset(Rel);
   return object_error::success;
 }
 
 template<class ELFT>
 error_code ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel,
                                                     uint64_t &Result) const {
-  uint64_t offset;
+  assert(Header->e_type == ELF::ET_REL &&
+         "Only relocatable object files have relocation offsets");
+  Result = getROffset(Rel);
+  return object_error::success;
+}
+
+template<class ELFT>
+uint64_t ELFObjectFile<ELFT>::getROffset(DataRefImpl Rel) const {
   const Elf_Shdr *sec = getSection(Rel.w.b);
   switch (sec->sh_type) {
-    default :
-      report_fatal_error("Invalid section type in Rel!");
-    case ELF::SHT_REL : {
-      offset = getRel(Rel)->r_offset;
-      break;
-    }
-    case ELF::SHT_RELA : {
-      offset = getRela(Rel)->r_offset;
-      break;
-    }
+  default:
+    report_fatal_error("Invalid section type in Rel!");
+  case ELF::SHT_REL:
+    return getRel(Rel)->r_offset;
+  case ELF::SHT_RELA:
+    return getRela(Rel)->r_offset;
   }
-
-  Result = offset - sec->sh_addr;
-  return object_error::success;
 }
 
 template<class ELFT>
index 2dcbdf905327dd8a8e9b1b0e3e92e9ff0c258130..59d810763f29e22c8723479de0be24f3feeb7860 100644 (file)
@@ -133,7 +133,7 @@ private:
     int64_t Addend;
     R.getAdditionalInfo(Addend);
     uint64_t Address;
-    R.getAddress(Address);
+    R.getOffset(Address);
     return RelocToApply(Value + Addend - Address, 4);
   }
 
@@ -151,7 +151,7 @@ private:
     int64_t Addend;
     R.getAdditionalInfo(Addend);
     uint64_t Address;
-    R.getAddress(Address);
+    R.getOffset(Address);
     return RelocToApply(Value + Addend - Address, 4);
   }
   RelocToApply visitELF_X86_64_32(RelocationRef R, uint64_t Value) {
index 1e13731361a0d78da1fb9ea540de4b46de5c571c..e5daf55982f7d7085d0faa8376bc4b37b463d75c 100644 (file)
@@ -572,7 +572,7 @@ DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) :
              reloc_e = i->end_relocations();
            reloc_i != reloc_e; reloc_i.increment(ec)) {
         uint64_t Address;
-        reloc_i->getAddress(Address);
+        reloc_i->getOffset(Address);
         uint64_t Type;
         reloc_i->getType(Type);
         uint64_t SymAddr = 0;
index 46acd4d5370244f888a19cf94293a1bc23bee6b3..70fec321ba3ec61cf45de0a5756e25716422004e 100644 (file)
@@ -705,8 +705,7 @@ error_code COFFObjectFile::getRelocationNext(DataRefImpl Rel,
 }
 error_code COFFObjectFile::getRelocationAddress(DataRefImpl Rel,
                                                 uint64_t &Res) const {
-  Res = toRel(Rel)->VirtualAddress;
-  return object_error::success;
+  report_fatal_error("getRelocationAddress not implemented in COFFObjectFile");
 }
 error_code COFFObjectFile::getRelocationOffset(DataRefImpl Rel,
                                                uint64_t &Res) const {
index 51cd5b9a95d746d9a25e1da66e7226ab111da5f5..14bca2bf901f9eebd83807f7bbbf0c40c387b215 100644 (file)
@@ -789,21 +789,7 @@ MachOObjectFile::getSectionRelEnd(DataRefImpl Sec) const {
 
 error_code
 MachOObjectFile::getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const {
-  uint64_t SectAddress;
-  DataRefImpl Sec;
-  Sec.d.a = Rel.d.b;
-  if (is64Bit()) {
-    macho::Section64 Sect = getSection64(Sec);
-    SectAddress = Sect.Address;
-  } else {
-    macho::Section Sect = getSection(Sec);
-    SectAddress = Sect.Address;
-  }
-
-  macho::RelocationEntry RE = getRelocation(Rel);
-  uint64_t RelAddr = getAnyRelocationAddress(RE);
-  Res = SectAddress + RelAddr;
-  return object_error::success;
+  report_fatal_error("getRelocationAddress not implemented in MachOObjectFile");
 }
 
 error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
diff --git a/test/Object/Inputs/hello-world.elf-x86-64 b/test/Object/Inputs/hello-world.elf-x86-64
new file mode 100755 (executable)
index 0000000..16092b8
Binary files /dev/null and b/test/Object/Inputs/hello-world.elf-x86-64 differ
diff --git a/test/Object/relocation-executable.test b/test/Object/relocation-executable.test
new file mode 100644 (file)
index 0000000..98f5b4e
--- /dev/null
@@ -0,0 +1,18 @@
+RUN: llvm-readobj -r -expand-relocs %p/Inputs/hello-world.elf-x86-64 \
+RUN:   | FileCheck %s
+
+// CHECK:     Relocations [
+// CHECK:       Section (11) .plt {
+// CHECK-NEXT:    Relocation {
+// CHECK-NEXT:      Offset: 0x4018F8
+// CHECK-NEXT:      Type: R_X86_64_JUMP_SLOT (7)
+// CHECK-NEXT:      Symbol: __libc_start_main
+// CHECK-NEXT:      Info: 0x0
+// CHECK-NEXT:    }
+// CHECK-NEXT:    Relocation {
+// CHECK-NEXT:      Offset: 0x401900
+// CHECK-NEXT:      Type: R_X86_64_JUMP_SLOT (7)
+// CHECK-NEXT:      Symbol: puts
+// CHECK-NEXT:      Info: 0x0
+// CHECK-NEXT:    }
+// CHECK-NEXT:  }
index d78d7f31a6cac9bce10aaa9ffa2e4caeb03eb763..6797e2dc5b868a204bfe2f5380e75fe50cc8a8da 100644 (file)
@@ -343,7 +343,7 @@ static void DisassembleInputMachO2(StringRef Filename,
     for (relocation_iterator RI = Sections[SectIdx].begin_relocations(),
          RE = Sections[SectIdx].end_relocations(); RI != RE; RI.increment(ec)) {
       uint64_t RelocOffset, SectionAddress;
-      RI->getAddress(RelocOffset);
+      RI->getOffset(RelocOffset);
       Sections[SectIdx].getAddress(SectionAddress);
       RelocOffset -= SectionAddress;
 
index 99855995651e7ee68492f1a341af0383787d8154..247b90f03003c95b280547f816b2c5a0cb11a57a 100644 (file)
@@ -186,8 +186,8 @@ void llvm::DumpBytes(StringRef bytes) {
 
 bool llvm::RelocAddressLess(RelocationRef a, RelocationRef b) {
   uint64_t a_addr, b_addr;
-  if (error(a.getAddress(a_addr))) return false;
-  if (error(b.getAddress(b_addr))) return false;
+  if (error(a.getOffset(a_addr))) return false;
+  if (error(b.getOffset(b_addr))) return false;
   return a_addr < b_addr;
 }
 
@@ -378,7 +378,7 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
           if (error(rel_cur->getHidden(hidden))) goto skip_print_rel;
           if (hidden) goto skip_print_rel;
 
-          if (error(rel_cur->getAddress(addr))) goto skip_print_rel;
+          if (error(rel_cur->getOffset(addr))) goto skip_print_rel;
           // Stop when rel_cur's address is past the current instruction.
           if (addr >= Index + Size) break;
           if (error(rel_cur->getTypeName(name))) goto skip_print_rel;
@@ -417,7 +417,7 @@ static void PrintRelocations(const ObjectFile *o) {
       if (error(ri->getHidden(hidden))) continue;
       if (hidden) continue;
       if (error(ri->getTypeName(relocname))) continue;
-      if (error(ri->getAddress(address))) continue;
+      if (error(ri->getOffset(address))) continue;
       if (error(ri->getValueString(valuestr))) continue;
       outs() << address << " " << relocname << " " << valuestr << "\n";
     }
index f771cbdd52b5062194c2acf6fc5e089851ed8c25..ea1b83f32f130ccdb78b2a88336467331c786457 100644 (file)
@@ -582,7 +582,11 @@ void ELFDumper<ELFT>::printRelocation(section_iterator Sec,
   int64_t Info;
   StringRef SymbolName;
   SymbolRef Symbol;
-  if (error(RelI->getOffset(Offset))) return;
+  if (Obj->getElfHeader()->e_type == ELF::ET_REL){
+    if (error(RelI->getOffset(Offset))) return;
+  } else {
+    if (error(RelI->getAddress(Offset))) return;
+  }
   if (error(RelI->getType(RelocType))) return;
   if (error(RelI->getTypeName(RelocName))) return;
   if (error(RelI->getAdditionalInfo(Info))) return;
index 7a4b4e4431c2bd6a907867951ce433469bdd3997..2e95b6b5518f97032ce07e87dec3b1f8243f2241 100644 (file)
@@ -143,8 +143,8 @@ bool error(error_code EC) {
 
 bool relocAddressLess(RelocationRef a, RelocationRef b) {
   uint64_t a_addr, b_addr;
-  if (error(a.getAddress(a_addr))) return false;
-  if (error(b.getAddress(b_addr))) return false;
+  if (error(a.getOffset(a_addr))) return false;
+  if (error(b.getOffset(b_addr))) return false;
   return a_addr < b_addr;
 }