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