From ec0b927e4aa863dd610b97f3d6e996ca05475846 Mon Sep 17 00:00:00 2001 From: Georgii Rymar Date: Tue, 24 Nov 2020 13:49:40 +0300 Subject: [PATCH] [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 --- llvm/tools/llvm-readobj/ELFDumper.cpp | 128 ++++++++++++-------------- 1 file changed, 57 insertions(+), 71 deletions(-) diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index d1a5aa7e0e5d..3676ee9724d3 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -5541,6 +5541,54 @@ const StringRef getNoteTypeName(const typename ELFT::Note &Note, return FindNote(GenericNoteTypes); } +template +static void printNotesHelper( + const ELFDumper &Dumper, + llvm::function_ref, typename ELFT::Off, + typename ELFT::Addr)> + StartNotesFn, + llvm::function_ref ProcessNoteFn, + llvm::function_ref FinishNotesFn = []() {}) { + const ELFFile &Obj = *Dumper.getElfObject().getELFFile(); + + ArrayRef 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> 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 void GNUStyle::printNotes() { auto PrintHeader = [&](Optional SecName, const typename ELFT::Off Offset, @@ -5603,39 +5651,7 @@ template void GNUStyle::printNotes() { } }; - ArrayRef Sections = cantFail(this->Obj.sections()); - 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> 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); - } - } + printNotesHelper(this->dumper(), PrintHeader, ProcessNote); } template void GNUStyle::printELFLinkerOptions() { @@ -6828,14 +6844,18 @@ static void printCoreNoteLLVMStyle(const CoreNote &Note, ScopedPrinter &W) { template void LLVMStyle::printNotes() { ListScope L(W, "Notes"); - auto PrintHeader = [&](Optional SecName, - const typename ELFT::Off Offset, - const typename ELFT::Addr Size) { + std::unique_ptr NoteScope; + auto StartNotes = [&](Optional SecName, + const typename ELFT::Off Offset, + const typename ELFT::Addr Size) { + NoteScope = std::make_unique(W, "NoteSection"); W.printString("Name", SecName ? *SecName : ""); W.printHex("Offset", Offset); W.printHex("Size", Size); }; + auto EndNotes = [&] { NoteScope.reset(); }; + auto ProcessNote = [&](const Elf_Note &Note) { DictScope D2(W, "Note"); StringRef Name = Note.getName(); @@ -6882,41 +6902,7 @@ template void LLVMStyle::printNotes() { } }; - ArrayRef Sections = cantFail(this->Obj.sections()); - 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> 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); - } - } + printNotesHelper(this->dumper(), StartNotes, ProcessNote, EndNotes); } template void LLVMStyle::printELFLinkerOptions() {