28 using namespace dwarf;
29 using namespace object;
31 #define DEBUG_TYPE "dwarf"
42 OS <<
"\n." << Name <<
" contents:\n";
50 bool SummarizeTypes) {
52 OS <<
".debug_abbrev contents:\n";
53 getDebugAbbrev()->dump(OS);
58 OS <<
"\n.debug_abbrev.dwo contents:\n";
63 OS <<
"\n.debug_info contents:\n";
64 for (
const auto &CU : compile_units())
69 getNumDWOCompileUnits()) {
70 OS <<
"\n.debug_info.dwo contents:\n";
71 for (
const auto &DWOCU : dwo_compile_units())
76 OS <<
"\n.debug_types contents:\n";
77 for (
const auto &TUS : type_unit_sections())
78 for (
const auto &TU : TUS)
79 TU->dump(OS, SummarizeTypes);
83 getNumDWOTypeUnits()) {
84 OS <<
"\n.debug_types.dwo contents:\n";
85 for (
const auto &DWOTUS : dwo_type_unit_sections())
86 for (
const auto &DWOTU : DWOTUS)
87 DWOTU->dump(OS, SummarizeTypes);
91 OS <<
"\n.debug_loc contents:\n";
92 getDebugLoc()->dump(OS);
96 OS <<
"\n.debug_loc.dwo contents:\n";
97 getDebugLocDWO()->dump(OS);
101 OS <<
"\n.debug_frame contents:\n";
102 getDebugFrame()->dump(OS);
104 OS <<
"\n.eh_frame contents:\n";
105 getEHFrame()->dump(OS);
110 OS <<
"\n.debug_macinfo contents:\n";
111 getDebugMacro()->dump(OS);
116 OS <<
"\n.debug_aranges contents:\n";
119 while (set.
extract(arangesData, &offset))
123 uint8_t savedAddressByteSize = 0;
125 OS <<
"\n.debug_line contents:\n";
126 for (
const auto &CU : compile_units()) {
127 savedAddressByteSize = CU->getAddressByteSize();
128 auto CUDIE = CU->getUnitDIE();
131 if (
auto StmtOffset =
132 CUDIE.getAttributeValueAsSectionOffset(DW_AT_stmt_list)) {
134 savedAddressByteSize);
137 LineTable.
parse(lineData, &getLineSection().Relocs, &Offset);
144 OS <<
"\n.debug_cu_index contents:\n";
145 getCUIndex().dump(OS);
149 OS <<
"\n.debug_tu_index contents:\n";
150 getTUIndex().dump(OS);
154 OS <<
"\n.debug_line.dwo contents:\n";
155 unsigned stmtOffset = 0;
157 savedAddressByteSize);
166 OS <<
"\n.debug_str contents:\n";
170 while (
const char *s = strData.
getCStr(&offset)) {
171 OS <<
format(
"0x%8.8x: \"%s\"\n", strOffset, s);
177 !getStringDWOSection().empty()) {
178 OS <<
"\n.debug_str.dwo contents:\n";
182 while (
const char *s = strDWOData.
getCStr(&offset)) {
183 OS <<
format(
"0x%8.8x: \"%s\"\n", strDWOOffset, s);
184 strDWOOffset = offset;
189 OS <<
"\n.debug_ranges contents:\n";
195 savedAddressByteSize);
198 while (rangeList.
extract(rangesData, &offset))
204 .
dump(
"debug_pubnames", OS);
208 .
dump(
"debug_pubtypes", OS);
213 .
dump(
"debug_gnu_pubnames", OS);
218 .
dump(
"debug_gnu_pubtypes", OS);
221 !getStringOffsetDWOSection().empty()) {
222 OS <<
"\n.debug_str_offsets.dwo contents:\n";
226 uint64_t size = getStringOffsetDWOSection().size();
227 while (offset < size) {
228 OS <<
format(
"0x%8.8x: ", offset);
234 !getGdbIndexSection().empty()) {
235 OS <<
"\n.gnu_index contents:\n";
236 getGdbIndex().dump(OS);
262 CUIndex = llvm::make_unique<DWARFUnitIndex>(
DW_SECT_INFO);
263 CUIndex->parse(CUIndexData);
274 TUIndex->parse(TUIndexData);
283 GdbIndex = llvm::make_unique<DWARFGdbIndex>();
284 GdbIndex->parse(GdbIndexData);
295 Abbrev->extract(abbrData);
301 return AbbrevDWO.get();
305 AbbrevDWO->extract(abbrData);
306 return AbbrevDWO.get();
316 if (getNumCompileUnits())
317 Loc->parse(LocData, getCompileUnitAtIndex(0)->getAddressByteSize());
327 LocDWO->parse(LocData);
333 return Aranges.get();
337 return Aranges.get();
342 return DebugFrame.get();
356 DebugFrame->parse(debugFrameData);
357 return DebugFrame.get();
362 return EHFrame.get();
367 DebugFrame->parse(debugFrameData);
368 return DebugFrame.get();
377 Macro->parse(MacinfoData);
390 auto Offset = UnitDIE.getAttributeValueAsSectionOffset(DW_AT_stmt_list);
402 return Line->getOrParseLineTable(lineData, stmtOffset);
405 void DWARFContext::parseCompileUnits() {
406 CUs.parse(*
this, getInfoSection());
409 void DWARFContext::parseTypeUnits() {
412 for (
const auto &
I : getTypesSections()) {
414 TUs.back().parse(*
this,
I.second);
418 void DWARFContext::parseDWOCompileUnits() {
419 DWOCUs.parseDWO(*
this, getInfoDWOSection());
422 void DWARFContext::parseDWOTypeUnits() {
425 for (
const auto &
I : getTypesDWOSections()) {
426 DWOTUs.emplace_back();
427 DWOTUs.back().parseDWO(*
this,
I.second);
433 return CUs.getUnitForOffset(Offset);
438 uint32_t CUOffset = getDebugAranges()->findAddress(Address);
440 return getCompileUnitForOffset(CUOffset);
445 std::string &FunctionName) {
453 if (InlinedChain.
size() == 0)
455 if (
const char *
Name = InlinedChain[0].getSubroutineName(Kind)) {
486 std::string FunctionName =
"<invalid>";
494 Lines.
push_back(std::make_pair(Address, Result));
501 std::vector<uint32_t> RowVector;
505 for (
uint32_t RowIndex : RowVector) {
532 if (InlinedChain.
size() == 0) {
537 LineTable = getLineTableForUnit(CU);
546 uint32_t CallFile = 0, CallLine = 0, CallColumn = 0;
557 LineTable = getLineTableForUnit(CU);
568 Frame.
Line = CallLine;
569 Frame.
Column = CallColumn;
584 AddressSize(Obj.getBytesInAddress()) {
592 bool IsVirtual =
Section.isVirtual();
610 if (
auto Err = Decompressor->decompress(Out))
612 UncompressedSections.emplace_back(std::move(Out));
613 data = UncompressedSections.back();
623 .Case(
"debug_info", &InfoSection.
Data)
624 .
Case(
"debug_abbrev", &AbbrevSection)
625 .
Case(
"debug_loc", &LocSection.
Data)
626 .
Case(
"debug_line", &LineSection.
Data)
627 .
Case(
"debug_aranges", &ARangeSection)
628 .
Case(
"debug_frame", &DebugFrameSection)
629 .
Case(
"eh_frame", &EHFrameSection)
630 .
Case(
"debug_str", &StringSection)
631 .
Case(
"debug_ranges", &RangeSection)
632 .
Case(
"debug_macinfo", &MacinfoSection)
633 .
Case(
"debug_pubnames", &PubNamesSection)
634 .
Case(
"debug_pubtypes", &PubTypesSection)
635 .
Case(
"debug_gnu_pubnames", &GnuPubNamesSection)
636 .
Case(
"debug_gnu_pubtypes", &GnuPubTypesSection)
637 .
Case(
"debug_info.dwo", &InfoDWOSection.
Data)
638 .
Case(
"debug_abbrev.dwo", &AbbrevDWOSection)
639 .
Case(
"debug_loc.dwo", &LocDWOSection.
Data)
640 .
Case(
"debug_line.dwo", &LineDWOSection.
Data)
641 .
Case(
"debug_str.dwo", &StringDWOSection)
642 .
Case(
"debug_str_offsets.dwo", &StringOffsetDWOSection)
643 .
Case(
"debug_addr", &AddrSection)
644 .
Case(
"apple_names", &AppleNamesSection.
Data)
645 .
Case(
"apple_types", &AppleTypesSection.
Data)
646 .
Case(
"apple_namespaces", &AppleNamespacesSection.
Data)
647 .
Case(
"apple_namespac", &AppleNamespacesSection.
Data)
648 .
Case(
"apple_objc", &AppleObjCSection.
Data)
649 .
Case(
"debug_cu_index", &CUIndexSection)
650 .
Case(
"debug_tu_index", &TUIndexSection)
651 .
Case(
"gdb_index", &GdbIndexSection)
656 if (name ==
"debug_ranges") {
658 RangeDWOSection = data;
660 }
else if (name ==
"debug_types") {
663 TypesSections[
Section].Data = data;
664 }
else if (name ==
"debug_types.dwo") {
665 TypesDWOSections[
Section].Data = data;
673 RelocatedSection->getName(RelSecName);
686 if (!L && isa<MachOObjectFile>(&Obj))
689 RelSecName = RelSecName.
substr(
695 .Case(
"debug_info", &InfoSection.
Relocs)
697 .
Case(
"debug_info.dwo", &InfoDWOSection.
Relocs)
699 .
Case(
"apple_names", &AppleNamesSection.
Relocs)
700 .
Case(
"apple_types", &AppleTypesSection.
Relocs)
701 .
Case(
"apple_namespaces", &AppleNamespacesSection.
Relocs)
702 .
Case(
"apple_namespac", &AppleNamespacesSection.
Relocs)
708 if (RelSecName ==
"debug_types")
709 Map = &TypesSections[*RelocatedSection].Relocs;
710 else if (RelSecName ==
"debug_types.dwo")
711 Map = &TypesDWOSections[*RelocatedSection].Relocs;
717 uint64_t
SectionSize = RelocatedSection->getSize();
719 uint64_t Address = Reloc.getOffset();
720 uint64_t
Type = Reloc.getType();
721 uint64_t SymAddr = 0;
722 uint64_t SectionLoadAddress = 0;
735 errs() <<
"error: failed to compute symbol address: "
739 SymAddr = *SymAddrOrErr;
747 errs() <<
"error: failed to get symbol section: "
752 }
else if (
auto *MObj = dyn_cast<MachOObjectFile>(&Obj)) {
755 auto RelocInfo = MObj->getRelocation(Reloc.getRawDataRefImpl());
756 if (MObj->isRelocationScattered(RelocInfo)) {
761 RSec = MObj->getRelocationSection(Reloc.getRawDataRefImpl());
762 SymAddr = RSec->getAddress();
775 RSec->getName(SecName);
780 if (SectionLoadAddress != 0)
781 SymAddr += SectionLoadAddress - RSec->getAddress();
788 Reloc.getTypeName(Name);
789 errs() <<
"error: failed to compute relocation: "
794 if (Address + R.Width > SectionSize) {
795 errs() <<
"error: " << R.Width <<
"-byte relocation starting "
796 << Address <<
" bytes into section " << name <<
" which is "
797 << SectionSize <<
" bytes long.\n";
801 errs() <<
"error: can't handle a relocation of more than 8 bytes at "
806 <<
" at " <<
format(
"%p", Address)
807 <<
" with width " <<
format(
"%d", R.Width)
809 Map->
insert(std::make_pair(Address, std::make_pair(R.Width, R.Value)));
815 void DWARFContextInMemory::anchor() { }
const DWARFUnitIndex & getTUIndex()
RelocToApply visit(uint32_t RelocType, RelocationRef R, uint64_t Value=0)
const DWARFDebugFrame * getEHFrame()
Get a pointer to the parsed eh frame information object.
void push_back(const T &Elt)
const DWARFDebugFrame * getDebugFrame()
Get a pointer to the parsed frame information object.
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
virtual bool getLoadedSectionContents(const object::SectionRef &Sec, StringRef &Data) const
If conveniently available, return the content of the given Section.
static bool isCompressed(const object::SectionRef &Section)
Return true if section is compressed, including gnu-styled case.
A parsed .debug_frame or .eh_frame section.
const DWARFDebugLocDWO * getDebugLocDWO()
Get a pointer to the parsed DebugLoc object.
Represents structure for holding and parsing .debug_pub* tables.
const DWARFDebugLoc * getDebugLoc()
Get a pointer to the parsed DebugLoc object.
void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner)
Log all errors (if any) in E to OS.
DWARFGdbIndex & getGdbIndex()
void getCallerFrame(uint32_t &CallFile, uint32_t &CallLine, uint32_t &CallColumn) const
Retrieves values of DW_AT_call_file, DW_AT_call_line and DW_AT_call_column from DIE (or zeroes if the...
static bool getFunctionNameForAddress(DWARFCompileUnit *CU, uint64_t Address, FunctionNameKind Kind, std::string &FunctionName)
bool getFileNameByIndex(uint64_t FileIndex, const char *CompDir, DILineInfoSpecifier::FileLineInfoKind Kind, std::string &Result) const
This class is the base class for all object file types.
void addFrame(const DILineInfo &Frame)
const DWARFDebugAbbrev * getDebugAbbrevDWO()
Get a pointer to the parsed dwo abbreviations object.
DINameKind
A DINameKind is passed to name search methods to specify a preference regarding the type of name reso...
Error takeError()
Take ownership of the stored error.
void generate(DWARFContext *CTX)
static void dumpAccelSection(raw_ostream &OS, StringRef Name, const DWARFSection &Section, StringRef StringSection, bool LittleEndian)
const char * getSubroutineName(DINameKind Kind) const
If a DIE represents a subprogram (or inlined subroutine), returns its mangled name (or short name...
DILineInfo - a format-neutral container for source line information.
void dump(raw_ostream &OS, DIDumpType DumpType=DIDT_All, bool DumpEH=false, bool SummarizeTypes=false) override
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Decompressor helps to handle decompression of compressed sections.
void dump(StringRef Name, raw_ostream &OS) const
static GCRegistry::Add< StatepointGC > D("statepoint-example","an example strategy for statepoint")
This is a value type class that represents a single relocation in the list of relocations in the obje...
LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(const T &Value) const
Tagged union holding either a T or a Error.
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(const char(&S)[N], const T &Value)
const DWARFDebugAranges * getDebugAranges()
Get a pointer to the parsed DebugAranges object.
const DWARFDebugAbbrev * getDebugAbbrev()
Get a pointer to the parsed DebugAbbrev object.
bool extract(DataExtractor data, uint32_t *offset_ptr)
format_object< Ts...> format(const char *Fmt, const Ts &...Vals)
These are helper functions used to produce formatted output.
A switch()-like statement whose cases are string literals.
Utility class that carries the DWARF compile/type unit and the debug info entry in an object...
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
void dump(raw_ostream &OS) const
The instances of the Type class are immutable: once they are created, they are never changed...
DILineInfoSpecifier - controls which fields of DILineInfo container should be filled with data...
const DWARFDebugMacro * getDebugMacro()
Get a pointer to the parsed DebugMacro object.
DIInliningInfo - a format-neutral container for inlined code description.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
DIDumpType
Selects which debug sections get dumped.
DILineInfo getLineInfoForAddress(uint64_t Address, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override
StringRef getLineSection() const
bool parse(DataExtractor debug_line_data, uint32_t *offset_ptr)
void dump(raw_ostream &OS) const
virtual basic_symbol_iterator symbol_end() const =0
bool parse(DataExtractor debug_line_data, const RelocAddrMap *RMap, uint32_t *offset_ptr)
Parse prologue and all rows.
const char * getCompilationDir()
section_iterator_range sections() const
bool lookupAddressRange(uint64_t address, uint64_t size, std::vector< uint32_t > &result) const
LLVM_NODISCARD size_t find_first_not_of(char C, size_t From=0) const
Find the first character in the string that is not C or npos if not found.
void dump(raw_ostream &OS) const
Expected< uint64_t > getAddress() const
Returns the symbol virtual address (i.e.
DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind
DWARFDie getUnitDIE(bool ExtractUnitDIEOnly=true)
virtual uint64_t getSectionLoadAddress(const object::SectionRef &Sec) const =0
Obtain the Load Address of a section by SectionRef.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
DIInliningInfo getInliningInfoForAddress(uint64_t Address, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override
bool extract(DataExtractor data, uint32_t *offset_ptr)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
An inferface for inquiring the load address of a loaded object file to be used by the DIContext imple...
DWARFDebugLine::LineTable DWARFLineTable
Expected< section_iterator > getSection() const
Get section this symbol is defined in reference to.
DILineInfoTable getLineInfoForAddressRange(uint64_t Address, uint64_t Size, DILineInfoSpecifier Specifier=DILineInfoSpecifier()) override
DILineInfoSpecifier::FunctionNameKind FunctionNameKind
virtual section_iterator section_end() const =0
void getInlinedChainForAddress(uint64_t Address, SmallVectorImpl< DWARFDie > &InlinedChain)
getInlinedChainForAddress - fetches inlined chain for a given address.
void dump(raw_ostream &OS) const
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
DWARFContextInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L=nullptr)
bool getFileLineInfoForAddress(uint64_t Address, const char *CompDir, DILineInfoSpecifier::FileLineInfoKind Kind, DILineInfo &Result) const
const DWARFUnitIndex & getCUIndex()
uint8_t getAddressByteSize() const
uint32_t getLineTableOffset() const
A raw_ostream that writes to an std::string.
const DWARFDebugLine::LineTable * getLineTableForUnit(DWARFUnit *cu)
Get a pointer to a parsed line table corresponding to a compile unit.
This class implements an extremely fast bulk output stream that can only output to a stream...
StringRef - Represent a constant reference to a string, i.e.
This is a value type class that represents a single section in the list of sections in the object fil...
Base class for object file relocation visitors.
static Expected< Decompressor > create(StringRef Name, StringRef Data, bool IsLE, bool Is64Bit)
Create decompressor object.