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