diff --git a/llvm/lib/Support/ELFAttributeParser.cpp b/llvm/lib/Support/ELFAttributeParser.cpp index df955cdf5d30a5..2a30794bc1e910 100644 --- a/llvm/lib/Support/ELFAttributeParser.cpp +++ b/llvm/lib/Support/ELFAttributeParser.cpp @@ -200,7 +200,7 @@ Error ELFAttributeParser::parse(ArrayRef section, // Unrecognized format-version. uint8_t formatVersion = de.getU8(cursor); - if (formatVersion != 'A') + if (formatVersion != ELFAttrs::Format_Version) return createStringError(errc::invalid_argument, "unrecognized format-version: 0x" + utohexstr(formatVersion)); diff --git a/llvm/test/tools/llvm-readobj/ELF/RISCV/attributes-invalid.test b/llvm/test/tools/llvm-readobj/ELF/RISCV/attributes-invalid.test index 547ed93bcd10ba..882bbb53b5774e 100644 --- a/llvm/test/tools/llvm-readobj/ELF/RISCV/attributes-invalid.test +++ b/llvm/test/tools/llvm-readobj/ELF/RISCV/attributes-invalid.test @@ -5,11 +5,16 @@ ## here we use 'B' (42). # RUN: yaml2obj %s -D BITS=32 -DCONTENT=42 -o %t1.32.o -# RUN: llvm-readobj -A %t1.32.o 2>&1 | FileCheck -DFILE=%t1 %s --check-prefix=ERR-FORMAT +# RUN: llvm-readobj -A %t1.32.o 2>&1 | \ +# RUN: FileCheck -DFILE=%t1 %s --implicit-check-not=warning: --check-prefix=ERR-FORMAT # RUN: yaml2obj %s -D BITS=64 -DCONTENT=42 -o %t1.64.o -# RUN: llvm-readobj -A %t1.64.o 2>&1 | FileCheck -DFILE=%t1 %s --check-prefix=ERR-FORMAT +# RUN: llvm-readobj -A %t1.64.o 2>&1 | \ +# RUN: FileCheck -DFILE=%t1 %s --implicit-check-not=warning: --check-prefix=ERR-FORMAT -# ERR-FORMAT: warning: '[[FILE]].{{32|64}}.o': unrecognised FormatVersion: 0x42 +# ERR-FORMAT: BuildAttributes { +# ERR-FORMAT-NEXT: FormatVersion: 0x42 +# ERR-FORMAT-NEXT: warning: '[[FILE]].{{32|64}}.o': unable to dump attributes from the SHT_RISCV_ATTRIBUTES section with index 1: unrecognized format-version: 0x42 +# ERR-FORMAT-NEXT: } --- !ELF FileHeader: @@ -18,15 +23,54 @@ FileHeader: Type: ET_REL Machine: EM_RISCV Sections: - - Name: .riscv.attributes - Type: SHT_RISCV_ATTRIBUTES - Content: [[CONTENT]] + - Name: .riscv.attributes + Type: SHT_RISCV_ATTRIBUTES + Content: [[CONTENT]] + ShOffset: [[SHOFFSET=]] ## Check we report a warning when we are unable to parse the attribute section data. +## FIXME: this test case documents that we don't close the "Section X" clause of +## the output properly when a warning is reported by the attributes parser. # RUN: yaml2obj %s -D BITS=32 -DCONTENT=4100000000 -o %t2.32.o -# RUN: llvm-readobj -A %t2.32.o 2>&1 | FileCheck -DFILE=%t2 %s --check-prefix=ERR-LENGTH +# RUN: llvm-readobj -A %t2.32.o 2>&1 | \ +# RUN: FileCheck -DFILE=%t2 %s --implicit-check-not=warning: --check-prefix=ERR-LENGTH # RUN: yaml2obj %s -D BITS=64 -DCONTENT=4100000000 -o %t2.64.o -# RUN: llvm-readobj -A %t2.64.o 2>&1 | FileCheck -DFILE=%t2 %s --check-prefix=ERR-LENGTH +# RUN: llvm-readobj -A %t2.64.o 2>&1 | \ +# RUN: FileCheck -DFILE=%t2 %s --implicit-check-not=warning: --check-prefix=ERR-LENGTH -# ERR-LENGTH: warning: '[[FILE]].{{32|64}}.o': invalid section length 0 at offset 0x1 +# ERR-LENGTH: BuildAttributes { +# ERR-LENGTH-NEXT: FormatVersion: 0x41 +# ERR-LENGTH-NEXT: Section 1 { +# ERR-LENGTH-NEXT: warning: '[[FILE]].{{32|64}}.o': unable to dump attributes from the SHT_RISCV_ATTRIBUTES section with index 1: invalid section length 0 at offset 0x1 +# ERR-LENGTH-NEXT: } +# ERR-LENGTH-NOT: {{.}} + +## Check that we don't report a warning when the SHT_RISCV_ATTRIBUTES section contains the +## valid format version byte and no other data. + +# RUN: yaml2obj %s -DCONTENT=41 -o %t3.o +# RUN: llvm-readobj -A %t3.o 2>&1 | \ +# RUN: FileCheck %s --implicit-check-not=warning: --check-prefix=NO-CONTENT + +# NO-CONTENT: BuildAttributes { +# NO-CONTENT-NEXT: FormatVersion: 0x41 +# NO-CONTENT-NEXT: } + +## Check we report a warning when we are unable to read the content of the SHT_RISCV_ATTRIBUTES section. + +# RUN: yaml2obj %s -DCONTENT="''" -DSHOFFSET=0xffffffff -o %t4.o +# RUN: llvm-readobj -A %t4.o 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t4.o --implicit-check-not=warning: --check-prefix=BROKEN-CONTENT + +# BROKEN-CONTENT: BuildAttributes { +# BROKEN-CONTENT-NEXT: warning: '[[FILE]]': unable to read the content of the SHT_RISCV_ATTRIBUTES section with index 1: section [index 1] has a sh_offset (0xffffffff) + sh_size (0x0) that is greater than the file size (0x168) +# BROKEN-CONTENT-NEXT: } + +# RUN: yaml2obj %s -DCONTENT="''" -o %t5.o +# RUN: llvm-readobj -A %t5.o 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t5.o --implicit-check-not=warning: --check-prefix=EMPTY-CONTENT + +# EMPTY-CONTENT: BuildAttributes { +# EMPTY-CONTENT-NEXT: warning: '[[FILE]]': the SHT_RISCV_ATTRIBUTES section with index 1 is empty +# EMPTY-CONTENT-NEXT: } diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index d5313d6c182a30..646616f6649d15 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -2896,26 +2896,31 @@ template void ELFDumper::printAttributes() { Sec.sh_type != ELF::SHT_RISCV_ATTRIBUTES) continue; - ArrayRef Contents = - unwrapOrError(ObjF.getFileName(), Obj.getSectionContents(Sec)); - if (Contents[0] != ELFAttrs::Format_Version) { - reportWarning(createError(Twine("unrecognised FormatVersion: 0x") + - Twine::utohexstr(Contents[0])), - ObjF.getFileName()); + ArrayRef Contents; + if (Expected> ContentOrErr = + Obj.getSectionContents(Sec)) { + Contents = *ContentOrErr; + if (Contents.empty()) { + reportUniqueWarning("the " + describe(Sec) + " is empty"); + continue; + } + } else { + reportUniqueWarning("unable to read the content of the " + describe(Sec) + + ": " + toString(ContentOrErr.takeError())); continue; } + W.printHex("FormatVersion", Contents[0]); - if (Contents.size() == 1) - continue; - // TODO: Delete the redundant FormatVersion check above. - if (Machine == EM_ARM) { - if (Error E = ARMAttributeParser(&W).parse(Contents, support::little)) - reportWarning(std::move(E), ObjF.getFileName()); - } else if (Machine == EM_RISCV) { - if (Error E = RISCVAttributeParser(&W).parse(Contents, support::little)) - reportWarning(std::move(E), ObjF.getFileName()); - } + auto ParseAttrubutes = [&]() { + if (Machine == EM_ARM) + return ARMAttributeParser(&W).parse(Contents, support::little); + return RISCVAttributeParser(&W).parse(Contents, support::little); + }; + + if (Error E = ParseAttrubutes()) + reportUniqueWarning("unable to dump attributes from the " + + describe(Sec) + ": " + toString(std::move(E))); } }