llvm.org GIT mirror llvm / 4cbb2db
[Object][ELF] Add support for dumping dynamic relocations when sections are stripped. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240703 91177308-0d34-0410-b5e6-96231b3b80d8 Michael J. Spencer 5 years ago
6 changed file(s) with 104 addition(s) and 4 deletion(s). Raw diff Collapse all Expand all
264264 DynRegionInfo DynHashRegion;
265265 DynRegionInfo DynStrRegion;
266266 DynRegionInfo DynSymRegion;
267 DynRegionInfo DynRelaRegion;
267268
268269 // Pointer to SONAME entry in dynamic string table
269270 // This is set the first time getLoadName is called.
360361 (const char *)DynSymRegion.Addr + DynSymRegion.Size,
361362 true);
362363 return Elf_Sym_Iter(0, nullptr, true);
364 }
365
366 Elf_Rela_Iter begin_dyn_rela() const {
367 if (DynRelaRegion.Addr)
368 return Elf_Rela_Iter(DynRelaRegion.EntSize,
369 (const char *)DynRelaRegion.Addr);
370 return Elf_Rela_Iter(0, nullptr);
371 }
372
373 Elf_Rela_Iter end_dyn_rela() const {
374 if (DynRelaRegion.Addr)
375 return Elf_Rela_Iter(
376 DynRelaRegion.EntSize,
377 (const char *)DynRelaRegion.Addr + DynRelaRegion.Size);
378 return Elf_Rela_Iter(0, nullptr);
363379 }
364380
365381 Elf_Rela_Iter begin_rela(const Elf_Shdr *sec) const {
761777 }
762778 }
763779
780 // Scan dynamic table.
781 for (Elf_Dyn_Iter DynI = begin_dynamic_table(), DynE = end_dynamic_table();
782 DynI != DynE; ++DynI) {
783 switch (DynI->d_tag) {
784 case ELF::DT_RELA: {
785 uint64_t VBase = 0;
786 const uint8_t *FBase = nullptr;
787 for (Elf_Phdr_Iter PhdrI = begin_program_headers(),
788 PhdrE = end_program_headers();
789 PhdrI != PhdrE; ++PhdrI) {
790 if (PhdrI->p_type != ELF::PT_LOAD)
791 continue;
792 if (DynI->getPtr() >= PhdrI->p_vaddr &&
793 DynI->getPtr() < PhdrI->p_vaddr + PhdrI->p_memsz) {
794 VBase = PhdrI->p_vaddr;
795 FBase = base() + PhdrI->p_offset;
796 break;
797 }
798 }
799 if (!VBase)
800 return;
801 DynRelaRegion.Addr = FBase + DynI->getPtr() - VBase;
802 break;
803 }
804 case ELF::DT_RELASZ:
805 DynRelaRegion.Size = DynI->getVal();
806 break;
807 case ELF::DT_RELAENT:
808 DynRelaRegion.EntSize = DynI->getVal();
809 }
810 }
811
764812 EC = std::error_code();
765813 }
766814
292292 using Elf_Dyn_Base::d_un;
293293 int64_t getTag() const { return d_tag; }
294294 uint64_t getVal() const { return d_un.d_val; }
295 uint64_t getPtr() const { return d_un.ptr; }
295 uint64_t getPtr() const { return d_un.d_ptr; }
296296 };
297297
298298 // Elf_Rel: Elf Relocation
0 RUN: llvm-readobj -r -expand-relocs %p/Inputs/hello-world.elf-x86-64 \
11 RUN: | FileCheck %s
2 RUN: llvm-readobj -dyn-relocations -expand-relocs \
3 RUN: %p/Inputs/hello-world.elf-x86-64 | FileCheck %s --check-prefix=DYN
24
35 // CHECK: Relocations [
46 // CHECK-NEXT: Section (8) .rela.dyn {
2325 // CHECK-NEXT: Addend: 0x0
2426 // CHECK-NEXT: }
2527 // CHECK-NEXT: }
28
29 // DYN: Dynamic Relocations {
30 // DYN-NEXT: Relocation {
31 // DYN-NEXT: Offset: 0x4018D8
32 // DYN-NEXT: Type: R_X86_64_GLOB_DAT (6)
33 // DYN-NEXT: Symbol: __gmon_start__
34 // DYN-NEXT: Addend: 0x0
35 // DYN-NEXT: }
36 // DYN-NEXT: }
4646 void printFileHeaders() override;
4747 void printSections() override;
4848 void printRelocations() override;
49 void printDynamicRelocations() override;
4950 void printSymbols() override;
5051 void printDynamicSymbols() override;
5152 void printUnwindInfo() override;
675676 }
676677 }
677678
679 template
680 void ELFDumper::printDynamicRelocations() {
681 W.startLine() << "Dynamic Relocations {\n";
682 W.indent();
683 for (typename ELFO::Elf_Rela_Iter RelI = Obj->begin_dyn_rela(),
684 RelE = Obj->end_dyn_rela();
685 RelI != RelE; ++RelI) {
686 SmallString<32> RelocName;
687 Obj->getRelocationTypeName(RelI->getType(Obj->isMips64EL()), RelocName);
688 StringRef SymbolName;
689 uint32_t SymIndex = RelI->getSymbol(Obj->isMips64EL());
690 typename ELFO::Elf_Sym_Iter Sym = Obj->begin_dynamic_symbols() + SymIndex;
691 SymbolName = errorOrDefault(Obj->getSymbolName(Sym));
692 if (opts::ExpandRelocs) {
693 DictScope Group(W, "Relocation");
694 W.printHex("Offset", RelI->r_offset);
695 W.printNumber("Type", RelocName, (int)RelI->getType(Obj->isMips64EL()));
696 W.printString("Symbol", SymbolName.size() > 0 ? SymbolName : "-");
697 W.printHex("Addend", RelI->r_addend);
698 }
699 else {
700 raw_ostream& OS = W.startLine();
701 OS << W.hex(RelI->r_offset)
702 << " " << RelocName
703 << " " << (SymbolName.size() > 0 ? SymbolName : "-")
704 << " " << W.hex(RelI->r_addend)
705 << "\n";
706 }
707 }
708 W.unindent();
709 W.startLine() << "}\n";
710 }
711
678712 template
679713 void ELFDumper::printRelocations(const Elf_Shdr *Sec) {
680714 switch (Sec->sh_type) {
9851019 case DT_FLAGS_1:
9861020 printFlags(Value, makeArrayRef(ElfDynamicDTFlags1), OS);
9871021 break;
1022 default:
1023 OS << format("0x%" PRIX64, Value);
1024 break;
9881025 }
9891026 }
9901027
3232 virtual void printUnwindInfo() = 0;
3333
3434 // Only implemented for ELF at this time.
35 virtual void printDynamicRelocations() { }
3536 virtual void printDynamicTable() { }
3637 virtual void printNeededLibraries() { }
3738 virtual void printProgramHeaders() { }
3939 #include
4040 #include
4141
42
4342 using namespace llvm;
4443 using namespace llvm::object;
4544
8988 cl::alias RelocationsShort("r",
9089 cl::desc("Alias for --relocations"),
9190 cl::aliasopt(Relocations));
91
92 // -dyn-relocations
93 cl::opt DynRelocs("dyn-relocations",
94 cl::desc("Display the dynamic relocation entries in the file"));
9295
9396 // -symbols, -t
9497 cl::opt Symbols("symbols",
279282 Dumper->printSections();
280283 if (opts::Relocations)
281284 Dumper->printRelocations();
285 if (opts::DynRelocs)
286 Dumper->printDynamicRelocations();
282287 if (opts::Symbols)
283288 Dumper->printSymbols();
284289 if (opts::DynamicSymbols)
312317 Dumper->printCOFFBaseReloc();
313318 }
314319
315
316320 /// @brief Dumps each object file in \a Arc;
317321 static void dumpArchive(const Archive *Arc) {
318322 for (Archive::child_iterator ArcI = Arc->child_begin(),
373377 reportError(File, readobj_error::unrecognized_file_format);
374378 }
375379
376
377380 int main(int argc, const char *argv[]) {
378381 sys::PrintStackTraceOnErrorSignal();
379382 PrettyStackTraceProgram X(argc, argv);