Index: llvm/test/tools/llvm-readobj/ELF/note-core-ntfile-bad.test =================================================================== --- llvm/test/tools/llvm-readobj/ELF/note-core-ntfile-bad.test +++ llvm/test/tools/llvm-readobj/ELF/note-core-ntfile-bad.test @@ -9,7 +9,9 @@ # RUN: yaml2obj --docnum=1 %s -o %t1.o # RUN: llvm-readelf -n %t1.o 2>&1 | FileCheck -DFILE=%t1.o %s --check-prefix=ERR-HEADER-SHORT -# ERR-HEADER-SHORT: warning: '[[FILE]]': malformed note: header too short +# RUN: llvm-readobj -n %t1.o 2>&1 | FileCheck -DFILE=%t1.o %s --check-prefix=ERR-HEADER-SHORT + +# ERR-HEADER-SHORT: warning: '[[FILE]]': unable to read note with index 0 from the PT_NOTE segment with index 1: the note of size 0x8 is too short, expected at least 0x10 # .section ".note.foo", "a" # .align 4 @@ -38,7 +40,9 @@ # RUN: yaml2obj --docnum=2 %s -o %t2.o # RUN: llvm-readelf -n %t2.o 2>&1 | FileCheck -DFILE=%t2.o %s --check-prefix=ERR-NULL-TERM -# ERR-NULL-TERM: warning: '[[FILE]]': malformed note: not NUL terminated +# RUN: llvm-readobj -n %t2.o 2>&1 | FileCheck -DFILE=%t2.o %s --check-prefix=ERR-NULL-TERM + +# ERR-NULL-TERM: warning: '[[FILE]]': unable to read note with index 0 from the PT_NOTE segment with index 1: the note is not NUL terminated # .section ".note.foo", "a" # .align 4 @@ -72,7 +76,9 @@ # RUN: yaml2obj --docnum=3 %s -o %t3.o # RUN: llvm-readelf -n %t3.o 2>&1 | FileCheck -DFILE=%t3.o %s --check-prefix=ERR-FILE-COUNT -# ERR-FILE-COUNT: warning: '[[FILE]]': malformed note: too short for number of files +# RUN: llvm-readobj -n %t3.o 2>&1 | FileCheck -DFILE=%t3.o %s --check-prefix=ERR-FILE-COUNT + +# ERR-FILE-COUNT: warning: '[[FILE]]': unable to read note with index 0 from the PT_NOTE segment with index 1: unable to read file mappings (found 2): the note of size 0x2c is too short # .section ".note.foo", "a" # .align 4 @@ -106,7 +112,9 @@ # RUN: yaml2obj --docnum=4 %s -o %t4.o # RUN: llvm-readelf -n %t4.o 2>&1 | FileCheck -DFILE=%t4.o %s --check-prefix=ERR-FILE-END-EARLY -# ERR-FILE-END-EARLY: warning: '[[FILE]]': malformed note: too few filenames +# RUN: llvm-readobj -n %t4.o 2>&1 | FileCheck -DFILE=%t4.o %s --check-prefix=ERR-FILE-END-EARLY + +# ERR-FILE-END-EARLY: warning: '[[FILE]]': unable to read note with index 0 from the PT_NOTE segment with index 1: unable to read the file name for the mapping with index 2: the note of size 0x44 is truncated # .section ".note.foo", "a" # .align 4 Index: llvm/tools/llvm-readobj/ELFDumper.cpp =================================================================== --- llvm/tools/llvm-readobj/ELFDumper.cpp +++ llvm/tools/llvm-readobj/ELFDumper.cpp @@ -5333,19 +5333,20 @@ const int Bytes = Desc.getAddressSize(); if (!Desc.isValidOffsetForAddress(2)) - return createStringError(object_error::parse_failed, - "malformed note: header too short"); + return createError("the note of size 0x" + Twine::utohexstr(Desc.size()) + + " is too short, expected at least 0x" + + Twine::utohexstr(Bytes * 2)); if (Desc.getData().back() != 0) - return createStringError(object_error::parse_failed, - "malformed note: not NUL terminated"); + return createError("the note is not NUL terminated"); uint64_t DescOffset = 0; uint64_t FileCount = Desc.getAddress(&DescOffset); Ret.PageSize = Desc.getAddress(&DescOffset); if (!Desc.isValidOffsetForAddress(3 * FileCount * Bytes)) - return createStringError(object_error::parse_failed, - "malformed note: too short for number of files"); + return createError("unable to read file mappings (found " + + Twine(FileCount) + "): the note of size 0x" + + Twine::utohexstr(Desc.size()) + " is too short"); uint64_t FilenamesOffset = 0; DataExtractor Filenames( @@ -5353,10 +5354,14 @@ Desc.isLittleEndian(), Desc.getAddressSize()); Ret.Mappings.resize(FileCount); + size_t I = 0; for (CoreFileMapping &Mapping : Ret.Mappings) { + ++I; if (!Filenames.isValidOffsetForDataOfSize(FilenamesOffset, 1)) - return createStringError(object_error::parse_failed, - "malformed note: too few filenames"); + return createError( + "unable to read the file name for the mapping with index " + + Twine(I) + ": the note of size 0x" + Twine::utohexstr(Desc.size()) + + " is truncated"); Mapping.Start = Desc.getAddress(&DescOffset); Mapping.End = Desc.getAddress(&DescOffset); Mapping.Offset = Desc.getAddress(&DescOffset); @@ -5521,7 +5526,7 @@ llvm::function_ref, typename ELFT::Off, typename ELFT::Addr)> StartNotesFn, - llvm::function_ref ProcessNoteFn, + llvm::function_ref ProcessNoteFn, llvm::function_ref FinishNotesFn) { const ELFFile &Obj = Dumper.getElfObject().getELFFile(); @@ -5533,8 +5538,14 @@ StartNotesFn(expectedToOptional(Obj.getSectionName(S)), S.sh_offset, S.sh_size); Error Err = Error::success(); - for (const typename ELFT::Note Note : Obj.notes(S, Err)) - ProcessNoteFn(Note); + size_t I = 0; + for (const typename ELFT::Note Note : Obj.notes(S, Err)) { + if (Error E = ProcessNoteFn(Note)) + Dumper.reportUniqueWarning( + "unable to read note with index " + Twine(I) + " from the " + + describe(Obj, S) + ": " + toString(std::move(E))); + ++I; + } if (Err) Dumper.reportUniqueWarning("unable to read notes from the " + describe(Obj, S) + ": " + @@ -5559,8 +5570,15 @@ continue; StartNotesFn(/*SecName=*/None, P.p_offset, P.p_filesz); Error Err = Error::success(); - for (const typename ELFT::Note Note : Obj.notes(P, Err)) - ProcessNoteFn(Note); + size_t Index = 0; + for (const typename ELFT::Note Note : Obj.notes(P, Err)) { + if (Error E = ProcessNoteFn(Note)) + Dumper.reportUniqueWarning("unable to read note with index " + + Twine(Index) + + " from the PT_NOTE segment with index " + + Twine(I) + ": " + toString(std::move(E))); + ++Index; + } if (Err) Dumper.reportUniqueWarning( "unable to read notes from the PT_NOTE segment with index " + @@ -5584,7 +5602,7 @@ OS << " Owner Data size \tDescription\n"; }; - auto ProcessNote = [&](const Elf_Note &Note) { + auto ProcessNote = [&](const Elf_Note &Note) -> Error { StringRef Name = Note.getName(); ArrayRef Descriptor = Note.getDesc(); Elf_Word Type = Note.getType(); @@ -5617,11 +5635,10 @@ DataExtractor DescExtractor(Descriptor, ELFT::TargetEndianness == support::little, sizeof(Elf_Addr)); - Expected Note = readCoreNote(DescExtractor); - if (Note) - printCoreNote(OS, *Note); + if (Expected NoteOrErr = readCoreNote(DescExtractor)) + printCoreNote(OS, *NoteOrErr); else - reportWarning(Note.takeError(), this->FileName); + return NoteOrErr.takeError(); } } else if (!Descriptor.empty()) { OS << " description data:"; @@ -5629,6 +5646,7 @@ OS << " " << format("%02x", B); OS << '\n'; } + return Error::success(); }; printNotesHelper(this->dumper(), PrintHeader, ProcessNote, []() {}); @@ -6828,7 +6846,7 @@ auto EndNotes = [&] { NoteScope.reset(); }; - auto ProcessNote = [&](const Elf_Note &Note) { + auto ProcessNote = [&](const Elf_Note &Note) -> Error { DictScope D2(W, "Note"); StringRef Name = Note.getName(); ArrayRef Descriptor = Note.getDesc(); @@ -6863,15 +6881,15 @@ DataExtractor DescExtractor(Descriptor, ELFT::TargetEndianness == support::little, sizeof(Elf_Addr)); - Expected Note = readCoreNote(DescExtractor); - if (Note) + if (Expected Note = readCoreNote(DescExtractor)) printCoreNoteLLVMStyle(*Note, W); else - reportWarning(Note.takeError(), this->FileName); + return Note.takeError(); } } else if (!Descriptor.empty()) { W.printBinaryBlock("Description data", Descriptor); } + return Error::success(); }; printNotesHelper(this->dumper(), StartNotes, ProcessNote, EndNotes);