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
9#include "DWARFLinkerCompileUnit.h"
10#include "AcceleratorRecordsSaver.h"
11#include "DIEAttributeCloner.h"
12#include "DIEGenerator.h"
13#include "DependencyTracker.h"
14#include "SyntheticTypeNameBuilder.h"
15#include "llvm/DWARFLinker/Utils.h"
16#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
17#include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
18#include "llvm/Support/FileSystem.h"
19#include "llvm/Support/FormatVariadic.h"
20#include "llvm/Support/Path.h"
21#include <utility>
22
23using namespace llvm;
24using namespace dwarf_linker;
25using namespace dwarf_linker::parallel;
26
27CompileUnit::CompileUnit(LinkingGlobalData &GlobalData, unsigned ID,
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, Endianness: Endianess);
36 getOrCreateSectionDescriptor(SectionKind: DebugSectionKind::DebugInfo);
37}
38
39CompileUnit::CompileUnit(LinkingGlobalData &GlobalData, DWARFUnit &OrigUnit,
40 unsigned ID, StringRef ClangModuleName,
41 DWARFFile &File, OffsetToUnitTy UnitFromOffset,
42 dwarf::FormParams Format, llvm::endianness Endianess)
43 : DwarfUnit(GlobalData, ID, ClangModuleName), File(File),
44 OrigUnit(&OrigUnit), getUnitFromOffset(UnitFromOffset),
45 Stage(Stage::CreatedNotLoaded),
46 AcceleratorRecords(&GlobalData.getAllocator()) {
47 setOutputFormat(Format, Endianness: Endianess);
48 getOrCreateSectionDescriptor(SectionKind: DebugSectionKind::DebugInfo);
49
50 DWARFDie CUDie = OrigUnit.getUnitDIE();
51 if (!CUDie)
52 return;
53
54 Language = CUDie.getLanguage();
55
56 if (!GlobalData.getOptions().NoODR && Language.has_value() &&
57 isODRLanguage(Language: *Language))
58 NoODR = false;
59
60 if (const char *CUName = CUDie.getName(Kind: DINameKind::ShortName))
61 UnitName = CUName;
62 else
63 UnitName = File.FileName;
64 SysRoot = dwarf::toStringRef(V: CUDie.find(Attr: dwarf::DW_AT_LLVM_sysroot)).str();
65}
66
67void CompileUnit::loadLineTable() {
68 LineTablePtr = File.Dwarf->getLineTableForUnit(U: &getOrigUnit());
69}
70
71void CompileUnit::maybeResetToLoadedStage() {
72 // Nothing to reset if stage is less than "Loaded".
73 if (getStage() < Stage::Loaded)
74 return;
75
76 // Note: We need to do erasing for "Loaded" stage because
77 // if live analysys failed then we will have "Loaded" stage
78 // with marking from "LivenessAnalysisDone" stage partially
79 // done. That marking should be cleared.
80
81 for (DIEInfo &Info : DieInfoArray)
82 Info.unsetFlagsWhichSetDuringLiveAnalysis();
83
84 LowPc = std::nullopt;
85 HighPc = 0;
86 Labels.clear();
87 Ranges.clear();
88 Dependencies.reset(p: nullptr);
89
90 if (getStage() < Stage::Cloned) {
91 setStage(Stage::Loaded);
92 return;
93 }
94
95 AcceleratorRecords.erase();
96 AbbreviationsSet.clear();
97 Abbreviations.clear();
98 OutUnitDIE = nullptr;
99 DebugAddrIndexMap.clear();
100 StmtSeqListAttributes.clear();
101
102 llvm::fill(Range&: OutDieOffsetArray, Value: 0);
103 llvm::fill(Range&: TypeEntries, Value: nullptr);
104 eraseSections();
105
106 setStage(Stage::CreatedNotLoaded);
107}
108
109bool CompileUnit::loadInputDIEs() {
110 DWARFDie InputUnitDIE = getUnitDIE(ExtractUnitDIEOnly: false);
111 if (!InputUnitDIE)
112 return false;
113
114 // load input dies, resize Info structures array.
115 DieInfoArray.resize(N: getOrigUnit().getNumDIEs());
116 OutDieOffsetArray.resize(N: getOrigUnit().getNumDIEs(), NV: 0);
117 if (!NoODR)
118 TypeEntries.resize(N: getOrigUnit().getNumDIEs());
119 return true;
120}
121
122void CompileUnit::analyzeDWARFStructureRec(const DWARFDebugInfoEntry *DieEntry,
123 bool IsODRUnavailableFunctionScope) {
124 CompileUnit::DIEInfo &DieInfo = getDIEInfo(Entry: DieEntry);
125
126 for (const DWARFDebugInfoEntry *CurChild = getFirstChildEntry(Die: DieEntry);
127 CurChild && CurChild->getAbbreviationDeclarationPtr();
128 CurChild = getSiblingEntry(Die: CurChild)) {
129 CompileUnit::DIEInfo &ChildInfo = getDIEInfo(Entry: CurChild);
130 bool ChildIsODRUnavailableFunctionScope = IsODRUnavailableFunctionScope;
131
132 if (DieInfo.getIsInMouduleScope())
133 ChildInfo.setIsInMouduleScope();
134
135 if (DieInfo.getIsInFunctionScope())
136 ChildInfo.setIsInFunctionScope();
137
138 if (DieInfo.getIsInAnonNamespaceScope())
139 ChildInfo.setIsInAnonNamespaceScope();
140
141 switch (CurChild->getTag()) {
142 case dwarf::DW_TAG_module:
143 ChildInfo.setIsInMouduleScope();
144 if (DieEntry->getTag() == dwarf::DW_TAG_compile_unit &&
145 dwarf::toString(V: find(Die: CurChild, Attrs: dwarf::DW_AT_name), Default: "") !=
146 getClangModuleName())
147 analyzeImportedModule(DieEntry: CurChild);
148 break;
149 case dwarf::DW_TAG_subprogram:
150 ChildInfo.setIsInFunctionScope();
151 if (!ChildIsODRUnavailableFunctionScope &&
152 !ChildInfo.getIsInMouduleScope()) {
153 if (find(Die: CurChild,
154 Attrs: {dwarf::DW_AT_abstract_origin, dwarf::DW_AT_specification}))
155 ChildIsODRUnavailableFunctionScope = true;
156 }
157 break;
158 case dwarf::DW_TAG_namespace: {
159 UnitEntryPairTy NamespaceEntry = {this, CurChild};
160
161 if (find(Die: CurChild, Attrs: dwarf::DW_AT_extension))
162 NamespaceEntry = NamespaceEntry.getNamespaceOrigin();
163
164 if (!NamespaceEntry.CU->find(Die: NamespaceEntry.DieEntry, Attrs: dwarf::DW_AT_name))
165 ChildInfo.setIsInAnonNamespaceScope();
166 } break;
167 default:
168 break;
169 }
170
171 if (!isClangModule() && !getGlobalData().getOptions().UpdateIndexTablesOnly)
172 ChildInfo.setTrackLiveness();
173
174 if ((!ChildInfo.getIsInAnonNamespaceScope() &&
175 !ChildIsODRUnavailableFunctionScope && !NoODR))
176 ChildInfo.setODRAvailable();
177
178 if (CurChild->hasChildren())
179 analyzeDWARFStructureRec(DieEntry: CurChild, IsODRUnavailableFunctionScope: ChildIsODRUnavailableFunctionScope);
180 }
181}
182
183StringEntry *CompileUnit::getFileName(unsigned FileIdx,
184 StringPool &GlobalStrings) {
185 if (LineTablePtr) {
186 if (LineTablePtr->hasFileAtIndex(FileIndex: FileIdx)) {
187 // Cache the resolved paths based on the index in the line table,
188 // because calling realpath is expensive.
189 ResolvedPathsMap::const_iterator It = ResolvedFullPaths.find(Val: FileIdx);
190 if (It == ResolvedFullPaths.end()) {
191 std::string OrigFileName;
192 bool FoundFileName = LineTablePtr->getFileNameByIndex(
193 FileIndex: FileIdx, CompDir: getOrigUnit().getCompilationDir(),
194 Kind: DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
195 Result&: OrigFileName);
196 (void)FoundFileName;
197 assert(FoundFileName && "Must get file name from line table");
198
199 // Second level of caching, this time based on the file's parent
200 // path.
201 StringRef FileName = sys::path::filename(path: OrigFileName);
202 StringRef ParentPath = sys::path::parent_path(path: OrigFileName);
203
204 // If the ParentPath has not yet been resolved, resolve and cache it for
205 // future look-ups.
206 StringMap<StringEntry *>::iterator ParentIt =
207 ResolvedParentPaths.find(Key: ParentPath);
208 if (ParentIt == ResolvedParentPaths.end()) {
209 SmallString<256> RealPath;
210 sys::fs::real_path(path: ParentPath, output&: RealPath);
211 ParentIt =
212 ResolvedParentPaths
213 .insert(KV: {ParentPath, GlobalStrings.insert(NewValue: RealPath).first})
214 .first;
215 }
216
217 // Join the file name again with the resolved path.
218 SmallString<256> ResolvedPath(ParentIt->second->first());
219 sys::path::append(path&: ResolvedPath, a: FileName);
220
221 It = ResolvedFullPaths
222 .insert(KV: std::make_pair(
223 x&: FileIdx, y: GlobalStrings.insert(NewValue: ResolvedPath).first))
224 .first;
225 }
226
227 return It->second;
228 }
229 }
230
231 return nullptr;
232}
233
234llvm::Error CompileUnit::setPriority(uint64_t ObjFileIdx, uint64_t LocalIdx) {
235 if (ObjFileIdx > std::numeric_limits<uint32_t>::max())
236 return llvm::createStringError(Fmt: "cannot compute priority when number of "
237 "object files exceeds UINT32_MAX");
238 if (LocalIdx > std::numeric_limits<uint32_t>::max())
239 return llvm::createStringError(Fmt: "cannot compute priority when number of "
240 "local index exceeds UINT32_MAX");
241
242 Priority = (ObjFileIdx << 32) | LocalIdx;
243 return llvm::Error::success();
244}
245
246void CompileUnit::cleanupDataAfterClonning() {
247 AbbreviationsSet.clear();
248 ResolvedFullPaths.shrink_and_clear();
249 ResolvedParentPaths.clear();
250 FileNames.shrink_and_clear();
251 DieInfoArray = SmallVector<DIEInfo>();
252 OutDieOffsetArray = SmallVector<uint64_t>();
253 TypeEntries = SmallVector<TypeEntry *>();
254 Dependencies.reset(p: nullptr);
255 StmtSeqListAttributes.clear();
256 getOrigUnit().clear();
257}
258
259bool CompileUnit::getModulePath(const DWARFDebugInfoEntry *DieEntry,
260 SmallVectorImpl<char> &Path) {
261 assert(DieEntry->getTag() == dwarf::DW_TAG_module);
262
263 SmallVector<StringRef, 4> Names;
264 for (const DWARFDebugInfoEntry *CurEntry = DieEntry;
265 CurEntry && CurEntry->getTag() == dwarf::DW_TAG_module;
266 CurEntry = getParent(Die: CurEntry).getDebugInfoEntry()) {
267 StringRef Name = dwarf::toStringRef(V: find(Die: CurEntry, Attrs: dwarf::DW_AT_name));
268 if (Name.empty())
269 return false;
270 Names.push_back(Elt: Name);
271 }
272
273 for (StringRef Name : reverse(C&: Names)) {
274 Path.append(in_start: Name.begin(), in_end: Name.end());
275 Path.push_back(Elt: '\0');
276 }
277
278 return true;
279}
280
281void CompileUnit::noteModuleAnchors() {
282 const DWARFDebugInfoEntry *UnitEntry = getUnitDIE().getDebugInfoEntry();
283 assert(UnitEntry && "unit reached cloning without loaded DIEs");
284
285 // Find the root, ignoring the skeletons for the imported module.
286 const DWARFDebugInfoEntry *Root = nullptr;
287 for (const DWARFDebugInfoEntry *CurChild = getFirstChildEntry(Die: UnitEntry);
288 CurChild && CurChild->getAbbreviationDeclarationPtr();
289 CurChild = getSiblingEntry(Die: CurChild)) {
290 if (CurChild->getTag() == dwarf::DW_TAG_module &&
291 dwarf::toStringRef(V: find(Die: CurChild, Attrs: dwarf::DW_AT_name)) ==
292 getClangModuleName()) {
293 Root = CurChild;
294 break;
295 }
296 }
297 if (!Root)
298 return;
299
300 SmallString<128> Path;
301
302 // Submodules nest inside the module which declares them, so following the
303 // DW_TAG_module chain down from the root visits every module this unit
304 // describes, without walking the types they contain.
305 SmallVector<const DWARFDebugInfoEntry *, 4> WorkList = {Root};
306 while (!WorkList.empty()) {
307 const DWARFDebugInfoEntry *DieEntry = WorkList.pop_back_val();
308
309 for (const DWARFDebugInfoEntry *CurChild = getFirstChildEntry(Die: DieEntry);
310 CurChild && CurChild->getAbbreviationDeclarationPtr();
311 CurChild = getSiblingEntry(Die: CurChild))
312 if (CurChild->getTag() == dwarf::DW_TAG_module)
313 WorkList.push_back(Elt: CurChild);
314
315 Path.clear();
316 if (!getModulePath(DieEntry, Path))
317 continue;
318
319 ModuleAnchor Anchor;
320 Anchor.Priority = getPriority();
321 if (getDIEInfo(Entry: DieEntry).needToPlaceInTypeTable())
322 Anchor.TypeName = getDieTypeEntry(InputDieEntry: DieEntry);
323 if (!Anchor.TypeName) {
324 // Don't create a dangling reference to a DIE without a type entry or
325 // output offset.
326 uint64_t OutOffset = getDieOutOffset(InputDieEntry: DieEntry);
327 if (!OutOffset)
328 continue;
329 Anchor.Section = &getSectionDescriptor(SectionKind: DebugSectionKind::DebugInfo);
330 Anchor.LocalOffset = OutOffset;
331 }
332
333 getGlobalData().getModulePool().set(Path, Location: Anchor);
334 }
335}
336
337/// Collect references to parseable Swift interfaces in imported
338/// DW_TAG_module blocks.
339void CompileUnit::analyzeImportedModule(const DWARFDebugInfoEntry *DieEntry) {
340 if (!Language || Language != dwarf::DW_LANG_Swift)
341 return;
342
343 if (!GlobalData.getOptions().ParseableSwiftInterfaces)
344 return;
345
346 StringRef Path =
347 dwarf::toStringRef(V: find(Die: DieEntry, Attrs: dwarf::DW_AT_LLVM_include_path));
348 if (!Path.ends_with(Suffix: ".swiftinterface"))
349 return;
350 // Don't track interfaces that are part of the SDK.
351 StringRef SysRoot =
352 dwarf::toStringRef(V: find(Die: DieEntry, Attrs: dwarf::DW_AT_LLVM_sysroot));
353 if (SysRoot.empty())
354 SysRoot = getSysRoot();
355 if (!SysRoot.empty() && Path.starts_with(Prefix: SysRoot))
356 return;
357 // Don't track interfaces that are part of the toolchain.
358 // For example: Swift, _Concurrency, ...
359 StringRef DeveloperDir = guessDeveloperDir(SysRoot);
360 if (!DeveloperDir.empty() && Path.starts_with(Prefix: DeveloperDir))
361 return;
362 if (isInToolchainDir(Path))
363 return;
364 if (std::optional<DWARFFormValue> Val = find(Die: DieEntry, Attrs: dwarf::DW_AT_name)) {
365 Expected<const char *> Name = Val->getAsCString();
366 if (!Name) {
367 warn(Warning: Name.takeError());
368 return;
369 }
370
371 // The prepend path is applied later when copying.
372 SmallString<128> ResolvedPath;
373 if (sys::path::is_relative(path: Path))
374 sys::path::append(
375 path&: ResolvedPath,
376 a: dwarf::toString(V: getUnitDIE().find(Attr: dwarf::DW_AT_comp_dir), Default: ""));
377 sys::path::append(path&: ResolvedPath, a: Path);
378
379 // Stage the entry. It will be merged into the shared
380 // ParseableSwiftInterfaces map after the parallel analysis phase so that
381 // the final contents and any conflict warnings are deterministic.
382 PendingSwiftInterfaces.emplace_back(Args&: *Name, Args&: ResolvedPath);
383 }
384}
385
386void CompileUnit::mergeSwiftInterfaces(
387 DWARFLinkerBase::SwiftInterfacesMapTy &Map) {
388 for (auto &Pending : PendingSwiftInterfaces) {
389 auto &Entry = Map[Pending.ModuleName];
390 if (!Entry.empty() && Entry != Pending.ResolvedPath)
391 warn(Warning: Twine("conflicting parseable interfaces for Swift Module ") +
392 Pending.ModuleName + ": " + Entry + " and " + Pending.ResolvedPath +
393 ".");
394 Entry = Pending.ResolvedPath;
395 }
396 PendingSwiftInterfaces.clear();
397}
398
399Error CompileUnit::assignTypeNames(TypePool &TypePoolRef) {
400 if (!getUnitDIE().isValid())
401 return Error::success();
402
403 SyntheticTypeNameBuilder NameBuilder(TypePoolRef);
404 return assignTypeNamesRec(DieEntry: getDebugInfoEntry(Index: 0), NameBuilder);
405}
406
407Error CompileUnit::assignTypeNamesRec(const DWARFDebugInfoEntry *DieEntry,
408 SyntheticTypeNameBuilder &NameBuilder) {
409 OrderedChildrenIndexAssigner ChildrenIndexAssigner(*this, DieEntry);
410 for (const DWARFDebugInfoEntry *CurChild = getFirstChildEntry(Die: DieEntry);
411 CurChild && CurChild->getAbbreviationDeclarationPtr();
412 CurChild = getSiblingEntry(Die: CurChild)) {
413 CompileUnit::DIEInfo &ChildInfo = getDIEInfo(Entry: CurChild);
414 if (!ChildInfo.needToPlaceInTypeTable())
415 continue;
416
417 assert(ChildInfo.getODRAvailable());
418 if (Error Err = NameBuilder.assignName(
419 InputUnitEntryPair: {this, CurChild},
420 ChildIndex: ChildrenIndexAssigner.getChildIndex(CU&: *this, ChildDieEntry: CurChild)))
421 return Err;
422
423 if (Error Err = assignTypeNamesRec(DieEntry: CurChild, NameBuilder))
424 return Err;
425 }
426
427 return Error::success();
428}
429
430void CompileUnit::updateDieRefPatchesWithClonedOffsets() {
431 if (std::optional<SectionDescriptor *> DebugInfoSection =
432 tryGetSectionDescriptor(SectionKind: DebugSectionKind::DebugInfo)) {
433
434 (*DebugInfoSection)
435 ->ListDebugDieRefPatch.forEach(Handler: [&](DebugDieRefPatch &Patch) {
436 /// Replace stored DIE indexes with DIE output offsets.
437 Patch.RefDieIdxOrClonedOffset =
438 Patch.RefCU.getPointer()->getDieOutOffset(
439 Idx: Patch.RefDieIdxOrClonedOffset);
440 });
441
442 (*DebugInfoSection)
443 ->ListDebugULEB128DieRefPatch.forEach(
444 Handler: [&](DebugULEB128DieRefPatch &Patch) {
445 /// Replace stored DIE indexes with DIE output offsets.
446 Patch.RefDieIdxOrClonedOffset =
447 Patch.RefCU.getPointer()->getDieOutOffset(
448 Idx: Patch.RefDieIdxOrClonedOffset);
449 });
450
451 (*DebugInfoSection)
452 ->ListDebugDieModuleRefPatch.forEach(
453 Handler: [&](DebugDieModuleRefPatch &Patch) {
454 /// Replace stored DIE indexes with DIE output offsets.
455 Patch.RefDieIdxOrClonedOffset =
456 Patch.RefCU.getPointer()->getDieOutOffset(
457 Idx: Patch.RefDieIdxOrClonedOffset);
458 });
459 }
460
461 if (std::optional<SectionDescriptor *> DebugLocSection =
462 tryGetSectionDescriptor(SectionKind: DebugSectionKind::DebugLoc)) {
463 (*DebugLocSection)
464 ->ListDebugULEB128DieRefPatch.forEach(
465 Handler: [](DebugULEB128DieRefPatch &Patch) {
466 /// Replace stored DIE indexes with DIE output offsets.
467 Patch.RefDieIdxOrClonedOffset =
468 Patch.RefCU.getPointer()->getDieOutOffset(
469 Idx: Patch.RefDieIdxOrClonedOffset);
470 });
471 }
472
473 if (std::optional<SectionDescriptor *> DebugLocListsSection =
474 tryGetSectionDescriptor(SectionKind: DebugSectionKind::DebugLocLists)) {
475 (*DebugLocListsSection)
476 ->ListDebugULEB128DieRefPatch.forEach(
477 Handler: [](DebugULEB128DieRefPatch &Patch) {
478 /// Replace stored DIE indexes with DIE output offsets.
479 Patch.RefDieIdxOrClonedOffset =
480 Patch.RefCU.getPointer()->getDieOutOffset(
481 Idx: Patch.RefDieIdxOrClonedOffset);
482 });
483 }
484}
485
486std::optional<UnitEntryPairTy> CompileUnit::resolveDIEReference(
487 const DWARFFormValue &RefValue,
488 ResolveInterCUReferencesMode CanResolveInterCUReferences) {
489 CompileUnit *RefCU;
490 uint64_t RefDIEOffset;
491 if (std::optional<uint64_t> Offset = RefValue.getAsRelativeReference()) {
492 RefCU = this;
493 RefDIEOffset = RefValue.getUnit()->getOffset() + *Offset;
494 } else if (Offset = RefValue.getAsDebugInfoReference(); Offset) {
495 RefCU = getUnitFromOffset(*Offset);
496 RefDIEOffset = *Offset;
497 } else {
498 return std::nullopt;
499 }
500
501 if (RefCU == this) {
502 // Referenced DIE is in current compile unit.
503 if (std::optional<uint32_t> RefDieIdx =
504 getDIEIndexForOffset(Offset: RefDIEOffset)) {
505 const DWARFDebugInfoEntry *RefEntry = getDebugInfoEntry(Index: *RefDieIdx);
506 // In a file with broken references, an attribute might point to a
507 // NULL DIE. Treat that as a resolution failure so callers can warn.
508 if (RefEntry && RefEntry->getAbbreviationDeclarationPtr())
509 return UnitEntryPairTy{this, RefEntry};
510 }
511 } else if (RefCU && CanResolveInterCUReferences) {
512 // Referenced DIE is in other compile unit.
513
514 // Check whether DIEs are loaded for that compile unit.
515 enum Stage ReferredCUStage = RefCU->getStage();
516 if (ReferredCUStage < Stage::Loaded || ReferredCUStage > Stage::Cloned)
517 return UnitEntryPairTy{RefCU, nullptr};
518
519 if (std::optional<uint32_t> RefDieIdx =
520 RefCU->getDIEIndexForOffset(Offset: RefDIEOffset)) {
521 const DWARFDebugInfoEntry *RefEntry =
522 RefCU->getDebugInfoEntry(Index: *RefDieIdx);
523 if (RefEntry && RefEntry->getAbbreviationDeclarationPtr())
524 return UnitEntryPairTy{RefCU, RefEntry};
525 }
526 } else {
527 return UnitEntryPairTy{RefCU, nullptr};
528 }
529 return std::nullopt;
530}
531
532std::optional<UnitEntryPairTy> CompileUnit::resolveDIEReference(
533 const DWARFDebugInfoEntry *DieEntry, dwarf::Attribute Attr,
534 ResolveInterCUReferencesMode CanResolveInterCUReferences) {
535 if (std::optional<DWARFFormValue> AttrVal = find(Die: DieEntry, Attrs: Attr))
536 return resolveDIEReference(RefValue: *AttrVal, CanResolveInterCUReferences);
537
538 return std::nullopt;
539}
540
541void CompileUnit::addFunctionRange(uint64_t FuncLowPc, uint64_t FuncHighPc,
542 int64_t PcOffset) {
543 std::lock_guard<std::mutex> Guard(RangesMutex);
544
545 Ranges.insert(Range: {FuncLowPc, FuncHighPc}, Value: PcOffset);
546 if (LowPc)
547 LowPc = std::min(a: *LowPc, b: FuncLowPc + PcOffset);
548 else
549 LowPc = FuncLowPc + PcOffset;
550 this->HighPc = std::max(a: HighPc, b: FuncHighPc + PcOffset);
551}
552
553void CompileUnit::addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset) {
554 std::lock_guard<std::mutex> Guard(LabelsMutex);
555 Labels.insert(KV: {LabelLowPc, PcOffset});
556}
557
558Error CompileUnit::cloneAndEmitDebugLocations() {
559 if (getGlobalData().getOptions().UpdateIndexTablesOnly)
560 return Error::success();
561
562 if (getOrigUnit().getVersion() < 5) {
563 emitLocations(LocationSectionKind: DebugSectionKind::DebugLoc);
564 return Error::success();
565 }
566
567 emitLocations(LocationSectionKind: DebugSectionKind::DebugLocLists);
568 return Error::success();
569}
570
571void CompileUnit::emitLocations(DebugSectionKind LocationSectionKind) {
572 SectionDescriptor &DebugInfoSection =
573 getOrCreateSectionDescriptor(SectionKind: DebugSectionKind::DebugInfo);
574
575 if (!DebugInfoSection.ListDebugLocPatch.empty()) {
576 SectionDescriptor &OutLocationSection =
577 getOrCreateSectionDescriptor(SectionKind: LocationSectionKind);
578 DWARFUnit &OrigUnit = getOrigUnit();
579
580 uint64_t OffsetAfterUnitLength = emitLocListHeader(OutLocationSection);
581
582 DebugInfoSection.ListDebugLocPatch.forEach(Handler: [&](DebugLocPatch &Patch) {
583 // Get location expressions vector corresponding to the current
584 // attribute from the source DWARF.
585 uint64_t InputDebugLocSectionOffset = DebugInfoSection.getIntVal(
586 PatchOffset: Patch.PatchOffset,
587 Size: DebugInfoSection.getFormParams().getDwarfOffsetByteSize());
588 Expected<DWARFLocationExpressionsVector> OriginalLocations =
589 OrigUnit.findLoclistFromOffset(Offset: InputDebugLocSectionOffset);
590
591 if (!OriginalLocations) {
592 warn(Warning: OriginalLocations.takeError());
593 return;
594 }
595
596 LinkedLocationExpressionsVector LinkedLocationExpressions;
597 for (DWARFLocationExpression &CurExpression : *OriginalLocations) {
598 LinkedLocationExpressionsWithOffsetPatches LinkedExpression;
599
600 if (CurExpression.Range) {
601 // Relocate address range.
602 LinkedExpression.Expression.Range = {
603 CurExpression.Range->LowPC + Patch.AddrAdjustmentValue,
604 CurExpression.Range->HighPC + Patch.AddrAdjustmentValue};
605 }
606
607 DataExtractor Data(CurExpression.Expr, OrigUnit.isLittleEndian());
608
609 DWARFExpression InputExpression(Data, OrigUnit.getAddressByteSize(),
610 OrigUnit.getFormParams().Format);
611 cloneDieAttrExpression(InputExpression,
612 OutputExpression&: LinkedExpression.Expression.Expr,
613 Section&: OutLocationSection, VarAddressAdjustment: Patch.AddrAdjustmentValue,
614 PatchesOffsets&: LinkedExpression.Patches);
615
616 LinkedLocationExpressions.push_back(Elt: {LinkedExpression});
617 }
618
619 // Emit locations list table fragment corresponding to the CurLocAttr.
620 DebugInfoSection.apply(PatchOffset: Patch.PatchOffset, AttrForm: dwarf::DW_FORM_sec_offset,
621 Val: OutLocationSection.OS.tell());
622 emitLocListFragment(LinkedLocationExpression: LinkedLocationExpressions, OutLocationSection);
623 });
624
625 if (OffsetAfterUnitLength > 0) {
626 assert(OffsetAfterUnitLength -
627 OutLocationSection.getFormParams().getDwarfOffsetByteSize() <
628 OffsetAfterUnitLength);
629 OutLocationSection.apply(
630 PatchOffset: OffsetAfterUnitLength -
631 OutLocationSection.getFormParams().getDwarfOffsetByteSize(),
632 AttrForm: dwarf::DW_FORM_sec_offset,
633 Val: OutLocationSection.OS.tell() - OffsetAfterUnitLength);
634 }
635 }
636}
637
638/// Emit debug locations(.debug_loc, .debug_loclists) header.
639uint64_t CompileUnit::emitLocListHeader(SectionDescriptor &OutLocationSection) {
640 if (getOrigUnit().getVersion() < 5)
641 return 0;
642
643 // unit_length.
644 OutLocationSection.emitUnitLength(Length: 0xBADDEF);
645 uint64_t OffsetAfterUnitLength = OutLocationSection.OS.tell();
646
647 // Version.
648 OutLocationSection.emitIntVal(Val: 5, Size: 2);
649
650 // Address size.
651 OutLocationSection.emitIntVal(Val: OutLocationSection.getFormParams().AddrSize, Size: 1);
652
653 // Seg_size
654 OutLocationSection.emitIntVal(Val: 0, Size: 1);
655
656 // Offset entry count
657 OutLocationSection.emitIntVal(Val: 0, Size: 4);
658
659 return OffsetAfterUnitLength;
660}
661
662/// Emit debug locations(.debug_loc, .debug_loclists) fragment.
663uint64_t CompileUnit::emitLocListFragment(
664 const LinkedLocationExpressionsVector &LinkedLocationExpression,
665 SectionDescriptor &OutLocationSection) {
666 uint64_t OffsetBeforeLocationExpression = 0;
667
668 if (getOrigUnit().getVersion() < 5) {
669 uint64_t BaseAddress = 0;
670 if (std::optional<uint64_t> LowPC = getLowPc())
671 BaseAddress = *LowPC;
672
673 for (const LinkedLocationExpressionsWithOffsetPatches &LocExpression :
674 LinkedLocationExpression) {
675 if (LocExpression.Expression.Range) {
676 OutLocationSection.emitIntVal(
677 Val: LocExpression.Expression.Range->LowPC - BaseAddress,
678 Size: OutLocationSection.getFormParams().AddrSize);
679 OutLocationSection.emitIntVal(
680 Val: LocExpression.Expression.Range->HighPC - BaseAddress,
681 Size: OutLocationSection.getFormParams().AddrSize);
682 }
683
684 OutLocationSection.emitIntVal(Val: LocExpression.Expression.Expr.size(), Size: 2);
685 OffsetBeforeLocationExpression = OutLocationSection.OS.tell();
686 for (uint64_t *OffsetPtr : LocExpression.Patches)
687 *OffsetPtr += OffsetBeforeLocationExpression;
688
689 OutLocationSection.OS
690 << StringRef((const char *)LocExpression.Expression.Expr.data(),
691 LocExpression.Expression.Expr.size());
692 }
693
694 // Emit the terminator entry.
695 OutLocationSection.emitIntVal(Val: 0,
696 Size: OutLocationSection.getFormParams().AddrSize);
697 OutLocationSection.emitIntVal(Val: 0,
698 Size: OutLocationSection.getFormParams().AddrSize);
699 return OffsetBeforeLocationExpression;
700 }
701
702 std::optional<uint64_t> BaseAddress;
703 for (const LinkedLocationExpressionsWithOffsetPatches &LocExpression :
704 LinkedLocationExpression) {
705 if (LocExpression.Expression.Range) {
706 // Check whether base address is set. If it is not set yet
707 // then set current base address and emit base address selection entry.
708 if (!BaseAddress) {
709 BaseAddress = LocExpression.Expression.Range->LowPC;
710
711 // Emit base address.
712 OutLocationSection.emitIntVal(Val: dwarf::DW_LLE_base_addressx, Size: 1);
713 encodeULEB128(Value: DebugAddrIndexMap.getValueIndex(Value: *BaseAddress),
714 OS&: OutLocationSection.OS);
715 }
716
717 // Emit type of entry.
718 OutLocationSection.emitIntVal(Val: dwarf::DW_LLE_offset_pair, Size: 1);
719
720 // Emit start offset relative to base address.
721 encodeULEB128(Value: LocExpression.Expression.Range->LowPC - *BaseAddress,
722 OS&: OutLocationSection.OS);
723
724 // Emit end offset relative to base address.
725 encodeULEB128(Value: LocExpression.Expression.Range->HighPC - *BaseAddress,
726 OS&: OutLocationSection.OS);
727 } else
728 // Emit type of entry.
729 OutLocationSection.emitIntVal(Val: dwarf::DW_LLE_default_location, Size: 1);
730
731 encodeULEB128(Value: LocExpression.Expression.Expr.size(), OS&: OutLocationSection.OS);
732 OffsetBeforeLocationExpression = OutLocationSection.OS.tell();
733 for (uint64_t *OffsetPtr : LocExpression.Patches)
734 *OffsetPtr += OffsetBeforeLocationExpression;
735
736 OutLocationSection.OS << StringRef(
737 (const char *)LocExpression.Expression.Expr.data(),
738 LocExpression.Expression.Expr.size());
739 }
740
741 // Emit the terminator entry.
742 OutLocationSection.emitIntVal(Val: dwarf::DW_LLE_end_of_list, Size: 1);
743 return OffsetBeforeLocationExpression;
744}
745
746Error CompileUnit::emitDebugAddrSection() {
747 if (GlobalData.getOptions().UpdateIndexTablesOnly)
748 return Error::success();
749
750 if (getVersion() < 5)
751 return Error::success();
752
753 // Every cloned unit root has DW_AT_addr_base, so emit the table even when it
754 // is empty.
755 SectionDescriptor &OutAddrSection =
756 getOrCreateSectionDescriptor(SectionKind: DebugSectionKind::DebugAddr);
757
758 // Emit section header.
759
760 // Emit length.
761 OutAddrSection.emitUnitLength(Length: 0xBADDEF);
762 uint64_t OffsetAfterSectionLength = OutAddrSection.OS.tell();
763
764 // Emit version.
765 OutAddrSection.emitIntVal(Val: 5, Size: 2);
766
767 // Emit address size.
768 OutAddrSection.emitIntVal(Val: getFormParams().AddrSize, Size: 1);
769
770 // Emit segment size.
771 OutAddrSection.emitIntVal(Val: 0, Size: 1);
772
773 // Emit addresses.
774 for (uint64_t AddrValue : DebugAddrIndexMap.getValues())
775 OutAddrSection.emitIntVal(Val: AddrValue, Size: getFormParams().AddrSize);
776
777 // Patch section length.
778 OutAddrSection.apply(
779 PatchOffset: OffsetAfterSectionLength -
780 OutAddrSection.getFormParams().getDwarfOffsetByteSize(),
781 AttrForm: dwarf::DW_FORM_sec_offset,
782 Val: OutAddrSection.OS.tell() - OffsetAfterSectionLength);
783
784 return Error::success();
785}
786
787Error CompileUnit::cloneAndEmitRanges() {
788 if (getGlobalData().getOptions().UpdateIndexTablesOnly)
789 return Error::success();
790
791 // Build set of linked address ranges for unit function ranges.
792 AddressRanges LinkedFunctionRanges;
793 for (const AddressRangeValuePair &Range : getFunctionRanges())
794 LinkedFunctionRanges.insert(
795 Range: {Range.Range.start() + Range.Value, Range.Range.end() + Range.Value});
796
797 emitAranges(LinkedFunctionRanges);
798
799 if (getOrigUnit().getVersion() < 5) {
800 cloneAndEmitRangeList(RngSectionKind: DebugSectionKind::DebugRange, LinkedFunctionRanges);
801 return Error::success();
802 }
803
804 cloneAndEmitRangeList(RngSectionKind: DebugSectionKind::DebugRngLists, LinkedFunctionRanges);
805 return Error::success();
806}
807
808void CompileUnit::cloneAndEmitRangeList(DebugSectionKind RngSectionKind,
809 AddressRanges &LinkedFunctionRanges) {
810 SectionDescriptor &DebugInfoSection =
811 getOrCreateSectionDescriptor(SectionKind: DebugSectionKind::DebugInfo);
812 SectionDescriptor &OutRangeSection =
813 getOrCreateSectionDescriptor(SectionKind: RngSectionKind);
814
815 if (!DebugInfoSection.ListDebugRangePatch.empty()) {
816 std::optional<AddressRangeValuePair> CachedRange;
817 uint64_t OffsetAfterUnitLength = emitRangeListHeader(OutRangeSection);
818
819 DebugRangePatch *CompileUnitRangePtr = nullptr;
820 DebugInfoSection.ListDebugRangePatch.forEach(Handler: [&](DebugRangePatch &Patch) {
821 if (Patch.IsCompileUnitRanges) {
822 CompileUnitRangePtr = &Patch;
823 } else {
824 // Get ranges from the source DWARF corresponding to the current
825 // attribute.
826 AddressRanges LinkedRanges;
827 uint64_t InputDebugRangesSectionOffset = DebugInfoSection.getIntVal(
828 PatchOffset: Patch.PatchOffset,
829 Size: DebugInfoSection.getFormParams().getDwarfOffsetByteSize());
830 if (Expected<DWARFAddressRangesVector> InputRanges =
831 getOrigUnit().findRnglistFromOffset(
832 Offset: InputDebugRangesSectionOffset)) {
833 // Apply relocation adjustment.
834 for (const auto &Range : *InputRanges) {
835 if (!CachedRange || !CachedRange->Range.contains(Addr: Range.LowPC))
836 CachedRange =
837 getFunctionRanges().getRangeThatContains(Addr: Range.LowPC);
838
839 // All range entries should lie in the function range.
840 if (!CachedRange) {
841 warn(Warning: "inconsistent range data.");
842 continue;
843 }
844
845 // Store range for emiting.
846 LinkedRanges.insert(Range: {Range.LowPC + CachedRange->Value,
847 Range.HighPC + CachedRange->Value});
848 }
849 } else {
850 llvm::consumeError(Err: InputRanges.takeError());
851 warn(Warning: "invalid range list ignored.");
852 }
853
854 // Emit linked ranges.
855 DebugInfoSection.apply(PatchOffset: Patch.PatchOffset, AttrForm: dwarf::DW_FORM_sec_offset,
856 Val: OutRangeSection.OS.tell());
857 emitRangeListFragment(LinkedRanges, OutRangeSection);
858 }
859 });
860
861 if (CompileUnitRangePtr != nullptr) {
862 // Emit compile unit ranges last to be binary compatible with classic
863 // dsymutil.
864 DebugInfoSection.apply(PatchOffset: CompileUnitRangePtr->PatchOffset,
865 AttrForm: dwarf::DW_FORM_sec_offset,
866 Val: OutRangeSection.OS.tell());
867 emitRangeListFragment(LinkedRanges: LinkedFunctionRanges, OutRangeSection);
868 }
869
870 if (OffsetAfterUnitLength > 0) {
871 assert(OffsetAfterUnitLength -
872 OutRangeSection.getFormParams().getDwarfOffsetByteSize() <
873 OffsetAfterUnitLength);
874 OutRangeSection.apply(
875 PatchOffset: OffsetAfterUnitLength -
876 OutRangeSection.getFormParams().getDwarfOffsetByteSize(),
877 AttrForm: dwarf::DW_FORM_sec_offset,
878 Val: OutRangeSection.OS.tell() - OffsetAfterUnitLength);
879 }
880 }
881}
882
883uint64_t CompileUnit::emitRangeListHeader(SectionDescriptor &OutRangeSection) {
884 if (OutRangeSection.getFormParams().Version < 5)
885 return 0;
886
887 // unit_length.
888 OutRangeSection.emitUnitLength(Length: 0xBADDEF);
889 uint64_t OffsetAfterUnitLength = OutRangeSection.OS.tell();
890
891 // Version.
892 OutRangeSection.emitIntVal(Val: 5, Size: 2);
893
894 // Address size.
895 OutRangeSection.emitIntVal(Val: OutRangeSection.getFormParams().AddrSize, Size: 1);
896
897 // Seg_size
898 OutRangeSection.emitIntVal(Val: 0, Size: 1);
899
900 // Offset entry count
901 OutRangeSection.emitIntVal(Val: 0, Size: 4);
902
903 return OffsetAfterUnitLength;
904}
905
906void CompileUnit::emitRangeListFragment(const AddressRanges &LinkedRanges,
907 SectionDescriptor &OutRangeSection) {
908 if (OutRangeSection.getFormParams().Version < 5) {
909 // Emit ranges.
910 uint64_t BaseAddress = 0;
911 if (std::optional<uint64_t> LowPC = getLowPc())
912 BaseAddress = *LowPC;
913
914 for (const AddressRange &Range : LinkedRanges) {
915 OutRangeSection.emitIntVal(Val: Range.start() - BaseAddress,
916 Size: OutRangeSection.getFormParams().AddrSize);
917 OutRangeSection.emitIntVal(Val: Range.end() - BaseAddress,
918 Size: OutRangeSection.getFormParams().AddrSize);
919 }
920
921 // Add the terminator entry.
922 OutRangeSection.emitIntVal(Val: 0, Size: OutRangeSection.getFormParams().AddrSize);
923 OutRangeSection.emitIntVal(Val: 0, Size: OutRangeSection.getFormParams().AddrSize);
924 return;
925 }
926
927 std::optional<uint64_t> BaseAddress;
928 for (const AddressRange &Range : LinkedRanges) {
929 if (!BaseAddress) {
930 BaseAddress = Range.start();
931
932 // Emit base address.
933 OutRangeSection.emitIntVal(Val: dwarf::DW_RLE_base_addressx, Size: 1);
934 encodeULEB128(Value: getDebugAddrIndex(Addr: *BaseAddress), OS&: OutRangeSection.OS);
935 }
936
937 // Emit type of entry.
938 OutRangeSection.emitIntVal(Val: dwarf::DW_RLE_offset_pair, Size: 1);
939
940 // Emit start offset relative to base address.
941 encodeULEB128(Value: Range.start() - *BaseAddress, OS&: OutRangeSection.OS);
942
943 // Emit end offset relative to base address.
944 encodeULEB128(Value: Range.end() - *BaseAddress, OS&: OutRangeSection.OS);
945 }
946
947 // Emit the terminator entry.
948 OutRangeSection.emitIntVal(Val: dwarf::DW_RLE_end_of_list, Size: 1);
949}
950
951void CompileUnit::emitAranges(AddressRanges &LinkedFunctionRanges) {
952 if (LinkedFunctionRanges.empty())
953 return;
954
955 SectionDescriptor &DebugInfoSection =
956 getOrCreateSectionDescriptor(SectionKind: DebugSectionKind::DebugInfo);
957 SectionDescriptor &OutArangesSection =
958 getOrCreateSectionDescriptor(SectionKind: DebugSectionKind::DebugARanges);
959
960 // Emit Header.
961 unsigned HeaderSize =
962 sizeof(int32_t) + // Size of contents (w/o this field
963 sizeof(int16_t) + // DWARF ARange version number
964 sizeof(int32_t) + // Offset of CU in the .debug_info section
965 sizeof(int8_t) + // Pointer Size (in bytes)
966 sizeof(int8_t); // Segment Size (in bytes)
967
968 unsigned TupleSize = OutArangesSection.getFormParams().AddrSize * 2;
969 unsigned Padding = offsetToAlignment(Value: HeaderSize, Alignment: Align(TupleSize));
970
971 OutArangesSection.emitOffset(Val: 0xBADDEF); // Aranges length
972 uint64_t OffsetAfterArangesLengthField = OutArangesSection.OS.tell();
973
974 OutArangesSection.emitIntVal(Val: dwarf::DW_ARANGES_VERSION, Size: 2); // Version number
975 OutArangesSection.notePatch(
976 Patch: DebugOffsetPatch{OutArangesSection.OS.tell(), &DebugInfoSection});
977 OutArangesSection.emitOffset(Val: 0xBADDEF); // Corresponding unit's offset
978 OutArangesSection.emitIntVal(Val: OutArangesSection.getFormParams().AddrSize,
979 Size: 1); // Address size
980 OutArangesSection.emitIntVal(Val: 0, Size: 1); // Segment size
981
982 for (size_t Idx = 0; Idx < Padding; Idx++)
983 OutArangesSection.emitIntVal(Val: 0, Size: 1); // Padding
984
985 // Emit linked ranges.
986 for (const AddressRange &Range : LinkedFunctionRanges) {
987 OutArangesSection.emitIntVal(Val: Range.start(),
988 Size: OutArangesSection.getFormParams().AddrSize);
989 OutArangesSection.emitIntVal(Val: Range.end() - Range.start(),
990 Size: OutArangesSection.getFormParams().AddrSize);
991 }
992
993 // Emit terminator.
994 OutArangesSection.emitIntVal(Val: 0, Size: OutArangesSection.getFormParams().AddrSize);
995 OutArangesSection.emitIntVal(Val: 0, Size: OutArangesSection.getFormParams().AddrSize);
996
997 uint64_t OffsetAfterArangesEnd = OutArangesSection.OS.tell();
998
999 // Update Aranges lentgh.
1000 OutArangesSection.apply(
1001 PatchOffset: OffsetAfterArangesLengthField -
1002 OutArangesSection.getFormParams().getDwarfOffsetByteSize(),
1003 AttrForm: dwarf::DW_FORM_sec_offset,
1004 Val: OffsetAfterArangesEnd - OffsetAfterArangesLengthField);
1005}
1006
1007Error CompileUnit::cloneAndEmitDebugMacro() {
1008 if (getOutUnitDIE() == nullptr)
1009 return Error::success();
1010
1011 DWARFUnit &OrigUnit = getOrigUnit();
1012 DWARFDie OrigUnitDie = OrigUnit.getUnitDIE();
1013
1014 // Check for .debug_macro table.
1015 if (std::optional<uint64_t> MacroAttr =
1016 dwarf::toSectionOffset(V: OrigUnitDie.find(Attr: dwarf::DW_AT_macros))) {
1017 if (const DWARFDebugMacro *Table =
1018 getContainingFile().Dwarf->getDebugMacro()) {
1019 emitMacroTableImpl(MacroTable: Table, OffsetToMacroTable: *MacroAttr, hasDWARFv5Header: true);
1020 }
1021 }
1022
1023 // Check for .debug_macinfo table.
1024 if (std::optional<uint64_t> MacroAttr =
1025 dwarf::toSectionOffset(V: OrigUnitDie.find(Attr: dwarf::DW_AT_macro_info))) {
1026 if (const DWARFDebugMacro *Table =
1027 getContainingFile().Dwarf->getDebugMacinfo()) {
1028 emitMacroTableImpl(MacroTable: Table, OffsetToMacroTable: *MacroAttr, hasDWARFv5Header: false);
1029 }
1030 }
1031
1032 return Error::success();
1033}
1034
1035void CompileUnit::emitMacroTableImpl(const DWARFDebugMacro *MacroTable,
1036 uint64_t OffsetToMacroTable,
1037 bool hasDWARFv5Header) {
1038 SectionDescriptor &OutSection =
1039 hasDWARFv5Header
1040 ? getOrCreateSectionDescriptor(SectionKind: DebugSectionKind::DebugMacro)
1041 : getOrCreateSectionDescriptor(SectionKind: DebugSectionKind::DebugMacinfo);
1042
1043 bool DefAttributeIsReported = false;
1044 bool UndefAttributeIsReported = false;
1045 bool ImportAttributeIsReported = false;
1046
1047 for (const DWARFDebugMacro::MacroList &List : MacroTable->MacroLists) {
1048 if (OffsetToMacroTable == List.Offset) {
1049 // Write DWARFv5 header.
1050 if (hasDWARFv5Header) {
1051 // Write header version.
1052 OutSection.emitIntVal(Val: List.Header.Version, Size: sizeof(List.Header.Version));
1053
1054 uint8_t Flags = List.Header.Flags;
1055
1056 // Check for OPCODE_OPERANDS_TABLE.
1057 if (Flags &
1058 DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE) {
1059 Flags &=
1060 ~DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE;
1061 warn(Warning: "opcode_operands_table is not supported yet.");
1062 }
1063
1064 // Check for DEBUG_LINE_OFFSET.
1065 std::optional<uint64_t> StmtListOffset;
1066 if (Flags & DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET) {
1067 // Get offset to the line table from the cloned compile unit.
1068 for (auto &V : getOutUnitDIE()->values()) {
1069 if (V.getAttribute() == dwarf::DW_AT_stmt_list) {
1070 StmtListOffset = V.getDIEInteger().getValue();
1071 break;
1072 }
1073 }
1074
1075 if (!StmtListOffset) {
1076 Flags &= ~DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET;
1077 warn(Warning: "couldn`t find line table for macro table.");
1078 }
1079 }
1080
1081 // Write flags.
1082 OutSection.emitIntVal(Val: Flags, Size: sizeof(Flags));
1083
1084 // Write offset to line table.
1085 if (StmtListOffset) {
1086 OutSection.notePatch(Patch: DebugOffsetPatch{
1087 OutSection.OS.tell(),
1088 &getOrCreateSectionDescriptor(SectionKind: DebugSectionKind::DebugLine)});
1089 // TODO: check that List.Header.getOffsetByteSize() and
1090 // DebugOffsetPatch agree on size.
1091 OutSection.emitIntVal(Val: 0xBADDEF, Size: List.Header.getOffsetByteSize());
1092 }
1093 }
1094
1095 // Write macro entries.
1096 for (const DWARFDebugMacro::Entry &MacroEntry : List.Macros) {
1097 if (MacroEntry.Type == 0) {
1098 encodeULEB128(Value: MacroEntry.Type, OS&: OutSection.OS);
1099 continue;
1100 }
1101
1102 uint8_t MacroType = MacroEntry.Type;
1103 switch (MacroType) {
1104 default: {
1105 bool HasVendorSpecificExtension =
1106 (!hasDWARFv5Header &&
1107 MacroType == dwarf::DW_MACINFO_vendor_ext) ||
1108 (hasDWARFv5Header && (MacroType >= dwarf::DW_MACRO_lo_user &&
1109 MacroType <= dwarf::DW_MACRO_hi_user));
1110
1111 if (HasVendorSpecificExtension) {
1112 // Write macinfo type.
1113 OutSection.emitIntVal(Val: MacroType, Size: 1);
1114
1115 // Write vendor extension constant.
1116 encodeULEB128(Value: MacroEntry.ExtConstant, OS&: OutSection.OS);
1117
1118 // Write vendor extension string.
1119 OutSection.emitString(StringForm: dwarf::DW_FORM_string, StringVal: MacroEntry.ExtStr);
1120 } else
1121 warn(Warning: "unknown macro type. skip.");
1122 } break;
1123 // debug_macro and debug_macinfo share some common encodings.
1124 // DW_MACRO_define == DW_MACINFO_define
1125 // DW_MACRO_undef == DW_MACINFO_undef
1126 // DW_MACRO_start_file == DW_MACINFO_start_file
1127 // DW_MACRO_end_file == DW_MACINFO_end_file
1128 // For readibility/uniformity we are using DW_MACRO_*.
1129 case dwarf::DW_MACRO_define:
1130 case dwarf::DW_MACRO_undef: {
1131 // Write macinfo type.
1132 OutSection.emitIntVal(Val: MacroType, Size: 1);
1133
1134 // Write source line.
1135 encodeULEB128(Value: MacroEntry.Line, OS&: OutSection.OS);
1136
1137 // Write macro string.
1138 OutSection.emitString(StringForm: dwarf::DW_FORM_string, StringVal: MacroEntry.MacroStr);
1139 } break;
1140 case dwarf::DW_MACRO_define_strp:
1141 case dwarf::DW_MACRO_undef_strp:
1142 case dwarf::DW_MACRO_define_strx:
1143 case dwarf::DW_MACRO_undef_strx: {
1144 // DW_MACRO_*_strx forms are not supported currently.
1145 // Convert to *_strp.
1146 switch (MacroType) {
1147 case dwarf::DW_MACRO_define_strx: {
1148 MacroType = dwarf::DW_MACRO_define_strp;
1149 if (!DefAttributeIsReported) {
1150 warn(Warning: "DW_MACRO_define_strx unsupported yet. Convert to "
1151 "DW_MACRO_define_strp.");
1152 DefAttributeIsReported = true;
1153 }
1154 } break;
1155 case dwarf::DW_MACRO_undef_strx: {
1156 MacroType = dwarf::DW_MACRO_undef_strp;
1157 if (!UndefAttributeIsReported) {
1158 warn(Warning: "DW_MACRO_undef_strx unsupported yet. Convert to "
1159 "DW_MACRO_undef_strp.");
1160 UndefAttributeIsReported = true;
1161 }
1162 } break;
1163 default:
1164 // Nothing to do.
1165 break;
1166 }
1167
1168 // Write macinfo type.
1169 OutSection.emitIntVal(Val: MacroType, Size: 1);
1170
1171 // Write source line.
1172 encodeULEB128(Value: MacroEntry.Line, OS&: OutSection.OS);
1173
1174 // Write macro string.
1175 OutSection.emitString(StringForm: dwarf::DW_FORM_strp, StringVal: MacroEntry.MacroStr);
1176 break;
1177 }
1178 case dwarf::DW_MACRO_start_file: {
1179 // Write macinfo type.
1180 OutSection.emitIntVal(Val: MacroType, Size: 1);
1181 // Write source line.
1182 encodeULEB128(Value: MacroEntry.Line, OS&: OutSection.OS);
1183 // Write source file id.
1184 encodeULEB128(Value: MacroEntry.File, OS&: OutSection.OS);
1185 } break;
1186 case dwarf::DW_MACRO_end_file: {
1187 // Write macinfo type.
1188 OutSection.emitIntVal(Val: MacroType, Size: 1);
1189 } break;
1190 case dwarf::DW_MACRO_import:
1191 case dwarf::DW_MACRO_import_sup: {
1192 if (!ImportAttributeIsReported) {
1193 warn(Warning: "DW_MACRO_import and DW_MACRO_import_sup are unsupported "
1194 "yet. remove.");
1195 ImportAttributeIsReported = true;
1196 }
1197 } break;
1198 }
1199 }
1200
1201 return;
1202 }
1203 }
1204}
1205
1206void CompileUnit::cloneDieAttrExpression(
1207 const DWARFExpression &InputExpression,
1208 SmallVectorImpl<uint8_t> &OutputExpression, SectionDescriptor &Section,
1209 std::optional<int64_t> VarAddressAdjustment,
1210 OffsetsPtrVector &PatchesOffsets) {
1211 using Encoding = DWARFExpression::Operation::Encoding;
1212
1213 DWARFUnit &OrigUnit = getOrigUnit();
1214 uint8_t OrigAddressByteSize = OrigUnit.getAddressByteSize();
1215
1216 uint64_t OpOffset = 0;
1217 for (auto &Op : InputExpression) {
1218 if (Op.isError()) {
1219 // The operation could not be decoded, so neither it nor anything after
1220 // it can be located. Its end offset is the offset it started at, so the
1221 // slice copied below would be empty and the rest of the expression
1222 // would be silently dropped. Preserve the remaining bytes instead.
1223 warn(Warning: "cannot decode a DW_OP, copying the rest of the expression "
1224 "unmodified.");
1225 StringRef Bytes = InputExpression.getData().substr(Start: OpOffset);
1226 OutputExpression.append(in_start: Bytes.begin(), in_end: Bytes.end());
1227 return;
1228 }
1229 auto Desc = Op.getDescription();
1230 // DW_OP_const_type is variable-length and has 3
1231 // operands. Thus far we only support 2.
1232 if ((Desc.Op.size() == 2 && Desc.Op[0] == Encoding::BaseTypeRef) ||
1233 (Desc.Op.size() == 2 && Desc.Op[1] == Encoding::BaseTypeRef &&
1234 Desc.Op[0] != Encoding::Size1))
1235 warn(Warning: "unsupported DW_OP encoding.");
1236
1237 if ((Desc.Op.size() == 1 && Desc.Op[0] == Encoding::BaseTypeRef) ||
1238 (Desc.Op.size() == 2 && Desc.Op[1] == Encoding::BaseTypeRef &&
1239 Desc.Op[0] == Encoding::Size1)) {
1240 // This code assumes that the other non-typeref operand fits into 1 byte.
1241 assert(OpOffset < Op.getEndOffset());
1242 uint32_t ULEBsize = Op.getEndOffset() - OpOffset - 1;
1243 assert(ULEBsize <= 16);
1244
1245 // Copy over the operation.
1246 assert(!Op.getSubCode() && "SubOps not yet supported");
1247 OutputExpression.push_back(Elt: Op.getCode());
1248 uint64_t RefOffset;
1249 if (Desc.Op.size() == 1) {
1250 RefOffset = Op.getRawOperand(Idx: 0);
1251 } else {
1252 OutputExpression.push_back(Elt: Op.getRawOperand(Idx: 0));
1253 RefOffset = Op.getRawOperand(Idx: 1);
1254 }
1255 uint8_t ULEB[16];
1256 uint32_t Offset = 0;
1257 unsigned RealSize = 0;
1258 // Look up the base type. For DW_OP_convert, the operand may be 0 to
1259 // instead indicate the generic type. The same holds for
1260 // DW_OP_reinterpret, which is currently not supported.
1261 if (RefOffset > 0 || Op.getCode() != dwarf::DW_OP_convert) {
1262 RefOffset += OrigUnit.getOffset();
1263 uint32_t RefDieIdx = 0;
1264 if (std::optional<uint32_t> Idx =
1265 OrigUnit.getDIEIndexForOffset(Offset: RefOffset))
1266 RefDieIdx = *Idx;
1267
1268 // Use fixed size for ULEB128 data, since we need to update that size
1269 // later with the proper offsets. Use 5 for DWARF32, 9 for DWARF64.
1270 ULEBsize = getFormParams().getDwarfOffsetByteSize() + 1;
1271
1272 RealSize = encodeULEB128(Value: 0xBADDEF, p: ULEB, PadTo: ULEBsize);
1273
1274 Section.notePatchWithOffsetUpdate(
1275 Patch: DebugULEB128DieRefPatch(OutputExpression.size(), this, this,
1276 RefDieIdx),
1277 PatchesOffsetsList&: PatchesOffsets);
1278 } else
1279 RealSize = encodeULEB128(Value: Offset, p: ULEB, PadTo: ULEBsize);
1280
1281 if (RealSize > ULEBsize) {
1282 // Emit the generic type as a fallback.
1283 RealSize = encodeULEB128(Value: 0, p: ULEB, PadTo: ULEBsize);
1284 warn(Warning: "base type ref doesn't fit.");
1285 }
1286 assert(RealSize == ULEBsize && "padding failed");
1287 ArrayRef<uint8_t> ULEBbytes(ULEB, ULEBsize);
1288 OutputExpression.append(in_start: ULEBbytes.begin(), in_end: ULEBbytes.end());
1289 } else if (!getGlobalData().getOptions().UpdateIndexTablesOnly &&
1290 Op.getCode() == dwarf::DW_OP_addrx) {
1291 if (std::optional<object::SectionedAddress> SA =
1292 OrigUnit.getAddrOffsetSectionItem(Index: Op.getRawOperand(Idx: 0))) {
1293 // DWARFLinker does not use addrx forms since it generates relocated
1294 // addresses. Replace DW_OP_addrx with DW_OP_addr here.
1295 // Argument of DW_OP_addrx should be relocated here as it is not
1296 // processed by applyValidRelocs.
1297 OutputExpression.push_back(Elt: dwarf::DW_OP_addr);
1298 uint64_t LinkedAddress =
1299 SA->Address +
1300 getContainingFile()
1301 .Addresses->getAddrIndexRelocAdjustment(U&: OrigUnit, Op, Verbose: false)
1302 .value_or(u: VarAddressAdjustment.value_or(u: 0));
1303 if (getEndianness() != llvm::endianness::native)
1304 sys::swapByteOrder(Value&: LinkedAddress);
1305 ArrayRef<uint8_t> AddressBytes(
1306 reinterpret_cast<const uint8_t *>(&LinkedAddress),
1307 OrigAddressByteSize);
1308 OutputExpression.append(in_start: AddressBytes.begin(), in_end: AddressBytes.end());
1309 } else
1310 warn(Warning: "cann't read DW_OP_addrx operand.");
1311 } else if (!getGlobalData().getOptions().UpdateIndexTablesOnly &&
1312 Op.getCode() == dwarf::DW_OP_constx) {
1313 if (std::optional<object::SectionedAddress> SA =
1314 OrigUnit.getAddrOffsetSectionItem(Index: Op.getRawOperand(Idx: 0))) {
1315 // DWARFLinker does not use constx forms since it generates relocated
1316 // addresses. Replace DW_OP_constx with DW_OP_const[*]u here.
1317 // Argument of DW_OP_constx should be relocated here as it is not
1318 // processed by applyValidRelocs.
1319 std::optional<uint8_t> OutOperandKind;
1320 switch (OrigAddressByteSize) {
1321 case 2:
1322 OutOperandKind = dwarf::DW_OP_const2u;
1323 break;
1324 case 4:
1325 OutOperandKind = dwarf::DW_OP_const4u;
1326 break;
1327 case 8:
1328 OutOperandKind = dwarf::DW_OP_const8u;
1329 break;
1330 default:
1331 warn(
1332 Warning: formatv(Fmt: ("unsupported address size: {0}."), Vals&: OrigAddressByteSize));
1333 break;
1334 }
1335
1336 if (OutOperandKind) {
1337 OutputExpression.push_back(Elt: *OutOperandKind);
1338 uint64_t LinkedAddress =
1339 SA->Address +
1340 getContainingFile()
1341 .Addresses->getAddrIndexRelocAdjustment(U&: OrigUnit, Op, Verbose: false)
1342 .value_or(u: VarAddressAdjustment.value_or(u: 0));
1343 if (getEndianness() != llvm::endianness::native)
1344 sys::swapByteOrder(Value&: LinkedAddress);
1345 ArrayRef<uint8_t> AddressBytes(
1346 reinterpret_cast<const uint8_t *>(&LinkedAddress),
1347 OrigAddressByteSize);
1348 OutputExpression.append(in_start: AddressBytes.begin(), in_end: AddressBytes.end());
1349 }
1350 } else
1351 warn(Warning: "cann't read DW_OP_constx operand.");
1352 } else {
1353 // Copy over everything else unmodified.
1354 StringRef Bytes =
1355 InputExpression.getData().slice(Start: OpOffset, End: Op.getEndOffset());
1356 OutputExpression.append(in_start: Bytes.begin(), in_end: Bytes.end());
1357 }
1358 OpOffset = Op.getEndOffset();
1359 }
1360}
1361
1362Error CompileUnit::cloneAndEmit(
1363 std::optional<std::reference_wrapper<const Triple>> TargetTriple,
1364 TypeUnit *ArtificialTypeUnit) {
1365 BumpPtrAllocator Allocator;
1366
1367 DWARFDie OrigUnitDIE = getOrigUnit().getUnitDIE();
1368 if (!OrigUnitDIE.isValid())
1369 return Error::success();
1370
1371 TypeEntry *RootEntry = nullptr;
1372 if (ArtificialTypeUnit)
1373 RootEntry = ArtificialTypeUnit->getTypePool().getRoot();
1374
1375 // Clone input DIE entry recursively.
1376 std::pair<DIE *, TypeEntry *> OutCUDie = cloneDIE(
1377 InputDieEntry: OrigUnitDIE.getDebugInfoEntry(), ClonedParentTypeDIE: RootEntry, OutOffset: getDebugInfoHeaderSize(),
1378 FuncAddressAdjustment: std::nullopt, VarAddressAdjustment: std::nullopt, Allocator, ArtificialTypeUnit);
1379 setOutUnitDIE(OutCUDie.first);
1380
1381 if (!TargetTriple.has_value() || (OutCUDie.first == nullptr))
1382 return Error::success();
1383
1384 if (Error Err = cloneAndEmitLineTable(TargetTriple: (*TargetTriple).get()))
1385 return Err;
1386
1387 if (Error Err = cloneAndEmitDebugMacro())
1388 return Err;
1389
1390 getOrCreateSectionDescriptor(SectionKind: DebugSectionKind::DebugInfo);
1391 if (Error Err = emitDebugInfo(TargetTriple: (*TargetTriple).get()))
1392 return Err;
1393
1394 // ASSUMPTION: .debug_info section should already be emitted at this point.
1395 // cloneAndEmitRanges & cloneAndEmitDebugLocations use .debug_info section
1396 // data.
1397
1398 if (Error Err = cloneAndEmitRanges())
1399 return Err;
1400
1401 if (Error Err = cloneAndEmitDebugLocations())
1402 return Err;
1403
1404 if (Error Err = emitDebugAddrSection())
1405 return Err;
1406
1407 // Generate Pub accelerator tables.
1408 if (llvm::is_contained(Range: GlobalData.getOptions().AccelTables,
1409 Element: DWARFLinker::AccelTableKind::Pub))
1410 emitPubAccelerators();
1411
1412 if (Error Err = emitDebugStringOffsetSection())
1413 return Err;
1414
1415 return emitAbbreviations();
1416}
1417
1418std::pair<DIE *, TypeEntry *> CompileUnit::cloneDIE(
1419 const DWARFDebugInfoEntry *InputDieEntry, TypeEntry *ClonedParentTypeDIE,
1420 uint64_t OutOffset, std::optional<int64_t> FuncAddressAdjustment,
1421 std::optional<int64_t> VarAddressAdjustment, BumpPtrAllocator &Allocator,
1422 TypeUnit *ArtificialTypeUnit, uint32_t SiblingOrdinal) {
1423 uint32_t InputDieIdx = getDIEIndex(Die: InputDieEntry);
1424 CompileUnit::DIEInfo &Info = getDIEInfo(Idx: InputDieIdx);
1425
1426 bool NeedToClonePlainDIE = Info.needToKeepInPlainDwarf();
1427 bool NeedToCloneTypeDIE =
1428 (InputDieEntry->getTag() != dwarf::DW_TAG_compile_unit) &&
1429 Info.needToPlaceInTypeTable();
1430 std::pair<DIE *, TypeEntry *> ClonedDIE;
1431
1432 DIEGenerator PlainDIEGenerator(Allocator, *this);
1433
1434 if (NeedToClonePlainDIE)
1435 // Create a cloned DIE which would be placed into the cloned version
1436 // of input compile unit.
1437 ClonedDIE.first = createPlainDIEandCloneAttributes(
1438 InputDieEntry, PlainDIEGenerator, OutOffset, FuncAddressAdjustment,
1439 VarAddressAdjustment);
1440 if (NeedToCloneTypeDIE) {
1441 // Create a cloned DIE which would be placed into the artificial type
1442 // unit.
1443 assert(ArtificialTypeUnit != nullptr);
1444 DIEGenerator TypeDIEGenerator(
1445 ArtificialTypeUnit->getTypePool().getThreadLocalAllocator(), *this);
1446
1447 ClonedDIE.second = createTypeDIEandCloneAttributes(
1448 InputDieEntry, TypeDIEGenerator, ClonedParentTypeDIE,
1449 ArtificialTypeUnit, SiblingOrdinal);
1450 }
1451 TypeEntry *TypeParentForChild =
1452 ClonedDIE.second ? ClonedDIE.second : ClonedParentTypeDIE;
1453
1454 bool HasPlainChildrenToClone =
1455 (ClonedDIE.first && Info.getKeepPlainChildren());
1456
1457 bool HasTypeChildrenToClone =
1458 ((ClonedDIE.second ||
1459 InputDieEntry->getTag() == dwarf::DW_TAG_compile_unit) &&
1460 Info.getKeepTypeChildren());
1461
1462 // Recursively clone children.
1463 if (HasPlainChildrenToClone || HasTypeChildrenToClone) {
1464 uint32_t ChildOrdinal = 0;
1465 for (const DWARFDebugInfoEntry *CurChild =
1466 getFirstChildEntry(Die: InputDieEntry);
1467 CurChild && CurChild->getAbbreviationDeclarationPtr();
1468 CurChild = getSiblingEntry(Die: CurChild), ++ChildOrdinal) {
1469 std::pair<DIE *, TypeEntry *> ClonedChild = cloneDIE(
1470 InputDieEntry: CurChild, ClonedParentTypeDIE: TypeParentForChild, OutOffset, FuncAddressAdjustment,
1471 VarAddressAdjustment, Allocator, ArtificialTypeUnit, SiblingOrdinal: ChildOrdinal);
1472
1473 if (ClonedChild.first) {
1474 OutOffset =
1475 ClonedChild.first->getOffset() + ClonedChild.first->getSize();
1476 PlainDIEGenerator.addChild(Child: ClonedChild.first);
1477 }
1478 }
1479 assert(ClonedDIE.first == nullptr ||
1480 HasPlainChildrenToClone == ClonedDIE.first->hasChildren());
1481
1482 // Account for the end of children marker.
1483 if (HasPlainChildrenToClone)
1484 OutOffset += sizeof(int8_t);
1485 }
1486
1487 // Update our size.
1488 if (ClonedDIE.first != nullptr)
1489 ClonedDIE.first->setSize(OutOffset - ClonedDIE.first->getOffset());
1490
1491 return ClonedDIE;
1492}
1493
1494DIE *CompileUnit::createPlainDIEandCloneAttributes(
1495 const DWARFDebugInfoEntry *InputDieEntry, DIEGenerator &PlainDIEGenerator,
1496 uint64_t &OutOffset, std::optional<int64_t> &FuncAddressAdjustment,
1497 std::optional<int64_t> &VarAddressAdjustment) {
1498 uint32_t InputDieIdx = getDIEIndex(Die: InputDieEntry);
1499 CompileUnit::DIEInfo &Info = getDIEInfo(Idx: InputDieIdx);
1500 DIE *ClonedDIE = nullptr;
1501 bool HasLocationExpressionAddress = false;
1502 if (InputDieEntry->getTag() == dwarf::DW_TAG_subprogram) {
1503 // Get relocation adjustment value for the current function.
1504 FuncAddressAdjustment =
1505 getContainingFile().Addresses->getSubprogramRelocAdjustment(
1506 DIE: getDIE(Die: InputDieEntry), Verbose: false);
1507 } else if (InputDieEntry->getTag() == dwarf::DW_TAG_label) {
1508 // Get relocation adjustment value for the current label.
1509 std::optional<uint64_t> lowPC =
1510 dwarf::toAddress(V: find(Die: InputDieEntry, Attrs: dwarf::DW_AT_low_pc));
1511 if (lowPC) {
1512 LabelMapTy::iterator It = Labels.find(Val: *lowPC);
1513 if (It != Labels.end())
1514 FuncAddressAdjustment = It->second;
1515 }
1516 } else if (InputDieEntry->getTag() == dwarf::DW_TAG_variable) {
1517 // Get relocation adjustment value for the current variable.
1518 std::pair<bool, std::optional<int64_t>> LocExprAddrAndRelocAdjustment =
1519 getContainingFile().Addresses->getVariableRelocAdjustment(
1520 DIE: getDIE(Die: InputDieEntry), Verbose: false);
1521
1522 HasLocationExpressionAddress = LocExprAddrAndRelocAdjustment.first;
1523 if (LocExprAddrAndRelocAdjustment.first &&
1524 LocExprAddrAndRelocAdjustment.second)
1525 VarAddressAdjustment = *LocExprAddrAndRelocAdjustment.second;
1526 }
1527
1528 ClonedDIE = PlainDIEGenerator.createDIE(DieTag: InputDieEntry->getTag(), OutOffset);
1529
1530 // Offset to the DIE would be used after output DIE tree is deleted.
1531 // Thus we need to remember DIE offset separately.
1532 rememberDieOutOffset(Idx: InputDieIdx, Offset: OutOffset);
1533
1534 // Clone Attributes.
1535 DIEAttributeCloner AttributesCloner(ClonedDIE, *this, this, InputDieEntry,
1536 PlainDIEGenerator, FuncAddressAdjustment,
1537 VarAddressAdjustment,
1538 HasLocationExpressionAddress);
1539 AttributesCloner.clone();
1540
1541 // Remember accelerator info.
1542 AcceleratorRecordsSaver AccelRecordsSaver(getGlobalData(), *this, this);
1543 AccelRecordsSaver.save(InputDieEntry, OutDIE: ClonedDIE, AttrInfo&: AttributesCloner.AttrInfo,
1544 TypeEntry: nullptr);
1545
1546 OutOffset =
1547 AttributesCloner.finalizeAbbreviations(HasChildrenToClone: Info.getKeepPlainChildren());
1548
1549 return ClonedDIE;
1550}
1551
1552/// Allocates output DIE for the specified \p TypeDescriptor.
1553DIE *CompileUnit::allocateTypeDie(TypeEntryBody *TypeDescriptor,
1554 DIEGenerator &TypeDIEGenerator,
1555 dwarf::Tag DieTag, bool IsDeclaration,
1556 bool IsParentDeclaration) {
1557 uint64_t Priority = getPriority();
1558
1559 // Lock-free pre-checks: skip the lock (and downstream cloning) when this CU
1560 // has no chance of winning the type slot.
1561 if (!IsDeclaration && !IsParentDeclaration) {
1562 // DiePriority only ever decreases, so a relaxed read that is <= our
1563 // priority means we definitely cannot win.
1564 if (Priority >= TypeDescriptor->DiePriority.load(m: std::memory_order_relaxed))
1565 return nullptr;
1566 } else {
1567 // Once a definition exists the declaration slot is dead.
1568 if (TypeDescriptor->Die.load(m: std::memory_order_relaxed))
1569 return nullptr;
1570 }
1571
1572 while (TypeDescriptor->Lock.test_and_set(m: std::memory_order_acquire))
1573 ; // spin
1574
1575 DIE *Result = nullptr;
1576
1577 if (!IsDeclaration && !IsParentDeclaration) {
1578 // Definition: lowest priority wins.
1579 if (Priority <
1580 TypeDescriptor->DiePriority.load(m: std::memory_order_relaxed)) {
1581 TypeDescriptor->DiePriority.store(i: Priority, m: std::memory_order_relaxed);
1582 Result = TypeDIEGenerator.createDIE(DieTag, OutOffset: 0);
1583 TypeDescriptor->Die.store(p: Result, m: std::memory_order_relaxed);
1584 }
1585 } else if (!TypeDescriptor->Die.load(m: std::memory_order_relaxed)) {
1586 // Declaration (no definition exists yet).
1587 // Prefer declarations whose parent is a definition (better context);
1588 // break ties by CU priority (lower wins).
1589 bool WorseParent =
1590 IsParentDeclaration && !TypeDescriptor->DeclarationParentIsDeclaration;
1591 bool BetterParent =
1592 !IsParentDeclaration && TypeDescriptor->DeclarationParentIsDeclaration;
1593 if (!WorseParent &&
1594 (BetterParent || Priority < TypeDescriptor->DeclarationDiePriority)) {
1595 TypeDescriptor->DeclarationDiePriority = Priority;
1596 TypeDescriptor->DeclarationParentIsDeclaration = IsParentDeclaration;
1597 Result = TypeDIEGenerator.createDIE(DieTag, OutOffset: 0);
1598 TypeDescriptor->DeclarationDie.store(p: Result, m: std::memory_order_relaxed);
1599 }
1600 }
1601
1602 TypeDescriptor->Lock.clear(m: std::memory_order_release);
1603 return Result;
1604}
1605
1606TypeEntry *CompileUnit::createTypeDIEandCloneAttributes(
1607 const DWARFDebugInfoEntry *InputDieEntry, DIEGenerator &TypeDIEGenerator,
1608 TypeEntry *ClonedParentTypeDIE, TypeUnit *ArtificialTypeUnit,
1609 uint32_t SiblingOrdinal) {
1610 assert(ArtificialTypeUnit != nullptr);
1611 uint32_t InputDieIdx = getDIEIndex(Die: InputDieEntry);
1612
1613 TypeEntry *Entry = getDieTypeEntry(Idx: InputDieIdx);
1614 assert(Entry != nullptr);
1615 assert(ClonedParentTypeDIE != nullptr);
1616 TypeEntryBody *EntryBody =
1617 ArtificialTypeUnit->getTypePool().getOrCreateTypeEntryBody(
1618 Entry, ParentEntry: ClonedParentTypeDIE);
1619 assert(EntryBody);
1620
1621 // Min-merge this child's ordinal in its parent's child list so children of
1622 // record-like types (class/struct/union/interface) sort in source order.
1623 // Min across CUs because Clang appends template instantiations lazily, so
1624 // positions vary between CUs.
1625 if (std::optional<uint32_t> ParentIdx = InputDieEntry->getParentIdx()) {
1626 dwarf::Tag ParentTag = getDebugInfoEntry(Index: *ParentIdx)->getTag();
1627 if (ParentTag == dwarf::DW_TAG_structure_type ||
1628 ParentTag == dwarf::DW_TAG_class_type ||
1629 ParentTag == dwarf::DW_TAG_union_type ||
1630 ParentTag == dwarf::DW_TAG_interface_type) {
1631 uint32_t Prev = EntryBody->SortKey.load(m: std::memory_order_relaxed);
1632 while (SiblingOrdinal < Prev &&
1633 !EntryBody->SortKey.compare_exchange_weak(
1634 i1&: Prev, i2: SiblingOrdinal, m1: std::memory_order_relaxed,
1635 m2: std::memory_order_relaxed))
1636 ;
1637 }
1638 }
1639
1640 bool IsDeclaration =
1641 dwarf::toUnsigned(V: find(Die: InputDieEntry, Attrs: dwarf::DW_AT_declaration), Default: 0);
1642
1643 bool ParentIsDeclaration = false;
1644 if (std::optional<uint32_t> ParentIdx = InputDieEntry->getParentIdx())
1645 ParentIsDeclaration =
1646 dwarf::toUnsigned(V: find(DieIdx: *ParentIdx, Attrs: dwarf::DW_AT_declaration), Default: 0);
1647
1648 DIE *OutDIE =
1649 allocateTypeDie(TypeDescriptor: EntryBody, TypeDIEGenerator, DieTag: InputDieEntry->getTag(),
1650 IsDeclaration, IsParentDeclaration: ParentIsDeclaration);
1651
1652 if (OutDIE != nullptr) {
1653 assert(ArtificialTypeUnit != nullptr);
1654 ArtificialTypeUnit->getSectionDescriptor(SectionKind: DebugSectionKind::DebugInfo);
1655
1656 DIEAttributeCloner AttributesCloner(OutDIE, *this, ArtificialTypeUnit,
1657 InputDieEntry, TypeDIEGenerator,
1658 std::nullopt, std::nullopt, false);
1659 AttributesCloner.clone();
1660
1661 // Remember accelerator info.
1662 AcceleratorRecordsSaver AccelRecordsSaver(getGlobalData(), *this,
1663 ArtificialTypeUnit);
1664 AccelRecordsSaver.save(InputDieEntry, OutDIE, AttrInfo&: AttributesCloner.AttrInfo,
1665 TypeEntry: Entry);
1666
1667 // if AttributesCloner.getOutOffset() == 0 then we need to add
1668 // 1 to avoid assertion for zero size. We will subtract it back later.
1669 OutDIE->setSize(AttributesCloner.getOutOffset() + 1);
1670 }
1671
1672 return Entry;
1673}
1674
1675Error CompileUnit::cloneAndEmitLineTable(const Triple &TargetTriple) {
1676 const DWARFDebugLine::LineTable *InputLineTable =
1677 getContainingFile().Dwarf->getLineTableForUnit(U: &getOrigUnit());
1678 if (InputLineTable == nullptr) {
1679 if (getOrigUnit().getUnitDIE().find(Attr: dwarf::DW_AT_stmt_list))
1680 warn(Warning: "cann't load line table.");
1681 return Error::success();
1682 }
1683
1684 DWARFDebugLine::LineTable OutLineTable;
1685
1686 // Set Line Table header.
1687 OutLineTable.Prologue = InputLineTable->Prologue;
1688 OutLineTable.Prologue.FormParams.AddrSize = getFormParams().AddrSize;
1689
1690 // Set Line Table Rows.
1691 if (getGlobalData().getOptions().UpdateIndexTablesOnly) {
1692 OutLineTable.Rows = InputLineTable->Rows;
1693 // If all the line table contains is a DW_LNE_end_sequence, clear the line
1694 // table rows, it will be inserted again in the DWARFStreamer.
1695 if (OutLineTable.Rows.size() == 1 && OutLineTable.Rows[0].EndSequence)
1696 OutLineTable.Rows.clear();
1697
1698 OutLineTable.Sequences = InputLineTable->Sequences;
1699 return emitDebugLine(TargetTriple, OutLineTable);
1700 }
1701
1702 SmallVector<uint64_t> OrigRowIndices;
1703 filterLineTableRows(InputLineTable: *InputLineTable, NewRows&: OutLineTable.Rows, NewRowIndices&: OrigRowIndices);
1704
1705 if (StmtSeqListAttributes.empty())
1706 return emitDebugLine(TargetTriple, OutLineTable);
1707
1708 // When DW_AT_LLVM_stmt_sequence attributes on this CU need their values
1709 // rewritten to point at the correct output sequence, have the emitter
1710 // record, for every row that originated from an input row, the byte
1711 // offset of the DW_LNE_set_address that opens the sequence containing
1712 // that row. Keying the map on the input row index (rather than on an
1713 // output address) avoids collisions when two input sequences would
1714 // relocate to the same output address — e.g. ICF folding two functions
1715 // from the same CU to a single output range.
1716 //
1717 // The patching below MUST run before emitDebugInfo() serializes the
1718 // DIE bytes and before OutputSections::applyPatches() runs for this
1719 // unit's .debug_info — it writes a local offset into the DIEValue that
1720 // the serializer then emits, and a DebugOffsetPatch (registered at DIE
1721 // cloning time) later adds the CU's .debug_line start offset to reach
1722 // the final absolute value.
1723 DenseMap<uint64_t, uint64_t> RowIndexToSeqStartOffset;
1724 if (Error Err = emitDebugLine(TargetTriple, OutLineTable, OrigRowIndices,
1725 RowIndexToSeqStartOffset: &RowIndexToSeqStartOffset))
1726 return Err;
1727
1728 DenseMap<uint64_t, uint64_t> SeqOffsetToFirstRowIndex =
1729 buildStmtSeqOffsetToFirstRowIndex(InputLineTable: *InputLineTable);
1730 patchStmtSeqAttributes(SeqOffsetToFirstRowIndex, RowIndexToSeqStartOffset);
1731 return Error::success();
1732}
1733
1734void CompileUnit::filterLineTableRows(
1735 const DWARFDebugLine::LineTable &InputLineTable,
1736 std::vector<DWARFDebugLine::Row> &NewRows,
1737 SmallVectorImpl<uint64_t> &NewRowIndices) {
1738 NewRows.reserve(n: InputLineTable.Rows.size());
1739 NewRowIndices.reserve(N: InputLineTable.Rows.size());
1740
1741 // Current sequence of rows being extracted, before being inserted
1742 // in NewRows. Kept in lockstep with SeqIndices, which stores the
1743 // originating input row index (or InvalidRowIndex for manufactured
1744 // end-of-range rows).
1745 std::vector<DWARFDebugLine::Row> Seq;
1746 SmallVector<uint64_t> SeqIndices;
1747 constexpr uint64_t InvalidRowIndex = std::numeric_limits<uint64_t>::max();
1748
1749 const auto &FunctionRanges = getFunctionRanges();
1750 std::optional<AddressRangeValuePair> CurrRange;
1751
1752 // FIXME: This logic is meant to generate exactly the same output as
1753 // Darwin's classic dsymutil. There is a nicer way to implement this
1754 // by simply putting all the relocated line info in NewRows and simply
1755 // sorting NewRows before passing it to emitLineTableForUnit. This
1756 // should be correct as sequences for a function should stay
1757 // together in the sorted output. There are a few corner cases that
1758 // look suspicious though, and that required to implement the logic
1759 // this way. Revisit that once initial validation is finished.
1760
1761 // Iterate over the object file line info and extract the sequences
1762 // that correspond to linked functions.
1763 for (auto [InputRowIdx, InputRow] : llvm::enumerate(First: InputLineTable.Rows)) {
1764 DWARFDebugLine::Row Row = InputRow;
1765 // Check whether we stepped out of the range. The range is
1766 // half-open, but consider accept the end address of the range if
1767 // it is marked as end_sequence in the input (because in that
1768 // case, the relocation offset is accurate and that entry won't
1769 // serve as the start of another function).
1770 if (!CurrRange || !CurrRange->Range.contains(Addr: Row.Address.Address)) {
1771 // We just stepped out of a known range. Insert a end_sequence
1772 // corresponding to the end of the range.
1773 uint64_t StopAddress =
1774 CurrRange ? CurrRange->Range.end() + CurrRange->Value : -1ULL;
1775 CurrRange = FunctionRanges.getRangeThatContains(Addr: Row.Address.Address);
1776 if (StopAddress != -1ULL && !Seq.empty()) {
1777 // Insert end sequence row with the computed end address, but
1778 // the same line as the previous one. This row is synthesised
1779 // and has no input counterpart, so tag it with
1780 // InvalidRowIndex.
1781 auto NextLine = Seq.back();
1782 NextLine.Address.Address = StopAddress;
1783 NextLine.EndSequence = 1;
1784 NextLine.PrologueEnd = 0;
1785 NextLine.BasicBlock = 0;
1786 NextLine.EpilogueBegin = 0;
1787 Seq.push_back(x: NextLine);
1788 SeqIndices.push_back(Elt: InvalidRowIndex);
1789 insertLineSequence(Seq, SeqIndices, Rows&: NewRows, RowIndices&: NewRowIndices);
1790 }
1791
1792 if (!CurrRange)
1793 continue;
1794 }
1795
1796 // Ignore empty sequences.
1797 if (Row.EndSequence && Seq.empty())
1798 continue;
1799
1800 // Relocate row address and add it to the current sequence.
1801 Row.Address.Address += CurrRange->Value;
1802 Seq.emplace_back(args&: Row);
1803 SeqIndices.push_back(Elt: InputRowIdx);
1804
1805 if (Row.EndSequence)
1806 insertLineSequence(Seq, SeqIndices, Rows&: NewRows, RowIndices&: NewRowIndices);
1807 }
1808}
1809
1810void CompileUnit::patchStmtSeqAttributes(
1811 const DenseMap<uint64_t, uint64_t> &SeqOffsetToFirstRowIndex,
1812 const DenseMap<uint64_t, uint64_t> &RowIndexToSeqStartOffset) {
1813 const uint64_t InvalidOffset = getFormParams().getDwarfMaxOffset();
1814
1815 for (const CompileUnit::StmtSeqPatch &Patch : StmtSeqListAttributes) {
1816 uint64_t NewStmtSeq = InvalidOffset;
1817 auto RowIt = SeqOffsetToFirstRowIndex.find(Val: Patch.InputStmtSeqOffset);
1818 if (RowIt != SeqOffsetToFirstRowIndex.end()) {
1819 auto OffIt = RowIndexToSeqStartOffset.find(Val: RowIt->second);
1820 if (OffIt != RowIndexToSeqStartOffset.end())
1821 NewStmtSeq = OffIt->second;
1822 }
1823 // When resolution fails, the InvalidOffset sentinel must survive the
1824 // combination-time section-offset fixup. The patch applier preserves
1825 // InvalidOffset as-is so consumers see a clean invalid marker rather
1826 // than StartOffset - 1.
1827 *Patch.Value = DIEValue(Patch.Value->getAttribute(), Patch.Value->getForm(),
1828 DIEInteger(NewStmtSeq));
1829 }
1830}
1831
1832DenseMap<uint64_t, uint64_t> CompileUnit::buildStmtSeqOffsetToFirstRowIndex(
1833 const DWARFDebugLine::LineTable &InputLineTable) const {
1834 // Collect this CU's stmt-sequence attribute values (input offsets),
1835 // sorted ascending and deduplicated.
1836 SmallVector<uint64_t> StmtAttrs;
1837 StmtAttrs.reserve(N: StmtSeqListAttributes.size());
1838 for (const StmtSeqPatch &Patch : StmtSeqListAttributes)
1839 StmtAttrs.push_back(Elt: Patch.InputStmtSeqOffset);
1840 llvm::sort(C&: StmtAttrs);
1841 StmtAttrs.erase(CS: llvm::unique(R&: StmtAttrs), CE: StmtAttrs.end());
1842
1843 DenseMap<uint64_t, uint64_t> Result;
1844 dwarf_linker::buildStmtSeqOffsetToFirstRowIndex(LT: InputLineTable, SortedStmtSeqOffsets: StmtAttrs,
1845 SeqOffToFirstRow&: Result);
1846 return Result;
1847}
1848
1849void CompileUnit::insertLineSequence(std::vector<DWARFDebugLine::Row> &Seq,
1850 SmallVectorImpl<uint64_t> &SeqIndices,
1851 std::vector<DWARFDebugLine::Row> &Rows,
1852 SmallVectorImpl<uint64_t> &RowIndices) {
1853 assert(Seq.size() == SeqIndices.size() &&
1854 "Seq and SeqIndices must be kept in lockstep");
1855 assert(Rows.size() == RowIndices.size() &&
1856 "Rows and RowIndices must be kept in lockstep");
1857 if (Seq.empty())
1858 return;
1859
1860 auto ClearSeq = [&] {
1861 Seq.clear();
1862 SeqIndices.clear();
1863 };
1864
1865 if (!Rows.empty() && Rows.back().Address < Seq.front().Address) {
1866 llvm::append_range(C&: Rows, R&: Seq);
1867 llvm::append_range(C&: RowIndices, R&: SeqIndices);
1868 ClearSeq();
1869 return;
1870 }
1871
1872 object::SectionedAddress Front = Seq.front().Address;
1873 auto InsertPoint = partition_point(
1874 Range&: Rows, P: [=](const DWARFDebugLine::Row &O) { return O.Address < Front; });
1875 size_t InsertIdx = std::distance(first: Rows.begin(), last: InsertPoint);
1876
1877 // FIXME: this only removes the unneeded end_sequence if the
1878 // sequences have been inserted in order. Using a global sort like
1879 // described in cloneAndEmitLineTable() and delaying the end_sequene
1880 // elimination to DebugLineEmitter::emit() we can get rid of all of them.
1881 if (InsertPoint != Rows.end() && InsertPoint->Address == Front &&
1882 InsertPoint->EndSequence) {
1883 *InsertPoint = Seq.front();
1884 RowIndices[InsertIdx] = SeqIndices.front();
1885 Rows.insert(position: InsertPoint + 1, first: Seq.begin() + 1, last: Seq.end());
1886 RowIndices.insert(I: RowIndices.begin() + InsertIdx + 1,
1887 From: SeqIndices.begin() + 1, To: SeqIndices.end());
1888 } else {
1889 Rows.insert(position: InsertPoint, first: Seq.begin(), last: Seq.end());
1890 RowIndices.insert(I: RowIndices.begin() + InsertIdx, From: SeqIndices.begin(),
1891 To: SeqIndices.end());
1892 }
1893
1894 ClearSeq();
1895}
1896
1897#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1898LLVM_DUMP_METHOD void CompileUnit::DIEInfo::dump() {
1899 llvm::errs() << "{";
1900 llvm::errs() << " Placement: ";
1901 switch (getPlacement()) {
1902 case NotSet:
1903 llvm::errs() << "NotSet";
1904 break;
1905 case TypeTable:
1906 llvm::errs() << "TypeTable";
1907 break;
1908 case PlainDwarf:
1909 llvm::errs() << "PlainDwarf";
1910 break;
1911 case Both:
1912 llvm::errs() << "Both";
1913 break;
1914 }
1915
1916 llvm::errs() << " Keep: " << getKeep();
1917 llvm::errs() << " KeepPlainChildren: " << getKeepPlainChildren();
1918 llvm::errs() << " KeepTypeChildren: " << getKeepTypeChildren();
1919 llvm::errs() << " IsInMouduleScope: " << getIsInMouduleScope();
1920 llvm::errs() << " IsInFunctionScope: " << getIsInFunctionScope();
1921 llvm::errs() << " IsInAnonNamespaceScope: " << getIsInAnonNamespaceScope();
1922 llvm::errs() << " ODRAvailable: " << getODRAvailable();
1923 llvm::errs() << " TrackLiveness: " << getTrackLiveness();
1924 llvm::errs() << "}\n";
1925}
1926#endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1927
1928std::optional<std::pair<StringRef, StringRef>>
1929CompileUnit::getDirAndFilenameFromLineTable(
1930 const DWARFFormValue &FileIdxValue) {
1931 uint64_t FileIdx;
1932 if (std::optional<uint64_t> Val = FileIdxValue.getAsUnsignedConstant())
1933 FileIdx = *Val;
1934 else if (std::optional<int64_t> Val = FileIdxValue.getAsSignedConstant())
1935 FileIdx = *Val;
1936 else if (std::optional<uint64_t> Val = FileIdxValue.getAsSectionOffset())
1937 FileIdx = *Val;
1938 else
1939 return std::nullopt;
1940
1941 return getDirAndFilenameFromLineTable(FileIdx);
1942}
1943
1944std::optional<std::pair<StringRef, StringRef>>
1945CompileUnit::getDirAndFilenameFromLineTable(uint64_t FileIdx) {
1946 std::lock_guard<std::mutex> Guard(FileNamesMutex);
1947 FileNamesCache::iterator FileData = FileNames.find(Val: FileIdx);
1948 if (FileData != FileNames.end())
1949 return {{StringRef(FileData->second->first),
1950 StringRef(FileData->second->second)}};
1951
1952 if (const DWARFDebugLine::LineTable *LineTable =
1953 getOrigUnit().getContext().getLineTableForUnit(U: &getOrigUnit())) {
1954 if (LineTable->hasFileAtIndex(FileIndex: FileIdx)) {
1955
1956 const llvm::DWARFDebugLine::FileNameEntry &Entry =
1957 LineTable->Prologue.getFileNameEntry(Index: FileIdx);
1958
1959 Expected<const char *> Name = Entry.Name.getAsCString();
1960 if (!Name) {
1961 warn(Warning: Name.takeError());
1962 return std::nullopt;
1963 }
1964
1965 std::string FileName = *Name;
1966 if (isPathAbsoluteOnWindowsOrPosix(Path: FileName)) {
1967 FileNamesCache::iterator FileData =
1968 FileNames
1969 .insert(KV: {FileIdx,
1970 std::make_unique<std::pair<std::string, std::string>>(
1971 args: std::string(""), args: std::move(FileName))})
1972 .first;
1973 return {{StringRef(FileData->second->first),
1974 StringRef(FileData->second->second)}};
1975 }
1976
1977 SmallString<256> FilePath;
1978 StringRef IncludeDir;
1979 // Be defensive about the contents of Entry.
1980 if (getVersion() >= 5) {
1981 // DirIdx 0 is the compilation directory, so don't include it for
1982 // relative names.
1983 if ((Entry.DirIdx != 0) &&
1984 Entry.DirIdx < LineTable->Prologue.IncludeDirectories.size()) {
1985 Expected<const char *> DirName =
1986 LineTable->Prologue.IncludeDirectories[Entry.DirIdx]
1987 .getAsCString();
1988 if (DirName)
1989 IncludeDir = *DirName;
1990 else {
1991 warn(Warning: DirName.takeError());
1992 return std::nullopt;
1993 }
1994 }
1995 } else {
1996 if (0 < Entry.DirIdx &&
1997 Entry.DirIdx <= LineTable->Prologue.IncludeDirectories.size()) {
1998 Expected<const char *> DirName =
1999 LineTable->Prologue.IncludeDirectories[Entry.DirIdx - 1]
2000 .getAsCString();
2001 if (DirName)
2002 IncludeDir = *DirName;
2003 else {
2004 warn(Warning: DirName.takeError());
2005 return std::nullopt;
2006 }
2007 }
2008 }
2009
2010 StringRef CompDir = getOrigUnit().getCompilationDir();
2011
2012 if (!CompDir.empty() && !isPathAbsoluteOnWindowsOrPosix(Path: IncludeDir)) {
2013 sys::path::append(path&: FilePath, style: sys::path::Style::native, a: CompDir);
2014 }
2015
2016 sys::path::append(path&: FilePath, style: sys::path::Style::native, a: IncludeDir);
2017
2018 FileNamesCache::iterator FileData =
2019 FileNames
2020 .insert(KV: {FileIdx,
2021 std::make_unique<std::pair<std::string, std::string>>(
2022 args: std::string(FilePath), args: std::move(FileName))})
2023 .first;
2024 return {{StringRef(FileData->second->first),
2025 StringRef(FileData->second->second)}};
2026 }
2027 }
2028
2029 return std::nullopt;
2030}
2031
2032#define MAX_REFERENCIES_DEPTH 1000
2033UnitEntryPairTy UnitEntryPairTy::getNamespaceOrigin() {
2034 UnitEntryPairTy CUDiePair(*this);
2035 std::optional<UnitEntryPairTy> RefDiePair;
2036 int refDepth = 0;
2037 do {
2038 RefDiePair = CUDiePair.CU->resolveDIEReference(
2039 DieEntry: CUDiePair.DieEntry, Attr: dwarf::DW_AT_extension,
2040 CanResolveInterCUReferences: ResolveInterCUReferencesMode::Resolve);
2041 if (!RefDiePair || !RefDiePair->DieEntry)
2042 return CUDiePair;
2043
2044 CUDiePair = *RefDiePair;
2045 } while (refDepth++ < MAX_REFERENCIES_DEPTH);
2046
2047 return CUDiePair;
2048}
2049
2050std::optional<UnitEntryPairTy> UnitEntryPairTy::getParent() {
2051 if (std::optional<uint32_t> ParentIdx = DieEntry->getParentIdx())
2052 return UnitEntryPairTy{CU, CU->getDebugInfoEntry(Index: *ParentIdx)};
2053
2054 return std::nullopt;
2055}
2056
2057CompileUnit::OutputUnitVariantPtr::OutputUnitVariantPtr(CompileUnit *U)
2058 : Ptr(U) {
2059 assert(U != nullptr);
2060}
2061
2062CompileUnit::OutputUnitVariantPtr::OutputUnitVariantPtr(TypeUnit *U) : Ptr(U) {
2063 assert(U != nullptr);
2064}
2065
2066DwarfUnit *CompileUnit::OutputUnitVariantPtr::operator->() {
2067 if (isCompileUnit())
2068 return getAsCompileUnit();
2069 else
2070 return getAsTypeUnit();
2071}
2072
2073bool CompileUnit::OutputUnitVariantPtr::isCompileUnit() {
2074 return isa<CompileUnit *>(Val: Ptr);
2075}
2076
2077bool CompileUnit::OutputUnitVariantPtr::isTypeUnit() {
2078 return isa<TypeUnit *>(Val: Ptr);
2079}
2080
2081CompileUnit *CompileUnit::OutputUnitVariantPtr::getAsCompileUnit() {
2082 return cast<CompileUnit *>(Val&: Ptr);
2083}
2084
2085TypeUnit *CompileUnit::OutputUnitVariantPtr::getAsTypeUnit() {
2086 return cast<TypeUnit *>(Val&: Ptr);
2087}
2088
2089bool CompileUnit::resolveDependenciesAndMarkLiveness(
2090 bool InterCUProcessingStarted, std::atomic<bool> &HasNewInterconnectedCUs) {
2091 if (!Dependencies)
2092 Dependencies.reset(p: new DependencyTracker(*this));
2093
2094 return Dependencies->resolveDependenciesAndMarkLiveness(
2095 InterCUProcessingStarted, HasNewInterconnectedCUs);
2096}
2097
2098bool CompileUnit::updateDependenciesCompleteness() {
2099 assert(Dependencies.get());
2100
2101 return Dependencies->updateDependenciesCompleteness();
2102}
2103
2104void CompileUnit::verifyDependencies() {
2105 assert(Dependencies.get());
2106
2107 Dependencies->verifyKeepChain();
2108}
2109
2110ArrayRef<dwarf::Attribute> dwarf_linker::parallel::getODRAttributes() {
2111 static dwarf::Attribute ODRAttributes[] = {
2112 dwarf::DW_AT_type, dwarf::DW_AT_specification,
2113 dwarf::DW_AT_abstract_origin, dwarf::DW_AT_import,
2114 dwarf::DW_AT_LLVM_alloc_type};
2115
2116 return ODRAttributes;
2117}
2118