[llvm-objdump] Printing relocations in executable and shared object files. This...
authorColin LeMahieu <colinl@codeaurora.org>
Mon, 21 Mar 2016 19:14:50 +0000 (19:14 +0000)
committerColin LeMahieu <colinl@codeaurora.org>
Mon, 21 Mar 2016 19:14:50 +0000 (19:14 +0000)
In executable and shared object ELF files, relocations in the file contain the final virtual address rather than section offset so this is adjusted to display section offset.

Differential revision: http://reviews.llvm.org/D15965

llvm-svn: 263971

llvm/include/llvm/Object/ELFObjectFile.h
llvm/test/Object/objdump-reloc-shared.test [deleted file]
llvm/test/tools/llvm-objdump/X86/Inputs/relocations-in-nonrelocatable.elf-x86_64 [new file with mode: 0644]
llvm/test/tools/llvm-objdump/X86/relocations-in-nonrelocatable.test [new file with mode: 0644]
llvm/tools/llvm-objdump/llvm-objdump.cpp

index b01fa1d..5ee90ee 100644 (file)
@@ -640,9 +640,6 @@ ELFObjectFile<ELFT>::section_rel_end(DataRefImpl Sec) const {
 template <class ELFT>
 section_iterator
 ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const {
-  if (EF.getHeader()->e_type != ELF::ET_REL)
-    return section_end();
-
   const Elf_Shdr *EShdr = getSection(Sec);
   uintX_t Type = EShdr->sh_type;
   if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA)
@@ -682,14 +679,20 @@ ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const {
 }
 
 template <class ELFT>
-uint64_t ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel) const {
-  assert(EF.getHeader()->e_type == ELF::ET_REL &&
-         "Only relocatable object files have relocation offsets");
-  const Elf_Shdr *sec = getRelSection(Rel);
-  if (sec->sh_type == ELF::SHT_REL)
-    return getRel(Rel)->r_offset;
-
-  return getRela(Rel)->r_offset;
+uint64_t ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel) const {\r
+  const Elf_Shdr *sec = getRelSection(Rel);\r
+  uint64_t Offset = sec->sh_type == ELF::SHT_REL ?\r
+                    getRel(Rel)->r_offset :\r
+                    getRela(Rel)->r_offset;\r
+  if (EF.getHeader()->e_type == ELF::ET_EXEC ||\r
+      EF.getHeader()->e_type == ELF::ET_DYN) {\r
+    // For an executable file or a shared object, the value is the virtual\r
+    // address of the storage unit affected by the relocation.\r
+    auto SectionIter = getRelocatedSection(toDRI(sec));\r
+    if (SectionIter != section_end())\r
+      Offset -= SectionIter->getAddress();\r
+  }\r
+  return Offset;
 }
 
 template <class ELFT>
diff --git a/llvm/test/Object/objdump-reloc-shared.test b/llvm/test/Object/objdump-reloc-shared.test
deleted file mode 100644 (file)
index d899ffb..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-RUN: llvm-objdump -r %p/Inputs/elf-reloc-no-sym.x86_64 \
-RUN:              | FileCheck %s
-
-; CHECK: elf-reloc-no-sym.x86_64:       file format ELF64-x86-64
-; CHECK-NOT: {{.}}
diff --git a/llvm/test/tools/llvm-objdump/X86/Inputs/relocations-in-nonrelocatable.elf-x86_64 b/llvm/test/tools/llvm-objdump/X86/Inputs/relocations-in-nonrelocatable.elf-x86_64
new file mode 100644 (file)
index 0000000..bb706c9
Binary files /dev/null and b/llvm/test/tools/llvm-objdump/X86/Inputs/relocations-in-nonrelocatable.elf-x86_64 differ
diff --git a/llvm/test/tools/llvm-objdump/X86/relocations-in-nonrelocatable.test b/llvm/test/tools/llvm-objdump/X86/relocations-in-nonrelocatable.test
new file mode 100644 (file)
index 0000000..4860b91
--- /dev/null
@@ -0,0 +1,9 @@
+// This test checks that relocation in nonrelocatable files are printed\r
+// RUN: llvm-objdump -r %p/Inputs/relocations-in-nonrelocatable.elf-x86_64 | FileCheck %s\r
+\r
+// (main.c)\r
+// void g(void){}\r
+// int main(void) { g(); };\r
+// gcc main.c -o main -Wl,--emit-relocs\r
+\r
+CHECK: 00000000000000f8 R_X86_64_PC32 g-4-P
\ No newline at end of file
index f436183..7f49efd 100644 (file)
@@ -1188,10 +1188,6 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
 void llvm::PrintRelocations(const ObjectFile *Obj) {
   StringRef Fmt = Obj->getBytesInAddress() > 4 ? "%016" PRIx64 :
                                                  "%08" PRIx64;
-  // Regular objdump doesn't print relocations in non-relocatable object
-  // files.
-  if (!Obj->isRelocatableObject())
-    return;
 
   for (const SectionRef &Section : ToolSectionFilter(*Obj)) {
     if (Section.relocation_begin() == Section.relocation_end())