From 30c7cef157e9b52f8024d4b802aafa298964a3e9 Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Tue, 2 Jul 2024 14:10:35 +0000 Subject: [PATCH] [llvm/DWARF] Recursively resolve DW_AT_signature references findRecursively follows DW_AT_specification and DW_AT_abstract_origin references, but not DW_AT_signature. As far as I can tell, there is no fundamental difference between these attributes that would make this behavior desirable, and this just seems like a consequence of the fact that this attribute is newer. This patch aims to change that. The motivation is some code in lldb, which assumes that it can construct a qualified name of a type by just walking the parent chain and looking at the name attribute. This works for "regular" debug info, even when some of the DIEs are just forward declarations, but it breaks in the presence of type units, because of the need to explicitly resolve the signature reference. While LLDB does not use the llvm's DWARFDie class (yet?), this seems like a very important change in the overall API, and any divergance here would complicate eventual reunification, which is why I am making the change in the llvm API first. Nonetheless, I think this change is beneficial in llvm as well, as it allows us to remove the explicit DW_AT_signature resolution in the DWARFTypePrinter. --- llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h | 2 - llvm/lib/DebugInfo/DWARF/DWARFDie.cpp | 43 ++++++--------- llvm/lib/DebugInfo/DWARF/DWARFTypePrinter.cpp | 52 +++++++++---------- 3 files changed, 40 insertions(+), 57 deletions(-) diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h index 421b84d644db64..497d3bee048ab6 100644 --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h @@ -181,8 +181,6 @@ class DWARFDie { DWARFDie getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const; DWARFDie getAttributeValueAsReferencedDie(const DWARFFormValue &V) const; - DWARFDie resolveTypeUnitReference() const; - /// Extract the range base attribute from this DIE as absolute section offset. /// /// This is a utility function that checks for either the DW_AT_rnglists_base diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp index 410842a80b0151..2cc5b416fe1a20 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp @@ -103,10 +103,6 @@ static void dumpLocationExpr(raw_ostream &OS, const DWARFFormValue &FormValue, .print(OS, DumpOpts, U); } -static DWARFDie resolveReferencedType(DWARFDie D, DWARFFormValue F) { - return D.getAttributeValueAsReferencedDie(F).resolveTypeUnitReference(); -} - static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die, const DWARFAttribute &AttrValue, unsigned Indent, DIDumpOptions DumpOpts) { @@ -198,8 +194,8 @@ static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die, DINameKind::LinkageName)) OS << Space << "\"" << Name << '\"'; } else if (Attr == DW_AT_type || Attr == DW_AT_containing_type) { - DWARFDie D = resolveReferencedType(Die, FormValue); - if (D && !D.isNULL()) { + if (DWARFDie D = Die.getAttributeValueAsReferencedDie(FormValue); + D && !D.isNULL()) { OS << Space << "\""; dumpTypeQualifiedName(D, OS); OS << '"'; @@ -291,13 +287,12 @@ DWARFDie::findRecursively(ArrayRef Attrs) const { if (auto Value = Die.find(Attrs)) return Value; - if (auto D = Die.getAttributeValueAsReferencedDie(DW_AT_abstract_origin)) - if (Seen.insert(D).second) - Worklist.push_back(D); - - if (auto D = Die.getAttributeValueAsReferencedDie(DW_AT_specification)) - if (Seen.insert(D).second) - Worklist.push_back(D); + for (dwarf::Attribute Attr : + {DW_AT_abstract_origin, DW_AT_specification, DW_AT_signature}) { + if (auto D = Die.getAttributeValueAsReferencedDie(Attr)) + if (Seen.insert(D).second) + Worklist.push_back(D); + } } return std::nullopt; @@ -312,27 +307,19 @@ DWARFDie::getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const { DWARFDie DWARFDie::getAttributeValueAsReferencedDie(const DWARFFormValue &V) const { - DWARFDie Result; if (auto SpecRef = V.getAsRelativeReference()) { if (SpecRef->Unit) - Result = SpecRef->Unit->getDIEForOffset(SpecRef->Unit->getOffset() + - SpecRef->Offset); - else if (auto SpecUnit = - U->getUnitVector().getUnitForOffset(SpecRef->Offset)) - Result = SpecUnit->getDIEForOffset(SpecRef->Offset); - } - return Result; -} - -DWARFDie DWARFDie::resolveTypeUnitReference() const { - if (auto Attr = find(DW_AT_signature)) { - if (std::optional Sig = Attr->getAsReferenceUVal()) { + return SpecRef->Unit->getDIEForOffset(SpecRef->Unit->getOffset() + + SpecRef->Offset); + if (V.getForm() == dwarf::DW_FORM_ref_sig8) { if (DWARFTypeUnit *TU = U->getContext().getTypeUnitForHash( - U->getVersion(), *Sig, U->isDWOUnit())) + U->getVersion(), SpecRef->Offset, U->isDWOUnit())) return TU->getDIEForOffset(TU->getTypeOffset() + TU->getOffset()); } + if (auto *SpecUnit = U->getUnitVector().getUnitForOffset(SpecRef->Offset)) + return SpecUnit->getDIEForOffset(SpecRef->Offset); } - return *this; + return {}; } std::optional DWARFDie::getRangesBaseAttribute() const { diff --git a/llvm/lib/DebugInfo/DWARF/DWARFTypePrinter.cpp b/llvm/lib/DebugInfo/DWARF/DWARFTypePrinter.cpp index a26431e8313f69..fc1aae77a92937 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFTypePrinter.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFTypePrinter.cpp @@ -62,17 +62,10 @@ void DWARFTypePrinter::appendArrayType(const DWARFDie &D) { EndedWithTemplate = false; } -static DWARFDie resolveReferencedType(DWARFDie D, - dwarf::Attribute Attr = DW_AT_type) { - return D.getAttributeValueAsReferencedDie(Attr).resolveTypeUnitReference(); -} -static DWARFDie resolveReferencedType(DWARFDie D, DWARFFormValue F) { - return D.getAttributeValueAsReferencedDie(F).resolveTypeUnitReference(); -} DWARFDie DWARFTypePrinter::skipQualifiers(DWARFDie D) { while (D && (D.getTag() == DW_TAG_const_type || D.getTag() == DW_TAG_volatile_type)) - D = resolveReferencedType(D); + D = D.getAttributeValueAsReferencedDie(DW_AT_type); return D; } @@ -103,7 +96,9 @@ DWARFTypePrinter::appendUnqualifiedNameBefore(DWARFDie D, return DWARFDie(); } DWARFDie InnerDIE; - auto Inner = [&] { return InnerDIE = resolveReferencedType(D); }; + auto Inner = [&] { + return InnerDIE = D.getAttributeValueAsReferencedDie(DW_AT_type); + }; const dwarf::Tag T = D.getTag(); switch (T) { case DW_TAG_pointer_type: { @@ -134,7 +129,8 @@ DWARFTypePrinter::appendUnqualifiedNameBefore(DWARFDie D, OS << '('; else if (Word) OS << ' '; - if (DWARFDie Cont = resolveReferencedType(D, DW_AT_containing_type)) { + if (DWARFDie Cont = + D.getAttributeValueAsReferencedDie(DW_AT_containing_type)) { appendQualifiedName(Cont); EndedWithTemplate = false; OS << "::"; @@ -173,7 +169,8 @@ DWARFTypePrinter::appendUnqualifiedNameBefore(DWARFDie D, case DW_TAG_base_type: */ default: { - const char *NamePtr = dwarf::toString(D.find(DW_AT_name), nullptr); + const char *NamePtr = + dwarf::toString(D.findRecursively(DW_AT_name), nullptr); if (!NamePtr) { appendTypeTagName(D.getTag()); return DWARFDie(); @@ -235,9 +232,9 @@ void DWARFTypePrinter::appendUnqualifiedNameAfter( case DW_TAG_pointer_type: { if (needsParens(Inner)) OS << ')'; - appendUnqualifiedNameAfter(Inner, resolveReferencedType(Inner), - /*SkipFirstParamIfArtificial=*/D.getTag() == - DW_TAG_ptr_to_member_type); + appendUnqualifiedNameAfter( + Inner, Inner.getAttributeValueAsReferencedDie(DW_AT_type), + /*SkipFirstParamIfArtificial=*/D.getTag() == DW_TAG_ptr_to_member_type); break; } case DW_TAG_LLVM_ptrauth_type: { @@ -341,7 +338,7 @@ bool DWARFTypePrinter::appendTemplateParameters(DWARFDie D, appendTemplateParameters(C, FirstParameter); } if (C.getTag() == dwarf::DW_TAG_template_value_parameter) { - DWARFDie T = resolveReferencedType(C); + DWARFDie T = C.getAttributeValueAsReferencedDie(DW_AT_type); Sep(); if (T.getTag() == DW_TAG_enumeration_type) { OS << '('; @@ -461,7 +458,7 @@ bool DWARFTypePrinter::appendTemplateParameters(DWARFDie D, continue; auto TypeAttr = C.find(DW_AT_type); Sep(); - appendQualifiedName(TypeAttr ? resolveReferencedType(C, *TypeAttr) + appendQualifiedName(TypeAttr ? C.getAttributeValueAsReferencedDie(*TypeAttr) : DWARFDie()); } if (IsTemplate && *FirstParameter && FirstParameter == &FirstParameterValue) { @@ -473,15 +470,15 @@ bool DWARFTypePrinter::appendTemplateParameters(DWARFDie D, void DWARFTypePrinter::decomposeConstVolatile(DWARFDie &N, DWARFDie &T, DWARFDie &C, DWARFDie &V) { (N.getTag() == DW_TAG_const_type ? C : V) = N; - T = resolveReferencedType(N); + T = N.getAttributeValueAsReferencedDie(DW_AT_type); if (T) { auto Tag = T.getTag(); if (Tag == DW_TAG_const_type) { C = T; - T = resolveReferencedType(T); + T = T.getAttributeValueAsReferencedDie(DW_AT_type); } else if (Tag == DW_TAG_volatile_type) { V = T; - T = resolveReferencedType(T); + T = T.getAttributeValueAsReferencedDie(DW_AT_type); } } } @@ -491,10 +488,11 @@ void DWARFTypePrinter::appendConstVolatileQualifierAfter(DWARFDie N) { DWARFDie T; decomposeConstVolatile(N, T, C, V); if (T && T.getTag() == DW_TAG_subroutine_type) - appendSubroutineNameAfter(T, resolveReferencedType(T), false, C.isValid(), - V.isValid()); + appendSubroutineNameAfter(T, T.getAttributeValueAsReferencedDie(DW_AT_type), + false, C.isValid(), V.isValid()); else - appendUnqualifiedNameAfter(T, resolveReferencedType(T)); + appendUnqualifiedNameAfter(T, + T.getAttributeValueAsReferencedDie(DW_AT_type)); } void DWARFTypePrinter::appendConstVolatileQualifierBefore(DWARFDie N) { DWARFDie C; @@ -504,7 +502,7 @@ void DWARFTypePrinter::appendConstVolatileQualifierBefore(DWARFDie N) { bool Subroutine = T && T.getTag() == DW_TAG_subroutine_type; DWARFDie A = T; while (A && A.getTag() == DW_TAG_array_type) - A = resolveReferencedType(A); + A = A.getAttributeValueAsReferencedDie(DW_AT_type); bool Leading = (!A || (A.getTag() != DW_TAG_pointer_type && A.getTag() != llvm::dwarf::DW_TAG_ptr_to_member_type)) && @@ -546,7 +544,7 @@ void DWARFTypePrinter::appendSubroutineNameAfter( if (P.getTag() != DW_TAG_formal_parameter && P.getTag() != DW_TAG_unspecified_parameters) return; - DWARFDie T = resolveReferencedType(P); + DWARFDie T = P.getAttributeValueAsReferencedDie(DW_AT_type); if (SkipFirstParamIfArtificial && RealFirst && P.find(DW_AT_artificial)) { FirstParamIfArtificial = T; RealFirst = false; @@ -567,7 +565,7 @@ void DWARFTypePrinter::appendSubroutineNameAfter( if (DWARFDie P = FirstParamIfArtificial) { if (P.getTag() == DW_TAG_pointer_type) { auto CVStep = [&](DWARFDie CV) { - if (DWARFDie U = resolveReferencedType(CV)) { + if (DWARFDie U = CV.getAttributeValueAsReferencedDie(DW_AT_type)) { Const |= U.getTag() == DW_TAG_const_type; Volatile |= U.getTag() == DW_TAG_volatile_type; return U; @@ -653,7 +651,8 @@ void DWARFTypePrinter::appendSubroutineNameAfter( if (D.find(DW_AT_rvalue_reference)) OS << " &&"; - appendUnqualifiedNameAfter(Inner, resolveReferencedType(Inner)); + appendUnqualifiedNameAfter( + Inner, Inner.getAttributeValueAsReferencedDie(DW_AT_type)); } void DWARFTypePrinter::appendScopes(DWARFDie D) { if (D.getTag() == DW_TAG_compile_unit) @@ -666,7 +665,6 @@ void DWARFTypePrinter::appendScopes(DWARFDie D) { return; if (D.getTag() == DW_TAG_lexical_block) return; - D = D.resolveTypeUnitReference(); if (DWARFDie P = D.getParent()) appendScopes(P); appendUnqualifiedName(D);