Skip to content

Commit

Permalink
[llvm-readelf/obj] - Deduplicate the logic that prints notes. NFCI.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Georgii Rymar committed Nov 25, 2020
1 parent 0bf3d4b commit ec0b927
Showing 1 changed file with 57 additions and 71 deletions.
128 changes: 57 additions & 71 deletions llvm/tools/llvm-readobj/ELFDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5541,6 +5541,54 @@ const StringRef getNoteTypeName(const typename ELFT::Note &Note,
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() {
auto PrintHeader = [&](Optional<StringRef> SecName,
const typename ELFT::Off Offset,
Expand Down Expand Up @@ -5603,39 +5651,7 @@ template <class ELFT> void GNUStyle<ELFT>::printNotes() {
}
};

ArrayRef<Elf_Shdr> 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<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);
}
}
printNotesHelper(this->dumper(), PrintHeader, ProcessNote);
}

template <class ELFT> void GNUStyle<ELFT>::printELFLinkerOptions() {
Expand Down Expand Up @@ -6828,14 +6844,18 @@ static void printCoreNoteLLVMStyle(const CoreNote &Note, ScopedPrinter &W) {
template <class ELFT> void LLVMStyle<ELFT>::printNotes() {
ListScope L(W, "Notes");

auto PrintHeader = [&](Optional<StringRef> SecName,
const typename ELFT::Off Offset,
const typename ELFT::Addr Size) {
std::unique_ptr<DictScope> NoteScope;
auto StartNotes = [&](Optional<StringRef> SecName,
const typename ELFT::Off Offset,
const typename ELFT::Addr Size) {
NoteScope = std::make_unique<DictScope>(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();
Expand Down Expand Up @@ -6882,41 +6902,7 @@ template <class ELFT> void LLVMStyle<ELFT>::printNotes() {
}
};

ArrayRef<Elf_Shdr> 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<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);
}
}
printNotesHelper(this->dumper(), StartNotes, ProcessNote, EndNotes);
}

template <class ELFT> void LLVMStyle<ELFT>::printELFLinkerOptions() {
Expand Down

0 comments on commit ec0b927

Please sign in to comment.