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 "AcceleratorRecordsSaver.h"
11 #include "DIEAttributeCloner.h"
12 #include "DIEGenerator.h"
13 #include "DependencyTracker.h"
14 #include "SyntheticTypeNameBuilder.h"
15 #include "llvm/DWARFLinker/Utils.h"
16 #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
17 #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
18 #include "llvm/Support/DJB.h"
19 #include "llvm/Support/FileSystem.h"
20 #include "llvm/Support/FormatVariadic.h"
21 #include "llvm/Support/Path.h"
25 using namespace dwarf_linker
;
26 using namespace dwarf_linker::parallel
;
28 CompileUnit::CompileUnit(LinkingGlobalData
&GlobalData
, unsigned ID
,
29 StringRef ClangModuleName
, DWARFFile
&File
,
30 OffsetToUnitTy UnitFromOffset
,
31 dwarf::FormParams Format
, llvm::endianness Endianess
)
32 : DwarfUnit(GlobalData
, ID
, ClangModuleName
), File(File
),
33 getUnitFromOffset(UnitFromOffset
), Stage(Stage::CreatedNotLoaded
),
34 AcceleratorRecords(&GlobalData
.getAllocator()) {
35 UnitName
= File
.FileName
;
36 setOutputFormat(Format
, Endianess
);
37 getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo
);
40 CompileUnit::CompileUnit(LinkingGlobalData
&GlobalData
, DWARFUnit
&OrigUnit
,
41 unsigned ID
, StringRef ClangModuleName
,
42 DWARFFile
&File
, OffsetToUnitTy UnitFromOffset
,
43 dwarf::FormParams Format
, llvm::endianness Endianess
)
44 : DwarfUnit(GlobalData
, ID
, ClangModuleName
), File(File
),
45 OrigUnit(&OrigUnit
), getUnitFromOffset(UnitFromOffset
),
46 Stage(Stage::CreatedNotLoaded
),
47 AcceleratorRecords(&GlobalData
.getAllocator()) {
48 setOutputFormat(Format
, Endianess
);
49 getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo
);
51 DWARFDie CUDie
= OrigUnit
.getUnitDIE();
55 if (std::optional
<DWARFFormValue
> Val
= CUDie
.find(dwarf::DW_AT_language
)) {
56 uint16_t LangVal
= dwarf::toUnsigned(Val
, 0);
57 if (isODRLanguage(LangVal
))
61 if (!GlobalData
.getOptions().NoODR
&& Language
.has_value())
64 if (const char *CUName
= CUDie
.getName(DINameKind::ShortName
))
67 UnitName
= File
.FileName
;
68 SysRoot
= dwarf::toStringRef(CUDie
.find(dwarf::DW_AT_LLVM_sysroot
)).str();
71 void CompileUnit::loadLineTable() {
72 LineTablePtr
= File
.Dwarf
->getLineTableForUnit(&getOrigUnit());
75 void CompileUnit::maybeResetToLoadedStage() {
76 // Nothing to reset if stage is less than "Loaded".
77 if (getStage() < Stage::Loaded
)
80 // Note: We need to do erasing for "Loaded" stage because
81 // if live analysys failed then we will have "Loaded" stage
82 // with marking from "LivenessAnalysisDone" stage partially
83 // done. That marking should be cleared.
85 for (DIEInfo
&Info
: DieInfoArray
)
86 Info
.unsetFlagsWhichSetDuringLiveAnalysis();
92 Dependencies
.reset(nullptr);
94 if (getStage() < Stage::Cloned
) {
95 setStage(Stage::Loaded
);
99 AcceleratorRecords
.erase();
100 AbbreviationsSet
.clear();
101 Abbreviations
.clear();
102 OutUnitDIE
= nullptr;
103 DebugAddrIndexMap
.clear();
105 for (uint64_t &Offset
: OutDieOffsetArray
)
107 for (TypeEntry
*&Name
: TypeEntries
)
111 setStage(Stage::CreatedNotLoaded
);
114 bool CompileUnit::loadInputDIEs() {
115 DWARFDie InputUnitDIE
= getUnitDIE(false);
119 // load input dies, resize Info structures array.
120 DieInfoArray
.resize(getOrigUnit().getNumDIEs());
121 OutDieOffsetArray
.resize(getOrigUnit().getNumDIEs(), 0);
123 TypeEntries
.resize(getOrigUnit().getNumDIEs());
127 void CompileUnit::analyzeDWARFStructureRec(const DWARFDebugInfoEntry
*DieEntry
,
128 bool IsODRUnavailableFunctionScope
) {
129 CompileUnit::DIEInfo
&DieInfo
= getDIEInfo(DieEntry
);
131 for (const DWARFDebugInfoEntry
*CurChild
= getFirstChildEntry(DieEntry
);
132 CurChild
&& CurChild
->getAbbreviationDeclarationPtr();
133 CurChild
= getSiblingEntry(CurChild
)) {
134 CompileUnit::DIEInfo
&ChildInfo
= getDIEInfo(CurChild
);
135 bool ChildIsODRUnavailableFunctionScope
= IsODRUnavailableFunctionScope
;
137 if (DieInfo
.getIsInMouduleScope())
138 ChildInfo
.setIsInMouduleScope();
140 if (DieInfo
.getIsInFunctionScope())
141 ChildInfo
.setIsInFunctionScope();
143 if (DieInfo
.getIsInAnonNamespaceScope())
144 ChildInfo
.setIsInAnonNamespaceScope();
146 switch (CurChild
->getTag()) {
147 case dwarf::DW_TAG_module
:
148 ChildInfo
.setIsInMouduleScope();
149 if (DieEntry
->getTag() == dwarf::DW_TAG_compile_unit
&&
150 dwarf::toString(find(CurChild
, dwarf::DW_AT_name
), "") !=
151 getClangModuleName())
152 analyzeImportedModule(CurChild
);
154 case dwarf::DW_TAG_subprogram
:
155 ChildInfo
.setIsInFunctionScope();
156 if (!ChildIsODRUnavailableFunctionScope
&&
157 !ChildInfo
.getIsInMouduleScope()) {
159 {dwarf::DW_AT_abstract_origin
, dwarf::DW_AT_specification
}))
160 ChildIsODRUnavailableFunctionScope
= true;
163 case dwarf::DW_TAG_namespace
: {
164 UnitEntryPairTy NamespaceEntry
= {this, CurChild
};
166 if (find(CurChild
, dwarf::DW_AT_extension
))
167 NamespaceEntry
= NamespaceEntry
.getNamespaceOrigin();
169 if (!NamespaceEntry
.CU
->find(NamespaceEntry
.DieEntry
, dwarf::DW_AT_name
))
170 ChildInfo
.setIsInAnonNamespaceScope();
176 if (!isClangModule() && !getGlobalData().getOptions().UpdateIndexTablesOnly
)
177 ChildInfo
.setTrackLiveness();
179 if ((!ChildInfo
.getIsInAnonNamespaceScope() &&
180 !ChildIsODRUnavailableFunctionScope
&& !NoODR
))
181 ChildInfo
.setODRAvailable();
183 if (CurChild
->hasChildren())
184 analyzeDWARFStructureRec(CurChild
, ChildIsODRUnavailableFunctionScope
);
188 StringEntry
*CompileUnit::getFileName(unsigned FileIdx
,
189 StringPool
&GlobalStrings
) {
191 if (LineTablePtr
->hasFileAtIndex(FileIdx
)) {
192 // Cache the resolved paths based on the index in the line table,
193 // because calling realpath is expensive.
194 ResolvedPathsMap::const_iterator It
= ResolvedFullPaths
.find(FileIdx
);
195 if (It
== ResolvedFullPaths
.end()) {
196 std::string OrigFileName
;
197 bool FoundFileName
= LineTablePtr
->getFileNameByIndex(
198 FileIdx
, getOrigUnit().getCompilationDir(),
199 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath
,
202 assert(FoundFileName
&& "Must get file name from line table");
204 // Second level of caching, this time based on the file's parent
206 StringRef FileName
= sys::path::filename(OrigFileName
);
207 StringRef ParentPath
= sys::path::parent_path(OrigFileName
);
209 // If the ParentPath has not yet been resolved, resolve and cache it for
211 StringMap
<StringEntry
*>::iterator ParentIt
=
212 ResolvedParentPaths
.find(ParentPath
);
213 if (ParentIt
== ResolvedParentPaths
.end()) {
214 SmallString
<256> RealPath
;
215 sys::fs::real_path(ParentPath
, RealPath
);
218 .insert({ParentPath
, GlobalStrings
.insert(RealPath
).first
})
222 // Join the file name again with the resolved path.
223 SmallString
<256> ResolvedPath(ParentIt
->second
->first());
224 sys::path::append(ResolvedPath
, FileName
);
226 It
= ResolvedFullPaths
227 .insert(std::make_pair(
228 FileIdx
, GlobalStrings
.insert(ResolvedPath
).first
))
239 void CompileUnit::cleanupDataAfterClonning() {
240 AbbreviationsSet
.clear();
241 ResolvedFullPaths
.shrink_and_clear();
242 ResolvedParentPaths
.clear();
243 FileNames
.shrink_and_clear();
244 DieInfoArray
= SmallVector
<DIEInfo
>();
245 OutDieOffsetArray
= SmallVector
<uint64_t>();
246 TypeEntries
= SmallVector
<TypeEntry
*>();
247 Dependencies
.reset(nullptr);
248 getOrigUnit().clear();
251 /// Collect references to parseable Swift interfaces in imported
252 /// DW_TAG_module blocks.
253 void CompileUnit::analyzeImportedModule(const DWARFDebugInfoEntry
*DieEntry
) {
254 if (!Language
|| Language
!= dwarf::DW_LANG_Swift
)
257 if (!GlobalData
.getOptions().ParseableSwiftInterfaces
)
261 dwarf::toStringRef(find(DieEntry
, dwarf::DW_AT_LLVM_include_path
));
262 if (!Path
.ends_with(".swiftinterface"))
264 // Don't track interfaces that are part of the SDK.
266 dwarf::toStringRef(find(DieEntry
, dwarf::DW_AT_LLVM_sysroot
));
268 SysRoot
= getSysRoot();
269 if (!SysRoot
.empty() && Path
.starts_with(SysRoot
))
271 // Don't track interfaces that are part of the toolchain.
272 // For example: Swift, _Concurrency, ...
273 StringRef DeveloperDir
= guessDeveloperDir(SysRoot
);
274 if (!DeveloperDir
.empty() && Path
.starts_with(DeveloperDir
))
276 if (isInToolchainDir(Path
))
278 if (std::optional
<DWARFFormValue
> Val
= find(DieEntry
, dwarf::DW_AT_name
)) {
279 Expected
<const char *> Name
= Val
->getAsCString();
281 warn(Name
.takeError());
285 auto &Entry
= (*GlobalData
.getOptions().ParseableSwiftInterfaces
)[*Name
];
286 // The prepend path is applied later when copying.
287 SmallString
<128> ResolvedPath
;
288 if (sys::path::is_relative(Path
))
291 dwarf::toString(getUnitDIE().find(dwarf::DW_AT_comp_dir
), ""));
292 sys::path::append(ResolvedPath
, Path
);
293 if (!Entry
.empty() && Entry
!= ResolvedPath
) {
294 DWARFDie Die
= getDIE(DieEntry
);
295 warn(Twine("conflicting parseable interfaces for Swift Module ") + *Name
+
296 ": " + Entry
+ " and " + Path
+ ".",
299 Entry
= std::string(ResolvedPath
);
303 Error
CompileUnit::assignTypeNames(TypePool
&TypePoolRef
) {
304 if (!getUnitDIE().isValid())
305 return Error::success();
307 SyntheticTypeNameBuilder
NameBuilder(TypePoolRef
);
308 return assignTypeNamesRec(getDebugInfoEntry(0), NameBuilder
);
311 Error
CompileUnit::assignTypeNamesRec(const DWARFDebugInfoEntry
*DieEntry
,
312 SyntheticTypeNameBuilder
&NameBuilder
) {
313 OrderedChildrenIndexAssigner
ChildrenIndexAssigner(*this, DieEntry
);
314 for (const DWARFDebugInfoEntry
*CurChild
= getFirstChildEntry(DieEntry
);
315 CurChild
&& CurChild
->getAbbreviationDeclarationPtr();
316 CurChild
= getSiblingEntry(CurChild
)) {
317 CompileUnit::DIEInfo
&ChildInfo
= getDIEInfo(CurChild
);
318 if (!ChildInfo
.needToPlaceInTypeTable())
321 assert(ChildInfo
.getODRAvailable());
322 if (Error Err
= NameBuilder
.assignName(
324 ChildrenIndexAssigner
.getChildIndex(*this, CurChild
)))
327 if (Error Err
= assignTypeNamesRec(CurChild
, NameBuilder
))
331 return Error::success();
334 void CompileUnit::updateDieRefPatchesWithClonedOffsets() {
335 if (std::optional
<SectionDescriptor
*> DebugInfoSection
=
336 tryGetSectionDescriptor(DebugSectionKind::DebugInfo
)) {
339 ->ListDebugDieRefPatch
.forEach([&](DebugDieRefPatch
&Patch
) {
340 /// Replace stored DIE indexes with DIE output offsets.
341 Patch
.RefDieIdxOrClonedOffset
=
342 Patch
.RefCU
.getPointer()->getDieOutOffset(
343 Patch
.RefDieIdxOrClonedOffset
);
347 ->ListDebugULEB128DieRefPatch
.forEach(
348 [&](DebugULEB128DieRefPatch
&Patch
) {
349 /// Replace stored DIE indexes with DIE output offsets.
350 Patch
.RefDieIdxOrClonedOffset
=
351 Patch
.RefCU
.getPointer()->getDieOutOffset(
352 Patch
.RefDieIdxOrClonedOffset
);
356 if (std::optional
<SectionDescriptor
*> DebugLocSection
=
357 tryGetSectionDescriptor(DebugSectionKind::DebugLoc
)) {
359 ->ListDebugULEB128DieRefPatch
.forEach(
360 [](DebugULEB128DieRefPatch
&Patch
) {
361 /// Replace stored DIE indexes with DIE output offsets.
362 Patch
.RefDieIdxOrClonedOffset
=
363 Patch
.RefCU
.getPointer()->getDieOutOffset(
364 Patch
.RefDieIdxOrClonedOffset
);
368 if (std::optional
<SectionDescriptor
*> DebugLocListsSection
=
369 tryGetSectionDescriptor(DebugSectionKind::DebugLocLists
)) {
370 (*DebugLocListsSection
)
371 ->ListDebugULEB128DieRefPatch
.forEach(
372 [](DebugULEB128DieRefPatch
&Patch
) {
373 /// Replace stored DIE indexes with DIE output offsets.
374 Patch
.RefDieIdxOrClonedOffset
=
375 Patch
.RefCU
.getPointer()->getDieOutOffset(
376 Patch
.RefDieIdxOrClonedOffset
);
381 std::optional
<UnitEntryPairTy
> CompileUnit::resolveDIEReference(
382 const DWARFFormValue
&RefValue
,
383 ResolveInterCUReferencesMode CanResolveInterCUReferences
) {
385 uint64_t RefDIEOffset
;
386 if (std::optional
<uint64_t> Offset
= RefValue
.getAsRelativeReference()) {
388 RefDIEOffset
= RefValue
.getUnit()->getOffset() + *Offset
;
389 } else if (Offset
= RefValue
.getAsDebugInfoReference(); Offset
) {
390 RefCU
= getUnitFromOffset(*Offset
);
391 RefDIEOffset
= *Offset
;
397 // Referenced DIE is in current compile unit.
398 if (std::optional
<uint32_t> RefDieIdx
= getDIEIndexForOffset(RefDIEOffset
))
399 return UnitEntryPairTy
{this, getDebugInfoEntry(*RefDieIdx
)};
400 } else if (RefCU
&& CanResolveInterCUReferences
) {
401 // Referenced DIE is in other compile unit.
403 // Check whether DIEs are loaded for that compile unit.
404 enum Stage ReferredCUStage
= RefCU
->getStage();
405 if (ReferredCUStage
< Stage::Loaded
|| ReferredCUStage
> Stage::Cloned
)
406 return UnitEntryPairTy
{RefCU
, nullptr};
408 if (std::optional
<uint32_t> RefDieIdx
=
409 RefCU
->getDIEIndexForOffset(RefDIEOffset
))
410 return UnitEntryPairTy
{RefCU
, RefCU
->getDebugInfoEntry(*RefDieIdx
)};
412 return UnitEntryPairTy
{RefCU
, nullptr};
417 std::optional
<UnitEntryPairTy
> CompileUnit::resolveDIEReference(
418 const DWARFDebugInfoEntry
*DieEntry
, dwarf::Attribute Attr
,
419 ResolveInterCUReferencesMode CanResolveInterCUReferences
) {
420 if (std::optional
<DWARFFormValue
> AttrVal
= find(DieEntry
, Attr
))
421 return resolveDIEReference(*AttrVal
, CanResolveInterCUReferences
);
426 void CompileUnit::addFunctionRange(uint64_t FuncLowPc
, uint64_t FuncHighPc
,
428 std::lock_guard
<std::mutex
> Guard(RangesMutex
);
430 Ranges
.insert({FuncLowPc
, FuncHighPc
}, PcOffset
);
432 LowPc
= std::min(*LowPc
, FuncLowPc
+ PcOffset
);
434 LowPc
= FuncLowPc
+ PcOffset
;
435 this->HighPc
= std::max(HighPc
, FuncHighPc
+ PcOffset
);
438 void CompileUnit::addLabelLowPc(uint64_t LabelLowPc
, int64_t PcOffset
) {
439 std::lock_guard
<std::mutex
> Guard(LabelsMutex
);
440 Labels
.insert({LabelLowPc
, PcOffset
});
443 Error
CompileUnit::cloneAndEmitDebugLocations() {
444 if (getGlobalData().getOptions().UpdateIndexTablesOnly
)
445 return Error::success();
447 if (getOrigUnit().getVersion() < 5) {
448 emitLocations(DebugSectionKind::DebugLoc
);
449 return Error::success();
452 emitLocations(DebugSectionKind::DebugLocLists
);
453 return Error::success();
456 void CompileUnit::emitLocations(DebugSectionKind LocationSectionKind
) {
457 SectionDescriptor
&DebugInfoSection
=
458 getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo
);
460 if (!DebugInfoSection
.ListDebugLocPatch
.empty()) {
461 SectionDescriptor
&OutLocationSection
=
462 getOrCreateSectionDescriptor(LocationSectionKind
);
463 DWARFUnit
&OrigUnit
= getOrigUnit();
465 uint64_t OffsetAfterUnitLength
= emitLocListHeader(OutLocationSection
);
467 DebugInfoSection
.ListDebugLocPatch
.forEach([&](DebugLocPatch
&Patch
) {
468 // Get location expressions vector corresponding to the current
469 // attribute from the source DWARF.
470 uint64_t InputDebugLocSectionOffset
= DebugInfoSection
.getIntVal(
472 DebugInfoSection
.getFormParams().getDwarfOffsetByteSize());
473 Expected
<DWARFLocationExpressionsVector
> OriginalLocations
=
474 OrigUnit
.findLoclistFromOffset(InputDebugLocSectionOffset
);
476 if (!OriginalLocations
) {
477 warn(OriginalLocations
.takeError());
481 LinkedLocationExpressionsVector LinkedLocationExpressions
;
482 for (DWARFLocationExpression
&CurExpression
: *OriginalLocations
) {
483 LinkedLocationExpressionsWithOffsetPatches LinkedExpression
;
485 if (CurExpression
.Range
) {
486 // Relocate address range.
487 LinkedExpression
.Expression
.Range
= {
488 CurExpression
.Range
->LowPC
+ Patch
.AddrAdjustmentValue
,
489 CurExpression
.Range
->HighPC
+ Patch
.AddrAdjustmentValue
};
492 DataExtractor
Data(CurExpression
.Expr
, OrigUnit
.isLittleEndian(),
493 OrigUnit
.getAddressByteSize());
495 DWARFExpression
InputExpression(Data
, OrigUnit
.getAddressByteSize(),
496 OrigUnit
.getFormParams().Format
);
497 cloneDieAttrExpression(InputExpression
,
498 LinkedExpression
.Expression
.Expr
,
499 OutLocationSection
, Patch
.AddrAdjustmentValue
,
500 LinkedExpression
.Patches
);
502 LinkedLocationExpressions
.push_back({LinkedExpression
});
505 // Emit locations list table fragment corresponding to the CurLocAttr.
506 DebugInfoSection
.apply(Patch
.PatchOffset
, dwarf::DW_FORM_sec_offset
,
507 OutLocationSection
.OS
.tell());
508 emitLocListFragment(LinkedLocationExpressions
, OutLocationSection
);
511 if (OffsetAfterUnitLength
> 0) {
512 assert(OffsetAfterUnitLength
-
513 OutLocationSection
.getFormParams().getDwarfOffsetByteSize() <
514 OffsetAfterUnitLength
);
515 OutLocationSection
.apply(
516 OffsetAfterUnitLength
-
517 OutLocationSection
.getFormParams().getDwarfOffsetByteSize(),
518 dwarf::DW_FORM_sec_offset
,
519 OutLocationSection
.OS
.tell() - OffsetAfterUnitLength
);
524 /// Emit debug locations(.debug_loc, .debug_loclists) header.
525 uint64_t CompileUnit::emitLocListHeader(SectionDescriptor
&OutLocationSection
) {
526 if (getOrigUnit().getVersion() < 5)
530 OutLocationSection
.emitUnitLength(0xBADDEF);
531 uint64_t OffsetAfterUnitLength
= OutLocationSection
.OS
.tell();
534 OutLocationSection
.emitIntVal(5, 2);
537 OutLocationSection
.emitIntVal(OutLocationSection
.getFormParams().AddrSize
, 1);
540 OutLocationSection
.emitIntVal(0, 1);
542 // Offset entry count
543 OutLocationSection
.emitIntVal(0, 4);
545 return OffsetAfterUnitLength
;
548 /// Emit debug locations(.debug_loc, .debug_loclists) fragment.
549 uint64_t CompileUnit::emitLocListFragment(
550 const LinkedLocationExpressionsVector
&LinkedLocationExpression
,
551 SectionDescriptor
&OutLocationSection
) {
552 uint64_t OffsetBeforeLocationExpression
= 0;
554 if (getOrigUnit().getVersion() < 5) {
555 uint64_t BaseAddress
= 0;
556 if (std::optional
<uint64_t> LowPC
= getLowPc())
557 BaseAddress
= *LowPC
;
559 for (const LinkedLocationExpressionsWithOffsetPatches
&LocExpression
:
560 LinkedLocationExpression
) {
561 if (LocExpression
.Expression
.Range
) {
562 OutLocationSection
.emitIntVal(
563 LocExpression
.Expression
.Range
->LowPC
- BaseAddress
,
564 OutLocationSection
.getFormParams().AddrSize
);
565 OutLocationSection
.emitIntVal(
566 LocExpression
.Expression
.Range
->HighPC
- BaseAddress
,
567 OutLocationSection
.getFormParams().AddrSize
);
570 OutLocationSection
.emitIntVal(LocExpression
.Expression
.Expr
.size(), 2);
571 OffsetBeforeLocationExpression
= OutLocationSection
.OS
.tell();
572 for (uint64_t *OffsetPtr
: LocExpression
.Patches
)
573 *OffsetPtr
+= OffsetBeforeLocationExpression
;
575 OutLocationSection
.OS
576 << StringRef((const char *)LocExpression
.Expression
.Expr
.data(),
577 LocExpression
.Expression
.Expr
.size());
580 // Emit the terminator entry.
581 OutLocationSection
.emitIntVal(0,
582 OutLocationSection
.getFormParams().AddrSize
);
583 OutLocationSection
.emitIntVal(0,
584 OutLocationSection
.getFormParams().AddrSize
);
585 return OffsetBeforeLocationExpression
;
588 std::optional
<uint64_t> BaseAddress
;
589 for (const LinkedLocationExpressionsWithOffsetPatches
&LocExpression
:
590 LinkedLocationExpression
) {
591 if (LocExpression
.Expression
.Range
) {
592 // Check whether base address is set. If it is not set yet
593 // then set current base address and emit base address selection entry.
595 BaseAddress
= LocExpression
.Expression
.Range
->LowPC
;
597 // Emit base address.
598 OutLocationSection
.emitIntVal(dwarf::DW_LLE_base_addressx
, 1);
599 encodeULEB128(DebugAddrIndexMap
.getValueIndex(*BaseAddress
),
600 OutLocationSection
.OS
);
603 // Emit type of entry.
604 OutLocationSection
.emitIntVal(dwarf::DW_LLE_offset_pair
, 1);
606 // Emit start offset relative to base address.
607 encodeULEB128(LocExpression
.Expression
.Range
->LowPC
- *BaseAddress
,
608 OutLocationSection
.OS
);
610 // Emit end offset relative to base address.
611 encodeULEB128(LocExpression
.Expression
.Range
->HighPC
- *BaseAddress
,
612 OutLocationSection
.OS
);
614 // Emit type of entry.
615 OutLocationSection
.emitIntVal(dwarf::DW_LLE_default_location
, 1);
617 encodeULEB128(LocExpression
.Expression
.Expr
.size(), OutLocationSection
.OS
);
618 OffsetBeforeLocationExpression
= OutLocationSection
.OS
.tell();
619 for (uint64_t *OffsetPtr
: LocExpression
.Patches
)
620 *OffsetPtr
+= OffsetBeforeLocationExpression
;
622 OutLocationSection
.OS
<< StringRef(
623 (const char *)LocExpression
.Expression
.Expr
.data(),
624 LocExpression
.Expression
.Expr
.size());
627 // Emit the terminator entry.
628 OutLocationSection
.emitIntVal(dwarf::DW_LLE_end_of_list
, 1);
629 return OffsetBeforeLocationExpression
;
632 Error
CompileUnit::emitDebugAddrSection() {
633 if (GlobalData
.getOptions().UpdateIndexTablesOnly
)
634 return Error::success();
636 if (getVersion() < 5)
637 return Error::success();
639 if (DebugAddrIndexMap
.empty())
640 return Error::success();
642 SectionDescriptor
&OutAddrSection
=
643 getOrCreateSectionDescriptor(DebugSectionKind::DebugAddr
);
645 // Emit section header.
648 OutAddrSection
.emitUnitLength(0xBADDEF);
649 uint64_t OffsetAfterSectionLength
= OutAddrSection
.OS
.tell();
652 OutAddrSection
.emitIntVal(5, 2);
654 // Emit address size.
655 OutAddrSection
.emitIntVal(getFormParams().AddrSize
, 1);
657 // Emit segment size.
658 OutAddrSection
.emitIntVal(0, 1);
661 for (uint64_t AddrValue
: DebugAddrIndexMap
.getValues())
662 OutAddrSection
.emitIntVal(AddrValue
, getFormParams().AddrSize
);
664 // Patch section length.
665 OutAddrSection
.apply(
666 OffsetAfterSectionLength
-
667 OutAddrSection
.getFormParams().getDwarfOffsetByteSize(),
668 dwarf::DW_FORM_sec_offset
,
669 OutAddrSection
.OS
.tell() - OffsetAfterSectionLength
);
671 return Error::success();
674 Error
CompileUnit::cloneAndEmitRanges() {
675 if (getGlobalData().getOptions().UpdateIndexTablesOnly
)
676 return Error::success();
678 // Build set of linked address ranges for unit function ranges.
679 AddressRanges LinkedFunctionRanges
;
680 for (const AddressRangeValuePair
&Range
: getFunctionRanges())
681 LinkedFunctionRanges
.insert(
682 {Range
.Range
.start() + Range
.Value
, Range
.Range
.end() + Range
.Value
});
684 emitAranges(LinkedFunctionRanges
);
686 if (getOrigUnit().getVersion() < 5) {
687 cloneAndEmitRangeList(DebugSectionKind::DebugRange
, LinkedFunctionRanges
);
688 return Error::success();
691 cloneAndEmitRangeList(DebugSectionKind::DebugRngLists
, LinkedFunctionRanges
);
692 return Error::success();
695 void CompileUnit::cloneAndEmitRangeList(DebugSectionKind RngSectionKind
,
696 AddressRanges
&LinkedFunctionRanges
) {
697 SectionDescriptor
&DebugInfoSection
=
698 getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo
);
699 SectionDescriptor
&OutRangeSection
=
700 getOrCreateSectionDescriptor(RngSectionKind
);
702 if (!DebugInfoSection
.ListDebugRangePatch
.empty()) {
703 std::optional
<AddressRangeValuePair
> CachedRange
;
704 uint64_t OffsetAfterUnitLength
= emitRangeListHeader(OutRangeSection
);
706 DebugRangePatch
*CompileUnitRangePtr
= nullptr;
707 DebugInfoSection
.ListDebugRangePatch
.forEach([&](DebugRangePatch
&Patch
) {
708 if (Patch
.IsCompileUnitRanges
) {
709 CompileUnitRangePtr
= &Patch
;
711 // Get ranges from the source DWARF corresponding to the current
713 AddressRanges LinkedRanges
;
714 uint64_t InputDebugRangesSectionOffset
= DebugInfoSection
.getIntVal(
716 DebugInfoSection
.getFormParams().getDwarfOffsetByteSize());
717 if (Expected
<DWARFAddressRangesVector
> InputRanges
=
718 getOrigUnit().findRnglistFromOffset(
719 InputDebugRangesSectionOffset
)) {
720 // Apply relocation adjustment.
721 for (const auto &Range
: *InputRanges
) {
722 if (!CachedRange
|| !CachedRange
->Range
.contains(Range
.LowPC
))
724 getFunctionRanges().getRangeThatContains(Range
.LowPC
);
726 // All range entries should lie in the function range.
728 warn("inconsistent range data.");
732 // Store range for emiting.
733 LinkedRanges
.insert({Range
.LowPC
+ CachedRange
->Value
,
734 Range
.HighPC
+ CachedRange
->Value
});
737 llvm::consumeError(InputRanges
.takeError());
738 warn("invalid range list ignored.");
741 // Emit linked ranges.
742 DebugInfoSection
.apply(Patch
.PatchOffset
, dwarf::DW_FORM_sec_offset
,
743 OutRangeSection
.OS
.tell());
744 emitRangeListFragment(LinkedRanges
, OutRangeSection
);
748 if (CompileUnitRangePtr
!= nullptr) {
749 // Emit compile unit ranges last to be binary compatible with classic
751 DebugInfoSection
.apply(CompileUnitRangePtr
->PatchOffset
,
752 dwarf::DW_FORM_sec_offset
,
753 OutRangeSection
.OS
.tell());
754 emitRangeListFragment(LinkedFunctionRanges
, OutRangeSection
);
757 if (OffsetAfterUnitLength
> 0) {
758 assert(OffsetAfterUnitLength
-
759 OutRangeSection
.getFormParams().getDwarfOffsetByteSize() <
760 OffsetAfterUnitLength
);
761 OutRangeSection
.apply(
762 OffsetAfterUnitLength
-
763 OutRangeSection
.getFormParams().getDwarfOffsetByteSize(),
764 dwarf::DW_FORM_sec_offset
,
765 OutRangeSection
.OS
.tell() - OffsetAfterUnitLength
);
770 uint64_t CompileUnit::emitRangeListHeader(SectionDescriptor
&OutRangeSection
) {
771 if (OutRangeSection
.getFormParams().Version
< 5)
775 OutRangeSection
.emitUnitLength(0xBADDEF);
776 uint64_t OffsetAfterUnitLength
= OutRangeSection
.OS
.tell();
779 OutRangeSection
.emitIntVal(5, 2);
782 OutRangeSection
.emitIntVal(OutRangeSection
.getFormParams().AddrSize
, 1);
785 OutRangeSection
.emitIntVal(0, 1);
787 // Offset entry count
788 OutRangeSection
.emitIntVal(0, 4);
790 return OffsetAfterUnitLength
;
793 void CompileUnit::emitRangeListFragment(const AddressRanges
&LinkedRanges
,
794 SectionDescriptor
&OutRangeSection
) {
795 if (OutRangeSection
.getFormParams().Version
< 5) {
797 uint64_t BaseAddress
= 0;
798 if (std::optional
<uint64_t> LowPC
= getLowPc())
799 BaseAddress
= *LowPC
;
801 for (const AddressRange
&Range
: LinkedRanges
) {
802 OutRangeSection
.emitIntVal(Range
.start() - BaseAddress
,
803 OutRangeSection
.getFormParams().AddrSize
);
804 OutRangeSection
.emitIntVal(Range
.end() - BaseAddress
,
805 OutRangeSection
.getFormParams().AddrSize
);
808 // Add the terminator entry.
809 OutRangeSection
.emitIntVal(0, OutRangeSection
.getFormParams().AddrSize
);
810 OutRangeSection
.emitIntVal(0, OutRangeSection
.getFormParams().AddrSize
);
814 std::optional
<uint64_t> BaseAddress
;
815 for (const AddressRange
&Range
: LinkedRanges
) {
817 BaseAddress
= Range
.start();
819 // Emit base address.
820 OutRangeSection
.emitIntVal(dwarf::DW_RLE_base_addressx
, 1);
821 encodeULEB128(getDebugAddrIndex(*BaseAddress
), OutRangeSection
.OS
);
824 // Emit type of entry.
825 OutRangeSection
.emitIntVal(dwarf::DW_RLE_offset_pair
, 1);
827 // Emit start offset relative to base address.
828 encodeULEB128(Range
.start() - *BaseAddress
, OutRangeSection
.OS
);
830 // Emit end offset relative to base address.
831 encodeULEB128(Range
.end() - *BaseAddress
, OutRangeSection
.OS
);
834 // Emit the terminator entry.
835 OutRangeSection
.emitIntVal(dwarf::DW_RLE_end_of_list
, 1);
838 void CompileUnit::emitAranges(AddressRanges
&LinkedFunctionRanges
) {
839 if (LinkedFunctionRanges
.empty())
842 SectionDescriptor
&DebugInfoSection
=
843 getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo
);
844 SectionDescriptor
&OutArangesSection
=
845 getOrCreateSectionDescriptor(DebugSectionKind::DebugARanges
);
848 unsigned HeaderSize
=
849 sizeof(int32_t) + // Size of contents (w/o this field
850 sizeof(int16_t) + // DWARF ARange version number
851 sizeof(int32_t) + // Offset of CU in the .debug_info section
852 sizeof(int8_t) + // Pointer Size (in bytes)
853 sizeof(int8_t); // Segment Size (in bytes)
855 unsigned TupleSize
= OutArangesSection
.getFormParams().AddrSize
* 2;
856 unsigned Padding
= offsetToAlignment(HeaderSize
, Align(TupleSize
));
858 OutArangesSection
.emitOffset(0xBADDEF); // Aranges length
859 uint64_t OffsetAfterArangesLengthField
= OutArangesSection
.OS
.tell();
861 OutArangesSection
.emitIntVal(dwarf::DW_ARANGES_VERSION
, 2); // Version number
862 OutArangesSection
.notePatch(
863 DebugOffsetPatch
{OutArangesSection
.OS
.tell(), &DebugInfoSection
});
864 OutArangesSection
.emitOffset(0xBADDEF); // Corresponding unit's offset
865 OutArangesSection
.emitIntVal(OutArangesSection
.getFormParams().AddrSize
,
867 OutArangesSection
.emitIntVal(0, 1); // Segment size
869 for (size_t Idx
= 0; Idx
< Padding
; Idx
++)
870 OutArangesSection
.emitIntVal(0, 1); // Padding
872 // Emit linked ranges.
873 for (const AddressRange
&Range
: LinkedFunctionRanges
) {
874 OutArangesSection
.emitIntVal(Range
.start(),
875 OutArangesSection
.getFormParams().AddrSize
);
876 OutArangesSection
.emitIntVal(Range
.end() - Range
.start(),
877 OutArangesSection
.getFormParams().AddrSize
);
881 OutArangesSection
.emitIntVal(0, OutArangesSection
.getFormParams().AddrSize
);
882 OutArangesSection
.emitIntVal(0, OutArangesSection
.getFormParams().AddrSize
);
884 uint64_t OffsetAfterArangesEnd
= OutArangesSection
.OS
.tell();
886 // Update Aranges lentgh.
887 OutArangesSection
.apply(
888 OffsetAfterArangesLengthField
-
889 OutArangesSection
.getFormParams().getDwarfOffsetByteSize(),
890 dwarf::DW_FORM_sec_offset
,
891 OffsetAfterArangesEnd
- OffsetAfterArangesLengthField
);
894 Error
CompileUnit::cloneAndEmitDebugMacro() {
895 if (getOutUnitDIE() == nullptr)
896 return Error::success();
898 DWARFUnit
&OrigUnit
= getOrigUnit();
899 DWARFDie OrigUnitDie
= OrigUnit
.getUnitDIE();
901 // Check for .debug_macro table.
902 if (std::optional
<uint64_t> MacroAttr
=
903 dwarf::toSectionOffset(OrigUnitDie
.find(dwarf::DW_AT_macros
))) {
904 if (const DWARFDebugMacro
*Table
=
905 getContaingFile().Dwarf
->getDebugMacro()) {
906 emitMacroTableImpl(Table
, *MacroAttr
, true);
910 // Check for .debug_macinfo table.
911 if (std::optional
<uint64_t> MacroAttr
=
912 dwarf::toSectionOffset(OrigUnitDie
.find(dwarf::DW_AT_macro_info
))) {
913 if (const DWARFDebugMacro
*Table
=
914 getContaingFile().Dwarf
->getDebugMacinfo()) {
915 emitMacroTableImpl(Table
, *MacroAttr
, false);
919 return Error::success();
922 void CompileUnit::emitMacroTableImpl(const DWARFDebugMacro
*MacroTable
,
923 uint64_t OffsetToMacroTable
,
924 bool hasDWARFv5Header
) {
925 SectionDescriptor
&OutSection
=
927 ? getOrCreateSectionDescriptor(DebugSectionKind::DebugMacro
)
928 : getOrCreateSectionDescriptor(DebugSectionKind::DebugMacinfo
);
930 bool DefAttributeIsReported
= false;
931 bool UndefAttributeIsReported
= false;
932 bool ImportAttributeIsReported
= false;
934 for (const DWARFDebugMacro::MacroList
&List
: MacroTable
->MacroLists
) {
935 if (OffsetToMacroTable
== List
.Offset
) {
936 // Write DWARFv5 header.
937 if (hasDWARFv5Header
) {
938 // Write header version.
939 OutSection
.emitIntVal(List
.Header
.Version
, sizeof(List
.Header
.Version
));
941 uint8_t Flags
= List
.Header
.Flags
;
943 // Check for OPCODE_OPERANDS_TABLE.
945 DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE
) {
947 ~DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE
;
948 warn("opcode_operands_table is not supported yet.");
951 // Check for DEBUG_LINE_OFFSET.
952 std::optional
<uint64_t> StmtListOffset
;
953 if (Flags
& DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET
) {
954 // Get offset to the line table from the cloned compile unit.
955 for (auto &V
: getOutUnitDIE()->values()) {
956 if (V
.getAttribute() == dwarf::DW_AT_stmt_list
) {
957 StmtListOffset
= V
.getDIEInteger().getValue();
962 if (!StmtListOffset
) {
963 Flags
&= ~DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET
;
964 warn("couldn`t find line table for macro table.");
969 OutSection
.emitIntVal(Flags
, sizeof(Flags
));
971 // Write offset to line table.
972 if (StmtListOffset
) {
973 OutSection
.notePatch(DebugOffsetPatch
{
974 OutSection
.OS
.tell(),
975 &getOrCreateSectionDescriptor(DebugSectionKind::DebugLine
)});
976 // TODO: check that List.Header.getOffsetByteSize() and
977 // DebugOffsetPatch agree on size.
978 OutSection
.emitIntVal(0xBADDEF, List
.Header
.getOffsetByteSize());
982 // Write macro entries.
983 for (const DWARFDebugMacro::Entry
&MacroEntry
: List
.Macros
) {
984 if (MacroEntry
.Type
== 0) {
985 encodeULEB128(MacroEntry
.Type
, OutSection
.OS
);
989 uint8_t MacroType
= MacroEntry
.Type
;
992 bool HasVendorSpecificExtension
=
993 (!hasDWARFv5Header
&&
994 MacroType
== dwarf::DW_MACINFO_vendor_ext
) ||
995 (hasDWARFv5Header
&& (MacroType
>= dwarf::DW_MACRO_lo_user
&&
996 MacroType
<= dwarf::DW_MACRO_hi_user
));
998 if (HasVendorSpecificExtension
) {
999 // Write macinfo type.
1000 OutSection
.emitIntVal(MacroType
, 1);
1002 // Write vendor extension constant.
1003 encodeULEB128(MacroEntry
.ExtConstant
, OutSection
.OS
);
1005 // Write vendor extension string.
1006 OutSection
.emitString(dwarf::DW_FORM_string
, MacroEntry
.ExtStr
);
1008 warn("unknown macro type. skip.");
1010 // debug_macro and debug_macinfo share some common encodings.
1011 // DW_MACRO_define == DW_MACINFO_define
1012 // DW_MACRO_undef == DW_MACINFO_undef
1013 // DW_MACRO_start_file == DW_MACINFO_start_file
1014 // DW_MACRO_end_file == DW_MACINFO_end_file
1015 // For readibility/uniformity we are using DW_MACRO_*.
1016 case dwarf::DW_MACRO_define
:
1017 case dwarf::DW_MACRO_undef
: {
1018 // Write macinfo type.
1019 OutSection
.emitIntVal(MacroType
, 1);
1021 // Write source line.
1022 encodeULEB128(MacroEntry
.Line
, OutSection
.OS
);
1024 // Write macro string.
1025 OutSection
.emitString(dwarf::DW_FORM_string
, MacroEntry
.MacroStr
);
1027 case dwarf::DW_MACRO_define_strp
:
1028 case dwarf::DW_MACRO_undef_strp
:
1029 case dwarf::DW_MACRO_define_strx
:
1030 case dwarf::DW_MACRO_undef_strx
: {
1031 // DW_MACRO_*_strx forms are not supported currently.
1032 // Convert to *_strp.
1033 switch (MacroType
) {
1034 case dwarf::DW_MACRO_define_strx
: {
1035 MacroType
= dwarf::DW_MACRO_define_strp
;
1036 if (!DefAttributeIsReported
) {
1037 warn("DW_MACRO_define_strx unsupported yet. Convert to "
1038 "DW_MACRO_define_strp.");
1039 DefAttributeIsReported
= true;
1042 case dwarf::DW_MACRO_undef_strx
: {
1043 MacroType
= dwarf::DW_MACRO_undef_strp
;
1044 if (!UndefAttributeIsReported
) {
1045 warn("DW_MACRO_undef_strx unsupported yet. Convert to "
1046 "DW_MACRO_undef_strp.");
1047 UndefAttributeIsReported
= true;
1055 // Write macinfo type.
1056 OutSection
.emitIntVal(MacroType
, 1);
1058 // Write source line.
1059 encodeULEB128(MacroEntry
.Line
, OutSection
.OS
);
1061 // Write macro string.
1062 OutSection
.emitString(dwarf::DW_FORM_strp
, MacroEntry
.MacroStr
);
1065 case dwarf::DW_MACRO_start_file
: {
1066 // Write macinfo type.
1067 OutSection
.emitIntVal(MacroType
, 1);
1068 // Write source line.
1069 encodeULEB128(MacroEntry
.Line
, OutSection
.OS
);
1070 // Write source file id.
1071 encodeULEB128(MacroEntry
.File
, OutSection
.OS
);
1073 case dwarf::DW_MACRO_end_file
: {
1074 // Write macinfo type.
1075 OutSection
.emitIntVal(MacroType
, 1);
1077 case dwarf::DW_MACRO_import
:
1078 case dwarf::DW_MACRO_import_sup
: {
1079 if (!ImportAttributeIsReported
) {
1080 warn("DW_MACRO_import and DW_MACRO_import_sup are unsupported "
1082 ImportAttributeIsReported
= true;
1093 void CompileUnit::cloneDieAttrExpression(
1094 const DWARFExpression
&InputExpression
,
1095 SmallVectorImpl
<uint8_t> &OutputExpression
, SectionDescriptor
&Section
,
1096 std::optional
<int64_t> VarAddressAdjustment
,
1097 OffsetsPtrVector
&PatchesOffsets
) {
1098 using Encoding
= DWARFExpression::Operation::Encoding
;
1100 DWARFUnit
&OrigUnit
= getOrigUnit();
1101 uint8_t OrigAddressByteSize
= OrigUnit
.getAddressByteSize();
1103 uint64_t OpOffset
= 0;
1104 for (auto &Op
: InputExpression
) {
1105 auto Desc
= Op
.getDescription();
1106 // DW_OP_const_type is variable-length and has 3
1107 // operands. Thus far we only support 2.
1108 if ((Desc
.Op
.size() == 2 && Desc
.Op
[0] == Encoding::BaseTypeRef
) ||
1109 (Desc
.Op
.size() == 2 && Desc
.Op
[1] == Encoding::BaseTypeRef
&&
1110 Desc
.Op
[0] != Encoding::Size1
))
1111 warn("unsupported DW_OP encoding.");
1113 if ((Desc
.Op
.size() == 1 && Desc
.Op
[0] == Encoding::BaseTypeRef
) ||
1114 (Desc
.Op
.size() == 2 && Desc
.Op
[1] == Encoding::BaseTypeRef
&&
1115 Desc
.Op
[0] == Encoding::Size1
)) {
1116 // This code assumes that the other non-typeref operand fits into 1 byte.
1117 assert(OpOffset
< Op
.getEndOffset());
1118 uint32_t ULEBsize
= Op
.getEndOffset() - OpOffset
- 1;
1119 assert(ULEBsize
<= 16);
1121 // Copy over the operation.
1122 assert(!Op
.getSubCode() && "SubOps not yet supported");
1123 OutputExpression
.push_back(Op
.getCode());
1125 if (Desc
.Op
.size() == 1) {
1126 RefOffset
= Op
.getRawOperand(0);
1128 OutputExpression
.push_back(Op
.getRawOperand(0));
1129 RefOffset
= Op
.getRawOperand(1);
1132 uint32_t Offset
= 0;
1133 unsigned RealSize
= 0;
1134 // Look up the base type. For DW_OP_convert, the operand may be 0 to
1135 // instead indicate the generic type. The same holds for
1136 // DW_OP_reinterpret, which is currently not supported.
1137 if (RefOffset
> 0 || Op
.getCode() != dwarf::DW_OP_convert
) {
1138 RefOffset
+= OrigUnit
.getOffset();
1139 uint32_t RefDieIdx
= 0;
1140 if (std::optional
<uint32_t> Idx
=
1141 OrigUnit
.getDIEIndexForOffset(RefOffset
))
1144 // Use fixed size for ULEB128 data, since we need to update that size
1145 // later with the proper offsets. Use 5 for DWARF32, 9 for DWARF64.
1146 ULEBsize
= getFormParams().getDwarfOffsetByteSize() + 1;
1148 RealSize
= encodeULEB128(0xBADDEF, ULEB
, ULEBsize
);
1150 Section
.notePatchWithOffsetUpdate(
1151 DebugULEB128DieRefPatch(OutputExpression
.size(), this, this,
1155 RealSize
= encodeULEB128(Offset
, ULEB
, ULEBsize
);
1157 if (RealSize
> ULEBsize
) {
1158 // Emit the generic type as a fallback.
1159 RealSize
= encodeULEB128(0, ULEB
, ULEBsize
);
1160 warn("base type ref doesn't fit.");
1162 assert(RealSize
== ULEBsize
&& "padding failed");
1163 ArrayRef
<uint8_t> ULEBbytes(ULEB
, ULEBsize
);
1164 OutputExpression
.append(ULEBbytes
.begin(), ULEBbytes
.end());
1165 } else if (!getGlobalData().getOptions().UpdateIndexTablesOnly
&&
1166 Op
.getCode() == dwarf::DW_OP_addrx
) {
1167 if (std::optional
<object::SectionedAddress
> SA
=
1168 OrigUnit
.getAddrOffsetSectionItem(Op
.getRawOperand(0))) {
1169 // DWARFLinker does not use addrx forms since it generates relocated
1170 // addresses. Replace DW_OP_addrx with DW_OP_addr here.
1171 // Argument of DW_OP_addrx should be relocated here as it is not
1172 // processed by applyValidRelocs.
1173 OutputExpression
.push_back(dwarf::DW_OP_addr
);
1174 uint64_t LinkedAddress
=
1175 SA
->Address
+ (VarAddressAdjustment
? *VarAddressAdjustment
: 0);
1176 if (getEndianness() != llvm::endianness::native
)
1177 sys::swapByteOrder(LinkedAddress
);
1178 ArrayRef
<uint8_t> AddressBytes(
1179 reinterpret_cast<const uint8_t *>(&LinkedAddress
),
1180 OrigAddressByteSize
);
1181 OutputExpression
.append(AddressBytes
.begin(), AddressBytes
.end());
1183 warn("cann't read DW_OP_addrx operand.");
1184 } else if (!getGlobalData().getOptions().UpdateIndexTablesOnly
&&
1185 Op
.getCode() == dwarf::DW_OP_constx
) {
1186 if (std::optional
<object::SectionedAddress
> SA
=
1187 OrigUnit
.getAddrOffsetSectionItem(Op
.getRawOperand(0))) {
1188 // DWARFLinker does not use constx forms since it generates relocated
1189 // addresses. Replace DW_OP_constx with DW_OP_const[*]u here.
1190 // Argument of DW_OP_constx should be relocated here as it is not
1191 // processed by applyValidRelocs.
1192 std::optional
<uint8_t> OutOperandKind
;
1193 switch (OrigAddressByteSize
) {
1195 OutOperandKind
= dwarf::DW_OP_const2u
;
1198 OutOperandKind
= dwarf::DW_OP_const4u
;
1201 OutOperandKind
= dwarf::DW_OP_const8u
;
1205 formatv(("unsupported address size: {0}."), OrigAddressByteSize
));
1209 if (OutOperandKind
) {
1210 OutputExpression
.push_back(*OutOperandKind
);
1211 uint64_t LinkedAddress
=
1212 SA
->Address
+ (VarAddressAdjustment
? *VarAddressAdjustment
: 0);
1213 if (getEndianness() != llvm::endianness::native
)
1214 sys::swapByteOrder(LinkedAddress
);
1215 ArrayRef
<uint8_t> AddressBytes(
1216 reinterpret_cast<const uint8_t *>(&LinkedAddress
),
1217 OrigAddressByteSize
);
1218 OutputExpression
.append(AddressBytes
.begin(), AddressBytes
.end());
1221 warn("cann't read DW_OP_constx operand.");
1223 // Copy over everything else unmodified.
1225 InputExpression
.getData().slice(OpOffset
, Op
.getEndOffset());
1226 OutputExpression
.append(Bytes
.begin(), Bytes
.end());
1228 OpOffset
= Op
.getEndOffset();
1232 Error
CompileUnit::cloneAndEmit(
1233 std::optional
<std::reference_wrapper
<const Triple
>> TargetTriple
,
1234 TypeUnit
*ArtificialTypeUnit
) {
1235 BumpPtrAllocator Allocator
;
1237 DWARFDie OrigUnitDIE
= getOrigUnit().getUnitDIE();
1238 if (!OrigUnitDIE
.isValid())
1239 return Error::success();
1241 TypeEntry
*RootEntry
= nullptr;
1242 if (ArtificialTypeUnit
)
1243 RootEntry
= ArtificialTypeUnit
->getTypePool().getRoot();
1245 // Clone input DIE entry recursively.
1246 std::pair
<DIE
*, TypeEntry
*> OutCUDie
= cloneDIE(
1247 OrigUnitDIE
.getDebugInfoEntry(), RootEntry
, getDebugInfoHeaderSize(),
1248 std::nullopt
, std::nullopt
, Allocator
, ArtificialTypeUnit
);
1249 setOutUnitDIE(OutCUDie
.first
);
1251 if (!TargetTriple
.has_value() || (OutCUDie
.first
== nullptr))
1252 return Error::success();
1254 if (Error Err
= cloneAndEmitLineTable((*TargetTriple
).get()))
1257 if (Error Err
= cloneAndEmitDebugMacro())
1260 getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo
);
1261 if (Error Err
= emitDebugInfo((*TargetTriple
).get()))
1264 // ASSUMPTION: .debug_info section should already be emitted at this point.
1265 // cloneAndEmitRanges & cloneAndEmitDebugLocations use .debug_info section
1268 if (Error Err
= cloneAndEmitRanges())
1271 if (Error Err
= cloneAndEmitDebugLocations())
1274 if (Error Err
= emitDebugAddrSection())
1277 // Generate Pub accelerator tables.
1278 if (llvm::is_contained(GlobalData
.getOptions().AccelTables
,
1279 DWARFLinker::AccelTableKind::Pub
))
1280 emitPubAccelerators();
1282 if (Error Err
= emitDebugStringOffsetSection())
1285 return emitAbbreviations();
1288 std::pair
<DIE
*, TypeEntry
*> CompileUnit::cloneDIE(
1289 const DWARFDebugInfoEntry
*InputDieEntry
, TypeEntry
*ClonedParentTypeDIE
,
1290 uint64_t OutOffset
, std::optional
<int64_t> FuncAddressAdjustment
,
1291 std::optional
<int64_t> VarAddressAdjustment
, BumpPtrAllocator
&Allocator
,
1292 TypeUnit
*ArtificialTypeUnit
) {
1293 uint32_t InputDieIdx
= getDIEIndex(InputDieEntry
);
1294 CompileUnit::DIEInfo
&Info
= getDIEInfo(InputDieIdx
);
1296 bool NeedToClonePlainDIE
= Info
.needToKeepInPlainDwarf();
1297 bool NeedToCloneTypeDIE
=
1298 (InputDieEntry
->getTag() != dwarf::DW_TAG_compile_unit
) &&
1299 Info
.needToPlaceInTypeTable();
1300 std::pair
<DIE
*, TypeEntry
*> ClonedDIE
;
1302 DIEGenerator
PlainDIEGenerator(Allocator
, *this);
1304 if (NeedToClonePlainDIE
)
1305 // Create a cloned DIE which would be placed into the cloned version
1306 // of input compile unit.
1307 ClonedDIE
.first
= createPlainDIEandCloneAttributes(
1308 InputDieEntry
, PlainDIEGenerator
, OutOffset
, FuncAddressAdjustment
,
1309 VarAddressAdjustment
);
1310 if (NeedToCloneTypeDIE
) {
1311 // Create a cloned DIE which would be placed into the artificial type
1313 assert(ArtificialTypeUnit
!= nullptr);
1314 DIEGenerator
TypeDIEGenerator(
1315 ArtificialTypeUnit
->getTypePool().getThreadLocalAllocator(), *this);
1317 ClonedDIE
.second
= createTypeDIEandCloneAttributes(
1318 InputDieEntry
, TypeDIEGenerator
, ClonedParentTypeDIE
,
1319 ArtificialTypeUnit
);
1321 TypeEntry
*TypeParentForChild
=
1322 ClonedDIE
.second
? ClonedDIE
.second
: ClonedParentTypeDIE
;
1324 bool HasPlainChildrenToClone
=
1325 (ClonedDIE
.first
&& Info
.getKeepPlainChildren());
1327 bool HasTypeChildrenToClone
=
1328 ((ClonedDIE
.second
||
1329 InputDieEntry
->getTag() == dwarf::DW_TAG_compile_unit
) &&
1330 Info
.getKeepTypeChildren());
1332 // Recursively clone children.
1333 if (HasPlainChildrenToClone
|| HasTypeChildrenToClone
) {
1334 for (const DWARFDebugInfoEntry
*CurChild
=
1335 getFirstChildEntry(InputDieEntry
);
1336 CurChild
&& CurChild
->getAbbreviationDeclarationPtr();
1337 CurChild
= getSiblingEntry(CurChild
)) {
1338 std::pair
<DIE
*, TypeEntry
*> ClonedChild
= cloneDIE(
1339 CurChild
, TypeParentForChild
, OutOffset
, FuncAddressAdjustment
,
1340 VarAddressAdjustment
, Allocator
, ArtificialTypeUnit
);
1342 if (ClonedChild
.first
) {
1344 ClonedChild
.first
->getOffset() + ClonedChild
.first
->getSize();
1345 PlainDIEGenerator
.addChild(ClonedChild
.first
);
1348 assert(ClonedDIE
.first
== nullptr ||
1349 HasPlainChildrenToClone
== ClonedDIE
.first
->hasChildren());
1351 // Account for the end of children marker.
1352 if (HasPlainChildrenToClone
)
1353 OutOffset
+= sizeof(int8_t);
1357 if (ClonedDIE
.first
!= nullptr)
1358 ClonedDIE
.first
->setSize(OutOffset
- ClonedDIE
.first
->getOffset());
1363 DIE
*CompileUnit::createPlainDIEandCloneAttributes(
1364 const DWARFDebugInfoEntry
*InputDieEntry
, DIEGenerator
&PlainDIEGenerator
,
1365 uint64_t &OutOffset
, std::optional
<int64_t> &FuncAddressAdjustment
,
1366 std::optional
<int64_t> &VarAddressAdjustment
) {
1367 uint32_t InputDieIdx
= getDIEIndex(InputDieEntry
);
1368 CompileUnit::DIEInfo
&Info
= getDIEInfo(InputDieIdx
);
1369 DIE
*ClonedDIE
= nullptr;
1370 bool HasLocationExpressionAddress
= false;
1371 if (InputDieEntry
->getTag() == dwarf::DW_TAG_subprogram
) {
1372 // Get relocation adjustment value for the current function.
1373 FuncAddressAdjustment
=
1374 getContaingFile().Addresses
->getSubprogramRelocAdjustment(
1375 getDIE(InputDieEntry
), false);
1376 } else if (InputDieEntry
->getTag() == dwarf::DW_TAG_label
) {
1377 // Get relocation adjustment value for the current label.
1378 std::optional
<uint64_t> lowPC
=
1379 dwarf::toAddress(find(InputDieEntry
, dwarf::DW_AT_low_pc
));
1381 LabelMapTy::iterator It
= Labels
.find(*lowPC
);
1382 if (It
!= Labels
.end())
1383 FuncAddressAdjustment
= It
->second
;
1385 } else if (InputDieEntry
->getTag() == dwarf::DW_TAG_variable
) {
1386 // Get relocation adjustment value for the current variable.
1387 std::pair
<bool, std::optional
<int64_t>> LocExprAddrAndRelocAdjustment
=
1388 getContaingFile().Addresses
->getVariableRelocAdjustment(
1389 getDIE(InputDieEntry
), false);
1391 HasLocationExpressionAddress
= LocExprAddrAndRelocAdjustment
.first
;
1392 if (LocExprAddrAndRelocAdjustment
.first
&&
1393 LocExprAddrAndRelocAdjustment
.second
)
1394 VarAddressAdjustment
= *LocExprAddrAndRelocAdjustment
.second
;
1397 ClonedDIE
= PlainDIEGenerator
.createDIE(InputDieEntry
->getTag(), OutOffset
);
1399 // Offset to the DIE would be used after output DIE tree is deleted.
1400 // Thus we need to remember DIE offset separately.
1401 rememberDieOutOffset(InputDieIdx
, OutOffset
);
1403 // Clone Attributes.
1404 DIEAttributeCloner
AttributesCloner(ClonedDIE
, *this, this, InputDieEntry
,
1405 PlainDIEGenerator
, FuncAddressAdjustment
,
1406 VarAddressAdjustment
,
1407 HasLocationExpressionAddress
);
1408 AttributesCloner
.clone();
1410 // Remember accelerator info.
1411 AcceleratorRecordsSaver
AccelRecordsSaver(getGlobalData(), *this, this);
1412 AccelRecordsSaver
.save(InputDieEntry
, ClonedDIE
, AttributesCloner
.AttrInfo
,
1416 AttributesCloner
.finalizeAbbreviations(Info
.getKeepPlainChildren());
1421 /// Allocates output DIE for the specified \p TypeDescriptor.
1422 DIE
*CompileUnit::allocateTypeDie(TypeEntryBody
*TypeDescriptor
,
1423 DIEGenerator
&TypeDIEGenerator
,
1424 dwarf::Tag DieTag
, bool IsDeclaration
,
1425 bool IsParentDeclaration
) {
1426 DIE
*DefinitionDie
= TypeDescriptor
->Die
;
1427 // Do not allocate any new DIE if definition DIE is already met.
1431 DIE
*DeclarationDie
= TypeDescriptor
->DeclarationDie
;
1432 bool OldParentIsDeclaration
= TypeDescriptor
->ParentIsDeclaration
;
1434 if (IsDeclaration
&& !DeclarationDie
) {
1435 // Alocate declaration DIE.
1436 DIE
*NewDie
= TypeDIEGenerator
.createDIE(DieTag
, 0);
1437 if (TypeDescriptor
->DeclarationDie
.compare_exchange_weak(DeclarationDie
,
1440 } else if (IsDeclaration
&& !IsParentDeclaration
&& OldParentIsDeclaration
) {
1441 // Overwrite existing declaration DIE if it's parent is also an declaration
1442 // while parent of current declaration DIE is a definition.
1443 if (TypeDescriptor
->ParentIsDeclaration
.compare_exchange_weak(
1444 OldParentIsDeclaration
, false)) {
1445 DIE
*NewDie
= TypeDIEGenerator
.createDIE(DieTag
, 0);
1446 TypeDescriptor
->DeclarationDie
= NewDie
;
1449 } else if (!IsDeclaration
&& IsParentDeclaration
&& !DeclarationDie
) {
1450 // Alocate declaration DIE since parent of current DIE is marked as
1452 DIE
*NewDie
= TypeDIEGenerator
.createDIE(DieTag
, 0);
1453 if (TypeDescriptor
->DeclarationDie
.compare_exchange_weak(DeclarationDie
,
1456 } else if (!IsDeclaration
&& !IsParentDeclaration
) {
1457 // Allocate definition DIE.
1458 DIE
*NewDie
= TypeDIEGenerator
.createDIE(DieTag
, 0);
1459 if (TypeDescriptor
->Die
.compare_exchange_weak(DefinitionDie
, NewDie
)) {
1460 TypeDescriptor
->ParentIsDeclaration
= false;
1468 TypeEntry
*CompileUnit::createTypeDIEandCloneAttributes(
1469 const DWARFDebugInfoEntry
*InputDieEntry
, DIEGenerator
&TypeDIEGenerator
,
1470 TypeEntry
*ClonedParentTypeDIE
, TypeUnit
*ArtificialTypeUnit
) {
1471 assert(ArtificialTypeUnit
!= nullptr);
1472 uint32_t InputDieIdx
= getDIEIndex(InputDieEntry
);
1474 TypeEntry
*Entry
= getDieTypeEntry(InputDieIdx
);
1475 assert(Entry
!= nullptr);
1476 assert(ClonedParentTypeDIE
!= nullptr);
1477 TypeEntryBody
*EntryBody
=
1478 ArtificialTypeUnit
->getTypePool().getOrCreateTypeEntryBody(
1479 Entry
, ClonedParentTypeDIE
);
1482 bool IsDeclaration
=
1483 dwarf::toUnsigned(find(InputDieEntry
, dwarf::DW_AT_declaration
), 0);
1485 bool ParentIsDeclaration
= false;
1486 if (std::optional
<uint32_t> ParentIdx
= InputDieEntry
->getParentIdx())
1487 ParentIsDeclaration
=
1488 dwarf::toUnsigned(find(*ParentIdx
, dwarf::DW_AT_declaration
), 0);
1491 allocateTypeDie(EntryBody
, TypeDIEGenerator
, InputDieEntry
->getTag(),
1492 IsDeclaration
, ParentIsDeclaration
);
1494 if (OutDIE
!= nullptr) {
1495 assert(ArtificialTypeUnit
!= nullptr);
1496 ArtificialTypeUnit
->getSectionDescriptor(DebugSectionKind::DebugInfo
);
1498 DIEAttributeCloner
AttributesCloner(OutDIE
, *this, ArtificialTypeUnit
,
1499 InputDieEntry
, TypeDIEGenerator
,
1500 std::nullopt
, std::nullopt
, false);
1501 AttributesCloner
.clone();
1503 // Remember accelerator info.
1504 AcceleratorRecordsSaver
AccelRecordsSaver(getGlobalData(), *this,
1505 ArtificialTypeUnit
);
1506 AccelRecordsSaver
.save(InputDieEntry
, OutDIE
, AttributesCloner
.AttrInfo
,
1509 // if AttributesCloner.getOutOffset() == 0 then we need to add
1510 // 1 to avoid assertion for zero size. We will subtract it back later.
1511 OutDIE
->setSize(AttributesCloner
.getOutOffset() + 1);
1517 Error
CompileUnit::cloneAndEmitLineTable(const Triple
&TargetTriple
) {
1518 const DWARFDebugLine::LineTable
*InputLineTable
=
1519 getContaingFile().Dwarf
->getLineTableForUnit(&getOrigUnit());
1520 if (InputLineTable
== nullptr) {
1521 if (getOrigUnit().getUnitDIE().find(dwarf::DW_AT_stmt_list
))
1522 warn("cann't load line table.");
1523 return Error::success();
1526 DWARFDebugLine::LineTable OutLineTable
;
1528 // Set Line Table header.
1529 OutLineTable
.Prologue
= InputLineTable
->Prologue
;
1530 OutLineTable
.Prologue
.FormParams
.AddrSize
= getFormParams().AddrSize
;
1532 // Set Line Table Rows.
1533 if (getGlobalData().getOptions().UpdateIndexTablesOnly
) {
1534 OutLineTable
.Rows
= InputLineTable
->Rows
;
1535 // If all the line table contains is a DW_LNE_end_sequence, clear the line
1536 // table rows, it will be inserted again in the DWARFStreamer.
1537 if (OutLineTable
.Rows
.size() == 1 && OutLineTable
.Rows
[0].EndSequence
)
1538 OutLineTable
.Rows
.clear();
1540 OutLineTable
.Sequences
= InputLineTable
->Sequences
;
1542 // This vector is the output line table.
1543 std::vector
<DWARFDebugLine::Row
> NewRows
;
1544 NewRows
.reserve(InputLineTable
->Rows
.size());
1546 // Current sequence of rows being extracted, before being inserted
1548 std::vector
<DWARFDebugLine::Row
> Seq
;
1550 const auto &FunctionRanges
= getFunctionRanges();
1551 std::optional
<AddressRangeValuePair
> CurrRange
;
1553 // FIXME: This logic is meant to generate exactly the same output as
1554 // Darwin's classic dsymutil. There is a nicer way to implement this
1555 // by simply putting all the relocated line info in NewRows and simply
1556 // sorting NewRows before passing it to emitLineTableForUnit. This
1557 // should be correct as sequences for a function should stay
1558 // together in the sorted output. There are a few corner cases that
1559 // look suspicious though, and that required to implement the logic
1560 // this way. Revisit that once initial validation is finished.
1562 // Iterate over the object file line info and extract the sequences
1563 // that correspond to linked functions.
1564 for (DWARFDebugLine::Row Row
: InputLineTable
->Rows
) {
1565 // Check whether we stepped out of the range. The range is
1566 // half-open, but consider accept the end address of the range if
1567 // it is marked as end_sequence in the input (because in that
1568 // case, the relocation offset is accurate and that entry won't
1569 // serve as the start of another function).
1570 if (!CurrRange
|| !CurrRange
->Range
.contains(Row
.Address
.Address
)) {
1571 // We just stepped out of a known range. Insert a end_sequence
1572 // corresponding to the end of the range.
1573 uint64_t StopAddress
=
1574 CurrRange
? CurrRange
->Range
.end() + CurrRange
->Value
: -1ULL;
1575 CurrRange
= FunctionRanges
.getRangeThatContains(Row
.Address
.Address
);
1576 if (StopAddress
!= -1ULL && !Seq
.empty()) {
1577 // Insert end sequence row with the computed end address, but
1578 // the same line as the previous one.
1579 auto NextLine
= Seq
.back();
1580 NextLine
.Address
.Address
= StopAddress
;
1581 NextLine
.EndSequence
= 1;
1582 NextLine
.PrologueEnd
= 0;
1583 NextLine
.BasicBlock
= 0;
1584 NextLine
.EpilogueBegin
= 0;
1585 Seq
.push_back(NextLine
);
1586 insertLineSequence(Seq
, NewRows
);
1593 // Ignore empty sequences.
1594 if (Row
.EndSequence
&& Seq
.empty())
1597 // Relocate row address and add it to the current sequence.
1598 Row
.Address
.Address
+= CurrRange
->Value
;
1599 Seq
.emplace_back(Row
);
1601 if (Row
.EndSequence
)
1602 insertLineSequence(Seq
, NewRows
);
1605 OutLineTable
.Rows
= std::move(NewRows
);
1608 return emitDebugLine(TargetTriple
, OutLineTable
);
1611 void CompileUnit::insertLineSequence(std::vector
<DWARFDebugLine::Row
> &Seq
,
1612 std::vector
<DWARFDebugLine::Row
> &Rows
) {
1616 if (!Rows
.empty() && Rows
.back().Address
< Seq
.front().Address
) {
1617 llvm::append_range(Rows
, Seq
);
1622 object::SectionedAddress Front
= Seq
.front().Address
;
1623 auto InsertPoint
= partition_point(
1624 Rows
, [=](const DWARFDebugLine::Row
&O
) { return O
.Address
< Front
; });
1626 // FIXME: this only removes the unneeded end_sequence if the
1627 // sequences have been inserted in order. Using a global sort like
1628 // described in cloneAndEmitLineTable() and delaying the end_sequene
1629 // elimination to DebugLineEmitter::emit() we can get rid of all of them.
1630 if (InsertPoint
!= Rows
.end() && InsertPoint
->Address
== Front
&&
1631 InsertPoint
->EndSequence
) {
1632 *InsertPoint
= Seq
.front();
1633 Rows
.insert(InsertPoint
+ 1, Seq
.begin() + 1, Seq
.end());
1635 Rows
.insert(InsertPoint
, Seq
.begin(), Seq
.end());
1641 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1642 LLVM_DUMP_METHOD
void CompileUnit::DIEInfo::dump() {
1643 llvm::errs() << "{";
1644 llvm::errs() << " Placement: ";
1645 switch (getPlacement()) {
1647 llvm::errs() << "NotSet";
1650 llvm::errs() << "TypeTable";
1653 llvm::errs() << "PlainDwarf";
1656 llvm::errs() << "Both";
1660 llvm::errs() << " Keep: " << getKeep();
1661 llvm::errs() << " KeepPlainChildren: " << getKeepPlainChildren();
1662 llvm::errs() << " KeepTypeChildren: " << getKeepTypeChildren();
1663 llvm::errs() << " IsInMouduleScope: " << getIsInMouduleScope();
1664 llvm::errs() << " IsInFunctionScope: " << getIsInFunctionScope();
1665 llvm::errs() << " IsInAnonNamespaceScope: " << getIsInAnonNamespaceScope();
1666 llvm::errs() << " ODRAvailable: " << getODRAvailable();
1667 llvm::errs() << " TrackLiveness: " << getTrackLiveness();
1668 llvm::errs() << "}\n";
1670 #endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1672 std::optional
<std::pair
<StringRef
, StringRef
>>
1673 CompileUnit::getDirAndFilenameFromLineTable(
1674 const DWARFFormValue
&FileIdxValue
) {
1676 if (std::optional
<uint64_t> Val
= FileIdxValue
.getAsUnsignedConstant())
1678 else if (std::optional
<int64_t> Val
= FileIdxValue
.getAsSignedConstant())
1680 else if (std::optional
<uint64_t> Val
= FileIdxValue
.getAsSectionOffset())
1683 return std::nullopt
;
1685 return getDirAndFilenameFromLineTable(FileIdx
);
1688 std::optional
<std::pair
<StringRef
, StringRef
>>
1689 CompileUnit::getDirAndFilenameFromLineTable(uint64_t FileIdx
) {
1690 FileNamesCache::iterator FileData
= FileNames
.find(FileIdx
);
1691 if (FileData
!= FileNames
.end())
1692 return std::make_pair(StringRef(FileData
->second
.first
),
1693 StringRef(FileData
->second
.second
));
1695 if (const DWARFDebugLine::LineTable
*LineTable
=
1696 getOrigUnit().getContext().getLineTableForUnit(&getOrigUnit())) {
1697 if (LineTable
->hasFileAtIndex(FileIdx
)) {
1699 const llvm::DWARFDebugLine::FileNameEntry
&Entry
=
1700 LineTable
->Prologue
.getFileNameEntry(FileIdx
);
1702 Expected
<const char *> Name
= Entry
.Name
.getAsCString();
1704 warn(Name
.takeError());
1705 return std::nullopt
;
1708 std::string FileName
= *Name
;
1709 if (isPathAbsoluteOnWindowsOrPosix(FileName
)) {
1710 FileNamesCache::iterator FileData
=
1712 .insert(std::make_pair(
1714 std::make_pair(std::string(""), std::move(FileName
))))
1716 return std::make_pair(StringRef(FileData
->second
.first
),
1717 StringRef(FileData
->second
.second
));
1720 SmallString
<256> FilePath
;
1721 StringRef IncludeDir
;
1722 // Be defensive about the contents of Entry.
1723 if (getVersion() >= 5) {
1724 // DirIdx 0 is the compilation directory, so don't include it for
1726 if ((Entry
.DirIdx
!= 0) &&
1727 Entry
.DirIdx
< LineTable
->Prologue
.IncludeDirectories
.size()) {
1728 Expected
<const char *> DirName
=
1729 LineTable
->Prologue
.IncludeDirectories
[Entry
.DirIdx
]
1732 IncludeDir
= *DirName
;
1734 warn(DirName
.takeError());
1735 return std::nullopt
;
1739 if (0 < Entry
.DirIdx
&&
1740 Entry
.DirIdx
<= LineTable
->Prologue
.IncludeDirectories
.size()) {
1741 Expected
<const char *> DirName
=
1742 LineTable
->Prologue
.IncludeDirectories
[Entry
.DirIdx
- 1]
1745 IncludeDir
= *DirName
;
1747 warn(DirName
.takeError());
1748 return std::nullopt
;
1753 StringRef CompDir
= getOrigUnit().getCompilationDir();
1755 if (!CompDir
.empty() && !isPathAbsoluteOnWindowsOrPosix(IncludeDir
)) {
1756 sys::path::append(FilePath
, sys::path::Style::native
, CompDir
);
1759 sys::path::append(FilePath
, sys::path::Style::native
, IncludeDir
);
1761 FileNamesCache::iterator FileData
=
1764 std::make_pair(FileIdx
, std::make_pair(std::string(FilePath
),
1765 std::move(FileName
))))
1767 return std::make_pair(StringRef(FileData
->second
.first
),
1768 StringRef(FileData
->second
.second
));
1772 return std::nullopt
;
1775 #define MAX_REFERENCIES_DEPTH 1000
1776 UnitEntryPairTy
UnitEntryPairTy::getNamespaceOrigin() {
1777 UnitEntryPairTy
CUDiePair(*this);
1778 std::optional
<UnitEntryPairTy
> RefDiePair
;
1781 RefDiePair
= CUDiePair
.CU
->resolveDIEReference(
1782 CUDiePair
.DieEntry
, dwarf::DW_AT_extension
,
1783 ResolveInterCUReferencesMode::Resolve
);
1784 if (!RefDiePair
|| !RefDiePair
->DieEntry
)
1787 CUDiePair
= *RefDiePair
;
1788 } while (refDepth
++ < MAX_REFERENCIES_DEPTH
);
1793 std::optional
<UnitEntryPairTy
> UnitEntryPairTy::getParent() {
1794 if (std::optional
<uint32_t> ParentIdx
= DieEntry
->getParentIdx())
1795 return UnitEntryPairTy
{CU
, CU
->getDebugInfoEntry(*ParentIdx
)};
1797 return std::nullopt
;
1800 CompileUnit::OutputUnitVariantPtr::OutputUnitVariantPtr(CompileUnit
*U
)
1802 assert(U
!= nullptr);
1805 CompileUnit::OutputUnitVariantPtr::OutputUnitVariantPtr(TypeUnit
*U
) : Ptr(U
) {
1806 assert(U
!= nullptr);
1809 DwarfUnit
*CompileUnit::OutputUnitVariantPtr::operator->() {
1810 if (isCompileUnit())
1811 return getAsCompileUnit();
1813 return getAsTypeUnit();
1816 bool CompileUnit::OutputUnitVariantPtr::isCompileUnit() {
1817 return Ptr
.is
<CompileUnit
*>();
1820 bool CompileUnit::OutputUnitVariantPtr::isTypeUnit() {
1821 return Ptr
.is
<TypeUnit
*>();
1824 CompileUnit
*CompileUnit::OutputUnitVariantPtr::getAsCompileUnit() {
1825 return Ptr
.get
<CompileUnit
*>();
1828 TypeUnit
*CompileUnit::OutputUnitVariantPtr::getAsTypeUnit() {
1829 return Ptr
.get
<TypeUnit
*>();
1832 bool CompileUnit::resolveDependenciesAndMarkLiveness(
1833 bool InterCUProcessingStarted
, std::atomic
<bool> &HasNewInterconnectedCUs
) {
1835 Dependencies
.reset(new DependencyTracker(*this));
1837 return Dependencies
->resolveDependenciesAndMarkLiveness(
1838 InterCUProcessingStarted
, HasNewInterconnectedCUs
);
1841 bool CompileUnit::updateDependenciesCompleteness() {
1842 assert(Dependencies
.get());
1844 return Dependencies
->updateDependenciesCompleteness();
1847 void CompileUnit::verifyDependencies() {
1848 assert(Dependencies
.get());
1850 Dependencies
->verifyKeepChain();
1853 ArrayRef
<dwarf::Attribute
> dwarf_linker::parallel::getODRAttributes() {
1854 static dwarf::Attribute ODRAttributes
[] = {
1855 dwarf::DW_AT_type
, dwarf::DW_AT_specification
,
1856 dwarf::DW_AT_abstract_origin
, dwarf::DW_AT_import
};
1858 return ODRAttributes
;