# 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
# 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
# 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
# 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
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(
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);
llvm::function_ref<void(Optional<StringRef>, typename ELFT::Off,
typename ELFT::Addr)>
StartNotesFn,
- llvm::function_ref<void(const typename ELFT::Note &)> ProcessNoteFn,
+ llvm::function_ref<Error(const typename ELFT::Note &)> ProcessNoteFn,
llvm::function_ref<void()> FinishNotesFn) {
const ELFFile<ELFT> &Obj = Dumper.getElfObject().getELFFile();
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) + ": " +
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 " +
OS << " Owner Data size \tDescription\n";
};
- auto ProcessNote = [&](const Elf_Note &Note) {
+ auto ProcessNote = [&](const Elf_Note &Note) -> Error {
StringRef Name = Note.getName();
ArrayRef<uint8_t> Descriptor = Note.getDesc();
Elf_Word Type = Note.getType();
DataExtractor DescExtractor(Descriptor,
ELFT::TargetEndianness == support::little,
sizeof(Elf_Addr));
- Expected<CoreNote> Note = readCoreNote(DescExtractor);
- if (Note)
- printCoreNote<ELFT>(OS, *Note);
+ if (Expected<CoreNote> NoteOrErr = readCoreNote(DescExtractor))
+ printCoreNote<ELFT>(OS, *NoteOrErr);
else
- reportWarning(Note.takeError(), this->FileName);
+ return NoteOrErr.takeError();
}
} else if (!Descriptor.empty()) {
OS << " description data:";
OS << " " << format("%02x", B);
OS << '\n';
}
+ return Error::success();
};
printNotesHelper(this->dumper(), PrintHeader, ProcessNote, []() {});
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<uint8_t> Descriptor = Note.getDesc();
DataExtractor DescExtractor(Descriptor,
ELFT::TargetEndianness == support::little,
sizeof(Elf_Addr));
- Expected<CoreNote> Note = readCoreNote(DescExtractor);
- if (Note)
+ if (Expected<CoreNote> 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);