1 //=== DWARFLinkerCompileUnit.cpp ------------------------------------------===//
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
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"
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
)
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();
41 if (getStage() < Stage::Cloned
) {
42 setStage(Stage::Loaded
);
46 AbbreviationsSet
.clear();
47 Abbreviations
.clear();
49 DebugAddrIndexMap
.clear();
51 for (uint64_t &Offset
: OutDieOffsetArray
)
55 setStage(Stage::CreatedNotLoaded
);
58 bool CompileUnit::loadInputDIEs() {
59 DWARFDie InputUnitDIE
= getUnitDIE(false);
63 // load input dies, resize Info structures array.
64 DieInfoArray
.resize(getOrigUnit().getNumDIEs());
65 OutDieOffsetArray
.resize(getOrigUnit().getNumDIEs(), 0);
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
);
77 ChildInfo
.setIsInMouduleScope();
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
), "") !=
87 analyzeImportedModule(CurChild
);
89 case dwarf::DW_TAG_subprogram
:
90 ChildInfo
.setIsInFunctionScope();
97 ChildInfo
.setIsInMouduleScope();
99 ChildInfo
.setIsInFunctionScope();
101 if (CurChild
->hasChildren())
102 analyzeDWARFStructureRec(CurChild
, ChildInfo
.getIsInMouduleScope(),
103 ChildInfo
.getIsInFunctionScope());
107 StringEntry
*CompileUnit::getFileName(unsigned FileIdx
,
108 StringPool
&GlobalStrings
) {
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
,
121 assert(FoundFileName
&& "Must get file name from line table");
123 // Second level of caching, this time based on the file's parent
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
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
);
137 .insert({ParentPath
, GlobalStrings
.insert(RealPath
).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
))
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
)
173 if (!GlobalData
.getOptions().ParseableSwiftInterfaces
)
177 dwarf::toStringRef(find(DieEntry
, dwarf::DW_AT_LLVM_include_path
));
178 if (!Path
.endswith(".swiftinterface"))
180 // Don't track interfaces that are part of the SDK.
182 dwarf::toStringRef(find(DieEntry
, dwarf::DW_AT_LLVM_sysroot
));
184 SysRoot
= getSysRoot();
185 if (!SysRoot
.empty() && Path
.startswith(SysRoot
))
187 if (std::optional
<DWARFFormValue
> Val
= find(DieEntry
, dwarf::DW_AT_name
)) {
188 Expected
<const char *> Name
= Val
->getAsCString();
190 warn(Name
.takeError());
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
))
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
+ ".",
208 Entry
= std::string(ResolvedPath
.str());
212 void CompileUnit::updateDieRefPatchesWithClonedOffsets() {
213 if (std::optional
<SectionDescriptor
*> DebugInfoSection
=
214 getSectionDescriptor(DebugSectionKind::DebugInfo
)) {
217 ->ListDebugDieRefPatch
.forEach([](DebugDieRefPatch
&Patch
) {
218 Patch
.RefDieIdxOrClonedOffset
=
219 Patch
.RefCU
.getPointer()->getDieOutOffset(
220 Patch
.RefDieIdxOrClonedOffset
);
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
)) {
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
);
282 void CompileUnit::addFunctionRange(uint64_t FuncLowPc
, uint64_t FuncHighPc
,
284 std::lock_guard
<std::mutex
> Guard(RangesMutex
);
286 Ranges
.insert({FuncLowPc
, FuncHighPc
}, PcOffset
);
288 LowPc
= std::min(*LowPc
, FuncLowPc
+ PcOffset
);
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(
328 DebugInfoSection
.getFormParams().getDwarfOffsetByteSize());
329 Expected
<DWARFLocationExpressionsVector
> OriginalLocations
=
330 OrigUnit
.findLoclistFromOffset(InputDebugLocSectionOffset
);
332 if (!OriginalLocations
) {
333 warn(OriginalLocations
.takeError());
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)
386 OutLocationSection
.emitUnitLength(0xBADDEF);
387 uint64_t OffsetAfterUnitLength
= OutLocationSection
.OS
.tell();
390 OutLocationSection
.emitIntVal(5, 2);
393 OutLocationSection
.emitIntVal(OutLocationSection
.getFormParams().AddrSize
, 1);
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.
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
);
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.
504 OutAddrSection
.emitUnitLength(0xBADDEF);
505 uint64_t OffsetAfterSectionLength
= OutAddrSection
.OS
.tell();
508 OutAddrSection
.emitIntVal(5, 2);
510 // Emit address size.
511 OutAddrSection
.emitIntVal(getFormParams().AddrSize
, 1);
513 // Emit segment size.
514 OutAddrSection
.emitIntVal(0, 1);
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.
543 OutDebugStrOffsetsSection
.emitUnitLength(0xBADDEF);
544 uint64_t OffsetAfterSectionLength
= OutDebugStrOffsetsSection
.OS
.tell();
547 OutDebugStrOffsetsSection
.emitIntVal(5, 2);
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
;
609 // Get ranges from the source DWARF corresponding to the current
611 AddressRanges LinkedRanges
;
612 uint64_t InputDebugRangesSectionOffset
= DebugInfoSection
.getIntVal(
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
))
622 getFunctionRanges().getRangeThatContains(Range
.LowPC
);
624 // All range entries should lie in the function range.
626 warn("inconsistent range data.");
630 // Store range for emiting.
631 LinkedRanges
.insert({Range
.LowPC
+ CachedRange
->Value
,
632 Range
.HighPC
+ CachedRange
->Value
});
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
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)
673 OutRangeSection
.emitUnitLength(0xBADDEF);
674 uint64_t OffsetAfterUnitLength
= OutRangeSection
.OS
.tell();
677 OutRangeSection
.emitIntVal(5, 2);
680 OutRangeSection
.emitIntVal(OutRangeSection
.getFormParams().AddrSize
, 1);
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) {
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
);
712 std::optional
<uint64_t> BaseAddress
;
713 for (const AddressRange
&Range
: LinkedRanges
) {
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())
740 SectionDescriptor
&DebugInfoSection
=
741 getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo
);
742 SectionDescriptor
&OutArangesSection
=
743 getOrCreateSectionDescriptor(DebugSectionKind::DebugARanges
);
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
,
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
);
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
=
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.
843 DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE
) {
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();
860 if (!StmtListOffset
) {
861 Flags
&= ~DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET
;
862 warn("couldn`t find line table for macro table.");
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
);
887 uint8_t MacroType
= MacroEntry
.Type
;
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
);
906 warn("unknown macro type. skip.");
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
);
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.
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;
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;
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
);
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
);
971 case dwarf::DW_MACRO_end_file
: {
972 // Write macinfo type.
973 OutSection
.emitIntVal(MacroType
, 1);
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 "
980 ImportAttributeIsReported
= true;
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());
1023 if (Desc
.Op
.size() == 1) {
1024 RefOffset
= Op
.getRawOperand(0);
1026 OutputExpression
.push_back(Op
.getRawOperand(0));
1027 RefOffset
= Op
.getRawOperand(1);
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
))
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,
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());
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
) {
1094 OutOperandKind
= dwarf::DW_OP_const2u
;
1097 OutOperandKind
= dwarf::DW_OP_const4u
;
1100 OutOperandKind
= dwarf::DW_OP_const8u
;
1104 formatv(("unsupported address size: {0}."), OrigAddressByteSize
));
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());
1121 warn("cann't read DW_OP_constx operand.");
1123 // Copy over everything else unmodified.
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.
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
))
1156 if (Error Err
= cloneAndEmitDebugMacro())
1159 if (Error Err
= emitDebugInfo(*TargetTriple
))
1162 // ASSUMPTION: .debug_info section should already be emitted at this point.
1163 // cloneAndEmitRanges & cloneAndEmitDebugLocations use .debug_info section
1166 if (Error Err
= cloneAndEmitRanges())
1169 if (Error Err
= cloneAndEmitDebugLocations())
1172 if (Error Err
= emitDebugAddrSection())
1175 if (Error Err
= emitDebugStringOffsetSection())
1178 return emitAbbreviations();
1181 bool needToClone(CompileUnit::DIEInfo
&Info
) {
1182 return Info
.getKeep() || Info
.getKeepChildren();
1185 DIE
*CompileUnit::cloneDIE(const DWARFDebugInfoEntry
*InputDieEntry
,
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
))
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);
1246 ClonedDIE
->setSize(OutOffset
- ClonedDIE
->getOffset());
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
;
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
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
);
1325 // Ignore empty sequences.
1326 if (Row
.EndSequence
&& Seq
.empty())
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
) {
1348 if (!Rows
.empty() && Rows
.back().Address
< Seq
.front().Address
) {
1349 llvm::append_range(Rows
, Seq
);
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());
1367 Rows
.insert(InsertPoint
, Seq
.begin(), Seq
.end());
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()) {
1379 llvm::errs() << "NotSet\n";
1382 llvm::errs() << "TypeTable\n";
1385 llvm::errs() << "PlainDwarf\n";
1388 llvm::errs() << "Both\n";
1391 llvm::errs() << "Parent\n";
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)