[llvm] r240703 - [Object][ELF] Add support for dumping dynamic relocations when sections are stripped.

Michael J. Spencer bigcheesegs at gmail.com
Thu Jun 25 14:47:32 PDT 2015


Author: mspencer
Date: Thu Jun 25 16:47:32 2015
New Revision: 240703

URL: http://llvm.org/viewvc/llvm-project?rev=240703&view=rev
Log:
[Object][ELF] Add support for dumping dynamic relocations when sections are stripped.

Modified:
    llvm/trunk/include/llvm/Object/ELF.h
    llvm/trunk/include/llvm/Object/ELFTypes.h
    llvm/trunk/test/Object/relocation-executable.test
    llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
    llvm/trunk/tools/llvm-readobj/ObjDumper.h
    llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp

Modified: llvm/trunk/include/llvm/Object/ELF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/ELF.h?rev=240703&r1=240702&r2=240703&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/ELF.h (original)
+++ llvm/trunk/include/llvm/Object/ELF.h Thu Jun 25 16:47:32 2015
@@ -265,6 +265,7 @@ private:
   DynRegionInfo DynHashRegion;
   DynRegionInfo DynStrRegion;
   DynRegionInfo DynSymRegion;
+  DynRegionInfo DynRelaRegion;
 
   // Pointer to SONAME entry in dynamic string table
   // This is set the first time getLoadName is called.
@@ -363,6 +364,21 @@ public:
     return Elf_Sym_Iter(0, nullptr, true);
   }
 
+  Elf_Rela_Iter begin_dyn_rela() const {
+    if (DynRelaRegion.Addr)
+      return Elf_Rela_Iter(DynRelaRegion.EntSize,
+        (const char *)DynRelaRegion.Addr);
+    return Elf_Rela_Iter(0, nullptr);
+  }
+
+  Elf_Rela_Iter end_dyn_rela() const {
+    if (DynRelaRegion.Addr)
+      return Elf_Rela_Iter(
+        DynRelaRegion.EntSize,
+        (const char *)DynRelaRegion.Addr + DynRelaRegion.Size);
+    return Elf_Rela_Iter(0, nullptr);
+  }
+
   Elf_Rela_Iter begin_rela(const Elf_Shdr *sec) const {
     return Elf_Rela_Iter(sec->sh_entsize,
                          (const char *)(base() + sec->sh_offset));
@@ -762,6 +778,38 @@ ELFFile<ELFT>::ELFFile(StringRef Object,
     }
   }
 
+  // Scan dynamic table.
+  for (Elf_Dyn_Iter DynI = begin_dynamic_table(), DynE = end_dynamic_table();
+  DynI != DynE; ++DynI) {
+    switch (DynI->d_tag) {
+    case ELF::DT_RELA: {
+      uint64_t VBase = 0;
+      const uint8_t *FBase = nullptr;
+      for (Elf_Phdr_Iter PhdrI = begin_program_headers(),
+        PhdrE = end_program_headers();
+        PhdrI != PhdrE; ++PhdrI) {
+        if (PhdrI->p_type != ELF::PT_LOAD)
+          continue;
+        if (DynI->getPtr() >= PhdrI->p_vaddr &&
+            DynI->getPtr() < PhdrI->p_vaddr + PhdrI->p_memsz) {
+          VBase = PhdrI->p_vaddr;
+          FBase = base() + PhdrI->p_offset;
+          break;
+        }
+      }
+      if (!VBase)
+        return;
+      DynRelaRegion.Addr = FBase + DynI->getPtr() - VBase;
+      break;
+    }
+    case ELF::DT_RELASZ:
+      DynRelaRegion.Size = DynI->getVal();
+      break;
+    case ELF::DT_RELAENT:
+      DynRelaRegion.EntSize = DynI->getVal();
+    }
+  }
+
   EC = std::error_code();
 }
 

Modified: llvm/trunk/include/llvm/Object/ELFTypes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/ELFTypes.h?rev=240703&r1=240702&r2=240703&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/ELFTypes.h (original)
+++ llvm/trunk/include/llvm/Object/ELFTypes.h Thu Jun 25 16:47:32 2015
@@ -293,7 +293,7 @@ struct Elf_Dyn_Impl : Elf_Dyn_Base<ELFT>
   using Elf_Dyn_Base<ELFT>::d_un;
   int64_t getTag() const { return d_tag; }
   uint64_t getVal() const { return d_un.d_val; }
-  uint64_t getPtr() const { return d_un.ptr; }
+  uint64_t getPtr() const { return d_un.d_ptr; }
 };
 
 // Elf_Rel: Elf Relocation

Modified: llvm/trunk/test/Object/relocation-executable.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/relocation-executable.test?rev=240703&r1=240702&r2=240703&view=diff
==============================================================================
--- llvm/trunk/test/Object/relocation-executable.test (original)
+++ llvm/trunk/test/Object/relocation-executable.test Thu Jun 25 16:47:32 2015
@@ -1,5 +1,7 @@
 RUN: llvm-readobj -r -expand-relocs %p/Inputs/hello-world.elf-x86-64 \
 RUN:   | FileCheck %s
+RUN: llvm-readobj -dyn-relocations -expand-relocs \
+RUN:   %p/Inputs/hello-world.elf-x86-64 | FileCheck %s --check-prefix=DYN
 
 // CHECK:     Relocations [
 // CHECK-NEXT:  Section (8) .rela.dyn {
