diff options
Diffstat (limited to 'lib/DebugInfo/DWARFDebugInfoEntry.cpp')
-rw-r--r-- | lib/DebugInfo/DWARFDebugInfoEntry.cpp | 115 |
1 files changed, 103 insertions, 12 deletions
diff --git a/lib/DebugInfo/DWARFDebugInfoEntry.cpp b/lib/DebugInfo/DWARFDebugInfoEntry.cpp index 2e7a54a..583e700 100644 --- a/lib/DebugInfo/DWARFDebugInfoEntry.cpp +++ b/lib/DebugInfo/DWARFDebugInfoEntry.cpp @@ -12,15 +12,26 @@ #include "DWARFContext.h" #include "DWARFDebugAbbrev.h" #include "llvm/DebugInfo/DWARFFormValue.h" +#include "llvm/Support/DataTypes.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; using namespace dwarf; -typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind; -void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, const DWARFUnit *u, +// Small helper to extract a DIE pointed by a reference +// attribute. It looks up the Unit containing the DIE and calls +// DIE.extractFast with the right unit. Returns new unit on success, +// nullptr otherwise. +static const DWARFUnit *findUnitAndExtractFast(DWARFDebugInfoEntryMinimal &DIE, + const DWARFUnit *Unit, + uint32_t *Offset) { + Unit = Unit->getUnitSection().getUnitForOffset(*Offset); + return (Unit && DIE.extractFast(Unit, Offset)) ? Unit : nullptr; +} + +void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, DWARFUnit *u, unsigned recurseDepth, unsigned indent) const { DataExtractor debug_info_data = u->getDebugInfoExtractor(); @@ -62,12 +73,42 @@ void DWARFDebugInfoEntryMinimal::dump(raw_ostream &OS, const DWARFUnit *u, } } +static void dumpApplePropertyAttribute(raw_ostream &OS, uint64_t Val) { + OS << " ("; + do { + uint64_t Bit = 1ULL << countTrailingZeros(Val); + if (const char *PropName = ApplePropertyString(Bit)) + OS << PropName; + else + OS << format("DW_APPLE_PROPERTY_0x%" PRIx64, Bit); + if (!(Val ^= Bit)) + break; + OS << ", "; + } while (true); + OS << ")"; +} + +static void dumpRanges(raw_ostream &OS, const DWARFAddressRangesVector& Ranges, + unsigned AddressSize, unsigned Indent) { + if (Ranges.empty()) + return; + + for (const auto &Range: Ranges) { + OS << '\n'; + OS.indent(Indent); + OS << format("[0x%0*" PRIx64 " - 0x%0*" PRIx64 ")", + AddressSize*2, Range.first, + AddressSize*2, Range.second); + } +} + void DWARFDebugInfoEntryMinimal::dumpAttribute(raw_ostream &OS, - const DWARFUnit *u, + DWARFUnit *u, uint32_t *offset_ptr, uint16_t attr, uint16_t form, unsigned indent) const { - OS << " "; + const char BaseIndent[] = " "; + OS << BaseIndent; OS.indent(indent+2); const char *attrString = AttributeString(attr); if (attrString) @@ -86,7 +127,48 @@ void DWARFDebugInfoEntryMinimal::dumpAttribute(raw_ostream &OS, return; OS << "\t("; - formValue.dump(OS, u); + + const char *Name = nullptr; + std::string File; + if (attr == DW_AT_decl_file || attr == DW_AT_call_file) { + if (const auto *LT = u->getContext().getLineTableForUnit(u)) + if (LT->getFileNameByIndex( + formValue.getAsUnsignedConstant().getValue(), + u->getCompilationDir(), + DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, File)) { + File = '"' + File + '"'; + Name = File.c_str(); + } + } else if (Optional<uint64_t> Val = formValue.getAsUnsignedConstant()) + Name = AttributeValueString(attr, *Val); + + if (Name) { + OS << Name; + } else if (attr == DW_AT_decl_line || attr == DW_AT_call_line) { + OS << *formValue.getAsUnsignedConstant(); + } else { + formValue.dump(OS, u); + } + + // We have dumped the attribute raw value. For some attributes + // having both the raw value and the pretty-printed value is + // interesting. These attributes are handled below. + if ((attr == DW_AT_specification || attr == DW_AT_abstract_origin) && + // The signature references aren't handled. + formValue.getForm() != DW_FORM_ref_sig8) { + uint32_t Ref = formValue.getAsReference(u).getValue(); + DWARFDebugInfoEntryMinimal DIE; + if (const DWARFUnit *RefU = findUnitAndExtractFast(DIE, u, &Ref)) + if (const char *Ref = DIE.getName(RefU, DINameKind::LinkageName)) + OS << " \"" << Ref << '\"'; + } else if (attr == DW_AT_APPLE_property_attribute) { + if (Optional<uint64_t> OptVal = formValue.getAsUnsignedConstant()) + dumpApplePropertyAttribute(OS, *OptVal); + } else if (attr == DW_AT_ranges) { + dumpRanges(OS, getAddressRanges(u), u->getAddressByteSize(), + sizeof(BaseIndent)+indent+4); + } + OS << ")\n"; } @@ -284,11 +366,19 @@ bool DWARFDebugInfoEntryMinimal::addressRangeContainsAddress( const char * DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U, - FunctionNameKind Kind) const { - if (!isSubroutineDIE() || Kind == FunctionNameKind::None) + DINameKind Kind) const { + if (!isSubroutineDIE()) + return nullptr; + return getName(U, Kind); +} + +const char * +DWARFDebugInfoEntryMinimal::getName(const DWARFUnit *U, + DINameKind Kind) const { + if (Kind == DINameKind::None) return nullptr; // Try to get mangled name only if it was asked for. - if (Kind == FunctionNameKind::LinkageName) { + if (Kind == DINameKind::LinkageName) { if (const char *name = getAttributeValueAsString(U, DW_AT_MIPS_linkage_name, nullptr)) return name; @@ -303,8 +393,8 @@ DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U, getAttributeValueAsReference(U, DW_AT_specification, -1U); if (spec_ref != -1U) { DWARFDebugInfoEntryMinimal spec_die; - if (spec_die.extractFast(U, &spec_ref)) { - if (const char *name = spec_die.getSubroutineName(U, Kind)) + if (const DWARFUnit *RefU = findUnitAndExtractFast(spec_die, U, &spec_ref)) { + if (const char *name = spec_die.getName(RefU, Kind)) return name; } } @@ -313,8 +403,9 @@ DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U, getAttributeValueAsReference(U, DW_AT_abstract_origin, -1U); if (abs_origin_ref != -1U) { DWARFDebugInfoEntryMinimal abs_origin_die; - if (abs_origin_die.extractFast(U, &abs_origin_ref)) { - if (const char *name = abs_origin_die.getSubroutineName(U, Kind)) + if (const DWARFUnit *RefU = findUnitAndExtractFast(abs_origin_die, U, + &abs_origin_ref)) { + if (const char *name = abs_origin_die.getName(RefU, Kind)) return name; } } |