[PATCH] D15965: Add support for dumping relocations in non-relocatable files

Colin LeMahieu via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 11 11:57:09 PST 2016


colinl removed rL LLVM as the repository for this revision.
colinl updated this revision to Diff 50459.
colinl added a comment.

It looks like in the ELF spec, as you already noticed, it says r_offset contains the virtual address if the file type is ET_EXEC or ET_DYN so in those cases we look for the relocated section and subtract the address.

I added a comment in the test on how the binary was created.

For equivalent functionality of dynamic relocations we'd need to add the -R flag to llvm-objdump, SymbolRef would need an accessor like isDynamic, the ELF implementation can use code from getRelocationSymbol to determine if it's dynamic:

  bool IsDyn = Rel.d.b & 1;
  DataRefImpl SymbolData;
  if (IsDyn)
    SymbolData = toDRI(DotDynSymSec, symbolIdx);
  else
    SymbolData = toDRI(DotSymtabSec, symbolIdx);

and then COFF and MachO would need implementations for those file types.  The interwoven disassembly/relocations would need to also take this in to account.

It'd be good to have equivalent functionality though I think we should do that in a separate revision since it's non-trivial.


http://reviews.llvm.org/D15965

Files:
  include/llvm/Object/ELFObjectFile.h
  test/tools/llvm-objdump/X86/Inputs/relocations-in-nonrelocatable.elf-x86_64
  test/tools/llvm-objdump/X86/relocations-in-nonrelocatable.test
  tools/llvm-objdump/llvm-objdump.cpp

Index: tools/llvm-objdump/llvm-objdump.cpp
===================================================================
--- tools/llvm-objdump/llvm-objdump.cpp
+++ tools/llvm-objdump/llvm-objdump.cpp
@@ -1183,10 +1183,6 @@
 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())
Index: test/tools/llvm-objdump/X86/relocations-in-nonrelocatable.test
===================================================================
--- test/tools/llvm-objdump/X86/relocations-in-nonrelocatable.test
+++ test/tools/llvm-objdump/X86/relocations-in-nonrelocatable.test
@@ -0,0 +1,9 @@
+// This test checks that relocation in nonrelocatable files are printed
+// RUN: llvm-objdump -r %p/Inputs/relocations-in-nonrelocatable.elf-x86_64 | FileCheck %s
+
+// (main.c)
+// void g(void){}
+// int main(void) { g(); };
+// gcc main.c -o main -Wl,--emit-relocs
+
+CHECK: 00000000000000f8 R_X86_64_PC32 g-4-P
\ No newline at end of file
Index: include/llvm/Object/ELFObjectFile.h
===================================================================
--- include/llvm/Object/ELFObjectFile.h
+++ include/llvm/Object/ELFObjectFile.h
@@ -640,9 +640,6 @@
 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 @@
 }
 
 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 {
+  const Elf_Shdr *sec = getRelSection(Rel);
+  uint64_t Offset = sec->sh_type == ELF::SHT_REL ?
+                    getRel(Rel)->r_offset :
+                    getRela(Rel)->r_offset;
+  if (EF.getHeader()->e_type == ELF::ET_EXEC ||
+      EF.getHeader()->e_type == ELF::ET_DYN) {
+    // For an executable file or a shared object, the value is the virtual
+    // address of the storage unit affected by the relocation.
+    auto SectionIter = getRelocatedSection(toDRI(sec));
+    if (SectionIter != section_end())
+      Offset -= SectionIter->getAddress();
+  }
+  return Offset;
 }
 
 template <class ELFT>


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D15965.50459.patch
Type: text/x-patch
Size: 2933 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160311/dd7ca7d7/attachment.bin>


More information about the llvm-commits mailing list