@@ -24,3 +26,12 @@ RUN:   | FileCheck %s
 // CHECK-NEXT:      Addend: 0x0
 // CHECK-NEXT:    }
 // CHECK-NEXT:  }
+
+// DYN:      Dynamic Relocations {
+// DYN-NEXT:   Relocation {
+// DYN-NEXT:     Offset: 0x4018D8
+// DYN-NEXT:     Type: R_X86_64_GLOB_DAT (6)
+// DYN-NEXT:     Symbol: __gmon_start__
+// DYN-NEXT:     Addend: 0x0
+// DYN-NEXT:   }
+// DYN-NEXT: }

Modified: llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ELFDumper.cpp?rev=240703&r1=240702&r2=240703&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/ELFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/ELFDumper.cpp Thu Jun 25 16:47:32 2015
@@ -47,6 +47,7 @@ public:
   void printFileHeaders() override;
   void printSections() override;
   void printRelocations() override;
+  void printDynamicRelocations() override;
   void printSymbols() override;
   void printDynamicSymbols() override;
   void printUnwindInfo() override;
@@ -676,6 +677,39 @@ void ELFDumper<ELFT>::printRelocations()
   }
 }
 
+template<class ELFT>
+void ELFDumper<ELFT>::printDynamicRelocations() {
+  W.startLine() << "Dynamic Relocations {\n";
+  W.indent();
+  for (typename ELFO::Elf_Rela_Iter RelI = Obj->begin_dyn_rela(),
+    RelE = Obj->end_dyn_rela();
+    RelI != RelE; ++RelI) {
+    SmallString<32> RelocName;
+    Obj->getRelocationTypeName(RelI->getType(Obj->isMips64EL()), RelocName);
+    StringRef SymbolName;
+    uint32_t SymIndex = RelI->getSymbol(Obj->isMips64EL());
+    typename ELFO::Elf_Sym_Iter Sym = Obj->begin_dynamic_symbols() + SymIndex;
+    SymbolName = errorOrDefault(Obj->getSymbolName(Sym));
+    if (opts::ExpandRelocs) {
+      DictScope Group(W, "Relocation");
+      W.printHex("Offset", RelI->r_offset);
+      W.printNumber("Type", RelocName, (int)RelI->getType(Obj->isMips64EL()));
+      W.printString("Symbol", SymbolName.size() > 0 ? SymbolName : "-");
+      W.printHex("Addend", RelI->r_addend);
+    }
+    else {
+      raw_ostream& OS = W.startLine();
+      OS << W.hex(RelI->r_offset)
+        << " " << RelocName
+        << " " << (SymbolName.size() > 0 ? SymbolName : "-")
+        << " " << W.hex(RelI->r_addend)
+        << "\n";
+    }
+  }
+  W.unindent();
+  W.startLine() << "}\n";
+}
+
 template <class ELFT>
 void ELFDumper<ELFT>::printRelocations(const Elf_Shdr *Sec) {
   switch (Sec->sh_type) {
@@ -986,6 +1020,9 @@ static void printValue(const ELFFile<ELF
   case DT_FLAGS_1:
     printFlags(Value, makeArrayRef(ElfDynamicDTFlags1), OS);
     break;
+  default:
+    OS << format("0x%" PRIX64, Value);
+    break;
   }
 }
 

Modified: llvm/trunk/tools/llvm-readobj/ObjDumper.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ObjDumper.h?rev=240703&r1=240702&r2=240703&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/ObjDumper.h (original)
+++ llvm/trunk/tools/llvm-readobj/ObjDumper.h Thu Jun 25 16:47:32 2015
@@ -33,6 +33,7 @@ public:
   virtual void printUnwindInfo() = 0;
 
   // Only implemented for ELF at this time.
+  virtual void printDynamicRelocations() { }
   virtual void printDynamicTable() { }
   virtual void printNeededLibraries() { }
   virtual void printProgramHeaders() { }

Modified: llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp?rev=240703&r1=240702&r2=240703&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp Thu Jun 25 16:47:32 2015
@@ -40,7 +40,6 @@
 #include <string>
 #include <system_error>
 
-
 using namespace llvm;
 using namespace llvm::object;
 
@@ -91,6 +90,10 @@ namespace opts {
     cl::desc("Alias for --relocations"),
     cl::aliasopt(Relocations));
 
+  // -dyn-relocations
+  cl::opt<bool> DynRelocs("dyn-relocations",
+    cl::desc("Display the dynamic relocation entries in the file"));
+
   // -symbols, -t
   cl::opt<bool> Symbols("symbols",
     cl::desc("Display the symbol table"));
@@ -280,6 +283,8 @@ static void dumpObject(const ObjectFile
     Dumper->printSections();
   if (opts::Relocations)
     Dumper->printRelocations();
+  if (opts::DynRelocs)
+    Dumper->printDynamicRelocations();
   if (opts::Symbols)
     Dumper->printSymbols();
   if (opts::DynamicSymbols)
@@ -313,7 +318,6 @@ static void dumpObject(const ObjectFile
     Dumper->printCOFFBaseReloc();
 }
 
-
 /// @brief Dumps each object file in \a Arc;
 static void dumpArchive(const Archive *Arc) {
   for (Archive::child_iterator ArcI = Arc->child_begin(),
@@ -374,7 +378,6 @@ static void dumpInput(StringRef File) {
     reportError(File, readobj_error::unrecognized_file_format);
 }
 
-
 int main(int argc, const char *argv[]) {
   sys::PrintStackTraceOnErrorSignal();
   PrettyStackTraceProgram X(argc, argv);





More information about the llvm-commits mailing list