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