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 @@ -139,10 +139,12 @@ /// code in the .debug_info data. /// \param Attr DWARF attribute to search for. /// \param U the DWARFUnit the contains the DIE. + /// \param OffsetPtr stores the offset of the attribute. /// \returns Optional DWARF form value if the attribute was extracted. Optional 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 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 @@ -137,9 +137,11 @@ /// DW_AT_abstract_origin referenced DIEs. /// /// \param Attr the attribute to extract. + /// \param OffsetPtr if the attriube is found stores it's offset. /// \returns an optional DWARFFormValue that will have the form value if the /// attribute was successfully extracted. - Optional find(dwarf::Attribute Attr) const; + Optional 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 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 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 +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::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 DWARFDie::find(dwarf::Attribute Attr) const { +Optional 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; }