forked from OSchip/llvm-project
[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:
parent
0bf3d4bc31
commit
ec0b927e4a
|
@ -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() {
|
||||||
|
|
Loading…
Reference in New Issue