[llvm-readelf/readobj] - Refine the error reporting in printMipsABIFlags() methods.
authorGeorgii Rymar <grimar@accesssoftek.com>
Fri, 17 Jul 2020 12:45:01 +0000 (15:45 +0300)
committerGeorgii Rymar <grimar@accesssoftek.com>
Mon, 20 Jul 2020 08:30:17 +0000 (11:30 +0300)
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

llvm/test/tools/llvm-readobj/ELF/mips-abiflags.test
llvm/tools/llvm-readobj/ELFDumper.cpp

index 1a8affa..f4432ef 100644 (file)
@@ -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.
index 15076f1..6b28044 100644 (file)
@@ -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);
@@ -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");