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

source code of llvm/lib/DWARFLinker/Parallel/DWARFLinkerCompileUnit.cpp