diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h @@ -142,7 +142,8 @@ /// \returns Optional DWARF form value if the attribute was extracted. Optional<DWARFFormValue> getAttributeValue(const uint64_t DIEOffset, const dwarf::Attribute Attr, - const DWARFUnit &U) const; + const DWARFUnit &U, + uint64_t *OffsetPtr = 0) const; bool extract(DataExtractor Data, uint64_t* OffsetPtr); void dump(raw_ostream &OS) const; diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h @@ -350,6 +350,11 @@ /// into "SectionedAddress Address" DIEsForAddress getDIEsForAddress(uint64_t Address); + /// Get offset to an attribute value within a compile unit + /// or 0 if the attribute was not found. + Optional<uint64_t> getAttrFieldOffsetForUnit(DWARFUnit &U, + dwarf::Attribute Attr) const; + DILineInfo getLineInfoForAddress( object::SectionedAddress Address, DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override; diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h @@ -139,7 +139,8 @@ /// \param Attr the attribute to extract. /// \returns an optional DWARFFormValue that will have the form value if the /// attribute was successfully extracted. - Optional<DWARFFormValue> find(dwarf::Attribute Attr) const; + Optional<DWARFFormValue> find(dwarf::Attribute Attr, + uint64_t *OffsetPtr = 0) const; /// Extract the first value of any attribute in Attrs from this DIE. /// diff --git a/llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp b/llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp @@ -148,8 +148,8 @@ } Optional<DWARFFormValue> DWARFAbbreviationDeclaration::getAttributeValue( - const uint64_t DIEOffset, const dwarf::Attribute Attr, - const DWARFUnit &U) const { + const uint64_t DIEOffset, const dwarf::Attribute Attr, const DWARFUnit &U, + uint64_t *OffsetPtr) const { // Check if this abbreviation has this attribute without needing to skip // any data so we can return quickly if it doesn't. Optional<uint32_t> MatchAttrIndex = findAttributeIndex(Attr); @@ -170,6 +170,8 @@ &Offset, U.getFormParams()); // We have arrived at the attribute to extract, extract if from Offset. + if (OffsetPtr) + *OffsetPtr = Offset; const AttributeSpec &Spec = AttributeSpecs[*MatchAttrIndex]; if (Spec.isImplicitConst()) return DWARFFormValue::createFromSValue(Spec.Form, diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -1368,6 +1368,20 @@ return InliningInfo; } +Optional<uint64_t> +DWARFContext::getAttrFieldOffsetForUnit(DWARFUnit &U, + dwarf::Attribute Attr) const { + const DWARFDie UnitDIE = U.getUnitDIE(); + if (!UnitDIE) + return None; + + uint64_t Offset = 0; + if (!UnitDIE.find(Attr, &Offset)) + return None; + + return Offset; +} + std::shared_ptr<DWARFContext> DWARFContext::getDWOContext(StringRef AbsolutePath) { if (auto S = DWP.lock()) { diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp @@ -352,12 +352,13 @@ return Tag == DW_TAG_subprogram || Tag == DW_TAG_inlined_subroutine; } -Optional<DWARFFormValue> DWARFDie::find(dwarf::Attribute Attr) const { +Optional<DWARFFormValue> DWARFDie::find(dwarf::Attribute Attr, + uint64_t *OffsetPtr) const { if (!isValid()) return None; auto AbbrevDecl = getAbbreviationDeclarationPtr(); if (AbbrevDecl) - return AbbrevDecl->getAttributeValue(getOffset(), Attr, *U); + return AbbrevDecl->getAttributeValue(getOffset(), Attr, *U, OffsetPtr); return None; }