24using namespace dwarf_linker;
25using namespace dwarf_linker::parallel;
31 :
DwarfUnit(GlobalData,
ID, ClangModuleName), File(File),
32 getUnitFromOffset(UnitFromOffset),
Stage(
Stage::CreatedNotLoaded),
33 AcceleratorRecords(&GlobalData.getAllocator()) {
43 :
DwarfUnit(GlobalData,
ID, ClangModuleName), File(File),
44 OrigUnit(&OrigUnit), getUnitFromOffset(UnitFromOffset),
46 AcceleratorRecords(&GlobalData.getAllocator()) {
54 if (std::optional<DWARFFormValue> Val = CUDie.
find(dwarf::DW_AT_language)) {
85 Info.unsetFlagsWhichSetDuringLiveAnalysis();
91 Dependencies.reset(
nullptr);
98 AcceleratorRecords.
erase();
102 DebugAddrIndexMap.
clear();
125 bool IsODRUnavailableFunctionScope) {
132 bool ChildIsODRUnavailableFunctionScope = IsODRUnavailableFunctionScope;
134 if (DieInfo.getIsInMouduleScope())
135 ChildInfo.setIsInMouduleScope();
137 if (DieInfo.getIsInFunctionScope())
138 ChildInfo.setIsInFunctionScope();
140 if (DieInfo.getIsInAnonNamespaceScope())
141 ChildInfo.setIsInAnonNamespaceScope();
143 switch (CurChild->getTag()) {
144 case dwarf::DW_TAG_module:
145 ChildInfo.setIsInMouduleScope();
146 if (DieEntry->
getTag() == dwarf::DW_TAG_compile_unit &&
151 case dwarf::DW_TAG_subprogram:
152 ChildInfo.setIsInFunctionScope();
153 if (!ChildIsODRUnavailableFunctionScope &&
154 !ChildInfo.getIsInMouduleScope()) {
156 {dwarf::DW_AT_abstract_origin, dwarf::DW_AT_specification}))
157 ChildIsODRUnavailableFunctionScope =
true;
160 case dwarf::DW_TAG_namespace: {
163 if (
find(CurChild, dwarf::DW_AT_extension))
166 if (!NamespaceEntry.
CU->
find(NamespaceEntry.
DieEntry, dwarf::DW_AT_name))
167 ChildInfo.setIsInAnonNamespaceScope();
174 ChildInfo.setTrackLiveness();
176 if ((!ChildInfo.getIsInAnonNamespaceScope() &&
177 !ChildIsODRUnavailableFunctionScope && !NoODR))
178 ChildInfo.setODRAvailable();
180 if (CurChild->hasChildren())
181 analyzeDWARFStructureRec(CurChild, ChildIsODRUnavailableFunctionScope);
192 if (It == ResolvedFullPaths.
end()) {
193 std::string OrigFileName;
196 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
199 assert(FoundFileName &&
"Must get file name from line table");
209 ResolvedParentPaths.find(ParentPath);
210 if (ParentIt == ResolvedParentPaths.end()) {
215 .insert({ParentPath, GlobalStrings.
insert(RealPath).first})
223 It = ResolvedFullPaths
225 FileIdx, GlobalStrings.
insert(ResolvedPath).first))
239 ResolvedParentPaths.clear();
244 Dependencies.reset(
nullptr);
251 if (!Language || Language != dwarf::DW_LANG_Swift)
259 if (!Path.ends_with(
".swiftinterface"))
271 if (!DeveloperDir.
empty() && Path.starts_with(DeveloperDir))
275 if (std::optional<DWARFFormValue> Val =
find(DieEntry, dwarf::DW_AT_name)) {
290 if (!Entry.empty() && Entry != ResolvedPath) {
292 warn(
Twine(
"conflicting parseable interfaces for Swift Module ") + *
Name +
293 ": " + Entry +
" and " + Path +
".",
296 Entry = std::string(ResolvedPath);
318 assert(ChildInfo.getODRAvailable());
321 ChildrenIndexAssigner.getChildIndex(*
this, CurChild)))
324 if (
Error Err = assignTypeNamesRec(CurChild, NameBuilder))
332 if (std::optional<SectionDescriptor *> DebugInfoSection =
344 ->ListDebugULEB128DieRefPatch.forEach(
353 if (std::optional<SectionDescriptor *> DebugLocSection =
356 ->ListDebugULEB128DieRefPatch.forEach(
365 if (std::optional<SectionDescriptor *> DebugLocListsSection =
367 (*DebugLocListsSection)
368 ->ListDebugULEB128DieRefPatch.forEach(
387 RefCU = getUnitFromOffset(*
Offset);
397 }
else if (RefCU && CanResolveInterCUReferences) {
402 if (ReferredCUStage < Stage::Loaded || ReferredCUStage >
Stage::Cloned)
405 if (std::optional<uint32_t> RefDieIdx =
417 if (std::optional<DWARFFormValue> AttrVal =
find(DieEntry, Attr))
425 std::lock_guard<std::mutex> Guard(RangesMutex);
427 Ranges.
insert({FuncLowPc, FuncHighPc}, PcOffset);
429 LowPc = std::min(*LowPc, FuncLowPc + PcOffset);
431 LowPc = FuncLowPc + PcOffset;
432 this->HighPc = std::max(HighPc, FuncHighPc + PcOffset);
436 std::lock_guard<std::mutex> Guard(LabelsMutex);
437 Labels.
insert({LabelLowPc, PcOffset});
457 if (!DebugInfoSection.ListDebugLocPatch.empty()) {
462 uint64_t OffsetAfterUnitLength = emitLocListHeader(OutLocationSection);
464 DebugInfoSection.ListDebugLocPatch.forEach([&](
DebugLocPatch &Patch) {
473 if (!OriginalLocations) {
474 warn(OriginalLocations.takeError());
478 LinkedLocationExpressionsVector LinkedLocationExpressions;
480 LinkedLocationExpressionsWithOffsetPatches LinkedExpression;
482 if (CurExpression.Range) {
484 LinkedExpression.Expression.Range = {
495 LinkedExpression.Expression.Expr,
497 LinkedExpression.Patches);
499 LinkedLocationExpressions.push_back({LinkedExpression});
504 OutLocationSection.
OS.
tell());
505 emitLocListFragment(LinkedLocationExpressions, OutLocationSection);
508 if (OffsetAfterUnitLength > 0) {
509 assert(OffsetAfterUnitLength -
511 OffsetAfterUnitLength);
512 OutLocationSection.
apply(
513 OffsetAfterUnitLength -
515 dwarf::DW_FORM_sec_offset,
516 OutLocationSection.
OS.
tell() - OffsetAfterUnitLength);
542 return OffsetAfterUnitLength;
546uint64_t CompileUnit::emitLocListFragment(
547 const LinkedLocationExpressionsVector &LinkedLocationExpression,
549 uint64_t OffsetBeforeLocationExpression = 0;
553 if (std::optional<uint64_t> LowPC =
getLowPc())
554 BaseAddress = *LowPC;
556 for (
const LinkedLocationExpressionsWithOffsetPatches &LocExpression :
557 LinkedLocationExpression) {
558 if (LocExpression.Expression.Range) {
560 LocExpression.Expression.Range->LowPC - BaseAddress,
563 LocExpression.Expression.Range->HighPC - BaseAddress,
567 OutLocationSection.
emitIntVal(LocExpression.Expression.Expr.size(), 2);
568 OffsetBeforeLocationExpression = OutLocationSection.
OS.
tell();
569 for (
uint64_t *OffsetPtr : LocExpression.Patches)
570 *OffsetPtr += OffsetBeforeLocationExpression;
572 OutLocationSection.
OS
573 <<
StringRef((
const char *)LocExpression.Expression.Expr.data(),
574 LocExpression.Expression.Expr.size());
582 return OffsetBeforeLocationExpression;
585 std::optional<uint64_t> BaseAddress;
586 for (
const LinkedLocationExpressionsWithOffsetPatches &LocExpression :
587 LinkedLocationExpression) {
588 if (LocExpression.Expression.Range) {
592 BaseAddress = LocExpression.Expression.Range->LowPC;
595 OutLocationSection.
emitIntVal(dwarf::DW_LLE_base_addressx, 1);
597 OutLocationSection.
OS);
601 OutLocationSection.
emitIntVal(dwarf::DW_LLE_offset_pair, 1);
604 encodeULEB128(LocExpression.Expression.Range->LowPC - *BaseAddress,
605 OutLocationSection.
OS);
608 encodeULEB128(LocExpression.Expression.Range->HighPC - *BaseAddress,
609 OutLocationSection.
OS);
612 OutLocationSection.
emitIntVal(dwarf::DW_LLE_default_location, 1);
614 encodeULEB128(LocExpression.Expression.Expr.size(), OutLocationSection.
OS);
615 OffsetBeforeLocationExpression = OutLocationSection.
OS.
tell();
616 for (
uint64_t *OffsetPtr : LocExpression.Patches)
617 *OffsetPtr += OffsetBeforeLocationExpression;
620 (
const char *)LocExpression.Expression.Expr.data(),
621 LocExpression.Expression.Expr.size());
625 OutLocationSection.
emitIntVal(dwarf::DW_LLE_end_of_list, 1);
626 return OffsetBeforeLocationExpression;
629Error CompileUnit::emitDebugAddrSection() {
636 if (DebugAddrIndexMap.
empty())
662 OutAddrSection.
apply(
663 OffsetAfterSectionLength -
665 dwarf::DW_FORM_sec_offset,
666 OutAddrSection.
OS.
tell() - OffsetAfterSectionLength);
678 LinkedFunctionRanges.
insert(
681 emitAranges(LinkedFunctionRanges);
699 if (!DebugInfoSection.ListDebugRangePatch.empty()) {
700 std::optional<AddressRangeValuePair> CachedRange;
701 uint64_t OffsetAfterUnitLength = emitRangeListHeader(OutRangeSection);
704 DebugInfoSection.ListDebugRangePatch.forEach([&](
DebugRangePatch &Patch) {
706 CompileUnitRangePtr = &Patch;
710 AddressRanges LinkedRanges;
711 uint64_t InputDebugRangesSectionOffset = DebugInfoSection.getIntVal(
713 DebugInfoSection.getFormParams().getDwarfOffsetByteSize());
714 if (Expected<DWARFAddressRangesVector> InputRanges =
715 getOrigUnit().findRnglistFromOffset(
716 InputDebugRangesSectionOffset)) {
718 for (const auto &Range : *InputRanges) {
719 if (!CachedRange || !CachedRange->Range.contains(Range.LowPC))
721 getFunctionRanges().getRangeThatContains(Range.LowPC);
725 warn(
"inconsistent range data.");
730 LinkedRanges.insert({Range.LowPC + CachedRange->Value,
731 Range.HighPC + CachedRange->Value});
734 llvm::consumeError(InputRanges.takeError());
735 warn(
"invalid range list ignored.");
740 OutRangeSection.
OS.
tell());
741 emitRangeListFragment(LinkedRanges, OutRangeSection);
745 if (CompileUnitRangePtr !=
nullptr) {
749 dwarf::DW_FORM_sec_offset,
750 OutRangeSection.
OS.
tell());
751 emitRangeListFragment(LinkedFunctionRanges, OutRangeSection);
754 if (OffsetAfterUnitLength > 0) {
755 assert(OffsetAfterUnitLength -
757 OffsetAfterUnitLength);
758 OutRangeSection.
apply(
759 OffsetAfterUnitLength -
761 dwarf::DW_FORM_sec_offset,
762 OutRangeSection.
OS.
tell() - OffsetAfterUnitLength);
787 return OffsetAfterUnitLength;
790void CompileUnit::emitRangeListFragment(
const AddressRanges &LinkedRanges,
795 if (std::optional<uint64_t> LowPC =
getLowPc())
796 BaseAddress = *LowPC;
811 std::optional<uint64_t> BaseAddress;
814 BaseAddress =
Range.start();
817 OutRangeSection.
emitIntVal(dwarf::DW_RLE_base_addressx, 1);
822 OutRangeSection.
emitIntVal(dwarf::DW_RLE_offset_pair, 1);
832 OutRangeSection.
emitIntVal(dwarf::DW_RLE_end_of_list, 1);
835void CompileUnit::emitAranges(
AddressRanges &LinkedFunctionRanges) {
836 if (LinkedFunctionRanges.
empty())
856 uint64_t OffsetAfterArangesLengthField = OutArangesSection.
OS.
tell();
859 OutArangesSection.notePatch(
884 OutArangesSection.
apply(
885 OffsetAfterArangesLengthField -
887 dwarf::DW_FORM_sec_offset,
888 OffsetAfterArangesEnd - OffsetAfterArangesLengthField);
899 if (std::optional<uint64_t> MacroAttr =
903 emitMacroTableImpl(Table, *MacroAttr,
true);
908 if (std::optional<uint64_t> MacroAttr =
912 emitMacroTableImpl(Table, *MacroAttr,
false);
921 bool hasDWARFv5Header) {
927 bool DefAttributeIsReported =
false;
928 bool UndefAttributeIsReported =
false;
929 bool ImportAttributeIsReported =
false;
931 for (
const DWARFDebugMacro::MacroList &
List : MacroTable->MacroLists) {
932 if (OffsetToMacroTable ==
List.Offset) {
934 if (hasDWARFv5Header) {
942 DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE) {
945 warn(
"opcode_operands_table is not supported yet.");
949 std::optional<uint64_t> StmtListOffset;
950 if (Flags & DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET) {
953 if (V.getAttribute() == dwarf::DW_AT_stmt_list) {
954 StmtListOffset = V.getDIEInteger().getValue();
959 if (!StmtListOffset) {
961 warn(
"couldn`t find line table for macro table.");
969 if (StmtListOffset) {
980 for (
const DWARFDebugMacro::Entry &MacroEntry :
List.Macros) {
981 if (MacroEntry.Type == 0) {
986 uint8_t MacroType = MacroEntry.Type;
989 bool HasVendorSpecificExtension =
990 (!hasDWARFv5Header &&
995 if (HasVendorSpecificExtension) {
1003 OutSection.
emitString(dwarf::DW_FORM_string, MacroEntry.ExtStr);
1005 warn(
"unknown macro type. skip.");
1013 case dwarf::DW_MACRO_define:
1014 case dwarf::DW_MACRO_undef: {
1022 OutSection.
emitString(dwarf::DW_FORM_string, MacroEntry.MacroStr);
1024 case dwarf::DW_MACRO_define_strp:
1025 case dwarf::DW_MACRO_undef_strp:
1026 case dwarf::DW_MACRO_define_strx:
1027 case dwarf::DW_MACRO_undef_strx: {
1030 switch (MacroType) {
1031 case dwarf::DW_MACRO_define_strx: {
1032 MacroType = dwarf::DW_MACRO_define_strp;
1033 if (!DefAttributeIsReported) {
1034 warn(
"DW_MACRO_define_strx unsupported yet. Convert to "
1035 "DW_MACRO_define_strp.");
1036 DefAttributeIsReported =
true;
1039 case dwarf::DW_MACRO_undef_strx: {
1040 MacroType = dwarf::DW_MACRO_undef_strp;
1041 if (!UndefAttributeIsReported) {
1042 warn(
"DW_MACRO_undef_strx unsupported yet. Convert to "
1043 "DW_MACRO_undef_strp.");
1044 UndefAttributeIsReported =
true;
1059 OutSection.
emitString(dwarf::DW_FORM_strp, MacroEntry.MacroStr);
1062 case dwarf::DW_MACRO_start_file: {
1070 case dwarf::DW_MACRO_end_file: {
1074 case dwarf::DW_MACRO_import:
1075 case dwarf::DW_MACRO_import_sup: {
1076 if (!ImportAttributeIsReported) {
1077 warn(
"DW_MACRO_import and DW_MACRO_import_sup are unsupported "
1079 ImportAttributeIsReported =
true;
1093 std::optional<int64_t> VarAddressAdjustment,
1101 for (
auto &
Op : InputExpression) {
1107 Desc.
Op[0] != Encoding::Size1))
1108 warn(
"unsupported DW_OP encoding.");
1112 Desc.
Op[0] == Encoding::Size1)) {
1130 unsigned RealSize = 0;
1134 if (RefOffset > 0 ||
Op.
getCode() != dwarf::DW_OP_convert) {
1137 if (std::optional<uint32_t>
Idx =
1147 Section.notePatchWithOffsetUpdate(
1154 if (RealSize > ULEBsize) {
1157 warn(
"base type ref doesn't fit.");
1159 assert(RealSize == ULEBsize &&
"padding failed");
1162 }
else if (!
getGlobalData().getOptions().UpdateIndexTablesOnly &&
1164 if (std::optional<object::SectionedAddress> SA =
1170 OutputExpression.
push_back(dwarf::DW_OP_addr);
1171 uint64_t LinkedAddress = SA->Address + VarAddressAdjustment.value_or(0);
1175 reinterpret_cast<const uint8_t *
>(&LinkedAddress),
1176 OrigAddressByteSize);
1177 OutputExpression.
append(AddressBytes.
begin(), AddressBytes.
end());
1179 warn(
"cann't read DW_OP_addrx operand.");
1180 }
else if (!
getGlobalData().getOptions().UpdateIndexTablesOnly &&
1182 if (std::optional<object::SectionedAddress> SA =
1188 std::optional<uint8_t> OutOperandKind;
1189 switch (OrigAddressByteSize) {
1191 OutOperandKind = dwarf::DW_OP_const2u;
1194 OutOperandKind = dwarf::DW_OP_const4u;
1197 OutOperandKind = dwarf::DW_OP_const8u;
1201 formatv((
"unsupported address size: {0}."), OrigAddressByteSize));
1205 if (OutOperandKind) {
1206 OutputExpression.
push_back(*OutOperandKind);
1208 SA->Address + VarAddressAdjustment.value_or(0);
1212 reinterpret_cast<const uint8_t *
>(&LinkedAddress),
1213 OrigAddressByteSize);
1214 OutputExpression.
append(AddressBytes.
begin(), AddressBytes.
end());
1217 warn(
"cann't read DW_OP_constx operand.");
1229 std::optional<std::reference_wrapper<const Triple>> TargetTriple,
1238 if (ArtificialTypeUnit)
1242 std::pair<DIE *, TypeEntry *> OutCUDie =
cloneDIE(
1244 std::nullopt, std::nullopt,
Allocator, ArtificialTypeUnit);
1247 if (!TargetTriple.has_value() || (OutCUDie.first ==
nullptr))
1270 if (
Error Err = emitDebugAddrSection())
1286 uint64_t OutOffset, std::optional<int64_t> FuncAddressAdjustment,
1292 bool NeedToClonePlainDIE =
Info.needToKeepInPlainDwarf();
1293 bool NeedToCloneTypeDIE =
1294 (InputDieEntry->
getTag() != dwarf::DW_TAG_compile_unit) &&
1295 Info.needToPlaceInTypeTable();
1296 std::pair<DIE *, TypeEntry *> ClonedDIE;
1300 if (NeedToClonePlainDIE)
1303 ClonedDIE.first = createPlainDIEandCloneAttributes(
1304 InputDieEntry, PlainDIEGenerator, OutOffset, FuncAddressAdjustment,
1305 VarAddressAdjustment);
1306 if (NeedToCloneTypeDIE) {
1309 assert(ArtificialTypeUnit !=
nullptr);
1313 ClonedDIE.second = createTypeDIEandCloneAttributes(
1314 InputDieEntry, TypeDIEGenerator, ClonedParentTypeDIE,
1315 ArtificialTypeUnit);
1318 ClonedDIE.
second ? ClonedDIE.second : ClonedParentTypeDIE;
1320 bool HasPlainChildrenToClone =
1321 (ClonedDIE.first &&
Info.getKeepPlainChildren());
1323 bool HasTypeChildrenToClone =
1324 ((ClonedDIE.second ||
1325 InputDieEntry->
getTag() == dwarf::DW_TAG_compile_unit) &&
1326 Info.getKeepTypeChildren());
1329 if (HasPlainChildrenToClone || HasTypeChildrenToClone) {
1334 std::pair<DIE *, TypeEntry *> ClonedChild =
cloneDIE(
1335 CurChild, TypeParentForChild, OutOffset, FuncAddressAdjustment,
1336 VarAddressAdjustment,
Allocator, ArtificialTypeUnit);
1338 if (ClonedChild.first) {
1340 ClonedChild.first->getOffset() + ClonedChild.first->getSize();
1341 PlainDIEGenerator.
addChild(ClonedChild.first);
1344 assert(ClonedDIE.first ==
nullptr ||
1345 HasPlainChildrenToClone == ClonedDIE.first->hasChildren());
1348 if (HasPlainChildrenToClone)
1349 OutOffset +=
sizeof(int8_t);
1353 if (ClonedDIE.first !=
nullptr)
1354 ClonedDIE.first->setSize(OutOffset - ClonedDIE.first->getOffset());
1359DIE *CompileUnit::createPlainDIEandCloneAttributes(
1361 uint64_t &OutOffset, std::optional<int64_t> &FuncAddressAdjustment,
1362 std::optional<int64_t> &VarAddressAdjustment) {
1365 DIE *ClonedDIE =
nullptr;
1366 bool HasLocationExpressionAddress =
false;
1367 if (InputDieEntry->
getTag() == dwarf::DW_TAG_subprogram) {
1369 FuncAddressAdjustment =
1371 getDIE(InputDieEntry),
false);
1372 }
else if (InputDieEntry->
getTag() == dwarf::DW_TAG_label) {
1374 std::optional<uint64_t> lowPC =
1378 if (It != Labels.
end())
1379 FuncAddressAdjustment = It->second;
1381 }
else if (InputDieEntry->
getTag() == dwarf::DW_TAG_variable) {
1383 std::pair<bool, std::optional<int64_t>> LocExprAddrAndRelocAdjustment =
1385 getDIE(InputDieEntry),
false);
1387 HasLocationExpressionAddress = LocExprAddrAndRelocAdjustment.first;
1388 if (LocExprAddrAndRelocAdjustment.first &&
1389 LocExprAddrAndRelocAdjustment.second)
1390 VarAddressAdjustment = *LocExprAddrAndRelocAdjustment.second;
1393 ClonedDIE = PlainDIEGenerator.
createDIE(InputDieEntry->
getTag(), OutOffset);
1401 PlainDIEGenerator, FuncAddressAdjustment,
1402 VarAddressAdjustment,
1403 HasLocationExpressionAddress);
1404 AttributesCloner.clone();
1408 AccelRecordsSaver.save(InputDieEntry, ClonedDIE, AttributesCloner.AttrInfo,
1412 AttributesCloner.finalizeAbbreviations(
Info.getKeepPlainChildren());
1421 bool IsParentDeclaration) {
1422 DIE *DefinitionDie = TypeDescriptor->
Die;
1430 if (IsDeclaration && !DeclarationDie) {
1433 if (TypeDescriptor->
DeclarationDie.compare_exchange_strong(DeclarationDie,
1436 }
else if (IsDeclaration && !IsParentDeclaration && OldParentIsDeclaration) {
1440 OldParentIsDeclaration,
false)) {
1445 }
else if (!IsDeclaration && IsParentDeclaration && !DeclarationDie) {
1449 if (TypeDescriptor->
DeclarationDie.compare_exchange_strong(DeclarationDie,
1452 }
else if (!IsDeclaration && !IsParentDeclaration) {
1455 if (TypeDescriptor->
Die.compare_exchange_strong(DefinitionDie, NewDie)) {
1464TypeEntry *CompileUnit::createTypeDIEandCloneAttributes(
1467 assert(ArtificialTypeUnit !=
nullptr);
1471 assert(Entry !=
nullptr);
1472 assert(ClonedParentTypeDIE !=
nullptr);
1475 Entry, ClonedParentTypeDIE);
1478 bool IsDeclaration =
1481 bool ParentIsDeclaration =
false;
1482 if (std::optional<uint32_t> ParentIdx = InputDieEntry->
getParentIdx())
1483 ParentIsDeclaration =
1487 allocateTypeDie(EntryBody, TypeDIEGenerator, InputDieEntry->
getTag(),
1488 IsDeclaration, ParentIsDeclaration);
1490 if (OutDIE !=
nullptr) {
1491 assert(ArtificialTypeUnit !=
nullptr);
1495 InputDieEntry, TypeDIEGenerator,
1496 std::nullopt, std::nullopt,
false);
1497 AttributesCloner.clone();
1501 ArtificialTypeUnit);
1502 AccelRecordsSaver.save(InputDieEntry, OutDIE, AttributesCloner.AttrInfo,
1507 OutDIE->
setSize(AttributesCloner.getOutOffset() + 1);
1516 if (InputLineTable ==
nullptr) {
1518 warn(
"cann't load line table.");
1530 OutLineTable.
Rows = InputLineTable->
Rows;
1533 if (OutLineTable.
Rows.size() == 1 && OutLineTable.
Rows[0].EndSequence)
1534 OutLineTable.
Rows.clear();
1539 std::vector<DWARFDebugLine::Row> NewRows;
1540 NewRows.reserve(InputLineTable->
Rows.size());
1544 std::vector<DWARFDebugLine::Row> Seq;
1547 std::optional<AddressRangeValuePair> CurrRange;
1566 if (!CurrRange || !CurrRange->Range.contains(Row.Address.Address)) {
1570 CurrRange ? CurrRange->Range.end() + CurrRange->Value : -1ULL;
1571 CurrRange = FunctionRanges.getRangeThatContains(Row.Address.Address);
1572 if (StopAddress != -1ULL && !Seq.empty()) {
1575 auto NextLine = Seq.back();
1576 NextLine.Address.Address = StopAddress;
1577 NextLine.EndSequence = 1;
1578 NextLine.PrologueEnd = 0;
1579 NextLine.BasicBlock = 0;
1580 NextLine.EpilogueBegin = 0;
1581 Seq.push_back(NextLine);
1582 insertLineSequence(Seq, NewRows);
1590 if (Row.EndSequence && Seq.empty())
1594 Row.Address.Address += CurrRange->Value;
1595 Seq.emplace_back(Row);
1597 if (Row.EndSequence)
1598 insertLineSequence(Seq, NewRows);
1601 OutLineTable.
Rows = std::move(NewRows);
1607void CompileUnit::insertLineSequence(std::vector<DWARFDebugLine::Row> &Seq,
1608 std::vector<DWARFDebugLine::Row> &Rows) {
1612 if (!Rows.empty() && Rows.back().Address < Seq.front().Address) {
1626 if (InsertPoint != Rows.end() && InsertPoint->Address == Front &&
1627 InsertPoint->EndSequence) {
1628 *InsertPoint = Seq.front();
1629 Rows.insert(InsertPoint + 1, Seq.begin() + 1, Seq.end());
1631 Rows.insert(InsertPoint, Seq.begin(), Seq.end());
1637#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1657 llvm::errs() <<
" KeepPlainChildren: " << getKeepPlainChildren();
1658 llvm::errs() <<
" KeepTypeChildren: " << getKeepTypeChildren();
1659 llvm::errs() <<
" IsInMouduleScope: " << getIsInMouduleScope();
1660 llvm::errs() <<
" IsInFunctionScope: " << getIsInFunctionScope();
1661 llvm::errs() <<
" IsInAnonNamespaceScope: " << getIsInAnonNamespaceScope();
1662 llvm::errs() <<
" ODRAvailable: " << getODRAvailable();
1663 llvm::errs() <<
" TrackLiveness: " << getTrackLiveness();
1668std::optional<std::pair<StringRef, StringRef>>
1679 return std::nullopt;
1684std::optional<std::pair<StringRef, StringRef>>
1688 return std::make_pair(
StringRef(FileData->second.first),
1693 if (LineTable->hasFileAtIndex(FileIdx)) {
1696 LineTable->Prologue.getFileNameEntry(FileIdx);
1701 return std::nullopt;
1704 std::string FileName = *
Name;
1710 std::make_pair(std::string(
""), std::move(FileName))))
1712 return std::make_pair(
StringRef(FileData->second.first),
1722 if ((Entry.DirIdx != 0) &&
1723 Entry.DirIdx < LineTable->Prologue.IncludeDirectories.size()) {
1725 LineTable->Prologue.IncludeDirectories[Entry.DirIdx]
1728 IncludeDir = *DirName;
1731 return std::nullopt;
1735 if (0 < Entry.DirIdx &&
1736 Entry.DirIdx <= LineTable->Prologue.IncludeDirectories.size()) {
1738 LineTable->Prologue.IncludeDirectories[Entry.DirIdx - 1]
1741 IncludeDir = *DirName;
1744 return std::nullopt;
1760 std::make_pair(FileIdx, std::make_pair(std::string(FilePath),
1761 std::move(FileName))))
1763 return std::make_pair(
StringRef(FileData->second.first),
1768 return std::nullopt;
1771#define MAX_REFERENCIES_DEPTH 1000
1774 std::optional<UnitEntryPairTy> RefDiePair;
1778 CUDiePair.
DieEntry, dwarf::DW_AT_extension,
1780 if (!RefDiePair || !RefDiePair->DieEntry)
1783 CUDiePair = *RefDiePair;
1790 if (std::optional<uint32_t> ParentIdx = DieEntry->
getParentIdx())
1793 return std::nullopt;
1807 return getAsCompileUnit();
1809 return getAsTypeUnit();
1813 return isa<CompileUnit *>(
Ptr);
1817 return isa<TypeUnit *>(
Ptr);
1821 return cast<CompileUnit *>(
Ptr);
1825 return cast<TypeUnit *>(
Ptr);
1829 bool InterCUProcessingStarted, std::atomic<bool> &HasNewInterconnectedCUs) {
1833 return Dependencies->resolveDependenciesAndMarkLiveness(
1834 InterCUProcessingStarted, HasNewInterconnectedCUs);
1838 assert(Dependencies.get());
1840 return Dependencies->updateDependenciesCompleteness();
1844 assert(Dependencies.get());
1846 Dependencies->verifyKeepChain();
1851 dwarf::DW_AT_type, dwarf::DW_AT_specification,
1852 dwarf::DW_AT_abstract_origin, dwarf::DW_AT_import};
1854 return ODRAttributes;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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_>.
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.
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.
This class represents an Operation in the Expression.
LLVM_ABI 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 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.
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.
void fill(R &&Range, T &&Value)
Provide wrappers to std::fill which take ranges instead of having to pass begin/end explicitly.
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 formatv(bool Validate, const char *Fmt, Ts &&...Vals)
@ 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...
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
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