From 256aea816da45bd3bc52317cbc89e704095a8991 Mon Sep 17 00:00:00 2001 From: Georgii Rymar Date: Fri, 17 Jul 2020 15:45:01 +0300 Subject: [PATCH] [llvm-readelf/readobj] - Refine the error reporting in printMipsABIFlags() 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 --- .../tools/llvm-readobj/ELF/mips-abiflags.test | 52 +++++++++++++++++ llvm/tools/llvm-readobj/ELFDumper.cpp | 56 +++++++++++-------- 2 files changed, 86 insertions(+), 22 deletions(-) diff --git a/llvm/test/tools/llvm-readobj/ELF/mips-abiflags.test b/llvm/test/tools/llvm-readobj/ELF/mips-abiflags.test index 1a8affa079843..f4432efb6aeba 100644 --- a/llvm/test/tools/llvm-readobj/ELF/mips-abiflags.test +++ b/llvm/test/tools/llvm-readobj/ELF/mips-abiflags.test @@ -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. diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index 15076f1f89337..6b28044d7d902 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -6052,20 +6052,35 @@ void GNUStyle::printMipsPLT(const MipsGOTParser &Parser) { } template -void GNUStyle::printMipsABIFlags(const ELFObjectFile *ObjF) { +Expected *> +getMipsAbiFlagsSection(const ELFObjectFile *ObjF) { const ELFFile *Obj = ObjF->getELFFile(); - const Elf_Shdr *Shdr = + const typename ELFT::Shdr *Shdr = findSectionByName(*Obj, ObjF->getFileName(), ".MIPS.abiflags"); if (!Shdr) - return; + return nullptr; - ArrayRef Sec = - unwrapOrError(ObjF->getFileName(), Obj->getSectionContents(Shdr)); - if (Sec.size() != sizeof(Elf_Mips_ABIFlags)) - reportError(createError(".MIPS.abiflags section has a wrong size"), - ObjF->getFileName()); + constexpr StringRef ErrPrefix = "unable to read the .MIPS.abiflags section: "; + Expected> DataOrErr = Obj->getSectionContents(Shdr); + if (!DataOrErr) + return createError(ErrPrefix + toString(DataOrErr.takeError())); - auto *Flags = reinterpret_cast *>(Sec.data()); + if (DataOrErr->size() != sizeof(Elf_Mips_ABIFlags)) + return createError(ErrPrefix + "it has a wrong size (" + + Twine(DataOrErr->size()) + ")"); + return reinterpret_cast *>(DataOrErr->data()); +} + +template +void GNUStyle::printMipsABIFlags(const ELFObjectFile *ObjF) { + const Elf_Mips_ABIFlags *Flags = nullptr; + if (Expected *> 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); @@ -7044,22 +7059,19 @@ void LLVMStyle::printMipsPLT(const MipsGOTParser &Parser) { template void LLVMStyle::printMipsABIFlags(const ELFObjectFile *ObjF) { - const ELFFile *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 Sec = - unwrapOrError(ObjF->getFileName(), Obj->getSectionContents(Shdr)); - if (Sec.size() != sizeof(Elf_Mips_ABIFlags)) { - W.startLine() << "The .MIPS.abiflags section has a wrong size.\n"; + const Elf_Mips_ABIFlags *Flags; + if (Expected *> 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 *>(Sec.data()); - raw_ostream &OS = W.getOStream(); DictScope GS(W, "MIPS ABI Flags");