LLVM 22.0.0git
DWARFLinkerCompileUnit.cpp
Go to the documentation of this file.
1//=== DWARFLinkerCompileUnit.cpp ------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
11#include "DIEAttributeCloner.h"
12#include "DIEGenerator.h"
13#include "DependencyTracker.h"
20#include "llvm/Support/Path.h"
21#include <utility>
22
23using namespace llvm;
24using namespace dwarf_linker;
25using namespace dwarf_linker::parallel;
26
28 StringRef ClangModuleName, DWARFFile &File,
29 OffsetToUnitTy UnitFromOffset,
30 dwarf::FormParams Format, llvm::endianness Endianess)
31 : DwarfUnit(GlobalData, ID, ClangModuleName), File(File),
32 getUnitFromOffset(UnitFromOffset), Stage(Stage::CreatedNotLoaded),
33 AcceleratorRecords(&GlobalData.getAllocator()) {
34 UnitName = File.FileName;
35 setOutputFormat(Format, Endianess);
37}
38
40 unsigned ID, StringRef ClangModuleName,
41 DWARFFile &File, OffsetToUnitTy UnitFromOffset,
43 : DwarfUnit(GlobalData, ID, ClangModuleName), File(File),
44 OrigUnit(&OrigUnit), getUnitFromOffset(UnitFromOffset),
45 Stage(Stage::CreatedNotLoaded),
46 AcceleratorRecords(&GlobalData.getAllocator()) {
47 setOutputFormat(Format, Endianess);
49
50 DWARFDie CUDie = OrigUnit.getUnitDIE();
51 if (!CUDie)
52 return;
53
54 if (std::optional<DWARFFormValue> Val = CUDie.find(dwarf::DW_AT_language)) {
55 uint16_t LangVal = dwarf::toUnsigned(Val, 0);
56 if (isODRLanguage(LangVal))
57 Language = LangVal;
58 }
59
60 if (!GlobalData.getOptions().NoODR && Language.has_value())
61 NoODR = false;
62
63 if (const char *CUName = CUDie.getName(DINameKind::ShortName))
64 UnitName = CUName;
65 else
66 UnitName = File.FileName;
67 SysRoot = dwarf::toStringRef(CUDie.find(dwarf::DW_AT_LLVM_sysroot)).str();
68}
69
71 LineTablePtr = File.Dwarf->getLineTableForUnit(&getOrigUnit());
72}
73
75 // Nothing to reset if stage is less than "Loaded".
76 if (getStage() < Stage::Loaded)
77 return;
78
79 // Note: We need to do erasing for "Loaded" stage because
80 // if live analysys failed then we will have "Loaded" stage
81 // with marking from "LivenessAnalysisDone" stage partially
82 // done. That marking should be cleared.
83
84 for (DIEInfo &Info : DieInfoArray)
85 Info.unsetFlagsWhichSetDuringLiveAnalysis();
86
87 LowPc = std::nullopt;
88 HighPc = 0;
89 Labels.clear();
90 Ranges.clear();
91 Dependencies.reset(nullptr);
92
93 if (getStage() < Stage::Cloned) {
95 return;
96 }
97
98 AcceleratorRecords.erase();
99 AbbreviationsSet.clear();
100 Abbreviations.clear();
101 OutUnitDIE = nullptr;
102 DebugAddrIndexMap.clear();
103
104 llvm::fill(OutDieOffsetArray, 0);
105 llvm::fill(TypeEntries, nullptr);
107
109}
110
112 DWARFDie InputUnitDIE = getUnitDIE(false);
113 if (!InputUnitDIE)
114 return false;
115
116 // load input dies, resize Info structures array.
117 DieInfoArray.resize(getOrigUnit().getNumDIEs());
118 OutDieOffsetArray.resize(getOrigUnit().getNumDIEs(), 0);
119 if (!NoODR)
120 TypeEntries.resize(getOrigUnit().getNumDIEs());
121 return true;
122}
123
124void CompileUnit::analyzeDWARFStructureRec(const DWARFDebugInfoEntry *DieEntry,
125 bool IsODRUnavailableFunctionScope) {
126 CompileUnit::DIEInfo &DieInfo = getDIEInfo(DieEntry);
127
128 for (const DWARFDebugInfoEntry *CurChild = getFirstChildEntry(DieEntry);
129 CurChild && CurChild->getAbbreviationDeclarationPtr();
130 CurChild = getSiblingEntry(CurChild)) {
131 CompileUnit::DIEInfo &ChildInfo = getDIEInfo(CurChild);
132 bool ChildIsODRUnavailableFunctionScope = IsODRUnavailableFunctionScope;
133
134 if (DieInfo.getIsInMouduleScope())
135 ChildInfo.setIsInMouduleScope();
136
137 if (DieInfo.getIsInFunctionScope())
138 ChildInfo.setIsInFunctionScope();
139
140 if (DieInfo.getIsInAnonNamespaceScope())
141 ChildInfo.setIsInAnonNamespaceScope();
142
143 switch (CurChild->getTag()) {
144 case dwarf::DW_TAG_module:
145 ChildInfo.setIsInMouduleScope();
146 if (DieEntry->getTag() == dwarf::DW_TAG_compile_unit &&
147 dwarf::toString(find(CurChild, dwarf::DW_AT_name), "") !=
149 analyzeImportedModule(CurChild);
150 break;
151 case dwarf::DW_TAG_subprogram:
152 ChildInfo.setIsInFunctionScope();
153 if (!ChildIsODRUnavailableFunctionScope &&
154 !ChildInfo.getIsInMouduleScope()) {
155 if (find(CurChild,
156 {dwarf::DW_AT_abstract_origin, dwarf::DW_AT_specification}))
157 ChildIsODRUnavailableFunctionScope = true;
158 }
159 break;
160 case dwarf::DW_TAG_namespace: {
161 UnitEntryPairTy NamespaceEntry = {this, CurChild};
162
163 if (find(CurChild, dwarf::DW_AT_extension))
164 NamespaceEntry = NamespaceEntry.getNamespaceOrigin();
165
166 if (!NamespaceEntry.CU->find(NamespaceEntry.DieEntry, dwarf::DW_AT_name))
167 ChildInfo.setIsInAnonNamespaceScope();
168 } break;
169 default:
170 break;
171 }
172
173 if (!isClangModule() && !getGlobalData().getOptions().UpdateIndexTablesOnly)
174 ChildInfo.setTrackLiveness();
175
176 if ((!ChildInfo.getIsInAnonNamespaceScope() &&
177 !ChildIsODRUnavailableFunctionScope && !NoODR))
178 ChildInfo.setODRAvailable();
179
180 if (CurChild->hasChildren())
181 analyzeDWARFStructureRec(CurChild, ChildIsODRUnavailableFunctionScope);
182 }
183}
184
186 StringPool &GlobalStrings) {
187 if (LineTablePtr) {
188 if (LineTablePtr->hasFileAtIndex(FileIdx)) {
189 // Cache the resolved paths based on the index in the line table,
190 // because calling realpath is expensive.
191 ResolvedPathsMap::const_iterator It = ResolvedFullPaths.find(FileIdx);
192 if (It == ResolvedFullPaths.end()) {
193 std::string OrigFileName;
194 bool FoundFileName = LineTablePtr->getFileNameByIndex(
195 FileIdx, getOrigUnit().getCompilationDir(),
196 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
197 OrigFileName);
198 (void)FoundFileName;
199 assert(FoundFileName && "Must get file name from line table");
200
201 // Second level of caching, this time based on the file's parent
202 // path.
203 StringRef FileName = sys::path::filename(OrigFileName);
204 StringRef ParentPath = sys::path::parent_path(OrigFileName);
205
206 // If the ParentPath has not yet been resolved, resolve and cache it for
207 // future look-ups.
209 ResolvedParentPaths.find(ParentPath);
210 if (ParentIt == ResolvedParentPaths.end()) {
211 SmallString<256> RealPath;
212 sys::fs::real_path(ParentPath, RealPath);
213 ParentIt =
214 ResolvedParentPaths
215 .insert({ParentPath, GlobalStrings.insert(RealPath).first})
216 .first;
217 }
218
219 // Join the file name again with the resolved path.
220 SmallString<256> ResolvedPath(ParentIt->second->first());
221 sys::path::append(ResolvedPath, FileName);
222
223 It = ResolvedFullPaths
224 .insert(std::make_pair(
225 FileIdx, GlobalStrings.insert(ResolvedPath).first))
226 .first;
227 }
228
229 return It->second;
230 }
231 }
232
233 return nullptr;
234}
235
237 AbbreviationsSet.clear();
238 ResolvedFullPaths.shrink_and_clear();
239 ResolvedParentPaths.clear();
241 DieInfoArray = SmallVector<DIEInfo>();
242 OutDieOffsetArray = SmallVector<uint64_t>();
243 TypeEntries = SmallVector<TypeEntry *>();
244 Dependencies.reset(nullptr);
245 getOrigUnit().clear();
246}
247
248/// Collect references to parseable Swift interfaces in imported
249/// DW_TAG_module blocks.
251 if (!Language || Language != dwarf::DW_LANG_Swift)
252 return;
253
255 return;
256
257 StringRef Path =
258 dwarf::toStringRef(find(DieEntry, dwarf::DW_AT_LLVM_include_path));
259 if (!Path.ends_with(".swiftinterface"))
260 return;
261 // Don't track interfaces that are part of the SDK.
263 dwarf::toStringRef(find(DieEntry, dwarf::DW_AT_LLVM_sysroot));
264 if (SysRoot.empty())
266 if (!SysRoot.empty() && Path.starts_with(SysRoot))
267 return;
268 // Don't track interfaces that are part of the toolchain.
269 // For example: Swift, _Concurrency, ...
270 StringRef DeveloperDir = guessDeveloperDir(SysRoot);
271 if (!DeveloperDir.empty() && Path.starts_with(DeveloperDir))
272 return;
273 if (isInToolchainDir(Path))
274 return;
275 if (std::optional<DWARFFormValue> Val = find(DieEntry, dwarf::DW_AT_name)) {
276 Expected<const char *> Name = Val->getAsCString();
277 if (!Name) {
278 warn(Name.takeError());
279 return;
280 }
281
283 // The prepend path is applied later when copying.
284 SmallString<128> ResolvedPath;
285 if (sys::path::is_relative(Path))
287 ResolvedPath,
288 dwarf::toString(getUnitDIE().find(dwarf::DW_AT_comp_dir), ""));
289 sys::path::append(ResolvedPath, Path);
290 if (!Entry.empty() && Entry != ResolvedPath) {
291 DWARFDie Die = getDIE(DieEntry);
292 warn(Twine("conflicting parseable interfaces for Swift Module ") + *Name +
293 ": " + Entry + " and " + Path + ".",
294 &Die);
295 }
296 Entry = std::string(ResolvedPath);
297 }
298}
299
301 if (!getUnitDIE().isValid())
302 return Error::success();
303
304 SyntheticTypeNameBuilder NameBuilder(TypePoolRef);
305 return assignTypeNamesRec(getDebugInfoEntry(0), NameBuilder);
306}
307
308Error CompileUnit::assignTypeNamesRec(const DWARFDebugInfoEntry *DieEntry,
309 SyntheticTypeNameBuilder &NameBuilder) {
310 OrderedChildrenIndexAssigner ChildrenIndexAssigner(*this, DieEntry);
311 for (const DWARFDebugInfoEntry *CurChild = getFirstChildEntry(DieEntry);
312 CurChild && CurChild->getAbbreviationDeclarationPtr();
313 CurChild = getSiblingEntry(CurChild)) {
314 CompileUnit::DIEInfo &ChildInfo = getDIEInfo(CurChild);
315 if (!ChildInfo.needToPlaceInTypeTable())
316 continue;
317
318 assert(ChildInfo.getODRAvailable());
319 if (Error Err = NameBuilder.assignName(
320 {this, CurChild},
321 ChildrenIndexAssigner.getChildIndex(*this, CurChild)))
322 return Err;
323
324 if (Error Err = assignTypeNamesRec(CurChild, NameBuilder))
325 return Err;
326 }
327
328 return Error::success();
329}
330
332 if (std::optional<SectionDescriptor *> DebugInfoSection =
334
335 (*DebugInfoSection)
336 ->ListDebugDieRefPatch.forEach([&](DebugDieRefPatch &Patch) {
337 /// Replace stored DIE indexes with DIE output offsets.
339 Patch.RefCU.getPointer()->getDieOutOffset(
341 });
342
343 (*DebugInfoSection)
344 ->ListDebugULEB128DieRefPatch.forEach(
345 [&](DebugULEB128DieRefPatch &Patch) {
346 /// Replace stored DIE indexes with DIE output offsets.
348 Patch.RefCU.getPointer()->getDieOutOffset(
350 });
351 }
352
353 if (std::optional<SectionDescriptor *> DebugLocSection =
355 (*DebugLocSection)
356 ->ListDebugULEB128DieRefPatch.forEach(
357 [](DebugULEB128DieRefPatch &Patch) {
358 /// Replace stored DIE indexes with DIE output offsets.
360 Patch.RefCU.getPointer()->getDieOutOffset(
362 });
363 }
364
365 if (std::optional<SectionDescriptor *> DebugLocListsSection =
367 (*DebugLocListsSection)
368 ->ListDebugULEB128DieRefPatch.forEach(
369 [](DebugULEB128DieRefPatch &Patch) {
370 /// Replace stored DIE indexes with DIE output offsets.
372 Patch.RefCU.getPointer()->getDieOutOffset(
374 });
375 }
376}
377
378std::optional<UnitEntryPairTy> CompileUnit::resolveDIEReference(
379 const DWARFFormValue &RefValue,
380 ResolveInterCUReferencesMode CanResolveInterCUReferences) {
381 CompileUnit *RefCU;
382 uint64_t RefDIEOffset;
383 if (std::optional<uint64_t> Offset = RefValue.getAsRelativeReference()) {
384 RefCU = this;
385 RefDIEOffset = RefValue.getUnit()->getOffset() + *Offset;
386 } else if (Offset = RefValue.getAsDebugInfoReference(); Offset) {
387 RefCU = getUnitFromOffset(*Offset);
388 RefDIEOffset = *Offset;
389 } else {
390 return std::nullopt;
391 }
392
393 if (RefCU == this) {
394 // Referenced DIE is in current compile unit.
395 if (std::optional<uint32_t> RefDieIdx = getDIEIndexForOffset(RefDIEOffset))
396 return UnitEntryPairTy{this, getDebugInfoEntry(*RefDieIdx)};
397 } else if (RefCU && CanResolveInterCUReferences) {
398 // Referenced DIE is in other compile unit.
399
400 // Check whether DIEs are loaded for that compile unit.
401 enum Stage ReferredCUStage = RefCU->getStage();
402 if (ReferredCUStage < Stage::Loaded || ReferredCUStage > Stage::Cloned)
403 return UnitEntryPairTy{RefCU, nullptr};
404
405 if (std::optional<uint32_t> RefDieIdx =
406 RefCU->getDIEIndexForOffset(RefDIEOffset))
407 return UnitEntryPairTy{RefCU, RefCU->getDebugInfoEntry(*RefDieIdx)};
408 } else {
409 return UnitEntryPairTy{RefCU, nullptr};
410 }
411 return std::nullopt;
412}
413
414std::optional<UnitEntryPairTy> CompileUnit::resolveDIEReference(
415 const DWARFDebugInfoEntry *DieEntry, dwarf::Attribute Attr,
416 ResolveInterCUReferencesMode CanResolveInterCUReferences) {
417 if (std::optional<DWARFFormValue> AttrVal = find(DieEntry, Attr))
418 return resolveDIEReference(*AttrVal, CanResolveInterCUReferences);
419
420 return std::nullopt;
421}
422
423void CompileUnit::addFunctionRange(uint64_t FuncLowPc, uint64_t FuncHighPc,
424 int64_t PcOffset) {
425 std::lock_guard<std::mutex> Guard(RangesMutex);
426
427 Ranges.insert({FuncLowPc, FuncHighPc}, PcOffset);
428 if (LowPc)
429 LowPc = std::min(*LowPc, FuncLowPc + PcOffset);
430 else
431 LowPc = FuncLowPc + PcOffset;
432 this->HighPc = std::max(HighPc, FuncHighPc + PcOffset);
433}
434
435void CompileUnit::addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset) {
436 std::lock_guard<std::mutex> Guard(LabelsMutex);
437 Labels.insert({LabelLowPc, PcOffset});
438}
439
441 if (getGlobalData().getOptions().UpdateIndexTablesOnly)
442 return Error::success();
443
444 if (getOrigUnit().getVersion() < 5) {
445 emitLocations(DebugSectionKind::DebugLoc);
446 return Error::success();
447 }
448
449 emitLocations(DebugSectionKind::DebugLocLists);
450 return Error::success();
451}
452
453void CompileUnit::emitLocations(DebugSectionKind LocationSectionKind) {
454 SectionDescriptor &DebugInfoSection =
456
457 if (!DebugInfoSection.ListDebugLocPatch.empty()) {
458 SectionDescriptor &OutLocationSection =
459 getOrCreateSectionDescriptor(LocationSectionKind);
460 DWARFUnit &OrigUnit = getOrigUnit();
461
462 uint64_t OffsetAfterUnitLength = emitLocListHeader(OutLocationSection);
463
464 DebugInfoSection.ListDebugLocPatch.forEach([&](DebugLocPatch &Patch) {
465 // Get location expressions vector corresponding to the current
466 // attribute from the source DWARF.
467 uint64_t InputDebugLocSectionOffset = DebugInfoSection.getIntVal(
468 Patch.PatchOffset,
469 DebugInfoSection.getFormParams().getDwarfOffsetByteSize());
471 OrigUnit.findLoclistFromOffset(InputDebugLocSectionOffset);
472
473 if (!OriginalLocations) {
474 warn(OriginalLocations.takeError());
475 return;
476 }
477
478 LinkedLocationExpressionsVector LinkedLocationExpressions;
479 for (DWARFLocationExpression &CurExpression : *OriginalLocations) {
480 LinkedLocationExpressionsWithOffsetPatches LinkedExpression;
481
482 if (CurExpression.Range) {
483 // Relocate address range.
484 LinkedExpression.Expression.Range = {
485 CurExpression.Range->LowPC + Patch.AddrAdjustmentValue,
486 CurExpression.Range->HighPC + Patch.AddrAdjustmentValue};
487 }
488
489 DataExtractor Data(CurExpression.Expr, OrigUnit.isLittleEndian(),
490 OrigUnit.getAddressByteSize());
491
492 DWARFExpression InputExpression(Data, OrigUnit.getAddressByteSize(),
493 OrigUnit.getFormParams().Format);
494 cloneDieAttrExpression(InputExpression,
495 LinkedExpression.Expression.Expr,
496 OutLocationSection, Patch.AddrAdjustmentValue,
497 LinkedExpression.Patches);
498
499 LinkedLocationExpressions.push_back({LinkedExpression});
500 }
501
502 // Emit locations list table fragment corresponding to the CurLocAttr.
503 DebugInfoSection.apply(Patch.PatchOffset, dwarf::DW_FORM_sec_offset,
504 OutLocationSection.OS.tell());
505 emitLocListFragment(LinkedLocationExpressions, OutLocationSection);
506 });
507
508 if (OffsetAfterUnitLength > 0) {
509 assert(OffsetAfterUnitLength -
510 OutLocationSection.getFormParams().getDwarfOffsetByteSize() <
511 OffsetAfterUnitLength);
512 OutLocationSection.apply(
513 OffsetAfterUnitLength -
514 OutLocationSection.getFormParams().getDwarfOffsetByteSize(),
515 dwarf::DW_FORM_sec_offset,
516 OutLocationSection.OS.tell() - OffsetAfterUnitLength);
517 }
518 }
519}
520
521/// Emit debug locations(.debug_loc, .debug_loclists) header.
522uint64_t CompileUnit::emitLocListHeader(SectionDescriptor &OutLocationSection) {
523 if (getOrigUnit().getVersion() < 5)
524 return 0;
525
526 // unit_length.
527 OutLocationSection.emitUnitLength(0xBADDEF);
528 uint64_t OffsetAfterUnitLength = OutLocationSection.OS.tell();
529
530 // Version.
531 OutLocationSection.emitIntVal(5, 2);
532
533 // Address size.
534 OutLocationSection.emitIntVal(OutLocationSection.getFormParams().AddrSize, 1);
535
536 // Seg_size
537 OutLocationSection.emitIntVal(0, 1);
538
539 // Offset entry count
540 OutLocationSection.emitIntVal(0, 4);
541
542 return OffsetAfterUnitLength;
543}
544
545/// Emit debug locations(.debug_loc, .debug_loclists) fragment.
546uint64_t CompileUnit::emitLocListFragment(
547 const LinkedLocationExpressionsVector &LinkedLocationExpression,
548 SectionDescriptor &OutLocationSection) {
549 uint64_t OffsetBeforeLocationExpression = 0;
550
551 if (getOrigUnit().getVersion() < 5) {
552 uint64_t BaseAddress = 0;
553 if (std::optional<uint64_t> LowPC = getLowPc())
554 BaseAddress = *LowPC;
555
556 for (const LinkedLocationExpressionsWithOffsetPatches &LocExpression :
557 LinkedLocationExpression) {
558 if (LocExpression.Expression.Range) {
559 OutLocationSection.emitIntVal(
560 LocExpression.Expression.Range->LowPC - BaseAddress,
561 OutLocationSection.getFormParams().AddrSize);
562 OutLocationSection.emitIntVal(
563 LocExpression.Expression.Range->HighPC - BaseAddress,
564 OutLocationSection.getFormParams().AddrSize);
565 }
566
567 OutLocationSection.emitIntVal(LocExpression.Expression.Expr.size(), 2);
568 OffsetBeforeLocationExpression = OutLocationSection.OS.tell();
569 for (uint64_t *OffsetPtr : LocExpression.Patches)
570 *OffsetPtr += OffsetBeforeLocationExpression;
571
572 OutLocationSection.OS
573 << StringRef((const char *)LocExpression.Expression.Expr.data(),
574 LocExpression.Expression.Expr.size());
575 }
576
577 // Emit the terminator entry.
578 OutLocationSection.emitIntVal(0,
579 OutLocationSection.getFormParams().AddrSize);
580 OutLocationSection.emitIntVal(0,
581 OutLocationSection.getFormParams().AddrSize);
582 return OffsetBeforeLocationExpression;
583 }
584
585 std::optional<uint64_t> BaseAddress;
586 for (const LinkedLocationExpressionsWithOffsetPatches &LocExpression :
587 LinkedLocationExpression) {
588 if (LocExpression.Expression.Range) {
589 // Check whether base address is set. If it is not set yet
590 // then set current base address and emit base address selection entry.
591 if (!BaseAddress) {
592 BaseAddress = LocExpression.Expression.Range->LowPC;
593
594 // Emit base address.
595 OutLocationSection.emitIntVal(dwarf::DW_LLE_base_addressx, 1);
596 encodeULEB128(DebugAddrIndexMap.getValueIndex(*BaseAddress),
597 OutLocationSection.OS);
598 }
599
600 // Emit type of entry.
601 OutLocationSection.emitIntVal(dwarf::DW_LLE_offset_pair, 1);
602
603 // Emit start offset relative to base address.
604 encodeULEB128(LocExpression.Expression.Range->LowPC - *BaseAddress,
605 OutLocationSection.OS);
606
607 // Emit end offset relative to base address.
608 encodeULEB128(LocExpression.Expression.Range->HighPC - *BaseAddress,
609 OutLocationSection.OS);
610 } else
611 // Emit type of entry.
612 OutLocationSection.emitIntVal(dwarf::DW_LLE_default_location, 1);
613
614 encodeULEB128(LocExpression.Expression.Expr.size(), OutLocationSection.OS);
615 OffsetBeforeLocationExpression = OutLocationSection.OS.tell();
616 for (uint64_t *OffsetPtr : LocExpression.Patches)
617 *OffsetPtr += OffsetBeforeLocationExpression;
618
619 OutLocationSection.OS << StringRef(
620 (const char *)LocExpression.Expression.Expr.data(),
621 LocExpression.Expression.Expr.size());
622 }
623
624 // Emit the terminator entry.
625 OutLocationSection.emitIntVal(dwarf::DW_LLE_end_of_list, 1);
626 return OffsetBeforeLocationExpression;
627}
628
629Error CompileUnit::emitDebugAddrSection() {
631 return Error::success();
632
633 if (getVersion() < 5)
634 return Error::success();
635
636 if (DebugAddrIndexMap.empty())
637 return Error::success();
638
639 SectionDescriptor &OutAddrSection =
641
642 // Emit section header.
643
644 // Emit length.
645 OutAddrSection.emitUnitLength(0xBADDEF);
646 uint64_t OffsetAfterSectionLength = OutAddrSection.OS.tell();
647
648 // Emit version.
649 OutAddrSection.emitIntVal(5, 2);
650
651 // Emit address size.
652 OutAddrSection.emitIntVal(getFormParams().AddrSize, 1);
653
654 // Emit segment size.
655 OutAddrSection.emitIntVal(0, 1);
656
657 // Emit addresses.
658 for (uint64_t AddrValue : DebugAddrIndexMap.getValues())
659 OutAddrSection.emitIntVal(AddrValue, getFormParams().AddrSize);
660
661 // Patch section length.
662 OutAddrSection.apply(
663 OffsetAfterSectionLength -
664 OutAddrSection.getFormParams().getDwarfOffsetByteSize(),
665 dwarf::DW_FORM_sec_offset,
666 OutAddrSection.OS.tell() - OffsetAfterSectionLength);
667
668 return Error::success();
669}
670
672 if (getGlobalData().getOptions().UpdateIndexTablesOnly)
673 return Error::success();
674
675 // Build set of linked address ranges for unit function ranges.
676 AddressRanges LinkedFunctionRanges;
678 LinkedFunctionRanges.insert(
679 {Range.Range.start() + Range.Value, Range.Range.end() + Range.Value});
680
681 emitAranges(LinkedFunctionRanges);
682
683 if (getOrigUnit().getVersion() < 5) {
684 cloneAndEmitRangeList(DebugSectionKind::DebugRange, LinkedFunctionRanges);
685 return Error::success();
686 }
687
688 cloneAndEmitRangeList(DebugSectionKind::DebugRngLists, LinkedFunctionRanges);
689 return Error::success();
690}
691
692void CompileUnit::cloneAndEmitRangeList(DebugSectionKind RngSectionKind,
693 AddressRanges &LinkedFunctionRanges) {
694 SectionDescriptor &DebugInfoSection =
696 SectionDescriptor &OutRangeSection =
697 getOrCreateSectionDescriptor(RngSectionKind);
698
699 if (!DebugInfoSection.ListDebugRangePatch.empty()) {
700 std::optional<AddressRangeValuePair> CachedRange;
701 uint64_t OffsetAfterUnitLength = emitRangeListHeader(OutRangeSection);
702
703 DebugRangePatch *CompileUnitRangePtr = nullptr;
704 DebugInfoSection.ListDebugRangePatch.forEach([&](DebugRangePatch &Patch) {
705 if (Patch.IsCompileUnitRanges) {
706 CompileUnitRangePtr = &Patch;
707 } else {
708 // Get ranges from the source DWARF corresponding to the current
709 // attribute.
710 AddressRanges LinkedRanges;
711 uint64_t InputDebugRangesSectionOffset = DebugInfoSection.getIntVal(
712 Patch.PatchOffset,
713 DebugInfoSection.getFormParams().getDwarfOffsetByteSize());
714 if (Expected<DWARFAddressRangesVector> InputRanges =
715 getOrigUnit().findRnglistFromOffset(
716 InputDebugRangesSectionOffset)) {
717 // Apply relocation adjustment.
718 for (const auto &Range : *InputRanges) {
719 if (!CachedRange || !CachedRange->Range.contains(Range.LowPC))
720 CachedRange =
721 getFunctionRanges().getRangeThatContains(Range.LowPC);
722
723 // All range entries should lie in the function range.
724 if (!CachedRange) {
725 warn("inconsistent range data.");
726 continue;
727 }
728
729 // Store range for emiting.
730 LinkedRanges.insert({Range.LowPC + CachedRange->Value,
731 Range.HighPC + CachedRange->Value});
732 }
733 } else {
734 llvm::consumeError(InputRanges.takeError());
735 warn("invalid range list ignored.");
736 }
737
738 // Emit linked ranges.
739 DebugInfoSection.apply(Patch.PatchOffset, dwarf::DW_FORM_sec_offset,
740 OutRangeSection.OS.tell());
741 emitRangeListFragment(LinkedRanges, OutRangeSection);
742 }
743 });
744
745 if (CompileUnitRangePtr != nullptr) {
746 // Emit compile unit ranges last to be binary compatible with classic
747 // dsymutil.
748 DebugInfoSection.apply(CompileUnitRangePtr->PatchOffset,
749 dwarf::DW_FORM_sec_offset,
750 OutRangeSection.OS.tell());
751 emitRangeListFragment(LinkedFunctionRanges, OutRangeSection);
752 }
753
754 if (OffsetAfterUnitLength > 0) {
755 assert(OffsetAfterUnitLength -
756 OutRangeSection.getFormParams().getDwarfOffsetByteSize() <
757 OffsetAfterUnitLength);
758 OutRangeSection.apply(
759 OffsetAfterUnitLength -
760 OutRangeSection.getFormParams().getDwarfOffsetByteSize(),
761 dwarf::DW_FORM_sec_offset,
762 OutRangeSection.OS.tell() - OffsetAfterUnitLength);
763 }
764 }
765}
766
767uint64_t CompileUnit::emitRangeListHeader(SectionDescriptor &OutRangeSection) {
768 if (OutRangeSection.getFormParams().Version < 5)
769 return 0;
770
771 // unit_length.
772 OutRangeSection.emitUnitLength(0xBADDEF);
773 uint64_t OffsetAfterUnitLength = OutRangeSection.OS.tell();
774
775 // Version.
776 OutRangeSection.emitIntVal(5, 2);
777
778 // Address size.
779 OutRangeSection.emitIntVal(OutRangeSection.getFormParams().AddrSize, 1);
780
781 // Seg_size
782 OutRangeSection.emitIntVal(0, 1);
783
784 // Offset entry count
785 OutRangeSection.emitIntVal(0, 4);
786
787 return OffsetAfterUnitLength;
788}
789
790void CompileUnit::emitRangeListFragment(const AddressRanges &LinkedRanges,
791 SectionDescriptor &OutRangeSection) {
792 if (OutRangeSection.getFormParams().Version < 5) {
793 // Emit ranges.
794 uint64_t BaseAddress = 0;
795 if (std::optional<uint64_t> LowPC = getLowPc())
796 BaseAddress = *LowPC;
797
798 for (const AddressRange &Range : LinkedRanges) {
799 OutRangeSection.emitIntVal(Range.start() - BaseAddress,
800 OutRangeSection.getFormParams().AddrSize);
801 OutRangeSection.emitIntVal(Range.end() - BaseAddress,
802 OutRangeSection.getFormParams().AddrSize);
803 }
804
805 // Add the terminator entry.
806 OutRangeSection.emitIntVal(0, OutRangeSection.getFormParams().AddrSize);
807 OutRangeSection.emitIntVal(0, OutRangeSection.getFormParams().AddrSize);
808 return;
809 }
810
811 std::optional<uint64_t> BaseAddress;
812 for (const AddressRange &Range : LinkedRanges) {
813 if (!BaseAddress) {
814 BaseAddress = Range.start();
815
816 // Emit base address.
817 OutRangeSection.emitIntVal(dwarf::DW_RLE_base_addressx, 1);
818 encodeULEB128(getDebugAddrIndex(*BaseAddress), OutRangeSection.OS);
819 }
820
821 // Emit type of entry.
822 OutRangeSection.emitIntVal(dwarf::DW_RLE_offset_pair, 1);
823
824 // Emit start offset relative to base address.
825 encodeULEB128(Range.start() - *BaseAddress, OutRangeSection.OS);
826
827 // Emit end offset relative to base address.
828 encodeULEB128(Range.end() - *BaseAddress, OutRangeSection.OS);
829 }
830
831 // Emit the terminator entry.
832 OutRangeSection.emitIntVal(dwarf::DW_RLE_end_of_list, 1);
833}
834
835void CompileUnit::emitAranges(AddressRanges &LinkedFunctionRanges) {
836 if (LinkedFunctionRanges.empty())
837 return;
838
839 SectionDescriptor &DebugInfoSection =
841 SectionDescriptor &OutArangesSection =
843
844 // Emit Header.
845 unsigned HeaderSize =
846 sizeof(int32_t) + // Size of contents (w/o this field
847 sizeof(int16_t) + // DWARF ARange version number
848 sizeof(int32_t) + // Offset of CU in the .debug_info section
849 sizeof(int8_t) + // Pointer Size (in bytes)
850 sizeof(int8_t); // Segment Size (in bytes)
851
852 unsigned TupleSize = OutArangesSection.getFormParams().AddrSize * 2;
853 unsigned Padding = offsetToAlignment(HeaderSize, Align(TupleSize));
854
855 OutArangesSection.emitOffset(0xBADDEF); // Aranges length
856 uint64_t OffsetAfterArangesLengthField = OutArangesSection.OS.tell();
857
858 OutArangesSection.emitIntVal(dwarf::DW_ARANGES_VERSION, 2); // Version number
859 OutArangesSection.notePatch(
860 DebugOffsetPatch{OutArangesSection.OS.tell(), &DebugInfoSection});
861 OutArangesSection.emitOffset(0xBADDEF); // Corresponding unit's offset
862 OutArangesSection.emitIntVal(OutArangesSection.getFormParams().AddrSize,
863 1); // Address size
864 OutArangesSection.emitIntVal(0, 1); // Segment size
865
866 for (size_t Idx = 0; Idx < Padding; Idx++)
867 OutArangesSection.emitIntVal(0, 1); // Padding
868
869 // Emit linked ranges.
870 for (const AddressRange &Range : LinkedFunctionRanges) {
871 OutArangesSection.emitIntVal(Range.start(),
872 OutArangesSection.getFormParams().AddrSize);
873 OutArangesSection.emitIntVal(Range.end() - Range.start(),
874 OutArangesSection.getFormParams().AddrSize);
875 }
876
877 // Emit terminator.
878 OutArangesSection.emitIntVal(0, OutArangesSection.getFormParams().AddrSize);
879 OutArangesSection.emitIntVal(0, OutArangesSection.getFormParams().AddrSize);
880
881 uint64_t OffsetAfterArangesEnd = OutArangesSection.OS.tell();
882
883 // Update Aranges lentgh.
884 OutArangesSection.apply(
885 OffsetAfterArangesLengthField -
886 OutArangesSection.getFormParams().getDwarfOffsetByteSize(),
887 dwarf::DW_FORM_sec_offset,
888 OffsetAfterArangesEnd - OffsetAfterArangesLengthField);
889}
890
892 if (getOutUnitDIE() == nullptr)
893 return Error::success();
894
895 DWARFUnit &OrigUnit = getOrigUnit();
896 DWARFDie OrigUnitDie = OrigUnit.getUnitDIE();
897
898 // Check for .debug_macro table.
899 if (std::optional<uint64_t> MacroAttr =
900 dwarf::toSectionOffset(OrigUnitDie.find(dwarf::DW_AT_macros))) {
901 if (const DWARFDebugMacro *Table =
902 getContaingFile().Dwarf->getDebugMacro()) {
903 emitMacroTableImpl(Table, *MacroAttr, true);
904 }
905 }
906
907 // Check for .debug_macinfo table.
908 if (std::optional<uint64_t> MacroAttr =
909 dwarf::toSectionOffset(OrigUnitDie.find(dwarf::DW_AT_macro_info))) {
910 if (const DWARFDebugMacro *Table =
911 getContaingFile().Dwarf->getDebugMacinfo()) {
912 emitMacroTableImpl(Table, *MacroAttr, false);
913 }
914 }
915
916 return Error::success();
917}
918
919void CompileUnit::emitMacroTableImpl(const DWARFDebugMacro *MacroTable,
920 uint64_t OffsetToMacroTable,
921 bool hasDWARFv5Header) {
922 SectionDescriptor &OutSection =
923 hasDWARFv5Header
926
927 bool DefAttributeIsReported = false;
928 bool UndefAttributeIsReported = false;
929 bool ImportAttributeIsReported = false;
930
931 for (const DWARFDebugMacro::MacroList &List : MacroTable->MacroLists) {
932 if (OffsetToMacroTable == List.Offset) {
933 // Write DWARFv5 header.
934 if (hasDWARFv5Header) {
935 // Write header version.
936 OutSection.emitIntVal(List.Header.Version, sizeof(List.Header.Version));
937
938 uint8_t Flags = List.Header.Flags;
939
940 // Check for OPCODE_OPERANDS_TABLE.
941 if (Flags &
942 DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE) {
943 Flags &=
944 ~DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE;
945 warn("opcode_operands_table is not supported yet.");
946 }
947
948 // Check for DEBUG_LINE_OFFSET.
949 std::optional<uint64_t> StmtListOffset;
950 if (Flags & DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET) {
951 // Get offset to the line table from the cloned compile unit.
952 for (auto &V : getOutUnitDIE()->values()) {
953 if (V.getAttribute() == dwarf::DW_AT_stmt_list) {
954 StmtListOffset = V.getDIEInteger().getValue();
955 break;
956 }
957 }
958
959 if (!StmtListOffset) {
960 Flags &= ~DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET;
961 warn("couldn`t find line table for macro table.");
962 }
963 }
964
965 // Write flags.
966 OutSection.emitIntVal(Flags, sizeof(Flags));
967
968 // Write offset to line table.
969 if (StmtListOffset) {
970 OutSection.notePatch(DebugOffsetPatch{
971 OutSection.OS.tell(),
973 // TODO: check that List.Header.getOffsetByteSize() and
974 // DebugOffsetPatch agree on size.
975 OutSection.emitIntVal(0xBADDEF, List.Header.getOffsetByteSize());
976 }
977 }
978
979 // Write macro entries.
980 for (const DWARFDebugMacro::Entry &MacroEntry : List.Macros) {
981 if (MacroEntry.Type == 0) {
982 encodeULEB128(MacroEntry.Type, OutSection.OS);
983 continue;
984 }
985
986 uint8_t MacroType = MacroEntry.Type;
987 switch (MacroType) {
988 default: {
989 bool HasVendorSpecificExtension =
990 (!hasDWARFv5Header &&
991 MacroType == dwarf::DW_MACINFO_vendor_ext) ||
992 (hasDWARFv5Header && (MacroType >= dwarf::DW_MACRO_lo_user &&
993 MacroType <= dwarf::DW_MACRO_hi_user));
994
995 if (HasVendorSpecificExtension) {
996 // Write macinfo type.
997 OutSection.emitIntVal(MacroType, 1);
998
999 // Write vendor extension constant.
1000 encodeULEB128(MacroEntry.ExtConstant, OutSection.OS);
1001
1002 // Write vendor extension string.
1003 OutSection.emitString(dwarf::DW_FORM_string, MacroEntry.ExtStr);
1004 } else
1005 warn("unknown macro type. skip.");
1006 } break;
1007 // debug_macro and debug_macinfo share some common encodings.
1008 // DW_MACRO_define == DW_MACINFO_define
1009 // DW_MACRO_undef == DW_MACINFO_undef
1010 // DW_MACRO_start_file == DW_MACINFO_start_file
1011 // DW_MACRO_end_file == DW_MACINFO_end_file
1012 // For readibility/uniformity we are using DW_MACRO_*.
1013 case dwarf::DW_MACRO_define:
1014 case dwarf::DW_MACRO_undef: {
1015 // Write macinfo type.
1016 OutSection.emitIntVal(MacroType, 1);
1017
1018 // Write source line.
1019 encodeULEB128(MacroEntry.Line, OutSection.OS);
1020
1021 // Write macro string.
1022 OutSection.emitString(dwarf::DW_FORM_string, MacroEntry.MacroStr);
1023 } break;
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: {
1028 // DW_MACRO_*_strx forms are not supported currently.
1029 // Convert to *_strp.
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;
1037 }
1038 } break;
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;
1045 }
1046 } break;
1047 default:
1048 // Nothing to do.
1049 break;
1050 }
1051
1052 // Write macinfo type.
1053 OutSection.emitIntVal(MacroType, 1);
1054
1055 // Write source line.
1056 encodeULEB128(MacroEntry.Line, OutSection.OS);
1057
1058 // Write macro string.
1059 OutSection.emitString(dwarf::DW_FORM_strp, MacroEntry.MacroStr);
1060 break;
1061 }
1062 case dwarf::DW_MACRO_start_file: {
1063 // Write macinfo type.
1064 OutSection.emitIntVal(MacroType, 1);
1065 // Write source line.
1066 encodeULEB128(MacroEntry.Line, OutSection.OS);
1067 // Write source file id.
1068 encodeULEB128(MacroEntry.File, OutSection.OS);
1069 } break;
1070 case dwarf::DW_MACRO_end_file: {
1071 // Write macinfo type.
1072 OutSection.emitIntVal(MacroType, 1);
1073 } break;
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 "
1078 "yet. remove.");
1079 ImportAttributeIsReported = true;
1080 }
1081 } break;
1082 }
1083 }
1084
1085 return;
1086 }
1087 }
1088}
1089
1091 const DWARFExpression &InputExpression,
1092 SmallVectorImpl<uint8_t> &OutputExpression, SectionDescriptor &Section,
1093 std::optional<int64_t> VarAddressAdjustment,
1094 OffsetsPtrVector &PatchesOffsets) {
1095 using Encoding = DWARFExpression::Operation::Encoding;
1096
1097 DWARFUnit &OrigUnit = getOrigUnit();
1098 uint8_t OrigAddressByteSize = OrigUnit.getAddressByteSize();
1099
1100 uint64_t OpOffset = 0;
1101 for (auto &Op : InputExpression) {
1102 auto Desc = Op.getDescription();
1103 // DW_OP_const_type is variable-length and has 3
1104 // operands. Thus far we only support 2.
1105 if ((Desc.Op.size() == 2 && Desc.Op[0] == Encoding::BaseTypeRef) ||
1106 (Desc.Op.size() == 2 && Desc.Op[1] == Encoding::BaseTypeRef &&
1107 Desc.Op[0] != Encoding::Size1))
1108 warn("unsupported DW_OP encoding.");
1109
1110 if ((Desc.Op.size() == 1 && Desc.Op[0] == Encoding::BaseTypeRef) ||
1111 (Desc.Op.size() == 2 && Desc.Op[1] == Encoding::BaseTypeRef &&
1112 Desc.Op[0] == Encoding::Size1)) {
1113 // This code assumes that the other non-typeref operand fits into 1 byte.
1114 assert(OpOffset < Op.getEndOffset());
1115 uint32_t ULEBsize = Op.getEndOffset() - OpOffset - 1;
1116 assert(ULEBsize <= 16);
1117
1118 // Copy over the operation.
1119 assert(!Op.getSubCode() && "SubOps not yet supported");
1120 OutputExpression.push_back(Op.getCode());
1121 uint64_t RefOffset;
1122 if (Desc.Op.size() == 1) {
1123 RefOffset = Op.getRawOperand(0);
1124 } else {
1125 OutputExpression.push_back(Op.getRawOperand(0));
1126 RefOffset = Op.getRawOperand(1);
1127 }
1128 uint8_t ULEB[16];
1129 uint32_t Offset = 0;
1130 unsigned RealSize = 0;
1131 // Look up the base type. For DW_OP_convert, the operand may be 0 to
1132 // instead indicate the generic type. The same holds for
1133 // DW_OP_reinterpret, which is currently not supported.
1134 if (RefOffset > 0 || Op.getCode() != dwarf::DW_OP_convert) {
1135 RefOffset += OrigUnit.getOffset();
1136 uint32_t RefDieIdx = 0;
1137 if (std::optional<uint32_t> Idx =
1138 OrigUnit.getDIEIndexForOffset(RefOffset))
1139 RefDieIdx = *Idx;
1140
1141 // Use fixed size for ULEB128 data, since we need to update that size
1142 // later with the proper offsets. Use 5 for DWARF32, 9 for DWARF64.
1143 ULEBsize = getFormParams().getDwarfOffsetByteSize() + 1;
1144
1145 RealSize = encodeULEB128(0xBADDEF, ULEB, ULEBsize);
1146
1147 Section.notePatchWithOffsetUpdate(
1148 DebugULEB128DieRefPatch(OutputExpression.size(), this, this,
1149 RefDieIdx),
1150 PatchesOffsets);
1151 } else
1152 RealSize = encodeULEB128(Offset, ULEB, ULEBsize);
1153
1154 if (RealSize > ULEBsize) {
1155 // Emit the generic type as a fallback.
1156 RealSize = encodeULEB128(0, ULEB, ULEBsize);
1157 warn("base type ref doesn't fit.");
1158 }
1159 assert(RealSize == ULEBsize && "padding failed");
1160 ArrayRef<uint8_t> ULEBbytes(ULEB, ULEBsize);
1161 OutputExpression.append(ULEBbytes.begin(), ULEBbytes.end());
1162 } else if (!getGlobalData().getOptions().UpdateIndexTablesOnly &&
1163 Op.getCode() == dwarf::DW_OP_addrx) {
1164 if (std::optional<object::SectionedAddress> SA =
1166 // DWARFLinker does not use addrx forms since it generates relocated
1167 // addresses. Replace DW_OP_addrx with DW_OP_addr here.
1168 // Argument of DW_OP_addrx should be relocated here as it is not
1169 // processed by applyValidRelocs.
1170 OutputExpression.push_back(dwarf::DW_OP_addr);
1171 uint64_t LinkedAddress = SA->Address + VarAddressAdjustment.value_or(0);
1173 sys::swapByteOrder(LinkedAddress);
1174 ArrayRef<uint8_t> AddressBytes(
1175 reinterpret_cast<const uint8_t *>(&LinkedAddress),
1176 OrigAddressByteSize);
1177 OutputExpression.append(AddressBytes.begin(), AddressBytes.end());
1178 } else
1179 warn("cann't read DW_OP_addrx operand.");
1180 } else if (!getGlobalData().getOptions().UpdateIndexTablesOnly &&
1181 Op.getCode() == dwarf::DW_OP_constx) {
1182 if (std::optional<object::SectionedAddress> SA =
1184 // DWARFLinker does not use constx forms since it generates relocated
1185 // addresses. Replace DW_OP_constx with DW_OP_const[*]u here.
1186 // Argument of DW_OP_constx should be relocated here as it is not
1187 // processed by applyValidRelocs.
1188 std::optional<uint8_t> OutOperandKind;
1189 switch (OrigAddressByteSize) {
1190 case 2:
1191 OutOperandKind = dwarf::DW_OP_const2u;
1192 break;
1193 case 4:
1194 OutOperandKind = dwarf::DW_OP_const4u;
1195 break;
1196 case 8:
1197 OutOperandKind = dwarf::DW_OP_const8u;
1198 break;
1199 default:
1200 warn(
1201 formatv(("unsupported address size: {0}."), OrigAddressByteSize));
1202 break;
1203 }
1204
1205 if (OutOperandKind) {
1206 OutputExpression.push_back(*OutOperandKind);
1207 uint64_t LinkedAddress =
1208 SA->Address + VarAddressAdjustment.value_or(0);
1210 sys::swapByteOrder(LinkedAddress);
1211 ArrayRef<uint8_t> AddressBytes(
1212 reinterpret_cast<const uint8_t *>(&LinkedAddress),
1213 OrigAddressByteSize);
1214 OutputExpression.append(AddressBytes.begin(), AddressBytes.end());
1215 }
1216 } else
1217 warn("cann't read DW_OP_constx operand.");
1218 } else {
1219 // Copy over everything else unmodified.
1220 StringRef Bytes =
1221 InputExpression.getData().slice(OpOffset, Op.getEndOffset());
1222 OutputExpression.append(Bytes.begin(), Bytes.end());
1223 }
1224 OpOffset = Op.getEndOffset();
1225 }
1226}
1227
1229 std::optional<std::reference_wrapper<const Triple>> TargetTriple,
1230 TypeUnit *ArtificialTypeUnit) {
1232
1233 DWARFDie OrigUnitDIE = getOrigUnit().getUnitDIE();
1234 if (!OrigUnitDIE.isValid())
1235 return Error::success();
1236
1237 TypeEntry *RootEntry = nullptr;
1238 if (ArtificialTypeUnit)
1239 RootEntry = ArtificialTypeUnit->getTypePool().getRoot();
1240
1241 // Clone input DIE entry recursively.
1242 std::pair<DIE *, TypeEntry *> OutCUDie = cloneDIE(
1243 OrigUnitDIE.getDebugInfoEntry(), RootEntry, getDebugInfoHeaderSize(),
1244 std::nullopt, std::nullopt, Allocator, ArtificialTypeUnit);
1245 setOutUnitDIE(OutCUDie.first);
1246
1247 if (!TargetTriple.has_value() || (OutCUDie.first == nullptr))
1248 return Error::success();
1249
1250 if (Error Err = cloneAndEmitLineTable((*TargetTriple).get()))
1251 return Err;
1252
1253 if (Error Err = cloneAndEmitDebugMacro())
1254 return Err;
1255
1257 if (Error Err = emitDebugInfo((*TargetTriple).get()))
1258 return Err;
1259
1260 // ASSUMPTION: .debug_info section should already be emitted at this point.
1261 // cloneAndEmitRanges & cloneAndEmitDebugLocations use .debug_info section
1262 // data.
1263
1264 if (Error Err = cloneAndEmitRanges())
1265 return Err;
1266
1268 return Err;
1269
1270 if (Error Err = emitDebugAddrSection())
1271 return Err;
1272
1273 // Generate Pub accelerator tables.
1277
1279 return Err;
1280
1281 return emitAbbreviations();
1282}
1283
1284std::pair<DIE *, TypeEntry *> CompileUnit::cloneDIE(
1285 const DWARFDebugInfoEntry *InputDieEntry, TypeEntry *ClonedParentTypeDIE,
1286 uint64_t OutOffset, std::optional<int64_t> FuncAddressAdjustment,
1287 std::optional<int64_t> VarAddressAdjustment, BumpPtrAllocator &Allocator,
1288 TypeUnit *ArtificialTypeUnit) {
1289 uint32_t InputDieIdx = getDIEIndex(InputDieEntry);
1290 CompileUnit::DIEInfo &Info = getDIEInfo(InputDieIdx);
1291
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;
1297
1298 DIEGenerator PlainDIEGenerator(Allocator, *this);
1299
1300 if (NeedToClonePlainDIE)
1301 // Create a cloned DIE which would be placed into the cloned version
1302 // of input compile unit.
1303 ClonedDIE.first = createPlainDIEandCloneAttributes(
1304 InputDieEntry, PlainDIEGenerator, OutOffset, FuncAddressAdjustment,
1305 VarAddressAdjustment);
1306 if (NeedToCloneTypeDIE) {
1307 // Create a cloned DIE which would be placed into the artificial type
1308 // unit.
1309 assert(ArtificialTypeUnit != nullptr);
1310 DIEGenerator TypeDIEGenerator(
1311 ArtificialTypeUnit->getTypePool().getThreadLocalAllocator(), *this);
1312
1313 ClonedDIE.second = createTypeDIEandCloneAttributes(
1314 InputDieEntry, TypeDIEGenerator, ClonedParentTypeDIE,
1315 ArtificialTypeUnit);
1316 }
1317 TypeEntry *TypeParentForChild =
1318 ClonedDIE.second ? ClonedDIE.second : ClonedParentTypeDIE;
1319
1320 bool HasPlainChildrenToClone =
1321 (ClonedDIE.first && Info.getKeepPlainChildren());
1322
1323 bool HasTypeChildrenToClone =
1324 ((ClonedDIE.second ||
1325 InputDieEntry->getTag() == dwarf::DW_TAG_compile_unit) &&
1326 Info.getKeepTypeChildren());
1327
1328 // Recursively clone children.
1329 if (HasPlainChildrenToClone || HasTypeChildrenToClone) {
1330 for (const DWARFDebugInfoEntry *CurChild =
1331 getFirstChildEntry(InputDieEntry);
1332 CurChild && CurChild->getAbbreviationDeclarationPtr();
1333 CurChild = getSiblingEntry(CurChild)) {
1334 std::pair<DIE *, TypeEntry *> ClonedChild = cloneDIE(
1335 CurChild, TypeParentForChild, OutOffset, FuncAddressAdjustment,
1336 VarAddressAdjustment, Allocator, ArtificialTypeUnit);
1337
1338 if (ClonedChild.first) {
1339 OutOffset =
1340 ClonedChild.first->getOffset() + ClonedChild.first->getSize();
1341 PlainDIEGenerator.addChild(ClonedChild.first);
1342 }
1343 }
1344 assert(ClonedDIE.first == nullptr ||
1345 HasPlainChildrenToClone == ClonedDIE.first->hasChildren());
1346
1347 // Account for the end of children marker.
1348 if (HasPlainChildrenToClone)
1349 OutOffset += sizeof(int8_t);
1350 }
1351
1352 // Update our size.
1353 if (ClonedDIE.first != nullptr)
1354 ClonedDIE.first->setSize(OutOffset - ClonedDIE.first->getOffset());
1355
1356 return ClonedDIE;
1357}
1358
1359DIE *CompileUnit::createPlainDIEandCloneAttributes(
1360 const DWARFDebugInfoEntry *InputDieEntry, DIEGenerator &PlainDIEGenerator,
1361 uint64_t &OutOffset, std::optional<int64_t> &FuncAddressAdjustment,
1362 std::optional<int64_t> &VarAddressAdjustment) {
1363 uint32_t InputDieIdx = getDIEIndex(InputDieEntry);
1364 CompileUnit::DIEInfo &Info = getDIEInfo(InputDieIdx);
1365 DIE *ClonedDIE = nullptr;
1366 bool HasLocationExpressionAddress = false;
1367 if (InputDieEntry->getTag() == dwarf::DW_TAG_subprogram) {
1368 // Get relocation adjustment value for the current function.
1369 FuncAddressAdjustment =
1370 getContaingFile().Addresses->getSubprogramRelocAdjustment(
1371 getDIE(InputDieEntry), false);
1372 } else if (InputDieEntry->getTag() == dwarf::DW_TAG_label) {
1373 // Get relocation adjustment value for the current label.
1374 std::optional<uint64_t> lowPC =
1375 dwarf::toAddress(find(InputDieEntry, dwarf::DW_AT_low_pc));
1376 if (lowPC) {
1377 LabelMapTy::iterator It = Labels.find(*lowPC);
1378 if (It != Labels.end())
1379 FuncAddressAdjustment = It->second;
1380 }
1381 } else if (InputDieEntry->getTag() == dwarf::DW_TAG_variable) {
1382 // Get relocation adjustment value for the current variable.
1383 std::pair<bool, std::optional<int64_t>> LocExprAddrAndRelocAdjustment =
1384 getContaingFile().Addresses->getVariableRelocAdjustment(
1385 getDIE(InputDieEntry), false);
1386
1387 HasLocationExpressionAddress = LocExprAddrAndRelocAdjustment.first;
1388 if (LocExprAddrAndRelocAdjustment.first &&
1389 LocExprAddrAndRelocAdjustment.second)
1390 VarAddressAdjustment = *LocExprAddrAndRelocAdjustment.second;
1391 }
1392
1393 ClonedDIE = PlainDIEGenerator.createDIE(InputDieEntry->getTag(), OutOffset);
1394
1395 // Offset to the DIE would be used after output DIE tree is deleted.
1396 // Thus we need to remember DIE offset separately.
1397 rememberDieOutOffset(InputDieIdx, OutOffset);
1398
1399 // Clone Attributes.
1400 DIEAttributeCloner AttributesCloner(ClonedDIE, *this, this, InputDieEntry,
1401 PlainDIEGenerator, FuncAddressAdjustment,
1402 VarAddressAdjustment,
1403 HasLocationExpressionAddress);
1404 AttributesCloner.clone();
1405
1406 // Remember accelerator info.
1407 AcceleratorRecordsSaver AccelRecordsSaver(getGlobalData(), *this, this);
1408 AccelRecordsSaver.save(InputDieEntry, ClonedDIE, AttributesCloner.AttrInfo,
1409 nullptr);
1410
1411 OutOffset =
1412 AttributesCloner.finalizeAbbreviations(Info.getKeepPlainChildren());
1413
1414 return ClonedDIE;
1415}
1416
1417/// Allocates output DIE for the specified \p TypeDescriptor.
1418DIE *CompileUnit::allocateTypeDie(TypeEntryBody *TypeDescriptor,
1419 DIEGenerator &TypeDIEGenerator,
1420 dwarf::Tag DieTag, bool IsDeclaration,
1421 bool IsParentDeclaration) {
1422 DIE *DefinitionDie = TypeDescriptor->Die;
1423 // Do not allocate any new DIE if definition DIE is already met.
1424 if (DefinitionDie)
1425 return nullptr;
1426
1427 DIE *DeclarationDie = TypeDescriptor->DeclarationDie;
1428 bool OldParentIsDeclaration = TypeDescriptor->ParentIsDeclaration;
1429
1430 if (IsDeclaration && !DeclarationDie) {
1431 // Alocate declaration DIE.
1432 DIE *NewDie = TypeDIEGenerator.createDIE(DieTag, 0);
1433 if (TypeDescriptor->DeclarationDie.compare_exchange_strong(DeclarationDie,
1434 NewDie))
1435 return NewDie;
1436 } else if (IsDeclaration && !IsParentDeclaration && OldParentIsDeclaration) {
1437 // Overwrite existing declaration DIE if it's parent is also an declaration
1438 // while parent of current declaration DIE is a definition.
1439 if (TypeDescriptor->ParentIsDeclaration.compare_exchange_strong(
1440 OldParentIsDeclaration, false)) {
1441 DIE *NewDie = TypeDIEGenerator.createDIE(DieTag, 0);
1442 TypeDescriptor->DeclarationDie = NewDie;
1443 return NewDie;
1444 }
1445 } else if (!IsDeclaration && IsParentDeclaration && !DeclarationDie) {
1446 // Alocate declaration DIE since parent of current DIE is marked as
1447 // declaration.
1448 DIE *NewDie = TypeDIEGenerator.createDIE(DieTag, 0);
1449 if (TypeDescriptor->DeclarationDie.compare_exchange_strong(DeclarationDie,
1450 NewDie))
1451 return NewDie;
1452 } else if (!IsDeclaration && !IsParentDeclaration) {
1453 // Allocate definition DIE.
1454 DIE *NewDie = TypeDIEGenerator.createDIE(DieTag, 0);
1455 if (TypeDescriptor->Die.compare_exchange_strong(DefinitionDie, NewDie)) {
1456 TypeDescriptor->ParentIsDeclaration = false;
1457 return NewDie;
1458 }
1459 }
1460
1461 return nullptr;
1462}
1463
1464TypeEntry *CompileUnit::createTypeDIEandCloneAttributes(
1465 const DWARFDebugInfoEntry *InputDieEntry, DIEGenerator &TypeDIEGenerator,
1466 TypeEntry *ClonedParentTypeDIE, TypeUnit *ArtificialTypeUnit) {
1467 assert(ArtificialTypeUnit != nullptr);
1468 uint32_t InputDieIdx = getDIEIndex(InputDieEntry);
1469
1470 TypeEntry *Entry = getDieTypeEntry(InputDieIdx);
1471 assert(Entry != nullptr);
1472 assert(ClonedParentTypeDIE != nullptr);
1473 TypeEntryBody *EntryBody =
1474 ArtificialTypeUnit->getTypePool().getOrCreateTypeEntryBody(
1475 Entry, ClonedParentTypeDIE);
1476 assert(EntryBody);
1477
1478 bool IsDeclaration =
1479 dwarf::toUnsigned(find(InputDieEntry, dwarf::DW_AT_declaration), 0);
1480
1481 bool ParentIsDeclaration = false;
1482 if (std::optional<uint32_t> ParentIdx = InputDieEntry->getParentIdx())
1483 ParentIsDeclaration =
1484 dwarf::toUnsigned(find(*ParentIdx, dwarf::DW_AT_declaration), 0);
1485
1486 DIE *OutDIE =
1487 allocateTypeDie(EntryBody, TypeDIEGenerator, InputDieEntry->getTag(),
1488 IsDeclaration, ParentIsDeclaration);
1489
1490 if (OutDIE != nullptr) {
1491 assert(ArtificialTypeUnit != nullptr);
1493
1494 DIEAttributeCloner AttributesCloner(OutDIE, *this, ArtificialTypeUnit,
1495 InputDieEntry, TypeDIEGenerator,
1496 std::nullopt, std::nullopt, false);
1497 AttributesCloner.clone();
1498
1499 // Remember accelerator info.
1500 AcceleratorRecordsSaver AccelRecordsSaver(getGlobalData(), *this,
1501 ArtificialTypeUnit);
1502 AccelRecordsSaver.save(InputDieEntry, OutDIE, AttributesCloner.AttrInfo,
1503 Entry);
1504
1505 // if AttributesCloner.getOutOffset() == 0 then we need to add
1506 // 1 to avoid assertion for zero size. We will subtract it back later.
1507 OutDIE->setSize(AttributesCloner.getOutOffset() + 1);
1508 }
1509
1510 return Entry;
1511}
1512
1514 const DWARFDebugLine::LineTable *InputLineTable =
1515 getContaingFile().Dwarf->getLineTableForUnit(&getOrigUnit());
1516 if (InputLineTable == nullptr) {
1517 if (getOrigUnit().getUnitDIE().find(dwarf::DW_AT_stmt_list))
1518 warn("cann't load line table.");
1519 return Error::success();
1520 }
1521
1522 DWARFDebugLine::LineTable OutLineTable;
1523
1524 // Set Line Table header.
1525 OutLineTable.Prologue = InputLineTable->Prologue;
1527
1528 // Set Line Table Rows.
1529 if (getGlobalData().getOptions().UpdateIndexTablesOnly) {
1530 OutLineTable.Rows = InputLineTable->Rows;
1531 // If all the line table contains is a DW_LNE_end_sequence, clear the line
1532 // table rows, it will be inserted again in the DWARFStreamer.
1533 if (OutLineTable.Rows.size() == 1 && OutLineTable.Rows[0].EndSequence)
1534 OutLineTable.Rows.clear();
1535
1536 OutLineTable.Sequences = InputLineTable->Sequences;
1537 } else {
1538 // This vector is the output line table.
1539 std::vector<DWARFDebugLine::Row> NewRows;
1540 NewRows.reserve(InputLineTable->Rows.size());
1541
1542 // Current sequence of rows being extracted, before being inserted
1543 // in NewRows.
1544 std::vector<DWARFDebugLine::Row> Seq;
1545
1546 const auto &FunctionRanges = getFunctionRanges();
1547 std::optional<AddressRangeValuePair> CurrRange;
1548
1549 // FIXME: This logic is meant to generate exactly the same output as
1550 // Darwin's classic dsymutil. There is a nicer way to implement this
1551 // by simply putting all the relocated line info in NewRows and simply
1552 // sorting NewRows before passing it to emitLineTableForUnit. This
1553 // should be correct as sequences for a function should stay
1554 // together in the sorted output. There are a few corner cases that
1555 // look suspicious though, and that required to implement the logic
1556 // this way. Revisit that once initial validation is finished.
1557
1558 // Iterate over the object file line info and extract the sequences
1559 // that correspond to linked functions.
1560 for (DWARFDebugLine::Row Row : InputLineTable->Rows) {
1561 // Check whether we stepped out of the range. The range is
1562 // half-open, but consider accept the end address of the range if
1563 // it is marked as end_sequence in the input (because in that
1564 // case, the relocation offset is accurate and that entry won't
1565 // serve as the start of another function).
1566 if (!CurrRange || !CurrRange->Range.contains(Row.Address.Address)) {
1567 // We just stepped out of a known range. Insert a end_sequence
1568 // corresponding to the end of the range.
1569 uint64_t StopAddress =
1570 CurrRange ? CurrRange->Range.end() + CurrRange->Value : -1ULL;
1571 CurrRange = FunctionRanges.getRangeThatContains(Row.Address.Address);
1572 if (StopAddress != -1ULL && !Seq.empty()) {
1573 // Insert end sequence row with the computed end address, but
1574 // the same line as the previous one.
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);
1583 }
1584
1585 if (!CurrRange)
1586 continue;
1587 }
1588
1589 // Ignore empty sequences.
1590 if (Row.EndSequence && Seq.empty())
1591 continue;
1592
1593 // Relocate row address and add it to the current sequence.
1594 Row.Address.Address += CurrRange->Value;
1595 Seq.emplace_back(Row);
1596
1597 if (Row.EndSequence)
1598 insertLineSequence(Seq, NewRows);
1599 }
1600
1601 OutLineTable.Rows = std::move(NewRows);
1602 }
1603
1604 return emitDebugLine(TargetTriple, OutLineTable);
1605}
1606
1607void CompileUnit::insertLineSequence(std::vector<DWARFDebugLine::Row> &Seq,
1608 std::vector<DWARFDebugLine::Row> &Rows) {
1609 if (Seq.empty())
1610 return;
1611
1612 if (!Rows.empty() && Rows.back().Address < Seq.front().Address) {
1613 llvm::append_range(Rows, Seq);
1614 Seq.clear();
1615 return;
1616 }
1617
1618 object::SectionedAddress Front = Seq.front().Address;
1619 auto InsertPoint = partition_point(
1620 Rows, [=](const DWARFDebugLine::Row &O) { return O.Address < Front; });
1621
1622 // FIXME: this only removes the unneeded end_sequence if the
1623 // sequences have been inserted in order. Using a global sort like
1624 // described in cloneAndEmitLineTable() and delaying the end_sequene
1625 // elimination to DebugLineEmitter::emit() we can get rid of all of them.
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());
1630 } else {
1631 Rows.insert(InsertPoint, Seq.begin(), Seq.end());
1632 }
1633
1634 Seq.clear();
1635}
1636
1637#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1639 llvm::errs() << "{";
1640 llvm::errs() << " Placement: ";
1641 switch (getPlacement()) {
1642 case NotSet:
1643 llvm::errs() << "NotSet";
1644 break;
1645 case TypeTable:
1646 llvm::errs() << "TypeTable";
1647 break;
1648 case PlainDwarf:
1649 llvm::errs() << "PlainDwarf";
1650 break;
1651 case Both:
1652 llvm::errs() << "Both";
1653 break;
1654 }
1655
1656 llvm::errs() << " Keep: " << getKeep();
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();
1664 llvm::errs() << "}\n";
1665}
1666#endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1667
1668std::optional<std::pair<StringRef, StringRef>>
1670 const DWARFFormValue &FileIdxValue) {
1671 uint64_t FileIdx;
1672 if (std::optional<uint64_t> Val = FileIdxValue.getAsUnsignedConstant())
1673 FileIdx = *Val;
1674 else if (std::optional<int64_t> Val = FileIdxValue.getAsSignedConstant())
1675 FileIdx = *Val;
1676 else if (std::optional<uint64_t> Val = FileIdxValue.getAsSectionOffset())
1677 FileIdx = *Val;
1678 else
1679 return std::nullopt;
1680
1681 return getDirAndFilenameFromLineTable(FileIdx);
1682}
1683
1684std::optional<std::pair<StringRef, StringRef>>
1686 FileNamesCache::iterator FileData = FileNames.find(FileIdx);
1687 if (FileData != FileNames.end())
1688 return std::make_pair(StringRef(FileData->second.first),
1689 StringRef(FileData->second.second));
1690
1691 if (const DWARFDebugLine::LineTable *LineTable =
1692 getOrigUnit().getContext().getLineTableForUnit(&getOrigUnit())) {
1693 if (LineTable->hasFileAtIndex(FileIdx)) {
1694
1696 LineTable->Prologue.getFileNameEntry(FileIdx);
1697
1698 Expected<const char *> Name = Entry.Name.getAsCString();
1699 if (!Name) {
1700 warn(Name.takeError());
1701 return std::nullopt;
1702 }
1703
1704 std::string FileName = *Name;
1705 if (isPathAbsoluteOnWindowsOrPosix(FileName)) {
1706 FileNamesCache::iterator FileData =
1707 FileNames
1708 .insert(std::make_pair(
1709 FileIdx,
1710 std::make_pair(std::string(""), std::move(FileName))))
1711 .first;
1712 return std::make_pair(StringRef(FileData->second.first),
1713 StringRef(FileData->second.second));
1714 }
1715
1716 SmallString<256> FilePath;
1717 StringRef IncludeDir;
1718 // Be defensive about the contents of Entry.
1719 if (getVersion() >= 5) {
1720 // DirIdx 0 is the compilation directory, so don't include it for
1721 // relative names.
1722 if ((Entry.DirIdx != 0) &&
1723 Entry.DirIdx < LineTable->Prologue.IncludeDirectories.size()) {
1724 Expected<const char *> DirName =
1725 LineTable->Prologue.IncludeDirectories[Entry.DirIdx]
1726 .getAsCString();
1727 if (DirName)
1728 IncludeDir = *DirName;
1729 else {
1730 warn(DirName.takeError());
1731 return std::nullopt;
1732 }
1733 }
1734 } else {
1735 if (0 < Entry.DirIdx &&
1736 Entry.DirIdx <= LineTable->Prologue.IncludeDirectories.size()) {
1737 Expected<const char *> DirName =
1738 LineTable->Prologue.IncludeDirectories[Entry.DirIdx - 1]
1739 .getAsCString();
1740 if (DirName)
1741 IncludeDir = *DirName;
1742 else {
1743 warn(DirName.takeError());
1744 return std::nullopt;
1745 }
1746 }
1747 }
1748
1750
1751 if (!CompDir.empty() && !isPathAbsoluteOnWindowsOrPosix(IncludeDir)) {
1752 sys::path::append(FilePath, sys::path::Style::native, CompDir);
1753 }
1754
1755 sys::path::append(FilePath, sys::path::Style::native, IncludeDir);
1756
1757 FileNamesCache::iterator FileData =
1758 FileNames
1759 .insert(
1760 std::make_pair(FileIdx, std::make_pair(std::string(FilePath),
1761 std::move(FileName))))
1762 .first;
1763 return std::make_pair(StringRef(FileData->second.first),
1764 StringRef(FileData->second.second));
1765 }
1766 }
1767
1768 return std::nullopt;
1769}
1770
1771#define MAX_REFERENCIES_DEPTH 1000
1773 UnitEntryPairTy CUDiePair(*this);
1774 std::optional<UnitEntryPairTy> RefDiePair;
1775 int refDepth = 0;
1776 do {
1777 RefDiePair = CUDiePair.CU->resolveDIEReference(
1778 CUDiePair.DieEntry, dwarf::DW_AT_extension,
1780 if (!RefDiePair || !RefDiePair->DieEntry)
1781 return CUDiePair;
1782
1783 CUDiePair = *RefDiePair;
1784 } while (refDepth++ < MAX_REFERENCIES_DEPTH);
1785
1786 return CUDiePair;
1787}
1788
1789std::optional<UnitEntryPairTy> UnitEntryPairTy::getParent() {
1790 if (std::optional<uint32_t> ParentIdx = DieEntry->getParentIdx())
1791 return UnitEntryPairTy{CU, CU->getDebugInfoEntry(*ParentIdx)};
1792
1793 return std::nullopt;
1794}
1795
1797 : Ptr(U) {
1798 assert(U != nullptr);
1799}
1800
1802 assert(U != nullptr);
1803}
1804
1806 if (isCompileUnit())
1807 return getAsCompileUnit();
1808 else
1809 return getAsTypeUnit();
1810}
1811
1813 return isa<CompileUnit *>(Ptr);
1814}
1815
1817 return isa<TypeUnit *>(Ptr);
1818}
1819
1821 return cast<CompileUnit *>(Ptr);
1822}
1823
1825 return cast<TypeUnit *>(Ptr);
1826}
1827
1829 bool InterCUProcessingStarted, std::atomic<bool> &HasNewInterconnectedCUs) {
1830 if (!Dependencies)
1831 Dependencies.reset(new DependencyTracker(*this));
1832
1833 return Dependencies->resolveDependenciesAndMarkLiveness(
1834 InterCUProcessingStarted, HasNewInterconnectedCUs);
1835}
1836
1838 assert(Dependencies.get());
1839
1840 return Dependencies->updateDependenciesCompleteness();
1841}
1842
1844 assert(Dependencies.get());
1845
1846 Dependencies->verifyKeepChain();
1847}
1848
1850 static dwarf::Attribute ODRAttributes[] = {
1851 dwarf::DW_AT_type, dwarf::DW_AT_specification,
1852 dwarf::DW_AT_abstract_origin, dwarf::DW_AT_import};
1853
1854 return ODRAttributes;
1855}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition: Compiler.h:638
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
if(PassOpts->AAPipeline)
Basic Register Allocator
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.
Definition: AddressRanges.h:22
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),...
Definition: ArrayRef.h:41
iterator end() const
Definition: ArrayRef.h:136
iterator begin() const
Definition: ArrayRef.h:135
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:67
std::pair< KeyDataTy *, bool > insert(const KeyTy &NewValue)
Insert new value NewValue or return already existing entry.
A structured debug information entry.
Definition: DIE.h:828
void setSize(unsigned S)
Definition: DIE.h:941
DWARFDebugInfoEntry - A DIE with only the minimum required data.
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.
Definition: DWARFDie.h:43
LLVM_ABI std::optional< DWARFFormValue > find(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE.
Definition: DWARFDie.cpp:250
const DWARFDebugInfoEntry * getDebugInfoEntry() const
Definition: DWARFDie.h:54
LLVM_ABI const char * getName(DINameKind Kind) const
Return the DIE name resolving DW_AT_specification or DW_AT_abstract_origin references if necessary.
Definition: DWARFDie.cpp:463
bool isValid() const
Definition: DWARFDie.h:52
This class represents an Operation in the Expression.
LLVM_ABI std::optional< unsigned > getSubCode() const
Encoding
Size and signedness of expression operations' operands.
const Description & getDescription() const
uint64_t getRawOperand(unsigned Idx) const
StringRef getData() const
LLVM_ABI std::optional< uint64_t > getAsSectionOffset() const
LLVM_ABI std::optional< int64_t > getAsSignedConstant() const
LLVM_ABI std::optional< uint64_t > getAsRelativeReference() const
getAsFoo functions below return the extracted value as Foo if only DWARFFormValue has form class is s...
LLVM_ABI std::optional< uint64_t > getAsDebugInfoReference() const
LLVM_ABI std::optional< uint64_t > getAsUnsignedConstant() const
const DWARFUnit * getUnit() const
const dwarf::FormParams & getFormParams() const
Definition: DWARFUnit.h:326
DWARFDie getUnitDIE(bool ExtractUnitDIEOnly=true)
Definition: DWARFUnit.h:447
uint8_t getAddressByteSize() const
Definition: DWARFUnit.h:330
const char * getCompilationDir()
Definition: DWARFUnit.cpp:401
std::optional< uint32_t > getDIEIndexForOffset(uint64_t Offset)
Return the DIE index for a given offset Offset inside the unit's DIE vector.
Definition: DWARFUnit.h:546
Expected< DWARFLocationExpressionsVector > findLoclistFromOffset(uint64_t Offset)
Definition: DWARFUnit.cpp:708
bool isLittleEndian() const
Definition: DWARFUnit.h:321
std::optional< object::SectionedAddress > getAddrOffsetSectionItem(uint32_t Index) const
Definition: DWARFUnit.cpp:215
uint64_t getOffset() const
Definition: DWARFUnit.h:325
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:177
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT > iterator
Definition: DenseMap.h:74
iterator end()
Definition: DenseMap.h:87
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:230
void shrink_and_clear()
Definition: DenseMap.h:828
Lightweight error class with error context and mandatory checking.
Definition: Error.h:159
static ErrorSuccess success()
Create a success value.
Definition: Error.h:336
Tagged union holding either a T or a Error.
Definition: Error.h:485
Error takeError()
Take ownership of the stored error.
Definition: Error.h:612
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
size_t size() const
Definition: SmallVector.h:79
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:574
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:684
void resize(size_type N)
Definition: SmallVector.h:639
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:233
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:151
iterator begin() const
Definition: StringRef.h:120
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
Definition: StringRef.h:694
iterator end() const
Definition: StringRef.h:122
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:47
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:82
This class represents DWARF information for source file and it's address map.
Definition: DWARFFile.h:25
std::unique_ptr< AddressesMap > Addresses
Helpful address information(list of valid address ranges, relocations).
Definition: DWARFFile.h:42
std::unique_ptr< DWARFContext > Dwarf
Source DWARF information.
Definition: DWARFFile.h:39
const SmallVector< T > & getValues() const
CompileUnit(DWARFUnit &OrigUnit, unsigned ID, bool CanUseODR, StringRef ClangModuleName)
This class helps to store information for accelerator entries.
CompileUnit * getAsCompileUnit()
Returns CompileUnit if applicable.
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)
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.
@ CreatedNotLoaded
Created, linked with input DWARF file.
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.
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.
Definition: DIEGenerator.h:22
void addChild(DIE *Child)
Adds a specified Child to the current DIE.
Definition: DIEGenerator.h:42
DIE * createDIE(dwarf::Tag DieTag, uint32_t OutOffset)
Creates a DIE of specified tag DieTag and OutOffset.
Definition: DIEGenerator.h:31
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.
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.
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.
Definition: TypePool.h:30
std::atomic< DIE * > Die
TypeEntryBody keeps partially cloned DIEs corresponding to this type.
Definition: TypePool.h:59
TypePool keeps type descriptors which contain partially cloned DIE correspinding to each type.
Definition: TypePool.h:111
BumpPtrAllocator & getThreadLocalAllocator()
Return thread local allocator used by pool.
Definition: TypePool.h:161
TypeEntryBody * getOrCreateTypeEntryBody(TypeEntry *Entry, TypeEntry *ParentEntry)
Create or return existing type entry body for the specified Entry.
Definition: TypePool.h:131
TypeEntry * getRoot() const
Return root for all type entries.
Definition: TypePool.h:158
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.
Definition: raw_ostream.h:148
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 emitDebugLine(const Triple &TargetTriple, const DWARFDebugLine::LineTable &OutLineTable)
Emit .debug_line section.
@ HeaderSize
Definition: BTF.h:61
@ Entry
Definition: COFF.h:862
bool isODRLanguage(uint16_t Language)
ArrayRef< dwarf::Attribute > getODRAttributes()
StringRef guessDeveloperDir(StringRef SysRoot)
Make a best effort to guess the Xcode.app/Contents/Developer path from an SDK path.
Definition: Utils.h:41
DebugSectionKind
List of tracked debug tables.
bool isInToolchainDir(StringRef Path)
Make a best effort to determine whether Path is inside a toolchain.
Definition: Utils.h:77
bool isPathAbsoluteOnWindowsOrPosix(const Twine &Path)
Definition: Utils.h:98
std::optional< uint64_t > toAddress(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an address.
@ DW_MACRO_lo_user
Definition: Dwarf.h:814
@ DW_MACRO_hi_user
Definition: Dwarf.h:815
Attribute
Attributes.
Definition: Dwarf.h:124
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
@ DW_MACINFO_vendor_ext
Definition: Dwarf.h:807
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.
Definition: Dwarf.h:65
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.
Definition: Path.cpp:467
LLVM_ABI bool is_relative(const Twine &path, Style style=Style::native)
Is path relative?
Definition: Path.cpp:699
LLVM_ABI StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get filename.
Definition: Path.cpp:577
LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition: Path.cpp:456
void swapByteOrder(T &Value)
Definition: SwapByteOrder.h:61
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:477
void fill(R &&Range, T &&Value)
Provide wrappers to std::fill which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1764
auto partition_point(R &&Range, Predicate P)
Binary search for the first iterator in a range where a predicate is false.
Definition: STLExtras.h:2090
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition: STLExtras.h:2155
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...
Definition: Alignment.h:197
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.
Definition: STLExtras.h:1916
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
Definition: LEB128.h:81
bool isCompileUnit(const std::unique_ptr< DWARFUnit > &U)
Definition: DWARFUnit.h:599
endianness
Definition: bit.h:71
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
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.
A helper struct providing information about the byte size of DW_FORM values that vary in size dependi...
Definition: Dwarf.h:1093
DwarfFormat Format
Definition: Dwarf.h:1096
uint8_t getDwarfOffsetByteSize() const
The size of a reference is determined by the DWARF 32/64-bit format.
Definition: Dwarf.h:1111
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.
This structure is used to update reference to the DIE.
PointerIntPair< CompileUnit *, 1 > RefCU
This structure is used to update location list offset into .debug_loc/.debug_loclists.
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.
dwarf::FormParams getFormParams() const
Returns FormParams used by section.
Definition: DWARFLinker.h:108
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.