# RUN: llvm-readelf -A %t.err1 2>&1 | FileCheck %s -DFILE=%t.err1 --check-prefix=CONTENT-ERR
# RUN: llvm-readobj -A %t.err1 2>&1 | FileCheck %s -DFILE=%t.err1 --check-prefix=CONTENT-ERR
-# CONTENT-ERR: warning: '[[FILE]]': unable to read the .MIPS.abiflags section: section [index 1] has a sh_offset (0xffffffff) + sh_size (0x18) that is greater than the file size (0x240)
+# CONTENT-ERR: warning: '[[FILE]]': unable to read the .MIPS.abiflags section: section [index 2] has a sh_offset (0xffffffff) + sh_size (0x18) that is greater than the file size (0x2c0)
# CONTENT-ERR-NEXT: There is no .MIPS.options section in the file.
# CONTENT-ERR-NEXT: There is no .reginfo section in the file.
Type: ET_REL
Machine: EM_MIPS
Sections:
+ - Type: SHT_PROGBITS
+ ShName: [[NAME=<none>]]
- Name: .MIPS.abiflags
Type: SHT_MIPS_ABIFLAGS
ISA: MIPS32
Offset: 0x100
ShOffset: [[SHOFFSET=0x100]]
ShSize: [[SHSIZE=24]]
+ ShName: [[ABIFLAGSNAME=<none>]]
+ - Type: SHT_PROGBITS
+ ShName: [[NAME=<none>]]
## Check we report a warning when the .MIPS.abiflags section has an unexpected size.
# RUN: yaml2obj --docnum=3 -DSHSIZE=23 %s -o %t.err2
# SIZE-ERR: warning: '[[FILE]]': unable to read the .MIPS.abiflags section: it has a wrong size (23)
# SIZE-ERR-NEXT: There is no .MIPS.options section in the file.
# SIZE-ERR-NEXT: There is no .reginfo section in the file.
+
+## Check that we try to dump the .MIPS.abiflags section when we are able to locate it by name.
+# RUN: yaml2obj --docnum=3 -DNAME=0xffff %s -o %t.err3
+# RUN: llvm-readelf -A %t.err3 2>&1 | \
+# RUN: FileCheck %s -DFILE=%t.err3 --check-prefixes=NAME-ERR-FOUND,NAME-ERR-FOUND-GNU --implicit-check-not=warning:
+# RUN: llvm-readobj -A %t.err3 2>&1 | \
+# RUN: FileCheck %s -DFILE=%t.err3 --check-prefixes=NAME-ERR-FOUND,NAME-ERR-FOUND-LLVM --implicit-check-not=warning:
+
+# NAME-ERR-FOUND: warning: '[[FILE]]': unable to read the name of SHT_PROGBITS section with index 1: a section [index 1] has an invalid sh_name (0xffff) offset which goes past the end of the section name string table
+# NAME-ERR-FOUND-GNU-NEXT: MIPS ABI Flags Version: 0
+# NAME-ERR-FOUND-LLVM-NEXT: MIPS ABI Flags {
+# NAME-ERR-FOUND: warning: '[[FILE]]': unable to read the name of SHT_PROGBITS section with index 3: a section [index 3] has an invalid sh_name (0xffff) offset which goes past the end of the section name string table
+
+## Check we report a warning when we are unable to find the .MIPS.abiflags section due to an error.
+# RUN: yaml2obj --docnum=3 -DABIFLAGSNAME=0xffff %s -o %t.err4
+# RUN: llvm-readelf -A %t.err4 2>&1 | \
+# RUN: FileCheck %s -DFILE=%t.err4 --check-prefix=NAME-ERR-NOTFOUND --implicit-check-not=warning: --implicit-check-not="MIPS ABI Flags"
+# RUN: llvm-readobj -A %t.err4 2>&1 | \
+# RUN: FileCheck %s -DFILE=%t.err4 --check-prefix=NAME-ERR-NOTFOUND --implicit-check-not=warning: --implicit-check-not="MIPS ABI Flags"
+
+# NAME-ERR-NOTFOUND: warning: '[[FILE]]': unable to read the name of SHT_MIPS_ABIFLAGS section with index 2: a section [index 2] has an invalid sh_name (0xffff) offset which goes past the end of the section name string table
void printSymbolsHelper(bool IsDynamic) const;
std::string getDynamicEntry(uint64_t Type, uint64_t Value) const;
+ Expected<const typename ELFT::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; }
return nullptr;
}
-template <class ELFO>
-static const typename ELFO::Elf_Shdr *
-findSectionByName(const ELFO &Obj, StringRef FileName, StringRef Name) {
- for (const typename ELFO::Elf_Shdr &Shdr : cantFail(Obj.sections()))
- if (Name == unwrapOrError(FileName, Obj.getSectionName(&Shdr)))
- return &Shdr;
- return nullptr;
-}
-
static const EnumEntry<unsigned> ElfClass[] = {
{"None", "none", ELF::ELFCLASSNONE},
{"32-bit", "ELF32", ELF::ELFCLASS32},
}
template <class ELFT>
+Expected<const typename ELFT::Shdr *>
+ELFDumper<ELFT>::findSectionByName(StringRef Name) const {
+ const ELFFile<ELFT> *Obj = ObjF->getELFFile();
+ for (const Elf_Shdr &Shdr : cantFail(Obj->sections())) {
+ if (Expected<StringRef> NameOrErr = Obj->getSectionName(&Shdr)) {
+ if (*NameOrErr == Name)
+ return &Shdr;
+ } else {
+ reportUniqueWarning(createError("unable to read the name of " +
+ describe(Shdr) + ": " +
+ toString(NameOrErr.takeError())));
+ }
+ }
+ return nullptr;
+}
+
+template <class ELFT>
std::string ELFDumper<ELFT>::getDynamicEntry(uint64_t Type,
uint64_t Value) const {
auto FormatHexValue = [](uint64_t V) {
ELFDumperStyle->printMipsABIFlags(ObjF);
printMipsOptions();
printMipsReginfo();
-
- MipsGOTParser<ELFT> Parser(Obj, ObjF->getFileName(), dynamic_table(),
- dynamic_symbols());
+ MipsGOTParser<ELFT> Parser(*this);
if (Error E = Parser.findGOT(dynamic_table(), dynamic_symbols()))
reportError(std::move(E), ObjF->getFileName());
else if (!Parser.isGotEmpty())
const bool IsStatic;
const ELFO * const Obj;
+ const ELFDumper<ELFT> &Dumper;
- MipsGOTParser(const ELFO *Obj, StringRef FileName, Elf_Dyn_Range DynTable,
- Elf_Sym_Range DynSyms);
+ MipsGOTParser(const ELFDumper<ELFT> &D);
Error findGOT(Elf_Dyn_Range DynTable, Elf_Sym_Range DynSyms);
Error findPLT(Elf_Dyn_Range DynTable);
} // end anonymous namespace
template <class ELFT>
-MipsGOTParser<ELFT>::MipsGOTParser(const ELFO *Obj, StringRef FileName,
- Elf_Dyn_Range DynTable,
- Elf_Sym_Range DynSyms)
- : IsStatic(DynTable.empty()), Obj(Obj), GotSec(nullptr), LocalNum(0),
- GlobalNum(0), PltSec(nullptr), PltRelSec(nullptr), PltSymTable(nullptr),
- FileName(FileName) {}
+MipsGOTParser<ELFT>::MipsGOTParser(const ELFDumper<ELFT> &D)
+ : IsStatic(D.dynamic_table().empty()), Obj(D.getElfObject()->getELFFile()),
+ Dumper(D), GotSec(nullptr), LocalNum(0), GlobalNum(0), PltSec(nullptr),
+ PltRelSec(nullptr), PltSymTable(nullptr),
+ FileName(D.getElfObject()->getFileName()) {}
template <class ELFT>
Error MipsGOTParser<ELFT>::findGOT(Elf_Dyn_Range DynTable,
// Find static GOT secton.
if (IsStatic) {
- GotSec = findSectionByName(*Obj, FileName, ".got");
+ Expected<const Elf_Shdr *> GotOrErr = Dumper.findSectionByName(".got");
+ if (!GotOrErr)
+ return GotOrErr.takeError();
+ else
+ GotSec = *GotOrErr;
+
if (!GotSec)
return Error::success();
template <class ELFT> void ELFDumper<ELFT>::printMipsReginfo() {
const ELFFile<ELFT> *Obj = ObjF->getELFFile();
- const Elf_Shdr *Shdr = findSectionByName(*Obj, ObjF->getFileName(), ".reginfo");
- if (!Shdr) {
+ Expected<const Elf_Shdr *> RegInfoOrErr = findSectionByName(".reginfo");
+ if (!RegInfoOrErr) {
+ reportUniqueWarning(RegInfoOrErr.takeError());
+ return;
+ }
+
+ if ((*RegInfoOrErr) == nullptr) {
W.startLine() << "There is no .reginfo section in the file.\n";
return;
}
- ArrayRef<uint8_t> Sec =
- unwrapOrError(ObjF->getFileName(), Obj->getSectionContents(Shdr));
+
+ ArrayRef<uint8_t> Sec = unwrapOrError(ObjF->getFileName(),
+ Obj->getSectionContents(*RegInfoOrErr));
if (Sec.size() != sizeof(Elf_Mips_RegInfo<ELFT>)) {
W.startLine() << "The .reginfo section has a wrong size.\n";
return;
template <class ELFT> void ELFDumper<ELFT>::printMipsOptions() {
const ELFFile<ELFT> *Obj = ObjF->getELFFile();
- const Elf_Shdr *Shdr =
- findSectionByName(*Obj, ObjF->getFileName(), ".MIPS.options");
- if (!Shdr) {
+ Expected<const Elf_Shdr *> MipsOptOrErr = findSectionByName(".MIPS.options");
+ if (!MipsOptOrErr) {
+ reportUniqueWarning(MipsOptOrErr.takeError());
+ return;
+ }
+
+ if ((*MipsOptOrErr) == nullptr) {
W.startLine() << "There is no .MIPS.options section in the file.\n";
return;
}
DictScope GS(W, "MIPS Options");
- ArrayRef<uint8_t> Sec =
- unwrapOrError(ObjF->getFileName(), Obj->getSectionContents(Shdr));
+ ArrayRef<uint8_t> Sec = unwrapOrError(ObjF->getFileName(),
+ Obj->getSectionContents(*MipsOptOrErr));
while (!Sec.empty()) {
if (Sec.size() < sizeof(Elf_Mips_Options<ELFT>)) {
W.startLine() << "The .MIPS.options section has a wrong size.\n";
template <class ELFT>
Expected<const Elf_Mips_ABIFlags<ELFT> *>
-getMipsAbiFlagsSection(const ELFObjectFile<ELFT> *ObjF) {
- const ELFFile<ELFT> *Obj = ObjF->getELFFile();
- const typename ELFT::Shdr *Shdr =
- findSectionByName(*Obj, ObjF->getFileName(), ".MIPS.abiflags");
- if (!Shdr)
+getMipsAbiFlagsSection(const ELFObjectFile<ELFT> *ObjF,
+ const ELFDumper<ELFT> &Dumper) {
+ Expected<const typename ELFT::Shdr *> SecOrErr =
+ Dumper.findSectionByName(".MIPS.abiflags");
+ if (!SecOrErr)
+ return SecOrErr.takeError();
+ if (*SecOrErr == nullptr)
return nullptr;
+ const ELFFile<ELFT> *Obj = ObjF->getELFFile();
constexpr StringRef ErrPrefix = "unable to read the .MIPS.abiflags section: ";
- Expected<ArrayRef<uint8_t>> DataOrErr = Obj->getSectionContents(Shdr);
+ Expected<ArrayRef<uint8_t>> DataOrErr = Obj->getSectionContents(*SecOrErr);
if (!DataOrErr)
return createError(ErrPrefix + toString(DataOrErr.takeError()));
void GNUStyle<ELFT>::printMipsABIFlags(const ELFObjectFile<ELFT> *ObjF) {
const Elf_Mips_ABIFlags<ELFT> *Flags = nullptr;
if (Expected<const Elf_Mips_ABIFlags<ELFT> *> SecOrErr =
- getMipsAbiFlagsSection(ObjF))
+ getMipsAbiFlagsSection(ObjF, *this->dumper()))
Flags = *SecOrErr;
else
this->reportUniqueWarning(SecOrErr.takeError());
void LLVMStyle<ELFT>::printMipsABIFlags(const ELFObjectFile<ELFT> *ObjF) {
const Elf_Mips_ABIFlags<ELFT> *Flags;
if (Expected<const Elf_Mips_ABIFlags<ELFT> *> SecOrErr =
- getMipsAbiFlagsSection(ObjF)) {
+ getMipsAbiFlagsSection(ObjF, *this->dumper())) {
Flags = *SecOrErr;
if (!Flags) {
W.startLine() << "There is no .MIPS.abiflags section in the file.\n";