diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -305,6 +305,8 @@ }; 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 @@ Expected> getRelocationTarget(const Elf_Shdr *SymTab, const Elf_Rela &R) const; + + std::function WarningHandler; + void reportUniqueWarning(Error Err) const; }; template @@ -459,12 +464,12 @@ 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 @@ StringRef StrTab; Expected StrTabOrErr = getLinkAsStrtab(Obj, Sec, SecNdx); if (!StrTabOrErr) - ELFDumperStyle->reportUniqueWarning(StrTabOrErr.takeError()); + reportUniqueWarning(StrTabOrErr.takeError()); else StrTab = *StrTabOrErr; @@ -707,14 +712,6 @@ 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 @@ 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 @@ }; 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 @@ 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 @@ bool IsDefault; Expected VersionOrErr = getSymbolVersion(&*Symbol, IsDefault); if (!VersionOrErr) { - ELFDumperStyle->reportUniqueWarning(VersionOrErr.takeError()); + reportUniqueWarning(VersionOrErr.takeError()); return SymbolName + "@"; } @@ -1984,6 +1983,14 @@ : 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 @@ // 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 @@ // 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 @@ 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 @@ 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());