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