};
mutable SmallVector<Optional<VersionEntry>, 16> VersionMap;
+ std::unordered_set<std::string> Warnings;
+
public:
Elf_Dyn_Range dynamic_table() const {
// A valid .dynamic section contains an array of entries terminated
Expected<std::pair<const Elf_Sym *, std::string>>
getRelocationTarget(const Elf_Shdr *SymTab, const Elf_Rela &R) const;
+
+ std::function<Error(const Twine &Msg)> WarningHandler;
+ void reportUniqueWarning(Error Err) const;
};
template <class ELFT>
Expected<std::pair<ArrayRef<Elf_Sym>, 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 (" +
StringRef StrTab;
Expected<StringRef> StrTabOrErr = getLinkAsStrtab(Obj, Sec, SecNdx);
if (!StrTabOrErr)
- ELFDumperStyle->reportUniqueWarning(StrTabOrErr.takeError());
+ reportUniqueWarning(StrTabOrErr.takeError());
else
StrTab = *StrTabOrErr;
DumpStyle(ELFDumper<ELFT> *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;
virtual void printMipsABIFlags(const ELFObjectFile<ELFT> *Obj) = 0;
const ELFDumper<ELFT> *dumper() const { return Dumper; }
- void reportUniqueWarning(Error Err) const;
-
protected:
- std::function<Error(const Twine &Msg)> WarningHandler;
+ void reportUniqueWarning(Error Err) const;
StringRef FileName;
private:
- std::unordered_set<std::string> Warnings;
const ELFDumper<ELFT> *Dumper;
};
};
template <class ELFT>
-void DumpStyle<ELFT>::reportUniqueWarning(Error Err) const {
+void ELFDumper<ELFT>::reportUniqueWarning(Error Err) const {
handleAllErrors(std::move(Err), [&](const ErrorInfoBase &EI) {
cantFail(WarningHandler(EI.message()),
"WarningHandler should always return ErrorSuccess");
});
}
+template <class ELFT>
+void DumpStyle<ELFT>::reportUniqueWarning(Error Err) const {
+ this->dumper()->reportUniqueWarning(std::move(Err));
+}
+
template <typename ELFT> class LLVMStyle : public DumpStyle<ELFT> {
public:
TYPEDEF_ELF_TYPES(ELFT)
Expected<unsigned> SectionIndex =
getSymbolSectionIndex(Symbol, Syms.begin());
if (!SectionIndex) {
- ELFDumperStyle->reportUniqueWarning(SectionIndex.takeError());
+ reportUniqueWarning(SectionIndex.takeError());
return "<?>";
}
Expected<StringRef> NameOrErr = getSymbolSectionName(Symbol, *SectionIndex);
if (!NameOrErr) {
- ELFDumperStyle->reportUniqueWarning(NameOrErr.takeError());
+ reportUniqueWarning(NameOrErr.takeError());
return ("<section " + Twine(*SectionIndex) + ">").str();
}
return std::string(*NameOrErr);
bool IsDefault;
Expected<StringRef> VersionOrErr = getSymbolVersion(&*Symbol, IsDefault);
if (!VersionOrErr) {
- ELFDumperStyle->reportUniqueWarning(VersionOrErr.takeError());
+ reportUniqueWarning(VersionOrErr.takeError());
return SymbolName + "@<corrupt>";
}
: 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<ELFT>(Writer, this));
else
// 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"));
// 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 (" +
const ELFObjectFile<ELFT> *ElfObj = this->dumper()->getElfObject();
StringRef SecStrTable = unwrapOrError<StringRef>(
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);
for (const Elf_Shdr &Sec : Sections) {
StringRef Name = "<?>";
if (Expected<StringRef> SecNameOrErr =
- Obj->getSectionName(&Sec, this->WarningHandler))
+ Obj->getSectionName(&Sec, this->dumper()->WarningHandler))
Name = *SecNameOrErr;
else
this->reportUniqueWarning(SecNameOrErr.takeError());