Skip to content

Commit

Permalink
[llvm-readelf/readobj] - Refine the error reporting in printMipsABIFl…
Browse files Browse the repository at this point in the history
…ags() methods.

It fixes/improves the following:
1) Some code was duplicated.
2) A "The .MIPS.abiflags section has a wrong size" error was not reported as a warning,
   but was printed to stdout for the LLVM style. Also, it was reported as an error for the GNU style.
   This patch changes the behavior to be consistent and to report warnings.
3) `unwrapOrError()` was used before, now a warning is reported instead.

Differential revision: https://reviews.llvm.org/D84033
  • Loading branch information
Georgii Rymar committed Jul 20, 2020
1 parent b6073ee commit 256aea8
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 22 deletions.
52 changes: 52 additions & 0 deletions llvm/test/tools/llvm-readobj/ELF/mips-abiflags.test
Expand Up @@ -312,3 +312,55 @@ Sections:

# FLAG2-ALL-GNU: FLAGS 2: ffffffff
# FLAG2-ALL-LLVM: Flags 2: 0xFFFFFFF

## Check what we print when there is no .MIPS.abiflags section in the file.
# RUN: yaml2obj --docnum=2 %s -o %t.nosection
## Note: GNU readelf 2.31.1 prints nothing.
# RUN: llvm-readelf -A %t.nosection 2>&1 | \
# RUN: FileCheck %s --check-prefix=NOSEC --implicit-check-not={{.}}
# RUN: llvm-readobj -A %t.nosection 2>&1 | \
# RUN: FileCheck %s --check-prefixes=NOSEC,NOSEC-LLVM --implicit-check-not=warning:

# NOSEC-LLVM: There is no .MIPS.abiflags section in the file.
# NOSEC: There is no .MIPS.options section in the file.
# NOSEC-NEXT: There is no .reginfo section in the file.

--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_MIPS
Sections: []

## Check we report a warning when we are unable to read the content of the .MIPS.abiflags section.
# RUN: yaml2obj --docnum=3 -DSHOFFSET=0xffffffff %s -o %t.err1
# 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-NEXT: There is no .MIPS.options section in the file.
# CONTENT-ERR-NEXT: There is no .reginfo section in the file.

--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_MIPS
Sections:
- Name: .MIPS.abiflags
Type: SHT_MIPS_ABIFLAGS
ISA: MIPS32
Offset: 0x100
ShOffset: [[SHOFFSET=0x100]]
ShSize: [[SHSIZE=24]]

## Check we report a warning when the .MIPS.abiflags section has an unexpected size.
# RUN: yaml2obj --docnum=3 -DSHSIZE=23 %s -o %t.err2
# RUN: llvm-readelf -A %t.err2 2>&1 | FileCheck %s -DFILE=%t.err2 --check-prefix=SIZE-ERR
# RUN: llvm-readobj -A %t.err2 2>&1 | FileCheck %s -DFILE=%t.err2 --check-prefix=SIZE-ERR

# 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.
56 changes: 34 additions & 22 deletions llvm/tools/llvm-readobj/ELFDumper.cpp
Expand Up @@ -6052,20 +6052,35 @@ void GNUStyle<ELFT>::printMipsPLT(const MipsGOTParser<ELFT> &Parser) {
}

template <class ELFT>
void GNUStyle<ELFT>::printMipsABIFlags(const ELFObjectFile<ELFT> *ObjF) {
Expected<const Elf_Mips_ABIFlags<ELFT> *>
getMipsAbiFlagsSection(const ELFObjectFile<ELFT> *ObjF) {
const ELFFile<ELFT> *Obj = ObjF->getELFFile();
const Elf_Shdr *Shdr =
const typename ELFT::Shdr *Shdr =
findSectionByName(*Obj, ObjF->getFileName(), ".MIPS.abiflags");
if (!Shdr)
return;
return nullptr;

ArrayRef<uint8_t> Sec =
unwrapOrError(ObjF->getFileName(), Obj->getSectionContents(Shdr));
if (Sec.size() != sizeof(Elf_Mips_ABIFlags<ELFT>))
reportError(createError(".MIPS.abiflags section has a wrong size"),
ObjF->getFileName());
constexpr StringRef ErrPrefix = "unable to read the .MIPS.abiflags section: ";
Expected<ArrayRef<uint8_t>> DataOrErr = Obj->getSectionContents(Shdr);
if (!DataOrErr)
return createError(ErrPrefix + toString(DataOrErr.takeError()));

auto *Flags = reinterpret_cast<const Elf_Mips_ABIFlags<ELFT> *>(Sec.data());
if (DataOrErr->size() != sizeof(Elf_Mips_ABIFlags<ELFT>))
return createError(ErrPrefix + "it has a wrong size (" +
Twine(DataOrErr->size()) + ")");
return reinterpret_cast<const Elf_Mips_ABIFlags<ELFT> *>(DataOrErr->data());
}

template <class ELFT>
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))
Flags = *SecOrErr;
else
this->reportUniqueWarning(SecOrErr.takeError());
if (!Flags)
return;

OS << "MIPS ABI Flags Version: " << Flags->version << "\n\n";
OS << "ISA: MIPS" << int(Flags->isa_level);
Expand Down Expand Up @@ -7044,22 +7059,19 @@ void LLVMStyle<ELFT>::printMipsPLT(const MipsGOTParser<ELFT> &Parser) {

template <class ELFT>
void LLVMStyle<ELFT>::printMipsABIFlags(const ELFObjectFile<ELFT> *ObjF) {
const ELFFile<ELFT> *Obj = ObjF->getELFFile();
const Elf_Shdr *Shdr =
findSectionByName(*Obj, ObjF->getFileName(), ".MIPS.abiflags");
if (!Shdr) {
W.startLine() << "There is no .MIPS.abiflags section in the file.\n";
return;
}
ArrayRef<uint8_t> Sec =
unwrapOrError(ObjF->getFileName(), Obj->getSectionContents(Shdr));
if (Sec.size() != sizeof(Elf_Mips_ABIFlags<ELFT>)) {
W.startLine() << "The .MIPS.abiflags section has a wrong size.\n";
const Elf_Mips_ABIFlags<ELFT> *Flags;
if (Expected<const Elf_Mips_ABIFlags<ELFT> *> SecOrErr =
getMipsAbiFlagsSection(ObjF)) {
Flags = *SecOrErr;
if (!Flags) {
W.startLine() << "There is no .MIPS.abiflags section in the file.\n";
return;
}
} else {
this->reportUniqueWarning(SecOrErr.takeError());
return;
}

auto *Flags = reinterpret_cast<const Elf_Mips_ABIFlags<ELFT> *>(Sec.data());

raw_ostream &OS = W.getOStream();
DictScope GS(W, "MIPS ABI Flags");

Expand Down

0 comments on commit 256aea8

Please sign in to comment.