Lines Matching +full:on +full:- +full:die

1 //=== DWARFLinker.cpp -----------------------------------------------------===//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
56 Size += Unit->getLength(); in getDebugInfoSize()
66 return LHS < RHS->getOrigUnit().getNextUnitOffset(); in getUnitForOffset()
68 return CU != Units.end() ? CU->get() : nullptr; in getUnitForOffset()
71 /// Resolve the DIE attribute reference that has been extracted in \p RefValue.
72 /// The resulting DIE might be in another CompileUnit which is stored into \p
77 const DWARFDie &DIE, in resolveDIEReference() argument
82 RefOffset = RefValue.getUnit()->getOffset() + *Off; in resolveDIEReference()
86 reportWarning("Unsupported reference type", File, &DIE); in resolveDIEReference()
90 if (const auto RefDie = RefCU->getOrigUnit().getDIEForOffset(RefOffset)) { in resolveDIEReference()
92 // DIE. in resolveDIEReference()
97 reportWarning("could not find referenced DIE", File, &DIE); in resolveDIEReference()
101 /// \returns whether the passed \a Attr type might contain a DIE reference
153 bool DWARFLinker::DIECloner::getDIENames(const DWARFDie &Die, in getDIENames() argument
157 // This function will be called on DIEs having low_pcs and in getDIENames()
160 if (Die.getTag() == dwarf::DW_TAG_lexical_block) in getDIENames()
164 if (const char *MangledName = Die.getLinkageName()) in getDIENames()
168 if (const char *Name = Die.getShortName()) in getDIENames()
192 const DWARFDie &DIE, CompileUnit &CU, in analyzeImportedModule() argument
201 StringRef Path = dwarf::toStringRef(DIE.find(dwarf::DW_AT_LLVM_include_path)); in analyzeImportedModule()
205 StringRef SysRoot = dwarf::toStringRef(DIE.find(dwarf::DW_AT_LLVM_sysroot)); in analyzeImportedModule()
218 dwarf::toString(DIE.find(dwarf::DW_AT_name)); in analyzeImportedModule()
231 DIE); in analyzeImportedModule()
245 /// but the Type and Die fields are optional based on the type.
247 DWARFDie Die; member
256 ContextWorklistItem(DWARFDie Die, ContextWorklistItemType T, in ContextWorklistItem()
258 : Die(Die), ParentIdx(0), OtherInfo(OtherInfo), Type(T), in ContextWorklistItem()
261 ContextWorklistItem(DWARFDie Die, DeclContext *Context, unsigned ParentIdx, in ContextWorklistItem()
263 : Die(Die), ParentIdx(ParentIdx), Context(Context), in ContextWorklistItem()
268 static bool updatePruning(const DWARFDie &Die, CompileUnit &CU, in updatePruning() argument
270 CompileUnit::DIEInfo &Info = CU.getInfo(Die); in updatePruning()
272 // Prune this DIE if it is either a forward declaration inside a in updatePruning()
275 Info.Prune &= (Die.getTag() == dwarf::DW_TAG_module) || in updatePruning()
276 (isTypeTag(Die.getTag()) && in updatePruning()
277 dwarf::toUnsigned(Die.find(dwarf::DW_AT_declaration), 0)); in updatePruning()
282 Info.Prune &= Info.Ctxt && Info.Ctxt->getCanonicalDIEOffset(); in updatePruning()
284 Info.Prune &= Info.Ctxt && Info.Ctxt->getCanonicalDIEOffset() > 0 && in updatePruning()
285 Info.Ctxt->getCanonicalDIEOffset() <= ModulesEndOffset; in updatePruning()
290 static void updateChildPruning(const DWARFDie &Die, CompileUnit &CU, in updateChildPruning() argument
292 CompileUnit::DIEInfo &Info = CU.getInfo(Die); in updateChildPruning()
297 /// gather the child->parent relationships in the original compile unit.
301 /// \return true when this DIE and all of its children are only
305 const DWARFDie &DIE, unsigned ParentIdx, CompileUnit &CU, in analyzeContextInfo() argument
312 Worklist.emplace_back(DIE, CurrentDeclContext, ParentIdx, false); in analyzeContextInfo()
320 updatePruning(Current.Die, CU, ModulesEndOffset); in analyzeContextInfo()
323 updateChildPruning(Current.Die, CU, *Current.OtherInfo); in analyzeContextInfo()
329 unsigned Idx = CU.getOrigUnit().getDIEIndex(Current.Die); in analyzeContextInfo()
332 // Clang imposes an ODR on modules(!) regardless of the language: in analyzeContextInfo()
333 // "The module-id should consist of only a single identifier, in analyzeContextInfo()
343 // We treat non-C++ modules like namespaces for this reason. in analyzeContextInfo()
344 if (Current.Die.getTag() == dwarf::DW_TAG_module && in analyzeContextInfo()
346 dwarf::toString(Current.Die.find(dwarf::DW_AT_name), "") != in analyzeContextInfo()
349 analyzeImportedModule(Current.Die, CU, ParseableSwiftInterfaces, in analyzeContextInfo()
358 *Current.Context, Current.Die, CU, Info.InModuleScope); in analyzeContextInfo()
363 Info.Ctxt->setDefinedInClangModule(Info.InModuleScope); in analyzeContextInfo()
371 Worklist.emplace_back(Current.Die, ContextWorklistItemType::UpdatePruning); in analyzeContextInfo()
372 for (auto Child : reverse(Current.Die.children())) { in analyzeContextInfo()
375 Current.Die, ContextWorklistItemType::UpdateChildPruning, &ChildInfo); in analyzeContextInfo()
402 I->~DIEBlock(); in cleanupAuxiliarryData()
404 I->~DIELoc(); in cleanupAuxiliarryData()
418 const DWARFDie &DIE) { in getVariableRelocAdjustment() argument
419 assert((DIE.getTag() == dwarf::DW_TAG_variable || in getVariableRelocAdjustment()
420 DIE.getTag() == dwarf::DW_TAG_constant) && in getVariableRelocAdjustment()
421 "Wrong type of input die"); in getVariableRelocAdjustment()
423 const auto *Abbrev = DIE.getAbbreviationDeclarationPtr(); in getVariableRelocAdjustment()
425 // Check if DIE has DW_AT_location attribute. in getVariableRelocAdjustment()
426 DWARFUnit *U = DIE.getDwarfUnit(); in getVariableRelocAdjustment()
428 Abbrev->findAttributeIndex(dwarf::DW_AT_location); in getVariableRelocAdjustment()
434 Abbrev->getAttributeOffsetFromIndex(*LocationIdx, DIE.getOffset(), *U); in getVariableRelocAdjustment()
438 Abbrev->getAttributeValueFromOffset(*LocationIdx, AttrOffset, *U); in getVariableRelocAdjustment()
445 std::optional<ArrayRef<uint8_t>> Expr = LocationValue->getAsBlock(); in getVariableRelocAdjustment()
450 DataExtractor Data(toStringRef(*Expr), U->getContext().isLittleEndian(), in getVariableRelocAdjustment()
451 U->getAddressByteSize()); in getVariableRelocAdjustment()
452 DWARFExpression Expression(Data, U->getAddressByteSize(), in getVariableRelocAdjustment()
453 U->getFormParams().Format); in getVariableRelocAdjustment()
470 if (NextIt == Expression.end() || !isTlsAddressCode(NextIt->getCode())) in getVariableRelocAdjustment()
486 DIE.getDwarfUnit()->getIndexedAddressOffset( in getVariableRelocAdjustment()
492 *AddressOffset + DIE.getDwarfUnit()->getAddressByteSize(), in getVariableRelocAdjustment()
507 /// Check if a variable describing DIE should be kept.
510 const DWARFDie &DIE, in shouldKeepVariableDIE() argument
513 const auto *Abbrev = DIE.getAbbreviationDeclarationPtr(); in shouldKeepVariableDIE()
517 Abbrev->findAttributeIndex(dwarf::DW_AT_const_value)) { in shouldKeepVariableDIE()
528 getVariableRelocAdjustment(RelocMgr, DIE); in shouldKeepVariableDIE()
544 outs() << "Keeping variable DIE:"; in shouldKeepVariableDIE()
548 DIE.dump(outs(), 8 /* Indent */, DumpOpts); in shouldKeepVariableDIE()
554 /// Check if a function describing DIE should be kept.
557 AddressesMap &RelocMgr, const DWARFDie &DIE, const DWARFFile &File, in shouldKeepSubprogramDIE() argument
561 auto LowPc = dwarf::toAddress(DIE.find(dwarf::DW_AT_low_pc)); in shouldKeepSubprogramDIE()
567 RelocMgr.getSubprogramRelocAdjustment(DIE, Options.Verbose); in shouldKeepSubprogramDIE()
575 outs() << "Keeping subprogram DIE:"; in shouldKeepSubprogramDIE()
579 DIE.dump(outs(), 8 /* Indent */, DumpOpts); in shouldKeepSubprogramDIE()
582 if (DIE.getTag() == dwarf::DW_TAG_label) { in shouldKeepSubprogramDIE()
587 // FIXME: dsymutil-classic compat. dsymutil-classic doesn't consider labels in shouldKeepSubprogramDIE()
600 std::optional<uint64_t> HighPc = DIE.getHighPC(*LowPc); in shouldKeepSubprogramDIE()
603 &DIE); in shouldKeepSubprogramDIE()
608 File, &DIE); in shouldKeepSubprogramDIE()
617 /// Check if a DIE should be kept.
619 unsigned DWARFLinker::shouldKeepDIE(AddressesMap &RelocMgr, const DWARFDie &DIE, in shouldKeepDIE() argument
623 switch (DIE.getTag()) { in shouldKeepDIE()
626 return shouldKeepVariableDIE(RelocMgr, DIE, MyInfo, Flags); in shouldKeepDIE()
629 return shouldKeepSubprogramDIE(RelocMgr, DIE, File, Unit, MyInfo, Flags); in shouldKeepDIE()
645 /// Helper that updates the completeness of the current DIE based on the
646 /// completeness of one of its children. It depends on the incompleteness of
648 static void updateChildIncompleteness(const DWARFDie &Die, CompileUnit &CU, in updateChildIncompleteness() argument
650 switch (Die.getTag()) { in updateChildIncompleteness()
659 CompileUnit::DIEInfo &MyInfo = CU.getInfo(Die); in updateChildIncompleteness()
665 /// Helper that updates the completeness of the current DIE based on the
666 /// completeness of the DIEs it references. It depends on the incompleteness of
667 /// the referenced DIE already being computed.
668 static void updateRefIncompleteness(const DWARFDie &Die, CompileUnit &CU, in updateRefIncompleteness() argument
670 switch (Die.getTag()) { in updateRefIncompleteness()
681 CompileUnit::DIEInfo &MyInfo = CU.getInfo(Die); in updateRefIncompleteness()
690 /// Look at the children of the given DIE and decide whether they should be
693 const DWARFDie &Die, CompileUnit &CU, unsigned Flags, in lookForChildDIEsToKeep() argument
696 // parent chain of a required DIE, and we don't want to mark all the children in lookForChildDIEsToKeep()
698 // the parent chain). There are however a set of DIE types for which we want in lookForChildDIEsToKeep()
700 if (dieNeedsChildrenToBeMeaningful(Die.getTag())) in lookForChildDIEsToKeep()
703 // We're finished if this DIE has no children or we're walking the parent in lookForChildDIEsToKeep()
705 if (!Die.hasChildren() || (Flags & DWARFLinker::TF_ParentWalk)) in lookForChildDIEsToKeep()
710 for (auto Child : reverse(Die.children())) { in lookForChildDIEsToKeep()
714 Worklist.emplace_back(Die, CU, WorklistItemType::UpdateChildIncompleteness, in lookForChildDIEsToKeep()
720 static bool isODRCanonicalCandidate(const DWARFDie &Die, CompileUnit &CU) { in isODRCanonicalCandidate() argument
721 CompileUnit::DIEInfo &Info = CU.getInfo(Die); in isODRCanonicalCandidate()
723 if (!Info.Ctxt || (Die.getTag() == dwarf::DW_TAG_namespace)) in isODRCanonicalCandidate()
732 void DWARFLinker::markODRCanonicalDie(const DWARFDie &Die, CompileUnit &CU) { in markODRCanonicalDie() argument
733 CompileUnit::DIEInfo &Info = CU.getInfo(Die); in markODRCanonicalDie()
736 if (Info.Keep && isODRCanonicalCandidate(Die, CU) && in markODRCanonicalDie()
737 !Info.Ctxt->hasCanonicalDIE()) in markODRCanonicalDie()
738 Info.Ctxt->setHasCanonicalDIE(); in markODRCanonicalDie()
741 /// Look at DIEs referenced by the given DIE and decide whether they should be
744 const DWARFDie &Die, CompileUnit &CU, unsigned Flags, in lookForRefDIEsToKeep() argument
752 const auto *Abbrev = Die.getAbbreviationDeclarationPtr(); in lookForRefDIEsToKeep()
753 uint64_t Offset = Die.getOffset() + getULEB128Size(Abbrev->getCode()); in lookForRefDIEsToKeep()
756 for (const auto &AttrSpec : Abbrev->attributes()) { in lookForRefDIEsToKeep()
768 resolveDIEReference(File, Units, Val, Die, ReferencedCU)) { in lookForRefDIEsToKeep()
769 CompileUnit::DIEInfo &Info = ReferencedCU->getInfo(RefDie); in lookForRefDIEsToKeep()
770 // If the referenced DIE has a DeclContext that has already been in lookForRefDIEsToKeep()
772 // the canonical DIE in cloneDieReferenceAttribute. in lookForRefDIEsToKeep()
774 // FIXME: compatibility with dsymutil-classic. UseODR shouldn't in lookForRefDIEsToKeep()
776 // ReferencedCU->hasODR() && CU.hasODR(). in lookForRefDIEsToKeep()
778 // FIXME: compatibility with dsymutil-classic. There is no in lookForRefDIEsToKeep()
782 Info.Ctxt->hasCanonicalDIE()) in lookForRefDIEsToKeep()
787 Info.Ctxt->hasCanonicalDIE())) in lookForRefDIEsToKeep()
801 Worklist.emplace_back(Die, CU, WorklistItemType::UpdateRefIncompleteness, in lookForRefDIEsToKeep()
809 /// Look at the parent of the given DIE and decide whether they should be kept.
823 /// Recursively walk the \p DIE tree and look for DIEs to keep. Store that
826 /// This function is the entry point of the DIE selection algorithm. It is
827 /// expected to walk the DIE tree in file order and (though the mediation of
828 /// its helper) call hasValidRelocation() on each DIE that might be a 'root
829 /// DIE' (See DwarfLinker class comment).
847 /// The return value indicates whether the DIE is incomplete.
850 const DWARFDie &Die, const DWARFFile &File, in lookForDIEsToKeep() argument
854 Worklist.emplace_back(Die, Cu, Flags); in lookForDIEsToKeep()
862 updateChildIncompleteness(Current.Die, Current.CU, *Current.OtherInfo); in lookForDIEsToKeep()
865 updateRefIncompleteness(Current.Die, Current.CU, *Current.OtherInfo); in lookForDIEsToKeep()
868 lookForChildDIEsToKeep(Current.Die, Current.CU, Current.Flags, Worklist); in lookForDIEsToKeep()
871 lookForRefDIEsToKeep(Current.Die, Current.CU, Current.Flags, Units, File, in lookForDIEsToKeep()
879 markODRCanonicalDie(Current.Die, Current.CU); in lookForDIEsToKeep()
885 unsigned Idx = Current.CU.getOrigUnit().getDIEIndex(Current.Die); in lookForDIEsToKeep()
897 // If the Keep flag is set, we are marking a required DIE's dependencies. in lookForDIEsToKeep()
904 Current.Flags = shouldKeepDIE(AddressesMap, Current.Die, File, Current.CU, in lookForDIEsToKeep()
907 // We need to mark context for the canonical die in the end of normal in lookForDIEsToKeep()
908 // traversing(not TF_DependencyWalk) or after normal traversing if die in lookForDIEsToKeep()
913 Worklist.emplace_back(Current.Die, Current.CU, in lookForDIEsToKeep()
920 Worklist.emplace_back(Current.Die, Current.CU, Current.Flags, in lookForDIEsToKeep()
926 // If it is a newly kept DIE mark it as well as all its dependencies as in lookForDIEsToKeep()
932 Current.Die.getTag() != dwarf::DW_TAG_subprogram && in lookForDIEsToKeep()
933 Current.Die.getTag() != dwarf::DW_TAG_member && in lookForDIEsToKeep()
934 dwarf::toUnsigned(Current.Die.find(dwarf::DW_AT_declaration), 0); in lookForDIEsToKeep()
939 Worklist.emplace_back(Current.Die, Current.CU, Current.Flags, in lookForDIEsToKeep()
1020 Abbrev.setNumber(InSet->getNumber()); in assignAbbrev()
1026 Abbreviations.back()->AddAttribute(Attr); in assignAbbrev()
1030 Abbreviations.back()->setNumber(Abbreviations.size()); in assignAbbrev()
1034 unsigned DWARFLinker::DIECloner::cloneStringAttribute(DIE &Die, in cloneStringAttribute() argument
1051 ObjFile.Addresses->getLibraryInstallName()) { in cloneStringAttribute()
1066 return Die in cloneStringAttribute()
1069 ->sizeOf(U.getFormParams()); in cloneStringAttribute()
1074 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr), AttrSpec.Form, in cloneStringAttribute()
1080 DIE &Die, const DWARFDie &InputDIE, AttributeSpec AttrSpec, in cloneDieReferenceAttribute() argument
1086 Ref = Val.getUnit()->getOffset() + *Off; in cloneDieReferenceAttribute()
1092 DIE *NewRefDie = nullptr; in cloneDieReferenceAttribute()
1098 // If the referenced DIE is not found, drop the attribute. in cloneDieReferenceAttribute()
1102 CompileUnit::DIEInfo &RefInfo = RefUnit->getInfo(RefDie); in cloneDieReferenceAttribute()
1107 RefInfo.Ctxt->getCanonicalDIEOffset()) { in cloneDieReferenceAttribute()
1108 assert(RefInfo.Ctxt->hasCanonicalDIE() && in cloneDieReferenceAttribute()
1109 "Offset to canonical die is set, but context is not marked"); in cloneDieReferenceAttribute()
1110 DIEInteger Attr(RefInfo.Ctxt->getCanonicalDIEOffset()); in cloneDieReferenceAttribute()
1111 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr), in cloneDieReferenceAttribute()
1117 // We haven't cloned this DIE yet. Just create an empty one and in cloneDieReferenceAttribute()
1120 RefInfo.Clone = DIE::get(DIEAlloc, dwarf::Tag(RefDie.getTag())); in cloneDieReferenceAttribute()
1126 // We cannot currently rely on a DIEEntry to emit ref_addr in cloneDieReferenceAttribute()
1129 // FIXME: we should be able to design DIEEntry reliance on in cloneDieReferenceAttribute()
1133 // We have already cloned that DIE. in cloneDieReferenceAttribute()
1135 RefUnit->getStartOffset() + NewRefDie->getOffset(); in cloneDieReferenceAttribute()
1137 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr), in cloneDieReferenceAttribute()
1144 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr), in cloneDieReferenceAttribute()
1150 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr), in cloneDieReferenceAttribute()
1167 // DW_OP_const_type is variable-length and has 3 in cloneExpression()
1177 // This code assumes that the other non-typeref operand fits into 1 byte. in cloneExpression()
1179 uint32_t ULEBsize = Op.getEndOffset() - OpOffset - 1; in cloneExpression()
1200 if (DIE *Clone = Info.Clone) in cloneExpression()
1201 Offset = Clone->getOffset(); in cloneExpression()
1225 uint64_t LinkedAddress = SA->Address + AddrRelocAdjustment; in cloneExpression()
1259 uint64_t LinkedAddress = SA->Address + AddrRelocAdjustment; in cloneExpression()
1279 DIE &Die, const DWARFDie &InputDIE, const DWARFFile &File, in cloneBlockAttribute() argument
1313 Attr->addValue(DIEAlloc, static_cast<dwarf::Attribute>(0), in cloneBlockAttribute()
1317 // the DIE class, this "if" could be replaced by in cloneBlockAttribute()
1318 // Attr->setSize(Bytes.size()). in cloneBlockAttribute()
1320 Loc->setSize(Bytes.size()); in cloneBlockAttribute()
1322 Block->setSize(Bytes.size()); in cloneBlockAttribute()
1341 return Die.addValue(DIEAlloc, Value)->sizeOf(OrigUnit.getFormParams()); in cloneBlockAttribute()
1345 DIE &Die, const DWARFDie &InputDIE, AttributeSpec AttrSpec, in cloneAddressAttribute() argument
1352 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr), in cloneAddressAttribute()
1357 // Cloned Die may have address attributes relocated to a in cloneAddressAttribute()
1359 // - If high_pc is an address (Dwarf version == 2), then it might have been in cloneAddressAttribute()
1363 // - If address relocated in an inline_subprogram that happens at the in cloneAddressAttribute()
1373 std::optional<uint64_t> Addr = AddrAttribute->getAsAddress(); in cloneAddressAttribute()
1396 Die.addValue(DIEAlloc, static_cast<dwarf::Attribute>(AttrSpec.Attr), in cloneAddressAttribute()
1403 return Die in cloneAddressAttribute()
1406 ->sizeOf(Unit.getOrigUnit().getFormParams()); in cloneAddressAttribute()
1410 DIE &Die, const DWARFDie &InputDIE, const DWARFFile &File, in cloneScalarAttribute() argument
1419 const llvm::DWARFDebugMacro *Macro = File.Dwarf->getDebugMacinfo(); in cloneScalarAttribute()
1420 if (Macro == nullptr || !Macro->hasEntryForOffset(*Offset)) in cloneScalarAttribute()
1427 const llvm::DWARFDebugMacro *Macro = File.Dwarf->getDebugMacro(); in cloneScalarAttribute()
1428 if (Macro == nullptr || !Macro->hasEntryForOffset(*Offset)) in cloneScalarAttribute()
1435 // compile units. The offset to the common .debug_str_offsets table is 8 on in cloneScalarAttribute()
1438 return Die in cloneScalarAttribute()
1441 ->sizeOf(Unit.getOrigUnit().getFormParams()); in cloneScalarAttribute()
1461 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr), in cloneScalarAttribute()
1464 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr), in cloneScalarAttribute()
1513 Die.getTag() == dwarf::DW_TAG_compile_unit) { in cloneScalarAttribute()
1518 Value = Unit.getHighPc() - *LowPC; in cloneScalarAttribute()
1532 DIE::value_iterator Patch = in cloneScalarAttribute()
1533 Die.addValue(DIEAlloc, dwarf::Attribute(AttrSpec.Attr), in cloneScalarAttribute()
1537 Unit.noteRangeAttribute(Die, Patch); in cloneScalarAttribute()
1559 /// value \p Val, and add it to \p Die.
1562 DIE &Die, const DWARFDie &InputDIE, const DWARFFile &File, in cloneAttribute() argument
1576 return cloneStringAttribute(Die, AttrSpec, Val, U, Info); in cloneAttribute()
1582 return cloneDieReferenceAttribute(Die, InputDIE, AttrSpec, AttrSize, Val, in cloneAttribute()
1589 return cloneBlockAttribute(Die, InputDIE, File, Unit, AttrSpec, Val, in cloneAttribute()
1597 return cloneAddressAttribute(Die, InputDIE, AttrSpec, AttrSize, Val, Unit, in cloneAttribute()
1611 return cloneScalarAttribute(Die, InputDIE, File, Unit, AttrSpec, Val, in cloneAttribute()
1624 const DIE *Die, in addObjCAccelerator() argument
1632 Unit.addNameAccelerator(Die, StringPool.getEntry(Names->Selector), in addObjCAccelerator()
1634 Unit.addObjCAccelerator(Die, StringPool.getEntry(Names->ClassName), in addObjCAccelerator()
1636 if (Names->ClassNameNoCategory) in addObjCAccelerator()
1638 Die, StringPool.getEntry(*Names->ClassNameNoCategory), SkipPubSection); in addObjCAccelerator()
1639 if (Names->MethodNameNoCategory) in addObjCAccelerator()
1641 Die, StringPool.getEntry(*Names->MethodNameNoCategory), SkipPubSection); in addObjCAccelerator()
1679 DIE *DWARFLinker::DIECloner::cloneDIE(const DWARFDie &InputDIE, in cloneDIE()
1683 DIE *Die) { in cloneDIE() argument
1688 // Should the DIE appear in the output? in cloneDIE()
1693 assert(!(Die && Info.Clone) && "Can't supply a DIE and a cloned DIE"); in cloneDIE()
1694 if (!Die) { in cloneDIE()
1695 // The DIE might have been already created by a forward reference in cloneDIE()
1698 Info.Clone = DIE::get(DIEAlloc, dwarf::Tag(InputDIE.getTag())); in cloneDIE()
1699 Die = Info.Clone; in cloneDIE()
1702 assert(Die->getTag() == InputDIE.getTag()); in cloneDIE()
1703 Die->setOffset(OutOffset); in cloneDIE()
1705 (Info.Ctxt->getCanonicalDIEOffset() == 0)) { in cloneDIE()
1706 if (!Info.Ctxt->hasCanonicalDIE()) in cloneDIE()
1707 Info.Ctxt->setHasCanonicalDIE(); in cloneDIE()
1708 // We are about to emit a DIE that is the root of its own valid in cloneDIE()
1711 Info.Ctxt->setCanonicalDIEOffset(OutOffset + Unit.getStartOffset()); in cloneDIE()
1716 // Point to the next DIE (generally there is always at least a NULL in cloneDIE()
1727 SmallString<40> DIECopy(Data.getData().substr(Offset, NextOffset - Offset)); in cloneDIE()
1732 ObjFile.Addresses->applyValidRelocs(DIECopy, Offset, Data.isLittleEndian()); in cloneDIE()
1734 // Reset the Offset to 0 as we will be working on the local copy of in cloneDIE()
1739 Offset += getULEB128Size(Abbrev->getCode()); in cloneDIE()
1742 if (Die->getTag() == dwarf::DW_TAG_subprogram) in cloneDIE()
1746 if (Abbrev->getTag() == dwarf::DW_TAG_subprogram) { in cloneDIE()
1750 } else if (Abbrev->getTag() == dwarf::DW_TAG_variable) { in cloneDIE()
1751 // Function-local globals could be in the debug map even when the function in cloneDIE()
1763 ObjFile.Addresses->getLibraryInstallName(); in cloneDIE()
1765 for (const auto &AttrSpec : Abbrev->attributes()) { in cloneDIE()
1775 Unit.getStartOffset() + OutOffset - CurAttrFixup.InputAttrStartOffset; in cloneDIE()
1781 AttrSize = Offset - AttrSize; in cloneDIE()
1784 cloneAttribute(*Die, InputDIE, File, Unit, Val, AttrSpec, AttrSize, in cloneDIE()
1786 if (FinalAttrSize != 0 && ObjFile.Addresses->needToSaveValidRelocs()) in cloneDIE()
1793 // Add the DW_AT_APPLE_origin attribute to Compile Unit die if we have in cloneDIE()
1800 Die->addValue(DIEAlloc, dwarf::Attribute(dwarf::DW_AT_APPLE_origin), in cloneDIE()
1815 Unit.addNameAccelerator(Die, AttrInfo.MangledName, in cloneDIE()
1819 Unit.addNameAccelerator(Die, AttrInfo.NameWithoutTemplate, in cloneDIE()
1821 Unit.addNameAccelerator(Die, AttrInfo.Name, in cloneDIE()
1825 addObjCAccelerator(Unit, Die, AttrInfo.Name, DebugStrPool, in cloneDIE()
1831 Unit.addNamespaceAccelerator(Die, AttrInfo.Name); in cloneDIE()
1833 Unit.addNamespaceAccelerator(Die, AttrInfo.Name); in cloneDIE()
1846 Unit.addTypeAccelerator(Die, AttrInfo.Name, ObjCClassIsImplementation, in cloneDIE()
1861 Die->getTag() == dwarf::DW_TAG_compile_unit) { in cloneDIE()
1862 // No DW_AT_str_offsets_base seen, add it to the DIE. in cloneDIE()
1863 Die->addValue(DIEAlloc, dwarf::DW_AT_str_offsets_base, in cloneDIE()
1868 DIEAbbrev NewAbbrev = Die->generateAbbrev(); in cloneDIE()
1873 Die->setAbbrevNumber(NewAbbrev.getNumber()); in cloneDIE()
1875 uint64_t AbbrevNumberSize = getULEB128Size(Die->getAbbrevNumber()); in cloneDIE()
1885 ObjFile.Addresses->updateAndSaveValidRelocs( in cloneDIE()
1891 Die->setSize(OutOffset - Die->getOffset()); in cloneDIE()
1892 return Die; in cloneDIE()
1897 if (DIE *Clone = cloneDIE(Child, File, Unit, PCOffset, OutOffset, Flags, in cloneDIE()
1899 Die->addChild(Clone); in cloneDIE()
1900 OutOffset = Clone->getOffset() + Clone->getSize(); in cloneDIE()
1907 Die->setSize(OutOffset - Die->getOffset()); in cloneDIE()
1908 return Die; in cloneDIE()
1929 TheDwarfEmitter->emitDwarfDebugArangesTable(Unit, LinkedFunctionRanges); in generateUnitRanges()
1937 MCSymbol *EndLabel = TheDwarfEmitter->emitDwarfDebugRangeListHeader(Unit); in generateUnitRanges()
1949 if (!CachedRange || !CachedRange->Range.contains(Range.LowPC)) in generateUnitRanges()
1959 LinkedRanges.insert({Range.LowPC + CachedRange->Value, in generateUnitRanges()
1960 Range.HighPC + CachedRange->Value}); in generateUnitRanges()
1968 TheDwarfEmitter->emitDwarfDebugRangeListFragment( in generateUnitRanges()
1974 TheDwarfEmitter->emitDwarfDebugRangeListFragment( in generateUnitRanges()
1978 TheDwarfEmitter->emitDwarfDebugRangeListFooter(Unit, EndLabel); in generateUnitRanges()
1995 MCSymbol *EndLabel = Emitter->emitDwarfDebugLocListHeader(Unit); in generateUnitLocations()
2016 CurExpression.Range->LowPC + CurLocAttr.RelocAdjustment, in generateUnitLocations()
2017 CurExpression.Range->HighPC + CurLocAttr.RelocAdjustment}; in generateUnitLocations()
2029 Emitter->emitDwarfDebugLocListFragment(Unit, LinkedLocationExpressions, in generateUnitLocations()
2034 Emitter->emitDwarfDebugLocListFooter(Unit, EndLabel); in generateUnitLocations()
2037 static void patchAddrBase(DIE &Die, DIEInteger Offset) { in patchAddrBase() argument
2038 for (auto &V : Die.values()) in patchAddrBase()
2044 llvm_unreachable("Didn't find a DW_AT_addr_base in cloned DIE!"); in patchAddrBase()
2059 MCSymbol *EndLabel = Emitter->emitDwarfDebugAddrsHeader(Unit); in emitDebugAddrSection()
2061 DIEInteger(Emitter->getDebugAddrSectionSize())); in emitDebugAddrSection()
2062 Emitter->emitDwarfDebugAddrs(AddrPool.getValues(), in emitDebugAddrSection()
2064 Emitter->emitDwarfDebugAddrsFooter(Unit, EndLabel); in emitDebugAddrSection()
2088 if (InsertPoint != Rows.end() && InsertPoint->Address == Front && in insertLineSequence()
2089 InsertPoint->EndSequence) { in insertLineSequence()
2099 static void patchStmtList(DIE &Die, DIEInteger Offset) { in patchStmtList() argument
2100 for (auto &V : Die.values()) in patchStmtList()
2106 llvm_unreachable("Didn't find DW_AT_stmt_list in cloned DIE!"); in patchStmtList()
2138 patchStmtList(*OutputDIE, DIEInteger(Emitter->getLineSectionSize())); in generateLineTableForUnit()
2141 ObjFile.Dwarf->getLineTableForUnit(&Unit.getOrigUnit())) { in generateLineTableForUnit()
2146 LineTable.Prologue = LT->Prologue; in generateLineTableForUnit()
2150 LineTable.Rows = LT->Rows; in generateLineTableForUnit()
2156 LineTable.Sequences = LT->Sequences; in generateLineTableForUnit()
2160 NewRows.reserve(LT->Rows.size()); in generateLineTableForUnit()
2180 for (DWARFDebugLine::Row Row : LT->Rows) { in generateLineTableForUnit()
2182 // half-open, but consider accept the end address of the range if in generateLineTableForUnit()
2186 if (!CurrRange || !CurrRange->Range.contains(Row.Address.Address)) { in generateLineTableForUnit()
2190 CurrRange ? CurrRange->Range.end() + CurrRange->Value : -1ULL; in generateLineTableForUnit()
2192 if (StopAddress != -1ULL && !Seq.empty()) { in generateLineTableForUnit()
2214 Row.Address.Address += CurrRange->Value; in generateLineTableForUnit()
2224 Emitter->emitLineTableForUnit(LineTable, Unit, DebugStrPool, in generateLineTableForUnit()
2236 AppleNamespaces.addName(Namespace.Name, Namespace.Die->getOffset() + in emitAcceleratorEntriesForUnit()
2241 Pubname.Die->getOffset() + Unit.getStartOffset()); in emitAcceleratorEntriesForUnit()
2245 Pubtype.Name, Pubtype.Die->getOffset() + Unit.getStartOffset(), in emitAcceleratorEntriesForUnit()
2246 Pubtype.Die->getTag(), in emitAcceleratorEntriesForUnit()
2253 ObjC.Die->getOffset() + Unit.getStartOffset()); in emitAcceleratorEntriesForUnit()
2256 TheDwarfEmitter->emitPubNamesForUnit(Unit); in emitAcceleratorEntriesForUnit()
2257 TheDwarfEmitter->emitPubTypesForUnit(Unit); in emitAcceleratorEntriesForUnit()
2262 Namespace.Name, Namespace.Die->getOffset(), in emitAcceleratorEntriesForUnit()
2263 DWARF5AccelTableData::getDefiningParentDieOffset(*Namespace.Die), in emitAcceleratorEntriesForUnit()
2264 Namespace.Die->getTag(), Unit.getUniqueID(), in emitAcceleratorEntriesForUnit()
2268 Pubname.Name, Pubname.Die->getOffset(), in emitAcceleratorEntriesForUnit()
2269 DWARF5AccelTableData::getDefiningParentDieOffset(*Pubname.Die), in emitAcceleratorEntriesForUnit()
2270 Pubname.Die->getTag(), Unit.getUniqueID(), in emitAcceleratorEntriesForUnit()
2274 Pubtype.Name, Pubtype.Die->getOffset(), in emitAcceleratorEntriesForUnit()
2275 DWARF5AccelTableData::getDefiningParentDieOffset(*Pubtype.Die), in emitAcceleratorEntriesForUnit()
2276 Pubtype.Die->getTag(), Unit.getUniqueID(), in emitAcceleratorEntriesForUnit()
2299 for (auto CurRange : Unit->getFunctionRanges()) in patchFrameInfoForObject()
2321 // The -4 is to account for the CIEId we just read. in patchFrameInfoForObject()
2322 InputOffset += InitialLength - 4; in patchFrameInfoForObject()
2350 std::make_pair(CIEData, TheDwarfEmitter->getFrameSectionSize())); in patchFrameInfoForObject()
2353 LastCIEOffset = TheDwarfEmitter->getFrameSectionSize(); in patchFrameInfoForObject()
2354 IteratorInserted.first->getValue() = LastCIEOffset; in patchFrameInfoForObject()
2355 TheDwarfEmitter->emitCIE(CIEData); in patchFrameInfoForObject()
2361 unsigned FDERemainingBytes = InitialLength - (4 + SrcAddrSize); in patchFrameInfoForObject()
2362 TheDwarfEmitter->emitFDE(IteratorInserted.first->getValue(), SrcAddrSize, in patchFrameInfoForObject()
2363 Loc + Range->Value, in patchFrameInfoForObject()
2369 uint32_t DWARFLinker::DIECloner::hashFullyQualifiedName(DWARFDie DIE, in hashFullyQualifiedName() argument
2379 if (const char *CurrentName = DIE.getName(DINameKind::ShortName)) in hashFullyQualifiedName()
2382 if (!(Ref = DIE.find(dwarf::DW_AT_specification)) && in hashFullyQualifiedName()
2383 !(Ref = DIE.find(dwarf::DW_AT_abstract_origin))) in hashFullyQualifiedName()
2386 if (!Ref->isFormClass(DWARFFormValue::FC_Reference)) in hashFullyQualifiedName()
2391 Linker.resolveDIEReference(File, CompileUnits, *Ref, DIE, RefCU)) { in hashFullyQualifiedName()
2393 OrigUnit = &RefCU->getOrigUnit(); in hashFullyQualifiedName()
2394 DIE = RefDIE; in hashFullyQualifiedName()
2398 unsigned Idx = OrigUnit->getDIEIndex(DIE); in hashFullyQualifiedName()
2399 if (!Name && DIE.getTag() == dwarf::DW_TAG_namespace) in hashFullyQualifiedName()
2402 if (CU->getInfo(Idx).ParentIdx == 0 || in hashFullyQualifiedName()
2403 // FIXME: dsymutil-classic compatibility. Ignore modules. in hashFullyQualifiedName()
2404 CU->getOrigUnit().getDIEAtIndex(CU->getInfo(Idx).ParentIdx).getTag() == in hashFullyQualifiedName()
2408 DWARFDie Die = OrigUnit->getDIEAtIndex(CU->getInfo(Idx).ParentIdx); in hashFullyQualifiedName() local
2412 hashFullyQualifiedName(Die, *CU, File, ++ChildRecurseDepth))); in hashFullyQualifiedName()
2480 if (!Quiet && Options.Verbose && (Cached->second != DwoId)) in isClangModuleRef()
2535 // Don't use the cached binary holder because we have no thread-safety in loadClangModule()
2549 for (const auto &CU : ErrOrObj->Dwarf->compile_units()) { in loadClangModule()
2552 auto ChildCUDie = CU->getUnitDIE(); in loadClangModule()
2594 (Emitter == nullptr) ? 0 : Emitter->getDebugInfoSectionSize(); in cloneAllCompileUnits()
2598 const uint16_t DwarfVersion = CurrentUnit->getOrigUnit().getVersion(); in cloneAllCompileUnits()
2600 auto InputDIE = CurrentUnit->getOrigUnit().getUnitDIE(); in cloneAllCompileUnits()
2601 CurrentUnit->setStartOffset(OutputDebugInfoSize); in cloneAllCompileUnits()
2603 OutputDebugInfoSize = CurrentUnit->computeNextUnitOffset(DwarfVersion); in cloneAllCompileUnits()
2606 if (CurrentUnit->getInfo(0).Keep) { in cloneAllCompileUnits()
2607 // Clone the InputDIE into your Unit DIE in our compile unit since it in cloneAllCompileUnits()
2608 // already has a DIE inside of it. in cloneAllCompileUnits()
2609 CurrentUnit->createOutputDIE(); in cloneAllCompileUnits()
2612 0, IsLittleEndian, CurrentUnit->getOutputUnitDIE()); in cloneAllCompileUnits()
2615 OutputDebugInfoSize = CurrentUnit->computeNextUnitOffset(DwarfVersion); in cloneAllCompileUnits()
2631 DWARFUnit &OrigUnit = CurrentUnit->getOrigUnit(); in cloneAllCompileUnits()
2649 Emitter->emitMacroTables(File.Dwarf.get(), UnitMacroMap, DebugStrPool); in cloneAllCompileUnits()
2653 CurrentUnit->fixupForwardReferences(); in cloneAllCompileUnits()
2655 if (!CurrentUnit->getOutputUnitDIE()) in cloneAllCompileUnits()
2658 unsigned DwarfVersion = CurrentUnit->getOrigUnit().getVersion(); in cloneAllCompileUnits()
2660 assert(Emitter->getDebugInfoSectionSize() == in cloneAllCompileUnits()
2661 CurrentUnit->getStartOffset()); in cloneAllCompileUnits()
2662 Emitter->emitCompileUnitHeader(*CurrentUnit, DwarfVersion); in cloneAllCompileUnits()
2663 Emitter->emitDIE(*CurrentUnit->getOutputUnitDIE()); in cloneAllCompileUnits()
2664 assert(Emitter->getDebugInfoSectionSize() == in cloneAllCompileUnits()
2665 CurrentUnit->computeNextUnitOffset(DwarfVersion)); in cloneAllCompileUnits()
2669 return OutputDebugInfoSize - StartOutputDebugInfoSize; in cloneAllCompileUnits()
2673 TheDwarfEmitter->emitSectionContents(Dwarf.getDWARFObj().getLocSection().Data, in copyInvariantDebugSection()
2675 TheDwarfEmitter->emitSectionContents( in copyInvariantDebugSection()
2678 TheDwarfEmitter->emitSectionContents( in copyInvariantDebugSection()
2680 TheDwarfEmitter->emitSectionContents(Dwarf.getDWARFObj().getArangesSection(), in copyInvariantDebugSection()
2682 TheDwarfEmitter->emitSectionContents( in copyInvariantDebugSection()
2684 TheDwarfEmitter->emitSectionContents( in copyInvariantDebugSection()
2687 TheDwarfEmitter->emitSectionContents( in copyInvariantDebugSection()
2698 ObjectContexts.back().File.Dwarf->compile_units()) { in addObjectFile()
2699 DWARFDie CUDie = CU->getUnitDIE(); in addObjectFile()
2746 !OptContext.File.Addresses->hasValidRelocs()) { in link()
2761 if (!OptContext.File.Dwarf->types_section_units().empty()) { in link()
2769 // Clone all the clang modules with requires extracting the DIE units. We in link()
2772 OptContext.File.Dwarf->getNumCompileUnits()); in link()
2773 for (const auto &CU : OptContext.File.Dwarf->compile_units()) { in link()
2774 auto CUDie = CU->getUnitDIE(/*ExtractUnitDIEOnly=*/true); in link()
2792 // compare canonical DIE offsets in analyzeContextInfo to see if a definition in link()
2793 // is already emitted, without being affected by canonical die offsets set in link()
2795 // concurrently, as clone set the canonical DIE offset and analyze reads it. in link()
2798 : TheDwarfEmitter->getDebugInfoSectionSize(); in link()
2814 for (const auto &CU : Context.File.Dwarf->compile_units()) { in link()
2817 auto CUDie = CU->getUnitDIE(/*ExtractUnitDIEOnly=*/false); in link()
2827 // Now build the DIE parent links that we will use during the next phase. in link()
2829 auto CUDie = CurrentUnit->getOrigUnit().getUnitDIE(); in link()
2832 analyzeContextInfo(CurrentUnit->getOrigUnit().getUnitDIE(), 0, in link()
2835 [&](const Twine &Warning, const DWARFDie &DIE) { in link() argument
2836 reportWarning(Warning, Context.File, &DIE); in link()
2856 // cross-cu references require the ParentIdx to be setup for every CU in in link()
2860 CurrentUnit->markEverythingAsKept(); in link()
2865 CurrentUnit->getOrigUnit().getUnitDIE(), in link()
2876 if (OptContext.File.Addresses->hasValidRelocs() || in link()
2885 OptContext.File.Dwarf->isLittleEndian()); in link()
2891 // Clean-up before starting working on the next object. in link()
2898 TheDwarfEmitter->emitAbbrevs(Abbreviations, Options.TargetDWARFVersion); in link()
2899 TheDwarfEmitter->emitStrings(DebugStrPool); in link()
2900 TheDwarfEmitter->emitStringOffsets(StringOffsetPool.getValues(), in link()
2902 TheDwarfEmitter->emitLineStrings(DebugLineStrPool); in link()
2906 TheDwarfEmitter->emitAppleNamespaces(AppleNamespaces); in link()
2907 TheDwarfEmitter->emitAppleNames(AppleNames); in link()
2908 TheDwarfEmitter->emitAppleTypes(AppleTypes); in link()
2909 TheDwarfEmitter->emitAppleObjc(AppleObjc); in link()
2916 TheDwarfEmitter->emitDebugNames(DebugNames); in link()
2973 auto ComputePercentange = [](int64_t Input, int64_t Output) -> float { in link()
2974 const float Difference = Output - Input; in link()
2983 const char *FormatStr = "{0,-45} {1,10}b {2,10}b {3,8:P}\n"; in link()
2987 outs() << "----------------------------------------------------------------" in link()
2988 "---------------\n"; in link()
2991 outs() << "----------------------------------------------------------------" in link()
2992 "---------------\n"; in link()
3003 outs() << "----------------------------------------------------------------" in link()
3004 "---------------\n"; in link()
3007 outs() << "----------------------------------------------------------------" in link()
3008 "---------------\n\n"; in link()
3022 if (!Unit.Unit->getOrigUnit().getUnitDIE().hasChildren()) in cloneModuleUnit()
3031 analyzeContextInfo(Unit.Unit->getOrigUnit().getUnitDIE(), 0, *(Unit.Unit), in cloneModuleUnit()
3034 [&](const Twine &Warning, const DWARFDie &DIE) { in cloneModuleUnit() argument
3035 reportWarning(Warning, Context.File, &DIE); in cloneModuleUnit()
3038 Unit.Unit->markEverythingAsKept(); in cloneModuleUnit()
3047 Unit.File.Dwarf->isLittleEndian()); in cloneModuleUnit()
3057 if (!File.Dwarf->verify(OS, DumpOpts.noImplicitRecursion())) { in verifyInput()