diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index ca8f8472849658..a09ee6d630d783 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -82,8 +82,6 @@ using namespace ELF; namespace { -template class DumpStyle; - template struct RelSymbol { RelSymbol(const typename ELFT::Sym *S, StringRef N) : Sym(S), Name(N.str()) {} @@ -232,50 +230,120 @@ template class Relocation { Optional Addend; }; +template class MipsGOTParser; + template class ELFDumper : public ObjDumper { + LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) + public: ELFDumper(const object::ELFObjectFile &ObjF, ScopedPrinter &Writer); - void printFileHeaders() override; - void printSectionHeaders() override; - void printRelocations() override; - void printDependentLibs() override; - void printDynamicRelocations() override; - void printSymbols(bool PrintSymbols, bool PrintDynamicSymbols) override; - void printHashSymbols() override; - void printSectionDetails() override; void printUnwindInfo() override; - - void printDynamicTable() override; void printNeededLibraries() override; - void printProgramHeaders(bool PrintProgramHeaders, - cl::boolOrDefault PrintSectionMapping) override; void printHashTable() override; void printGnuHashTable() override; void printLoadName() override; void printVersionInfo() override; - void printGroupSections() override; - void printArchSpecificInfo() override; - void printStackMap() const override; - void printHashHistograms() override; + const object::ELFObjectFile &getElfObject() const { return ObjF; }; - void printCGProfile() override; - void printAddrsig() override; + std::string describe(const Elf_Shdr &Sec) const; - void printNotes() override; + unsigned getHashTableEntSize() const { + // EM_S390 and ELF::EM_ALPHA platforms use 8-bytes entries in SHT_HASH + // sections. This violates the ELF specification. + if (Obj.getHeader().e_machine == ELF::EM_S390 || + Obj.getHeader().e_machine == ELF::EM_ALPHA) + return 8; + return 4; + } - void printELFLinkerOptions() override; - void printStackSizes() override; + Elf_Dyn_Range dynamic_table() const { + // A valid .dynamic section contains an array of entries terminated + // with a DT_NULL entry. However, sometimes the section content may + // continue past the DT_NULL entry, so to dump the section correctly, + // we first find the end of the entries by iterating over them. + Elf_Dyn_Range Table = DynamicTable.getAsArrayRef(); - const object::ELFObjectFile &getElfObject() const { return ObjF; }; + size_t Size = 0; + while (Size < Table.size()) + if (Table[Size++].getTag() == DT_NULL) + break; -private: - std::unique_ptr> ELFDumperStyle; + return Table.slice(0, Size); + } - LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) + Elf_Sym_Range dynamic_symbols() const { + if (!DynSymRegion) + return Elf_Sym_Range(); + return DynSymRegion->getAsArrayRef(); + } + + const Elf_Shdr *findSectionByName(StringRef Name) const; + + StringRef getDynamicStringTable() const { return DynamicStringTable; } + +protected: + virtual void printVersionSymbolSection(const Elf_Shdr *Sec) = 0; + virtual void printVersionDefinitionSection(const Elf_Shdr *Sec) = 0; + virtual void printVersionDependencySection(const Elf_Shdr *Sec) = 0; + + void + printDependentLibsHelper(function_ref OnSectionStart, + function_ref OnLibEntry); + + virtual void printRelRelaReloc(const Relocation &R, + const RelSymbol &RelSym) = 0; + virtual void printRelrReloc(const Elf_Relr &R) = 0; + virtual void printDynamicRelocHeader(unsigned Type, StringRef Name, + const DynRegionInfo &Reg) {} + void printReloc(const Relocation &R, unsigned RelIndex, + const Elf_Shdr &Sec, const Elf_Shdr *SymTab); + void printDynamicReloc(const Relocation &R); + void printDynamicRelocationsHelper(); + void printRelocationsHelper(const Elf_Shdr &Sec); + void forEachRelocationDo( + const Elf_Shdr &Sec, bool RawRelr, + llvm::function_ref &, unsigned, + const Elf_Shdr &, const Elf_Shdr *)> + RelRelaFn, + llvm::function_ref RelrFn); + + virtual void printSymtabMessage(const Elf_Shdr *Symtab, size_t Offset, + bool NonVisibilityBitsUsed) const {}; + virtual void printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, + Optional StrTable, bool IsDynamic, + bool NonVisibilityBitsUsed) const = 0; + + virtual void printMipsABIFlags() = 0; + virtual void printMipsGOT(const MipsGOTParser &Parser) = 0; + virtual void printMipsPLT(const MipsGOTParser &Parser) = 0; + + Expected> getVersionTable(const Elf_Shdr &Sec, + ArrayRef *SymTab, + StringRef *StrTab) const; + StringRef getPrintableSectionName(const Elf_Shdr &Sec) const; + + std::vector getGroups(); + + bool printFunctionStackSize(uint64_t SymValue, + Optional FunctionSec, + const Elf_Shdr &StackSizeSec, DataExtractor Data, + uint64_t *Offset); + void printStackSize(const Relocation &R, const Elf_Shdr &RelocSec, + unsigned Ndx, const Elf_Shdr *SymTab, + const Elf_Shdr *FunctionSec, const Elf_Shdr &StackSizeSec, + const RelocationResolver &Resolver, DataExtractor Data); + virtual void printStackSizeEntry(uint64_t Size, StringRef FuncName) = 0; + + void printRelocatableStackSizes(std::function PrintHeader); + void printNonRelocatableStackSizes(std::function PrintHeader); + + const object::ELFObjectFile &ObjF; + const ELFFile &Obj; + StringRef FileName; Expected createDRI(uint64_t Offset, uint64_t Size, uint64_t EntSize) { @@ -299,8 +367,6 @@ template class ELFDumper : public ObjDumper { bool &IsDefault) const; Error LoadVersionMap() const; - const object::ELFObjectFile &ObjF; - const ELFFile &Obj; DynRegionInfo DynRelRegion; DynRegionInfo DynRelaRegion; DynRegionInfo DynRelrRegion; @@ -327,44 +393,6 @@ template class ELFDumper : public ObjDumper { }; mutable SmallVector, 16> VersionMap; - std::string describe(const Elf_Shdr &Sec) const; - -public: - unsigned getHashTableEntSize() const { - // EM_S390 and ELF::EM_ALPHA platforms use 8-bytes entries in SHT_HASH - // sections. This violates the ELF specification. - if (Obj.getHeader().e_machine == ELF::EM_S390 || - Obj.getHeader().e_machine == ELF::EM_ALPHA) - return 8; - return 4; - } - - Elf_Dyn_Range dynamic_table() const { - // A valid .dynamic section contains an array of entries terminated - // with a DT_NULL entry. However, sometimes the section content may - // continue past the DT_NULL entry, so to dump the section correctly, - // we first find the end of the entries by iterating over them. - Elf_Dyn_Range Table = DynamicTable.getAsArrayRef(); - - size_t Size = 0; - while (Size < Table.size()) - if (Table[Size++].getTag() == DT_NULL) - break; - - return Table.slice(0, Size); - } - - Optional getDynSymRegion() const { return DynSymRegion; } - - Elf_Sym_Range dynamic_symbols() const { - if (!DynSymRegion) - return Elf_Sym_Range(); - return DynSymRegion->getAsArrayRef(); - } - - Elf_Rel_Range dyn_rels() const; - Elf_Rela_Range dyn_relas() const; - Elf_Relr_Range dyn_relrs() const; std::string getFullSymbolName(const Elf_Sym &Symbol, unsigned SymIndex, Optional StrTable, bool IsDynamic) const; @@ -380,24 +408,6 @@ template class ELFDumper : public ObjDumper { void printSymbolsHelper(bool IsDynamic) const; std::string getDynamicEntry(uint64_t Type, uint64_t Value) const; - const Elf_Shdr *findSectionByName(StringRef Name) const; - - const Elf_Shdr *getDotSymtabSec() const { return DotSymtabSec; } - const Elf_Shdr *getDotCGProfileSec() const { return DotCGProfileSec; } - const Elf_Shdr *getDotAddrsigSec() const { return DotAddrsigSec; } - ArrayRef getShndxTable() const { return ShndxTable; } - StringRef getDynamicStringTable() const { return DynamicStringTable; } - const DynRegionInfo &getDynRelRegion() const { return DynRelRegion; } - const DynRegionInfo &getDynRelaRegion() const { return DynRelaRegion; } - const DynRegionInfo &getDynRelrRegion() const { return DynRelrRegion; } - const DynRegionInfo &getDynPLTRelRegion() const { return DynPLTRelRegion; } - const DynRegionInfo &getDynamicTableRegion() const { return DynamicTable; } - const Elf_Hash *getHashTable() const { return HashTable; } - const Elf_GnuHash *getGnuHashTable() const { return GnuHashTable; } - - Expected> getVersionTable(const Elf_Shdr &Sec, - ArrayRef *SymTab, - StringRef *StrTab) const; Expected> getVersionDefinitions(const Elf_Shdr &Sec) const; Expected> @@ -710,111 +720,21 @@ void ELFDumper::printSymbolsHelper(bool IsDynamic) const { bool NonVisibilityBitsUsed = llvm::any_of(Syms, [](const Elf_Sym &S) { return S.st_other & ~0x3; }); - ELFDumperStyle->printSymtabMessage(SymtabSec, Entries, NonVisibilityBitsUsed); + printSymtabMessage(SymtabSec, Entries, NonVisibilityBitsUsed); for (const Elf_Sym &Sym : Syms) - ELFDumperStyle->printSymbol(Sym, &Sym - Syms.begin(), StrTable, IsDynamic, - NonVisibilityBitsUsed); + printSymbol(Sym, &Sym - Syms.begin(), StrTable, IsDynamic, + NonVisibilityBitsUsed); } -template class MipsGOTParser; - -template class DumpStyle { -public: - LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) - - DumpStyle(const ELFDumper &Dumper) - : Obj(Dumper.getElfObject().getELFFile()), ElfObj(Dumper.getElfObject()), - Dumper(Dumper) { - FileName = ElfObj.getFileName(); - } - - virtual ~DumpStyle() = default; - - virtual void printFileHeaders() = 0; - virtual void printGroupSections() = 0; - virtual void printRelocations() = 0; - virtual void printSectionHeaders() = 0; - virtual void printSymbols(bool PrintSymbols, bool PrintDynamicSymbols) = 0; - virtual void printHashSymbols() {} - virtual void printSectionDetails() {} - virtual void printDependentLibs() = 0; - virtual void printDynamic() {} - virtual void printDynamicRelocations() = 0; - virtual void printSymtabMessage(const Elf_Shdr *Symtab, size_t Offset, - bool NonVisibilityBitsUsed) {} - virtual void printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, - Optional StrTable, bool IsDynamic, - bool NonVisibilityBitsUsed) = 0; - virtual void printProgramHeaders(bool PrintProgramHeaders, - cl::boolOrDefault PrintSectionMapping) = 0; - virtual void printVersionSymbolSection(const Elf_Shdr *Sec) = 0; - virtual void printVersionDefinitionSection(const Elf_Shdr *Sec) = 0; - virtual void printVersionDependencySection(const Elf_Shdr *Sec) = 0; - virtual void printHashHistograms() = 0; - virtual void printCGProfile() = 0; - virtual void printAddrsig() = 0; - virtual void printNotes() = 0; - virtual void printELFLinkerOptions() = 0; - virtual void printStackSizes() = 0; - void printNonRelocatableStackSizes(std::function PrintHeader); - void printRelocatableStackSizes(std::function PrintHeader); - bool printFunctionStackSize(uint64_t SymValue, - Optional FunctionSec, - const Elf_Shdr &StackSizeSec, DataExtractor Data, - uint64_t *Offset); - void printStackSize(const Relocation &R, const Elf_Shdr &RelocSec, - unsigned Ndx, const Elf_Shdr *SymTab, - const Elf_Shdr *FunctionSec, const Elf_Shdr &StackSizeSec, - const RelocationResolver &Resolver, DataExtractor Data); - virtual void printStackSizeEntry(uint64_t Size, StringRef FuncName) = 0; - virtual void printMipsGOT(const MipsGOTParser &Parser) = 0; - virtual void printMipsPLT(const MipsGOTParser &Parser) = 0; - virtual void printMipsABIFlags() = 0; - const ELFDumper &dumper() const { return Dumper; } - void reportUniqueWarning(Error Err) const; - void reportUniqueWarning(const Twine &Msg) const; - -protected: - std::vector getGroups(); - - void printDependentLibsHelper( - function_ref OnSectionStart, - function_ref OnSectionEntry); - - virtual void printReloc(const Relocation &R, unsigned RelIndex, - const Elf_Shdr &Sec, const Elf_Shdr *SymTab) = 0; - virtual void printRelrReloc(const Elf_Relr &R) = 0; - virtual void printDynamicReloc(const Relocation &R) = 0; - void forEachRelocationDo( - const Elf_Shdr &Sec, bool RawRelr, - llvm::function_ref &, unsigned, - const Elf_Shdr &, const Elf_Shdr *)> - RelRelaFn, - llvm::function_ref RelrFn); - void printRelocationsHelper(const Elf_Shdr &Sec); - void printDynamicRelocationsHelper(); - virtual void printDynamicRelocHeader(unsigned Type, StringRef Name, - const DynRegionInfo &Reg){}; - - StringRef getPrintableSectionName(const Elf_Shdr &Sec) const; - - StringRef FileName; - const ELFFile &Obj; - const ELFObjectFile &ElfObj; - -private: - const ELFDumper &Dumper; -}; - -template class GNUStyle : public DumpStyle { +template class GNUELFDumper : public ELFDumper { formatted_raw_ostream &OS; public: LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) - GNUStyle(ScopedPrinter &W, const ELFDumper &Dumper) - : DumpStyle(Dumper), - OS(static_cast(W.getOStream())) { + GNUELFDumper(const object::ELFObjectFile &ObjF, ScopedPrinter &Writer) + : ELFDumper(ObjF, Writer), + OS(static_cast(Writer.getOStream())) { assert(&W.getOStream() == &llvm::fouts()); } @@ -826,10 +746,10 @@ template class GNUStyle : public DumpStyle { void printHashSymbols() override; void printSectionDetails() override; void printDependentLibs() override; - void printDynamic() override; + void printDynamicTable() override; void printDynamicRelocations() override; void printSymtabMessage(const Elf_Shdr *Symtab, size_t Offset, - bool NonVisibilityBitsUsed) override; + bool NonVisibilityBitsUsed) const override; void printProgramHeaders(bool PrintProgramHeaders, cl::boolOrDefault PrintSectionMapping) override; void printVersionSymbolSection(const Elf_Shdr *Sec) override; @@ -841,15 +761,10 @@ template class GNUStyle : public DumpStyle { void printNotes() override; void printELFLinkerOptions() override; void printStackSizes() override; - void printStackSizeEntry(uint64_t Size, StringRef FuncName) override; - void printMipsGOT(const MipsGOTParser &Parser) override; - void printMipsPLT(const MipsGOTParser &Parser) override; - void printMipsABIFlags() override; private: void printHashHistogram(const Elf_Hash &HashTable); void printGnuHashHistogram(const Elf_GnuHash &GnuHashTable); - void printHashTableSymbols(const Elf_Hash &HashTable); void printGnuHashTableSymbols(const Elf_GnuHash &GnuHashTable); @@ -862,7 +777,7 @@ template class GNUStyle : public DumpStyle { }; template - std::string printEnum(T Value, ArrayRef> EnumValues) { + std::string printEnum(T Value, ArrayRef> EnumValues) const { for (const EnumEntry &EnumItem : EnumValues) if (EnumItem.Value == Value) return std::string(EnumItem.AltName); @@ -872,7 +787,7 @@ template class GNUStyle : public DumpStyle { template std::string printFlags(T Value, ArrayRef> EnumValues, TEnum EnumMask1 = {}, TEnum EnumMask2 = {}, - TEnum EnumMask3 = {}) { + TEnum EnumMask3 = {}) const { std::string Str; for (const EnumEntry &Flag : EnumValues) { if (Flag.Value == 0) @@ -896,7 +811,7 @@ template class GNUStyle : public DumpStyle { return Str; } - formatted_raw_ostream &printField(struct Field F) { + formatted_raw_ostream &printField(struct Field F) const { if (F.Column != 0) OS.PadToColumn(F.Column); OS << F.Str; @@ -905,42 +820,35 @@ template class GNUStyle : public DumpStyle { } void printHashedSymbol(const Elf_Sym *Sym, unsigned SymIndex, StringRef StrTable, uint32_t Bucket); - void printReloc(const Relocation &R, unsigned RelIndex, - const Elf_Shdr &Sec, const Elf_Shdr *SymTab) override; void printRelrReloc(const Elf_Relr &R) override; - void printRelRelaReloc(const Relocation &R, - const RelSymbol &RelSym); + const RelSymbol &RelSym) override; void printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, Optional StrTable, bool IsDynamic, - bool NonVisibilityBitsUsed) override; + bool NonVisibilityBitsUsed) const override; void printDynamicRelocHeader(unsigned Type, StringRef Name, const DynRegionInfo &Reg) override; - void printDynamicReloc(const Relocation &R) override; - std::string getSymbolSectionNdx(const Elf_Sym &Symbol, unsigned SymIndex); + std::string getSymbolSectionNdx(const Elf_Sym &Symbol, + unsigned SymIndex) const; void printProgramHeaders(); void printSectionMapping(); void printGNUVersionSectionProlog(const typename ELFT::Shdr &Sec, const Twine &Label, unsigned EntriesNum); -}; -template -void DumpStyle::reportUniqueWarning(Error Err) const { - this->dumper().reportUniqueWarning(std::move(Err)); -} + void printStackSizeEntry(uint64_t Size, StringRef FuncName) override; -template -void DumpStyle::reportUniqueWarning(const Twine &Msg) const { - this->dumper().reportUniqueWarning(Msg); -} + void printMipsGOT(const MipsGOTParser &Parser) override; + void printMipsPLT(const MipsGOTParser &Parser) override; + void printMipsABIFlags() override; +}; -template class LLVMStyle : public DumpStyle { +template class LLVMELFDumper : public ELFDumper { public: LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) - LLVMStyle(ScopedPrinter &W, const ELFDumper &Dumper) - : DumpStyle(Dumper), W(W) {} + LLVMELFDumper(const object::ELFObjectFile &ObjF, ScopedPrinter &Writer) + : ELFDumper(ObjF, Writer), W(Writer) {} void printFileHeaders() override; void printGroupSections() override; @@ -948,7 +856,7 @@ template class LLVMStyle : public DumpStyle { void printSectionHeaders() override; void printSymbols(bool PrintSymbols, bool PrintDynamicSymbols) override; void printDependentLibs() override; - void printDynamic() override; + void printDynamicTable() override; void printDynamicRelocations() override; void printProgramHeaders(bool PrintProgramHeaders, cl::boolOrDefault PrintSectionMapping) override; @@ -961,26 +869,23 @@ template class LLVMStyle : public DumpStyle { void printNotes() override; void printELFLinkerOptions() override; void printStackSizes() override; - void printStackSizeEntry(uint64_t Size, StringRef FuncName) override; - void printMipsGOT(const MipsGOTParser &Parser) override; - void printMipsPLT(const MipsGOTParser &Parser) override; - void printMipsABIFlags() override; private: - void printReloc(const Relocation &R, unsigned RelIndex, - const Elf_Shdr &Sec, const Elf_Shdr *SymTab) override; void printRelrReloc(const Elf_Relr &R) override; - void printDynamicReloc(const Relocation &R) override; + void printRelRelaReloc(const Relocation &R, + const RelSymbol &RelSym) override; - void printRelRelaReloc(const Relocation &R, StringRef SymbolName); - void printSymbols(); - void printDynamicSymbols(); - void printSymbolSection(const Elf_Sym &Symbol, unsigned SymIndex); + void printSymbolSection(const Elf_Sym &Symbol, unsigned SymIndex) const; void printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, Optional StrTable, bool IsDynamic, - bool /*NonVisibilityBitsUsed*/) override; + bool /*NonVisibilityBitsUsed*/) const override; void printProgramHeaders(); void printSectionMapping() {} + void printStackSizeEntry(uint64_t Size, StringRef FuncName) override; + + void printMipsGOT(const MipsGOTParser &Parser) override; + void printMipsPLT(const MipsGOTParser &Parser) override; + void printMipsABIFlags() override; ScopedPrinter &W; }; @@ -990,9 +895,11 @@ template class LLVMStyle : public DumpStyle { namespace llvm { template -static std::unique_ptr createELFDumper(const ELFObjectFile &Obj, - ScopedPrinter &Writer) { - return std::make_unique>(Obj, Writer); +static std::unique_ptr +createELFDumper(const ELFObjectFile &Obj, ScopedPrinter &Writer) { + if (opts::Output == opts::GNU) + return std::make_unique>(Obj, Writer); + return std::make_unique>(Obj, Writer); } std::unique_ptr createELFDumper(const object::ELFObjectFileBase &Obj, @@ -1076,7 +983,7 @@ Expected ELFDumper::getSymbolVersion(const Elf_Sym &Sym, // Get the corresponding version index entry. if (Expected EntryOrErr = Obj.template getEntry(*SymbolVersionSection, EntryIndex)) - return this->getSymbolVersionByIndex((*EntryOrErr)->vs_index, IsDefault); + return getSymbolVersionByIndex((*EntryOrErr)->vs_index, IsDefault); else return EntryOrErr.takeError(); } @@ -1116,8 +1023,8 @@ static std::string maybeDemangle(StringRef Name) { template std::string ELFDumper::getStaticSymbolName(uint32_t Index) const { auto Warn = [&](Error E) -> std::string { - this->reportUniqueWarning("unable to read the name of symbol with index " + - Twine(Index) + ": " + toString(std::move(E))); + reportUniqueWarning("unable to read the name of symbol with index " + + Twine(Index) + ": " + toString(std::move(E))); return ""; }; @@ -1860,7 +1767,7 @@ ELFDumper::findDynamic() { break; } } else { - this->reportUniqueWarning( + reportUniqueWarning( "unable to read program headers to locate the PT_DYNAMIC segment: " + toString(PhdrsOrErr.takeError())); } @@ -1991,13 +1898,9 @@ template ELFDumper::ELFDumper(const object::ELFObjectFile &O, ScopedPrinter &Writer) : ObjDumper(Writer, O.getFileName()), ObjF(O), Obj(O.getELFFile()), - DynRelRegion(O, *this), DynRelaRegion(O, *this), DynRelrRegion(O, *this), + FileName(O.getFileName()), DynRelRegion(O, *this), + DynRelaRegion(O, *this), DynRelrRegion(O, *this), DynPLTRelRegion(O, *this), DynamicTable(O, *this) { - if (opts::Output == opts::GNU) - ELFDumperStyle.reset(new GNUStyle(Writer, *this)); - else - ELFDumperStyle.reset(new LLVMStyle(Writer, *this)); - if (!O.IsContentValid()) return; @@ -2252,90 +2155,15 @@ template void ELFDumper::parseDynamicTable() { } } -template -typename ELFDumper::Elf_Rel_Range ELFDumper::dyn_rels() const { - return DynRelRegion.getAsArrayRef(); -} - -template -typename ELFDumper::Elf_Rela_Range ELFDumper::dyn_relas() const { - return DynRelaRegion.getAsArrayRef(); -} - -template -typename ELFDumper::Elf_Relr_Range ELFDumper::dyn_relrs() const { - return DynRelrRegion.getAsArrayRef(); -} - -template void ELFDumper::printFileHeaders() { - ELFDumperStyle->printFileHeaders(); -} - -template void ELFDumper::printSectionHeaders() { - ELFDumperStyle->printSectionHeaders(); -} - -template void ELFDumper::printRelocations() { - ELFDumperStyle->printRelocations(); -} - -template -void ELFDumper::printProgramHeaders( - bool PrintProgramHeaders, cl::boolOrDefault PrintSectionMapping) { - ELFDumperStyle->printProgramHeaders(PrintProgramHeaders, PrintSectionMapping); -} - template void ELFDumper::printVersionInfo() { // Dump version symbol section. - ELFDumperStyle->printVersionSymbolSection(SymbolVersionSection); + printVersionSymbolSection(SymbolVersionSection); // Dump version definition section. - ELFDumperStyle->printVersionDefinitionSection(SymbolVersionDefSection); + printVersionDefinitionSection(SymbolVersionDefSection); // Dump version dependency section. - ELFDumperStyle->printVersionDependencySection(SymbolVersionNeedSection); -} - -template void ELFDumper::printDependentLibs() { - ELFDumperStyle->printDependentLibs(); -} - -template void ELFDumper::printDynamicRelocations() { - ELFDumperStyle->printDynamicRelocations(); -} - -template -void ELFDumper::printSymbols(bool PrintSymbols, - bool PrintDynamicSymbols) { - ELFDumperStyle->printSymbols(PrintSymbols, PrintDynamicSymbols); -} - -template void ELFDumper::printHashSymbols() { - ELFDumperStyle->printHashSymbols(); -} - -template void ELFDumper::printSectionDetails() { - ELFDumperStyle->printSectionDetails(); -} - -template void ELFDumper::printHashHistograms() { - ELFDumperStyle->printHashHistograms(); -} - -template void ELFDumper::printCGProfile() { - ELFDumperStyle->printCGProfile(); -} - -template void ELFDumper::printNotes() { - ELFDumperStyle->printNotes(); -} - -template void ELFDumper::printELFLinkerOptions() { - ELFDumperStyle->printELFLinkerOptions(); -} - -template void ELFDumper::printStackSizes() { - ELFDumperStyle->printStackSizes(); + printVersionDependencySection(SymbolVersionNeedSection); } #define LLVM_READOBJ_DT_FLAG_ENT(prefix, enum) \ @@ -2641,8 +2469,6 @@ template void ELFDumper::printUnwindInfo() { Ctx.printUnwindInformation(); } -namespace { - template <> void ELFDumper::printUnwindInfo() { if (Obj.getHeader().e_machine == EM_ARM) { ARM::EHABI::PrinterContext Ctx(W, Obj, ObjF.getFileName(), @@ -2653,12 +2479,6 @@ template <> void ELFDumper::printUnwindInfo() { Ctx.printUnwindInformation(); } -} // end anonymous namespace - -template void ELFDumper::printDynamicTable() { - ELFDumperStyle->printDynamic(); -} - template void ELFDumper::printNeededLibraries() { ListScope D(W, "NeededLibraries"); @@ -2842,19 +2662,19 @@ template void ELFDumper::printArchSpecificInfo() { printAttributes(); break; case EM_MIPS: { - ELFDumperStyle->printMipsABIFlags(); + printMipsABIFlags(); printMipsOptions(); printMipsReginfo(); MipsGOTParser Parser(*this); if (Error E = Parser.findGOT(dynamic_table(), dynamic_symbols())) reportUniqueWarning(std::move(E)); else if (!Parser.isGotEmpty()) - ELFDumperStyle->printMipsGOT(Parser); + printMipsGOT(Parser); if (Error E = Parser.findPLT(dynamic_table())) reportUniqueWarning(std::move(E)); else if (!Parser.isPltEmpty()) - ELFDumperStyle->printMipsPLT(Parser); + printMipsPLT(Parser); break; } default: @@ -3427,12 +3247,16 @@ template void ELFDumper::printStackMap() const { prettyPrintStackMap(W, StackMapParser(*ContentOrErr)); } -template void ELFDumper::printGroupSections() { - ELFDumperStyle->printGroupSections(); -} - -template void ELFDumper::printAddrsig() { - ELFDumperStyle->printAddrsig(); +template +void ELFDumper::printReloc(const Relocation &R, unsigned RelIndex, + const Elf_Shdr &Sec, const Elf_Shdr *SymTab) { + Expected> Target = getRelocationTarget(R, SymTab); + if (!Target) + reportUniqueWarning("unable to print relocation " + Twine(RelIndex) + + " in " + describe(Sec) + ": " + + toString(Target.takeError())); + else + printRelRelaReloc(R, *Target); } static inline void printFields(formatted_raw_ostream &OS, StringRef Str1, @@ -3494,7 +3318,7 @@ static const EnumEntry *getObjectFileEnumEntry(unsigned Type) { return nullptr; } -template void GNUStyle::printFileHeaders() { +template void GNUELFDumper::printFileHeaders() { const Elf_Ehdr &e = this->Obj.getHeader(); OS << "ELF Header:\n"; OS << " Magic: "; @@ -3566,13 +3390,13 @@ template void GNUStyle::printFileHeaders() { printFields(OS, "Section header string table index:", Str); } -template std::vector DumpStyle::getGroups() { +template std::vector ELFDumper::getGroups() { auto GetSignature = [&](const Elf_Sym &Sym, unsigned SymNdx, const Elf_Shdr &Symtab) -> StringRef { Expected StrTableOrErr = Obj.getStringTableForSymtab(Symtab); if (!StrTableOrErr) { reportUniqueWarning("unable to get the string table for " + - describe(Obj, Symtab) + ": " + + describe(Symtab) + ": " + toString(StrTableOrErr.takeError())); return ""; } @@ -3604,11 +3428,11 @@ template std::vector DumpStyle::getGroups() { Signature = GetSignature(**SymOrErr, Sec.sh_info, **SymtabOrErr); else reportUniqueWarning("unable to get the signature symbol for " + - describe(Obj, Sec) + ": " + + describe(Sec) + ": " + toString(SymOrErr.takeError())); } else { reportUniqueWarning("unable to get the symbol table for " + - describe(Obj, Sec) + ": " + + describe(Sec) + ": " + toString(SymtabOrErr.takeError())); } @@ -3617,13 +3441,12 @@ template std::vector DumpStyle::getGroups() { Obj.template getSectionContentsAsArray(Sec)) { if (ContentsOrErr->empty()) reportUniqueWarning("unable to read the section group flag from the " + - describe(Obj, Sec) + ": the section is empty"); + describe(Sec) + ": the section is empty"); else Data = *ContentsOrErr; } else { - reportUniqueWarning("unable to get the content of the " + - describe(Obj, Sec) + ": " + - toString(ContentsOrErr.takeError())); + reportUniqueWarning("unable to get the content of the " + describe(Sec) + + ": " + toString(ContentsOrErr.takeError())); } Ret.push_back({getPrintableSectionName(Sec), @@ -3644,9 +3467,8 @@ template std::vector DumpStyle::getGroups() { GM.push_back({getPrintableSectionName(**SecOrErr), Ndx}); } else { reportUniqueWarning("unable to get the section with index " + - Twine(Ndx) + " when dumping the " + - describe(Obj, Sec) + ": " + - toString(SecOrErr.takeError())); + Twine(Ndx) + " when dumping the " + describe(Sec) + + ": " + toString(SecOrErr.takeError())); GM.push_back({"", Ndx}); } } @@ -3663,7 +3485,7 @@ mapSectionsToGroups(ArrayRef Groups) { return Ret; } -template void GNUStyle::printGroupSections() { +template void GNUELFDumper::printGroupSections() { std::vector V = this->getGroups(); DenseMap Map = mapSectionsToGroups(V); for (const GroupSection &G : V) { @@ -3690,25 +3512,13 @@ template void GNUStyle::printGroupSections() { } template -void GNUStyle::printReloc(const Relocation &R, unsigned RelIndex, - const Elf_Shdr &Sec, const Elf_Shdr *SymTab) { - Expected> Target = - this->dumper().getRelocationTarget(R, SymTab); - if (!Target) - this->reportUniqueWarning("unable to print relocation " + Twine(RelIndex) + - " in " + describe(this->Obj, Sec) + ": " + - toString(Target.takeError())); - else - printRelRelaReloc(R, *Target); -} - -template void GNUStyle::printRelrReloc(const Elf_Relr &R) { +void GNUELFDumper::printRelrReloc(const Elf_Relr &R) { OS << to_string(format_hex_no_prefix(R, ELFT::Is64Bits ? 16 : 8)) << "\n"; } template -void GNUStyle::printRelRelaReloc(const Relocation &R, - const RelSymbol &RelSym) { +void GNUELFDumper::printRelRelaReloc(const Relocation &R, + const RelSymbol &RelSym) { // First two fields are bit width dependent. The rest of them are fixed width. unsigned Bias = ELFT::Is64Bits ? 8 : 0; Field Fields[5] = {0, 10 + Bias, 19 + 2 * Bias, 42 + 2 * Bias, 53 + 2 * Bias}; @@ -3768,8 +3578,8 @@ static void printRelocHeaderFields(formatted_raw_ostream &OS, unsigned SType) { } template -void GNUStyle::printDynamicRelocHeader(unsigned Type, StringRef Name, - const DynRegionInfo &Reg) { +void GNUELFDumper::printDynamicRelocHeader(unsigned Type, StringRef Name, + const DynRegionInfo &Reg) { uint64_t Offset = Reg.Addr - this->Obj.base(); OS << "\n'" << Name.str().c_str() << "' relocation section at offset 0x" << to_hexString(Offset, false) << " contains " << Reg.Size << " bytes:\n"; @@ -3784,7 +3594,7 @@ static bool isRelocationSec(const typename ELFT::Shdr &Sec) { Sec.sh_type == ELF::SHT_ANDROID_RELR; } -template void GNUStyle::printRelocations() { +template void GNUELFDumper::printRelocations() { auto GetEntriesNum = [&](const Elf_Shdr &Sec) -> Expected { // Android's packed relocation section needs to be unpacked first // to get the actual number of entries. @@ -3819,7 +3629,7 @@ template void GNUStyle::printRelocations() { EntriesNum = std::to_string(*NumOrErr); else this->reportUniqueWarning("unable to get the number of relocations in " + - describe(this->Obj, Sec) + ": " + + this->describe(Sec) + ": " + toString(NumOrErr.takeError())); uintX_t Offset = Sec.sh_offset; @@ -3886,7 +3696,7 @@ static void printSectionDescription(formatted_raw_ostream &OS, OS << "p (processor specific)\n"; } -template void GNUStyle::printSectionHeaders() { +template void GNUELFDumper::printSectionHeaders() { unsigned Bias = ELFT::Is64Bits ? 0 : 8; ArrayRef Sections = cantFail(this->Obj.sections()); OS << "There are " << to_string(Sections.size()) @@ -3903,8 +3713,8 @@ template void GNUStyle::printSectionHeaders() { OS << "\n"; StringRef SecStrTable; - if (Expected SecStrTableOrErr = this->Obj.getSectionStringTable( - Sections, this->dumper().WarningHandler)) + if (Expected SecStrTableOrErr = + this->Obj.getSectionStringTable(Sections, this->WarningHandler)) SecStrTable = *SecStrTableOrErr; else this->reportUniqueWarning(SecStrTableOrErr.takeError()); @@ -3948,8 +3758,9 @@ template void GNUStyle::printSectionHeaders() { } template -void GNUStyle::printSymtabMessage(const Elf_Shdr *Symtab, size_t Entries, - bool NonVisibilityBitsUsed) { +void GNUELFDumper::printSymtabMessage(const Elf_Shdr *Symtab, + size_t Entries, + bool NonVisibilityBitsUsed) const { StringRef Name; if (Symtab) Name = this->getPrintableSectionName(*Symtab); @@ -3970,8 +3781,8 @@ void GNUStyle::printSymtabMessage(const Elf_Shdr *Symtab, size_t Entries, } template -std::string GNUStyle::getSymbolSectionNdx(const Elf_Sym &Symbol, - unsigned SymIndex) { +std::string GNUELFDumper::getSymbolSectionNdx(const Elf_Sym &Symbol, + unsigned SymIndex) const { unsigned SectionIndex = Symbol.st_shndx; switch (SectionIndex) { case ELF::SHN_UNDEF: @@ -3982,7 +3793,7 @@ std::string GNUStyle::getSymbolSectionNdx(const Elf_Sym &Symbol, return "COM"; case ELF::SHN_XINDEX: { Expected IndexOrErr = object::getExtendedSymbolTableIndex( - Symbol, SymIndex, this->dumper().getShndxTable()); + Symbol, SymIndex, this->ShndxTable); if (!IndexOrErr) { assert(Symbol.st_shndx == SHN_XINDEX && "getExtendedSymbolTableIndex should only fail due to an invalid " @@ -4013,9 +3824,10 @@ std::string GNUStyle::getSymbolSectionNdx(const Elf_Sym &Symbol, } template -void GNUStyle::printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, - Optional StrTable, bool IsDynamic, - bool NonVisibilityBitsUsed) { +void GNUELFDumper::printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, + Optional StrTable, + bool IsDynamic, + bool NonVisibilityBitsUsed) const { unsigned Bias = ELFT::Is64Bits ? 8 : 0; Field Fields[8] = {0, 8, 17 + Bias, 23 + Bias, 31 + Bias, 38 + Bias, 48 + Bias, 51 + Bias}; @@ -4056,15 +3868,17 @@ void GNUStyle::printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, Fields[6].Str = getSymbolSectionNdx(Symbol, SymIndex); Fields[7].Str = - this->dumper().getFullSymbolName(Symbol, SymIndex, StrTable, IsDynamic); + this->getFullSymbolName(Symbol, SymIndex, StrTable, IsDynamic); for (const Field &Entry : Fields) printField(Entry); OS << "\n"; } template -void GNUStyle::printHashedSymbol(const Elf_Sym *Symbol, unsigned SymIndex, - StringRef StrTable, uint32_t Bucket) { +void GNUELFDumper::printHashedSymbol(const Elf_Sym *Symbol, + unsigned SymIndex, + StringRef StrTable, + uint32_t Bucket) { unsigned Bias = ELFT::Is64Bits ? 8 : 0; Field Fields[9] = {0, 6, 11, 20 + Bias, 25 + Bias, 34 + Bias, 41 + Bias, 49 + Bias, 53 + Bias}; @@ -4087,8 +3901,7 @@ void GNUStyle::printHashedSymbol(const Elf_Sym *Symbol, unsigned SymIndex, Fields[6].Str = printEnum(Symbol->getVisibility(), makeArrayRef(ElfSymbolVisibilities)); Fields[7].Str = getSymbolSectionNdx(*Symbol, SymIndex); - Fields[8].Str = - this->dumper().getFullSymbolName(*Symbol, SymIndex, StrTable, true); + Fields[8].Str = this->getFullSymbolName(*Symbol, SymIndex, StrTable, true); for (const Field &Entry : Fields) printField(Entry); @@ -4096,19 +3909,19 @@ void GNUStyle::printHashedSymbol(const Elf_Sym *Symbol, unsigned SymIndex, } template -void GNUStyle::printSymbols(bool PrintSymbols, bool PrintDynamicSymbols) { +void GNUELFDumper::printSymbols(bool PrintSymbols, + bool PrintDynamicSymbols) { if (!PrintSymbols && !PrintDynamicSymbols) return; // GNU readelf prints both the .dynsym and .symtab with --symbols. - this->dumper().printSymbolsHelper(true); + this->printSymbolsHelper(true); if (PrintSymbols) - this->dumper().printSymbolsHelper(false); + this->printSymbolsHelper(false); } template -void GNUStyle::printHashTableSymbols(const Elf_Hash &SysVHash) { - StringRef StringTable = this->dumper().getDynamicStringTable(); - if (StringTable.empty()) +void GNUELFDumper::printHashTableSymbols(const Elf_Hash &SysVHash) { + if (this->DynamicStringTable.empty()) return; if (ELFT::Is64Bits) @@ -4117,14 +3930,13 @@ void GNUStyle::printHashTableSymbols(const Elf_Hash &SysVHash) { OS << " Num Buc: Value Size Type Bind Vis Ndx Name"; OS << "\n"; - Elf_Sym_Range DynSyms = this->dumper().dynamic_symbols(); + Elf_Sym_Range DynSyms = this->dynamic_symbols(); const Elf_Sym *FirstSym = DynSyms.empty() ? nullptr : &DynSyms[0]; if (!FirstSym) { - Optional DynSymRegion = this->dumper().getDynSymRegion(); this->reportUniqueWarning( Twine("unable to print symbols for the .hash table: the " "dynamic symbol table ") + - (DynSymRegion ? "is empty" : "was not found")); + (this->DynSymRegion ? "is empty" : "was not found")); return; } @@ -4145,26 +3957,24 @@ void GNUStyle::printHashTableSymbols(const Elf_Hash &SysVHash) { break; } - printHashedSymbol(FirstSym + Ch, Ch, StringTable, Buc); + printHashedSymbol(FirstSym + Ch, Ch, this->DynamicStringTable, Buc); Visited[Ch] = true; } } } template -void GNUStyle::printGnuHashTableSymbols(const Elf_GnuHash &GnuHash) { - StringRef StringTable = this->dumper().getDynamicStringTable(); - if (StringTable.empty()) +void GNUELFDumper::printGnuHashTableSymbols(const Elf_GnuHash &GnuHash) { + if (this->DynamicStringTable.empty()) return; - Elf_Sym_Range DynSyms = this->dumper().dynamic_symbols(); + Elf_Sym_Range DynSyms = this->dynamic_symbols(); const Elf_Sym *FirstSym = DynSyms.empty() ? nullptr : &DynSyms[0]; - Optional DynSymRegion = this->dumper().getDynSymRegion(); if (!FirstSym) { this->reportUniqueWarning( Twine("unable to print symbols for the .gnu.hash table: the " "dynamic symbol table ") + - (DynSymRegion ? "is empty" : "was not found")); + (this->DynSymRegion ? "is empty" : "was not found")); return; } @@ -4182,7 +3992,7 @@ void GNUStyle::printGnuHashTableSymbols(const Elf_GnuHash &GnuHash) { }; Expected> ValuesOrErr = - getGnuHashTableChains(DynSymRegion, &GnuHash); + getGnuHashTableChains(this->DynSymRegion, &GnuHash); ArrayRef Values; if (!ValuesOrErr) this->reportUniqueWarning("unable to get hash values for the SHT_GNU_HASH " @@ -4200,7 +4010,7 @@ void GNUStyle::printGnuHashTableSymbols(const Elf_GnuHash &GnuHash) { while (true) { uint32_t SymIndex = Index++; if (const Elf_Sym *Sym = GetSymbol(SymIndex, DynSyms.size())) - printHashedSymbol(Sym, SymIndex, StringTable, Buc); + printHashedSymbol(Sym, SymIndex, this->DynamicStringTable, Buc); else break; @@ -4220,17 +4030,17 @@ void GNUStyle::printGnuHashTableSymbols(const Elf_GnuHash &GnuHash) { } } -template void GNUStyle::printHashSymbols() { - if (const Elf_Hash *SysVHash = this->dumper().getHashTable()) { +template void GNUELFDumper::printHashSymbols() { + if (this->HashTable) { OS << "\n Symbol table of .hash for image:\n"; - if (Error E = checkHashTable(this->dumper(), SysVHash)) + if (Error E = checkHashTable(*this, this->HashTable)) this->reportUniqueWarning(std::move(E)); else - printHashTableSymbols(*SysVHash); + printHashTableSymbols(*this->HashTable); } // Try printing the .gnu.hash table. - if (const Elf_GnuHash *GnuHash = this->dumper().getGnuHashTable()) { + if (this->GnuHashTable) { OS << "\n Symbol table of .gnu.hash for image:\n"; if (ELFT::Is64Bits) OS << " Num Buc: Value Size Type Bind Vis Ndx Name"; @@ -4238,14 +4048,14 @@ template void GNUStyle::printHashSymbols() { OS << " Num Buc: Value Size Type Bind Vis Ndx Name"; OS << "\n"; - if (Error E = checkGNUHashTable(this->Obj, GnuHash)) + if (Error E = checkGNUHashTable(this->Obj, this->GnuHashTable)) this->reportUniqueWarning(std::move(E)); else - printGnuHashTableSymbols(*GnuHash); + printGnuHashTableSymbols(*this->GnuHashTable); } } -template void GNUStyle::printSectionDetails() { +template void GNUELFDumper::printSectionDetails() { ArrayRef Sections = cantFail(this->Obj.sections()); OS << "There are " << to_string(Sections.size()) << " section headers, starting at offset " @@ -4273,8 +4083,8 @@ template void GNUStyle::printSectionDetails() { PrintFields({{"Flags", 7}}); StringRef SecStrTable; - if (Expected SecStrTableOrErr = this->Obj.getSectionStringTable( - Sections, this->dumper().WarningHandler)) + if (Expected SecStrTableOrErr = + this->Obj.getSectionStringTable(Sections, this->WarningHandler)) SecStrTable = *SecStrTableOrErr; else this->reportUniqueWarning(SecStrTableOrErr.takeError()); @@ -4435,7 +4245,7 @@ static bool checkPTDynamic(const typename ELFT::Phdr &Phdr, } template -void GNUStyle::printProgramHeaders( +void GNUELFDumper::printProgramHeaders( bool PrintProgramHeaders, cl::boolOrDefault PrintSectionMapping) { if (PrintProgramHeaders) printProgramHeaders(); @@ -4446,7 +4256,7 @@ void GNUStyle::printProgramHeaders( printSectionMapping(); } -template void GNUStyle::printProgramHeaders() { +template void GNUELFDumper::printProgramHeaders() { unsigned Bias = ELFT::Is64Bits ? 8 : 0; const Elf_Ehdr &Header = this->Obj.getHeader(); Field Fields[8] = {2, 17, 26, 37 + Bias, @@ -4515,7 +4325,7 @@ template void GNUStyle::printProgramHeaders() { } } -template void GNUStyle::printSectionMapping() { +template void GNUELFDumper::printSectionMapping() { OS << "\n Section to Segment mapping:\n Segment Sections...\n"; DenseSet BelongsToSegment; int Phnum = 0; @@ -4611,11 +4421,6 @@ RelSymbol getSymbolForReloc(const ELFDumper &Dumper, } } // namespace -template -void GNUStyle::printDynamicReloc(const Relocation &R) { - printRelRelaReloc(R, getSymbolForReloc(this->dumper(), R)); -} - template static size_t getMaxDynamicTagSize(const ELFFile &Obj, typename ELFT::DynRange Tags) { @@ -4625,14 +4430,13 @@ static size_t getMaxDynamicTagSize(const ELFFile &Obj, return Max; } -template void GNUStyle::printDynamic() { - Elf_Dyn_Range Table = this->dumper().dynamic_table(); +template void GNUELFDumper::printDynamicTable() { + Elf_Dyn_Range Table = this->dynamic_table(); if (Table.empty()) return; OS << "Dynamic section at offset " - << format_hex(reinterpret_cast( - this->dumper().getDynamicTableRegion().Addr) - + << format_hex(reinterpret_cast(this->DynamicTable.Addr) - this->Obj.base(), 1) << " contains " << Table.size() << " entries:\n"; @@ -4650,18 +4454,23 @@ template void GNUStyle::printDynamic() { uintX_t Tag = Entry.getTag(); std::string Type = std::string("(") + this->Obj.getDynamicTagAsString(Tag).c_str() + ")"; - std::string Value = this->dumper().getDynamicEntry(Tag, Entry.getVal()); + std::string Value = this->getDynamicEntry(Tag, Entry.getVal()); OS << " " << format_hex(Tag, ELFT::Is64Bits ? 18 : 10) << format(ValueFmt.c_str(), Type.c_str()) << Value << "\n"; } } -template void GNUStyle::printDynamicRelocations() { +template void GNUELFDumper::printDynamicRelocations() { this->printDynamicRelocationsHelper(); } template -void DumpStyle::printRelocationsHelper(const Elf_Shdr &Sec) { +void ELFDumper::printDynamicReloc(const Relocation &R) { + printRelRelaReloc(R, getSymbolForReloc(*this, R)); +} + +template +void ELFDumper::printRelocationsHelper(const Elf_Shdr &Sec) { this->forEachRelocationDo( Sec, opts::RawRelr, [&](const Relocation &R, unsigned Ndx, const Elf_Shdr &Sec, @@ -4669,46 +4478,43 @@ void DumpStyle::printRelocationsHelper(const Elf_Shdr &Sec) { [&](const Elf_Relr &R) { printRelrReloc(R); }); } -template void DumpStyle::printDynamicRelocationsHelper() { +template void ELFDumper::printDynamicRelocationsHelper() { const bool IsMips64EL = this->Obj.isMips64EL(); - const DynRegionInfo &DynRelaRegion = this->dumper().getDynRelaRegion(); - if (DynRelaRegion.Size > 0) { - printDynamicRelocHeader(ELF::SHT_RELA, "RELA", DynRelaRegion); - for (const Elf_Rela &Rela : this->dumper().dyn_relas()) + if ( this->DynRelaRegion.Size > 0) { + printDynamicRelocHeader(ELF::SHT_RELA, "RELA", this->DynRelaRegion); + for (const Elf_Rela &Rela : this->DynRelaRegion.getAsArrayRef()) printDynamicReloc(Relocation(Rela, IsMips64EL)); } - const DynRegionInfo &DynRelRegion = this->dumper().getDynRelRegion(); - if (DynRelRegion.Size > 0) { - printDynamicRelocHeader(ELF::SHT_REL, "REL", DynRelRegion); - for (const Elf_Rel &Rel : this->dumper().dyn_rels()) + if (this->DynRelRegion.Size > 0) { + printDynamicRelocHeader(ELF::SHT_REL, "REL", this->DynRelRegion); + for (const Elf_Rel &Rel : this->DynRelRegion.getAsArrayRef()) printDynamicReloc(Relocation(Rel, IsMips64EL)); } - const DynRegionInfo &DynRelrRegion = this->dumper().getDynRelrRegion(); - if (DynRelrRegion.Size > 0) { - printDynamicRelocHeader(ELF::SHT_REL, "RELR", DynRelrRegion); - Elf_Relr_Range Relrs = this->dumper().dyn_relrs(); + if (this->DynRelrRegion.Size > 0) { + printDynamicRelocHeader(ELF::SHT_REL, "RELR", this->DynRelrRegion); + Elf_Relr_Range Relrs = this->DynRelrRegion.getAsArrayRef(); for (const Elf_Rel &Rel : Obj.decode_relrs(Relrs)) printDynamicReloc(Relocation(Rel, IsMips64EL)); } - const DynRegionInfo &DynPLTRelRegion = this->dumper().getDynPLTRelRegion(); - if (DynPLTRelRegion.Size) { - if (DynPLTRelRegion.EntSize == sizeof(Elf_Rela)) { - printDynamicRelocHeader(ELF::SHT_RELA, "PLT", DynPLTRelRegion); - for (const Elf_Rela &Rela : DynPLTRelRegion.getAsArrayRef()) + if (this->DynPLTRelRegion.Size) { + if (this->DynPLTRelRegion.EntSize == sizeof(Elf_Rela)) { + printDynamicRelocHeader(ELF::SHT_RELA, "PLT", this->DynPLTRelRegion); + for (const Elf_Rela &Rela : + this->DynPLTRelRegion.getAsArrayRef()) printDynamicReloc(Relocation(Rela, IsMips64EL)); } else { - printDynamicRelocHeader(ELF::SHT_REL, "PLT", DynPLTRelRegion); - for (const Elf_Rel &Rel : DynPLTRelRegion.getAsArrayRef()) + printDynamicRelocHeader(ELF::SHT_REL, "PLT", this->DynPLTRelRegion); + for (const Elf_Rel &Rel : this->DynPLTRelRegion.getAsArrayRef()) printDynamicReloc(Relocation(Rel, IsMips64EL)); } } } template -void GNUStyle::printGNUVersionSectionProlog( +void GNUELFDumper::printGNUVersionSectionProlog( const typename ELFT::Shdr &Sec, const Twine &Label, unsigned EntriesNum) { // Don't inline the SecName, because it might report a warning to stderr and // corrupt the output. @@ -4722,7 +4528,7 @@ void GNUStyle::printGNUVersionSectionProlog( LinkedSecName = this->getPrintableSectionName(**LinkedSecOrErr); else this->reportUniqueWarning("invalid section linked to " + - describe(this->Obj, Sec) + ": " + + this->describe(Sec) + ": " + toString(LinkedSecOrErr.takeError())); OS << " Addr: " << format_hex_no_prefix(Sec.sh_addr, 16) @@ -4731,15 +4537,15 @@ void GNUStyle::printGNUVersionSectionProlog( } template -void GNUStyle::printVersionSymbolSection(const Elf_Shdr *Sec) { +void GNUELFDumper::printVersionSymbolSection(const Elf_Shdr *Sec) { if (!Sec) return; printGNUVersionSectionProlog(*Sec, "Version symbols", Sec->sh_size / sizeof(Elf_Versym)); Expected> VerTableOrErr = - this->dumper().getVersionTable(*Sec, /*SymTab=*/nullptr, - /*StrTab=*/nullptr); + this->getVersionTable(*Sec, /*SymTab=*/nullptr, + /*StrTab=*/nullptr); if (!VerTableOrErr) { this->reportUniqueWarning(VerTableOrErr.takeError()); return; @@ -4756,10 +4562,10 @@ void GNUStyle::printVersionSymbolSection(const Elf_Shdr *Sec) { bool IsDefault; Expected NameOrErr = - this->dumper().getSymbolVersionByIndex(Ndx, IsDefault); + this->getSymbolVersionByIndex(Ndx, IsDefault); if (!NameOrErr) { this->reportUniqueWarning("unable to get a version for entry " + - Twine(I) + " of " + describe(this->Obj, *Sec) + + Twine(I) + " of " + this->describe(*Sec) + ": " + toString(NameOrErr.takeError())); Versions.emplace_back(""); continue; @@ -4804,13 +4610,13 @@ static std::string versionFlagToString(unsigned Flags) { } template -void GNUStyle::printVersionDefinitionSection(const Elf_Shdr *Sec) { +void GNUELFDumper::printVersionDefinitionSection(const Elf_Shdr *Sec) { if (!Sec) return; printGNUVersionSectionProlog(*Sec, "Version definition", Sec->sh_info); - Expected> V = this->dumper().getVersionDefinitions(*Sec); + Expected> V = this->getVersionDefinitions(*Sec); if (!V) { this->reportUniqueWarning(V.takeError()); return; @@ -4831,15 +4637,14 @@ void GNUStyle::printVersionDefinitionSection(const Elf_Shdr *Sec) { } template -void GNUStyle::printVersionDependencySection(const Elf_Shdr *Sec) { +void GNUELFDumper::printVersionDependencySection(const Elf_Shdr *Sec) { if (!Sec) return; unsigned VerneedNum = Sec->sh_info; printGNUVersionSectionProlog(*Sec, "Version needs", VerneedNum); - Expected> V = - this->dumper().getVersionDependencies(*Sec); + Expected> V = this->getVersionDependencies(*Sec); if (!V) { this->reportUniqueWarning(V.takeError()); return; @@ -4857,7 +4662,7 @@ void GNUStyle::printVersionDependencySection(const Elf_Shdr *Sec) { } template -void GNUStyle::printHashHistogram(const Elf_Hash &HashTable) { +void GNUELFDumper::printHashHistogram(const Elf_Hash &HashTable) { size_t NBucket = HashTable.nbucket; size_t NChain = HashTable.nchain; ArrayRef Buckets = HashTable.buckets(); @@ -4912,9 +4717,10 @@ void GNUStyle::printHashHistogram(const Elf_Hash &HashTable) { } template -void GNUStyle::printGnuHashHistogram(const Elf_GnuHash &GnuHashTable) { - Expected> ChainsOrErr = getGnuHashTableChains( - this->dumper().getDynSymRegion(), &GnuHashTable); +void GNUELFDumper::printGnuHashHistogram( + const Elf_GnuHash &GnuHashTable) { + Expected> ChainsOrErr = + getGnuHashTableChains(this->DynSymRegion, &GnuHashTable); if (!ChainsOrErr) { this->reportUniqueWarning("unable to print the GNU hash table histogram: " + toString(ChainsOrErr.takeError())); @@ -4969,25 +4775,25 @@ void GNUStyle::printGnuHashHistogram(const Elf_GnuHash &GnuHashTable) { // dynamic symbol table. The table shows the number of hash buckets for // different lengths of chains as an absolute number and percentage of the total // buckets, and the cumulative coverage of symbols for each set of buckets. -template void GNUStyle::printHashHistograms() { +template void GNUELFDumper::printHashHistograms() { // Print histogram for the .hash section. - if (const Elf_Hash *HashTable = this->dumper().getHashTable()) { - if (Error E = checkHashTable(this->dumper(), HashTable)) + if (this->HashTable) { + if (Error E = checkHashTable(*this, this->HashTable)) this->reportUniqueWarning(std::move(E)); else - printHashHistogram(*HashTable); + printHashHistogram(*this->HashTable); } // Print histogram for the .gnu.hash section. - if (const Elf_GnuHash *GnuHashTable = this->dumper().getGnuHashTable()) { - if (Error E = checkGNUHashTable(this->Obj, GnuHashTable)) + if (this->GnuHashTable) { + if (Error E = checkGNUHashTable(this->Obj, this->GnuHashTable)) this->reportUniqueWarning(std::move(E)); else - printGnuHashHistogram(*GnuHashTable); + printGnuHashHistogram(*this->GnuHashTable); } } -template void GNUStyle::printCGProfile() { +template void GNUELFDumper::printCGProfile() { OS << "GNUStyle::printCGProfile not implemented\n"; } @@ -5021,19 +4827,18 @@ decodeAddrsigSection(const ELFFile &Obj, const typename ELFT::Shdr &Sec) { toString(SymsOrErr.takeError())); } -template void GNUStyle::printAddrsig() { - const Elf_Shdr *Sec = this->dumper().getDotAddrsigSec(); - if (!Sec) +template void GNUELFDumper::printAddrsig() { + if (!this->DotAddrsigSec) return; Expected> SymsOrErr = - decodeAddrsigSection(this->Obj, *Sec); + decodeAddrsigSection(this->Obj, *this->DotAddrsigSec); if (!SymsOrErr) { this->reportUniqueWarning(SymsOrErr.takeError()); return; } - StringRef Name = this->getPrintableSectionName(*Sec); + StringRef Name = this->getPrintableSectionName(*this->DotAddrsigSec); OS << "\nAddress-significant symbols section '" << Name << "'" << " contains " << SymsOrErr->size() << " entries:\n"; OS << " Num: Name\n"; @@ -5042,7 +4847,7 @@ template void GNUStyle::printAddrsig() { size_t SymIndex = 0; for (uint64_t Sym : *SymsOrErr) { Fields[0].Str = to_string(format_decimal(++SymIndex, 6)) + ":"; - Fields[1].Str = this->dumper().getStaticSymbolName(Sym); + Fields[1].Str = this->getStaticSymbolName(Sym); for (const Field &Entry : Fields) printField(Entry); OS << "\n"; @@ -5601,7 +5406,7 @@ static void printNotesHelper( } } -template void GNUStyle::printNotes() { +template void GNUELFDumper::printNotes() { auto PrintHeader = [&](Optional SecName, const typename ELFT::Off Offset, const typename ELFT::Addr Size) { @@ -5663,15 +5468,15 @@ template void GNUStyle::printNotes() { return Error::success(); }; - printNotesHelper(this->dumper(), PrintHeader, ProcessNote, []() {}); + printNotesHelper(*this, PrintHeader, ProcessNote, []() {}); } -template void GNUStyle::printELFLinkerOptions() { +template void GNUELFDumper::printELFLinkerOptions() { OS << "printELFLinkerOptions not implemented!\n"; } template -void DumpStyle::printDependentLibsHelper( +void ELFDumper::printDependentLibsHelper( function_ref OnSectionStart, function_ref OnLibEntry) { auto Warn = [this](unsigned SecNdx, StringRef Msg) { @@ -5708,7 +5513,7 @@ void DumpStyle::printDependentLibsHelper( } template -void DumpStyle::forEachRelocationDo( +void ELFDumper::forEachRelocationDo( const Elf_Shdr &Sec, bool RawRelr, llvm::function_ref &, unsigned, const Elf_Shdr &, const Elf_Shdr *)> @@ -5716,7 +5521,7 @@ void DumpStyle::forEachRelocationDo( llvm::function_ref RelrFn) { auto Warn = [&](Error &&E, const Twine &Prefix = "unable to read relocations from") { - this->reportUniqueWarning(Prefix + " " + describe(Obj, Sec) + ": " + + this->reportUniqueWarning(Prefix + " " + describe(Sec) + ": " + toString(std::move(E))); }; @@ -5783,19 +5588,18 @@ void DumpStyle::forEachRelocationDo( } template -StringRef DumpStyle::getPrintableSectionName(const Elf_Shdr &Sec) const { +StringRef ELFDumper::getPrintableSectionName(const Elf_Shdr &Sec) const { StringRef Name = ""; if (Expected SecNameOrErr = - Obj.getSectionName(Sec, this->dumper().WarningHandler)) + Obj.getSectionName(Sec, this->WarningHandler)) Name = *SecNameOrErr; else - this->reportUniqueWarning("unable to get the name of " + - describe(Obj, Sec) + ": " + - toString(SecNameOrErr.takeError())); + this->reportUniqueWarning("unable to get the name of " + describe(Sec) + + ": " + toString(SecNameOrErr.takeError())); return Name; } -template void GNUStyle::printDependentLibs() { +template void GNUELFDumper::printDependentLibs() { bool SectionStarted = false; struct NameOffset { StringRef Name; @@ -5831,12 +5635,12 @@ template void GNUStyle::printDependentLibs() { } template -bool DumpStyle::printFunctionStackSize( +bool ELFDumper::printFunctionStackSize( uint64_t SymValue, Optional FunctionSec, const Elf_Shdr &StackSizeSec, DataExtractor Data, uint64_t *Offset) { uint32_t FuncSymIndex = 0; - if (const Elf_Shdr *SymTab = this->dumper().getDotSymtabSec()) { - if (Expected SymsOrError = Obj.symbols(SymTab)) { + if (this->DotSymtabSec) { + if (Expected SymsOrError = Obj.symbols(this->DotSymtabSec)) { uint32_t Index = (uint32_t)-1; for (const Elf_Sym &Sym : *SymsOrError) { ++Index; @@ -5845,11 +5649,11 @@ bool DumpStyle::printFunctionStackSize( continue; if (Expected SymAddrOrErr = - ElfObj.toSymbolRef(SymTab, Index).getAddress()) { + ObjF.toSymbolRef(this->DotSymtabSec, Index).getAddress()) { if (SymValue != *SymAddrOrErr) continue; } else { - std::string Name = this->dumper().getStaticSymbolName(Index); + std::string Name = this->getStaticSymbolName(Index); reportUniqueWarning("unable to get address of symbol '" + Name + "': " + toString(SymAddrOrErr.takeError())); break; @@ -5859,11 +5663,11 @@ bool DumpStyle::printFunctionStackSize( // means "any section". if (FunctionSec) { if (Expected SecOrErr = - Obj.getSection(Sym, SymTab, this->dumper().getShndxTable())) { + Obj.getSection(Sym, this->DotSymtabSec, this->ShndxTable)) { if (*FunctionSec != *SecOrErr) continue; } else { - std::string Name = this->dumper().getStaticSymbolName(Index); + std::string Name = this->getStaticSymbolName(Index); // Note: it is impossible to trigger this error currently, it is // untested. reportUniqueWarning("unable to get section of symbol '" + Name + @@ -5885,9 +5689,9 @@ bool DumpStyle::printFunctionStackSize( if (!FuncSymIndex) reportUniqueWarning( "could not identify function symbol for stack size entry in " + - describe(Obj, StackSizeSec)); + describe(StackSizeSec)); else - FuncName = this->dumper().getStaticSymbolName(FuncSymIndex); + FuncName = this->getStaticSymbolName(FuncSymIndex); // Extract the size. The expectation is that Offset is pointing to the right // place, i.e. past the function address. @@ -5895,7 +5699,7 @@ bool DumpStyle::printFunctionStackSize( uint64_t StackSize = Data.getULEB128(Offset, &Err); if (Err) { reportUniqueWarning("could not extract a valid stack size from " + - describe(Obj, StackSizeSec) + ": " + + describe(StackSizeSec) + ": " + toString(std::move(Err))); return false; } @@ -5904,7 +5708,8 @@ bool DumpStyle::printFunctionStackSize( } template -void GNUStyle::printStackSizeEntry(uint64_t Size, StringRef FuncName) { +void GNUELFDumper::printStackSizeEntry(uint64_t Size, + StringRef FuncName) { OS.PadToColumn(2); OS << format_decimal(Size, 11); OS.PadToColumn(18); @@ -5912,7 +5717,7 @@ void GNUStyle::printStackSizeEntry(uint64_t Size, StringRef FuncName) { } template -void DumpStyle::printStackSize(const Relocation &R, +void ELFDumper::printStackSize(const Relocation &R, const Elf_Shdr &RelocSec, unsigned Ndx, const Elf_Shdr *SymTab, const Elf_Shdr *FunctionSec, @@ -5922,11 +5727,10 @@ void DumpStyle::printStackSize(const Relocation &R, // This function ignores potentially erroneous input, unless it is directly // related to stack size reporting. const Elf_Sym *Sym = nullptr; - Expected> TargetOrErr = - this->dumper().getRelocationTarget(R, SymTab); + Expected> TargetOrErr = this->getRelocationTarget(R, SymTab); if (!TargetOrErr) reportUniqueWarning("unable to get the target of relocation with index " + - Twine(Ndx) + " in " + describe(Obj, RelocSec) + ": " + + Twine(Ndx) + " in " + describe(RelocSec) + ": " + toString(TargetOrErr.takeError())); else Sym = TargetOrErr->Sym; @@ -5934,7 +5738,7 @@ void DumpStyle::printStackSize(const Relocation &R, uint64_t RelocSymValue = 0; if (Sym) { Expected SectionOrErr = - this->Obj.getSection(*Sym, SymTab, this->dumper().getShndxTable()); + this->Obj.getSection(*Sym, SymTab, this->ShndxTable); if (!SectionOrErr) { reportUniqueWarning( "cannot identify the section for relocation symbol '" + @@ -5954,7 +5758,7 @@ void DumpStyle::printStackSize(const Relocation &R, if (!Data.isValidOffsetForDataOfSize(Offset, sizeof(Elf_Addr) + 1)) { reportUniqueWarning("found invalid relocation offset (0x" + Twine::utohexstr(Offset) + ") into " + - describe(Obj, StackSizeSec) + + describe(StackSizeSec) + " while trying to extract a stack size entry"); return; } @@ -5967,7 +5771,7 @@ void DumpStyle::printStackSize(const Relocation &R, } template -void DumpStyle::printNonRelocatableStackSizes( +void ELFDumper::printNonRelocatableStackSizes( std::function PrintHeader) { // This function ignores potentially erroneous input, unless it is directly // related to stack size reporting. @@ -5984,7 +5788,7 @@ void DumpStyle::printNonRelocatableStackSizes( // size. Check for an extra byte before we try to process the entry. if (!Data.isValidOffsetForDataOfSize(Offset, sizeof(Elf_Addr) + 1)) { reportUniqueWarning( - describe(Obj, Sec) + + describe(Sec) + " ended while trying to extract a stack size entry"); break; } @@ -5997,7 +5801,7 @@ void DumpStyle::printNonRelocatableStackSizes( } template -void DumpStyle::printRelocatableStackSizes( +void ELFDumper::printRelocatableStackSizes( std::function PrintHeader) { // Build a map between stack size sections and their corresponding relocation // sections. @@ -6024,7 +5828,7 @@ void DumpStyle::printRelocatableStackSizes( Expected RelSecOrErr = Obj.getSection(Sec.sh_info); if (!RelSecOrErr) { - reportUniqueWarning(describe(Obj, Sec) + + reportUniqueWarning(describe(Sec) + ": failed to get a relocated section: " + toString(RelSecOrErr.takeError())); continue; @@ -6045,8 +5849,7 @@ void DumpStyle::printRelocatableStackSizes( // Warn about stack size sections without a relocation section. if (!RelocSec) { - reportWarning(createError(".stack_sizes (" + - describe(Obj, *StackSizesELFSec) + + reportWarning(createError(".stack_sizes (" + describe(*StackSizesELFSec) + ") does not have a corresponding " "relocation section"), FileName); @@ -6061,7 +5864,7 @@ void DumpStyle::printRelocatableStackSizes( SupportsRelocation IsSupportedFn; RelocationResolver Resolver; - std::tie(IsSupportedFn, Resolver) = getRelocationResolver(ElfObj); + std::tie(IsSupportedFn, Resolver) = getRelocationResolver(this->ObjF); ArrayRef Contents = unwrapOrError(this->FileName, Obj.getSectionContents(*StackSizesELFSec)); DataExtractor Data(Contents, Obj.isLE(), sizeof(Elf_Addr)); @@ -6072,7 +5875,7 @@ void DumpStyle::printRelocatableStackSizes( const Elf_Shdr *SymTab) { if (!IsSupportedFn || !IsSupportedFn(R.Type)) { reportUniqueWarning( - describe(Obj, *RelocSec) + + describe(*RelocSec) + " contains an unsupported relocation with index " + Twine(Ndx) + ": " + Obj.getRelocationTypeName(R.Type)); return; @@ -6089,7 +5892,7 @@ void DumpStyle::printRelocatableStackSizes( } template -void GNUStyle::printStackSizes() { +void GNUELFDumper::printStackSizes() { bool HeaderHasBeenPrinted = false; auto PrintHeader = [&]() { if (HeaderHasBeenPrinted) @@ -6111,7 +5914,7 @@ void GNUStyle::printStackSizes() { } template -void GNUStyle::printMipsGOT(const MipsGOTParser &Parser) { +void GNUELFDumper::printMipsGOT(const MipsGOTParser &Parser) { size_t Bias = ELFT::Is64Bits ? 8 : 0; auto PrintEntry = [&](const Elf_Addr *E, StringRef Purpose) { OS.PadToColumn(2); @@ -6161,9 +5964,9 @@ void GNUStyle::printMipsGOT(const MipsGOTParser &Parser) { OS << " Address Access Initial Sym.Val. Type Ndx Name\n"; for (auto &E : Parser.getGlobalEntries()) { const Elf_Sym &Sym = *Parser.getGotSym(&E); - const Elf_Sym &FirstSym = this->dumper().dynamic_symbols()[0]; - std::string SymName = this->dumper().getFullSymbolName( - Sym, &Sym - &FirstSym, this->dumper().getDynamicStringTable(), false); + const Elf_Sym &FirstSym = this->dynamic_symbols()[0]; + std::string SymName = this->getFullSymbolName( + Sym, &Sym - &FirstSym, this->DynamicStringTable, false); OS.PadToColumn(2); OS << to_string(format_hex_no_prefix(Parser.getGotAddress(&E), 8 + Bias)); @@ -6176,8 +5979,7 @@ void GNUStyle::printMipsGOT(const MipsGOTParser &Parser) { OS.PadToColumn(40 + 3 * Bias); OS << printEnum(Sym.getType(), makeArrayRef(ElfSymbolTypes)); OS.PadToColumn(48 + 3 * Bias); - OS << getSymbolSectionNdx( - Sym, &Sym - this->dumper().dynamic_symbols().begin()); + OS << getSymbolSectionNdx(Sym, &Sym - this->dynamic_symbols().begin()); OS.PadToColumn(52 + 3 * Bias); OS << SymName << "\n"; } @@ -6189,7 +5991,7 @@ void GNUStyle::printMipsGOT(const MipsGOTParser &Parser) { } template -void GNUStyle::printMipsPLT(const MipsGOTParser &Parser) { +void GNUELFDumper::printMipsPLT(const MipsGOTParser &Parser) { size_t Bias = ELFT::Is64Bits ? 8 : 0; auto PrintEntry = [&](const Elf_Addr *E, StringRef Purpose) { OS.PadToColumn(2); @@ -6216,8 +6018,8 @@ void GNUStyle::printMipsPLT(const MipsGOTParser &Parser) { const Elf_Sym &Sym = *Parser.getPltSym(&E); const Elf_Sym &FirstSym = *cantFail( this->Obj.template getEntry(*Parser.getPltSymTable(), 0)); - std::string SymName = this->dumper().getFullSymbolName( - Sym, &Sym - &FirstSym, this->dumper().getDynamicStringTable(), false); + std::string SymName = this->getFullSymbolName( + Sym, &Sym - &FirstSym, this->DynamicStringTable, false); OS.PadToColumn(2); OS << to_string(format_hex_no_prefix(Parser.getPltAddress(&E), 8 + Bias)); @@ -6228,8 +6030,7 @@ void GNUStyle::printMipsPLT(const MipsGOTParser &Parser) { OS.PadToColumn(29 + 3 * Bias); OS << printEnum(Sym.getType(), makeArrayRef(ElfSymbolTypes)); OS.PadToColumn(37 + 3 * Bias); - OS << getSymbolSectionNdx( - Sym, &Sym - this->dumper().dynamic_symbols().begin()); + OS << getSymbolSectionNdx(Sym, &Sym - this->dynamic_symbols().begin()); OS.PadToColumn(41 + 3 * Bias); OS << SymName << "\n"; } @@ -6255,10 +6056,10 @@ getMipsAbiFlagsSection(const ELFDumper &Dumper) { return reinterpret_cast *>(DataOrErr->data()); } -template void GNUStyle::printMipsABIFlags() { +template void GNUELFDumper::printMipsABIFlags() { const Elf_Mips_ABIFlags *Flags = nullptr; if (Expected *> SecOrErr = - getMipsAbiFlagsSection(this->dumper())) + getMipsAbiFlagsSection(*this)) Flags = *SecOrErr; else this->reportUniqueWarning(SecOrErr.takeError()); @@ -6288,7 +6089,7 @@ template void GNUStyle::printMipsABIFlags() { OS << "\n"; } -template void LLVMStyle::printFileHeaders() { +template void LLVMELFDumper::printFileHeaders() { const Elf_Ehdr &E = this->Obj.getHeader(); { DictScope D(W, "ElfHeader"); @@ -6360,7 +6161,7 @@ template void LLVMStyle::printFileHeaders() { } } -template void LLVMStyle::printGroupSections() { +template void LLVMELFDumper::printGroupSections() { DictScope Lists(W, "Groups"); std::vector V = this->getGroups(); DenseMap Map = mapSectionsToGroups(V); @@ -6391,7 +6192,7 @@ template void LLVMStyle::printGroupSections() { W.startLine() << "There are no group sections in the file.\n"; } -template void LLVMStyle::printRelocations() { +template void LLVMELFDumper::printRelocations() { ListScope D(W, "Relocations"); for (const Elf_Shdr &Sec : cantFail(this->Obj.sections())) { @@ -6408,28 +6209,15 @@ template void LLVMStyle::printRelocations() { } } -template void LLVMStyle::printRelrReloc(const Elf_Relr &R) { - W.startLine() << W.hex(R) << "\n"; -} - template -void LLVMStyle::printReloc(const Relocation &R, unsigned RelIndex, - const Elf_Shdr &Sec, const Elf_Shdr *SymTab) { - Expected> Target = - this->dumper().getRelocationTarget(R, SymTab); - if (!Target) { - this->reportUniqueWarning("unable to print relocation " + Twine(RelIndex) + - " in " + describe(this->Obj, Sec) + ": " + - toString(Target.takeError())); - return; - } - - printRelRelaReloc(R, Target->Name); +void LLVMELFDumper::printRelrReloc(const Elf_Relr &R) { + W.startLine() << W.hex(R) << "\n"; } template -void LLVMStyle::printRelRelaReloc(const Relocation &R, - StringRef SymbolName) { +void LLVMELFDumper::printRelRelaReloc(const Relocation &R, + const RelSymbol &RelSym) { + StringRef SymbolName = RelSym.Name; SmallString<32> RelocName; this->Obj.getRelocationTypeName(R.Type, RelocName); @@ -6450,7 +6238,7 @@ void LLVMStyle::printRelRelaReloc(const Relocation &R, } } -template void LLVMStyle::printSectionHeaders() { +template void LLVMELFDumper::printSectionHeaders() { ListScope SectionsD(W, "Sections"); int SectionIndex = -1; @@ -6480,16 +6268,17 @@ template void LLVMStyle::printSectionHeaders() { if (opts::SectionSymbols) { ListScope D(W, "Symbols"); - if (const Elf_Shdr *Symtab = this->dumper().getDotSymtabSec()) { + if (this->DotSymtabSec) { StringRef StrTable = unwrapOrError( - this->FileName, this->Obj.getStringTableForSymtab(*Symtab)); + this->FileName, + this->Obj.getStringTableForSymtab(*this->DotSymtabSec)); - typename ELFT::SymRange Symbols = - unwrapOrError(this->FileName, this->Obj.symbols(Symtab)); + typename ELFT::SymRange Symbols = unwrapOrError( + this->FileName, this->Obj.symbols(this->DotSymtabSec)); for (const Elf_Sym &Sym : Symbols) { const Elf_Shdr *SymSec = unwrapOrError( - this->FileName, this->Obj.getSection( - Sym, Symtab, this->dumper().getShndxTable())); + this->FileName, + this->Obj.getSection(Sym, this->DotSymtabSec, this->ShndxTable)); if (SymSec == &Sec) printSymbol(Sym, &Sym - &Symbols[0], StrTable, false, false); } @@ -6507,8 +6296,8 @@ template void LLVMStyle::printSectionHeaders() { } template -void LLVMStyle::printSymbolSection(const Elf_Sym &Symbol, - unsigned SymIndex) { +void LLVMELFDumper::printSymbolSection(const Elf_Sym &Symbol, + unsigned SymIndex) const { auto GetSectionSpecialType = [&]() -> Optional { if (Symbol.isUndefined()) return StringRef("Undefined"); @@ -6531,7 +6320,7 @@ void LLVMStyle::printSymbolSection(const Elf_Sym &Symbol, } Expected SectionIndex = - this->dumper().getSymbolSectionIndex(Symbol, SymIndex); + this->getSymbolSectionIndex(Symbol, SymIndex); if (!SectionIndex) { assert(Symbol.st_shndx == SHN_XINDEX && "getSymbolSectionIndex should only fail due to an invalid " @@ -6542,11 +6331,11 @@ void LLVMStyle::printSymbolSection(const Elf_Sym &Symbol, } Expected SectionName = - this->dumper().getSymbolSectionName(Symbol, *SectionIndex); + this->getSymbolSectionName(Symbol, *SectionIndex); if (!SectionName) { // Don't report an invalid section name if the section headers are missing. // In such situations, all sections will be "invalid". - if (!this->dumper().getElfObject().sections().empty()) + if (!this->ObjF.sections().empty()) this->reportUniqueWarning(SectionName.takeError()); else consumeError(SectionName.takeError()); @@ -6557,11 +6346,12 @@ void LLVMStyle::printSymbolSection(const Elf_Sym &Symbol, } template -void LLVMStyle::printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, - Optional StrTable, bool IsDynamic, - bool /*NonVisibilityBitsUsed*/) { +void LLVMELFDumper::printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, + Optional StrTable, + bool IsDynamic, + bool /*NonVisibilityBitsUsed*/) const { std::string FullSymbolName = - this->dumper().getFullSymbolName(Symbol, SymIndex, StrTable, IsDynamic); + this->getFullSymbolName(Symbol, SymIndex, StrTable, IsDynamic); unsigned char SymbolType = Symbol.getType(); DictScope D(W, "Symbol"); @@ -6604,26 +6394,20 @@ void LLVMStyle::printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, } template -void LLVMStyle::printSymbols(bool PrintSymbols, - bool PrintDynamicSymbols) { - if (PrintSymbols) - printSymbols(); - if (PrintDynamicSymbols) - printDynamicSymbols(); -} - -template void LLVMStyle::printSymbols() { - ListScope Group(W, "Symbols"); - this->dumper().printSymbolsHelper(false); -} - -template void LLVMStyle::printDynamicSymbols() { - ListScope Group(W, "DynamicSymbols"); - this->dumper().printSymbolsHelper(true); +void LLVMELFDumper::printSymbols(bool PrintSymbols, + bool PrintDynamicSymbols) { + if (PrintSymbols) { + ListScope Group(W, "Symbols"); + this->printSymbolsHelper(false); + } + if (PrintDynamicSymbols) { + ListScope Group(W, "DynamicSymbols"); + this->printSymbolsHelper(true); + } } -template void LLVMStyle::printDynamic() { - Elf_Dyn_Range Table = this->dumper().dynamic_table(); +template void LLVMELFDumper::printDynamicTable() { + Elf_Dyn_Range Table = this->dynamic_table(); if (Table.empty()) return; @@ -6639,7 +6423,7 @@ template void LLVMStyle::printDynamic() { std::string ValueFmt = "%-" + std::to_string(MaxTagSize) + "s "; for (auto Entry : Table) { uintX_t Tag = Entry.getTag(); - std::string Value = this->dumper().getDynamicEntry(Tag, Entry.getVal()); + std::string Value = this->getDynamicEntry(Tag, Entry.getVal()); W.startLine() << " " << format_hex(Tag, ELFT::Is64Bits ? 18 : 10, true) << " " << format(ValueFmt.c_str(), @@ -6649,7 +6433,7 @@ template void LLVMStyle::printDynamic() { W.startLine() << "]\n"; } -template void LLVMStyle::printDynamicRelocations() { +template void LLVMELFDumper::printDynamicRelocations() { W.startLine() << "Dynamic Relocations {\n"; W.indent(); this->printDynamicRelocationsHelper(); @@ -6658,13 +6442,7 @@ template void LLVMStyle::printDynamicRelocations() { } template -void LLVMStyle::printDynamicReloc(const Relocation &R) { - RelSymbol S = getSymbolForReloc(this->dumper(), R); - printRelRelaReloc(R, S.Name); -} - -template -void LLVMStyle::printProgramHeaders( +void LLVMELFDumper::printProgramHeaders( bool PrintProgramHeaders, cl::boolOrDefault PrintSectionMapping) { if (PrintProgramHeaders) printProgramHeaders(); @@ -6672,7 +6450,7 @@ void LLVMStyle::printProgramHeaders( printSectionMapping(); } -template void LLVMStyle::printProgramHeaders() { +template void LLVMELFDumper::printProgramHeaders() { ListScope L(W, "ProgramHeaders"); Expected> PhdrsOrErr = this->Obj.program_headers(); @@ -6699,7 +6477,7 @@ template void LLVMStyle::printProgramHeaders() { } template -void LLVMStyle::printVersionSymbolSection(const Elf_Shdr *Sec) { +void LLVMELFDumper::printVersionSymbolSection(const Elf_Shdr *Sec) { ListScope SS(W, "VersionSymbols"); if (!Sec) return; @@ -6707,7 +6485,7 @@ void LLVMStyle::printVersionSymbolSection(const Elf_Shdr *Sec) { StringRef StrTable; ArrayRef Syms; Expected> VerTableOrErr = - this->dumper().getVersionTable(*Sec, &Syms, &StrTable); + this->getVersionTable(*Sec, &Syms, &StrTable); if (!VerTableOrErr) { this->reportUniqueWarning(VerTableOrErr.takeError()); return; @@ -6719,7 +6497,7 @@ void LLVMStyle::printVersionSymbolSection(const Elf_Shdr *Sec) { for (size_t I = 0, E = Syms.size(); I < E; ++I) { DictScope S(W, "Symbol"); W.printNumber("Version", (*VerTableOrErr)[I].vs_index & VERSYM_VERSION); - W.printString("Name", this->dumper().getFullSymbolName(Syms[I], I, StrTable, + W.printString("Name", this->getFullSymbolName(Syms[I], I, StrTable, /*IsDynamic=*/true)); } } @@ -6730,12 +6508,12 @@ static const EnumEntry SymVersionFlags[] = { {"Info", "INFO", VER_FLG_INFO}}; template -void LLVMStyle::printVersionDefinitionSection(const Elf_Shdr *Sec) { +void LLVMELFDumper::printVersionDefinitionSection(const Elf_Shdr *Sec) { ListScope SD(W, "VersionDefinitions"); if (!Sec) return; - Expected> V = this->dumper().getVersionDefinitions(*Sec); + Expected> V = this->getVersionDefinitions(*Sec); if (!V) { this->reportUniqueWarning(V.takeError()); return; @@ -6755,12 +6533,12 @@ void LLVMStyle::printVersionDefinitionSection(const Elf_Shdr *Sec) { } template -void LLVMStyle::printVersionDependencySection(const Elf_Shdr *Sec) { +void LLVMELFDumper::printVersionDependencySection(const Elf_Shdr *Sec) { ListScope SD(W, "VersionRequirements"); if (!Sec) return; - Expected> V = this->dumper().getVersionDependencies(*Sec); + Expected> V = this->getVersionDependencies(*Sec); if (!V) { this->reportUniqueWarning(V.takeError()); return; @@ -6783,18 +6561,18 @@ void LLVMStyle::printVersionDependencySection(const Elf_Shdr *Sec) { } } -template void LLVMStyle::printHashHistograms() { +template void LLVMELFDumper::printHashHistograms() { W.startLine() << "Hash Histogram not implemented!\n"; } -template void LLVMStyle::printCGProfile() { +template void LLVMELFDumper::printCGProfile() { ListScope L(W, "CGProfile"); - if (!this->dumper().getDotCGProfileSec()) + if (!this->DotCGProfileSec) return; Expected> CGProfileOrErr = this->Obj.template getSectionContentsAsArray( - *this->dumper().getDotCGProfileSec()); + *this->DotCGProfileSec); if (!CGProfileOrErr) { this->reportUniqueWarning( "unable to dump the SHT_LLVM_CALL_GRAPH_PROFILE section: " + @@ -6804,29 +6582,28 @@ template void LLVMStyle::printCGProfile() { for (const Elf_CGProfile &CGPE : *CGProfileOrErr) { DictScope D(W, "CGProfileEntry"); - W.printNumber("From", this->dumper().getStaticSymbolName(CGPE.cgp_from), + W.printNumber("From", this->getStaticSymbolName(CGPE.cgp_from), CGPE.cgp_from); - W.printNumber("To", this->dumper().getStaticSymbolName(CGPE.cgp_to), + W.printNumber("To", this->getStaticSymbolName(CGPE.cgp_to), CGPE.cgp_to); W.printNumber("Weight", CGPE.cgp_weight); } } -template void LLVMStyle::printAddrsig() { +template void LLVMELFDumper::printAddrsig() { ListScope L(W, "Addrsig"); - const Elf_Shdr *Sec = this->dumper().getDotAddrsigSec(); - if (!Sec) + if (!this->DotAddrsigSec) return; Expected> SymsOrErr = - decodeAddrsigSection(this->Obj, *Sec); + decodeAddrsigSection(this->Obj, *this->DotAddrsigSec); if (!SymsOrErr) { this->reportUniqueWarning(SymsOrErr.takeError()); return; } for (uint64_t Sym : *SymsOrErr) - W.printNumber("Sym", this->dumper().getStaticSymbolName(Sym), Sym); + W.printNumber("Sym", this->getStaticSymbolName(Sym), Sym); } template @@ -6871,7 +6648,7 @@ static void printCoreNoteLLVMStyle(const CoreNote &Note, ScopedPrinter &W) { } } -template void LLVMStyle::printNotes() { +template void LLVMELFDumper::printNotes() { ListScope L(W, "Notes"); std::unique_ptr NoteScope; @@ -6932,10 +6709,10 @@ template void LLVMStyle::printNotes() { return Error::success(); }; - printNotesHelper(this->dumper(), StartNotes, ProcessNote, EndNotes); + printNotesHelper(*this, StartNotes, ProcessNote, EndNotes); } -template void LLVMStyle::printELFLinkerOptions() { +template void LLVMELFDumper::printELFLinkerOptions() { ListScope L(W, "LinkerOptions"); unsigned I = -1; @@ -6979,15 +6756,14 @@ template void LLVMStyle::printELFLinkerOptions() { } } -template void LLVMStyle::printDependentLibs() { +template void LLVMELFDumper::printDependentLibs() { ListScope L(W, "DependentLibs"); this->printDependentLibsHelper( [](const Elf_Shdr &) {}, [this](StringRef Lib, uint64_t) { W.printString(Lib); }); } -template -void LLVMStyle::printStackSizes() { +template void LLVMELFDumper::printStackSizes() { ListScope L(W, "StackSizes"); if (this->Obj.getHeader().e_type == ELF::ET_REL) this->printRelocatableStackSizes([]() {}); @@ -6996,14 +6772,14 @@ void LLVMStyle::printStackSizes() { } template -void LLVMStyle::printStackSizeEntry(uint64_t Size, StringRef FuncName) { +void LLVMELFDumper::printStackSizeEntry(uint64_t Size, StringRef FuncName) { DictScope D(W, "Entry"); W.printString("Function", FuncName); W.printHex("Size", Size); } template -void LLVMStyle::printMipsGOT(const MipsGOTParser &Parser) { +void LLVMELFDumper::printMipsGOT(const MipsGOTParser &Parser) { auto PrintEntry = [&](const Elf_Addr *E) { W.printHex("Address", Parser.getGotAddress(E)); W.printNumber("Access", Parser.getGotOffset(E)); @@ -7049,11 +6825,11 @@ void LLVMStyle::printMipsGOT(const MipsGOTParser &Parser) { W.printHex("Value", Sym.st_value); W.printEnum("Type", Sym.getType(), makeArrayRef(ElfSymbolTypes)); - const unsigned SymIndex = &Sym - this->dumper().dynamic_symbols().begin(); + const unsigned SymIndex = &Sym - this->dynamic_symbols().begin(); printSymbolSection(Sym, SymIndex); - std::string SymName = this->dumper().getFullSymbolName( - Sym, SymIndex, this->dumper().getDynamicStringTable(), true); + std::string SymName = this->getFullSymbolName( + Sym, SymIndex, this->DynamicStringTable, true); W.printNumber("Name", SymName, Sym.st_name); } } @@ -7063,7 +6839,7 @@ void LLVMStyle::printMipsGOT(const MipsGOTParser &Parser) { } template -void LLVMStyle::printMipsPLT(const MipsGOTParser &Parser) { +void LLVMELFDumper::printMipsPLT(const MipsGOTParser &Parser) { auto PrintEntry = [&](const Elf_Addr *E) { W.printHex("Address", Parser.getPltAddress(E)); W.printHex("Initial", *E); @@ -7094,21 +6870,21 @@ void LLVMStyle::printMipsPLT(const MipsGOTParser &Parser) { const Elf_Sym &Sym = *Parser.getPltSym(&E); W.printHex("Value", Sym.st_value); W.printEnum("Type", Sym.getType(), makeArrayRef(ElfSymbolTypes)); - printSymbolSection(Sym, &Sym - this->dumper().dynamic_symbols().begin()); + printSymbolSection(Sym, &Sym - this->dynamic_symbols().begin()); const Elf_Sym *FirstSym = cantFail( this->Obj.template getEntry(*Parser.getPltSymTable(), 0)); - std::string SymName = this->dumper().getFullSymbolName( + std::string SymName = this->getFullSymbolName( Sym, &Sym - FirstSym, Parser.getPltStrTable(), true); W.printNumber("Name", SymName, Sym.st_name); } } } -template void LLVMStyle::printMipsABIFlags() { +template void LLVMELFDumper::printMipsABIFlags() { const Elf_Mips_ABIFlags *Flags; if (Expected *> SecOrErr = - getMipsAbiFlagsSection(this->dumper())) { + getMipsAbiFlagsSection(*this)) { Flags = *SecOrErr; if (!Flags) { W.startLine() << "There is no .MIPS.abiflags section in the file.\n";