[AMDGPU] Test codegen'ing True16 additions.
[llvm-project.git] / llvm / lib / DWARFLinkerParallel / DWARFLinkerCompileUnit.cpp
blob81751601293cb7664c269500a9305e84dbd7c331
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 //===----------------------------------------------------------------------===//
9 #include "DWARFLinkerCompileUnit.h"
10 #include "DIEAttributeCloner.h"
11 #include "DIEGenerator.h"
12 #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
13 #include "llvm/Support/FileSystem.h"
14 #include "llvm/Support/FormatVariadic.h"
16 using namespace llvm;
17 using namespace llvm::dwarflinker_parallel;
19 void CompileUnit::loadLineTable() {
20 LineTablePtr = File.Dwarf->getLineTableForUnit(&getOrigUnit());
23 void CompileUnit::maybeResetToLoadedStage() {
24 // Nothing to reset if stage is less than "Loaded".
25 if (getStage() < Stage::Loaded)
26 return;
28 // Note: We need to do erasing for "Loaded" stage because
29 // if live analysys failed then we will have "Loaded" stage
30 // with marking from "LivenessAnalysisDone" stage partially
31 // done. That marking should be cleared.
33 for (DIEInfo &DieInfo : DieInfoArray)
34 DieInfo.unsetFlagsWhichSetDuringLiveAnalysis();
36 LowPc = std::nullopt;
37 HighPc = 0;
38 Labels.clear();
39 Ranges.clear();
41 if (getStage() < Stage::Cloned) {
42 setStage(Stage::Loaded);
43 return;
46 AbbreviationsSet.clear();
47 Abbreviations.clear();
48 OutUnitDIE = nullptr;
49 DebugAddrIndexMap.clear();
51 for (uint64_t &Offset : OutDieOffsetArray)
52 Offset = 0;
53 eraseSections();
55 setStage(Stage::CreatedNotLoaded);
58 bool CompileUnit::loadInputDIEs() {
59 DWARFDie InputUnitDIE = getUnitDIE(false);
60 if (!InputUnitDIE)
61 return false;
63 // load input dies, resize Info structures array.
64 DieInfoArray.resize(getOrigUnit().getNumDIEs());
65 OutDieOffsetArray.resize(getOrigUnit().getNumDIEs(), 0);
66 return true;
69 void CompileUnit::analyzeDWARFStructureRec(const DWARFDebugInfoEntry *DieEntry,
70 bool IsInModule, bool IsInFunction) {
71 for (const DWARFDebugInfoEntry *CurChild = getFirstChildEntry(DieEntry);
72 CurChild && CurChild->getAbbreviationDeclarationPtr();
73 CurChild = getSiblingEntry(CurChild)) {
74 CompileUnit::DIEInfo &ChildInfo = getDIEInfo(CurChild);
76 if (IsInModule)
77 ChildInfo.setIsInMouduleScope();
78 if (IsInFunction)
79 ChildInfo.setIsInFunctionScope();
81 switch (CurChild->getTag()) {
82 case dwarf::DW_TAG_module:
83 ChildInfo.setIsInMouduleScope();
84 if (DieEntry->getTag() == dwarf::DW_TAG_compile_unit &&
85 dwarf::toString(find(CurChild, dwarf::DW_AT_name), "") !=
86 getClangModuleName())
87 analyzeImportedModule(CurChild);
88 break;
89 case dwarf::DW_TAG_subprogram:
90 ChildInfo.setIsInFunctionScope();
91 break;
92 default:
93 break;
96 if (IsInModule)
97 ChildInfo.setIsInMouduleScope();
98 if (IsInFunction)
99 ChildInfo.setIsInFunctionScope();
101 if (CurChild->hasChildren())
102 analyzeDWARFStructureRec(CurChild, ChildInfo.getIsInMouduleScope(),
103 ChildInfo.getIsInFunctionScope());
107 StringEntry *CompileUnit::getFileName(unsigned FileIdx,
108 StringPool &GlobalStrings) {
109 if (LineTablePtr) {
110 if (LineTablePtr->hasFileAtIndex(FileIdx)) {
111 // Cache the resolved paths based on the index in the line table,
112 // because calling realpath is expensive.
113 ResolvedPathsMap::const_iterator It = ResolvedFullPaths.find(FileIdx);
114 if (It == ResolvedFullPaths.end()) {
115 std::string OrigFileName;
116 bool FoundFileName = LineTablePtr->getFileNameByIndex(
117 FileIdx, getOrigUnit().getCompilationDir(),
118 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
119 OrigFileName);
120 (void)FoundFileName;
121 assert(FoundFileName && "Must get file name from line table");
123 // Second level of caching, this time based on the file's parent
124 // path.
125 StringRef FileName = sys::path::filename(OrigFileName);
126 StringRef ParentPath = sys::path::parent_path(OrigFileName);
128 // If the ParentPath has not yet been resolved, resolve and cache it for
129 // future look-ups.
130 StringMap<StringEntry *>::iterator ParentIt =
131 ResolvedParentPaths.find(ParentPath);
132 if (ParentIt == ResolvedParentPaths.end()) {
133 SmallString<256> RealPath;
134 sys::fs::real_path(ParentPath, RealPath);
135 ParentIt =
136 ResolvedParentPaths
137 .insert({ParentPath, GlobalStrings.insert(RealPath).first})
138 .first;
141 // Join the file name again with the resolved path.
142 SmallString<256> ResolvedPath(ParentIt->second->first());
143 sys::path::append(ResolvedPath, FileName);
145 It = ResolvedFullPaths
146 .insert(std::make_pair(
147 FileIdx, GlobalStrings.insert(ResolvedPath).first))
148 .first;
151 return It->second;
155 return nullptr;
158 void CompileUnit::cleanupDataAfterClonning() {
159 AbbreviationsSet.clear();
160 ResolvedFullPaths.shrink_and_clear();
161 ResolvedParentPaths.clear();
162 DieInfoArray = SmallVector<DIEInfo>();
163 OutDieOffsetArray = SmallVector<uint64_t>();
164 getOrigUnit().clear();
167 /// Collect references to parseable Swift interfaces in imported
168 /// DW_TAG_module blocks.
169 void CompileUnit::analyzeImportedModule(const DWARFDebugInfoEntry *DieEntry) {
170 if (getLanguage() != dwarf::DW_LANG_Swift)
171 return;
173 if (!GlobalData.getOptions().ParseableSwiftInterfaces)
174 return;
176 StringRef Path =
177 dwarf::toStringRef(find(DieEntry, dwarf::DW_AT_LLVM_include_path));
178 if (!Path.endswith(".swiftinterface"))
179 return;
180 // Don't track interfaces that are part of the SDK.
181 StringRef SysRoot =
182 dwarf::toStringRef(find(DieEntry, dwarf::DW_AT_LLVM_sysroot));
183 if (SysRoot.empty())
184 SysRoot = getSysRoot();
185 if (!SysRoot.empty() && Path.startswith(SysRoot))
186 return;
187 if (std::optional<DWARFFormValue> Val = find(DieEntry, dwarf::DW_AT_name)) {
188 Expected<const char *> Name = Val->getAsCString();
189 if (!Name) {
190 warn(Name.takeError());
191 return;
194 auto &Entry = (*GlobalData.getOptions().ParseableSwiftInterfaces)[*Name];
195 // The prepend path is applied later when copying.
196 SmallString<128> ResolvedPath;
197 if (sys::path::is_relative(Path))
198 sys::path::append(
199 ResolvedPath,
200 dwarf::toString(getUnitDIE().find(dwarf::DW_AT_comp_dir), ""));
201 sys::path::append(ResolvedPath, Path);
202 if (!Entry.empty() && Entry != ResolvedPath) {
203 DWARFDie Die = getDIE(DieEntry);
204 warn(Twine("conflicting parseable interfaces for Swift Module ") + *Name +
205 ": " + Entry + " and " + Path + ".",
206 &Die);
208 Entry = std::string(ResolvedPath.str());
212 void CompileUnit::updateDieRefPatchesWithClonedOffsets() {
213 if (std::optional<SectionDescriptor *> DebugInfoSection =
214 getSectionDescriptor(DebugSectionKind::DebugInfo)) {
216 (*DebugInfoSection)
217 ->ListDebugDieRefPatch.forEach([](DebugDieRefPatch &Patch) {
218 Patch.RefDieIdxOrClonedOffset =
219 Patch.RefCU.getPointer()->getDieOutOffset(
220 Patch.RefDieIdxOrClonedOffset);
223 (*DebugInfoSection)
224 ->ListDebugULEB128DieRefPatch.forEach(
225 [](DebugULEB128DieRefPatch &Patch) {
226 Patch.RefDieIdxOrClonedOffset =
227 Patch.RefCU.getPointer()->getDieOutOffset(
228 Patch.RefDieIdxOrClonedOffset);
232 if (std::optional<SectionDescriptor *> DebugLocSection =
233 getSectionDescriptor(DebugSectionKind::DebugLoc)) {
234 (*DebugLocSection)
235 ->ListDebugULEB128DieRefPatch.forEach(
236 [](DebugULEB128DieRefPatch &Patch) {
237 Patch.RefDieIdxOrClonedOffset =
238 Patch.RefCU.getPointer()->getDieOutOffset(
239 Patch.RefDieIdxOrClonedOffset);
243 if (std::optional<SectionDescriptor *> DebugLocListsSection =
244 getSectionDescriptor(DebugSectionKind::DebugLocLists)) {
245 (*DebugLocListsSection)
246 ->ListDebugULEB128DieRefPatch.forEach(
247 [](DebugULEB128DieRefPatch &Patch) {
248 Patch.RefDieIdxOrClonedOffset =
249 Patch.RefCU.getPointer()->getDieOutOffset(
250 Patch.RefDieIdxOrClonedOffset);
255 std::optional<std::pair<CompileUnit *, uint32_t>>
256 CompileUnit::resolveDIEReference(const DWARFFormValue &RefValue) {
257 if (std::optional<DWARFFormValue::UnitOffset> Ref =
258 *RefValue.getAsRelativeReference()) {
259 if (Ref->Unit != nullptr) {
260 // Referenced DIE is in current compile unit.
262 if (std::optional<uint32_t> RefDieIdx =
263 getDIEIndexForOffset(Ref->Unit->getOffset() + Ref->Offset))
264 return std::make_pair(this, *RefDieIdx);
265 } else if (CompileUnit *RefCU = getUnitFromOffset(Ref->Offset)) {
266 // Referenced DIE is in other compile unit.
268 // Check whether DIEs are loaded for that compile unit.
269 enum Stage ReferredCUStage = RefCU->getStage();
270 if (ReferredCUStage < Stage::Loaded || ReferredCUStage > Stage::Cloned)
271 return std::make_pair(RefCU, 0);
273 if (std::optional<uint32_t> RefDieIdx =
274 RefCU->getDIEIndexForOffset(Ref->Offset))
275 return std::make_pair(RefCU, *RefDieIdx);
279 return std::nullopt;
282 void CompileUnit::addFunctionRange(uint64_t FuncLowPc, uint64_t FuncHighPc,
283 int64_t PcOffset) {
284 std::lock_guard<std::mutex> Guard(RangesMutex);
286 Ranges.insert({FuncLowPc, FuncHighPc}, PcOffset);
287 if (LowPc)
288 LowPc = std::min(*LowPc, FuncLowPc + PcOffset);
289 else
290 LowPc = FuncLowPc + PcOffset;
291 this->HighPc = std::max(HighPc, FuncHighPc + PcOffset);
294 void CompileUnit::addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset) {
295 std::lock_guard<std::mutex> Guard(LabelsMutex);
296 Labels.insert({LabelLowPc, PcOffset});
299 Error CompileUnit::cloneAndEmitDebugLocations() {
300 if (getGlobalData().getOptions().UpdateIndexTablesOnly)
301 return Error::success();
303 if (getOrigUnit().getVersion() < 5) {
304 emitLocations(DebugSectionKind::DebugLoc);
305 return Error::success();
308 emitLocations(DebugSectionKind::DebugLocLists);
309 return Error::success();
312 void CompileUnit::emitLocations(DebugSectionKind LocationSectionKind) {
313 SectionDescriptor &DebugInfoSection =
314 getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);
316 if (!DebugInfoSection.ListDebugLocPatch.empty()) {
317 SectionDescriptor &OutLocationSection =
318 getOrCreateSectionDescriptor(LocationSectionKind);
319 DWARFUnit &OrigUnit = getOrigUnit();
321 uint64_t OffsetAfterUnitLength = emitLocListHeader(OutLocationSection);
323 DebugInfoSection.ListDebugLocPatch.forEach([&](DebugLocPatch &Patch) {
324 // Get location expressions vector corresponding to the current
325 // attribute from the source DWARF.
326 uint64_t InputDebugLocSectionOffset = DebugInfoSection.getIntVal(
327 Patch.PatchOffset,
328 DebugInfoSection.getFormParams().getDwarfOffsetByteSize());
329 Expected<DWARFLocationExpressionsVector> OriginalLocations =
330 OrigUnit.findLoclistFromOffset(InputDebugLocSectionOffset);
332 if (!OriginalLocations) {
333 warn(OriginalLocations.takeError());
334 return;
337 LinkedLocationExpressionsVector LinkedLocationExpressions;
338 for (DWARFLocationExpression &CurExpression : *OriginalLocations) {
339 LinkedLocationExpressionsWithOffsetPatches LinkedExpression;
341 if (CurExpression.Range) {
342 // Relocate address range.
343 LinkedExpression.Expression.Range = {
344 CurExpression.Range->LowPC + Patch.AddrAdjustmentValue,
345 CurExpression.Range->HighPC + Patch.AddrAdjustmentValue};
348 DataExtractor Data(CurExpression.Expr, OrigUnit.isLittleEndian(),
349 OrigUnit.getAddressByteSize());
351 DWARFExpression InputExpression(Data, OrigUnit.getAddressByteSize(),
352 OrigUnit.getFormParams().Format);
353 cloneDieAttrExpression(InputExpression,
354 LinkedExpression.Expression.Expr,
355 OutLocationSection, Patch.AddrAdjustmentValue,
356 LinkedExpression.Patches);
358 LinkedLocationExpressions.push_back({LinkedExpression});
361 // Emit locations list table fragment corresponding to the CurLocAttr.
362 DebugInfoSection.apply(Patch.PatchOffset, dwarf::DW_FORM_sec_offset,
363 OutLocationSection.OS.tell());
364 emitLocListFragment(LinkedLocationExpressions, OutLocationSection);
367 if (OffsetAfterUnitLength > 0) {
368 assert(OffsetAfterUnitLength -
369 OutLocationSection.getFormParams().getDwarfOffsetByteSize() <
370 OffsetAfterUnitLength);
371 OutLocationSection.apply(
372 OffsetAfterUnitLength -
373 OutLocationSection.getFormParams().getDwarfOffsetByteSize(),
374 dwarf::DW_FORM_sec_offset,
375 OutLocationSection.OS.tell() - OffsetAfterUnitLength);
380 /// Emit debug locations(.debug_loc, .debug_loclists) header.
381 uint64_t CompileUnit::emitLocListHeader(SectionDescriptor &OutLocationSection) {
382 if (getOrigUnit().getVersion() < 5)
383 return 0;
385 // unit_length.
386 OutLocationSection.emitUnitLength(0xBADDEF);
387 uint64_t OffsetAfterUnitLength = OutLocationSection.OS.tell();
389 // Version.
390 OutLocationSection.emitIntVal(5, 2);
392 // Address size.
393 OutLocationSection.emitIntVal(OutLocationSection.getFormParams().AddrSize, 1);
395 // Seg_size
396 OutLocationSection.emitIntVal(0, 1);
398 // Offset entry count
399 OutLocationSection.emitIntVal(0, 4);
401 return OffsetAfterUnitLength;
404 /// Emit debug locations(.debug_loc, .debug_loclists) fragment.
405 uint64_t CompileUnit::emitLocListFragment(
406 const LinkedLocationExpressionsVector &LinkedLocationExpression,
407 SectionDescriptor &OutLocationSection) {
408 uint64_t OffsetBeforeLocationExpression = 0;
410 if (getOrigUnit().getVersion() < 5) {
411 uint64_t BaseAddress = 0;
412 if (std::optional<uint64_t> LowPC = getLowPc())
413 BaseAddress = *LowPC;
415 for (const LinkedLocationExpressionsWithOffsetPatches &LocExpression :
416 LinkedLocationExpression) {
417 if (LocExpression.Expression.Range) {
418 OutLocationSection.emitIntVal(
419 LocExpression.Expression.Range->LowPC - BaseAddress,
420 OutLocationSection.getFormParams().AddrSize);
421 OutLocationSection.emitIntVal(
422 LocExpression.Expression.Range->HighPC - BaseAddress,
423 OutLocationSection.getFormParams().AddrSize);
426 OutLocationSection.emitIntVal(LocExpression.Expression.Expr.size(), 2);
427 OffsetBeforeLocationExpression = OutLocationSection.OS.tell();
428 for (uint64_t *OffsetPtr : LocExpression.Patches)
429 *OffsetPtr += OffsetBeforeLocationExpression;
431 OutLocationSection.OS
432 << StringRef((const char *)LocExpression.Expression.Expr.data(),
433 LocExpression.Expression.Expr.size());
436 // Emit the terminator entry.
437 OutLocationSection.emitIntVal(0,
438 OutLocationSection.getFormParams().AddrSize);
439 OutLocationSection.emitIntVal(0,
440 OutLocationSection.getFormParams().AddrSize);
441 return OffsetBeforeLocationExpression;
444 std::optional<uint64_t> BaseAddress;
445 for (const LinkedLocationExpressionsWithOffsetPatches &LocExpression :
446 LinkedLocationExpression) {
447 if (LocExpression.Expression.Range) {
448 // Check whether base address is set. If it is not set yet
449 // then set current base address and emit base address selection entry.
450 if (!BaseAddress) {
451 BaseAddress = LocExpression.Expression.Range->LowPC;
453 // Emit base address.
454 OutLocationSection.emitIntVal(dwarf::DW_LLE_base_addressx, 1);
455 encodeULEB128(DebugAddrIndexMap.getValueIndex(*BaseAddress),
456 OutLocationSection.OS);
459 // Emit type of entry.
460 OutLocationSection.emitIntVal(dwarf::DW_LLE_offset_pair, 1);
462 // Emit start offset relative to base address.
463 encodeULEB128(LocExpression.Expression.Range->LowPC - *BaseAddress,
464 OutLocationSection.OS);
466 // Emit end offset relative to base address.
467 encodeULEB128(LocExpression.Expression.Range->HighPC - *BaseAddress,
468 OutLocationSection.OS);
469 } else
470 // Emit type of entry.
471 OutLocationSection.emitIntVal(dwarf::DW_LLE_default_location, 1);
473 encodeULEB128(LocExpression.Expression.Expr.size(), OutLocationSection.OS);
474 OffsetBeforeLocationExpression = OutLocationSection.OS.tell();
475 for (uint64_t *OffsetPtr : LocExpression.Patches)
476 *OffsetPtr += OffsetBeforeLocationExpression;
478 OutLocationSection.OS << StringRef(
479 (const char *)LocExpression.Expression.Expr.data(),
480 LocExpression.Expression.Expr.size());
483 // Emit the terminator entry.
484 OutLocationSection.emitIntVal(dwarf::DW_LLE_end_of_list, 1);
485 return OffsetBeforeLocationExpression;
488 Error CompileUnit::emitDebugAddrSection() {
489 if (GlobalData.getOptions().UpdateIndexTablesOnly)
490 return Error::success();
492 if (getVersion() < 5)
493 return Error::success();
495 if (DebugAddrIndexMap.empty())
496 return Error::success();
498 SectionDescriptor &OutAddrSection =
499 getOrCreateSectionDescriptor(DebugSectionKind::DebugAddr);
501 // Emit section header.
503 // Emit length.
504 OutAddrSection.emitUnitLength(0xBADDEF);
505 uint64_t OffsetAfterSectionLength = OutAddrSection.OS.tell();
507 // Emit version.
508 OutAddrSection.emitIntVal(5, 2);
510 // Emit address size.
511 OutAddrSection.emitIntVal(getFormParams().AddrSize, 1);
513 // Emit segment size.
514 OutAddrSection.emitIntVal(0, 1);
516 // Emit addresses.
517 for (uint64_t AddrValue : DebugAddrIndexMap.getValues())
518 OutAddrSection.emitIntVal(AddrValue, getFormParams().AddrSize);
520 // Patch section length.
521 OutAddrSection.apply(
522 OffsetAfterSectionLength -
523 OutAddrSection.getFormParams().getDwarfOffsetByteSize(),
524 dwarf::DW_FORM_sec_offset,
525 OutAddrSection.OS.tell() - OffsetAfterSectionLength);
527 return Error::success();
530 Error CompileUnit::emitDebugStringOffsetSection() {
531 if (getVersion() < 5)
532 return Error::success();
534 if (DebugStringIndexMap.empty())
535 return Error::success();
537 SectionDescriptor &OutDebugStrOffsetsSection =
538 getOrCreateSectionDescriptor(DebugSectionKind::DebugStrOffsets);
540 // Emit section header.
542 // Emit length.
543 OutDebugStrOffsetsSection.emitUnitLength(0xBADDEF);
544 uint64_t OffsetAfterSectionLength = OutDebugStrOffsetsSection.OS.tell();
546 // Emit version.
547 OutDebugStrOffsetsSection.emitIntVal(5, 2);
549 // Emit padding.
550 OutDebugStrOffsetsSection.emitIntVal(0, 2);
552 // Emit index to offset map.
553 for (const StringEntry *String : DebugStringIndexMap.getValues()) {
554 // Note patch for string offset value.
555 OutDebugStrOffsetsSection.notePatch(
556 DebugStrPatch{{OutDebugStrOffsetsSection.OS.tell()}, String});
558 // Emit placeholder for offset value.
559 OutDebugStrOffsetsSection.emitOffset(0xBADDEF);
562 // Patch section length.
563 OutDebugStrOffsetsSection.apply(
564 OffsetAfterSectionLength -
565 OutDebugStrOffsetsSection.getFormParams().getDwarfOffsetByteSize(),
566 dwarf::DW_FORM_sec_offset,
567 OutDebugStrOffsetsSection.OS.tell() - OffsetAfterSectionLength);
569 return Error::success();
572 Error CompileUnit::cloneAndEmitRanges() {
573 if (getGlobalData().getOptions().UpdateIndexTablesOnly)
574 return Error::success();
576 // Build set of linked address ranges for unit function ranges.
577 AddressRanges LinkedFunctionRanges;
578 for (const AddressRangeValuePair &Range : getFunctionRanges())
579 LinkedFunctionRanges.insert(
580 {Range.Range.start() + Range.Value, Range.Range.end() + Range.Value});
582 emitAranges(LinkedFunctionRanges);
584 if (getOrigUnit().getVersion() < 5) {
585 cloneAndEmitRangeList(DebugSectionKind::DebugRange, LinkedFunctionRanges);
586 return Error::success();
589 cloneAndEmitRangeList(DebugSectionKind::DebugRngLists, LinkedFunctionRanges);
590 return Error::success();
593 void CompileUnit::cloneAndEmitRangeList(DebugSectionKind RngSectionKind,
594 AddressRanges &LinkedFunctionRanges) {
595 SectionDescriptor &DebugInfoSection =
596 getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);
597 SectionDescriptor &OutRangeSection =
598 getOrCreateSectionDescriptor(RngSectionKind);
600 if (!DebugInfoSection.ListDebugRangePatch.empty()) {
601 std::optional<AddressRangeValuePair> CachedRange;
602 uint64_t OffsetAfterUnitLength = emitRangeListHeader(OutRangeSection);
604 DebugRangePatch *CompileUnitRangePtr = nullptr;
605 DebugInfoSection.ListDebugRangePatch.forEach([&](DebugRangePatch &Patch) {
606 if (Patch.IsCompileUnitRanges) {
607 CompileUnitRangePtr = &Patch;
608 } else {
609 // Get ranges from the source DWARF corresponding to the current
610 // attribute.
611 AddressRanges LinkedRanges;
612 uint64_t InputDebugRangesSectionOffset = DebugInfoSection.getIntVal(
613 Patch.PatchOffset,
614 DebugInfoSection.getFormParams().getDwarfOffsetByteSize());
615 if (Expected<DWARFAddressRangesVector> InputRanges =
616 getOrigUnit().findRnglistFromOffset(
617 InputDebugRangesSectionOffset)) {
618 // Apply relocation adjustment.
619 for (const auto &Range : *InputRanges) {
620 if (!CachedRange || !CachedRange->Range.contains(Range.LowPC))
621 CachedRange =
622 getFunctionRanges().getRangeThatContains(Range.LowPC);
624 // All range entries should lie in the function range.
625 if (!CachedRange) {
626 warn("inconsistent range data.");
627 continue;
630 // Store range for emiting.
631 LinkedRanges.insert({Range.LowPC + CachedRange->Value,
632 Range.HighPC + CachedRange->Value});
634 } else {
635 llvm::consumeError(InputRanges.takeError());
636 warn("invalid range list ignored.");
639 // Emit linked ranges.
640 DebugInfoSection.apply(Patch.PatchOffset, dwarf::DW_FORM_sec_offset,
641 OutRangeSection.OS.tell());
642 emitRangeListFragment(LinkedRanges, OutRangeSection);
646 if (CompileUnitRangePtr != nullptr) {
647 // Emit compile unit ranges last to be binary compatible with classic
648 // dsymutil.
649 DebugInfoSection.apply(CompileUnitRangePtr->PatchOffset,
650 dwarf::DW_FORM_sec_offset,
651 OutRangeSection.OS.tell());
652 emitRangeListFragment(LinkedFunctionRanges, OutRangeSection);
655 if (OffsetAfterUnitLength > 0) {
656 assert(OffsetAfterUnitLength -
657 OutRangeSection.getFormParams().getDwarfOffsetByteSize() <
658 OffsetAfterUnitLength);
659 OutRangeSection.apply(
660 OffsetAfterUnitLength -
661 OutRangeSection.getFormParams().getDwarfOffsetByteSize(),
662 dwarf::DW_FORM_sec_offset,
663 OutRangeSection.OS.tell() - OffsetAfterUnitLength);
668 uint64_t CompileUnit::emitRangeListHeader(SectionDescriptor &OutRangeSection) {
669 if (OutRangeSection.getFormParams().Version < 5)
670 return 0;
672 // unit_length.
673 OutRangeSection.emitUnitLength(0xBADDEF);
674 uint64_t OffsetAfterUnitLength = OutRangeSection.OS.tell();
676 // Version.
677 OutRangeSection.emitIntVal(5, 2);
679 // Address size.
680 OutRangeSection.emitIntVal(OutRangeSection.getFormParams().AddrSize, 1);
682 // Seg_size
683 OutRangeSection.emitIntVal(0, 1);
685 // Offset entry count
686 OutRangeSection.emitIntVal(0, 4);
688 return OffsetAfterUnitLength;
691 void CompileUnit::emitRangeListFragment(const AddressRanges &LinkedRanges,
692 SectionDescriptor &OutRangeSection) {
693 if (OutRangeSection.getFormParams().Version < 5) {
694 // Emit ranges.
695 uint64_t BaseAddress = 0;
696 if (std::optional<uint64_t> LowPC = getLowPc())
697 BaseAddress = *LowPC;
699 for (const AddressRange &Range : LinkedRanges) {
700 OutRangeSection.emitIntVal(Range.start() - BaseAddress,
701 OutRangeSection.getFormParams().AddrSize);
702 OutRangeSection.emitIntVal(Range.end() - BaseAddress,
703 OutRangeSection.getFormParams().AddrSize);
706 // Add the terminator entry.
707 OutRangeSection.emitIntVal(0, OutRangeSection.getFormParams().AddrSize);
708 OutRangeSection.emitIntVal(0, OutRangeSection.getFormParams().AddrSize);
709 return;
712 std::optional<uint64_t> BaseAddress;
713 for (const AddressRange &Range : LinkedRanges) {
714 if (!BaseAddress) {
715 BaseAddress = Range.start();
717 // Emit base address.
718 OutRangeSection.emitIntVal(dwarf::DW_RLE_base_addressx, 1);
719 encodeULEB128(getDebugAddrIndex(*BaseAddress), OutRangeSection.OS);
722 // Emit type of entry.
723 OutRangeSection.emitIntVal(dwarf::DW_RLE_offset_pair, 1);
725 // Emit start offset relative to base address.
726 encodeULEB128(Range.start() - *BaseAddress, OutRangeSection.OS);
728 // Emit end offset relative to base address.
729 encodeULEB128(Range.end() - *BaseAddress, OutRangeSection.OS);
732 // Emit the terminator entry.
733 OutRangeSection.emitIntVal(dwarf::DW_RLE_end_of_list, 1);
736 void CompileUnit::emitAranges(AddressRanges &LinkedFunctionRanges) {
737 if (LinkedFunctionRanges.empty())
738 return;
740 SectionDescriptor &DebugInfoSection =
741 getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);
742 SectionDescriptor &OutArangesSection =
743 getOrCreateSectionDescriptor(DebugSectionKind::DebugARanges);
745 // Emit Header.
746 unsigned HeaderSize =
747 sizeof(int32_t) + // Size of contents (w/o this field
748 sizeof(int16_t) + // DWARF ARange version number
749 sizeof(int32_t) + // Offset of CU in the .debug_info section
750 sizeof(int8_t) + // Pointer Size (in bytes)
751 sizeof(int8_t); // Segment Size (in bytes)
753 unsigned TupleSize = OutArangesSection.getFormParams().AddrSize * 2;
754 unsigned Padding = offsetToAlignment(HeaderSize, Align(TupleSize));
756 OutArangesSection.emitOffset(0xBADDEF); // Aranges length
757 uint64_t OffsetAfterArangesLengthField = OutArangesSection.OS.tell();
759 OutArangesSection.emitIntVal(dwarf::DW_ARANGES_VERSION, 2); // Version number
760 OutArangesSection.notePatch(
761 DebugOffsetPatch{OutArangesSection.OS.tell(), &DebugInfoSection});
762 OutArangesSection.emitOffset(0xBADDEF); // Corresponding unit's offset
763 OutArangesSection.emitIntVal(OutArangesSection.getFormParams().AddrSize,
764 1); // Address size
765 OutArangesSection.emitIntVal(0, 1); // Segment size
767 for (size_t Idx = 0; Idx < Padding; Idx++)
768 OutArangesSection.emitIntVal(0, 1); // Padding
770 // Emit linked ranges.
771 for (const AddressRange &Range : LinkedFunctionRanges) {
772 OutArangesSection.emitIntVal(Range.start(),
773 OutArangesSection.getFormParams().AddrSize);
774 OutArangesSection.emitIntVal(Range.end() - Range.start(),
775 OutArangesSection.getFormParams().AddrSize);
778 // Emit terminator.
779 OutArangesSection.emitIntVal(0, OutArangesSection.getFormParams().AddrSize);
780 OutArangesSection.emitIntVal(0, OutArangesSection.getFormParams().AddrSize);
782 uint64_t OffsetAfterArangesEnd = OutArangesSection.OS.tell();
784 // Update Aranges lentgh.
785 OutArangesSection.apply(
786 OffsetAfterArangesLengthField -
787 OutArangesSection.getFormParams().getDwarfOffsetByteSize(),
788 dwarf::DW_FORM_sec_offset,
789 OffsetAfterArangesEnd - OffsetAfterArangesLengthField);
792 Error CompileUnit::cloneAndEmitDebugMacro() {
793 if (getOutUnitDIE() == nullptr)
794 return Error::success();
796 DWARFUnit &OrigUnit = getOrigUnit();
797 DWARFDie OrigUnitDie = OrigUnit.getUnitDIE();
799 // Check for .debug_macro table.
800 if (std::optional<uint64_t> MacroAttr =
801 dwarf::toSectionOffset(OrigUnitDie.find(dwarf::DW_AT_macros))) {
802 if (const DWARFDebugMacro *Table =
803 getContaingFile().Dwarf->getDebugMacro()) {
804 emitMacroTableImpl(Table, *MacroAttr, true);
808 // Check for .debug_macinfo table.
809 if (std::optional<uint64_t> MacroAttr =
810 dwarf::toSectionOffset(OrigUnitDie.find(dwarf::DW_AT_macro_info))) {
811 if (const DWARFDebugMacro *Table =
812 getContaingFile().Dwarf->getDebugMacinfo()) {
813 emitMacroTableImpl(Table, *MacroAttr, false);
817 return Error::success();
820 void CompileUnit::emitMacroTableImpl(const DWARFDebugMacro *MacroTable,
821 uint64_t OffsetToMacroTable,
822 bool hasDWARFv5Header) {
823 SectionDescriptor &OutSection =
824 hasDWARFv5Header
825 ? getOrCreateSectionDescriptor(DebugSectionKind::DebugMacro)
826 : getOrCreateSectionDescriptor(DebugSectionKind::DebugMacinfo);
828 bool DefAttributeIsReported = false;
829 bool UndefAttributeIsReported = false;
830 bool ImportAttributeIsReported = false;
832 for (const DWARFDebugMacro::MacroList &List : MacroTable->MacroLists) {
833 if (OffsetToMacroTable == List.Offset) {
834 // Write DWARFv5 header.
835 if (hasDWARFv5Header) {
836 // Write header version.
837 OutSection.emitIntVal(List.Header.Version, sizeof(List.Header.Version));
839 uint8_t Flags = List.Header.Flags;
841 // Check for OPCODE_OPERANDS_TABLE.
842 if (Flags &
843 DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE) {
844 Flags &=
845 ~DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE;
846 warn("opcode_operands_table is not supported yet.");
849 // Check for DEBUG_LINE_OFFSET.
850 std::optional<uint64_t> StmtListOffset;
851 if (Flags & DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET) {
852 // Get offset to the line table from the cloned compile unit.
853 for (auto &V : getOutUnitDIE()->values()) {
854 if (V.getAttribute() == dwarf::DW_AT_stmt_list) {
855 StmtListOffset = V.getDIEInteger().getValue();
856 break;
860 if (!StmtListOffset) {
861 Flags &= ~DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET;
862 warn("couldn`t find line table for macro table.");
866 // Write flags.
867 OutSection.emitIntVal(Flags, sizeof(Flags));
869 // Write offset to line table.
870 if (StmtListOffset) {
871 OutSection.notePatch(DebugOffsetPatch{
872 OutSection.OS.tell(),
873 &getOrCreateSectionDescriptor(DebugSectionKind::DebugLine)});
874 // TODO: check that List.Header.getOffsetByteSize() and
875 // DebugOffsetPatch agree on size.
876 OutSection.emitIntVal(0xBADDEF, List.Header.getOffsetByteSize());
880 // Write macro entries.
881 for (const DWARFDebugMacro::Entry &MacroEntry : List.Macros) {
882 if (MacroEntry.Type == 0) {
883 encodeULEB128(MacroEntry.Type, OutSection.OS);
884 continue;
887 uint8_t MacroType = MacroEntry.Type;
888 switch (MacroType) {
889 default: {
890 bool HasVendorSpecificExtension =
891 (!hasDWARFv5Header &&
892 MacroType == dwarf::DW_MACINFO_vendor_ext) ||
893 (hasDWARFv5Header && (MacroType >= dwarf::DW_MACRO_lo_user &&
894 MacroType <= dwarf::DW_MACRO_hi_user));
896 if (HasVendorSpecificExtension) {
897 // Write macinfo type.
898 OutSection.emitIntVal(MacroType, 1);
900 // Write vendor extension constant.
901 encodeULEB128(MacroEntry.ExtConstant, OutSection.OS);
903 // Write vendor extension string.
904 OutSection.emitString(dwarf::DW_FORM_string, MacroEntry.ExtStr);
905 } else
906 warn("unknown macro type. skip.");
907 } break;
908 // debug_macro and debug_macinfo share some common encodings.
909 // DW_MACRO_define == DW_MACINFO_define
910 // DW_MACRO_undef == DW_MACINFO_undef
911 // DW_MACRO_start_file == DW_MACINFO_start_file
912 // DW_MACRO_end_file == DW_MACINFO_end_file
913 // For readibility/uniformity we are using DW_MACRO_*.
914 case dwarf::DW_MACRO_define:
915 case dwarf::DW_MACRO_undef: {
916 // Write macinfo type.
917 OutSection.emitIntVal(MacroType, 1);
919 // Write source line.
920 encodeULEB128(MacroEntry.Line, OutSection.OS);
922 // Write macro string.
923 OutSection.emitString(dwarf::DW_FORM_string, MacroEntry.MacroStr);
924 } break;
925 case dwarf::DW_MACRO_define_strp:
926 case dwarf::DW_MACRO_undef_strp:
927 case dwarf::DW_MACRO_define_strx:
928 case dwarf::DW_MACRO_undef_strx: {
929 // DW_MACRO_*_strx forms are not supported currently.
930 // Convert to *_strp.
931 switch (MacroType) {
932 case dwarf::DW_MACRO_define_strx: {
933 MacroType = dwarf::DW_MACRO_define_strp;
934 if (!DefAttributeIsReported) {
935 warn("DW_MACRO_define_strx unsupported yet. Convert to "
936 "DW_MACRO_define_strp.");
937 DefAttributeIsReported = true;
939 } break;
940 case dwarf::DW_MACRO_undef_strx: {
941 MacroType = dwarf::DW_MACRO_undef_strp;
942 if (!UndefAttributeIsReported) {
943 warn("DW_MACRO_undef_strx unsupported yet. Convert to "
944 "DW_MACRO_undef_strp.");
945 UndefAttributeIsReported = true;
947 } break;
948 default:
949 // Nothing to do.
950 break;
953 // Write macinfo type.
954 OutSection.emitIntVal(MacroType, 1);
956 // Write source line.
957 encodeULEB128(MacroEntry.Line, OutSection.OS);
959 // Write macro string.
960 OutSection.emitString(dwarf::DW_FORM_strp, MacroEntry.MacroStr);
961 break;
963 case dwarf::DW_MACRO_start_file: {
964 // Write macinfo type.
965 OutSection.emitIntVal(MacroType, 1);
966 // Write source line.
967 encodeULEB128(MacroEntry.Line, OutSection.OS);
968 // Write source file id.
969 encodeULEB128(MacroEntry.File, OutSection.OS);
970 } break;
971 case dwarf::DW_MACRO_end_file: {
972 // Write macinfo type.
973 OutSection.emitIntVal(MacroType, 1);
974 } break;
975 case dwarf::DW_MACRO_import:
976 case dwarf::DW_MACRO_import_sup: {
977 if (!ImportAttributeIsReported) {
978 warn("DW_MACRO_import and DW_MACRO_import_sup are unsupported "
979 "yet. remove.");
980 ImportAttributeIsReported = true;
982 } break;
986 return;
991 void CompileUnit::cloneDieAttrExpression(
992 const DWARFExpression &InputExpression,
993 SmallVectorImpl<uint8_t> &OutputExpression, SectionDescriptor &Section,
994 std::optional<int64_t> VarAddressAdjustment,
995 OffsetsPtrVector &PatchesOffsets) {
996 using Encoding = DWARFExpression::Operation::Encoding;
998 DWARFUnit &OrigUnit = getOrigUnit();
999 uint8_t OrigAddressByteSize = OrigUnit.getAddressByteSize();
1001 uint64_t OpOffset = 0;
1002 for (auto &Op : InputExpression) {
1003 auto Desc = Op.getDescription();
1004 // DW_OP_const_type is variable-length and has 3
1005 // operands. Thus far we only support 2.
1006 if ((Desc.Op.size() == 2 && Desc.Op[0] == Encoding::BaseTypeRef) ||
1007 (Desc.Op.size() == 2 && Desc.Op[1] == Encoding::BaseTypeRef &&
1008 Desc.Op[0] != Encoding::Size1))
1009 warn("unsupported DW_OP encoding.");
1011 if ((Desc.Op.size() == 1 && Desc.Op[0] == Encoding::BaseTypeRef) ||
1012 (Desc.Op.size() == 2 && Desc.Op[1] == Encoding::BaseTypeRef &&
1013 Desc.Op[0] == Encoding::Size1)) {
1014 // This code assumes that the other non-typeref operand fits into 1 byte.
1015 assert(OpOffset < Op.getEndOffset());
1016 uint32_t ULEBsize = Op.getEndOffset() - OpOffset - 1;
1017 assert(ULEBsize <= 16);
1019 // Copy over the operation.
1020 assert(!Op.getSubCode() && "SubOps not yet supported");
1021 OutputExpression.push_back(Op.getCode());
1022 uint64_t RefOffset;
1023 if (Desc.Op.size() == 1) {
1024 RefOffset = Op.getRawOperand(0);
1025 } else {
1026 OutputExpression.push_back(Op.getRawOperand(0));
1027 RefOffset = Op.getRawOperand(1);
1029 uint8_t ULEB[16];
1030 uint32_t Offset = 0;
1031 unsigned RealSize = 0;
1032 // Look up the base type. For DW_OP_convert, the operand may be 0 to
1033 // instead indicate the generic type. The same holds for
1034 // DW_OP_reinterpret, which is currently not supported.
1035 if (RefOffset > 0 || Op.getCode() != dwarf::DW_OP_convert) {
1036 RefOffset += OrigUnit.getOffset();
1037 uint32_t RefDieIdx = 0;
1038 if (std::optional<uint32_t> Idx =
1039 OrigUnit.getDIEIndexForOffset(RefOffset))
1040 RefDieIdx = *Idx;
1042 // Use fixed size for ULEB128 data, since we need to update that size
1043 // later with the proper offsets. Use 5 for DWARF32, 9 for DWARF64.
1044 ULEBsize = getFormParams().getDwarfOffsetByteSize() + 1;
1046 RealSize = encodeULEB128(0xBADDEF, ULEB, ULEBsize);
1048 Section.notePatchWithOffsetUpdate(
1049 DebugULEB128DieRefPatch(OutputExpression.size(), this, this,
1050 RefDieIdx),
1051 PatchesOffsets);
1052 } else
1053 RealSize = encodeULEB128(Offset, ULEB, ULEBsize);
1055 if (RealSize > ULEBsize) {
1056 // Emit the generic type as a fallback.
1057 RealSize = encodeULEB128(0, ULEB, ULEBsize);
1058 warn("base type ref doesn't fit.");
1060 assert(RealSize == ULEBsize && "padding failed");
1061 ArrayRef<uint8_t> ULEBbytes(ULEB, ULEBsize);
1062 OutputExpression.append(ULEBbytes.begin(), ULEBbytes.end());
1063 } else if (!getGlobalData().getOptions().UpdateIndexTablesOnly &&
1064 Op.getCode() == dwarf::DW_OP_addrx) {
1065 if (std::optional<object::SectionedAddress> SA =
1066 OrigUnit.getAddrOffsetSectionItem(Op.getRawOperand(0))) {
1067 // DWARFLinker does not use addrx forms since it generates relocated
1068 // addresses. Replace DW_OP_addrx with DW_OP_addr here.
1069 // Argument of DW_OP_addrx should be relocated here as it is not
1070 // processed by applyValidRelocs.
1071 OutputExpression.push_back(dwarf::DW_OP_addr);
1072 uint64_t LinkedAddress =
1073 SA->Address + (VarAddressAdjustment ? *VarAddressAdjustment : 0);
1074 if ((getEndianness() == support::endianness::little) !=
1075 sys::IsLittleEndianHost)
1076 sys::swapByteOrder(LinkedAddress);
1077 ArrayRef<uint8_t> AddressBytes(
1078 reinterpret_cast<const uint8_t *>(&LinkedAddress),
1079 OrigAddressByteSize);
1080 OutputExpression.append(AddressBytes.begin(), AddressBytes.end());
1081 } else
1082 warn("cann't read DW_OP_addrx operand.");
1083 } else if (!getGlobalData().getOptions().UpdateIndexTablesOnly &&
1084 Op.getCode() == dwarf::DW_OP_constx) {
1085 if (std::optional<object::SectionedAddress> SA =
1086 OrigUnit.getAddrOffsetSectionItem(Op.getRawOperand(0))) {
1087 // DWARFLinker does not use constx forms since it generates relocated
1088 // addresses. Replace DW_OP_constx with DW_OP_const[*]u here.
1089 // Argument of DW_OP_constx should be relocated here as it is not
1090 // processed by applyValidRelocs.
1091 std::optional<uint8_t> OutOperandKind;
1092 switch (OrigAddressByteSize) {
1093 case 2:
1094 OutOperandKind = dwarf::DW_OP_const2u;
1095 break;
1096 case 4:
1097 OutOperandKind = dwarf::DW_OP_const4u;
1098 break;
1099 case 8:
1100 OutOperandKind = dwarf::DW_OP_const8u;
1101 break;
1102 default:
1103 warn(
1104 formatv(("unsupported address size: {0}."), OrigAddressByteSize));
1105 break;
1108 if (OutOperandKind) {
1109 OutputExpression.push_back(*OutOperandKind);
1110 uint64_t LinkedAddress =
1111 SA->Address + (VarAddressAdjustment ? *VarAddressAdjustment : 0);
1112 if ((getEndianness() == support::endianness::little) !=
1113 sys::IsLittleEndianHost)
1114 sys::swapByteOrder(LinkedAddress);
1115 ArrayRef<uint8_t> AddressBytes(
1116 reinterpret_cast<const uint8_t *>(&LinkedAddress),
1117 OrigAddressByteSize);
1118 OutputExpression.append(AddressBytes.begin(), AddressBytes.end());
1120 } else
1121 warn("cann't read DW_OP_constx operand.");
1122 } else {
1123 // Copy over everything else unmodified.
1124 StringRef Bytes =
1125 InputExpression.getData().slice(OpOffset, Op.getEndOffset());
1126 OutputExpression.append(Bytes.begin(), Bytes.end());
1128 OpOffset = Op.getEndOffset();
1132 Error CompileUnit::cloneAndEmit(std::optional<Triple> TargetTriple) {
1133 BumpPtrAllocator Allocator;
1135 DWARFDie OrigUnitDIE = getOrigUnit().getUnitDIE();
1136 if (!OrigUnitDIE.isValid())
1137 return Error::success();
1139 CanStripTemplateName =
1140 llvm::is_contained(getGlobalData().getOptions().AccelTables,
1141 DWARFLinker::AccelTableKind::Apple);
1143 // Clone input DIE entry recursively.
1144 DIE *OutCUDie =
1145 cloneDIE(OrigUnitDIE.getDebugInfoEntry(), getDebugInfoHeaderSize(),
1146 std::nullopt, std::nullopt, Allocator);
1147 setOutUnitDIE(OutCUDie);
1149 if (getGlobalData().getOptions().NoOutput || (OutCUDie == nullptr))
1150 return Error::success();
1152 assert(TargetTriple.has_value());
1153 if (Error Err = cloneAndEmitLineTable(*TargetTriple))
1154 return Err;
1156 if (Error Err = cloneAndEmitDebugMacro())
1157 return Err;
1159 if (Error Err = emitDebugInfo(*TargetTriple))
1160 return Err;
1162 // ASSUMPTION: .debug_info section should already be emitted at this point.
1163 // cloneAndEmitRanges & cloneAndEmitDebugLocations use .debug_info section
1164 // data.
1166 if (Error Err = cloneAndEmitRanges())
1167 return Err;
1169 if (Error Err = cloneAndEmitDebugLocations())
1170 return Err;
1172 if (Error Err = emitDebugAddrSection())
1173 return Err;
1175 if (Error Err = emitDebugStringOffsetSection())
1176 return Err;
1178 return emitAbbreviations();
1181 bool needToClone(CompileUnit::DIEInfo &Info) {
1182 return Info.getKeep() || Info.getKeepChildren();
1185 DIE *CompileUnit::cloneDIE(const DWARFDebugInfoEntry *InputDieEntry,
1186 uint64_t OutOffset,
1187 std::optional<int64_t> FuncAddressAdjustment,
1188 std::optional<int64_t> VarAddressAdjustment,
1189 BumpPtrAllocator &Allocator) {
1190 uint32_t InputDieIdx = getDIEIndex(InputDieEntry);
1191 CompileUnit::DIEInfo &Info = getDIEInfo(InputDieIdx);
1193 if (!needToClone(Info))
1194 return nullptr;
1196 bool HasLocationExpressionAddress = false;
1197 if (InputDieEntry->getTag() == dwarf::DW_TAG_subprogram) {
1198 // Get relocation adjustment value for the current function.
1199 FuncAddressAdjustment =
1200 getContaingFile().Addresses->getSubprogramRelocAdjustment(
1201 getDIE(InputDieEntry));
1202 } else if (InputDieEntry->getTag() == dwarf::DW_TAG_variable) {
1203 // Get relocation adjustment value for the current variable.
1204 std::pair<bool, std::optional<int64_t>> LocExprAddrAndRelocAdjustment =
1205 getContaingFile().Addresses->getVariableRelocAdjustment(
1206 getDIE(InputDieEntry));
1208 HasLocationExpressionAddress = LocExprAddrAndRelocAdjustment.first;
1209 if (LocExprAddrAndRelocAdjustment.first &&
1210 LocExprAddrAndRelocAdjustment.second)
1211 VarAddressAdjustment = *LocExprAddrAndRelocAdjustment.second;
1214 DIEGenerator DIEGenerator(Allocator, *this);
1215 DIE *ClonedDIE = DIEGenerator.createDIE(InputDieEntry->getTag(), OutOffset);
1216 rememberDieOutOffset(InputDieIdx, OutOffset);
1218 // Clone Attributes.
1219 DIEAttributeCloner AttributesCloner(
1220 ClonedDIE, *this, InputDieEntry, DIEGenerator, FuncAddressAdjustment,
1221 VarAddressAdjustment, HasLocationExpressionAddress);
1222 AttributesCloner.clone();
1224 bool HasChildrenToClone = Info.getKeepChildren();
1225 OutOffset = AttributesCloner.finalizeAbbreviations(HasChildrenToClone);
1227 if (HasChildrenToClone) {
1228 // Recursively clone children.
1229 for (const DWARFDebugInfoEntry *CurChild =
1230 getFirstChildEntry(InputDieEntry);
1231 CurChild && CurChild->getAbbreviationDeclarationPtr();
1232 CurChild = getSiblingEntry(CurChild)) {
1233 if (DIE *ClonedChild =
1234 cloneDIE(CurChild, OutOffset, FuncAddressAdjustment,
1235 VarAddressAdjustment, Allocator)) {
1236 OutOffset = ClonedChild->getOffset() + ClonedChild->getSize();
1237 DIEGenerator.addChild(ClonedChild);
1241 // Account for the end of children marker.
1242 OutOffset += sizeof(int8_t);
1245 // Update our size.
1246 ClonedDIE->setSize(OutOffset - ClonedDIE->getOffset());
1247 return ClonedDIE;
1250 Error CompileUnit::cloneAndEmitLineTable(Triple &TargetTriple) {
1251 const DWARFDebugLine::LineTable *InputLineTable =
1252 getContaingFile().Dwarf->getLineTableForUnit(&getOrigUnit());
1253 if (InputLineTable == nullptr) {
1254 warn("cann't load line table.");
1255 return Error::success();
1258 DWARFDebugLine::LineTable OutLineTable;
1260 // Set Line Table header.
1261 OutLineTable.Prologue = InputLineTable->Prologue;
1262 OutLineTable.Prologue.FormParams.AddrSize = getFormParams().AddrSize;
1264 // Set Line Table Rows.
1265 if (getGlobalData().getOptions().UpdateIndexTablesOnly) {
1266 OutLineTable.Rows = InputLineTable->Rows;
1267 // If all the line table contains is a DW_LNE_end_sequence, clear the line
1268 // table rows, it will be inserted again in the DWARFStreamer.
1269 if (OutLineTable.Rows.size() == 1 && OutLineTable.Rows[0].EndSequence)
1270 OutLineTable.Rows.clear();
1272 OutLineTable.Sequences = InputLineTable->Sequences;
1273 } else {
1274 // This vector is the output line table.
1275 std::vector<DWARFDebugLine::Row> NewRows;
1276 NewRows.reserve(InputLineTable->Rows.size());
1278 // Current sequence of rows being extracted, before being inserted
1279 // in NewRows.
1280 std::vector<DWARFDebugLine::Row> Seq;
1282 const auto &FunctionRanges = getFunctionRanges();
1283 std::optional<AddressRangeValuePair> CurrRange;
1285 // FIXME: This logic is meant to generate exactly the same output as
1286 // Darwin's classic dsymutil. There is a nicer way to implement this
1287 // by simply putting all the relocated line info in NewRows and simply
1288 // sorting NewRows before passing it to emitLineTableForUnit. This
1289 // should be correct as sequences for a function should stay
1290 // together in the sorted output. There are a few corner cases that
1291 // look suspicious though, and that required to implement the logic
1292 // this way. Revisit that once initial validation is finished.
1294 // Iterate over the object file line info and extract the sequences
1295 // that correspond to linked functions.
1296 for (DWARFDebugLine::Row Row : InputLineTable->Rows) {
1297 // Check whether we stepped out of the range. The range is
1298 // half-open, but consider accept the end address of the range if
1299 // it is marked as end_sequence in the input (because in that
1300 // case, the relocation offset is accurate and that entry won't
1301 // serve as the start of another function).
1302 if (!CurrRange || !CurrRange->Range.contains(Row.Address.Address)) {
1303 // We just stepped out of a known range. Insert a end_sequence
1304 // corresponding to the end of the range.
1305 uint64_t StopAddress =
1306 CurrRange ? CurrRange->Range.end() + CurrRange->Value : -1ULL;
1307 CurrRange = FunctionRanges.getRangeThatContains(Row.Address.Address);
1308 if (StopAddress != -1ULL && !Seq.empty()) {
1309 // Insert end sequence row with the computed end address, but
1310 // the same line as the previous one.
1311 auto NextLine = Seq.back();
1312 NextLine.Address.Address = StopAddress;
1313 NextLine.EndSequence = 1;
1314 NextLine.PrologueEnd = 0;
1315 NextLine.BasicBlock = 0;
1316 NextLine.EpilogueBegin = 0;
1317 Seq.push_back(NextLine);
1318 insertLineSequence(Seq, NewRows);
1321 if (!CurrRange)
1322 continue;
1325 // Ignore empty sequences.
1326 if (Row.EndSequence && Seq.empty())
1327 continue;
1329 // Relocate row address and add it to the current sequence.
1330 Row.Address.Address += CurrRange->Value;
1331 Seq.emplace_back(Row);
1333 if (Row.EndSequence)
1334 insertLineSequence(Seq, NewRows);
1337 OutLineTable.Rows = std::move(NewRows);
1340 return emitDebugLine(TargetTriple, OutLineTable);
1343 void CompileUnit::insertLineSequence(std::vector<DWARFDebugLine::Row> &Seq,
1344 std::vector<DWARFDebugLine::Row> &Rows) {
1345 if (Seq.empty())
1346 return;
1348 if (!Rows.empty() && Rows.back().Address < Seq.front().Address) {
1349 llvm::append_range(Rows, Seq);
1350 Seq.clear();
1351 return;
1354 object::SectionedAddress Front = Seq.front().Address;
1355 auto InsertPoint = partition_point(
1356 Rows, [=](const DWARFDebugLine::Row &O) { return O.Address < Front; });
1358 // FIXME: this only removes the unneeded end_sequence if the
1359 // sequences have been inserted in order. Using a global sort like
1360 // described in cloneAndEmitLineTable() and delaying the end_sequene
1361 // elimination to DebugLineEmitter::emit() we can get rid of all of them.
1362 if (InsertPoint != Rows.end() && InsertPoint->Address == Front &&
1363 InsertPoint->EndSequence) {
1364 *InsertPoint = Seq.front();
1365 Rows.insert(InsertPoint + 1, Seq.begin() + 1, Seq.end());
1366 } else {
1367 Rows.insert(InsertPoint, Seq.begin(), Seq.end());
1370 Seq.clear();
1373 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1374 LLVM_DUMP_METHOD void CompileUnit::DIEInfo::dump() {
1375 llvm::errs() << "{\n";
1376 llvm::errs() << " Placement: ";
1377 switch (getPlacement()) {
1378 case NotSet:
1379 llvm::errs() << "NotSet\n";
1380 break;
1381 case TypeTable:
1382 llvm::errs() << "TypeTable\n";
1383 break;
1384 case PlainDwarf:
1385 llvm::errs() << "PlainDwarf\n";
1386 break;
1387 case Both:
1388 llvm::errs() << "Both\n";
1389 break;
1390 case Parent:
1391 llvm::errs() << "Parent\n";
1392 break;
1395 llvm::errs() << " Keep: " << getKeep();
1396 llvm::errs() << " KeepChildren: " << getKeepChildren();
1397 llvm::errs() << " ReferrencedBy: " << getReferrencedBy();
1398 llvm::errs() << " IsInMouduleScope: " << getIsInMouduleScope();
1399 llvm::errs() << " IsInFunctionScope: " << getIsInFunctionScope();
1400 llvm::errs() << "}\n";
1402 #endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)