diff options
Diffstat (limited to 'llvm/tools/llvm-readobj/ELFDumper.cpp')
-rw-r--r-- | llvm/tools/llvm-readobj/ELFDumper.cpp | 103 |
1 files changed, 69 insertions, 34 deletions
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index 64059ed74b3..4eac7e4b8bf 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -75,6 +75,7 @@ private: typedef typename ELFO::Elf_Dyn_Range Elf_Dyn_Range; typedef typename ELFO::Elf_Rel Elf_Rel; typedef typename ELFO::Elf_Rela Elf_Rela; + typedef typename ELFO::Elf_Rel_Range Elf_Rel_Range; typedef typename ELFO::Elf_Rela_Range Elf_Rela_Range; typedef typename ELFO::Elf_Phdr Elf_Phdr; typedef typename ELFO::Elf_Half Elf_Half; @@ -104,12 +105,16 @@ private: void printSymbol(const Elf_Sym *Symbol, const Elf_Shdr *SymTab, StringRef StrTable, bool IsDynamic); + void printDynamicRelocation(Elf_Rela Rel); void printRelocations(const Elf_Shdr *Sec); void printRelocation(Elf_Rela Rel, const Elf_Shdr *SymTab); void printValue(uint64_t Type, uint64_t Value); - const Elf_Rela *dyn_rela_begin() const; - const Elf_Rela *dyn_rela_end() const; + template <typename RELA> + static const RELA *dyn_rela_begin(const DynRegionInfo ®ion); + template <typename RELA> + static const RELA *dyn_rela_end(const DynRegionInfo ®ion); + Elf_Rel_Range dyn_rels() const; Elf_Rela_Range dyn_relas() const; StringRef getDynamicString(uint64_t Offset) const; const Elf_Dyn *dynamic_table_begin() const { @@ -129,6 +134,7 @@ private: void LoadVersionDefs(const Elf_Shdr *sec) const; const ELFO *Obj; + DynRegionInfo DynRelRegion; DynRegionInfo DynRelaRegion; const Elf_Phdr *DynamicProgHeader = nullptr; StringRef DynamicStringTable; @@ -944,6 +950,15 @@ ELFDumper<ELFT>::ELFDumper(const ELFFile<ELFT> *Obj, StreamWriter &Writer) GnuHashTable = reinterpret_cast<const Elf_GnuHash *>(toMappedAddr(Dyn.getPtr())); break; + case ELF::DT_REL: + DynRelRegion.Addr = toMappedAddr(Dyn.getPtr()); + break; + case ELF::DT_RELSZ: + DynRelRegion.Size = Dyn.getVal(); + break; + case ELF::DT_RELENT: + DynRelRegion.EntSize = Dyn.getVal(); + break; case ELF::DT_RELA: DynRelaRegion.Addr = toMappedAddr(Dyn.getPtr()); break; @@ -1011,25 +1026,32 @@ ELFDumper<ELFT>::ELFDumper(const ELFFile<ELFT> *Obj, StreamWriter &Writer) } template <typename ELFT> -const typename ELFDumper<ELFT>::Elf_Rela * -ELFDumper<ELFT>::dyn_rela_begin() const { - if (DynRelaRegion.Size && DynRelaRegion.EntSize != sizeof(Elf_Rela)) +template <typename RELA> +const RELA *ELFDumper<ELFT>::dyn_rela_begin(const DynRegionInfo &Region) { + if (Region.Size && Region.EntSize != sizeof(RELA)) report_fatal_error("Invalid relocation entry size"); - return reinterpret_cast<const Elf_Rela *>(DynRelaRegion.Addr); + return reinterpret_cast<const RELA *>(Region.Addr); } template <typename ELFT> -const typename ELFDumper<ELFT>::Elf_Rela * -ELFDumper<ELFT>::dyn_rela_end() const { - uint64_t Size = DynRelaRegion.Size; - if (Size % sizeof(Elf_Rela)) +template <typename RELA> +const RELA *ELFDumper<ELFT>::dyn_rela_end(const DynRegionInfo &Region) { + uint64_t Size = Region.Size; + if (Size % sizeof(RELA)) report_fatal_error("Invalid relocation table size"); - return dyn_rela_begin() + Size / sizeof(Elf_Rela); + return dyn_rela_begin<RELA>(Region) + Size / sizeof(RELA); +} + +template <typename ELFT> +typename ELFDumper<ELFT>::Elf_Rel_Range ELFDumper<ELFT>::dyn_rels() const { + return make_range(dyn_rela_begin<Elf_Rel>(DynRelRegion), + dyn_rela_end<Elf_Rel>(DynRelRegion)); } template <typename ELFT> typename ELFDumper<ELFT>::Elf_Rela_Range ELFDumper<ELFT>::dyn_relas() const { - return make_range(dyn_rela_begin(), dyn_rela_end()); + return make_range(dyn_rela_begin<Elf_Rela>(DynRelaRegion), + dyn_rela_end<Elf_Rela>(DynRelaRegion)); } template<class ELFT> @@ -1158,31 +1180,22 @@ void ELFDumper<ELFT>::printRelocations() { } } -template<class ELFT> -void ELFDumper<ELFT>::printDynamicRelocations() { +template <class ELFT> void ELFDumper<ELFT>::printDynamicRelocations() { + if (DynRelRegion.Size && DynRelaRegion.Size) + report_fatal_error("There are both REL and RELA dynamic relocations"); W.startLine() << "Dynamic Relocations {\n"; W.indent(); - for (const Elf_Rela &Rel : dyn_relas()) { - SmallString<32> RelocName; - Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName); - StringRef SymbolName; - uint32_t SymIndex = Rel.getSymbol(Obj->isMips64EL()); - const Elf_Sym *Sym = DynSymStart + SymIndex; - SymbolName = errorOrDefault(Sym->getName(DynamicStringTable)); - if (opts::ExpandRelocs) { - DictScope Group(W, "Relocation"); - W.printHex("Offset", Rel.r_offset); - W.printNumber("Type", RelocName, (int)Rel.getType(Obj->isMips64EL())); - W.printString("Symbol", SymbolName.size() > 0 ? SymbolName : "-"); - W.printHex("Addend", Rel.r_addend); - } - else { - raw_ostream& OS = W.startLine(); - OS << W.hex(Rel.r_offset) << " " << RelocName << " " - << (SymbolName.size() > 0 ? SymbolName : "-") << " " - << W.hex(Rel.r_addend) << "\n"; + if (DynRelaRegion.Size > 0) + for (const Elf_Rela &Rela : dyn_relas()) + printDynamicRelocation(Rela); + else + for (const Elf_Rel &Rel : dyn_rels()) { + 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"; } @@ -1243,6 +1256,28 @@ void ELFDumper<ELFT>::printRelocation(Elf_Rela Rel, const Elf_Shdr *SymTab) { } } +template <class ELFT> +void ELFDumper<ELFT>::printDynamicRelocation(Elf_Rela Rel) { + SmallString<32> RelocName; + Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName); + StringRef SymbolName; + uint32_t SymIndex = Rel.getSymbol(Obj->isMips64EL()); + const Elf_Sym *Sym = DynSymStart + SymIndex; + SymbolName = errorOrDefault(Sym->getName(DynamicStringTable)); + if (opts::ExpandRelocs) { + DictScope Group(W, "Relocation"); + W.printHex("Offset", Rel.r_offset); + W.printNumber("Type", RelocName, (int)Rel.getType(Obj->isMips64EL())); + W.printString("Symbol", SymbolName.size() > 0 ? SymbolName : "-"); + W.printHex("Addend", Rel.r_addend); + } else { + raw_ostream &OS = W.startLine(); + OS << W.hex(Rel.r_offset) << " " << RelocName << " " + << (SymbolName.size() > 0 ? SymbolName : "-") << " " + << W.hex(Rel.r_addend) << "\n"; + } +} + template<class ELFT> void ELFDumper<ELFT>::printSymbolsHelper(bool IsDynamic) { const Elf_Shdr *Symtab = (IsDynamic) ? DotDynSymSec : DotSymtabSec; |