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