diff options
| author | Rafael Espindola <rafael.espindola@gmail.com> | 2016-02-16 15:16:00 +0000 |
|---|---|---|
| committer | Rafael Espindola <rafael.espindola@gmail.com> | 2016-02-16 15:16:00 +0000 |
| commit | 944f655e05e0bb889f63a9949fd4bb3c0d040ae6 (patch) | |
| tree | c07e1c2e5513d738ecb71053f1414f6719c9f538 | |
| parent | be379e1590e60dd4adf6f38e7ccafa625f238539 (diff) | |
| download | bcm5719-llvm-944f655e05e0bb889f63a9949fd4bb3c0d040ae6.tar.gz bcm5719-llvm-944f655e05e0bb889f63a9949fd4bb3c0d040ae6.zip | |
Reapply r260489.
Original commit message:
[readobj] Dump DT_JMPREL relocations when outputting dynamic relocations.
The bits of r260488 it depends on have been committed.
llvm-svn: 260970
| -rw-r--r-- | llvm/test/Object/relocation-executable.test | 12 | ||||
| -rw-r--r-- | llvm/tools/llvm-readobj/ELFDumper.cpp | 29 |
2 files changed, 41 insertions, 0 deletions
diff --git a/llvm/test/Object/relocation-executable.test b/llvm/test/Object/relocation-executable.test index 93d4dee3089..bb0bb157b6a 100644 --- a/llvm/test/Object/relocation-executable.test +++ b/llvm/test/Object/relocation-executable.test @@ -34,6 +34,18 @@ RUN: %p/Inputs/hello-world.elf-x86-64 | FileCheck %s --check-prefix=DYN // DYN-NEXT: Symbol: __gmon_start__ // DYN-NEXT: Addend: 0x0 // DYN-NEXT: } +// DYN-NEXT: Relocation { +// DYN-NEXT: Offset: 0x4018F8 +// DYN-NEXT: Type: R_X86_64_JUMP_SLOT (7) +// DYN-NEXT: Symbol: __libc_start_main +// DYN-NEXT: Addend: 0x0 +// DYN-NEXT: } +// DYN-NEXT: Relocation { +// DYN-NEXT: Offset: 0x401900 +// DYN-NEXT: Type: R_X86_64_JUMP_SLOT (7) +// DYN-NEXT: Symbol: puts +// DYN-NEXT: Addend: 0x0 +// DYN-NEXT: } // DYN-NEXT: } RUN: llvm-readobj -dyn-relocations -expand-relocs \ diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index b8c815e4b35..f305d6d0d6c 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -60,6 +60,8 @@ struct DynRegionInfo { template <typename Type> iterator_range<const Type *> getAsRange() const { const Type *Start = reinterpret_cast<const Type *>(Addr); + if (!Start) + return {Start, Start}; if (EntSize != sizeof(Type) || Size % EntSize) reportError("Invalid entity size"); return {Start, Start + (Size / EntSize)}; @@ -152,6 +154,7 @@ private: const ELFO *Obj; DynRegionInfo DynRelRegion; DynRegionInfo DynRelaRegion; + DynRegionInfo DynPLTRelRegion; const Elf_Phdr *DynamicProgHeader = nullptr; StringRef DynamicStringTable; const Elf_Sym *DynSymStart = nullptr; @@ -1105,6 +1108,21 @@ void ELFDumper<ELFT>::parseDynamicTable( case ELF::DT_RELENT: DynRelRegion.EntSize = Dyn.getVal(); break; + case ELF::DT_PLTREL: + if (Dyn.getVal() == DT_REL) + DynPLTRelRegion.EntSize = sizeof(Elf_Rel); + else if (Dyn.getVal() == DT_RELA) + DynPLTRelRegion.EntSize = sizeof(Elf_Rela); + else + reportError(Twine("unknown DT_PLTREL value of ") + + Twine((uint64_t)Dyn.getVal())); + break; + case ELF::DT_JMPREL: + DynPLTRelRegion.Addr = toMappedAddr(Dyn.getPtr()); + break; + case ELF::DT_PLTRELSZ: + DynPLTRelRegion.Size = Dyn.getVal(); + break; } } if (StringTableBegin) @@ -1246,6 +1264,17 @@ template <class ELFT> void ELFDumper<ELFT>::printDynamicRelocations() { Rela.r_addend = 0; printDynamicRelocation(Rela); } + if (DynPLTRelRegion.EntSize == sizeof(Elf_Rela)) + for (const Elf_Rela &Rela : DynPLTRelRegion.getAsRange<Elf_Rela>()) + printDynamicRelocation(Rela); + else + for (const Elf_Rel &Rel : DynPLTRelRegion.getAsRange<Elf_Rel>()) { + Elf_Rela Rela; + Rela.r_offset = Rel.r_offset; + Rela.r_info = Rel.r_info; + Rela.r_addend = 0; + printDynamicRelocation(Rela); + } W.unindent(); W.startLine() << "}\n"; } |

