summaryrefslogtreecommitdiff
path: root/llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h')
-rw-r--r--llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h171
1 files changed, 77 insertions, 94 deletions
diff --git a/llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h b/llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h
index 0a365d4fe72a4..27942224053f1 100644
--- a/llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h
+++ b/llvm/tools/llvm-readobj/DwarfCFIEHPrinter.h
@@ -30,12 +30,14 @@ namespace DwarfCFIEH {
template <typename ELFT>
class PrinterContext {
+ using Elf_Shdr = typename ELFT::Shdr;
+ using Elf_Phdr = typename ELFT::Phdr;
+
ScopedPrinter &W;
const object::ELFObjectFile<ELFT> *ObjF;
- void printEHFrameHdr(uint64_t Offset, uint64_t Address, uint64_t Size) const;
-
- void printEHFrame(const typename ELFT::Shdr *EHFrameShdr) const;
+ void printEHFrameHdr(const Elf_Phdr *EHFramePHdr) const;
+ void printEHFrame(const Elf_Shdr *EHFrameShdr) const;
public:
PrinterContext(ScopedPrinter &W, const object::ELFObjectFile<ELFT> *ObjF)
@@ -45,13 +47,14 @@ public:
};
template <class ELFT>
-static const typename object::ELFObjectFile<ELFT>::Elf_Shdr *
+static const typename ELFT::Shdr *
findSectionByAddress(const object::ELFObjectFile<ELFT> *ObjF, uint64_t Addr) {
- auto Sections = ObjF->getELFFile()->sections();
- if (Error E = Sections.takeError())
- reportError(std::move(E), ObjF->getFileName());
+ Expected<typename ELFT::ShdrRange> SectionsOrErr =
+ ObjF->getELFFile()->sections();
+ if (!SectionsOrErr)
+ reportError(SectionsOrErr.takeError(), ObjF->getFileName());
- for (const auto &Shdr : *Sections)
+ for (const typename ELFT::Shdr &Shdr : *SectionsOrErr)
if (Shdr.sh_addr == Addr)
return &Shdr;
return nullptr;
@@ -60,61 +63,59 @@ findSectionByAddress(const object::ELFObjectFile<ELFT> *ObjF, uint64_t Addr) {
template <typename ELFT>
void PrinterContext<ELFT>::printUnwindInformation() const {
const object::ELFFile<ELFT> *Obj = ObjF->getELFFile();
- const typename ELFT::Phdr *EHFramePhdr = nullptr;
- auto PHs = Obj->program_headers();
- if (Error E = PHs.takeError())
- reportError(std::move(E), ObjF->getFileName());
-
- for (const auto &Phdr : *PHs) {
- if (Phdr.p_type == ELF::PT_GNU_EH_FRAME) {
- EHFramePhdr = &Phdr;
- if (Phdr.p_memsz != Phdr.p_filesz)
- reportError(object::createError(
- "p_memsz does not match p_filesz for GNU_EH_FRAME"),
- ObjF->getFileName());
- break;
- }
- }
+ Expected<typename ELFT::PhdrRange> PhdrsOrErr = Obj->program_headers();
+ if (!PhdrsOrErr)
+ reportError(PhdrsOrErr.takeError(), ObjF->getFileName());
- if (EHFramePhdr)
- printEHFrameHdr(EHFramePhdr->p_offset, EHFramePhdr->p_vaddr,
- EHFramePhdr->p_memsz);
+ for (const Elf_Phdr &Phdr : *PhdrsOrErr) {
+ if (Phdr.p_type != ELF::PT_GNU_EH_FRAME)
+ continue;
- auto Sections = Obj->sections();
- if (Error E = Sections.takeError())
- reportError(std::move(E), ObjF->getFileName());
+ if (Phdr.p_memsz != Phdr.p_filesz)
+ reportError(object::createError(
+ "p_memsz does not match p_filesz for GNU_EH_FRAME"),
+ ObjF->getFileName());
+ printEHFrameHdr(&Phdr);
+ break;
+ }
- for (const auto &Shdr : *Sections) {
- auto SectionName = Obj->getSectionName(&Shdr);
- if (Error E = SectionName.takeError())
- reportError(std::move(E), ObjF->getFileName());
+ Expected<typename ELFT::ShdrRange> SectionsOrErr =
+ ObjF->getELFFile()->sections();
+ if (!SectionsOrErr)
+ reportError(SectionsOrErr.takeError(), ObjF->getFileName());
- if (*SectionName == ".eh_frame")
+ for (const Elf_Shdr &Shdr : *SectionsOrErr) {
+ Expected<StringRef> NameOrErr = Obj->getSectionName(&Shdr);
+ if (!NameOrErr)
+ reportError(NameOrErr.takeError(), ObjF->getFileName());
+ if (*NameOrErr == ".eh_frame")
printEHFrame(&Shdr);
}
}
template <typename ELFT>
-void PrinterContext<ELFT>::printEHFrameHdr(uint64_t EHFrameHdrOffset,
- uint64_t EHFrameHdrAddress,
- uint64_t EHFrameHdrSize) const {
+void PrinterContext<ELFT>::printEHFrameHdr(const Elf_Phdr *EHFramePHdr) const {
DictScope L(W, "EHFrameHeader");
+ uint64_t EHFrameHdrAddress = EHFramePHdr->p_vaddr;
W.startLine() << format("Address: 0x%" PRIx64 "\n", EHFrameHdrAddress);
- W.startLine() << format("Offset: 0x%" PRIx64 "\n", EHFrameHdrOffset);
- W.startLine() << format("Size: 0x%" PRIx64 "\n", EHFrameHdrSize);
+ W.startLine() << format("Offset: 0x%" PRIx64 "\n", (uint64_t)EHFramePHdr->p_offset);
+ W.startLine() << format("Size: 0x%" PRIx64 "\n", (uint64_t)EHFramePHdr->p_memsz);
const object::ELFFile<ELFT> *Obj = ObjF->getELFFile();
- const auto *EHFrameHdrShdr = findSectionByAddress(ObjF, EHFrameHdrAddress);
- if (EHFrameHdrShdr) {
- auto SectionName = Obj->getSectionName(EHFrameHdrShdr);
- if (Error E = SectionName.takeError())
- reportError(std::move(E), ObjF->getFileName());
-
- W.printString("Corresponding Section", *SectionName);
+ if (const Elf_Shdr *EHFrameHdr =
+ findSectionByAddress(ObjF, EHFramePHdr->p_vaddr)) {
+ Expected<StringRef> NameOrErr = Obj->getSectionName(EHFrameHdr);
+ if (!NameOrErr)
+ reportError(NameOrErr.takeError(), ObjF->getFileName());
+ W.printString("Corresponding Section", *NameOrErr);
}
- DataExtractor DE(makeArrayRef(Obj->base() + EHFrameHdrOffset, EHFrameHdrSize),
+ Expected<ArrayRef<uint8_t>> Content = Obj->getSegmentContents(EHFramePHdr);
+ if (!Content)
+ reportError(Content.takeError(), ObjF->getFileName());
+
+ DataExtractor DE(*Content,
ELFT::TargetEndianness == support::endianness::little,
ELFT::Is64Bits ? 8 : 4);
@@ -154,7 +155,7 @@ void PrinterContext<ELFT>::printEHFrameHdr(uint64_t EHFrameHdrOffset,
unsigned NumEntries = 0;
uint64_t PrevPC = 0;
- while (Offset + 8 <= EHFrameHdrSize && NumEntries < FDECount) {
+ while (Offset + 8 <= EHFramePHdr->p_memsz && NumEntries < FDECount) {
DictScope D(W, std::string("entry ") + std::to_string(NumEntries));
auto InitialPC = DE.getSigned(&Offset, 4) + EHFrameHdrAddress;
@@ -172,8 +173,7 @@ void PrinterContext<ELFT>::printEHFrameHdr(uint64_t EHFrameHdrOffset,
}
template <typename ELFT>
-void PrinterContext<ELFT>::printEHFrame(
- const typename ELFT::Shdr *EHFrameShdr) const {
+void PrinterContext<ELFT>::printEHFrame(const Elf_Shdr *EHFrameShdr) const {
uint64_t Address = EHFrameShdr->sh_addr;
uint64_t ShOffset = EHFrameShdr->sh_offset;
W.startLine() << format(".eh_frame section at offset 0x%" PRIx64
@@ -181,26 +181,23 @@ void PrinterContext<ELFT>::printEHFrame(
ShOffset, Address);
W.indent();
- const object::ELFFile<ELFT> *Obj = ObjF->getELFFile();
- auto Result = Obj->getSectionContents(EHFrameShdr);
- if (Error E = Result.takeError())
- reportError(std::move(E), ObjF->getFileName());
+ Expected<ArrayRef<uint8_t>> DataOrErr =
+ ObjF->getELFFile()->getSectionContents(EHFrameShdr);
+ if (!DataOrErr)
+ reportError(DataOrErr.takeError(), ObjF->getFileName());
- auto Contents = Result.get();
- DWARFDataExtractor DE(
- StringRef(reinterpret_cast<const char *>(Contents.data()),
- Contents.size()),
- ELFT::TargetEndianness == support::endianness::little,
- ELFT::Is64Bits ? 8 : 4);
+ DWARFDataExtractor DE(*DataOrErr,
+ ELFT::TargetEndianness == support::endianness::little,
+ ELFT::Is64Bits ? 8 : 4);
DWARFDebugFrame EHFrame(Triple::ArchType(ObjF->getArch()), /*IsEH=*/true,
/*EHFrameAddress=*/Address);
- EHFrame.parse(DE);
+ if (Error E = EHFrame.parse(DE))
+ reportError(std::move(E), ObjF->getFileName());
- for (const auto &Entry : EHFrame) {
- if (const auto *CIE = dyn_cast<dwarf::CIE>(&Entry)) {
+ for (const dwarf::FrameEntry &Entry : EHFrame) {
+ if (const dwarf::CIE *CIE = dyn_cast<dwarf::CIE>(&Entry)) {
W.startLine() << format("[0x%" PRIx64 "] CIE length=%" PRIu64 "\n",
- Address + CIE->getOffset(),
- CIE->getLength());
+ Address + CIE->getOffset(), CIE->getLength());
W.indent();
W.printNumber("version", CIE->getVersion());
@@ -208,47 +205,33 @@ void PrinterContext<ELFT>::printEHFrame(
W.printNumber("code_alignment_factor", CIE->getCodeAlignmentFactor());
W.printNumber("data_alignment_factor", CIE->getDataAlignmentFactor());
W.printNumber("return_address_register", CIE->getReturnAddressRegister());
-
- W.getOStream() << "\n";
- W.startLine() << "Program:\n";
- W.indent();
- CIE->cfis().dump(W.getOStream(), nullptr, W.getIndentLevel());
- W.unindent();
-
- W.unindent();
- W.getOStream() << "\n";
-
- } else if (const auto *FDE = dyn_cast<dwarf::FDE>(&Entry)) {
+ } else {
+ const dwarf::FDE *FDE = cast<dwarf::FDE>(&Entry);
W.startLine() << format("[0x%" PRIx64 "] FDE length=%" PRIu64
" cie=[0x%" PRIx64 "]\n",
- Address + FDE->getOffset(),
- FDE->getLength(),
+ Address + FDE->getOffset(), FDE->getLength(),
Address + FDE->getLinkedCIE()->getOffset());
W.indent();
W.startLine() << format("initial_location: 0x%" PRIx64 "\n",
FDE->getInitialLocation());
- W.startLine()
- << format("address_range: 0x%" PRIx64 " (end : 0x%" PRIx64 ")\n",
- FDE->getAddressRange(),
- FDE->getInitialLocation() + FDE->getAddressRange());
-
- W.getOStream() << "\n";
- W.startLine() << "Program:\n";
- W.indent();
- FDE->cfis().dump(W.getOStream(), nullptr, W.getIndentLevel());
- W.unindent();
-
- W.unindent();
- W.getOStream() << "\n";
- } else {
- llvm_unreachable("unexpected DWARF frame kind");
+ W.startLine() << format(
+ "address_range: 0x%" PRIx64 " (end : 0x%" PRIx64 ")\n",
+ FDE->getAddressRange(),
+ FDE->getInitialLocation() + FDE->getAddressRange());
}
+
+ W.getOStream() << "\n";
+ W.startLine() << "Program:\n";
+ W.indent();
+ Entry.cfis().dump(W.getOStream(), nullptr, W.getIndentLevel());
+ W.unindent();
+ W.unindent();
+ W.getOStream() << "\n";
}
W.unindent();
}
-
}
}