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