25using namespace dwarf_linker;
26using namespace dwarf_linker::parallel;
32 :
DwarfUnit(GlobalData,
ID, ClangModuleName), File(File),
33 getUnitFromOffset(UnitFromOffset),
Stage(
Stage::CreatedNotLoaded),
34 AcceleratorRecords(&GlobalData.getAllocator()) {
44 :
DwarfUnit(GlobalData,
ID, ClangModuleName), File(File),
45 OrigUnit(&OrigUnit), getUnitFromOffset(UnitFromOffset),
47 AcceleratorRecords(&GlobalData.getAllocator()) {
55 if (std::optional<DWARFFormValue> Val = CUDie.
find(dwarf::DW_AT_language)) {
86 Info.unsetFlagsWhichSetDuringLiveAnalysis();
92 Dependencies.reset(
nullptr);
99 AcceleratorRecords.
erase();
103 DebugAddrIndexMap.
clear();
128 bool IsODRUnavailableFunctionScope) {
135 bool ChildIsODRUnavailableFunctionScope = IsODRUnavailableFunctionScope;
137 if (DieInfo.getIsInMouduleScope())
138 ChildInfo.setIsInMouduleScope();
140 if (DieInfo.getIsInFunctionScope())
141 ChildInfo.setIsInFunctionScope();
143 if (DieInfo.getIsInAnonNamespaceScope())
144 ChildInfo.setIsInAnonNamespaceScope();
146 switch (CurChild->getTag()) {
147 case dwarf::DW_TAG_module:
148 ChildInfo.setIsInMouduleScope();
149 if (DieEntry->
getTag() == dwarf::DW_TAG_compile_unit &&
154 case dwarf::DW_TAG_subprogram:
155 ChildInfo.setIsInFunctionScope();
156 if (!ChildIsODRUnavailableFunctionScope &&
157 !ChildInfo.getIsInMouduleScope()) {
159 {dwarf::DW_AT_abstract_origin, dwarf::DW_AT_specification}))
160 ChildIsODRUnavailableFunctionScope =
true;
163 case dwarf::DW_TAG_namespace: {
166 if (
find(CurChild, dwarf::DW_AT_extension))
169 if (!NamespaceEntry.
CU->
find(NamespaceEntry.
DieEntry, dwarf::DW_AT_name))
170 ChildInfo.setIsInAnonNamespaceScope();
177 ChildInfo.setTrackLiveness();
179 if ((!ChildInfo.getIsInAnonNamespaceScope() &&
180 !ChildIsODRUnavailableFunctionScope && !NoODR))
181 ChildInfo.setODRAvailable();
183 if (CurChild->hasChildren())
184 analyzeDWARFStructureRec(CurChild, ChildIsODRUnavailableFunctionScope);
195 if (It == ResolvedFullPaths.
end()) {
196 std::string OrigFileName;
199 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
202 assert(FoundFileName &&
"Must get file name from line table");
212 ResolvedParentPaths.find(ParentPath);
213 if (ParentIt == ResolvedParentPaths.end()) {
218 .insert({ParentPath, GlobalStrings.
insert(RealPath).first})
226 It = ResolvedFullPaths
228 FileIdx, GlobalStrings.
insert(ResolvedPath).first))
242 ResolvedParentPaths.clear();
247 Dependencies.reset(
nullptr);
254 if (!Language || Language != dwarf::DW_LANG_Swift)
262 if (!Path.ends_with(
".swiftinterface"))
274 if (!DeveloperDir.
empty() && Path.starts_with(DeveloperDir))
278 if (std::optional<DWARFFormValue> Val =
find(DieEntry, dwarf::DW_AT_name)) {
293 if (!Entry.empty() && Entry != ResolvedPath) {
295 warn(
Twine(
"conflicting parseable interfaces for Swift Module ") + *
Name +
296 ": " + Entry +
" and " + Path +
".",
299 Entry = std::string(ResolvedPath);
321 assert(ChildInfo.getODRAvailable());
324 ChildrenIndexAssigner.getChildIndex(*
this, CurChild)))
327 if (
Error Err = assignTypeNamesRec(CurChild, NameBuilder))
335 if (std::optional<SectionDescriptor *> DebugInfoSection =
347 ->ListDebugULEB128DieRefPatch.forEach(
356 if (std::optional<SectionDescriptor *> DebugLocSection =
359 ->ListDebugULEB128DieRefPatch.forEach(
368 if (std::optional<SectionDescriptor *> DebugLocListsSection =
370 (*DebugLocListsSection)
371 ->ListDebugULEB128DieRefPatch.forEach(
384 if (std::optional<DWARFFormValue::UnitOffset>
Ref =
386 if (
Ref->Unit == OrigUnit) {
388 if (std::optional<uint32_t> RefDieIdx =
393 Ref->Unit ?
Ref->Unit->getOffset() +
Ref->Offset :
Ref->Offset;
394 if (
CompileUnit *RefCU = getUnitFromOffset(RefDIEOffset)) {
397 if (std::optional<uint32_t> RefDieIdx =
400 }
else if (CanResolveInterCUReferences) {
404 enum Stage ReferredCUStage = RefCU->getStage();
405 if (ReferredCUStage < Stage::Loaded || ReferredCUStage >
Stage::Cloned)
408 if (std::optional<uint32_t> RefDieIdx =
409 RefCU->getDIEIndexForOffset(RefDIEOffset))
422 if (std::optional<DWARFFormValue> AttrVal =
find(DieEntry, Attr))
430 std::lock_guard<std::mutex> Guard(RangesMutex);
432 Ranges.
insert({FuncLowPc, FuncHighPc}, PcOffset);
434 LowPc = std::min(*LowPc, FuncLowPc + PcOffset);
436 LowPc = FuncLowPc + PcOffset;
437 this->HighPc = std::max(HighPc, FuncHighPc + PcOffset);
441 std::lock_guard<std::mutex> Guard(LabelsMutex);
442 Labels.
insert({LabelLowPc, PcOffset});
462 if (!DebugInfoSection.ListDebugLocPatch.empty()) {
467 uint64_t OffsetAfterUnitLength = emitLocListHeader(OutLocationSection);
469 DebugInfoSection.ListDebugLocPatch.forEach([&](
DebugLocPatch &Patch) {
478 if (!OriginalLocations) {
479 warn(OriginalLocations.takeError());
483 LinkedLocationExpressionsVector LinkedLocationExpressions;
485 LinkedLocationExpressionsWithOffsetPatches LinkedExpression;
487 if (CurExpression.Range) {
489 LinkedExpression.Expression.Range = {
500 LinkedExpression.Expression.Expr,
502 LinkedExpression.Patches);
504 LinkedLocationExpressions.push_back({LinkedExpression});
509 OutLocationSection.
OS.
tell());
510 emitLocListFragment(LinkedLocationExpressions, OutLocationSection);
513 if (OffsetAfterUnitLength > 0) {
514 assert(OffsetAfterUnitLength -
516 OffsetAfterUnitLength);
517 OutLocationSection.
apply(
518 OffsetAfterUnitLength -
520 dwarf::DW_FORM_sec_offset,
521 OutLocationSection.
OS.
tell() - OffsetAfterUnitLength);
547 return OffsetAfterUnitLength;
551uint64_t CompileUnit::emitLocListFragment(
552 const LinkedLocationExpressionsVector &LinkedLocationExpression,
554 uint64_t OffsetBeforeLocationExpression = 0;
558 if (std::optional<uint64_t> LowPC =
getLowPc())
559 BaseAddress = *LowPC;
561 for (
const LinkedLocationExpressionsWithOffsetPatches &LocExpression :
562 LinkedLocationExpression) {
563 if (LocExpression.Expression.Range) {
565 LocExpression.Expression.Range->LowPC - BaseAddress,
568 LocExpression.Expression.Range->HighPC - BaseAddress,
572 OutLocationSection.
emitIntVal(LocExpression.Expression.Expr.size(), 2);
573 OffsetBeforeLocationExpression = OutLocationSection.
OS.
tell();
574 for (
uint64_t *OffsetPtr : LocExpression.Patches)
575 *OffsetPtr += OffsetBeforeLocationExpression;
577 OutLocationSection.
OS
578 <<
StringRef((
const char *)LocExpression.Expression.Expr.data(),
579 LocExpression.Expression.Expr.size());
587 return OffsetBeforeLocationExpression;
590 std::optional<uint64_t> BaseAddress;
591 for (
const LinkedLocationExpressionsWithOffsetPatches &LocExpression :
592 LinkedLocationExpression) {
593 if (LocExpression.Expression.Range) {
597 BaseAddress = LocExpression.Expression.Range->LowPC;
600 OutLocationSection.
emitIntVal(dwarf::DW_LLE_base_addressx, 1);
602 OutLocationSection.
OS);
606 OutLocationSection.
emitIntVal(dwarf::DW_LLE_offset_pair, 1);
609 encodeULEB128(LocExpression.Expression.Range->LowPC - *BaseAddress,
610 OutLocationSection.
OS);
613 encodeULEB128(LocExpression.Expression.Range->HighPC - *BaseAddress,
614 OutLocationSection.
OS);
617 OutLocationSection.
emitIntVal(dwarf::DW_LLE_default_location, 1);
619 encodeULEB128(LocExpression.Expression.Expr.size(), OutLocationSection.
OS);
620 OffsetBeforeLocationExpression = OutLocationSection.
OS.
tell();
621 for (
uint64_t *OffsetPtr : LocExpression.Patches)
622 *OffsetPtr += OffsetBeforeLocationExpression;
625 (
const char *)LocExpression.Expression.Expr.data(),
626 LocExpression.Expression.Expr.size());
630 OutLocationSection.
emitIntVal(dwarf::DW_LLE_end_of_list, 1);
631 return OffsetBeforeLocationExpression;
634Error CompileUnit::emitDebugAddrSection() {
641 if (DebugAddrIndexMap.
empty())
667 OutAddrSection.
apply(
668 OffsetAfterSectionLength -
670 dwarf::DW_FORM_sec_offset,
671 OutAddrSection.
OS.
tell() - OffsetAfterSectionLength);
683 LinkedFunctionRanges.
insert(
686 emitAranges(LinkedFunctionRanges);
704 if (!DebugInfoSection.ListDebugRangePatch.empty()) {
705 std::optional<AddressRangeValuePair> CachedRange;
706 uint64_t OffsetAfterUnitLength = emitRangeListHeader(OutRangeSection);
709 DebugInfoSection.ListDebugRangePatch.forEach([&](
DebugRangePatch &Patch) {
711 CompileUnitRangePtr = &Patch;
715 AddressRanges LinkedRanges;
716 uint64_t InputDebugRangesSectionOffset = DebugInfoSection.getIntVal(
718 DebugInfoSection.getFormParams().getDwarfOffsetByteSize());
719 if (Expected<DWARFAddressRangesVector> InputRanges =
720 getOrigUnit().findRnglistFromOffset(
721 InputDebugRangesSectionOffset)) {
723 for (const auto &Range : *InputRanges) {
724 if (!CachedRange || !CachedRange->Range.contains(Range.LowPC))
726 getFunctionRanges().getRangeThatContains(Range.LowPC);
730 warn(
"inconsistent range data.");
735 LinkedRanges.insert({Range.LowPC + CachedRange->Value,
736 Range.HighPC + CachedRange->Value});
739 llvm::consumeError(InputRanges.takeError());
740 warn(
"invalid range list ignored.");
745 OutRangeSection.
OS.
tell());
746 emitRangeListFragment(LinkedRanges, OutRangeSection);
750 if (CompileUnitRangePtr !=
nullptr) {
754 dwarf::DW_FORM_sec_offset,
755 OutRangeSection.
OS.
tell());
756 emitRangeListFragment(LinkedFunctionRanges, OutRangeSection);
759 if (OffsetAfterUnitLength > 0) {
760 assert(OffsetAfterUnitLength -
762 OffsetAfterUnitLength);
763 OutRangeSection.
apply(
764 OffsetAfterUnitLength -
766 dwarf::DW_FORM_sec_offset,
767 OutRangeSection.
OS.
tell() - OffsetAfterUnitLength);
792 return OffsetAfterUnitLength;
795void CompileUnit::emitRangeListFragment(
const AddressRanges &LinkedRanges,
800 if (std::optional<uint64_t> LowPC =
getLowPc())
801 BaseAddress = *LowPC;
816 std::optional<uint64_t> BaseAddress;
819 BaseAddress =
Range.start();
822 OutRangeSection.
emitIntVal(dwarf::DW_RLE_base_addressx, 1);
827 OutRangeSection.
emitIntVal(dwarf::DW_RLE_offset_pair, 1);
837 OutRangeSection.
emitIntVal(dwarf::DW_RLE_end_of_list, 1);
840void CompileUnit::emitAranges(
AddressRanges &LinkedFunctionRanges) {
841 if (LinkedFunctionRanges.
empty())
861 uint64_t OffsetAfterArangesLengthField = OutArangesSection.
OS.
tell();
864 OutArangesSection.notePatch(
889 OutArangesSection.
apply(
890 OffsetAfterArangesLengthField -
892 dwarf::DW_FORM_sec_offset,
893 OffsetAfterArangesEnd - OffsetAfterArangesLengthField);
904 if (std::optional<uint64_t> MacroAttr =
908 emitMacroTableImpl(Table, *MacroAttr,
true);
913 if (std::optional<uint64_t> MacroAttr =
917 emitMacroTableImpl(Table, *MacroAttr,
false);
926 bool hasDWARFv5Header) {
932 bool DefAttributeIsReported =
false;
933 bool UndefAttributeIsReported =
false;
934 bool ImportAttributeIsReported =
false;
936 for (
const DWARFDebugMacro::MacroList &
List : MacroTable->MacroLists) {
937 if (OffsetToMacroTable ==
List.Offset) {
939 if (hasDWARFv5Header) {
943 uint8_t Flags =
List.Header.Flags;
947 DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE) {
950 warn(
"opcode_operands_table is not supported yet.");
954 std::optional<uint64_t> StmtListOffset;
955 if (Flags & DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET) {
958 if (V.getAttribute() == dwarf::DW_AT_stmt_list) {
959 StmtListOffset = V.getDIEInteger().getValue();
964 if (!StmtListOffset) {
966 warn(
"couldn`t find line table for macro table.");
974 if (StmtListOffset) {
985 for (
const DWARFDebugMacro::Entry &MacroEntry :
List.Macros) {
986 if (MacroEntry.Type == 0) {
991 uint8_t MacroType = MacroEntry.Type;
994 bool HasVendorSpecificExtension =
995 (!hasDWARFv5Header &&
1000 if (HasVendorSpecificExtension) {
1008 OutSection.
emitString(dwarf::DW_FORM_string, MacroEntry.ExtStr);
1010 warn(
"unknown macro type. skip.");
1018 case dwarf::DW_MACRO_define:
1019 case dwarf::DW_MACRO_undef: {
1027 OutSection.
emitString(dwarf::DW_FORM_string, MacroEntry.MacroStr);
1029 case dwarf::DW_MACRO_define_strp:
1030 case dwarf::DW_MACRO_undef_strp:
1031 case dwarf::DW_MACRO_define_strx:
1032 case dwarf::DW_MACRO_undef_strx: {
1035 switch (MacroType) {
1036 case dwarf::DW_MACRO_define_strx: {
1037 MacroType = dwarf::DW_MACRO_define_strp;
1038 if (!DefAttributeIsReported) {
1039 warn(
"DW_MACRO_define_strx unsupported yet. Convert to "
1040 "DW_MACRO_define_strp.");
1041 DefAttributeIsReported =
true;
1044 case dwarf::DW_MACRO_undef_strx: {
1045 MacroType = dwarf::DW_MACRO_undef_strp;
1046 if (!UndefAttributeIsReported) {
1047 warn(
"DW_MACRO_undef_strx unsupported yet. Convert to "
1048 "DW_MACRO_undef_strp.");
1049 UndefAttributeIsReported =
true;
1064 OutSection.
emitString(dwarf::DW_FORM_strp, MacroEntry.MacroStr);
1067 case dwarf::DW_MACRO_start_file: {
1075 case dwarf::DW_MACRO_end_file: {
1079 case dwarf::DW_MACRO_import:
1080 case dwarf::DW_MACRO_import_sup: {
1081 if (!ImportAttributeIsReported) {
1082 warn(
"DW_MACRO_import and DW_MACRO_import_sup are unsupported "
1084 ImportAttributeIsReported =
true;
1098 std::optional<int64_t> VarAddressAdjustment,
1106 for (
auto &
Op : InputExpression) {
1112 Desc.
Op[0] != Encoding::Size1))
1113 warn(
"unsupported DW_OP encoding.");
1117 Desc.
Op[0] == Encoding::Size1)) {
1135 unsigned RealSize = 0;
1139 if (RefOffset > 0 ||
Op.
getCode() != dwarf::DW_OP_convert) {
1142 if (std::optional<uint32_t>
Idx =
1152 Section.notePatchWithOffsetUpdate(
1159 if (RealSize > ULEBsize) {
1162 warn(
"base type ref doesn't fit.");
1164 assert(RealSize == ULEBsize &&
"padding failed");
1167 }
else if (!
getGlobalData().getOptions().UpdateIndexTablesOnly &&
1169 if (std::optional<object::SectionedAddress> SA =
1175 OutputExpression.
push_back(dwarf::DW_OP_addr);
1177 SA->Address + (VarAddressAdjustment ? *VarAddressAdjustment : 0);
1181 reinterpret_cast<const uint8_t *
>(&LinkedAddress),
1182 OrigAddressByteSize);
1183 OutputExpression.
append(AddressBytes.
begin(), AddressBytes.
end());
1185 warn(
"cann't read DW_OP_addrx operand.");
1186 }
else if (!
getGlobalData().getOptions().UpdateIndexTablesOnly &&
1188 if (std::optional<object::SectionedAddress> SA =
1194 std::optional<uint8_t> OutOperandKind;
1195 switch (OrigAddressByteSize) {
1197 OutOperandKind = dwarf::DW_OP_const2u;
1200 OutOperandKind = dwarf::DW_OP_const4u;
1203 OutOperandKind = dwarf::DW_OP_const8u;
1207 formatv((
"unsupported address size: {0}."), OrigAddressByteSize));
1211 if (OutOperandKind) {
1212 OutputExpression.
push_back(*OutOperandKind);
1214 SA->Address + (VarAddressAdjustment ? *VarAddressAdjustment : 0);
1218 reinterpret_cast<const uint8_t *
>(&LinkedAddress),
1219 OrigAddressByteSize);
1220 OutputExpression.
append(AddressBytes.
begin(), AddressBytes.
end());
1223 warn(
"cann't read DW_OP_constx operand.");
1235 std::optional<std::reference_wrapper<const Triple>> TargetTriple,
1244 if (ArtificialTypeUnit)
1248 std::pair<DIE *, TypeEntry *> OutCUDie =
cloneDIE(
1250 std::nullopt, std::nullopt,
Allocator, ArtificialTypeUnit);
1253 if (!TargetTriple.has_value() || (OutCUDie.first ==
nullptr))
1276 if (
Error Err = emitDebugAddrSection())
1292 uint64_t OutOffset, std::optional<int64_t> FuncAddressAdjustment,
1298 bool NeedToClonePlainDIE =
Info.needToKeepInPlainDwarf();
1299 bool NeedToCloneTypeDIE =
1300 (InputDieEntry->
getTag() != dwarf::DW_TAG_compile_unit) &&
1301 Info.needToPlaceInTypeTable();
1302 std::pair<DIE *, TypeEntry *> ClonedDIE;
1306 if (NeedToClonePlainDIE)
1309 ClonedDIE.first = createPlainDIEandCloneAttributes(
1310 InputDieEntry, PlainDIEGenerator, OutOffset, FuncAddressAdjustment,
1311 VarAddressAdjustment);
1312 if (NeedToCloneTypeDIE) {
1315 assert(ArtificialTypeUnit !=
nullptr);
1319 ClonedDIE.second = createTypeDIEandCloneAttributes(
1320 InputDieEntry, TypeDIEGenerator, ClonedParentTypeDIE,
1321 ArtificialTypeUnit);
1324 ClonedDIE.
second ? ClonedDIE.second : ClonedParentTypeDIE;
1326 bool HasPlainChildrenToClone =
1327 (ClonedDIE.first &&
Info.getKeepPlainChildren());
1329 bool HasTypeChildrenToClone =
1330 ((ClonedDIE.second ||
1331 InputDieEntry->
getTag() == dwarf::DW_TAG_compile_unit) &&
1332 Info.getKeepTypeChildren());
1335 if (HasPlainChildrenToClone || HasTypeChildrenToClone) {
1340 std::pair<DIE *, TypeEntry *> ClonedChild =
cloneDIE(
1341 CurChild, TypeParentForChild, OutOffset, FuncAddressAdjustment,
1342 VarAddressAdjustment,
Allocator, ArtificialTypeUnit);
1344 if (ClonedChild.first) {
1346 ClonedChild.first->getOffset() + ClonedChild.first->getSize();
1347 PlainDIEGenerator.
addChild(ClonedChild.first);
1350 assert(ClonedDIE.first ==
nullptr ||
1351 HasPlainChildrenToClone == ClonedDIE.first->hasChildren());
1354 if (HasPlainChildrenToClone)
1355 OutOffset +=
sizeof(int8_t);
1359 if (ClonedDIE.first !=
nullptr)
1360 ClonedDIE.first->setSize(OutOffset - ClonedDIE.first->getOffset());
1365DIE *CompileUnit::createPlainDIEandCloneAttributes(
1367 uint64_t &OutOffset, std::optional<int64_t> &FuncAddressAdjustment,
1368 std::optional<int64_t> &VarAddressAdjustment) {
1371 DIE *ClonedDIE =
nullptr;
1372 bool HasLocationExpressionAddress =
false;
1373 if (InputDieEntry->
getTag() == dwarf::DW_TAG_subprogram) {
1375 FuncAddressAdjustment =
1377 getDIE(InputDieEntry),
false);
1378 }
else if (InputDieEntry->
getTag() == dwarf::DW_TAG_label) {
1380 std::optional<uint64_t> lowPC =
1384 if (It != Labels.
end())
1385 FuncAddressAdjustment = It->second;
1387 }
else if (InputDieEntry->
getTag() == dwarf::DW_TAG_variable) {
1389 std::pair<bool, std::optional<int64_t>> LocExprAddrAndRelocAdjustment =
1391 getDIE(InputDieEntry),
false);
1393 HasLocationExpressionAddress = LocExprAddrAndRelocAdjustment.first;
1394 if (LocExprAddrAndRelocAdjustment.first &&
1395 LocExprAddrAndRelocAdjustment.second)
1396 VarAddressAdjustment = *LocExprAddrAndRelocAdjustment.second;
1399 ClonedDIE = PlainDIEGenerator.
createDIE(InputDieEntry->
getTag(), OutOffset);
1407 PlainDIEGenerator, FuncAddressAdjustment,
1408 VarAddressAdjustment,
1409 HasLocationExpressionAddress);
1410 AttributesCloner.clone();
1414 AccelRecordsSaver.save(InputDieEntry, ClonedDIE, AttributesCloner.AttrInfo,
1418 AttributesCloner.finalizeAbbreviations(
Info.getKeepPlainChildren());
1427 bool IsParentDeclaration) {
1428 DIE *DefinitionDie = TypeDescriptor->
Die;
1436 if (IsDeclaration && !DeclarationDie) {
1439 if (TypeDescriptor->
DeclarationDie.compare_exchange_weak(DeclarationDie,
1442 }
else if (IsDeclaration && !IsParentDeclaration && OldParentIsDeclaration) {
1446 OldParentIsDeclaration,
false)) {
1451 }
else if (!IsDeclaration && IsParentDeclaration && !DeclarationDie) {
1455 if (TypeDescriptor->
DeclarationDie.compare_exchange_weak(DeclarationDie,
1458 }
else if (!IsDeclaration && !IsParentDeclaration) {
1461 if (TypeDescriptor->
Die.compare_exchange_weak(DefinitionDie, NewDie)) {
1470TypeEntry *CompileUnit::createTypeDIEandCloneAttributes(
1473 assert(ArtificialTypeUnit !=
nullptr);
1477 assert(Entry !=
nullptr);
1478 assert(ClonedParentTypeDIE !=
nullptr);
1481 Entry, ClonedParentTypeDIE);
1484 bool IsDeclaration =
1487 bool ParentIsDeclaration =
false;
1488 if (std::optional<uint32_t> ParentIdx = InputDieEntry->
getParentIdx())
1489 ParentIsDeclaration =
1493 allocateTypeDie(EntryBody, TypeDIEGenerator, InputDieEntry->
getTag(),
1494 IsDeclaration, ParentIsDeclaration);
1496 if (OutDIE !=
nullptr) {
1497 assert(ArtificialTypeUnit !=
nullptr);
1501 InputDieEntry, TypeDIEGenerator,
1502 std::nullopt, std::nullopt,
false);
1503 AttributesCloner.clone();
1507 ArtificialTypeUnit);
1508 AccelRecordsSaver.save(InputDieEntry, OutDIE, AttributesCloner.AttrInfo,
1513 OutDIE->
setSize(AttributesCloner.getOutOffset() + 1);
1522 if (InputLineTable ==
nullptr) {
1524 warn(
"cann't load line table.");
1536 OutLineTable.
Rows = InputLineTable->
Rows;
1539 if (OutLineTable.
Rows.size() == 1 && OutLineTable.
Rows[0].EndSequence)
1540 OutLineTable.
Rows.clear();
1545 std::vector<DWARFDebugLine::Row> NewRows;
1546 NewRows.reserve(InputLineTable->
Rows.size());
1550 std::vector<DWARFDebugLine::Row> Seq;
1553 std::optional<AddressRangeValuePair> CurrRange;
1572 if (!CurrRange || !CurrRange->Range.contains(Row.Address.Address)) {
1576 CurrRange ? CurrRange->Range.end() + CurrRange->Value : -1ULL;
1577 CurrRange = FunctionRanges.getRangeThatContains(Row.Address.Address);
1578 if (StopAddress != -1ULL && !Seq.empty()) {
1581 auto NextLine = Seq.back();
1582 NextLine.Address.Address = StopAddress;
1583 NextLine.EndSequence = 1;
1584 NextLine.PrologueEnd = 0;
1585 NextLine.BasicBlock = 0;
1586 NextLine.EpilogueBegin = 0;
1587 Seq.push_back(NextLine);
1588 insertLineSequence(Seq, NewRows);
1596 if (Row.EndSequence && Seq.empty())
1600 Row.Address.Address += CurrRange->Value;
1601 Seq.emplace_back(Row);
1603 if (Row.EndSequence)
1604 insertLineSequence(Seq, NewRows);
1607 OutLineTable.
Rows = std::move(NewRows);
1613void CompileUnit::insertLineSequence(std::vector<DWARFDebugLine::Row> &Seq,
1614 std::vector<DWARFDebugLine::Row> &Rows) {
1618 if (!Rows.empty() && Rows.back().Address < Seq.front().Address) {
1632 if (InsertPoint != Rows.end() && InsertPoint->Address == Front &&
1633 InsertPoint->EndSequence) {
1634 *InsertPoint = Seq.front();
1635 Rows.insert(InsertPoint + 1, Seq.begin() + 1, Seq.end());
1637 Rows.insert(InsertPoint, Seq.begin(), Seq.end());
1643#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1663 llvm::errs() <<
" KeepPlainChildren: " << getKeepPlainChildren();
1664 llvm::errs() <<
" KeepTypeChildren: " << getKeepTypeChildren();
1665 llvm::errs() <<
" IsInMouduleScope: " << getIsInMouduleScope();
1666 llvm::errs() <<
" IsInFunctionScope: " << getIsInFunctionScope();
1667 llvm::errs() <<
" IsInAnonNamespaceScope: " << getIsInAnonNamespaceScope();
1668 llvm::errs() <<
" ODRAvailable: " << getODRAvailable();
1669 llvm::errs() <<
" TrackLiveness: " << getTrackLiveness();
1674std::optional<std::pair<StringRef, StringRef>>
1685 return std::nullopt;
1690std::optional<std::pair<StringRef, StringRef>>
1694 return std::make_pair(
StringRef(FileData->second.first),
1699 if (LineTable->hasFileAtIndex(FileIdx)) {
1702 LineTable->Prologue.getFileNameEntry(FileIdx);
1707 return std::nullopt;
1710 std::string FileName = *
Name;
1716 std::make_pair(std::string(
""), std::move(FileName))))
1718 return std::make_pair(
StringRef(FileData->second.first),
1728 if ((Entry.DirIdx != 0) &&
1729 Entry.DirIdx < LineTable->Prologue.IncludeDirectories.size()) {
1731 LineTable->Prologue.IncludeDirectories[Entry.DirIdx]
1734 IncludeDir = *DirName;
1737 return std::nullopt;
1741 if (0 < Entry.DirIdx &&
1742 Entry.DirIdx <= LineTable->Prologue.IncludeDirectories.size()) {
1744 LineTable->Prologue.IncludeDirectories[Entry.DirIdx - 1]
1747 IncludeDir = *DirName;
1750 return std::nullopt;
1766 std::make_pair(FileIdx, std::make_pair(std::string(FilePath),
1767 std::move(FileName))))
1769 return std::make_pair(
StringRef(FileData->second.first),
1774 return std::nullopt;
1777#define MAX_REFERENCIES_DEPTH 1000
1780 std::optional<UnitEntryPairTy> RefDiePair;
1784 CUDiePair.
DieEntry, dwarf::DW_AT_extension,
1786 if (!RefDiePair || !RefDiePair->DieEntry)
1789 CUDiePair = *RefDiePair;
1796 if (std::optional<uint32_t> ParentIdx = DieEntry->
getParentIdx())
1799 return std::nullopt;
1813 return getAsCompileUnit();
1815 return getAsTypeUnit();
1835 bool InterCUProcessingStarted, std::atomic<bool> &HasNewInterconnectedCUs) {
1836 if (!Dependencies.get())
1839 return Dependencies->resolveDependenciesAndMarkLiveness(
1840 InterCUProcessingStarted, HasNewInterconnectedCUs);
1844 assert(Dependencies.get());
1846 return Dependencies.get()->updateDependenciesCompleteness();
1850 assert(Dependencies.get());
1852 Dependencies.get()->verifyKeepChain();
1857 dwarf::DW_AT_type, dwarf::DW_AT_specification,
1858 dwarf::DW_AT_abstract_origin, dwarf::DW_AT_import};
1860 return ODRAttributes;
Analysis containing CSE Info
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
Mark the given Function as meaning that it cannot be changed in any way mark any values that are used as this function s parameters or by its return values(according to Uses) live as well. void DeadArgumentEliminationPass
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_>.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A class that represents an address range.
void insert(AddressRange Range, int64_t Value)
The AddressRanges class helps normalize address range collections.
Collection::const_iterator insert(AddressRange Range)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Allocate memory in an ever growing pool, as if by bump-pointer.
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.
std::optional< DWARFFormValue > find(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE.
const DWARFDebugInfoEntry * getDebugInfoEntry() const
const char * getName(DINameKind Kind) const
Return the DIE name resolving DW_AT_specification or DW_AT_abstract_origin references if necessary.
This class represents an Operation in the Expression.
std::optional< unsigned > getSubCode() const
uint64_t getEndOffset() const
Encoding
Size and signedness of expression operations' operands.
const Description & getDescription() const
uint64_t getRawOperand(unsigned Idx) const
StringRef getData() const
const DWARFDebugInfoEntry * getDebugInfoEntry(unsigned Index) const
Return DWARFDebugInfoEntry for the specified index Index.
const dwarf::FormParams & getFormParams() const
DWARFDie getUnitDIE(bool ExtractUnitDIEOnly=true)
uint8_t getAddressByteSize() const
const char * getCompilationDir()
std::optional< uint32_t > getDIEIndexForOffset(uint64_t Offset)
Return the DIE index for a given offset Offset inside the unit's DIE vector.
Expected< DWARFLocationExpressionsVector > findLoclistFromOffset(uint64_t Offset)
bool isLittleEndian() const
std::optional< object::SectionedAddress > getAddrOffsetSectionItem(uint32_t Index) const
uint64_t getOffset() const
iterator find(const_arg_type_t< KeyT > Val)
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT > 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 append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
constexpr bool empty() const
empty - 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
uint64_t getValueIndex(T Value)
const SmallVector< T > & getValues() const
CompileUnit(DWARFUnit &OrigUnit, unsigned ID, bool CanUseODR, StringRef ClangModuleName)
This class helps to store information for accelerator entries.
TypeUnit * getAsTypeUnit()
Returns TypeUnit if applicable.
DwarfUnit * operator->()
Accessor for common functionality.
CompileUnit * getAsCompileUnit()
Returns CompileUnit if applicable.
OutputUnitVariantPtr(CompileUnit *U)
Stores all information related to a compile unit, be it in its original instance of the object file o...
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)
void cleanupDataAfterClonning()
Cleanup unneeded resources after compile unit is cloned.
Error assignTypeNames(TypePool &TypePoolRef)
Search for type entries and assign names.
@ Both
Corresponding DIE goes to type table and to plain dwarf.
@ TypeTable
Corresponding DIE goes to the type table only.
@ PlainDwarf
Corresponding DIE goes to the plain dwarf only.
Error cloneAndEmitLineTable(const Triple &TargetTriple)
Error cloneAndEmitRanges()
Clone and emit ranges.
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.
const DWARFFile & getContaingFile() const
Returns DWARFFile containing this compile unit.
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.
StringEntry * getFileName(unsigned FileIdx, StringPool &GlobalStrings)
Returns name of the file for the FileIdx from the unit`s line table.
This class creates clones of input DIE attributes.
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...
Base class for all Dwarf units(Compile unit/Type table unit).
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.
const std::string & getClangModuleName() const
Return Clang module name;.
void setOutUnitDIE(DIE *UnitDie)
Set output unit DIE.
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.
const DWARFLinkerOptions & getOptions() const
Returns linking options.
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.
std::atomic< bool > ParentIsDeclaration
std::atomic< DIE * > DeclarationDie
std::atomic< DIE * > Die
TypeEntryBody keeps partially cloned DIEs corresponding to this type.
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)
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 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()
Error emitDebugLine(const Triple &TargetTriple, const DWARFDebugLine::LineTable &OutLineTable)
Emit .debug_line section.
bool isODRLanguage(uint16_t Language)
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.
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.
std::error_code real_path(const Twine &path, SmallVectorImpl< char > &output, bool expand_tilde=false)
Collapse all .
bool is_relative(const Twine &path, Style style=Style::native)
Is path relative?
StringRef filename(StringRef path, Style style=Style::native)
Get filename.
StringRef parent_path(StringRef path, Style style=Style::native)
Get parent path.
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 partition_point(R &&Range, Predicate P)
Binary search for the first iterator in a range where a predicate is false.
auto formatv(const char *Fmt, Ts &&...Vals) -> formatv_object< decltype(std::make_tuple(support::detail::build_format_adapter(std::forward< Ts >(Vals))...))>
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
@ Dwarf
DWARF v5 .debug_names.
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...
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Ref
The access may reference the value stored in memory.
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)
This struct is a compact representation of a valid (non-zero power of two) alignment.
bool hasFileAtIndex(uint64_t FileIndex) const
bool getFileNameByIndex(uint64_t FileIndex, StringRef CompDir, DILineInfoSpecifier::FileLineInfoKind Kind, std::string &Result) const
Extracts filename by its index in filename table in prologue.
dwarf::FormParams FormParams
Version, address size (starting in v5), and DWARF32/64 format; these parameters affect interpretation...
Standard .debug_line state machine structure.
Description of the encoding of one expression Op.
SmallVector< Encoding > Op
Encoding for Op operands.
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
DWARFLinkerBase::SwiftInterfacesMapTy * ParseableSwiftInterfaces
A list of all .swiftinterface files referenced by the debug info, mapping Module name to path on disk...
SmallVector< DWARFLinkerBase::AccelTableKind, 1 > AccelTables
The accelerator table kinds.
bool NoODR
Do not unique types according to ODR.
bool UpdateIndexTablesOnly
Update index tables.
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
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 emitString(dwarf::Form StringForm, const char *StringVal)
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.
std::optional< UnitEntryPairTy > getParent()
UnitEntryPairTy getNamespaceOrigin()
const DWARFDebugInfoEntry * DieEntry