33 AcceleratorRecords(&
GlobalData.getAllocator()) {
44 OrigUnit(&OrigUnit), getUnitFromOffset(UnitFromOffset),
46 AcceleratorRecords(&
GlobalData.getAllocator()) {
50 DWARFDie CUDie = OrigUnit.getUnitDIE();
56 if (!
GlobalData.getOptions().NoODR && Language.has_value() &&
68 LineTablePtr = File.Dwarf->getLineTableForUnit(&
getOrigUnit());
81 for (
DIEInfo &Info : DieInfoArray)
82 Info.unsetFlagsWhichSetDuringLiveAnalysis();
88 Dependencies.reset(
nullptr);
95 AcceleratorRecords.erase();
99 DebugAddrIndexMap.clear();
100 StmtSeqListAttributes.clear();
116 OutDieOffsetArray.resize(
getOrigUnit().getNumDIEs(), 0);
123 bool IsODRUnavailableFunctionScope) {
130 bool ChildIsODRUnavailableFunctionScope = IsODRUnavailableFunctionScope;
132 if (DieInfo.getIsInMouduleScope())
133 ChildInfo.setIsInMouduleScope();
135 if (DieInfo.getIsInFunctionScope())
136 ChildInfo.setIsInFunctionScope();
138 if (DieInfo.getIsInAnonNamespaceScope())
139 ChildInfo.setIsInAnonNamespaceScope();
141 switch (CurChild->getTag()) {
142 case dwarf::DW_TAG_module:
143 ChildInfo.setIsInMouduleScope();
144 if (DieEntry->
getTag() == dwarf::DW_TAG_compile_unit &&
149 case dwarf::DW_TAG_subprogram:
150 ChildInfo.setIsInFunctionScope();
151 if (!ChildIsODRUnavailableFunctionScope &&
152 !ChildInfo.getIsInMouduleScope()) {
154 {dwarf::DW_AT_abstract_origin, dwarf::DW_AT_specification}))
155 ChildIsODRUnavailableFunctionScope =
true;
158 case dwarf::DW_TAG_namespace: {
161 if (
find(CurChild, dwarf::DW_AT_extension))
164 if (!NamespaceEntry.
CU->
find(NamespaceEntry.
DieEntry, dwarf::DW_AT_name))
165 ChildInfo.setIsInAnonNamespaceScope();
172 ChildInfo.setTrackLiveness();
174 if ((!ChildInfo.getIsInAnonNamespaceScope() &&
175 !ChildIsODRUnavailableFunctionScope && !NoODR))
176 ChildInfo.setODRAvailable();
178 if (CurChild->hasChildren())
179 analyzeDWARFStructureRec(CurChild, ChildIsODRUnavailableFunctionScope);
186 if (LineTablePtr->hasFileAtIndex(FileIdx)) {
190 if (It == ResolvedFullPaths.end()) {
191 std::string OrigFileName;
192 bool FoundFileName = LineTablePtr->getFileNameByIndex(
197 assert(FoundFileName &&
"Must get file name from line table");
207 ResolvedParentPaths.find(ParentPath);
208 if (ParentIt == ResolvedParentPaths.end()) {
213 .insert({ParentPath, GlobalStrings.
insert(RealPath).first})
221 It = ResolvedFullPaths
222 .insert(std::make_pair(
223 FileIdx, GlobalStrings.
insert(ResolvedPath).first))
235 if (ObjFileIdx > std::numeric_limits<uint32_t>::max())
237 "object files exceeds UINT32_MAX");
238 if (LocalIdx > std::numeric_limits<uint32_t>::max())
240 "local index exceeds UINT32_MAX");
242 Priority = (ObjFileIdx << 32) | LocalIdx;
248 ResolvedFullPaths.shrink_and_clear();
249 ResolvedParentPaths.clear();
254 Dependencies.reset(
nullptr);
255 StmtSeqListAttributes.clear();
265 CurEntry && CurEntry->
getTag() == dwarf::DW_TAG_module;
274 Path.append(
Name.begin(),
Name.end());
275 Path.push_back(
'\0');
283 assert(UnitEntry &&
"unit reached cloning without loaded DIEs");
290 if (CurChild->getTag() == dwarf::DW_TAG_module &&
306 while (!WorkList.
empty()) {
312 if (CurChild->getTag() == dwarf::DW_TAG_module)
321 if (
getDIEInfo(DieEntry).needToPlaceInTypeTable())
340 if (!Language || Language != dwarf::DW_LANG_Swift)
343 if (!
GlobalData.getOptions().ParseableSwiftInterfaces)
348 if (!Path.ends_with(
".swiftinterface"))
360 if (!DeveloperDir.
empty() && Path.starts_with(DeveloperDir))
364 if (std::optional<DWARFFormValue> Val =
find(DieEntry, dwarf::DW_AT_name)) {
382 PendingSwiftInterfaces.emplace_back(*
Name, ResolvedPath);
388 for (
auto &Pending : PendingSwiftInterfaces) {
389 auto &Entry = Map[Pending.ModuleName];
390 if (!Entry.empty() && Entry != Pending.ResolvedPath)
391 warn(
Twine(
"conflicting parseable interfaces for Swift Module ") +
392 Pending.ModuleName +
": " + Entry +
" and " + Pending.ResolvedPath +
394 Entry = Pending.ResolvedPath;
396 PendingSwiftInterfaces.clear();
417 assert(ChildInfo.getODRAvailable());
420 ChildrenIndexAssigner.getChildIndex(*
this, CurChild)))
423 if (
Error Err = assignTypeNamesRec(CurChild, NameBuilder))
431 if (std::optional<SectionDescriptor *> DebugInfoSection =
438 Patch.
RefCU.getPointer()->getDieOutOffset(
443 ->ListDebugULEB128DieRefPatch.forEach(
447 Patch.
RefCU.getPointer()->getDieOutOffset(
452 ->ListDebugDieModuleRefPatch.forEach(
456 Patch.
RefCU.getPointer()->getDieOutOffset(
461 if (std::optional<SectionDescriptor *> DebugLocSection =
464 ->ListDebugULEB128DieRefPatch.forEach(
468 Patch.
RefCU.getPointer()->getDieOutOffset(
473 if (std::optional<SectionDescriptor *> DebugLocListsSection =
475 (*DebugLocListsSection)
476 ->ListDebugULEB128DieRefPatch.forEach(
480 Patch.
RefCU.getPointer()->getDieOutOffset(
490 uint64_t RefDIEOffset;
495 RefCU = getUnitFromOffset(*
Offset);
503 if (std::optional<uint32_t> RefDieIdx =
511 }
else if (RefCU && CanResolveInterCUReferences) {
516 if (ReferredCUStage < Stage::Loaded || ReferredCUStage >
Stage::Cloned)
519 if (std::optional<uint32_t> RefDieIdx =
535 if (std::optional<DWARFFormValue> AttrVal =
find(DieEntry, Attr))
543 std::lock_guard<std::mutex> Guard(RangesMutex);
545 Ranges.
insert({FuncLowPc, FuncHighPc}, PcOffset);
547 LowPc = std::min(*LowPc, FuncLowPc + PcOffset);
549 LowPc = FuncLowPc + PcOffset;
550 this->HighPc = std::max(HighPc, FuncHighPc + PcOffset);
554 std::lock_guard<std::mutex> Guard(LabelsMutex);
555 Labels.
insert({LabelLowPc, PcOffset});
575 if (!DebugInfoSection.ListDebugLocPatch.empty()) {
580 uint64_t OffsetAfterUnitLength = emitLocListHeader(OutLocationSection);
582 DebugInfoSection.ListDebugLocPatch.forEach([&](
DebugLocPatch &Patch) {
585 uint64_t InputDebugLocSectionOffset = DebugInfoSection.
getIntVal(
591 if (!OriginalLocations) {
596 LinkedLocationExpressionsVector LinkedLocationExpressions;
598 LinkedLocationExpressionsWithOffsetPatches LinkedExpression;
600 if (CurExpression.Range) {
602 LinkedExpression.Expression.Range = {
612 LinkedExpression.Expression.Expr,
614 LinkedExpression.Patches);
616 LinkedLocationExpressions.push_back({LinkedExpression});
621 OutLocationSection.
OS.
tell());
622 emitLocListFragment(LinkedLocationExpressions, OutLocationSection);
625 if (OffsetAfterUnitLength > 0) {
626 assert(OffsetAfterUnitLength -
628 OffsetAfterUnitLength);
629 OutLocationSection.
apply(
630 OffsetAfterUnitLength -
632 dwarf::DW_FORM_sec_offset,
633 OutLocationSection.
OS.
tell() - OffsetAfterUnitLength);
659 return OffsetAfterUnitLength;
663uint64_t CompileUnit::emitLocListFragment(
664 const LinkedLocationExpressionsVector &LinkedLocationExpression,
666 uint64_t OffsetBeforeLocationExpression = 0;
670 if (std::optional<uint64_t> LowPC =
getLowPc())
671 BaseAddress = *LowPC;
673 for (
const LinkedLocationExpressionsWithOffsetPatches &LocExpression :
674 LinkedLocationExpression) {
675 if (LocExpression.Expression.Range) {
677 LocExpression.Expression.Range->LowPC - BaseAddress,
680 LocExpression.Expression.Range->HighPC - BaseAddress,
684 OutLocationSection.
emitIntVal(LocExpression.Expression.Expr.size(), 2);
685 OffsetBeforeLocationExpression = OutLocationSection.
OS.
tell();
686 for (
uint64_t *OffsetPtr : LocExpression.Patches)
687 *OffsetPtr += OffsetBeforeLocationExpression;
689 OutLocationSection.
OS
690 << StringRef((
const char *)LocExpression.Expression.Expr.data(),
691 LocExpression.Expression.Expr.size());
699 return OffsetBeforeLocationExpression;
702 std::optional<uint64_t> BaseAddress;
703 for (
const LinkedLocationExpressionsWithOffsetPatches &LocExpression :
704 LinkedLocationExpression) {
705 if (LocExpression.Expression.Range) {
709 BaseAddress = LocExpression.Expression.Range->LowPC;
712 OutLocationSection.
emitIntVal(dwarf::DW_LLE_base_addressx, 1);
714 OutLocationSection.
OS);
718 OutLocationSection.
emitIntVal(dwarf::DW_LLE_offset_pair, 1);
721 encodeULEB128(LocExpression.Expression.Range->LowPC - *BaseAddress,
722 OutLocationSection.
OS);
725 encodeULEB128(LocExpression.Expression.Range->HighPC - *BaseAddress,
726 OutLocationSection.
OS);
729 OutLocationSection.
emitIntVal(dwarf::DW_LLE_default_location, 1);
731 encodeULEB128(LocExpression.Expression.Expr.size(), OutLocationSection.
OS);
732 OffsetBeforeLocationExpression = OutLocationSection.
OS.
tell();
733 for (
uint64_t *OffsetPtr : LocExpression.Patches)
734 *OffsetPtr += OffsetBeforeLocationExpression;
736 OutLocationSection.
OS << StringRef(
737 (
const char *)LocExpression.Expression.Expr.data(),
738 LocExpression.Expression.Expr.size());
742 OutLocationSection.
emitIntVal(dwarf::DW_LLE_end_of_list, 1);
743 return OffsetBeforeLocationExpression;
746Error CompileUnit::emitDebugAddrSection() {
747 if (
GlobalData.getOptions().UpdateIndexTablesOnly)
753 if (DebugAddrIndexMap.empty())
756 SectionDescriptor &OutAddrSection =
775 for (
uint64_t AddrValue : DebugAddrIndexMap.getValues())
779 OutAddrSection.
apply(
780 OffsetAfterSectionLength -
782 dwarf::DW_FORM_sec_offset,
783 OutAddrSection.
OS.
tell() - OffsetAfterSectionLength);
795 LinkedFunctionRanges.
insert(
798 emitAranges(LinkedFunctionRanges);
816 if (!DebugInfoSection.ListDebugRangePatch.empty()) {
817 std::optional<AddressRangeValuePair> CachedRange;
818 uint64_t OffsetAfterUnitLength = emitRangeListHeader(OutRangeSection);
821 DebugInfoSection.ListDebugRangePatch.forEach([&](
DebugRangePatch &Patch) {
823 CompileUnitRangePtr = &Patch;
828 uint64_t InputDebugRangesSectionOffset = DebugInfoSection.
getIntVal(
833 InputDebugRangesSectionOffset)) {
835 for (
const auto &
Range : *InputRanges) {
836 if (!CachedRange || !CachedRange->Range.contains(
Range.LowPC))
842 warn(
"inconsistent range data.");
847 LinkedRanges.
insert({
Range.LowPC + CachedRange->Value,
848 Range.HighPC + CachedRange->Value});
852 warn(
"invalid range list ignored.");
857 OutRangeSection.
OS.
tell());
858 emitRangeListFragment(LinkedRanges, OutRangeSection);
862 if (CompileUnitRangePtr !=
nullptr) {
866 dwarf::DW_FORM_sec_offset,
867 OutRangeSection.
OS.
tell());
868 emitRangeListFragment(LinkedFunctionRanges, OutRangeSection);
871 if (OffsetAfterUnitLength > 0) {
872 assert(OffsetAfterUnitLength -
874 OffsetAfterUnitLength);
875 OutRangeSection.
apply(
876 OffsetAfterUnitLength -
878 dwarf::DW_FORM_sec_offset,
879 OutRangeSection.
OS.
tell() - OffsetAfterUnitLength);
904 return OffsetAfterUnitLength;
907void CompileUnit::emitRangeListFragment(
const AddressRanges &LinkedRanges,
912 if (std::optional<uint64_t> LowPC =
getLowPc())
913 BaseAddress = *LowPC;
915 for (
const AddressRange &
Range : LinkedRanges) {
928 std::optional<uint64_t> BaseAddress;
929 for (
const AddressRange &
Range : LinkedRanges) {
931 BaseAddress =
Range.start();
934 OutRangeSection.
emitIntVal(dwarf::DW_RLE_base_addressx, 1);
939 OutRangeSection.
emitIntVal(dwarf::DW_RLE_offset_pair, 1);
949 OutRangeSection.
emitIntVal(dwarf::DW_RLE_end_of_list, 1);
952void CompileUnit::emitAranges(AddressRanges &LinkedFunctionRanges) {
953 if (LinkedFunctionRanges.
empty())
956 SectionDescriptor &DebugInfoSection =
958 SectionDescriptor &OutArangesSection =
973 uint64_t OffsetAfterArangesLengthField = OutArangesSection.
OS.
tell();
976 OutArangesSection.notePatch(
977 DebugOffsetPatch{OutArangesSection.
OS.
tell(), &DebugInfoSection});
983 for (
size_t Idx = 0; Idx <
Padding; Idx++)
987 for (
const AddressRange &
Range : LinkedFunctionRanges) {
1001 OutArangesSection.
apply(
1002 OffsetAfterArangesLengthField -
1004 dwarf::DW_FORM_sec_offset,
1005 OffsetAfterArangesEnd - OffsetAfterArangesLengthField);
1013 DWARFDie OrigUnitDie = OrigUnit.getUnitDIE();
1016 if (std::optional<uint64_t> MacroAttr =
1020 emitMacroTableImpl(
Table, *MacroAttr,
true);
1025 if (std::optional<uint64_t> MacroAttr =
1029 emitMacroTableImpl(
Table, *MacroAttr,
false);
1036void CompileUnit::emitMacroTableImpl(
const DWARFDebugMacro *MacroTable,
1037 uint64_t OffsetToMacroTable,
1038 bool hasDWARFv5Header) {
1044 bool DefAttributeIsReported =
false;
1045 bool UndefAttributeIsReported =
false;
1046 bool ImportAttributeIsReported =
false;
1048 for (
const DWARFDebugMacro::MacroList &
List : MacroTable->MacroLists) {
1049 if (OffsetToMacroTable == List.Offset) {
1051 if (hasDWARFv5Header) {
1053 OutSection.emitIntVal(List.Header.Version, sizeof(List.Header.Version));
1055 uint8_t Flags = List.Header.Flags;
1059 DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE) {
1061 ~DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE;
1062 warn(
"opcode_operands_table is not supported yet.");
1066 std::optional<uint64_t> StmtListOffset;
1067 if (Flags & DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET) {
1069 for (auto &V : getOutUnitDIE()->values()) {
1070 if (V.getAttribute() == dwarf::DW_AT_stmt_list) {
1071 StmtListOffset = V.getDIEInteger().getValue();
1076 if (!StmtListOffset) {
1077 Flags &= ~DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET;
1078 warn(
"couldn`t find line table for macro table.");
1083 OutSection.emitIntVal(Flags, sizeof(Flags));
1086 if (StmtListOffset) {
1087 OutSection.notePatch(DebugOffsetPatch{
1088 OutSection.OS.tell(),
1089 &getOrCreateSectionDescriptor(DebugSectionKind::DebugLine)});
1092 OutSection.emitIntVal(0xBADDEF, List.Header.getOffsetByteSize());
1097 for (const DWARFDebugMacro::Entry &MacroEntry : List.Macros) {
1098 if (MacroEntry.Type == 0) {
1099 encodeULEB128(MacroEntry.Type, OutSection.OS);
1103 uint8_t MacroType = MacroEntry.Type;
1104 switch (MacroType) {
1106 bool HasVendorSpecificExtension =
1107 (!hasDWARFv5Header &&
1108 MacroType == dwarf::DW_MACINFO_vendor_ext) ||
1109 (hasDWARFv5Header && (MacroType >= dwarf::DW_MACRO_lo_user &&
1110 MacroType <= dwarf::DW_MACRO_hi_user));
1112 if (HasVendorSpecificExtension) {
1114 OutSection.emitIntVal(MacroType, 1);
1117 encodeULEB128(MacroEntry.ExtConstant, OutSection.OS);
1120 OutSection.emitString(dwarf::DW_FORM_string, MacroEntry.ExtStr);
1122 warn(
"unknown macro type. skip.");
1130 case dwarf::DW_MACRO_define:
1131 case dwarf::DW_MACRO_undef: {
1133 OutSection.emitIntVal(MacroType, 1);
1136 encodeULEB128(MacroEntry.Line, OutSection.OS);
1139 OutSection.emitString(dwarf::DW_FORM_string, MacroEntry.MacroStr);
1141 case dwarf::DW_MACRO_define_strp:
1142 case dwarf::DW_MACRO_undef_strp:
1143 case dwarf::DW_MACRO_define_strx:
1144 case dwarf::DW_MACRO_undef_strx: {
1147 switch (MacroType) {
1148 case dwarf::DW_MACRO_define_strx: {
1149 MacroType = dwarf::DW_MACRO_define_strp;
1150 if (!DefAttributeIsReported) {
1151 warn(
"DW_MACRO_define_strx unsupported yet. Convert to "
1152 "DW_MACRO_define_strp.");
1153 DefAttributeIsReported = true;
1156 case dwarf::DW_MACRO_undef_strx: {
1157 MacroType = dwarf::DW_MACRO_undef_strp;
1158 if (!UndefAttributeIsReported) {
1159 warn(
"DW_MACRO_undef_strx unsupported yet. Convert to "
1160 "DW_MACRO_undef_strp.");
1161 UndefAttributeIsReported = true;
1170 OutSection.emitIntVal(MacroType, 1);
1173 encodeULEB128(MacroEntry.Line, OutSection.OS);
1176 OutSection.emitString(dwarf::DW_FORM_strp, MacroEntry.MacroStr);
1179 case dwarf::DW_MACRO_start_file: {
1181 OutSection.emitIntVal(MacroType, 1);
1183 encodeULEB128(MacroEntry.Line, OutSection.OS);
1185 encodeULEB128(MacroEntry.File, OutSection.OS);
1187 case dwarf::DW_MACRO_end_file: {
1189 OutSection.emitIntVal(MacroType, 1);
1191 case dwarf::DW_MACRO_import:
1192 case dwarf::DW_MACRO_import_sup: {
1193 if (!ImportAttributeIsReported) {
1194 warn(
"DW_MACRO_import and DW_MACRO_import_sup are unsupported "
1196 ImportAttributeIsReported = true;
1210 std::optional<int64_t> VarAddressAdjustment,
1215 uint8_t OrigAddressByteSize = OrigUnit.getAddressByteSize();
1217 uint64_t OpOffset = 0;
1218 for (
auto &
Op : InputExpression) {
1224 warn(
"cannot decode a DW_OP, copying the rest of the expression "
1230 auto Desc =
Op.getDescription();
1233 if ((
Desc.Op.size() == 2 &&
Desc.Op[0] == Encoding::BaseTypeRef) ||
1234 (
Desc.Op.size() == 2 &&
Desc.Op[1] == Encoding::BaseTypeRef &&
1235 Desc.Op[0] != Encoding::Size1))
1236 warn(
"unsupported DW_OP encoding.");
1238 if ((
Desc.Op.size() == 1 &&
Desc.Op[0] == Encoding::BaseTypeRef) ||
1239 (
Desc.Op.size() == 2 &&
Desc.Op[1] == Encoding::BaseTypeRef &&
1240 Desc.Op[0] == Encoding::Size1)) {
1242 assert(OpOffset <
Op.getEndOffset());
1243 uint32_t ULEBsize =
Op.getEndOffset() - OpOffset - 1;
1247 assert(!
Op.getSubCode() &&
"SubOps not yet supported");
1250 if (
Desc.Op.size() == 1) {
1251 RefOffset =
Op.getRawOperand(0);
1254 RefOffset =
Op.getRawOperand(1);
1258 unsigned RealSize = 0;
1262 if (RefOffset > 0 ||
Op.getCode() != dwarf::DW_OP_convert) {
1263 RefOffset += OrigUnit.getOffset();
1265 if (std::optional<uint32_t> Idx =
1266 OrigUnit.getDIEIndexForOffset(RefOffset))
1275 Section.notePatchWithOffsetUpdate(
1282 if (RealSize > ULEBsize) {
1285 warn(
"base type ref doesn't fit.");
1287 assert(RealSize == ULEBsize &&
"padding failed");
1290 }
else if (!
getGlobalData().getOptions().UpdateIndexTablesOnly &&
1291 Op.getCode() == dwarf::DW_OP_addrx) {
1292 if (std::optional<object::SectionedAddress> SA =
1293 OrigUnit.getAddrOffsetSectionItem(
Op.getRawOperand(0))) {
1298 OutputExpression.
push_back(dwarf::DW_OP_addr);
1299 uint64_t LinkedAddress = SA->Address + VarAddressAdjustment.value_or(0);
1303 reinterpret_cast<const uint8_t *
>(&LinkedAddress),
1304 OrigAddressByteSize);
1305 OutputExpression.
append(AddressBytes.
begin(), AddressBytes.
end());
1307 warn(
"cann't read DW_OP_addrx operand.");
1308 }
else if (!
getGlobalData().getOptions().UpdateIndexTablesOnly &&
1309 Op.getCode() == dwarf::DW_OP_constx) {
1310 if (std::optional<object::SectionedAddress> SA =
1311 OrigUnit.getAddrOffsetSectionItem(
Op.getRawOperand(0))) {
1316 std::optional<uint8_t> OutOperandKind;
1317 switch (OrigAddressByteSize) {
1319 OutOperandKind = dwarf::DW_OP_const2u;
1322 OutOperandKind = dwarf::DW_OP_const4u;
1325 OutOperandKind = dwarf::DW_OP_const8u;
1329 formatv((
"unsupported address size: {0}."), OrigAddressByteSize));
1333 if (OutOperandKind) {
1334 OutputExpression.
push_back(*OutOperandKind);
1335 uint64_t LinkedAddress =
1336 SA->Address + VarAddressAdjustment.value_or(0);
1340 reinterpret_cast<const uint8_t *
>(&LinkedAddress),
1341 OrigAddressByteSize);
1342 OutputExpression.
append(AddressBytes.
begin(), AddressBytes.
end());
1345 warn(
"cann't read DW_OP_constx operand.");
1352 OpOffset =
Op.getEndOffset();
1357 std::optional<std::reference_wrapper<const Triple>> TargetTriple,
1366 if (ArtificialTypeUnit)
1370 std::pair<DIE *, TypeEntry *> OutCUDie =
cloneDIE(
1372 std::nullopt, std::nullopt, Allocator, ArtificialTypeUnit);
1375 if (!TargetTriple.has_value() || (OutCUDie.first ==
nullptr))
1398 if (
Error Err = emitDebugAddrSection())
1414 uint64_t OutOffset, std::optional<int64_t> FuncAddressAdjustment,
1420 bool NeedToClonePlainDIE = Info.needToKeepInPlainDwarf();
1421 bool NeedToCloneTypeDIE =
1422 (InputDieEntry->
getTag() != dwarf::DW_TAG_compile_unit) &&
1423 Info.needToPlaceInTypeTable();
1424 std::pair<DIE *, TypeEntry *> ClonedDIE;
1428 if (NeedToClonePlainDIE)
1431 ClonedDIE.first = createPlainDIEandCloneAttributes(
1432 InputDieEntry, PlainDIEGenerator, OutOffset, FuncAddressAdjustment,
1433 VarAddressAdjustment);
1434 if (NeedToCloneTypeDIE) {
1437 assert(ArtificialTypeUnit !=
nullptr);
1441 ClonedDIE.second = createTypeDIEandCloneAttributes(
1442 InputDieEntry, TypeDIEGenerator, ClonedParentTypeDIE,
1443 ArtificialTypeUnit, SiblingOrdinal);
1446 ClonedDIE.second ? ClonedDIE.second : ClonedParentTypeDIE;
1448 bool HasPlainChildrenToClone =
1449 (ClonedDIE.first && Info.getKeepPlainChildren());
1451 bool HasTypeChildrenToClone =
1452 ((ClonedDIE.second ||
1453 InputDieEntry->
getTag() == dwarf::DW_TAG_compile_unit) &&
1454 Info.getKeepTypeChildren());
1457 if (HasPlainChildrenToClone || HasTypeChildrenToClone) {
1463 std::pair<DIE *, TypeEntry *> ClonedChild =
cloneDIE(
1464 CurChild, TypeParentForChild, OutOffset, FuncAddressAdjustment,
1465 VarAddressAdjustment, Allocator, ArtificialTypeUnit, ChildOrdinal);
1467 if (ClonedChild.first) {
1469 ClonedChild.first->getOffset() + ClonedChild.first->getSize();
1470 PlainDIEGenerator.
addChild(ClonedChild.first);
1473 assert(ClonedDIE.first ==
nullptr ||
1474 HasPlainChildrenToClone == ClonedDIE.first->hasChildren());
1477 if (HasPlainChildrenToClone)
1478 OutOffset +=
sizeof(int8_t);
1482 if (ClonedDIE.first !=
nullptr)
1483 ClonedDIE.first->setSize(OutOffset - ClonedDIE.first->getOffset());
1488DIE *CompileUnit::createPlainDIEandCloneAttributes(
1490 uint64_t &OutOffset, std::optional<int64_t> &FuncAddressAdjustment,
1491 std::optional<int64_t> &VarAddressAdjustment) {
1494 DIE *ClonedDIE =
nullptr;
1495 bool HasLocationExpressionAddress =
false;
1496 if (InputDieEntry->
getTag() == dwarf::DW_TAG_subprogram) {
1498 FuncAddressAdjustment =
1500 getDIE(InputDieEntry),
false);
1501 }
else if (InputDieEntry->
getTag() == dwarf::DW_TAG_label) {
1503 std::optional<uint64_t> lowPC =
1507 if (It != Labels.
end())
1508 FuncAddressAdjustment = It->second;
1510 }
else if (InputDieEntry->
getTag() == dwarf::DW_TAG_variable) {
1512 std::pair<bool, std::optional<int64_t>> LocExprAddrAndRelocAdjustment =
1514 getDIE(InputDieEntry),
false);
1516 HasLocationExpressionAddress = LocExprAddrAndRelocAdjustment.first;
1517 if (LocExprAddrAndRelocAdjustment.first &&
1518 LocExprAddrAndRelocAdjustment.second)
1519 VarAddressAdjustment = *LocExprAddrAndRelocAdjustment.second;
1522 ClonedDIE = PlainDIEGenerator.
createDIE(InputDieEntry->
getTag(), OutOffset);
1529 DIEAttributeCloner AttributesCloner(ClonedDIE, *
this,
this, InputDieEntry,
1530 PlainDIEGenerator, FuncAddressAdjustment,
1531 VarAddressAdjustment,
1532 HasLocationExpressionAddress);
1533 AttributesCloner.clone();
1536 AcceleratorRecordsSaver AccelRecordsSaver(
getGlobalData(), *
this,
this);
1537 AccelRecordsSaver.save(InputDieEntry, ClonedDIE, AttributesCloner.AttrInfo,
1541 AttributesCloner.finalizeAbbreviations(
Info.getKeepPlainChildren());
1547DIE *CompileUnit::allocateTypeDie(
TypeEntryBody *TypeDescriptor,
1550 bool IsParentDeclaration) {
1555 if (!IsDeclaration && !IsParentDeclaration) {
1558 if (Priority >= TypeDescriptor->
DiePriority.load(std::memory_order_relaxed))
1562 if (TypeDescriptor->
Die.load(std::memory_order_relaxed))
1566 while (TypeDescriptor->
Lock.test_and_set(std::memory_order_acquire))
1571 if (!IsDeclaration && !IsParentDeclaration) {
1574 TypeDescriptor->
DiePriority.load(std::memory_order_relaxed)) {
1575 TypeDescriptor->
DiePriority.store(Priority, std::memory_order_relaxed);
1577 TypeDescriptor->
Die.store(Result, std::memory_order_relaxed);
1579 }
else if (!TypeDescriptor->
Die.load(std::memory_order_relaxed)) {
1588 (BetterParent || Priority < TypeDescriptor->DeclarationDiePriority)) {
1592 TypeDescriptor->
DeclarationDie.store(Result, std::memory_order_relaxed);
1596 TypeDescriptor->
Lock.clear(std::memory_order_release);
1600TypeEntry *CompileUnit::createTypeDIEandCloneAttributes(
1601 const DWARFDebugInfoEntry *InputDieEntry,
DIEGenerator &TypeDIEGenerator,
1603 uint32_t SiblingOrdinal) {
1604 assert(ArtificialTypeUnit !=
nullptr);
1605 uint32_t InputDieIdx =
getDIEIndex(InputDieEntry);
1608 assert(Entry !=
nullptr);
1609 assert(ClonedParentTypeDIE !=
nullptr);
1610 TypeEntryBody *EntryBody =
1612 Entry, ClonedParentTypeDIE);
1619 if (std::optional<uint32_t> ParentIdx = InputDieEntry->
getParentIdx()) {
1621 if (ParentTag == dwarf::DW_TAG_structure_type ||
1622 ParentTag == dwarf::DW_TAG_class_type ||
1623 ParentTag == dwarf::DW_TAG_union_type ||
1624 ParentTag == dwarf::DW_TAG_interface_type) {
1625 uint32_t Prev = EntryBody->
SortKey.load(std::memory_order_relaxed);
1626 while (SiblingOrdinal < Prev &&
1627 !EntryBody->
SortKey.compare_exchange_weak(
1628 Prev, SiblingOrdinal, std::memory_order_relaxed,
1629 std::memory_order_relaxed))
1634 bool IsDeclaration =
1637 bool ParentIsDeclaration =
false;
1638 if (std::optional<uint32_t> ParentIdx = InputDieEntry->
getParentIdx())
1639 ParentIsDeclaration =
1643 allocateTypeDie(EntryBody, TypeDIEGenerator, InputDieEntry->
getTag(),
1644 IsDeclaration, ParentIsDeclaration);
1646 if (OutDIE !=
nullptr) {
1647 assert(ArtificialTypeUnit !=
nullptr);
1650 DIEAttributeCloner AttributesCloner(OutDIE, *
this, ArtificialTypeUnit,
1651 InputDieEntry, TypeDIEGenerator,
1652 std::nullopt, std::nullopt,
false);
1653 AttributesCloner.clone();
1656 AcceleratorRecordsSaver AccelRecordsSaver(
getGlobalData(), *
this,
1657 ArtificialTypeUnit);
1658 AccelRecordsSaver.save(InputDieEntry, OutDIE, AttributesCloner.AttrInfo,
1663 OutDIE->
setSize(AttributesCloner.getOutOffset() + 1);
1672 if (InputLineTable ==
nullptr) {
1674 warn(
"cann't load line table.");
1686 OutLineTable.
Rows = InputLineTable->
Rows;
1689 if (OutLineTable.
Rows.size() == 1 && OutLineTable.
Rows[0].EndSequence)
1690 OutLineTable.
Rows.clear();
1697 filterLineTableRows(*InputLineTable, OutLineTable.
Rows, OrigRowIndices);
1699 if (StmtSeqListAttributes.empty())
1719 &RowIndexToSeqStartOffset))
1723 buildStmtSeqOffsetToFirstRowIndex(*InputLineTable);
1724 patchStmtSeqAttributes(SeqOffsetToFirstRowIndex, RowIndexToSeqStartOffset);
1728void CompileUnit::filterLineTableRows(
1730 std::vector<DWARFDebugLine::Row> &NewRows,
1732 NewRows.reserve(InputLineTable.
Rows.size());
1733 NewRowIndices.
reserve(InputLineTable.
Rows.size());
1739 std::vector<DWARFDebugLine::Row> Seq;
1741 constexpr uint64_t InvalidRowIndex = std::numeric_limits<uint64_t>::max();
1744 std::optional<AddressRangeValuePair> CurrRange;
1764 if (!CurrRange || !CurrRange->Range.contains(Row.Address.Address)) {
1767 uint64_t StopAddress =
1768 CurrRange ? CurrRange->Range.end() + CurrRange->Value : -1ULL;
1769 CurrRange = FunctionRanges.getRangeThatContains(Row.Address.Address);
1770 if (StopAddress != -1ULL && !Seq.empty()) {
1775 auto NextLine = Seq.back();
1776 NextLine.Address.Address = StopAddress;
1777 NextLine.EndSequence = 1;
1778 NextLine.PrologueEnd = 0;
1779 NextLine.BasicBlock = 0;
1780 NextLine.EpilogueBegin = 0;
1781 Seq.push_back(NextLine);
1791 if (Row.EndSequence && Seq.empty())
1796 Seq.emplace_back(Row);
1799 if (Row.EndSequence)
1804void CompileUnit::patchStmtSeqAttributes(
1805 const DenseMap<uint64_t, uint64_t> &SeqOffsetToFirstRowIndex,
1806 const DenseMap<uint64_t, uint64_t> &RowIndexToSeqStartOffset) {
1809 for (
const CompileUnit::StmtSeqPatch &Patch : StmtSeqListAttributes) {
1810 uint64_t NewStmtSeq = InvalidOffset;
1811 auto RowIt = SeqOffsetToFirstRowIndex.
find(Patch.InputStmtSeqOffset);
1812 if (RowIt != SeqOffsetToFirstRowIndex.
end()) {
1813 auto OffIt = RowIndexToSeqStartOffset.
find(RowIt->second);
1814 if (OffIt != RowIndexToSeqStartOffset.
end())
1815 NewStmtSeq = OffIt->second;
1821 *Patch.Value = DIEValue(Patch.Value->getAttribute(), Patch.Value->getForm(),
1822 DIEInteger(NewStmtSeq));
1826DenseMap<uint64_t, uint64_t> CompileUnit::buildStmtSeqOffsetToFirstRowIndex(
1827 const DWARFDebugLine::LineTable &InputLineTable)
const {
1830 SmallVector<uint64_t> StmtAttrs;
1831 StmtAttrs.
reserve(StmtSeqListAttributes.size());
1832 for (
const StmtSeqPatch &Patch : StmtSeqListAttributes)
1833 StmtAttrs.
push_back(Patch.InputStmtSeqOffset);
1837 DenseMap<uint64_t, uint64_t>
Result;
1843void CompileUnit::insertLineSequence(std::vector<DWARFDebugLine::Row> &Seq,
1844 SmallVectorImpl<uint64_t> &SeqIndices,
1845 std::vector<DWARFDebugLine::Row> &Rows,
1846 SmallVectorImpl<uint64_t> &RowIndices) {
1848 "Seq and SeqIndices must be kept in lockstep");
1850 "Rows and RowIndices must be kept in lockstep");
1854 auto ClearSeq = [&] {
1859 if (!Rows.empty() && Rows.back().Address < Seq.front().Address) {
1866 object::SectionedAddress Front = Seq.front().Address;
1868 Rows, [=](
const DWARFDebugLine::Row &O) {
return O.Address < Front; });
1869 size_t InsertIdx = std::distance(Rows.begin(), InsertPoint);
1875 if (InsertPoint != Rows.end() && InsertPoint->Address == Front &&
1876 InsertPoint->EndSequence) {
1877 *InsertPoint = Seq.front();
1878 RowIndices[InsertIdx] = SeqIndices.
front();
1879 Rows.insert(InsertPoint + 1, Seq.begin() + 1, Seq.end());
1880 RowIndices.
insert(RowIndices.
begin() + InsertIdx + 1,
1881 SeqIndices.
begin() + 1, SeqIndices.
end());
1883 Rows.insert(InsertPoint, Seq.begin(), Seq.end());
1891#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1911 llvm::errs() <<
" KeepPlainChildren: " << getKeepPlainChildren();
1912 llvm::errs() <<
" KeepTypeChildren: " << getKeepTypeChildren();
1913 llvm::errs() <<
" IsInMouduleScope: " << getIsInMouduleScope();
1914 llvm::errs() <<
" IsInFunctionScope: " << getIsInFunctionScope();
1915 llvm::errs() <<
" IsInAnonNamespaceScope: " << getIsInAnonNamespaceScope();
1916 llvm::errs() <<
" ODRAvailable: " << getODRAvailable();
1917 llvm::errs() <<
" TrackLiveness: " << getTrackLiveness();
1922std::optional<std::pair<StringRef, StringRef>>
1933 return std::nullopt;
1938std::optional<std::pair<StringRef, StringRef>>
1941 FileNamesCache::iterator FileData =
FileNames.find(FileIdx);
1943 return {{
StringRef(FileData->second->first),
1948 if (LineTable->hasFileAtIndex(FileIdx)) {
1951 LineTable->Prologue.getFileNameEntry(FileIdx);
1956 return std::nullopt;
1959 std::string FileName = *
Name;
1961 FileNamesCache::iterator FileData =
1964 std::make_unique<std::pair<std::string, std::string>>(
1965 std::string(
""), std::move(FileName))})
1967 return {{
StringRef(FileData->second->first),
1977 if ((Entry.DirIdx != 0) &&
1978 Entry.DirIdx < LineTable->Prologue.IncludeDirectories.size()) {
1980 LineTable->Prologue.IncludeDirectories[Entry.DirIdx]
1983 IncludeDir = *DirName;
1986 return std::nullopt;
1990 if (0 < Entry.DirIdx &&
1991 Entry.DirIdx <= LineTable->Prologue.IncludeDirectories.size()) {
1993 LineTable->Prologue.IncludeDirectories[Entry.DirIdx - 1]
1996 IncludeDir = *DirName;
1999 return std::nullopt;
2012 FileNamesCache::iterator FileData =
2015 std::make_unique<std::pair<std::string, std::string>>(
2016 std::string(FilePath), std::move(FileName))})
2018 return {{
StringRef(FileData->second->first),
2023 return std::nullopt;
2026#define MAX_REFERENCIES_DEPTH 1000
2029 std::optional<UnitEntryPairTy> RefDiePair;
2033 CUDiePair.
DieEntry, dwarf::DW_AT_extension,
2035 if (!RefDiePair || !RefDiePair->DieEntry)
2038 CUDiePair = *RefDiePair;
2045 if (std::optional<uint32_t> ParentIdx =
DieEntry->getParentIdx())
2048 return std::nullopt;
2084 bool InterCUProcessingStarted, std::atomic<bool> &HasNewInterconnectedCUs) {
2088 return Dependencies->resolveDependenciesAndMarkLiveness(
2089 InterCUProcessingStarted, HasNewInterconnectedCUs);
2093 assert(Dependencies.get());
2095 return Dependencies->updateDependenciesCompleteness();
2099 assert(Dependencies.get());
2101 Dependencies->verifyKeepChain();
2106 dwarf::DW_AT_type, dwarf::DW_AT_specification,
2107 dwarf::DW_AT_abstract_origin, dwarf::DW_AT_import,
2108 dwarf::DW_AT_LLVM_alloc_type};
2110 return ODRAttributes;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
#define MAX_REFERENCIES_DEPTH
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
std::optional< T > getRangeThatContains(uint64_t Addr) const
void insert(AddressRange Range, int64_t Value)
The AddressRanges class helps normalize address range collections.
Collection::const_iterator insert(AddressRange Range)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
std::pair< KeyDataTy *, bool > insert(const KeyTy &NewValue)
Insert new value NewValue or return already existing entry.
A structured debug information entry.
DWARFDebugInfoEntry - A DIE with only the minimum required data.
dwarf::Tag getTag() const
std::optional< uint32_t > getParentIdx() const
Returns index of the parent die.
const DWARFAbbreviationDeclaration * getAbbreviationDeclarationPtr() const
Utility class that carries the DWARF compile/type unit and the debug info entry in an object.
LLVM_ABI std::optional< DWARFFormValue > find(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE.
const DWARFDebugInfoEntry * getDebugInfoEntry() const
LLVM_ABI const char * getName(DINameKind Kind) const
Return the DIE name resolving DW_AT_specification or DW_AT_abstract_origin references if necessary.
LLVM_ABI std::optional< uint64_t > getLanguage() const
Returns the DW_LANG_ code for this DIE's DWARF unit, if it exists.
Encoding
Size and signedness of expression operations' operands.
StringRef getData() const
const dwarf::FormParams & getFormParams() const
DWARFDie getUnitDIE(bool ExtractUnitDIEOnly=true)
uint8_t getAddressByteSize() const
const char * getCompilationDir()
Expected< DWARFLocationExpressionsVector > findLoclistFromOffset(uint64_t Offset)
bool isLittleEndian() const
uint64_t getOffset() const
iterator find(const_arg_type_t< KeyT > Val)
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT > iterator
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT, true > const_iterator
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void reserve(size_type N)
iterator erase(const_iterator CI)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
iterator insert(iterator I, T &&Elt)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMapIterBase< ValueTy, false > iterator
Represent a constant reference to a string, i.e.
std::string str() const
Get the contents as an std::string.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
constexpr bool empty() const
Check if the string is empty.
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
Triple - Helper class for working with autoconf configuration names.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
This class represents DWARF information for source file and it's address map.
std::unique_ptr< AddressesMap > Addresses
Helpful address information(list of valid address ranges, relocations).
std::unique_ptr< DWARFContext > Dwarf
Source DWARF information.
@ Pub
.debug_pubnames, .debug_pubtypes
std::map< std::string, std::string > SwiftInterfacesMapTy
CompileUnit(DWARFUnit &OrigUnit, unsigned ID, bool CanUseODR, StringRef ClangModuleName)
TypeUnit * getAsTypeUnit()
Returns TypeUnit if applicable.
DwarfUnit * operator->()
Accessor for common functionality.
PointerUnion< CompileUnit *, TypeUnit * > Ptr
CompileUnit * getAsCompileUnit()
Returns CompileUnit if applicable.
OutputUnitVariantPtr(CompileUnit *U)
void addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset)
Add the low_pc of a label that is relocated by applying offset PCOffset.
Error cloneAndEmitDebugLocations()
Clone and emit debug locations(.debug_loc/.debug_loclists).
void cloneDieAttrExpression(const DWARFExpression &InputExpression, SmallVectorImpl< uint8_t > &OutputExpression, SectionDescriptor &Section, std::optional< int64_t > VarAddressAdjustment, OffsetsPtrVector &PatchesOffsets)
Clone attribute location axpression.
void maybeResetToLoadedStage()
Reset compile units data(results of liveness analysis, clonning) if current stage greater than Stage:...
void addFunctionRange(uint64_t LowPC, uint64_t HighPC, int64_t PCOffset)
Add a function range [LowPC, HighPC) that is relocated by applying offset PCOffset.
void analyzeImportedModule(const DWARFDebugInfoEntry *DieEntry)
Collect references to parseable Swift interfaces in imported DW_TAG_module blocks.
std::pair< DIE *, TypeEntry * > cloneDIE(const DWARFDebugInfoEntry *InputDieEntry, TypeEntry *ClonedParentTypeDIE, uint64_t OutOffset, std::optional< int64_t > FuncAddressAdjustment, std::optional< int64_t > VarAddressAdjustment, BumpPtrAllocator &Allocator, TypeUnit *ArtificialTypeUnit, uint32_t SiblingOrdinal=std::numeric_limits< uint32_t >::max())
void cleanupDataAfterClonning()
Cleanup unneeded resources after compile unit is cloned.
Error assignTypeNames(TypePool &TypePoolRef)
Search for type entries and assign names.
llvm::Error setPriority(uint64_t ObjFileIdx, uint64_t LocalIdx)
Set deterministic priority for type DIE allocation ordering.
void noteModuleAnchors()
Must run while the output offsets are still available, and once they are final.
@ TypeTable
Corresponding DIE goes to the type table only.
@ PlainDwarf
Corresponding DIE goes to the plain dwarf only.
Error cloneAndEmitLineTable(const Triple &TargetTriple)
const DWARFFile & getContainingFile() const
Returns DWARFFile containing this compile unit.
Error cloneAndEmitRanges()
Clone and emit ranges.
void mergeSwiftInterfaces(DWARFLinkerBase::SwiftInterfacesMapTy &Map)
Merge the Swift interface entries collected by analyzeImportedModule into Map, emitting a warning for...
void updateDieRefPatchesWithClonedOffsets()
After cloning stage the output DIEs offsets are deallocated.
uint64_t getDebugAddrIndex(uint64_t Addr)
Returns index(inside .debug_addr) of an address.
bool resolveDependenciesAndMarkLiveness(bool InterCUProcessingStarted, std::atomic< bool > &HasNewInterconnectedCUs)
Search for subprograms and variables referencing live code and discover dependend DIEs.
bool updateDependenciesCompleteness()
Check dependend DIEs for incompatible placement.
bool loadInputDIEs()
Load DIEs of input compilation unit.
const RangesTy & getFunctionRanges() const
Returns function ranges of this unit.
Error cloneAndEmitDebugMacro()
Clone and emit debug macros(.debug_macinfo/.debug_macro).
Error cloneAndEmit(std::optional< std::reference_wrapper< const Triple > > TargetTriple, TypeUnit *ArtificialTypeUnit)
Clone and emit this compilation unit.
void setStage(Stage Stage)
Set stage of overall processing.
Stage getStage() const
Returns stage of overall processing.
CompileUnit(LinkingGlobalData &GlobalData, unsigned ID, StringRef ClangModuleName, DWARFFile &File, OffsetToUnitTy UnitFromOffset, dwarf::FormParams Format, llvm::endianness Endianess)
void verifyDependencies()
Check DIEs to have a consistent marking(keep marking, placement marking).
Stage
The stages of new compile unit processing.
@ Cloned
Output DWARF is generated.
@ CreatedNotLoaded
Created, linked with input DWARF file.
@ Loaded
Input DWARF is loaded.
std::optional< uint64_t > getLowPc() const
Returns value of DW_AT_low_pc attribute.
std::optional< std::pair< StringRef, StringRef > > getDirAndFilenameFromLineTable(const DWARFFormValue &FileIdxValue)
Returns directory and file from the line table by index.
std::optional< UnitEntryPairTy > resolveDIEReference(const DWARFFormValue &RefValue, ResolveInterCUReferencesMode CanResolveInterCUReferences)
Resolve the DIE attribute reference that has been extracted in RefValue.
void loadLineTable()
Loads unit line table.
bool getModulePath(const DWARFDebugInfoEntry *DieEntry, SmallVectorImpl< char > &Path)
Appends the names of the DW_TAG_module enclosing DieEntry, outermost first.
uint64_t getPriority() const
StringEntry * getFileName(unsigned FileIdx, StringPool &GlobalStrings)
Returns name of the file for the FileIdx from the unit`s line table.
This class is a helper to create output DIE tree.
void addChild(DIE *Child)
Adds a specified Child to the current DIE.
DIE * createDIE(dwarf::Tag DieTag, uint32_t OutOffset)
Creates a DIE of specified tag DieTag and OutOffset.
This class discovers DIEs dependencies: marks "live" DIEs, marks DIE locations (whether DIE should be...
std::string UnitName
The name of this unit.
LinkingGlobalData & getGlobalData()
Return global data.
std::vector< std::unique_ptr< DIEAbbrev > > Abbreviations
Storage for the unique Abbreviations.
DIE * OutUnitDIE
Output unit DIE.
std::string SysRoot
The DW_AT_LLVM_sysroot of this unit.
bool isClangModule() const
Return true if this compile unit is from Clang module.
std::mutex FileNamesMutex
Guards FileNames.
unsigned ID
Unique ID for the unit.
const std::string & getClangModuleName() const
Return Clang module name;.
void setOutUnitDIE(DIE *UnitDie)
Set output unit DIE.
DwarfUnit(LinkingGlobalData &GlobalData, unsigned ID, StringRef ClangModuleName)
std::string ClangModuleName
If this is a Clang module, this holds the module's name.
FoldingSet< DIEAbbrev > AbbreviationsSet
FoldingSet that uniques the abbreviations.
StringRef getSysRoot()
Return the DW_AT_LLVM_sysroot of the compile unit or an empty StringRef.
DIE * getOutUnitDIE()
Returns output unit DIE.
This class keeps data and services common for the whole linking process.
ModulePool & getModulePool()
void set(StringRef Path, const ModuleAnchor &Location)
This class helps to assign indexes for DIE children.
LinkingGlobalData & GlobalData
dwarf::FormParams Format
Format for sections.
const dwarf::FormParams & getFormParams() const
Return size of address.
void eraseSections()
Erases data of all sections.
std::optional< const SectionDescriptor * > tryGetSectionDescriptor(DebugSectionKind SectionKind) const
Returns descriptor for the specified section of SectionKind.
void setOutputFormat(dwarf::FormParams Format, llvm::endianness Endianness)
Sets output format for all keeping sections.
uint16_t getVersion() const
Return DWARF version.
uint16_t getDebugInfoHeaderSize() const
Return size of header of debug_info table.
llvm::endianness getEndianness() const
Endiannes for the sections.
SectionDescriptor & getOrCreateSectionDescriptor(DebugSectionKind SectionKind)
Returns descriptor for the specified section of SectionKind.
const SectionDescriptor & getSectionDescriptor(DebugSectionKind SectionKind) const
Returns descriptor for the specified section of SectionKind.
The helper class to build type name based on DIE properties.
Error assignName(UnitEntryPairTy InputUnitEntryPair, std::optional< std::pair< size_t, size_t > > ChildIndex)
Create synthetic name for the specified DIE InputUnitEntryPair and assign created name to the DIE typ...
Keeps cloned data for the type DIE.
bool DeclarationParentIsDeclaration
uint64_t DeclarationDiePriority
std::atomic< uint32_t > SortKey
std::atomic< DIE * > DeclarationDie
std::atomic< DIE * > Die
TypeEntryBody keeps partially cloned DIEs corresponding to this type.
std::atomic< uint64_t > DiePriority
TypePool keeps type descriptors which contain partially cloned DIE correspinding to each type.
BumpPtrAllocator & getThreadLocalAllocator()
Return thread local allocator used by pool.
TypeEntryBody * getOrCreateTypeEntryBody(TypeEntry *Entry, TypeEntry *ParentEntry)
Create or return existing type entry body for the specified Entry.
TypeEntry * getRoot() const
Return root for all type entries.
Type Unit is used to represent an artificial compilation unit which keeps all type information.
TypePool & getTypePool()
Returns global type pool.
uint64_t tell() const
tell - Return the current offset with the file.
void rememberDieOutOffset(uint32_t Idx, uint64_t Offset)
Idx index of the DIE.
TypeEntry * getDieTypeEntry(uint32_t Idx)
Idx index of the DIE.
DIEInfo & getDIEInfo(unsigned Idx)
Idx index of the DIE.
uint64_t getDieOutOffset(uint32_t Idx)
Idx index of the DIE.
const DWARFDebugInfoEntry * getSiblingEntry(const DWARFDebugInfoEntry *Die) const
const DWARFDebugInfoEntry * getFirstChildEntry(const DWARFDebugInfoEntry *Die) const
std::optional< uint32_t > getDIEIndexForOffset(uint64_t Offset)
DWARFDie getDIE(const DWARFDebugInfoEntry *Die)
const DWARFDebugInfoEntry * getDebugInfoEntry(unsigned Index) const
DWARFUnit & getOrigUnit() const
Returns paired compile unit from input DWARF.
DWARFDie getUnitDIE(bool ExtractUnitDIEOnly=true)
DWARFDie getParent(const DWARFDebugInfoEntry *Die)
uint32_t getDIEIndex(const DWARFDebugInfoEntry *Die) const
std::optional< DWARFFormValue > find(uint32_t DieIdx, ArrayRef< dwarf::Attribute > Attrs) const
Error emitDebugInfo(const Triple &TargetTriple)
Emit .debug_info section for unit DIEs.
Error emitDebugLine(const Triple &TargetTriple, const DWARFDebugLine::LineTable &OutLineTable, ArrayRef< uint64_t > OrigRowIndices={}, DenseMap< uint64_t, uint64_t > *RowIndexToSeqStartOffset=nullptr)
Emit .debug_line section.
Error emitDebugStringOffsetSection()
Emit the .debug_str_offsets section for current unit.
void emitPubAccelerators()
Emit .debug_pubnames and .debug_pubtypes for Unit.
void warn(const Twine &Warning, const DWARFDie *DIE=nullptr)
Error emitAbbreviations()
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
bool isODRLanguage(uint16_t Language)
function_ref< CompileUnit *(uint64_t Offset)> OffsetToUnitTy
SmallVector< uint64_t * > OffsetsPtrVector
Type for list of pointers to patches offsets.
StringMapEntry< std::atomic< TypeEntryBody * > > TypeEntry
ArrayRef< dwarf::Attribute > getODRAttributes()
ResolveInterCUReferencesMode
StringRef guessDeveloperDir(StringRef SysRoot)
Make a best effort to guess the Xcode.app/Contents/Developer path from an SDK path.
DebugSectionKind
List of tracked debug tables.
LLVM_ABI void buildStmtSeqOffsetToFirstRowIndex(const DWARFDebugLine::LineTable <, ArrayRef< uint64_t > SortedStmtSeqOffsets, DenseMap< uint64_t, uint64_t > &SeqOffToFirstRow)
Build a map from an input DW_AT_LLVM_stmt_sequence byte offset to the first-row index (in LT....
StringMapEntry< EmptyStringSetTag > StringEntry
StringEntry keeps data of the string: the length, external offset and a string body which is placed r...
bool isInToolchainDir(StringRef Path)
Make a best effort to determine whether Path is inside a toolchain.
bool isPathAbsoluteOnWindowsOrPosix(const Twine &Path)
std::optional< uint64_t > toAddress(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an address.
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
std::optional< uint64_t > toSectionOffset(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an section offset.
StringRef toStringRef(const std::optional< DWARFFormValue > &V, StringRef Default={})
Take an optional DWARFFormValue and try to extract a string value from it.
std::optional< uint64_t > toUnsigned(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an unsigned constant.
@ DW_ARANGES_VERSION
Section version number for .debug_aranges.
LLVM_ABI std::error_code real_path(const Twine &path, SmallVectorImpl< char > &output, bool expand_tilde=false)
Collapse all .
LLVM_ABI StringRef parent_path(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get parent path.
LLVM_ABI bool is_relative(const Twine &path, Style style=Style::native)
Is path relative?
LLVM_ABI StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get filename.
LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
void swapByteOrder(T &Value)
This is an optimization pass for GlobalISel generic memory operations.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
void fill(R &&Range, T &&Value)
Provide wrappers to std::fill which take ranges instead of having to pass begin/end explicitly.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
auto partition_point(R &&Range, Predicate P)
Binary search for the first iterator in a range where a predicate is false.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
auto unique(Range &&R, Predicate P)
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
static void insertLineSequence(std::vector< TrackedRow > &Seq, std::vector< TrackedRow > &Rows)
Insert the new line info sequence Seq into the current set of already linked line info Rows.
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
auto reverse(ContainerTy &&C)
void sort(IteratorTy Start, IteratorTy End)
@ Dwarf
DWARF v5 .debug_names.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
uint64_t offsetToAlignment(uint64_t Value, Align Alignment)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
bool isCompileUnit(const std::unique_ptr< DWARFUnit > &U)
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
void consumeError(Error Err)
Consume a Error without doing anything.
dwarf::FormParams FormParams
Version, address size (starting in v5), and DWARF32/64 format; these parameters affect interpretation...
Standard .debug_line state machine structure.
object::SectionedAddress Address
The program-counter value corresponding to a machine instruction generated by the compiler and sectio...
Represents a single DWARF expression, whose value is location-dependent.
Information gathered about source DIEs.
LLVM_DUMP_METHOD void dump()
bool needToPlaceInTypeTable() const
DieOutputPlacement getPlacement() const
This structure is used to update a DW_AT_import reference to a DW_TAG_module.
This structure is used to update reference to the DIE.
uint64_t RefDieIdxOrClonedOffset
PointerIntPair< CompileUnit *, 1 > RefCU
This structure is used to update location list offset into .debug_loc/.debug_loclists.
int64_t AddrAdjustmentValue
This structure is used to update range list offset into .debug_ranges/.debug_rnglists.
bool IsCompileUnitRanges
Indicates patch which points to immediate compile unit's attribute.
This structure is used to update reference to the DIE of ULEB128 form.
uint64_t RefDieIdxOrClonedOffset
PointerIntPair< CompileUnit *, 1 > RefCU
Where the DW_TAG_module DIE describing a clang module ended up in the output.
uint64_t Priority
Priority of the unit which recorded this anchor.
SectionDescriptor * Section
dwarf::FormParams getFormParams() const
Returns FormParams used by section.
This structure is used to keep data of the concrete section.
raw_svector_ostream OS
Stream which stores data to the Contents.
void emitUnitLength(uint64_t Length)
Emit unit length into the current section contents.
void emitOffset(uint64_t Val)
Emit specified offset value into the current section contents.
void emitIntVal(uint64_t Val, unsigned Size)
Emit specified integer value into the current section contents.
void apply(uint64_t PatchOffset, dwarf::Form AttrForm, uint64_t Val)
Write specified Value of AttrForm to the PatchOffset.
uint64_t getIntVal(uint64_t PatchOffset, unsigned Size)
Returns integer value of Size located by specified PatchOffset.
This is a helper structure which keeps a debug info entry with it's containing compilation unit.
UnitEntryPairTy()=default
std::optional< UnitEntryPairTy > getParent()
UnitEntryPairTy getNamespaceOrigin()
const DWARFDebugInfoEntry * DieEntry