21 using namespace dwarf;
22 using namespace object;
33 bool LittleEndian,
bool GnuStyle) {
34 OS <<
"\n." << Name <<
" contents:\n";
37 OS <<
"length = " <<
format(
"0x%08x", pubNames.
getU32(&offset));
38 OS <<
" version = " <<
format(
"0x%04x", pubNames.
getU16(&offset));
39 OS <<
" unit_offset = " <<
format(
"0x%08x", pubNames.
getU32(&offset));
40 OS <<
" unit_size = " <<
format(
"0x%08x", pubNames.
getU32(&offset)) <<
'\n';
42 OS <<
"Offset Linkage Kind Name\n";
44 OS <<
"Offset Name\n";
46 while (offset < Data.
size()) {
47 uint32_t dieRef = pubNames.
getU32(&offset);
50 OS <<
format(
"0x%8.8x ", dieRef);
57 OS <<
'\"' << pubNames.
getCStr(&offset) <<
"\"\n";
63 OS <<
".debug_abbrev contents:\n";
64 getDebugAbbrev()->dump(OS);
68 OS <<
"\n.debug_info contents:\n";
69 for (
unsigned i = 0, e = getNumCompileUnits(); i != e; ++i)
70 getCompileUnitAtIndex(i)->dump(OS);
74 OS <<
"\n.debug_types contents:\n";
75 for (
unsigned i = 0, e = getNumTypeUnits(); i != e; ++i)
76 getTypeUnitAtIndex(i)->dump(OS);
80 OS <<
"\n.debug_loc contents:\n";
81 getDebugLoc()->dump(OS);
85 OS <<
"\n.debug_frame contents:\n";
86 getDebugFrame()->dump(OS);
91 OS <<
"\n.debug_aranges contents:\n";
92 DataExtractor arangesData(getARangeSection(), isLittleEndian(), 0);
94 while (set.
extract(arangesData, &offset))
98 uint8_t savedAddressByteSize = 0;
100 OS <<
"\n.debug_line contents:\n";
101 for (
unsigned i = 0, e = getNumCompileUnits(); i != e; ++i) {
104 unsigned stmtOffset =
106 cu, DW_AT_stmt_list, -1U);
107 if (stmtOffset != -1U) {
108 DataExtractor lineData(getLineSection().Data, isLittleEndian(),
109 savedAddressByteSize);
117 OS <<
"\n.debug_str contents:\n";
118 DataExtractor strData(getStringSection(), isLittleEndian(), 0);
120 uint32_t strOffset = 0;
121 while (
const char *s = strData.
getCStr(&offset)) {
122 OS <<
format(
"0x%8.8x: \"%s\"\n", strOffset, s);
128 OS <<
"\n.debug_ranges contents:\n";
133 DataExtractor rangesData(getRangeSection(), isLittleEndian(),
134 savedAddressByteSize);
137 while (rangeList.
extract(rangesData, &offset))
143 isLittleEndian(),
false);
147 isLittleEndian(),
false);
151 isLittleEndian(),
true );
155 isLittleEndian(),
true );
160 OS <<
"\n.debug_abbrev.dwo contents:\n";
161 getDebugAbbrevDWO()->dump(OS);
166 if (getNumDWOCompileUnits()) {
167 OS <<
"\n.debug_info.dwo contents:\n";
168 for (
unsigned i = 0, e = getNumDWOCompileUnits(); i != e; ++i)
169 getDWOCompileUnitAtIndex(i)->dump(OS);
173 if (!getStringDWOSection().empty()) {
174 OS <<
"\n.debug_str.dwo contents:\n";
175 DataExtractor strDWOData(getStringDWOSection(), isLittleEndian(), 0);
177 uint32_t strDWOOffset = 0;
178 while (
const char *s = strDWOData.
getCStr(&offset)) {
179 OS <<
format(
"0x%8.8x: \"%s\"\n", strDWOOffset, s);
180 strDWOOffset = offset;
185 if (!getStringOffsetDWOSection().empty()) {
186 OS <<
"\n.debug_str_offsets.dwo contents:\n";
187 DataExtractor strOffsetExt(getStringOffsetDWOSection(), isLittleEndian(), 0);
189 uint64_t size = getStringOffsetDWOSection().size();
190 while (offset < size) {
191 OS <<
format(
"0x%8.8x: ", offset);
201 DataExtractor abbrData(getAbbrevSection(), isLittleEndian(), 0);
204 Abbrev->parse(abbrData);
210 return AbbrevDWO.get();
212 DataExtractor abbrData(getAbbrevDWOSection(), isLittleEndian(), 0);
214 AbbrevDWO->parse(abbrData);
215 return AbbrevDWO.get();
222 DataExtractor LocData(getLocSection().Data, isLittleEndian(), 0);
225 if (getNumCompileUnits())
226 Loc->parse(LocData, getCompileUnitAtIndex(0)->getAddressByteSize());
232 return Aranges.get();
236 return Aranges.get();
241 return DebugFrame.get();
252 DataExtractor debugFrameData(getDebugFrameSection(), isLittleEndian(),
255 DebugFrame->parse(debugFrameData);
256 return DebugFrame.get();
264 unsigned stmtOffset =
266 cu, DW_AT_stmt_list, -1U);
267 if (stmtOffset == -1U)
275 DataExtractor lineData(getLineSection().Data, isLittleEndian(),
277 return Line->getOrParseLineTable(lineData, stmtOffset);
280 void DWARFContext::parseCompileUnits() {
283 isLittleEndian(), 0);
286 getDebugAbbrev(), getInfoSection().Data, getAbbrevSection(),
287 getRangeSection(), getStringSection(),
StringRef(), getAddrSection(),
288 &getInfoSection().Relocs, isLittleEndian()));
289 if (!CU->extract(DIData, &offset)) {
292 CUs.push_back(CU.take());
293 offset = CUs.back()->getNextUnitOffset();
297 void DWARFContext::parseTypeUnits() {
298 const std::map<object::SectionRef, Section> &Sections = getTypesSections();
299 for (std::map<object::SectionRef, Section>::const_iterator
300 I = Sections.begin(),
308 getDebugAbbrev(),
I->second.Data, getAbbrevSection(),
309 getRangeSection(), getStringSection(),
StringRef(), getAddrSection(),
310 &
I->second.Relocs, isLittleEndian()));
311 if (!TU->extract(DIData, &offset))
313 TUs.push_back(TU.take());
314 offset = TUs.back()->getNextUnitOffset();
319 void DWARFContext::parseDWOCompileUnits() {
322 DataExtractor(getInfoDWOSection().Data, isLittleEndian(), 0);
325 getDebugAbbrevDWO(), getInfoDWOSection().Data, getAbbrevDWOSection(),
326 getRangeDWOSection(), getStringDWOSection(),
327 getStringOffsetDWOSection(), getAddrSection(),
328 &getInfoDWOSection().Relocs, isLittleEndian()));
329 if (!DWOCU->extract(DIData, &offset)) {
332 DWOCUs.push_back(DWOCU.take());
333 offset = DWOCUs.back()->getNextUnitOffset();
338 struct OffsetComparator {
357 std::lower_bound(CUs.begin(), CUs.end(), Offset, OffsetComparator());
358 if (CU != CUs.end()) {
364 DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
366 uint32_t CUOffset = getDebugAranges()->findAddress(Address);
368 return getCompileUnitForOffset(CUOffset);
374 bool NeedsAbsoluteFilePath,
375 std::string &FileName) {
388 FileName = AbsolutePath.
str();
396 bool NeedsAbsoluteFilePath,
397 std::string &FileName,
398 uint32_t &Line, uint32_t &Column) {
399 if (CU == 0 || LineTable == 0)
408 NeedsAbsoluteFilePath, FileName))
420 std::string FileName =
"<invalid>";
421 std::string FunctionName =
"<invalid>";
430 if (InlinedChain.
DIEs.size() > 0) {
438 const bool NeedsAbsoluteFilePath =
441 NeedsAbsoluteFilePath,
442 FileName, Line, Column);
456 std::string FunctionName =
"<invalid>";
463 if (InlinedChain.
DIEs.size() > 0) {
474 std::make_pair(Address,
DILineInfo(
"<invalid>", FunctionName, 0, 0)));
479 const bool NeedsAbsoluteFilePath =
483 std::vector<uint32_t> RowVector;
487 uint32_t NumRows = RowVector.
size();
488 for (uint32_t i = 0; i < NumRows; ++i) {
489 uint32_t RowIndex = RowVector[i];
492 std::string FileName =
"<invalid>";
494 NeedsAbsoluteFilePath, FileName);
510 if (InlinedChain.
DIEs.size() == 0)
514 uint32_t CallFile = 0, CallLine = 0, CallColumn = 0;
516 for (uint32_t i = 0, n = InlinedChain.
DIEs.size(); i != n; i++) {
518 std::string FileName =
"<invalid>";
519 std::string FunctionName =
"<invalid>";
528 const bool NeedsAbsoluteFilePath =
533 LineTable = getLineTableForCompileUnit(CU);
536 NeedsAbsoluteFilePath,
537 FileName, Line, Column);
542 NeedsAbsoluteFilePath, FileName);
560 uint64_t &OriginalSize) {
568 OriginalSize = extractor.
getU64(&Offset);
571 data = data.
substr(Offset);
576 IsLittleEndian(Obj->isLittleEndian()),
577 AddressSize(Obj->getBytesInAddress()) {
585 i->getContents(data);
591 uint64_t OriginalSize;
602 UncompressedSections.push_back(UncompressedSection.
take());
607 .Case(
"debug_info", &InfoSection.
Data)
608 .
Case(
"debug_abbrev", &AbbrevSection)
609 .
Case(
"debug_loc", &LocSection.
Data)
610 .
Case(
"debug_line", &LineSection.
Data)
611 .
Case(
"debug_aranges", &ARangeSection)
612 .
Case(
"debug_frame", &DebugFrameSection)
613 .
Case(
"debug_str", &StringSection)
614 .
Case(
"debug_ranges", &RangeSection)
615 .
Case(
"debug_pubnames", &PubNamesSection)
616 .
Case(
"debug_pubtypes", &PubTypesSection)
617 .
Case(
"debug_gnu_pubnames", &GnuPubNamesSection)
618 .
Case(
"debug_gnu_pubtypes", &GnuPubTypesSection)
619 .
Case(
"debug_info.dwo", &InfoDWOSection.
Data)
620 .
Case(
"debug_abbrev.dwo", &AbbrevDWOSection)
621 .
Case(
"debug_str.dwo", &StringDWOSection)
622 .
Case(
"debug_str_offsets.dwo", &StringOffsetDWOSection)
623 .
Case(
"debug_addr", &AddrSection)
628 if (name ==
"debug_ranges") {
630 RangeDWOSection = data;
632 }
else if (name ==
"debug_types") {
635 TypesSections[*i].Data = data;
643 RelocatedSection->getName(RelSecName);
644 RelSecName = RelSecName.
substr(
650 .Case(
"debug_info", &InfoSection.
Relocs)
652 .
Case(
"debug_info.dwo", &InfoDWOSection.
Relocs)
656 if (RelSecName !=
"debug_types")
660 Map = &TypesSections[*RelocatedSection].Relocs;
663 if (i->begin_relocations() != i->end_relocations()) {
665 RelocatedSection->getSize(SectionSize);
667 reloc_e = i->end_relocations();
668 reloc_i != reloc_e; reloc_i.
increment(ec)) {
670 reloc_i->getOffset(Address);
672 reloc_i->getType(Type);
673 uint64_t SymAddr = 0;
677 Sym->getAddress(SymAddr);
687 errs() <<
"Aaaaaa! Nameless relocation! Aaaaaa!\n";
689 errs() <<
"error: failed to compute relocation: "
694 if (Address + R.Width > SectionSize) {
695 errs() <<
"error: " << R.Width <<
"-byte relocation starting "
696 << Address <<
" bytes into section " << name <<
" which is "
697 << SectionSize <<
" bytes long.\n";
701 errs() <<
"error: can't handle a relocation of more than 8 bytes at "
706 <<
" at " <<
format(
"%p", Address)
707 <<
" with width " <<
format(
"%d", R.Width)
709 Map->
insert(std::make_pair(Address, std::make_pair(R.Width, R.Value)));
719 void DWARFContextInMemory::anchor() { }
void DeleteContainerPointers(Container &C)
COFF::RelocationTypeX86 Type
void push_back(const T &Elt)
const DWARFDebugFrame * getDebugFrame()
Get a pointer to the parsed frame information object.
A parsed .debug_frame section.
size_t size() const
size - Get the string size.
const DWARFDebugLoc * getDebugLoc()
Get a pointer to the parsed DebugLoc object.
bool is_relative(const Twine &path)
Is path relative?
const DWARFDebugInfoEntryMinimal * getCompileUnitDIE(bool extract_cu_die_only=true)
StringRef substr(size_t Start, size_t N=npos) const
StringRef getBuffer() const
void addFrame(const DILineInfo &Frame)
const DWARFDebugAbbrev * getDebugAbbrevDWO()
Get a pointer to the parsed dwo abbreviations object.
void generate(DWARFContext *CTX)
StringSwitch & Case(const char(&S)[N], const T &Value)
virtual DILineInfoTable getLineInfoForAddressRange(uint64_t Address, uint64_t Size, DILineInfoSpecifier Specifier=DILineInfoSpecifier())
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
const char * getCompilationDir()
virtual section_iterator end_sections() const =0
const char * getSubroutineName(const DWARFUnit *U) const
bool getFileNameByIndex(uint64_t FileIndex, bool NeedsAbsoluteFilePath, std::string &Result) const
format_object1< T > format(const char *Fmt, const T &Val)
const DWARFDebugAranges * getDebugAranges()
Get a pointer to the parsed DebugAranges object.
DWARFDebugInfoEntryInlinedChain getInlinedChainForAddress(uint64_t Address)
const DWARFDebugAbbrev * getDebugAbbrev()
Get a pointer to the parsed DebugAbbrev object.
bool extract(DataExtractor data, uint32_t *offset_ptr)
SmallVector< DWARFDebugInfoEntryMinimal, 4 > DIEs
const char * GDBIndexEntryLinkageString(GDBIndexEntryLinkage Linkage)
virtual section_iterator begin_sections() const =0
A switch()-like statement whose cases are string literals.
void dump(raw_ostream &OS) const
DWARFDebugInfoEntryMinimal - A DIE with only the minimum required data.
virtual void dump(raw_ostream &OS, DIDumpType DumpType=DIDT_All)
DIInliningInfo - a format-neutral container for inlined code description.
DIDumpType
Selects which debug sections get dumped.
static void dumpPubSection(raw_ostream &OS, StringRef Name, StringRef Data, bool LittleEndian, bool GnuStyle)
bool lookupAddressRange(uint64_t address, uint64_t size, std::vector< uint32_t > &result) const
size_t find_first_not_of(char C, size_t From=0) const
void dump(raw_ostream &OS) const
DILineInfo - a format-neutral container for source line information.
static bool getFileNameForCompileUnit(DWARFCompileUnit *CU, const DWARFLineTable *LineTable, uint64_t FileIndex, bool NeedsAbsoluteFilePath, std::string &FileName)
static bool getFileLineInfoForCompileUnit(DWARFCompileUnit *CU, const DWARFLineTable *LineTable, uint64_t Address, bool NeedsAbsoluteFilePath, std::string &FileName, uint32_t &Line, uint32_t &Column)
DWARFContextInMemory(object::ObjectFile *)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
uint32_t lookupAddress(uint64_t address) const
content_iterator & increment(error_code &err)
bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
static bool consumeCompressedDebugSectionHeader(StringRef &data, uint64_t &OriginalSize)
bool extract(DataExtractor data, uint32_t *offset_ptr)
uint64_t getAttributeValueAsSectionOffset(const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const
R Default(const T &Value) const
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
StringRef str() const
Explicit conversion to StringRef.
void getCallerFrame(const DWARFUnit *U, uint32_t &CallFile, uint32_t &CallLine, uint32_t &CallColumn) const
const DWARFDebugLine::LineTable * getLineTableForCompileUnit(DWARFCompileUnit *cu)
Get a pointer to a parsed line table corresponding to a compile unit.
DWARFDebugLine::LineTable DWARFLineTable
const char * GDBIndexEntryKindString(GDBIndexEntryKind Kind)
bool needs(Specification spec) const
uint32_t getOffset() const
uint8_t getAddressByteSize() const
virtual DIInliningInfo getInliningInfoForAddress(uint64_t Address, DILineInfoSpecifier Specifier=DILineInfoSpecifier())
Status uncompress(StringRef InputBuffer, OwningPtr< MemoryBuffer > &UncompressedBuffer, size_t UncompressedSize)
virtual StringRef getFileFormatName() const =0
static bool parseStatementTable(DataExtractor debug_line_data, const RelocAddrMap *RMap, uint32_t *offset_ptr, State &state)
Parse a single line table (prologue and all rows).
Base class for object file relocation visitors.
virtual DILineInfo getLineInfoForAddress(uint64_t Address, DILineInfoSpecifier Specifier=DILineInfoSpecifier())