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");