Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/DWARFLinker/Parallel/DWARFLinkerCompileUnit.h
35292 views
1
//===- DWARFLinkerCompileUnit.h ---------------------------------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#ifndef LLVM_LIB_DWARFLINKER_PARALLEL_DWARFLINKERCOMPILEUNIT_H
10
#define LLVM_LIB_DWARFLINKER_PARALLEL_DWARFLINKERCOMPILEUNIT_H
11
12
#include "DWARFLinkerUnit.h"
13
#include "llvm/DWARFLinker/DWARFFile.h"
14
#include <optional>
15
16
namespace llvm {
17
namespace dwarf_linker {
18
namespace parallel {
19
20
using OffsetToUnitTy = function_ref<CompileUnit *(uint64_t Offset)>;
21
22
struct AttributesInfo;
23
class SyntheticTypeNameBuilder;
24
class DIEGenerator;
25
class TypeUnit;
26
class DependencyTracker;
27
28
class CompileUnit;
29
30
/// This is a helper structure which keeps a debug info entry
31
/// with it's containing compilation unit.
32
struct UnitEntryPairTy {
33
UnitEntryPairTy() = default;
34
UnitEntryPairTy(CompileUnit *CU, const DWARFDebugInfoEntry *DieEntry)
35
: CU(CU), DieEntry(DieEntry) {}
36
37
CompileUnit *CU = nullptr;
38
const DWARFDebugInfoEntry *DieEntry = nullptr;
39
40
UnitEntryPairTy getNamespaceOrigin();
41
std::optional<UnitEntryPairTy> getParent();
42
};
43
44
enum ResolveInterCUReferencesMode : bool {
45
Resolve = true,
46
AvoidResolving = false,
47
};
48
49
/// Stores all information related to a compile unit, be it in its original
50
/// instance of the object file or its brand new cloned and generated DIE tree.
51
/// NOTE: we need alignment of at least 8 bytes as we use
52
/// PointerIntPair<CompileUnit *, 3> in the DependencyTracker.h
53
class alignas(8) CompileUnit : public DwarfUnit {
54
public:
55
/// The stages of new compile unit processing.
56
enum class Stage : uint8_t {
57
/// Created, linked with input DWARF file.
58
CreatedNotLoaded = 0,
59
60
/// Input DWARF is loaded.
61
Loaded,
62
63
/// Input DWARF is analysed(DIEs pointing to the real code section are
64
/// discovered, type names are assigned if ODR is requested).
65
LivenessAnalysisDone,
66
67
/// Check if dependencies have incompatible placement.
68
/// If that is the case modify placement to be compatible.
69
UpdateDependenciesCompleteness,
70
71
/// Type names assigned to DIEs.
72
TypeNamesAssigned,
73
74
/// Output DWARF is generated.
75
Cloned,
76
77
/// Offsets inside patch records are updated.
78
PatchesUpdated,
79
80
/// Resources(Input DWARF, Output DWARF tree) are released.
81
Cleaned,
82
83
/// Compile Unit should be skipped
84
Skipped
85
};
86
87
CompileUnit(LinkingGlobalData &GlobalData, unsigned ID,
88
StringRef ClangModuleName, DWARFFile &File,
89
OffsetToUnitTy UnitFromOffset, dwarf::FormParams Format,
90
llvm::endianness Endianess);
91
92
CompileUnit(LinkingGlobalData &GlobalData, DWARFUnit &OrigUnit, unsigned ID,
93
StringRef ClangModuleName, DWARFFile &File,
94
OffsetToUnitTy UnitFromOffset, dwarf::FormParams Format,
95
llvm::endianness Endianess);
96
97
/// Returns stage of overall processing.
98
Stage getStage() const { return Stage; }
99
100
/// Set stage of overall processing.
101
void setStage(Stage Stage) { this->Stage = Stage; }
102
103
/// Loads unit line table.
104
void loadLineTable();
105
106
/// Returns name of the file for the \p FileIdx
107
/// from the unit`s line table.
108
StringEntry *getFileName(unsigned FileIdx, StringPool &GlobalStrings);
109
110
/// Returns DWARFFile containing this compile unit.
111
const DWARFFile &getContaingFile() const { return File; }
112
113
/// Load DIEs of input compilation unit. \returns true if input DIEs
114
/// successfully loaded.
115
bool loadInputDIEs();
116
117
/// Reset compile units data(results of liveness analysis, clonning)
118
/// if current stage greater than Stage::Loaded. We need to reset data
119
/// as we are going to repeat stages.
120
void maybeResetToLoadedStage();
121
122
/// Collect references to parseable Swift interfaces in imported
123
/// DW_TAG_module blocks.
124
void analyzeImportedModule(const DWARFDebugInfoEntry *DieEntry);
125
126
/// Navigate DWARF tree and set die properties.
127
void analyzeDWARFStructure() {
128
analyzeDWARFStructureRec(getUnitDIE().getDebugInfoEntry(), false);
129
}
130
131
/// Cleanup unneeded resources after compile unit is cloned.
132
void cleanupDataAfterClonning();
133
134
/// After cloning stage the output DIEs offsets are deallocated.
135
/// This method copies output offsets for referenced DIEs into DIEs patches.
136
void updateDieRefPatchesWithClonedOffsets();
137
138
/// Search for subprograms and variables referencing live code and discover
139
/// dependend DIEs. Mark live DIEs, set placement for DIEs.
140
bool resolveDependenciesAndMarkLiveness(
141
bool InterCUProcessingStarted,
142
std::atomic<bool> &HasNewInterconnectedCUs);
143
144
/// Check dependend DIEs for incompatible placement.
145
/// Make placement to be consistent.
146
bool updateDependenciesCompleteness();
147
148
/// Check DIEs to have a consistent marking(keep marking, placement marking).
149
void verifyDependencies();
150
151
/// Search for type entries and assign names.
152
Error assignTypeNames(TypePool &TypePoolRef);
153
154
/// Kinds of placement for the output die.
155
enum DieOutputPlacement : uint8_t {
156
NotSet = 0,
157
158
/// Corresponding DIE goes to the type table only.
159
TypeTable = 1,
160
161
/// Corresponding DIE goes to the plain dwarf only.
162
PlainDwarf = 2,
163
164
/// Corresponding DIE goes to type table and to plain dwarf.
165
Both = 3,
166
};
167
168
/// Information gathered about source DIEs.
169
struct DIEInfo {
170
DIEInfo() = default;
171
DIEInfo(const DIEInfo &Other) { Flags = Other.Flags.load(); }
172
DIEInfo &operator=(const DIEInfo &Other) {
173
Flags = Other.Flags.load();
174
return *this;
175
}
176
177
/// Data member keeping various flags.
178
std::atomic<uint16_t> Flags = {0};
179
180
/// \returns Placement kind for the corresponding die.
181
DieOutputPlacement getPlacement() const {
182
return DieOutputPlacement(Flags & 0x7);
183
}
184
185
/// Sets Placement kind for the corresponding die.
186
void setPlacement(DieOutputPlacement Placement) {
187
auto InputData = Flags.load();
188
while (!Flags.compare_exchange_weak(InputData,
189
((InputData & ~0x7) | Placement))) {
190
}
191
}
192
193
/// Unsets Placement kind for the corresponding die.
194
void unsetPlacement() {
195
auto InputData = Flags.load();
196
while (!Flags.compare_exchange_weak(InputData, (InputData & ~0x7))) {
197
}
198
}
199
200
/// Sets Placement kind for the corresponding die.
201
bool setPlacementIfUnset(DieOutputPlacement Placement) {
202
auto InputData = Flags.load();
203
if ((InputData & 0x7) == NotSet)
204
if (Flags.compare_exchange_weak(InputData, (InputData | Placement)))
205
return true;
206
207
return false;
208
}
209
210
#define SINGLE_FLAG_METHODS_SET(Name, Value) \
211
bool get##Name() const { return Flags & Value; } \
212
void set##Name() { \
213
auto InputData = Flags.load(); \
214
while (!Flags.compare_exchange_weak(InputData, InputData | Value)) { \
215
} \
216
} \
217
void unset##Name() { \
218
auto InputData = Flags.load(); \
219
while (!Flags.compare_exchange_weak(InputData, InputData & ~Value)) { \
220
} \
221
}
222
223
/// DIE is a part of the linked output.
224
SINGLE_FLAG_METHODS_SET(Keep, 0x08)
225
226
/// DIE has children which are part of the linked output.
227
SINGLE_FLAG_METHODS_SET(KeepPlainChildren, 0x10)
228
229
/// DIE has children which are part of the type table.
230
SINGLE_FLAG_METHODS_SET(KeepTypeChildren, 0x20)
231
232
/// DIE is in module scope.
233
SINGLE_FLAG_METHODS_SET(IsInMouduleScope, 0x40)
234
235
/// DIE is in function scope.
236
SINGLE_FLAG_METHODS_SET(IsInFunctionScope, 0x80)
237
238
/// DIE is in anonymous namespace scope.
239
SINGLE_FLAG_METHODS_SET(IsInAnonNamespaceScope, 0x100)
240
241
/// DIE is available for ODR type deduplication.
242
SINGLE_FLAG_METHODS_SET(ODRAvailable, 0x200)
243
244
/// Track liveness for the DIE.
245
SINGLE_FLAG_METHODS_SET(TrackLiveness, 0x400)
246
247
/// Track liveness for the DIE.
248
SINGLE_FLAG_METHODS_SET(HasAnAddress, 0x800)
249
250
void unsetFlagsWhichSetDuringLiveAnalysis() {
251
auto InputData = Flags.load();
252
while (!Flags.compare_exchange_weak(
253
InputData, InputData & ~(0x7 | 0x8 | 0x10 | 0x20))) {
254
}
255
}
256
257
/// Erase all flags.
258
void eraseData() { Flags = 0; }
259
260
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
261
LLVM_DUMP_METHOD void dump();
262
#endif
263
264
bool needToPlaceInTypeTable() const {
265
return (getKeep() && (getPlacement() == CompileUnit::TypeTable ||
266
getPlacement() == CompileUnit::Both)) ||
267
getKeepTypeChildren();
268
}
269
270
bool needToKeepInPlainDwarf() const {
271
return (getKeep() && (getPlacement() == CompileUnit::PlainDwarf ||
272
getPlacement() == CompileUnit::Both)) ||
273
getKeepPlainChildren();
274
}
275
};
276
277
/// \defgroup Group of functions returning DIE info.
278
///
279
/// @{
280
281
/// \p Idx index of the DIE.
282
/// \returns DieInfo descriptor.
283
DIEInfo &getDIEInfo(unsigned Idx) { return DieInfoArray[Idx]; }
284
285
/// \p Idx index of the DIE.
286
/// \returns DieInfo descriptor.
287
const DIEInfo &getDIEInfo(unsigned Idx) const { return DieInfoArray[Idx]; }
288
289
/// \p Idx index of the DIE.
290
/// \returns DieInfo descriptor.
291
DIEInfo &getDIEInfo(const DWARFDebugInfoEntry *Entry) {
292
return DieInfoArray[getOrigUnit().getDIEIndex(Entry)];
293
}
294
295
/// \p Idx index of the DIE.
296
/// \returns DieInfo descriptor.
297
const DIEInfo &getDIEInfo(const DWARFDebugInfoEntry *Entry) const {
298
return DieInfoArray[getOrigUnit().getDIEIndex(Entry)];
299
}
300
301
/// \p Die
302
/// \returns PlainDieInfo descriptor.
303
DIEInfo &getDIEInfo(const DWARFDie &Die) {
304
return DieInfoArray[getOrigUnit().getDIEIndex(Die)];
305
}
306
307
/// \p Die
308
/// \returns PlainDieInfo descriptor.
309
const DIEInfo &getDIEInfo(const DWARFDie &Die) const {
310
return DieInfoArray[getOrigUnit().getDIEIndex(Die)];
311
}
312
313
/// \p Idx index of the DIE.
314
/// \returns DieInfo descriptor.
315
uint64_t getDieOutOffset(uint32_t Idx) {
316
return reinterpret_cast<std::atomic<uint64_t> *>(&OutDieOffsetArray[Idx])
317
->load();
318
}
319
320
/// \p Idx index of the DIE.
321
/// \returns type entry.
322
TypeEntry *getDieTypeEntry(uint32_t Idx) {
323
return reinterpret_cast<std::atomic<TypeEntry *> *>(&TypeEntries[Idx])
324
->load();
325
}
326
327
/// \p InputDieEntry debug info entry.
328
/// \returns DieInfo descriptor.
329
uint64_t getDieOutOffset(const DWARFDebugInfoEntry *InputDieEntry) {
330
return reinterpret_cast<std::atomic<uint64_t> *>(
331
&OutDieOffsetArray[getOrigUnit().getDIEIndex(InputDieEntry)])
332
->load();
333
}
334
335
/// \p InputDieEntry debug info entry.
336
/// \returns type entry.
337
TypeEntry *getDieTypeEntry(const DWARFDebugInfoEntry *InputDieEntry) {
338
return reinterpret_cast<std::atomic<TypeEntry *> *>(
339
&TypeEntries[getOrigUnit().getDIEIndex(InputDieEntry)])
340
->load();
341
}
342
343
/// \p Idx index of the DIE.
344
/// \returns DieInfo descriptor.
345
void rememberDieOutOffset(uint32_t Idx, uint64_t Offset) {
346
reinterpret_cast<std::atomic<uint64_t> *>(&OutDieOffsetArray[Idx])
347
->store(Offset);
348
}
349
350
/// \p Idx index of the DIE.
351
/// \p Type entry.
352
void setDieTypeEntry(uint32_t Idx, TypeEntry *Entry) {
353
reinterpret_cast<std::atomic<TypeEntry *> *>(&TypeEntries[Idx])
354
->store(Entry);
355
}
356
357
/// \p InputDieEntry debug info entry.
358
/// \p Type entry.
359
void setDieTypeEntry(const DWARFDebugInfoEntry *InputDieEntry,
360
TypeEntry *Entry) {
361
reinterpret_cast<std::atomic<TypeEntry *> *>(
362
&TypeEntries[getOrigUnit().getDIEIndex(InputDieEntry)])
363
->store(Entry);
364
}
365
366
/// @}
367
368
/// Returns value of DW_AT_low_pc attribute.
369
std::optional<uint64_t> getLowPc() const { return LowPc; }
370
371
/// Returns value of DW_AT_high_pc attribute.
372
uint64_t getHighPc() const { return HighPc; }
373
374
/// Returns true if there is a label corresponding to the specified \p Addr.
375
bool hasLabelAt(uint64_t Addr) const { return Labels.count(Addr); }
376
377
/// Add the low_pc of a label that is relocated by applying
378
/// offset \p PCOffset.
379
void addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset);
380
381
/// Resolve the DIE attribute reference that has been extracted in \p
382
/// RefValue. The resulting DIE might be in another CompileUnit.
383
/// \returns referenced die and corresponding compilation unit.
384
/// compilation unit is null if reference could not be resolved.
385
std::optional<UnitEntryPairTy>
386
resolveDIEReference(const DWARFFormValue &RefValue,
387
ResolveInterCUReferencesMode CanResolveInterCUReferences);
388
389
std::optional<UnitEntryPairTy>
390
resolveDIEReference(const DWARFDebugInfoEntry *DieEntry,
391
dwarf::Attribute Attr,
392
ResolveInterCUReferencesMode CanResolveInterCUReferences);
393
394
/// @}
395
396
/// Add a function range [\p LowPC, \p HighPC) that is relocated by applying
397
/// offset \p PCOffset.
398
void addFunctionRange(uint64_t LowPC, uint64_t HighPC, int64_t PCOffset);
399
400
/// Returns function ranges of this unit.
401
const RangesTy &getFunctionRanges() const { return Ranges; }
402
403
/// Clone and emit this compilation unit.
404
Error
405
cloneAndEmit(std::optional<std::reference_wrapper<const Triple>> TargetTriple,
406
TypeUnit *ArtificialTypeUnit);
407
408
/// Clone and emit debug locations(.debug_loc/.debug_loclists).
409
Error cloneAndEmitDebugLocations();
410
411
/// Clone and emit ranges.
412
Error cloneAndEmitRanges();
413
414
/// Clone and emit debug macros(.debug_macinfo/.debug_macro).
415
Error cloneAndEmitDebugMacro();
416
417
// Clone input DIE entry.
418
std::pair<DIE *, TypeEntry *>
419
cloneDIE(const DWARFDebugInfoEntry *InputDieEntry,
420
TypeEntry *ClonedParentTypeDIE, uint64_t OutOffset,
421
std::optional<int64_t> FuncAddressAdjustment,
422
std::optional<int64_t> VarAddressAdjustment,
423
BumpPtrAllocator &Allocator, TypeUnit *ArtificialTypeUnit);
424
425
// Clone and emit line table.
426
Error cloneAndEmitLineTable(const Triple &TargetTriple);
427
428
/// Clone attribute location axpression.
429
void cloneDieAttrExpression(const DWARFExpression &InputExpression,
430
SmallVectorImpl<uint8_t> &OutputExpression,
431
SectionDescriptor &Section,
432
std::optional<int64_t> VarAddressAdjustment,
433
OffsetsPtrVector &PatchesOffsets);
434
435
/// Returns index(inside .debug_addr) of an address.
436
uint64_t getDebugAddrIndex(uint64_t Addr) {
437
return DebugAddrIndexMap.getValueIndex(Addr);
438
}
439
440
/// Returns directory and file from the line table by index.
441
std::optional<std::pair<StringRef, StringRef>>
442
getDirAndFilenameFromLineTable(const DWARFFormValue &FileIdxValue);
443
444
/// Returns directory and file from the line table by index.
445
std::optional<std::pair<StringRef, StringRef>>
446
getDirAndFilenameFromLineTable(uint64_t FileIdx);
447
448
/// \defgroup Helper methods to access OrigUnit.
449
///
450
/// @{
451
452
/// Returns paired compile unit from input DWARF.
453
DWARFUnit &getOrigUnit() const {
454
assert(OrigUnit != nullptr);
455
return *OrigUnit;
456
}
457
458
const DWARFDebugInfoEntry *
459
getFirstChildEntry(const DWARFDebugInfoEntry *Die) const {
460
assert(OrigUnit != nullptr);
461
return OrigUnit->getFirstChildEntry(Die);
462
}
463
464
const DWARFDebugInfoEntry *
465
getSiblingEntry(const DWARFDebugInfoEntry *Die) const {
466
assert(OrigUnit != nullptr);
467
return OrigUnit->getSiblingEntry(Die);
468
}
469
470
DWARFDie getParent(const DWARFDebugInfoEntry *Die) {
471
assert(OrigUnit != nullptr);
472
return OrigUnit->getParent(Die);
473
}
474
475
DWARFDie getDIEAtIndex(unsigned Index) {
476
assert(OrigUnit != nullptr);
477
return OrigUnit->getDIEAtIndex(Index);
478
}
479
480
const DWARFDebugInfoEntry *getDebugInfoEntry(unsigned Index) const {
481
assert(OrigUnit != nullptr);
482
return OrigUnit->getDebugInfoEntry(Index);
483
}
484
485
DWARFDie getUnitDIE(bool ExtractUnitDIEOnly = true) {
486
assert(OrigUnit != nullptr);
487
return OrigUnit->getUnitDIE(ExtractUnitDIEOnly);
488
}
489
490
DWARFDie getDIE(const DWARFDebugInfoEntry *Die) {
491
assert(OrigUnit != nullptr);
492
return DWARFDie(OrigUnit, Die);
493
}
494
495
uint32_t getDIEIndex(const DWARFDebugInfoEntry *Die) const {
496
assert(OrigUnit != nullptr);
497
return OrigUnit->getDIEIndex(Die);
498
}
499
500
uint32_t getDIEIndex(const DWARFDie &Die) const {
501
assert(OrigUnit != nullptr);
502
return OrigUnit->getDIEIndex(Die);
503
}
504
505
std::optional<DWARFFormValue> find(uint32_t DieIdx,
506
ArrayRef<dwarf::Attribute> Attrs) const {
507
assert(OrigUnit != nullptr);
508
return find(OrigUnit->getDebugInfoEntry(DieIdx), Attrs);
509
}
510
511
std::optional<DWARFFormValue> find(const DWARFDebugInfoEntry *Die,
512
ArrayRef<dwarf::Attribute> Attrs) const {
513
if (!Die)
514
return std::nullopt;
515
auto AbbrevDecl = Die->getAbbreviationDeclarationPtr();
516
if (AbbrevDecl) {
517
for (auto Attr : Attrs) {
518
if (auto Value = AbbrevDecl->getAttributeValue(Die->getOffset(), Attr,
519
*OrigUnit))
520
return Value;
521
}
522
}
523
return std::nullopt;
524
}
525
526
std::optional<uint32_t> getDIEIndexForOffset(uint64_t Offset) {
527
return OrigUnit->getDIEIndexForOffset(Offset);
528
}
529
530
/// @}
531
532
/// \defgroup Methods used for reporting warnings and errors:
533
///
534
/// @{
535
536
void warn(const Twine &Warning, const DWARFDie *DIE = nullptr) {
537
GlobalData.warn(Warning, getUnitName(), DIE);
538
}
539
540
void warn(Error Warning, const DWARFDie *DIE = nullptr) {
541
handleAllErrors(std::move(Warning), [&](ErrorInfoBase &Info) {
542
GlobalData.warn(Info.message(), getUnitName(), DIE);
543
});
544
}
545
546
void warn(const Twine &Warning, const DWARFDebugInfoEntry *DieEntry) {
547
if (DieEntry != nullptr) {
548
DWARFDie DIE(&getOrigUnit(), DieEntry);
549
GlobalData.warn(Warning, getUnitName(), &DIE);
550
return;
551
}
552
553
GlobalData.warn(Warning, getUnitName());
554
}
555
556
void error(const Twine &Err, const DWARFDie *DIE = nullptr) {
557
GlobalData.warn(Err, getUnitName(), DIE);
558
}
559
560
void error(Error Err, const DWARFDie *DIE = nullptr) {
561
handleAllErrors(std::move(Err), [&](ErrorInfoBase &Info) {
562
GlobalData.error(Info.message(), getUnitName(), DIE);
563
});
564
}
565
566
/// @}
567
568
/// Save specified accelerator info \p Info.
569
void saveAcceleratorInfo(const DwarfUnit::AccelInfo &Info) {
570
AcceleratorRecords.add(Info);
571
}
572
573
/// Enumerates all units accelerator records.
574
void
575
forEachAcceleratorRecord(function_ref<void(AccelInfo &)> Handler) override {
576
AcceleratorRecords.forEach(Handler);
577
}
578
579
/// Output unit selector.
580
class OutputUnitVariantPtr {
581
public:
582
OutputUnitVariantPtr(CompileUnit *U);
583
OutputUnitVariantPtr(TypeUnit *U);
584
585
/// Accessor for common functionality.
586
DwarfUnit *operator->();
587
588
bool isCompileUnit();
589
590
bool isTypeUnit();
591
592
/// Returns CompileUnit if applicable.
593
CompileUnit *getAsCompileUnit();
594
595
/// Returns TypeUnit if applicable.
596
TypeUnit *getAsTypeUnit();
597
598
protected:
599
PointerUnion<CompileUnit *, TypeUnit *> Ptr;
600
};
601
602
private:
603
/// Navigate DWARF tree recursively and set die properties.
604
void analyzeDWARFStructureRec(const DWARFDebugInfoEntry *DieEntry,
605
bool IsODRUnavailableFunctionScope);
606
607
struct LinkedLocationExpressionsWithOffsetPatches {
608
DWARFLocationExpression Expression;
609
OffsetsPtrVector Patches;
610
};
611
using LinkedLocationExpressionsVector =
612
SmallVector<LinkedLocationExpressionsWithOffsetPatches>;
613
614
/// Emit debug locations.
615
void emitLocations(DebugSectionKind LocationSectionKind);
616
617
/// Emit location list header.
618
uint64_t emitLocListHeader(SectionDescriptor &OutLocationSection);
619
620
/// Emit location list fragment.
621
uint64_t emitLocListFragment(
622
const LinkedLocationExpressionsVector &LinkedLocationExpression,
623
SectionDescriptor &OutLocationSection);
624
625
/// Emit the .debug_addr section fragment for current unit.
626
Error emitDebugAddrSection();
627
628
/// Emit .debug_aranges.
629
void emitAranges(AddressRanges &LinkedFunctionRanges);
630
631
/// Clone and emit .debug_ranges/.debug_rnglists.
632
void cloneAndEmitRangeList(DebugSectionKind RngSectionKind,
633
AddressRanges &LinkedFunctionRanges);
634
635
/// Emit range list header.
636
uint64_t emitRangeListHeader(SectionDescriptor &OutRangeSection);
637
638
/// Emit range list fragment.
639
void emitRangeListFragment(const AddressRanges &LinkedRanges,
640
SectionDescriptor &OutRangeSection);
641
642
/// Insert the new line info sequence \p Seq into the current
643
/// set of already linked line info \p Rows.
644
void insertLineSequence(std::vector<DWARFDebugLine::Row> &Seq,
645
std::vector<DWARFDebugLine::Row> &Rows);
646
647
/// Emits body for both macro sections.
648
void emitMacroTableImpl(const DWARFDebugMacro *MacroTable,
649
uint64_t OffsetToMacroTable, bool hasDWARFv5Header);
650
651
/// Creates DIE which would be placed into the "Plain" compile unit.
652
DIE *createPlainDIEandCloneAttributes(
653
const DWARFDebugInfoEntry *InputDieEntry, DIEGenerator &PlainDIEGenerator,
654
uint64_t &OutOffset, std::optional<int64_t> &FuncAddressAdjustment,
655
std::optional<int64_t> &VarAddressAdjustment);
656
657
/// Creates DIE which would be placed into the "Type" compile unit.
658
TypeEntry *createTypeDIEandCloneAttributes(
659
const DWARFDebugInfoEntry *InputDieEntry, DIEGenerator &TypeDIEGenerator,
660
TypeEntry *ClonedParentTypeDIE, TypeUnit *ArtificialTypeUnit);
661
662
/// Create output DIE inside specified \p TypeDescriptor.
663
DIE *allocateTypeDie(TypeEntryBody *TypeDescriptor,
664
DIEGenerator &TypeDIEGenerator, dwarf::Tag DieTag,
665
bool IsDeclaration, bool IsParentDeclaration);
666
667
/// Enumerate \p DieEntry children and assign names for them.
668
Error assignTypeNamesRec(const DWARFDebugInfoEntry *DieEntry,
669
SyntheticTypeNameBuilder &NameBuilder);
670
671
/// DWARFFile containing this compile unit.
672
DWARFFile &File;
673
674
/// Pointer to the paired compile unit from the input DWARF.
675
DWARFUnit *OrigUnit = nullptr;
676
677
/// The DW_AT_language of this unit.
678
std::optional<uint16_t> Language;
679
680
/// Line table for this unit.
681
const DWARFDebugLine::LineTable *LineTablePtr = nullptr;
682
683
/// Cached resolved paths from the line table.
684
/// The key is <UniqueUnitID, FileIdx>.
685
using ResolvedPathsMap = DenseMap<unsigned, StringEntry *>;
686
ResolvedPathsMap ResolvedFullPaths;
687
StringMap<StringEntry *> ResolvedParentPaths;
688
689
/// Maps an address into the index inside .debug_addr section.
690
IndexedValuesMap<uint64_t> DebugAddrIndexMap;
691
692
std::unique_ptr<DependencyTracker> Dependencies;
693
694
/// \defgroup Data Members accessed asinchronously.
695
///
696
/// @{
697
OffsetToUnitTy getUnitFromOffset;
698
699
std::optional<uint64_t> LowPc;
700
uint64_t HighPc = 0;
701
702
/// Flag indicating whether type de-duplication is forbidden.
703
bool NoODR = true;
704
705
/// The ranges in that map are the PC ranges for functions in this unit,
706
/// associated with the PC offset to apply to the addresses to get
707
/// the linked address.
708
RangesTy Ranges;
709
std::mutex RangesMutex;
710
711
/// The DW_AT_low_pc of each DW_TAG_label.
712
using LabelMapTy = SmallDenseMap<uint64_t, uint64_t, 1>;
713
LabelMapTy Labels;
714
std::mutex LabelsMutex;
715
716
/// This field keeps current stage of overall compile unit processing.
717
std::atomic<Stage> Stage;
718
719
/// DIE info indexed by DIE index.
720
SmallVector<DIEInfo> DieInfoArray;
721
SmallVector<uint64_t> OutDieOffsetArray;
722
SmallVector<TypeEntry *> TypeEntries;
723
724
/// The list of accelerator records for this unit.
725
ArrayList<AccelInfo> AcceleratorRecords;
726
/// @}
727
};
728
729
/// \returns list of attributes referencing type DIEs which might be
730
/// deduplicated.
731
/// Note: it does not include DW_AT_containing_type attribute to avoid
732
/// infinite recursion.
733
ArrayRef<dwarf::Attribute> getODRAttributes();
734
735
} // end of namespace parallel
736
} // end of namespace dwarf_linker
737
} // end of namespace llvm
738
739
#endif // LLVM_LIB_DWARFLINKER_PARALLEL_DWARFLINKERCOMPILEUNIT_H
740
741