[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