From 3110ac15c5133acdf53221fa1c26d44dbc968d4c Mon Sep 17 00:00:00 2001 From: James Henderson Date: Wed, 25 Mar 2020 12:46:43 +0000 Subject: [PATCH] [NFC][llvm-readobj] Refactor unique warning handler The unique warning handler was previously a property of the dump style, but it is commonly used in the dumper too. Since the two ELF output styles have no impact on the way warnings are printed, this patch moves the handler and related functions into the dumper class, instead of the dump style class. Reviewed by: MaskRay, grimar Differential Revision: https://reviews.llvm.org/D76777 --- llvm/tools/llvm-readobj/ELFDumper.cpp | 53 +++++++++++++++------------ 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index defa4a3cc109..72c0625ecb63 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -305,6 +305,8 @@ private: }; mutable SmallVector, 16> VersionMap; + std::unordered_set Warnings; + public: Elf_Dyn_Range dynamic_table() const { // A valid .dynamic section contains an array of entries terminated @@ -367,6 +369,9 @@ public: Expected> getRelocationTarget(const Elf_Shdr *SymTab, const Elf_Rela &R) const; + + std::function WarningHandler; + void reportUniqueWarning(Error Err) const; }; template @@ -459,12 +464,12 @@ ELFDumper::getVersionTable(const Elf_Shdr *Sec, ArrayRef *SymTab, Expected, StringRef>> SymTabOrErr = getLinkAsSymtab(Obj, Sec, SecNdx, SHT_DYNSYM); if (!SymTabOrErr) { - ELFDumperStyle->reportUniqueWarning(SymTabOrErr.takeError()); + reportUniqueWarning(SymTabOrErr.takeError()); return *VersionsOrErr; } if (SymTabOrErr->first.size() != VersionsOrErr->size()) - ELFDumperStyle->reportUniqueWarning( + reportUniqueWarning( createError("SHT_GNU_versym section with index " + Twine(SecNdx) + ": the number of entries (" + Twine(VersionsOrErr->size()) + ") does not match the number of symbols (" + @@ -578,7 +583,7 @@ ELFDumper::getVersionDependencies(const Elf_Shdr *Sec) const { StringRef StrTab; Expected StrTabOrErr = getLinkAsStrtab(Obj, Sec, SecNdx); if (!StrTabOrErr) - ELFDumperStyle->reportUniqueWarning(StrTabOrErr.takeError()); + reportUniqueWarning(StrTabOrErr.takeError()); else StrTab = *StrTabOrErr; @@ -707,14 +712,6 @@ public: DumpStyle(ELFDumper *Dumper) : Dumper(Dumper) { FileName = this->Dumper->getElfObject()->getFileName(); - - // Dumper reports all non-critical errors as warnings. - // It does not print the same warning more than once. - WarningHandler = [this](const Twine &Msg) { - if (Warnings.insert(Msg.str()).second) - reportWarning(createError(Msg), FileName); - return Error::success(); - }; } virtual ~DumpStyle() = default; @@ -767,14 +764,11 @@ public: virtual void printMipsABIFlags(const ELFObjectFile *Obj) = 0; const ELFDumper *dumper() const { return Dumper; } - void reportUniqueWarning(Error Err) const; - protected: - std::function WarningHandler; + void reportUniqueWarning(Error Err) const; StringRef FileName; private: - std::unordered_set Warnings; const ELFDumper *Dumper; }; @@ -898,13 +892,18 @@ private: }; template -void DumpStyle::reportUniqueWarning(Error Err) const { +void ELFDumper::reportUniqueWarning(Error Err) const { handleAllErrors(std::move(Err), [&](const ErrorInfoBase &EI) { cantFail(WarningHandler(EI.message()), "WarningHandler should always return ErrorSuccess"); }); } +template +void DumpStyle::reportUniqueWarning(Error Err) const { + this->dumper()->reportUniqueWarning(std::move(Err)); +} + template class LLVMStyle : public DumpStyle { public: TYPEDEF_ELF_TYPES(ELFT) @@ -1156,12 +1155,12 @@ std::string ELFDumper::getFullSymbolName(const Elf_Sym *Symbol, Expected SectionIndex = getSymbolSectionIndex(Symbol, Syms.begin()); if (!SectionIndex) { - ELFDumperStyle->reportUniqueWarning(SectionIndex.takeError()); + reportUniqueWarning(SectionIndex.takeError()); return ""; } Expected NameOrErr = getSymbolSectionName(Symbol, *SectionIndex); if (!NameOrErr) { - ELFDumperStyle->reportUniqueWarning(NameOrErr.takeError()); + reportUniqueWarning(NameOrErr.takeError()); return ("
").str(); } return std::string(*NameOrErr); @@ -1173,7 +1172,7 @@ std::string ELFDumper::getFullSymbolName(const Elf_Sym *Symbol, bool IsDefault; Expected VersionOrErr = getSymbolVersion(&*Symbol, IsDefault); if (!VersionOrErr) { - ELFDumperStyle->reportUniqueWarning(VersionOrErr.takeError()); + reportUniqueWarning(VersionOrErr.takeError()); return SymbolName + "@"; } @@ -1984,6 +1983,14 @@ ELFDumper::ELFDumper(const object::ELFObjectFile *ObjF, : ObjDumper(Writer), ObjF(ObjF), DynRelRegion(ObjF->getFileName()), DynRelaRegion(ObjF->getFileName()), DynRelrRegion(ObjF->getFileName()), DynPLTRelRegion(ObjF->getFileName()), DynamicTable(ObjF->getFileName()) { + // Dumper reports all non-critical errors as warnings. + // It does not print the same warning more than once. + WarningHandler = [this](const Twine &Msg) { + if (Warnings.insert(Msg.str()).second) + reportWarning(createError(Msg), this->ObjF->getFileName()); + return Error::success(); + }; + if (opts::Output == opts::GNU) ELFDumperStyle.reset(new GNUStyle(Writer, this)); else @@ -2174,7 +2181,7 @@ void ELFDumper::parseDynamicTable(const ELFFile *Obj) { // locate .dynsym at runtime. The location we find in the section header // and the location we find here should match. if (DynSymFromTable && DynSymFromTable->Addr != DynSymRegion->Addr) - ELFDumperStyle->reportUniqueWarning( + reportUniqueWarning( createError("SHT_DYNSYM section header and DT_SYMTAB disagree about " "the location of the dynamic symbol table")); @@ -2184,7 +2191,7 @@ void ELFDumper::parseDynamicTable(const ELFFile *Obj) { // according to the section header. if (HashTable && HashTable->nchain != DynSymRegion->Size / DynSymRegion->EntSize) - ELFDumperStyle->reportUniqueWarning(createError( + reportUniqueWarning(createError( "hash table nchain (" + Twine(HashTable->nchain) + ") differs from symbol count derived from SHT_DYNSYM section " "header (" + @@ -3677,7 +3684,7 @@ void GNUStyle::printSectionHeaders(const ELFO *Obj) { const ELFObjectFile *ElfObj = this->dumper()->getElfObject(); StringRef SecStrTable = unwrapOrError( ElfObj->getFileName(), - Obj->getSectionStringTable(Sections, this->WarningHandler)); + Obj->getSectionStringTable(Sections, this->dumper()->WarningHandler)); size_t SectionIndex = 0; for (const Elf_Shdr &Sec : Sections) { Fields[0].Str = to_string(SectionIndex); @@ -5845,7 +5852,7 @@ void LLVMStyle::printSectionHeaders(const ELFO *Obj) { for (const Elf_Shdr &Sec : Sections) { StringRef Name = ""; if (Expected SecNameOrErr = - Obj->getSectionName(&Sec, this->WarningHandler)) + Obj->getSectionName(&Sec, this->dumper()->WarningHandler)) Name = *SecNameOrErr; else this->reportUniqueWarning(SecNameOrErr.takeError());