[llvm-readelf/obj] - Deduplicate the logic that prints notes. NFCI.

We have a similar logic for LLVM/GNU styles that can be deduplicated.
This will allow to replace `reportError` calls with `reportUniqueWarning`
calls in a single place.

Differential revision: https://reviews.llvm.org/D92018
This commit is contained in:
Georgii Rymar 2020-11-24 13:49:40 +03:00
parent 0bf3d4bc31
commit ec0b927e4a
1 changed files with 57 additions and 71 deletions

View File

@ -5541,6 +5541,54 @@ const StringRef getNoteTypeName(const typename ELFT::Note &Note,
return FindNote(GenericNoteTypes); return FindNote(GenericNoteTypes);
} }
template <class ELFT>
static void printNotesHelper(
const ELFDumper<ELFT> &Dumper,
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<void()> FinishNotesFn = []() {}) {
const ELFFile<ELFT> &Obj = *Dumper.getElfObject().getELFFile();
ArrayRef<typename ELFT::Shdr> Sections = cantFail(Obj.sections());
if (Obj.getHeader().e_type != ELF::ET_CORE && !Sections.empty()) {
for (const typename ELFT::Shdr &S : Sections) {
if (S.sh_type != SHT_NOTE)
continue;
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);
if (Err)
reportError(std::move(Err), Dumper.getElfObject().getFileName());
FinishNotesFn();
}
return;
}
Expected<ArrayRef<typename ELFT::Phdr>> PhdrsOrErr = Obj.program_headers();
if (!PhdrsOrErr) {
Dumper.reportUniqueWarning(createError(
"unable to read program headers to locate the PT_NOTE segment: " +
toString(PhdrsOrErr.takeError())));
return;
}
for (const typename ELFT::Phdr &P : *PhdrsOrErr) {
if (P.p_type != PT_NOTE)
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);
if (Err)
reportError(std::move(Err), Dumper.getElfObject().getFileName());
FinishNotesFn();
}
}
template <class ELFT> void GNUStyle<ELFT>::printNotes() { template <class ELFT> void GNUStyle<ELFT>::printNotes() {
auto PrintHeader = [&](Optional<StringRef> SecName, auto PrintHeader = [&](Optional<StringRef> SecName,
const typename ELFT::Off Offset, const typename ELFT::Off Offset,
@ -5603,39 +5651,7 @@ template <class ELFT> void GNUStyle<ELFT>::printNotes() {
} }
}; };
ArrayRef<Elf_Shdr> Sections = cantFail(this->Obj.sections()); printNotesHelper(this->dumper(), PrintHeader, ProcessNote);
if (this->Obj.getHeader().e_type != ELF::ET_CORE && !Sections.empty()) {
for (const Elf_Shdr &S : Sections) {
if (S.sh_type != SHT_NOTE)
continue;
PrintHeader(expectedToOptional(this->Obj.getSectionName(S)), S.sh_offset,
S.sh_size);
Error Err = Error::success();
for (const Elf_Note Note : this->Obj.notes(S, Err))
ProcessNote(Note);
if (Err)
reportError(std::move(Err), this->FileName);
}
} else {
Expected<ArrayRef<Elf_Phdr>> PhdrsOrErr = this->Obj.program_headers();
if (!PhdrsOrErr) {
this->reportUniqueWarning(createError(
"unable to read program headers to locate the PT_NOTE segment: " +
toString(PhdrsOrErr.takeError())));
return;
}
for (const Elf_Phdr &P : *PhdrsOrErr) {
if (P.p_type != PT_NOTE)
continue;
PrintHeader(/*SecName=*/None, P.p_offset, P.p_filesz);
Error Err = Error::success();
for (const Elf_Note Note : this->Obj.notes(P, Err))
ProcessNote(Note);
if (Err)
reportError(std::move(Err), this->FileName);
}
}
} }
template <class ELFT> void GNUStyle<ELFT>::printELFLinkerOptions() { template <class ELFT> void GNUStyle<ELFT>::printELFLinkerOptions() {
@ -6828,14 +6844,18 @@ static void printCoreNoteLLVMStyle(const CoreNote &Note, ScopedPrinter &W) {
template <class ELFT> void LLVMStyle<ELFT>::printNotes() { template <class ELFT> void LLVMStyle<ELFT>::printNotes() {
ListScope L(W, "Notes"); ListScope L(W, "Notes");
auto PrintHeader = [&](Optional<StringRef> SecName, std::unique_ptr<DictScope> NoteScope;
const typename ELFT::Off Offset, auto StartNotes = [&](Optional<StringRef> SecName,
const typename ELFT::Addr Size) { const typename ELFT::Off Offset,
const typename ELFT::Addr Size) {
NoteScope = std::make_unique<DictScope>(W, "NoteSection");
W.printString("Name", SecName ? *SecName : "<?>"); W.printString("Name", SecName ? *SecName : "<?>");
W.printHex("Offset", Offset); W.printHex("Offset", Offset);
W.printHex("Size", Size); W.printHex("Size", Size);
}; };
auto EndNotes = [&] { NoteScope.reset(); };
auto ProcessNote = [&](const Elf_Note &Note) { auto ProcessNote = [&](const Elf_Note &Note) {
DictScope D2(W, "Note"); DictScope D2(W, "Note");
StringRef Name = Note.getName(); StringRef Name = Note.getName();
@ -6882,41 +6902,7 @@ template <class ELFT> void LLVMStyle<ELFT>::printNotes() {
} }
}; };
ArrayRef<Elf_Shdr> Sections = cantFail(this->Obj.sections()); printNotesHelper(this->dumper(), StartNotes, ProcessNote, EndNotes);
if (this->Obj.getHeader().e_type != ELF::ET_CORE && !Sections.empty()) {
for (const Elf_Shdr &S : Sections) {
if (S.sh_type != SHT_NOTE)
continue;
DictScope D(W, "NoteSection");
PrintHeader(expectedToOptional(this->Obj.getSectionName(S)), S.sh_offset,
S.sh_size);
Error Err = Error::success();
for (auto Note : this->Obj.notes(S, Err))
ProcessNote(Note);
if (Err)
reportError(std::move(Err), this->FileName);
}
} else {
Expected<ArrayRef<Elf_Phdr>> PhdrsOrErr = this->Obj.program_headers();
if (!PhdrsOrErr) {
this->reportUniqueWarning(createError(
"unable to read program headers to locate the PT_NOTE segment: " +
toString(PhdrsOrErr.takeError())));
return;
}
for (const Elf_Phdr &P : *PhdrsOrErr) {
if (P.p_type != PT_NOTE)
continue;
DictScope D(W, "NoteSection");
PrintHeader(/*SecName=*/None, P.p_offset, P.p_filesz);
Error Err = Error::success();
for (auto Note : this->Obj.notes(P, Err))
ProcessNote(Note);
if (Err)
reportError(std::move(Err), this->FileName);
}
}
} }
template <class ELFT> void LLVMStyle<ELFT>::printELFLinkerOptions() { template <class ELFT> void LLVMStyle<ELFT>::printELFLinkerOptions() {