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