summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-readobj/ELFDumper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-readobj/ELFDumper.cpp')
-rw-r--r--llvm/tools/llvm-readobj/ELFDumper.cpp145
1 files changed, 85 insertions, 60 deletions
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index 6dbe36e0efa..6e14c389cf8 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -122,9 +122,9 @@ template <class ELFT> class DumpStyle;
/// the size, entity size and virtual address are different entries in arbitrary
/// order (DT_REL, DT_RELSZ, DT_RELENT for example).
struct DynRegionInfo {
- DynRegionInfo() = default;
- DynRegionInfo(const void *A, uint64_t S, uint64_t ES)
- : Addr(A), Size(S), EntSize(ES) {}
+ DynRegionInfo(StringRef ObjName) : FileName(ObjName) {}
+ DynRegionInfo(const void *A, uint64_t S, uint64_t ES, StringRef ObjName)
+ : Addr(A), Size(S), EntSize(ES), FileName(ObjName) {}
/// Address in current address space.
const void *Addr = nullptr;
@@ -133,14 +133,18 @@ struct DynRegionInfo {
/// Size of each entity in the region.
uint64_t EntSize = 0;
+ /// Name of the file. Used for error reporting.
+ StringRef FileName;
+
template <typename Type> ArrayRef<Type> getAsArrayRef() const {
const Type *Start = reinterpret_cast<const Type *>(Addr);
if (!Start)
return {Start, Start};
if (EntSize != sizeof(Type) || Size % EntSize) {
// TODO: Add a section index to this warning.
- reportWarning("invalid section size (" + Twine(Size) +
- ") or entity size (" + Twine(EntSize) + ")");
+ reportWarning(createError("invalid section size (" + Twine(Size) +
+ ") or entity size (" + Twine(EntSize) + ")"),
+ FileName);
return {Start, Start};
}
return {Start, Start + (Size / EntSize)};
@@ -199,18 +203,19 @@ private:
if (DRI.Addr < Obj->base() ||
reinterpret_cast<const uint8_t *>(DRI.Addr) + DRI.Size >
Obj->base() + Obj->getBufSize())
- error(llvm::object::object_error::parse_failed);
+ reportError(llvm::object::object_error::parse_failed,
+ ObjF->getFileName());
return DRI;
}
DynRegionInfo createDRIFrom(const Elf_Phdr *P, uintX_t EntSize) {
- return checkDRI(
- {ObjF->getELFFile()->base() + P->p_offset, P->p_filesz, EntSize});
+ return checkDRI({ObjF->getELFFile()->base() + P->p_offset, P->p_filesz,
+ EntSize, ObjF->getFileName()});
}
DynRegionInfo createDRIFrom(const Elf_Shdr *S) {
- return checkDRI(
- {ObjF->getELFFile()->base() + S->sh_offset, S->sh_size, S->sh_entsize});
+ return checkDRI({ObjF->getELFFile()->base() + S->sh_offset, S->sh_size,
+ S->sh_entsize, ObjF->getFileName()});
}
void loadDynamicTable(const ELFFile<ELFT> *Obj);
@@ -362,7 +367,7 @@ public:
// It does not print the same warning more than once.
WarningHandler = [this](const Twine &Msg) {
if (Warnings.insert(Msg.str()).second)
- reportWarning(FileName, createError(Msg));
+ reportWarning(createError(Msg), FileName);
return Error::success();
};
}
@@ -740,7 +745,7 @@ std::string ELFDumper<ELFT>::getStaticSymbolName(uint32_t Index) const {
Elf_Sym_Range Syms =
unwrapOrError(ObjF->getFileName(), Obj->symbols(DotSymtabSec));
if (Index >= Syms.size())
- reportError("Invalid symbol index");
+ reportError(createError("Invalid symbol index"), ObjF->getFileName());
const Elf_Sym *Sym = &Syms[Index];
return maybeDemangle(
unwrapOrError(ObjF->getFileName(), Sym->getName(StrTable)));
@@ -761,7 +766,7 @@ StringRef ELFDumper<ELFT>::getSymbolVersionByIndex(StringRef StrTab,
// Lookup this symbol in the version table.
LoadVersionMap();
if (VersionIndex >= VersionMap.size() || VersionMap[VersionIndex].isNull())
- reportError("Invalid version entry");
+ reportError(createError("Invalid version entry"), ObjF->getFileName());
const VersionMapEntry &Entry = VersionMap[VersionIndex];
// Get the version name string.
@@ -775,7 +780,7 @@ StringRef ELFDumper<ELFT>::getSymbolVersionByIndex(StringRef StrTab,
IsDefault = false;
}
if (NameOffset >= StrTab.size())
- reportError("Invalid string offset");
+ reportError(createError("Invalid string offset"), ObjF->getFileName());
return StrTab.data() + NameOffset;
}
@@ -1428,8 +1433,9 @@ void ELFDumper<ELFT>::loadDynamicTable(const ELFFile<ELFT> *Obj) {
// This allows us to dump the dynamic sections with a broken sh_entsize
// field.
if (DynamicSec) {
- DynamicTable = checkDRI({ObjF->getELFFile()->base() + DynamicSec->sh_offset,
- DynamicSec->sh_size, sizeof(Elf_Dyn)});
+ DynamicTable =
+ checkDRI({ObjF->getELFFile()->base() + DynamicSec->sh_offset,
+ DynamicSec->sh_size, sizeof(Elf_Dyn), ObjF->getFileName()});
parseDynamicTable();
}
@@ -1441,7 +1447,9 @@ void ELFDumper<ELFT>::loadDynamicTable(const ELFFile<ELFT> *Obj) {
if (DynamicPhdr->p_offset + DynamicPhdr->p_filesz >
ObjF->getMemoryBufferRef().getBufferSize()) {
reportWarning(
- "PT_DYNAMIC segment offset + size exceeds the size of the file");
+ createError(
+ "PT_DYNAMIC segment offset + size exceeds the size of the file"),
+ ObjF->getFileName());
return;
}
@@ -1456,22 +1464,26 @@ void ELFDumper<ELFT>::loadDynamicTable(const ELFFile<ELFT> *Obj) {
if (DynamicSec->sh_addr + DynamicSec->sh_size >
DynamicPhdr->p_vaddr + DynamicPhdr->p_memsz ||
DynamicSec->sh_addr < DynamicPhdr->p_vaddr)
- reportWarning("The SHT_DYNAMIC section '" + Name +
- "' is not contained within the "
- "PT_DYNAMIC segment");
+ reportWarning(createError("The SHT_DYNAMIC section '" + Name +
+ "' is not contained within the "
+ "PT_DYNAMIC segment"),
+ ObjF->getFileName());
if (DynamicSec->sh_addr != DynamicPhdr->p_vaddr)
- reportWarning("The SHT_DYNAMIC section '" + Name +
- "' is not at the start of "
- "PT_DYNAMIC segment");
+ reportWarning(createError("The SHT_DYNAMIC section '" + Name +
+ "' is not at the start of "
+ "PT_DYNAMIC segment"),
+ ObjF->getFileName());
}
template <typename ELFT>
ELFDumper<ELFT>::ELFDumper(const object::ELFObjectFile<ELFT> *ObjF,
- ScopedPrinter &Writer)
- : ObjDumper(Writer), ObjF(ObjF) {
+ ScopedPrinter &Writer)
+ : ObjDumper(Writer), ObjF(ObjF), DynRelRegion(ObjF->getFileName()),
+ DynRelaRegion(ObjF->getFileName()), DynRelrRegion(ObjF->getFileName()),
+ DynPLTRelRegion(ObjF->getFileName()), DynSymRegion(ObjF->getFileName()),
+ DynamicTable(ObjF->getFileName()) {
const ELFFile<ELFT> *Obj = ObjF->getELFFile();
-
for (const Elf_Shdr &Sec :
unwrapOrError(ObjF->getFileName(), Obj->sections())) {
switch (Sec.sh_type) {
@@ -1490,7 +1502,7 @@ ELFDumper<ELFT>::ELFDumper(const object::ELFObjectFile<ELFT> *ObjF,
if (Expected<StringRef> E = Obj->getStringTableForSymtab(Sec))
DynamicStringTable = *E;
else
- warn(E.takeError());
+ reportWarning(E.takeError(), ObjF->getFileName());
}
break;
case ELF::SHT_SYMTAB_SHNDX:
@@ -1599,10 +1611,13 @@ template <typename ELFT> void ELFDumper<ELFT>::parseDynamicTable() {
auto toMappedAddr = [&](uint64_t Tag, uint64_t VAddr) -> const uint8_t * {
auto MappedAddrOrError = ObjF->getELFFile()->toMappedAddr(VAddr);
if (!MappedAddrOrError) {
- reportWarning("Unable to parse DT_" +
- Twine(getTypeString(
- ObjF->getELFFile()->getHeader()->e_machine, Tag)) +
- ": " + llvm::toString(MappedAddrOrError.takeError()));
+ Error Err =
+ createError("Unable to parse DT_" +
+ Twine(getTypeString(
+ ObjF->getELFFile()->getHeader()->e_machine, Tag)) +
+ ": " + llvm::toString(MappedAddrOrError.takeError()));
+
+ reportWarning(std::move(Err), ObjF->getFileName());
return nullptr;
}
return MappedAddrOrError.get();
@@ -1671,8 +1686,9 @@ template <typename ELFT> void ELFDumper<ELFT>::parseDynamicTable() {
else if (Dyn.getVal() == DT_RELA)
DynPLTRelRegion.EntSize = sizeof(Elf_Rela);
else
- reportError(Twine("unknown DT_PLTREL value of ") +
- Twine((uint64_t)Dyn.getVal()));
+ reportError(createError(Twine("unknown DT_PLTREL value of ") +
+ Twine((uint64_t)Dyn.getVal())),
+ ObjF->getFileName());
break;
case ELF::DT_JMPREL:
DynPLTRelRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr());
@@ -2094,7 +2110,7 @@ template <typename ELFT> void ELFDumper<ELFT>::printGnuHashTable() {
Elf_Sym_Range Syms = dynamic_symbols();
unsigned NumSyms = std::distance(Syms.begin(), Syms.end());
if (!NumSyms)
- reportError("No dynamic symbol section");
+ reportError(createError("No dynamic symbol section"), ObjF->getFileName());
W.printHexList("Values", GnuHashTable->values(NumSyms));
}
@@ -2207,7 +2223,7 @@ MipsGOTParser<ELFT>::MipsGOTParser(const ELFO *Obj, StringRef FileName,
if (IsStatic) {
GotSec = findSectionByName(*Obj, FileName, ".got");
if (!GotSec)
- reportError("Cannot find .got section");
+ reportError(createError("Cannot find .got section"), FileName);
ArrayRef<uint8_t> Content =
unwrapOrError(FileName, Obj->getSectionContents(GotSec));
@@ -2254,12 +2270,15 @@ MipsGOTParser<ELFT>::MipsGOTParser(const ELFO *Obj, StringRef FileName,
size_t DynSymTotal = DynSyms.size();
if (*DtGotSym > DynSymTotal)
- reportError("MIPS_GOTSYM exceeds a number of dynamic symbols");
+ reportError(
+ createError("MIPS_GOTSYM exceeds a number of dynamic symbols"),
+ FileName);
GotSec = findNotEmptySectionByAddress(Obj, FileName, *DtPltGot);
if (!GotSec)
- reportError("There is no not empty GOT section at 0x" +
- Twine::utohexstr(*DtPltGot));
+ reportError(createError("There is no not empty GOT section at 0x" +
+ Twine::utohexstr(*DtPltGot)),
+ FileName);
LocalNum = *DtLocalGotNum;
GlobalNum = DynSymTotal - *DtGotSym;
@@ -2409,7 +2428,8 @@ MipsGOTParser<ELFT>::getPltSym(const Entry *E) const {
template <class ELFT> void ELFDumper<ELFT>::printMipsPLTGOT() {
const ELFFile<ELFT> *Obj = ObjF->getELFFile();
if (Obj->getHeader()->e_machine != EM_MIPS)
- reportError("MIPS PLT GOT is available for MIPS targets only");
+ reportError(createError("MIPS PLT GOT is available for MIPS targets only"),
+ ObjF->getFileName());
MipsGOTParser<ELFT> Parser(Obj, ObjF->getFileName(), dynamic_table(),
dynamic_symbols());
@@ -4492,7 +4512,7 @@ void GNUStyle<ELFT>::printNotes(const ELFFile<ELFT> *Obj) {
if (Note)
printCoreNote<ELFT>(OS, *Note);
else
- warn(Note.takeError());
+ reportWarning(Note.takeError(), this->FileName);
}
} else if (!Descriptor.empty()) {
OS << " description data:";
@@ -4556,7 +4576,6 @@ void DumpStyle<ELFT>::printFunctionStackSize(
}
}
- StringRef FileStr = Obj->getFileName();
std::string FuncName = "?";
// A valid SymbolRef has a non-null object file pointer.
if (FuncSym.BasicSymbolRef::getObject()) {
@@ -4566,9 +4585,11 @@ void DumpStyle<ELFT>::printFunctionStackSize(
FuncName = maybeDemangle(*FuncNameOrErr);
else
consumeError(FuncNameOrErr.takeError());
- } else
- reportWarning(" '" + FileStr +
- "': could not identify function symbol for stack size entry");
+ } else {
+ reportWarning(
+ createError("could not identify function symbol for stack size entry"),
+ Obj->getFileName());
+ }
// Extract the size. The expectation is that Offset is pointing to the right
// place, i.e. past the function address.
@@ -4581,7 +4602,7 @@ void DumpStyle<ELFT>::printFunctionStackSize(
createStringError(object_error::parse_failed,
"could not extract a valid stack size in section %s",
SectionName.data()),
- FileStr);
+ Obj->getFileName());
printStackSizeEntry(StackSize, FuncName);
}
@@ -4619,13 +4640,14 @@ void DumpStyle<ELFT>::printStackSize(const ELFObjectFile<ELFT> *Obj,
auto SectionOrErr = RelocSym->getSection();
if (!SectionOrErr) {
- reportWarning(" '" + FileStr +
- "': cannot identify the section for relocation symbol " +
- SymName);
- consumeError(SectionOrErr.takeError());
+ reportWarning(
+ createError("cannot identify the section for relocation symbol " +
+ SymName),
+ FileStr);
} else if (*SectionOrErr != FunctionSec) {
- reportWarning(" '" + FileStr + "': relocation symbol " + SymName +
- " is not in the expected section");
+ reportWarning(createError("relocation symbol " + SymName +
+ " is not in the expected section"),
+ FileStr);
// Pretend that the symbol is in the correct section and report its
// stack size anyway.
FunctionSec = **SectionOrErr;
@@ -4713,7 +4735,7 @@ template <class ELFT>
void DumpStyle<ELFT>::printRelocatableStackSizes(
const ELFObjectFile<ELFT> *Obj, std::function<void()> PrintHeader) {
const ELFFile<ELFT> *EF = Obj->getELFFile();
- StringRef FileStr = Obj->getFileName();
+
// Build a map between stack size sections and their corresponding relocation
// sections.
llvm::MapVector<SectionRef, SectionRef> StackSizeRelocMap;
@@ -4768,9 +4790,10 @@ void DumpStyle<ELFT>::printRelocatableStackSizes(
consumeError(NameOrErr.takeError());
if (RelocSec == NullSection) {
- reportWarning(" '" + FileStr + "': section " + StackSizeSectionName +
- " does not have a corresponding "
- "relocation section");
+ reportWarning(createError("section " + StackSizeSectionName +
+ " does not have a corresponding "
+ "relocation section"),
+ Obj->getFileName());
continue;
}
@@ -4805,7 +4828,7 @@ void DumpStyle<ELFT>::printRelocatableStackSizes(
createStringError(object_error::parse_failed,
"unsupported relocation type in section %s: %s",
RelocSectionName.data(), RelocName.data()),
- FileStr);
+ Obj->getFileName());
}
this->printStackSize(Obj, Reloc, FunctionSec, StackSizeSectionName,
Resolver, Data);
@@ -5225,9 +5248,10 @@ void LLVMStyle<ELFT>::printSectionHeaders(const ELFO *Obj) {
this->FileName,
Obj->getSection(&Sym, Symtab, this->dumper()->getShndxTable()));
if (SymSec == &Sec)
- printSymbol(Obj, &Sym,
+ printSymbol(
+ Obj, &Sym,
unwrapOrError(this->FileName, Obj->symbols(Symtab)).begin(),
- StrTable, false);
+ StrTable, false);
}
}
@@ -5587,7 +5611,8 @@ void LLVMStyle<ELFT>::printAddrsig(const ELFFile<ELFT> *Obj) {
const char *Err;
uint64_t SymIndex = decodeULEB128(Cur, &Size, End, &Err);
if (Err)
- reportError(Err);
+ reportError(createError(Err), this->FileName);
+
W.printNumber("Sym", this->dumper()->getStaticSymbolName(SymIndex),
SymIndex);
Cur += Size;
@@ -5696,7 +5721,7 @@ void LLVMStyle<ELFT>::printNotes(const ELFFile<ELFT> *Obj) {
if (Note)
printCoreNoteLLVMStyle(*Note, W);
else
- warn(Note.takeError());
+ reportWarning(Note.takeError(), this->FileName);
}
} else if (!Descriptor.empty()) {
W.printBinaryBlock("Description data", Descriptor);
OpenPOWER on IntegriCloud