summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/DebugInfo/DWARF/CMakeLists.txt1
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp6
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFContext.cpp42
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp399
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDie.cpp391
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp9
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp90
7 files changed, 462 insertions, 476 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/CMakeLists.txt b/llvm/lib/DebugInfo/DWARF/CMakeLists.txt
index d54c001d7f7..329ccfb15a2 100644
--- a/llvm/lib/DebugInfo/DWARF/CMakeLists.txt
+++ b/llvm/lib/DebugInfo/DWARF/CMakeLists.txt
@@ -12,6 +12,7 @@ add_llvm_library(LLVMDebugInfoDWARF
DWARFDebugLoc.cpp
DWARFDebugMacro.cpp
DWARFDebugRangeList.cpp
+ DWARFDie.cpp
DWARFFormValue.cpp
DWARFGdbIndex.cpp
DWARFTypeUnit.cpp
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
index faa51e0d5fd..948972f8f13 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
@@ -9,7 +9,7 @@
#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
+#include "llvm/DebugInfo/DWARF/DWARFDie.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
@@ -24,8 +24,8 @@ void DWARFCompileUnit::dump(raw_ostream &OS) {
<< " (next unit at " << format("0x%08x", getNextUnitOffset())
<< ")\n";
- if (const DWARFDebugInfoEntryMinimal *CU = getUnitDIE(false))
- CU->dump(OS, this, -1U);
+ if (DWARFDie CUDie = getUnitDIE(false))
+ CUDie.dump(OS, -1U);
else
OS << "<compile unit can't be parsed!>\n\n";
}
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index adcbff78d1c..5982fbbab24 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -156,11 +156,11 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpType DumpType, bool DumpEH,
OS << "\n.debug_line contents:\n";
for (const auto &CU : compile_units()) {
savedAddressByteSize = CU->getAddressByteSize();
- const auto *CUDIE = CU->getUnitDIE();
- if (CUDIE == nullptr)
+ auto CUDIE = CU->getUnitDIE();
+ if (!CUDIE)
continue;
- unsigned stmtOffset = CUDIE->getAttributeValueAsSectionOffset(
- CU.get(), DW_AT_stmt_list, -1U);
+ unsigned stmtOffset = CUDIE.getAttributeValueAsSectionOffset(
+ DW_AT_stmt_list, -1U);
if (stmtOffset != -1U) {
DataExtractor lineData(getLineSection().Data, isLittleEndian(),
savedAddressByteSize);
@@ -412,12 +412,12 @@ DWARFContext::getLineTableForUnit(DWARFUnit *U) {
if (!Line)
Line.reset(new DWARFDebugLine(&getLineSection().Relocs));
- const auto *UnitDIE = U->getUnitDIE();
- if (UnitDIE == nullptr)
+ auto UnitDIE = U->getUnitDIE();
+ if (!UnitDIE)
return nullptr;
unsigned stmtOffset =
- UnitDIE->getAttributeValueAsSectionOffset(U, DW_AT_stmt_list, -1U);
+ UnitDIE.getAttributeValueAsSectionOffset(DW_AT_stmt_list, -1U);
if (stmtOffset == -1U)
return nullptr; // No line table for this compile unit.
@@ -477,14 +477,12 @@ static bool getFunctionNameForAddress(DWARFCompileUnit *CU, uint64_t Address,
return false;
// The address may correspond to instruction in some inlined function,
// so we have to build the chain of inlined functions and take the
- // name of the topmost function in it.
- const DWARFDebugInfoEntryInlinedChain &InlinedChain =
- CU->getInlinedChainForAddress(Address);
- if (InlinedChain.DIEs.size() == 0)
+ // name of the topmost function in it.SmallVectorImpl<DWARFDie> &InlinedChain
+ SmallVector<DWARFDie, 4> InlinedChain;
+ CU->getInlinedChainForAddress(Address, InlinedChain);
+ if (InlinedChain.size() == 0)
return false;
- const DWARFDebugInfoEntryMinimal &TopFunctionDIE = InlinedChain.DIEs[0];
- if (const char *Name =
- TopFunctionDIE.getSubroutineName(InlinedChain.U, Kind)) {
+ if (const char *Name = InlinedChain[0].getSubroutineName(Kind)) {
FunctionName = Name;
return true;
}
@@ -559,9 +557,9 @@ DWARFContext::getInliningInfoForAddress(uint64_t Address,
return InliningInfo;
const DWARFLineTable *LineTable = nullptr;
- const DWARFDebugInfoEntryInlinedChain &InlinedChain =
- CU->getInlinedChainForAddress(Address);
- if (InlinedChain.DIEs.size() == 0) {
+ SmallVector<DWARFDie, 4> InlinedChain;
+ CU->getInlinedChainForAddress(Address, InlinedChain);
+ if (InlinedChain.size() == 0) {
// If there is no DIE for address (e.g. it is in unavailable .dwo file),
// try to at least get file/line info from symbol table.
if (Spec.FLIKind != FileLineInfoKind::None) {
@@ -576,12 +574,11 @@ DWARFContext::getInliningInfoForAddress(uint64_t Address,
}
uint32_t CallFile = 0, CallLine = 0, CallColumn = 0;
- for (uint32_t i = 0, n = InlinedChain.DIEs.size(); i != n; i++) {
- const DWARFDebugInfoEntryMinimal &FunctionDIE = InlinedChain.DIEs[i];
+ for (uint32_t i = 0, n = InlinedChain.size(); i != n; i++) {
+ DWARFDie &FunctionDIE = InlinedChain[i];
DILineInfo Frame;
// Get function name if necessary.
- if (const char *Name =
- FunctionDIE.getSubroutineName(InlinedChain.U, Spec.FNKind))
+ if (const char *Name = FunctionDIE.getSubroutineName(Spec.FNKind))
Frame.FunctionName = Name;
if (Spec.FLIKind != FileLineInfoKind::None) {
if (i == 0) {
@@ -603,8 +600,7 @@ DWARFContext::getInliningInfoForAddress(uint64_t Address,
}
// Get call file/line/column of a current DIE.
if (i + 1 < n) {
- FunctionDIE.getCallerFrame(InlinedChain.U, CallFile, CallLine,
- CallColumn);
+ FunctionDIE.getCallerFrame(CallFile, CallLine, CallColumn);
}
}
InliningInfo.addFrame(Frame);
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp
index c666f2953b0..8ea65ebfdd5 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp
@@ -22,174 +22,13 @@ using namespace llvm;
using namespace dwarf;
using namespace syntax;
-// 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();
- uint32_t offset = Offset;
-
- if (debug_info_data.isValidOffset(offset)) {
- uint32_t abbrCode = debug_info_data.getULEB128(&offset);
- WithColor(OS, syntax::Address).get() << format("\n0x%8.8x: ", Offset);
-
- if (abbrCode) {
- if (AbbrevDecl) {
- auto tagString = TagString(getTag());
- if (!tagString.empty())
- WithColor(OS, syntax::Tag).get().indent(indent) << tagString;
- else
- WithColor(OS, syntax::Tag).get().indent(indent)
- << format("DW_TAG_Unknown_%x", getTag());
-
- OS << format(" [%u] %c\n", abbrCode,
- AbbrevDecl->hasChildren() ? '*' : ' ');
-
- // Dump all data in the DIE for the attributes.
- for (const auto &AttrSpec : AbbrevDecl->attributes()) {
- dumpAttribute(OS, u, &offset, AttrSpec.Attr, AttrSpec.Form, indent);
- }
-
- const DWARFDebugInfoEntryMinimal *child = getFirstChild();
- if (recurseDepth > 0 && child) {
- while (child) {
- child->dump(OS, u, recurseDepth-1, indent+2);
- child = child->getSibling();
- }
- }
- } else {
- OS << "Abbreviation code not found in 'debug_abbrev' class for code: "
- << abbrCode << '\n';
- }
- } else {
- OS.indent(indent) << "NULL\n";
- }
- }
-}
-
-static void dumpApplePropertyAttribute(raw_ostream &OS, uint64_t Val) {
- OS << " (";
- do {
- uint64_t Shift = countTrailingZeros(Val);
- assert(Shift < 64 && "undefined behavior");
- uint64_t Bit = 1ULL << Shift;
- auto PropName = ApplePropertyString(Bit);
- if (!PropName.empty())
- 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,
- DWARFUnit *u,
- uint32_t *offset_ptr,
- dwarf::Attribute attr,
- dwarf::Form form,
- unsigned indent) const {
- const char BaseIndent[] = " ";
- OS << BaseIndent;
- OS.indent(indent+2);
- auto attrString = AttributeString(attr);
- if (!attrString.empty())
- WithColor(OS, syntax::Attribute) << attrString;
- else
- WithColor(OS, syntax::Attribute).get() << format("DW_AT_Unknown_%x", attr);
-
- auto formString = FormEncodingString(form);
- if (!formString.empty())
- OS << " [" << formString << ']';
- else
- OS << format(" [DW_FORM_Unknown_%x]", form);
-
- DWARFFormValue formValue(form);
-
- if (!formValue.extractValue(u->getDebugInfoExtractor(), offset_ptr, u))
- return;
-
- OS << "\t(";
-
- StringRef Name;
- std::string File;
- auto Color = syntax::Enumerator;
- if (attr == DW_AT_decl_file || attr == DW_AT_call_file) {
- Color = syntax::String;
- if (const auto *LT = u->getContext().getLineTableForUnit(u))
- if (LT->getFileNameByIndex(
- formValue.getAsUnsignedConstant().getValue(),
- u->getCompilationDir(),
- DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, File)) {
- File = '"' + File + '"';
- Name = File;
- }
- } else if (Optional<uint64_t> Val = formValue.getAsUnsignedConstant())
- Name = AttributeValueString(attr, *Val);
-
- if (!Name.empty())
- WithColor(OS, Color) << Name;
- else if (attr == DW_AT_decl_line || attr == DW_AT_call_line)
- OS << *formValue.getAsUnsignedConstant();
- else
- formValue.dump(OS);
-
- // 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) {
- Optional<uint64_t> Ref = formValue.getAsReference();
- if (Ref.hasValue()) {
- uint32_t RefOffset = Ref.getValue();
- DWARFDebugInfoEntryMinimal DIE;
- if (const DWARFUnit *RefU = findUnitAndExtractFast(DIE, u, &RefOffset))
- if (const char *Name = DIE.getName(RefU, DINameKind::LinkageName))
- OS << " \"" << Name << '\"';
- }
- } 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";
-}
-
-bool DWARFDebugInfoEntryMinimal::extractFast(const DWARFUnit &U,
+bool DWARFDebugInfoEntry::extractFast(const DWARFUnit &U,
uint32_t *OffsetPtr) {
DataExtractor DebugInfoData = U.getDebugInfoExtractor();
const uint32_t UEndOffset = U.getNextUnitOffset();
return extractFast(U, OffsetPtr, DebugInfoData, UEndOffset);
}
-bool DWARFDebugInfoEntryMinimal::extractFast(const DWARFUnit &U,
+bool DWARFDebugInfoEntry::extractFast(const DWARFUnit &U,
uint32_t *OffsetPtr,
const DataExtractor &DebugInfoData,
uint32_t UEndOffset) {
@@ -231,237 +70,3 @@ bool DWARFDebugInfoEntryMinimal::extractFast(const DWARFUnit &U,
}
return true;
}
-
-bool DWARFDebugInfoEntryMinimal::isSubprogramDIE() const {
- return getTag() == DW_TAG_subprogram;
-}
-
-bool DWARFDebugInfoEntryMinimal::isSubroutineDIE() const {
- uint32_t Tag = getTag();
- return Tag == DW_TAG_subprogram ||
- Tag == DW_TAG_inlined_subroutine;
-}
-
-bool DWARFDebugInfoEntryMinimal::getAttributeValue(const DWARFUnit *U,
- dwarf::Attribute Attr, DWARFFormValue &FormValue) const {
- if (!AbbrevDecl || !U)
- return false;
- return AbbrevDecl->getAttributeValue(Offset, Attr, *U, FormValue);
-}
-
-const char *DWARFDebugInfoEntryMinimal::getAttributeValueAsString(
- const DWARFUnit *U, dwarf::Attribute Attr,
- const char *FailValue) const {
- DWARFFormValue FormValue;
- if (!getAttributeValue(U, Attr, FormValue))
- return FailValue;
- Optional<const char *> Result = FormValue.getAsCString();
- return Result.hasValue() ? Result.getValue() : FailValue;
-}
-
-uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsAddress(
- const DWARFUnit *U, dwarf::Attribute Attr,
- uint64_t FailValue) const {
- DWARFFormValue FormValue;
- if (!getAttributeValue(U, Attr, FormValue))
- return FailValue;
- Optional<uint64_t> Result = FormValue.getAsAddress();
- return Result.hasValue() ? Result.getValue() : FailValue;
-}
-
-int64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsSignedConstant(
- const DWARFUnit *U, dwarf::Attribute Attr, int64_t FailValue) const {
- DWARFFormValue FormValue;
- if (!getAttributeValue(U, Attr, FormValue))
- return FailValue;
- Optional<int64_t> Result = FormValue.getAsSignedConstant();
- return Result.hasValue() ? Result.getValue() : FailValue;
-}
-
-uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsUnsignedConstant(
- const DWARFUnit *U, dwarf::Attribute Attr,
- uint64_t FailValue) const {
- DWARFFormValue FormValue;
- if (!getAttributeValue(U, Attr, FormValue))
- return FailValue;
- Optional<uint64_t> Result = FormValue.getAsUnsignedConstant();
- return Result.hasValue() ? Result.getValue() : FailValue;
-}
-
-uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsReference(
- const DWARFUnit *U, dwarf::Attribute Attr,
- uint64_t FailValue) const {
- DWARFFormValue FormValue;
- if (!getAttributeValue(U, Attr, FormValue))
- return FailValue;
- Optional<uint64_t> Result = FormValue.getAsReference();
- return Result.hasValue() ? Result.getValue() : FailValue;
-}
-
-uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsSectionOffset(
- const DWARFUnit *U, dwarf::Attribute Attr,
- uint64_t FailValue) const {
- DWARFFormValue FormValue;
- if (!getAttributeValue(U, Attr, FormValue))
- return FailValue;
- Optional<uint64_t> Result = FormValue.getAsSectionOffset();
- return Result.hasValue() ? Result.getValue() : FailValue;
-}
-
-uint64_t
-DWARFDebugInfoEntryMinimal::getRangesBaseAttribute(const DWARFUnit *U,
- uint64_t FailValue) const {
- uint64_t Result =
- getAttributeValueAsSectionOffset(U, DW_AT_rnglists_base, -1ULL);
- if (Result != -1ULL)
- return Result;
- return getAttributeValueAsSectionOffset(U, DW_AT_GNU_ranges_base, FailValue);
-}
-
-bool DWARFDebugInfoEntryMinimal::getLowAndHighPC(const DWARFUnit *U,
- uint64_t &LowPC,
- uint64_t &HighPC) const {
- LowPC = getAttributeValueAsAddress(U, DW_AT_low_pc, -1ULL);
- if (LowPC == -1ULL)
- return false;
- HighPC = getAttributeValueAsAddress(U, DW_AT_high_pc, -1ULL);
- if (HighPC == -1ULL) {
- // Since DWARF4, DW_AT_high_pc may also be of class constant, in which case
- // it represents function size.
- HighPC = getAttributeValueAsUnsignedConstant(U, DW_AT_high_pc, -1ULL);
- if (HighPC != -1ULL)
- HighPC += LowPC;
- }
- return (HighPC != -1ULL);
-}
-
-DWARFAddressRangesVector
-DWARFDebugInfoEntryMinimal::getAddressRanges(const DWARFUnit *U) const {
- if (isNULL())
- return DWARFAddressRangesVector();
- // Single range specified by low/high PC.
- uint64_t LowPC, HighPC;
- if (getLowAndHighPC(U, LowPC, HighPC)) {
- return DWARFAddressRangesVector(1, std::make_pair(LowPC, HighPC));
- }
- // Multiple ranges from .debug_ranges section.
- uint32_t RangesOffset =
- getAttributeValueAsSectionOffset(U, DW_AT_ranges, -1U);
- if (RangesOffset != -1U) {
- DWARFDebugRangeList RangeList;
- if (U->extractRangeList(RangesOffset, RangeList))
- return RangeList.getAbsoluteRanges(U->getBaseAddress());
- }
- return DWARFAddressRangesVector();
-}
-
-void DWARFDebugInfoEntryMinimal::collectChildrenAddressRanges(
- const DWARFUnit *U, DWARFAddressRangesVector& Ranges) const {
- if (isNULL())
- return;
- if (isSubprogramDIE()) {
- const auto &DIERanges = getAddressRanges(U);
- Ranges.insert(Ranges.end(), DIERanges.begin(), DIERanges.end());
- }
-
- const DWARFDebugInfoEntryMinimal *Child = getFirstChild();
- while (Child) {
- Child->collectChildrenAddressRanges(U, Ranges);
- Child = Child->getSibling();
- }
-}
-
-bool DWARFDebugInfoEntryMinimal::addressRangeContainsAddress(
- const DWARFUnit *U, const uint64_t Address) const {
- for (const auto& R : getAddressRanges(U)) {
- if (R.first <= Address && Address < R.second)
- return true;
- }
- return false;
-}
-
-const char *
-DWARFDebugInfoEntryMinimal::getSubroutineName(const DWARFUnit *U,
- 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 == DINameKind::LinkageName) {
- if (const char *name =
- getAttributeValueAsString(U, DW_AT_MIPS_linkage_name, nullptr))
- return name;
- if (const char *name =
- getAttributeValueAsString(U, DW_AT_linkage_name, nullptr))
- return name;
- }
- if (const char *name = getAttributeValueAsString(U, DW_AT_name, nullptr))
- return name;
- // Try to get name from specification DIE.
- uint32_t spec_ref =
- getAttributeValueAsReference(U, DW_AT_specification, -1U);
- if (spec_ref != -1U) {
- DWARFDebugInfoEntryMinimal spec_die;
- if (const DWARFUnit *RefU = findUnitAndExtractFast(spec_die, U, &spec_ref)) {
- if (const char *name = spec_die.getName(RefU, Kind))
- return name;
- }
- }
- // Try to get name from abstract origin DIE.
- uint32_t abs_origin_ref =
- getAttributeValueAsReference(U, DW_AT_abstract_origin, -1U);
- if (abs_origin_ref != -1U) {
- DWARFDebugInfoEntryMinimal abs_origin_die;
- if (const DWARFUnit *RefU = findUnitAndExtractFast(abs_origin_die, U,
- &abs_origin_ref)) {
- if (const char *name = abs_origin_die.getName(RefU, Kind))
- return name;
- }
- }
- return nullptr;
-}
-
-void DWARFDebugInfoEntryMinimal::getCallerFrame(const DWARFUnit *U,
- uint32_t &CallFile,
- uint32_t &CallLine,
- uint32_t &CallColumn) const {
- CallFile = getAttributeValueAsUnsignedConstant(U, DW_AT_call_file, 0);
- CallLine = getAttributeValueAsUnsignedConstant(U, DW_AT_call_line, 0);
- CallColumn = getAttributeValueAsUnsignedConstant(U, DW_AT_call_column, 0);
-}
-
-DWARFDebugInfoEntryInlinedChain
-DWARFDebugInfoEntryMinimal::getInlinedChainForAddress(
- const DWARFUnit *U, const uint64_t Address) const {
- DWARFDebugInfoEntryInlinedChain InlinedChain;
- InlinedChain.U = U;
- if (isNULL())
- return InlinedChain;
- for (const DWARFDebugInfoEntryMinimal *DIE = this; DIE; ) {
- // Append current DIE to inlined chain only if it has correct tag
- // (e.g. it is not a lexical block).
- if (DIE->isSubroutineDIE()) {
- InlinedChain.DIEs.push_back(*DIE);
- }
- // Try to get child which also contains provided address.
- const DWARFDebugInfoEntryMinimal *Child = DIE->getFirstChild();
- while (Child) {
- if (Child->addressRangeContainsAddress(U, Address)) {
- // Assume there is only one such child.
- break;
- }
- Child = Child->getSibling();
- }
- DIE = Child;
- }
- // Reverse the obtained chain to make the root of inlined chain last.
- std::reverse(InlinedChain.DIEs.begin(), InlinedChain.DIEs.end());
- return InlinedChain;
-}
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
new file mode 100644
index 00000000000..a41fe6fce1d
--- /dev/null
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -0,0 +1,391 @@
+//===-- DWARFDie.cpp ------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/DWARF/DWARFDie.h"
+#include "SyntaxHighlighting.h"
+#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
+#include "llvm/DebugInfo/DWARF/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;
+using namespace syntax;
+
+namespace {
+ static void dumpApplePropertyAttribute(raw_ostream &OS, uint64_t Val) {
+ OS << " (";
+ do {
+ uint64_t Shift = countTrailingZeros(Val);
+ assert(Shift < 64 && "undefined behavior");
+ uint64_t Bit = 1ULL << Shift;
+ auto PropName = ApplePropertyString(Bit);
+ if (!PropName.empty())
+ 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);
+ }
+}
+
+static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
+ uint32_t *OffsetPtr, dwarf::Attribute Attr,
+ dwarf::Form Form, unsigned Indent) {
+ if (!Die.isValid())
+ return;
+ const char BaseIndent[] = " ";
+ OS << BaseIndent;
+ OS.indent(Indent+2);
+ auto attrString = AttributeString(Attr);
+ if (!attrString.empty())
+ WithColor(OS, syntax::Attribute) << attrString;
+ else
+ WithColor(OS, syntax::Attribute).get() << format("DW_AT_Unknown_%x", Attr);
+
+ auto formString = FormEncodingString(Form);
+ if (!formString.empty())
+ OS << " [" << formString << ']';
+ else
+ OS << format(" [DW_FORM_Unknown_%x]", Form);
+
+ DWARFUnit *U = Die.getDwarfUnit();
+ DWARFFormValue formValue(Form);
+
+ if (!formValue.extractValue(U->getDebugInfoExtractor(), OffsetPtr, U))
+ return;
+
+ OS << "\t(";
+
+ StringRef Name;
+ std::string File;
+ auto Color = syntax::Enumerator;
+ if (Attr == DW_AT_decl_file || Attr == DW_AT_call_file) {
+ Color = syntax::String;
+ if (const auto *LT = U->getContext().getLineTableForUnit(U))
+ if (LT->getFileNameByIndex(formValue.getAsUnsignedConstant().getValue(), U->getCompilationDir(), DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, File)) {
+ File = '"' + File + '"';
+ Name = File;
+ }
+ } else if (Optional<uint64_t> Val = formValue.getAsUnsignedConstant())
+ Name = AttributeValueString(Attr, *Val);
+
+ if (!Name.empty())
+ WithColor(OS, Color) << Name;
+ else if (Attr == DW_AT_decl_line || Attr == DW_AT_call_line)
+ OS << *formValue.getAsUnsignedConstant();
+ else
+ formValue.dump(OS);
+
+ // 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) {
+ if (const char *Name = Die.getAttributeValueAsReferencedDie(Attr).getName(DINameKind::LinkageName))
+ OS << " \"" << Name << '\"';
+ } 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, Die.getAddressRanges(), U->getAddressByteSize(),
+ sizeof(BaseIndent)+Indent+4);
+ }
+
+ OS << ")\n";
+}
+
+} // end anonymous namespace
+
+bool DWARFDie::isSubprogramDIE() const {
+ return getTag() == DW_TAG_subprogram;
+}
+
+bool DWARFDie::isSubroutineDIE() const {
+ auto Tag = getTag();
+ return Tag == DW_TAG_subprogram || Tag == DW_TAG_inlined_subroutine;
+}
+
+bool DWARFDie::getAttributeValue(dwarf::Attribute Attr,
+ DWARFFormValue &FormValue) const {
+ if (!U)
+ return false;
+ auto AbbrevDecl = getAbbreviationDeclarationPtr();
+ if (AbbrevDecl)
+ return AbbrevDecl->getAttributeValue(getOffset(), Attr, *U, FormValue);
+ return false;
+}
+
+const char *DWARFDie::getAttributeValueAsString(dwarf::Attribute Attr,
+ const char *FailValue) const {
+ DWARFFormValue FormValue;
+ if (!getAttributeValue(Attr, FormValue))
+ return FailValue;
+ Optional<const char *> Result = FormValue.getAsCString();
+ return Result.hasValue() ? Result.getValue() : FailValue;
+}
+
+uint64_t DWARFDie::getAttributeValueAsAddress(dwarf::Attribute Attr,
+ uint64_t FailValue) const {
+ DWARFFormValue FormValue;
+ if (!getAttributeValue(Attr, FormValue))
+ return FailValue;
+ Optional<uint64_t> Result = FormValue.getAsAddress();
+ return Result.hasValue() ? Result.getValue() : FailValue;
+}
+
+int64_t DWARFDie::getAttributeValueAsSignedConstant(dwarf::Attribute Attr,
+ int64_t FailValue) const {
+ DWARFFormValue FormValue;
+ if (!getAttributeValue(Attr, FormValue))
+ return FailValue;
+ Optional<int64_t> Result = FormValue.getAsSignedConstant();
+ return Result.hasValue() ? Result.getValue() : FailValue;
+}
+
+uint64_t
+DWARFDie::getAttributeValueAsUnsignedConstant(dwarf::Attribute Attr,
+ uint64_t FailValue) const {
+ DWARFFormValue FormValue;
+ if (!getAttributeValue(Attr, FormValue))
+ return FailValue;
+ Optional<uint64_t> Result = FormValue.getAsUnsignedConstant();
+ return Result.hasValue() ? Result.getValue() : FailValue;
+}
+
+uint64_t DWARFDie::getAttributeValueAsReference(dwarf::Attribute Attr,
+ uint64_t FailValue) const {
+ DWARFFormValue FormValue;
+ if (!getAttributeValue(Attr, FormValue))
+ return FailValue;
+ Optional<uint64_t> Result = FormValue.getAsReference();
+ return Result.hasValue() ? Result.getValue() : FailValue;
+}
+
+uint64_t DWARFDie::getAttributeValueAsSectionOffset(dwarf::Attribute Attr,
+ uint64_t FailValue) const {
+ DWARFFormValue FormValue;
+ if (!getAttributeValue(Attr, FormValue))
+ return FailValue;
+ Optional<uint64_t> Result = FormValue.getAsSectionOffset();
+ return Result.hasValue() ? Result.getValue() : FailValue;
+}
+
+DWARFDie
+DWARFDie::getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const {
+ uint32_t SpecRef = getAttributeValueAsReference(Attr, -1U);
+ if (SpecRef != -1U) {
+ auto SpecUnit = U->getUnitSection().getUnitForOffset(SpecRef);
+ if (SpecUnit)
+ return SpecUnit->getDIEForOffset(SpecRef);
+ }
+ return DWARFDie();
+}
+
+uint64_t
+DWARFDie::getRangesBaseAttribute(uint64_t FailValue) const {
+ auto Result = getAttributeValueAsSectionOffset(DW_AT_rnglists_base, -1ULL);
+ if (Result != -1ULL)
+ return Result;
+ return getAttributeValueAsSectionOffset(DW_AT_GNU_ranges_base, FailValue);
+}
+
+bool DWARFDie::getLowAndHighPC(uint64_t &LowPC, uint64_t &HighPC) const {
+ LowPC = getAttributeValueAsAddress(DW_AT_low_pc, -1ULL);
+ if (LowPC == -1ULL)
+ return false;
+ HighPC = getAttributeValueAsAddress(DW_AT_high_pc, -1ULL);
+ if (HighPC == -1ULL) {
+ // Since DWARF4, DW_AT_high_pc may also be of class constant, in which case
+ // it represents function size.
+ HighPC = getAttributeValueAsUnsignedConstant(DW_AT_high_pc, -1ULL);
+ if (HighPC != -1ULL)
+ HighPC += LowPC;
+ }
+ return (HighPC != -1ULL);
+}
+
+DWARFAddressRangesVector
+DWARFDie::getAddressRanges() const {
+ if (isNULL())
+ return DWARFAddressRangesVector();
+ // Single range specified by low/high PC.
+ uint64_t LowPC, HighPC;
+ if (getLowAndHighPC(LowPC, HighPC)) {
+ return DWARFAddressRangesVector(1, std::make_pair(LowPC, HighPC));
+ }
+ // Multiple ranges from .debug_ranges section.
+ uint32_t RangesOffset = getAttributeValueAsSectionOffset(DW_AT_ranges, -1U);
+ if (RangesOffset != -1U) {
+ DWARFDebugRangeList RangeList;
+ if (U->extractRangeList(RangesOffset, RangeList))
+ return RangeList.getAbsoluteRanges(U->getBaseAddress());
+ }
+ return DWARFAddressRangesVector();
+}
+
+void
+DWARFDie::collectChildrenAddressRanges(DWARFAddressRangesVector& Ranges) const {
+ if (isNULL())
+ return;
+ if (isSubprogramDIE()) {
+ const auto &DIERanges = getAddressRanges();
+ Ranges.insert(Ranges.end(), DIERanges.begin(), DIERanges.end());
+ }
+
+ DWARFDie Child = getFirstChild();
+ while (Child) {
+ Child.collectChildrenAddressRanges(Ranges);
+ Child = Child.getSibling();
+ }
+}
+
+bool DWARFDie::addressRangeContainsAddress(const uint64_t Address) const {
+ for (const auto& R : getAddressRanges()) {
+ if (R.first <= Address && Address < R.second)
+ return true;
+ }
+ return false;
+}
+
+const char *
+DWARFDie::getSubroutineName(DINameKind Kind) const {
+ if (!isSubroutineDIE())
+ return nullptr;
+ return getName(Kind);
+}
+
+const char *
+DWARFDie::getName(DINameKind Kind) const {
+ if (!isValid() || Kind == DINameKind::None)
+ return nullptr;
+ const char *name = nullptr;
+ // Try to get mangled name only if it was asked for.
+ if (Kind == DINameKind::LinkageName) {
+ if ((name = getAttributeValueAsString(DW_AT_MIPS_linkage_name, nullptr)))
+ return name;
+ if ((name = getAttributeValueAsString(DW_AT_linkage_name, nullptr)))
+ return name;
+ }
+ if ((name = getAttributeValueAsString(DW_AT_name, nullptr)))
+ return name;
+ // Try to get name from specification DIE.
+ DWARFDie SpecDie = getAttributeValueAsReferencedDie(DW_AT_specification);
+ if (SpecDie && (name = SpecDie.getName(Kind)))
+ return name;
+ // Try to get name from abstract origin DIE.
+ DWARFDie AbsDie = getAttributeValueAsReferencedDie(DW_AT_abstract_origin);
+ if (AbsDie && (name = AbsDie.getName(Kind)))
+ return name;
+ return nullptr;
+}
+
+void DWARFDie::getCallerFrame(uint32_t &CallFile, uint32_t &CallLine,
+ uint32_t &CallColumn) const {
+ CallFile = getAttributeValueAsUnsignedConstant(DW_AT_call_file, 0);
+ CallLine = getAttributeValueAsUnsignedConstant(DW_AT_call_line, 0);
+ CallColumn = getAttributeValueAsUnsignedConstant(DW_AT_call_column, 0);
+}
+
+void DWARFDie::dump(raw_ostream &OS, unsigned RecurseDepth,
+ unsigned Indent) const {
+ if (!isValid())
+ return;
+ DataExtractor debug_info_data = U->getDebugInfoExtractor();
+ const uint32_t Offset = getOffset();
+ uint32_t offset = Offset;
+
+ if (debug_info_data.isValidOffset(offset)) {
+ uint32_t abbrCode = debug_info_data.getULEB128(&offset);
+ WithColor(OS, syntax::Address).get() << format("\n0x%8.8x: ", Offset);
+
+ if (abbrCode) {
+ auto AbbrevDecl = getAbbreviationDeclarationPtr();
+ if (AbbrevDecl) {
+ auto tagString = TagString(getTag());
+ if (!tagString.empty())
+ WithColor(OS, syntax::Tag).get().indent(Indent) << tagString;
+ else
+ WithColor(OS, syntax::Tag).get().indent(Indent)
+ << format("DW_TAG_Unknown_%x", getTag());
+
+ OS << format(" [%u] %c\n", abbrCode,
+ AbbrevDecl->hasChildren() ? '*' : ' ');
+
+ // Dump all data in the DIE for the attributes.
+ for (const auto &AttrSpec : AbbrevDecl->attributes()) {
+ dumpAttribute(OS, *this, &offset, AttrSpec.Attr, AttrSpec.Form,
+ Indent);
+ }
+
+ DWARFDie child = getFirstChild();
+ if (RecurseDepth > 0 && child) {
+ while (child) {
+ child.dump(OS, RecurseDepth-1, Indent+2);
+ child = child.getSibling();
+ }
+ }
+ } else {
+ OS << "Abbreviation code not found in 'debug_abbrev' class for code: "
+ << abbrCode << '\n';
+ }
+ } else {
+ OS.indent(Indent) << "NULL\n";
+ }
+ }
+}
+
+
+void DWARFDie::getInlinedChainForAddress(
+ const uint64_t Address, SmallVectorImpl<DWARFDie> &InlinedChain) const {
+ if (isNULL())
+ return;
+ DWARFDie DIE(*this);
+ while (DIE) {
+ // Append current DIE to inlined chain only if it has correct tag
+ // (e.g. it is not a lexical block).
+ if (DIE.isSubroutineDIE())
+ InlinedChain.push_back(DIE);
+
+ // Try to get child which also contains provided address.
+ DWARFDie Child = DIE.getFirstChild();
+ while (Child) {
+ if (Child.addressRangeContainsAddress(Address)) {
+ // Assume there is only one such child.
+ break;
+ }
+ Child = Child.getSibling();
+ }
+ DIE = Child;
+ }
+ // Reverse the obtained chain to make the root of inlined chain last.
+ std::reverse(InlinedChain.begin(), InlinedChain.end());
+}
+
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp
index fa3f1d4d2b8..dacd6449d3d 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp
@@ -25,11 +25,10 @@ bool DWARFTypeUnit::extractImpl(DataExtractor debug_info,
}
void DWARFTypeUnit::dump(raw_ostream &OS, bool SummarizeTypes) {
- const DWARFDebugInfoEntryMinimal *TD =
- getDIEForOffset(TypeOffset + getOffset());
+ DWARFDie TD = getDIEForOffset(TypeOffset + getOffset());
DWARFFormValue NameVal;
const char *Name = "";
- if (TD->getAttributeValue(this, llvm::dwarf::DW_AT_name, NameVal))
+ if (TD.getAttributeValue(llvm::dwarf::DW_AT_name, NameVal))
if (auto ON = NameVal.getAsCString())
Name = *ON;
@@ -50,8 +49,8 @@ void DWARFTypeUnit::dump(raw_ostream &OS, bool SummarizeTypes) {
<< " type_offset = " << format("0x%04x", TypeOffset)
<< " (next unit at " << format("0x%08x", getNextUnitOffset()) << ")\n";
- if (const DWARFDebugInfoEntryMinimal *TU = getUnitDIE(false))
- TU->dump(OS, this, -1U);
+ if (DWARFDie TU = getUnitDIE(false))
+ TU.dump(OS, -1U);
else
OS << "<type unit can't be parsed!>\n\n";
}
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
index caa3694a29d..2424ea44ca8 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -151,27 +151,20 @@ void DWARFUnit::clear() {
}
const char *DWARFUnit::getCompilationDir() {
- extractDIEsIfNeeded(true);
- if (DieArray.empty())
- return nullptr;
- return DieArray[0].getAttributeValueAsString(this, DW_AT_comp_dir, nullptr);
+ return getUnitDIE().getAttributeValueAsString(DW_AT_comp_dir, nullptr);
}
uint64_t DWARFUnit::getDWOId() {
- extractDIEsIfNeeded(true);
- const uint64_t FailValue = -1ULL;
- if (DieArray.empty())
- return FailValue;
- return DieArray[0]
- .getAttributeValueAsUnsignedConstant(this, DW_AT_GNU_dwo_id, FailValue);
+ return getUnitDIE().getAttributeValueAsUnsignedConstant(DW_AT_GNU_dwo_id,
+ -1ULL);
}
void DWARFUnit::setDIERelations() {
if (DieArray.size() <= 1)
return;
- std::vector<DWARFDebugInfoEntryMinimal *> ParentChain;
- DWARFDebugInfoEntryMinimal *SiblingChain = nullptr;
+ std::vector<DWARFDebugInfoEntry *> ParentChain;
+ DWARFDebugInfoEntry *SiblingChain = nullptr;
for (auto &DIE : DieArray) {
if (SiblingChain) {
SiblingChain->setSibling(&DIE);
@@ -197,7 +190,7 @@ void DWARFUnit::setDIERelations() {
void DWARFUnit::extractDIEsToVector(
bool AppendCUDie, bool AppendNonCUDies,
- std::vector<DWARFDebugInfoEntryMinimal> &Dies) const {
+ std::vector<DWARFDebugInfoEntry> &Dies) const {
if (!AppendCUDie && !AppendNonCUDies)
return;
@@ -205,7 +198,7 @@ void DWARFUnit::extractDIEsToVector(
// next compilation unit header.
uint32_t DIEOffset = Offset + getHeaderSize();
uint32_t NextCUOffset = getNextUnitOffset();
- DWARFDebugInfoEntryMinimal DIE;
+ DWARFDebugInfoEntry DIE;
DataExtractor DebugInfoData = getDebugInfoExtractor();
uint32_t Depth = 0;
bool IsCUDie = true;
@@ -260,15 +253,15 @@ size_t DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
// If CU DIE was just parsed, copy several attribute values from it.
if (!HasCUDie) {
- uint64_t BaseAddr =
- DieArray[0].getAttributeValueAsAddress(this, DW_AT_low_pc, -1ULL);
+ DWARFDie UnitDie = getUnitDIE();
+ uint64_t BaseAddr = UnitDie.getAttributeValueAsAddress(DW_AT_low_pc, -1ULL);
if (BaseAddr == -1ULL)
- BaseAddr = DieArray[0].getAttributeValueAsAddress(this, DW_AT_entry_pc, 0);
+ BaseAddr = UnitDie.getAttributeValueAsAddress(DW_AT_entry_pc, 0);
setBaseAddress(BaseAddr);
- AddrOffsetSectionBase = DieArray[0].getAttributeValueAsSectionOffset(
- this, DW_AT_GNU_addr_base, 0);
- RangeSectionBase = DieArray[0].getAttributeValueAsSectionOffset(
- this, DW_AT_rnglists_base, 0);
+ AddrOffsetSectionBase = UnitDie.getAttributeValueAsSectionOffset(
+ DW_AT_GNU_addr_base, 0);
+ RangeSectionBase = UnitDie.getAttributeValueAsSectionOffset(
+ DW_AT_rnglists_base, 0);
// Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for
// skeleton CU DIE, so that DWARF users not aware of it are not broken.
}
@@ -297,15 +290,15 @@ bool DWARFUnit::parseDWO() {
return false;
if (DWO.get())
return false;
- extractDIEsIfNeeded(true);
- if (DieArray.empty())
+ DWARFDie UnitDie = getUnitDIE();
+ if (!UnitDie)
return false;
const char *DWOFileName =
- DieArray[0].getAttributeValueAsString(this, DW_AT_GNU_dwo_name, nullptr);
+ UnitDie.getAttributeValueAsString(DW_AT_GNU_dwo_name, nullptr);
if (!DWOFileName)
return false;
const char *CompilationDir =
- DieArray[0].getAttributeValueAsString(this, DW_AT_comp_dir, nullptr);
+ UnitDie.getAttributeValueAsString(DW_AT_comp_dir, nullptr);
SmallString<16> AbsolutePath;
if (sys::path::is_relative(DWOFileName) && CompilationDir != nullptr) {
sys::path::append(AbsolutePath, CompilationDir);
@@ -320,7 +313,7 @@ bool DWARFUnit::parseDWO() {
}
// Share .debug_addr and .debug_ranges section with compile unit in .dwo
DWOCU->setAddrOffsetSection(AddrOffsetSection, AddrOffsetSectionBase);
- uint32_t DWORangesBase = DieArray[0].getRangesBaseAttribute(this, 0);
+ uint32_t DWORangesBase = UnitDie.getRangesBaseAttribute(0);
DWOCU->setRangesSection(RangeSection, DWORangesBase);
return true;
}
@@ -334,7 +327,7 @@ void DWARFUnit::clearDIEs(bool KeepCUDie) {
// contents which will cause just the internal pointers to be swapped
// so that when temporary vector goes out of scope, it will destroy the
// contents.
- std::vector<DWARFDebugInfoEntryMinimal> TmpArray;
+ std::vector<DWARFDebugInfoEntry> TmpArray;
DieArray.swap(TmpArray);
// Save at least the compile unit DIE
if (KeepCUDie)
@@ -343,11 +336,11 @@ void DWARFUnit::clearDIEs(bool KeepCUDie) {
}
void DWARFUnit::collectAddressRanges(DWARFAddressRangesVector &CURanges) {
- const auto *U = getUnitDIE();
- if (U == nullptr)
+ DWARFDie UnitDie = getUnitDIE();
+ if (!UnitDie)
return;
// First, check if unit DIE describes address ranges for the whole unit.
- const auto &CUDIERanges = U->getAddressRanges(this);
+ const auto &CUDIERanges = UnitDie.getAddressRanges();
if (!CUDIERanges.empty()) {
CURanges.insert(CURanges.end(), CUDIERanges.begin(), CUDIERanges.end());
return;
@@ -360,7 +353,7 @@ void DWARFUnit::collectAddressRanges(DWARFAddressRangesVector &CURanges) {
// up parsing the DWARF and then throwing them all away to keep memory usage
// down.
const bool ClearDIEs = extractDIEsIfNeeded(false) > 1;
- DieArray[0].collectChildrenAddressRanges(this, CURanges);
+ getUnitDIE().collectChildrenAddressRanges(CURanges);
// Collect address ranges from DIEs in .dwo if necessary.
bool DWOCreated = parseDWO();
@@ -375,36 +368,37 @@ void DWARFUnit::collectAddressRanges(DWARFAddressRangesVector &CURanges) {
clearDIEs(true);
}
-const DWARFDebugInfoEntryMinimal *
+DWARFDie
DWARFUnit::getSubprogramForAddress(uint64_t Address) {
extractDIEsIfNeeded(false);
- for (const DWARFDebugInfoEntryMinimal &DIE : DieArray) {
+ for (const DWARFDebugInfoEntry &D : DieArray) {
+ DWARFDie DIE(this, &D);
if (DIE.isSubprogramDIE() &&
- DIE.addressRangeContainsAddress(this, Address)) {
- return &DIE;
+ DIE.addressRangeContainsAddress(Address)) {
+ return DIE;
}
}
- return nullptr;
+ return DWARFDie();
}
-DWARFDebugInfoEntryInlinedChain
-DWARFUnit::getInlinedChainForAddress(uint64_t Address) {
+void
+DWARFUnit::getInlinedChainForAddress(uint64_t Address,
+ SmallVectorImpl<DWARFDie> &InlinedChain) {
// First, find a subprogram that contains the given address (the root
// of inlined chain).
- const DWARFUnit *ChainCU = nullptr;
- const DWARFDebugInfoEntryMinimal *SubprogramDIE;
+ DWARFDie SubprogramDIE;
// Try to look for subprogram DIEs in the DWO file.
parseDWO();
- if (DWO) {
- if ((SubprogramDIE = DWO->getUnit()->getSubprogramForAddress(Address)))
- ChainCU = DWO->getUnit();
- } else if ((SubprogramDIE = getSubprogramForAddress(Address)))
- ChainCU = this;
+ if (DWO)
+ SubprogramDIE = DWO->getUnit()->getSubprogramForAddress(Address);
+ else
+ SubprogramDIE = getSubprogramForAddress(Address);
// Get inlined chain rooted at this subprogram DIE.
- if (!SubprogramDIE)
- return DWARFDebugInfoEntryInlinedChain();
- return SubprogramDIE->getInlinedChainForAddress(ChainCU, Address);
+ if (SubprogramDIE)
+ SubprogramDIE.getInlinedChainForAddress(Address, InlinedChain);
+ else
+ InlinedChain.clear();
}
const DWARFUnitIndex &getDWARFUnitIndex(DWARFContext &Context,
OpenPOWER on IntegriCloud