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.cpp
35291 views
1
//=== DWARFLinkerCompileUnit.cpp ------------------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
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"
22
#include <utility>
23
24
using namespace llvm;
25
using namespace dwarf_linker;
26
using namespace dwarf_linker::parallel;
27
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);
38
}
39
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);
50
51
DWARFDie CUDie = OrigUnit.getUnitDIE();
52
if (!CUDie)
53
return;
54
55
if (std::optional<DWARFFormValue> Val = CUDie.find(dwarf::DW_AT_language)) {
56
uint16_t LangVal = dwarf::toUnsigned(Val, 0);
57
if (isODRLanguage(LangVal))
58
Language = LangVal;
59
}
60
61
if (!GlobalData.getOptions().NoODR && Language.has_value())
62
NoODR = false;
63
64
if (const char *CUName = CUDie.getName(DINameKind::ShortName))
65
UnitName = CUName;
66
else
67
UnitName = File.FileName;
68
SysRoot = dwarf::toStringRef(CUDie.find(dwarf::DW_AT_LLVM_sysroot)).str();
69
}
70
71
void CompileUnit::loadLineTable() {
72
LineTablePtr = File.Dwarf->getLineTableForUnit(&getOrigUnit());
73
}
74
75
void CompileUnit::maybeResetToLoadedStage() {
76
// Nothing to reset if stage is less than "Loaded".
77
if (getStage() < Stage::Loaded)
78
return;
79
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.
84
85
for (DIEInfo &Info : DieInfoArray)
86
Info.unsetFlagsWhichSetDuringLiveAnalysis();
87
88
LowPc = std::nullopt;
89
HighPc = 0;
90
Labels.clear();
91
Ranges.clear();
92
Dependencies.reset(nullptr);
93
94
if (getStage() < Stage::Cloned) {
95
setStage(Stage::Loaded);
96
return;
97
}
98
99
AcceleratorRecords.erase();
100
AbbreviationsSet.clear();
101
Abbreviations.clear();
102
OutUnitDIE = nullptr;
103
DebugAddrIndexMap.clear();
104
105
for (uint64_t &Offset : OutDieOffsetArray)
106
Offset = 0;
107
for (TypeEntry *&Name : TypeEntries)
108
Name = nullptr;
109
eraseSections();
110
111
setStage(Stage::CreatedNotLoaded);
112
}
113
114
bool CompileUnit::loadInputDIEs() {
115
DWARFDie InputUnitDIE = getUnitDIE(false);
116
if (!InputUnitDIE)
117
return false;
118
119
// load input dies, resize Info structures array.
120
DieInfoArray.resize(getOrigUnit().getNumDIEs());
121
OutDieOffsetArray.resize(getOrigUnit().getNumDIEs(), 0);
122
if (!NoODR)
123
TypeEntries.resize(getOrigUnit().getNumDIEs());
124
return true;
125
}
126
127
void CompileUnit::analyzeDWARFStructureRec(const DWARFDebugInfoEntry *DieEntry,
128
bool IsODRUnavailableFunctionScope) {
129
CompileUnit::DIEInfo &DieInfo = getDIEInfo(DieEntry);
130
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;
136
137
if (DieInfo.getIsInMouduleScope())
138
ChildInfo.setIsInMouduleScope();
139
140
if (DieInfo.getIsInFunctionScope())
141
ChildInfo.setIsInFunctionScope();
142
143
if (DieInfo.getIsInAnonNamespaceScope())
144
ChildInfo.setIsInAnonNamespaceScope();
145
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);
153
break;
154
case dwarf::DW_TAG_subprogram:
155
ChildInfo.setIsInFunctionScope();
156
if (!ChildIsODRUnavailableFunctionScope &&
157
!ChildInfo.getIsInMouduleScope()) {
158
if (find(CurChild,
159
{dwarf::DW_AT_abstract_origin, dwarf::DW_AT_specification}))
160
ChildIsODRUnavailableFunctionScope = true;
161
}
162
break;
163
case dwarf::DW_TAG_namespace: {
164
UnitEntryPairTy NamespaceEntry = {this, CurChild};
165
166
if (find(CurChild, dwarf::DW_AT_extension))
167
NamespaceEntry = NamespaceEntry.getNamespaceOrigin();
168
169
if (!NamespaceEntry.CU->find(NamespaceEntry.DieEntry, dwarf::DW_AT_name))
170
ChildInfo.setIsInAnonNamespaceScope();
171
} break;
172
default:
173
break;
174
}
175
176
if (!isClangModule() && !getGlobalData().getOptions().UpdateIndexTablesOnly)
177
ChildInfo.setTrackLiveness();
178
179
if ((!ChildInfo.getIsInAnonNamespaceScope() &&
180
!ChildIsODRUnavailableFunctionScope && !NoODR))
181
ChildInfo.setODRAvailable();
182
183
if (CurChild->hasChildren())
184
analyzeDWARFStructureRec(CurChild, ChildIsODRUnavailableFunctionScope);
185
}
186
}
187
188
StringEntry *CompileUnit::getFileName(unsigned FileIdx,
189
StringPool &GlobalStrings) {
190
if (LineTablePtr) {
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,
200
OrigFileName);
201
(void)FoundFileName;
202
assert(FoundFileName && "Must get file name from line table");
203
204
// Second level of caching, this time based on the file's parent
205
// path.
206
StringRef FileName = sys::path::filename(OrigFileName);
207
StringRef ParentPath = sys::path::parent_path(OrigFileName);
208
209
// If the ParentPath has not yet been resolved, resolve and cache it for
210
// future look-ups.
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);
216
ParentIt =
217
ResolvedParentPaths
218
.insert({ParentPath, GlobalStrings.insert(RealPath).first})
219
.first;
220
}
221
222
// Join the file name again with the resolved path.
223
SmallString<256> ResolvedPath(ParentIt->second->first());
224
sys::path::append(ResolvedPath, FileName);
225
226
It = ResolvedFullPaths
227
.insert(std::make_pair(
228
FileIdx, GlobalStrings.insert(ResolvedPath).first))
229
.first;
230
}
231
232
return It->second;
233
}
234
}
235
236
return nullptr;
237
}
238
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();
249
}
250
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)
255
return;
256
257
if (!GlobalData.getOptions().ParseableSwiftInterfaces)
258
return;
259
260
StringRef Path =
261
dwarf::toStringRef(find(DieEntry, dwarf::DW_AT_LLVM_include_path));
262
if (!Path.ends_with(".swiftinterface"))
263
return;
264
// Don't track interfaces that are part of the SDK.
265
StringRef SysRoot =
266
dwarf::toStringRef(find(DieEntry, dwarf::DW_AT_LLVM_sysroot));
267
if (SysRoot.empty())
268
SysRoot = getSysRoot();
269
if (!SysRoot.empty() && Path.starts_with(SysRoot))
270
return;
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))
275
return;
276
if (isInToolchainDir(Path))
277
return;
278
if (std::optional<DWARFFormValue> Val = find(DieEntry, dwarf::DW_AT_name)) {
279
Expected<const char *> Name = Val->getAsCString();
280
if (!Name) {
281
warn(Name.takeError());
282
return;
283
}
284
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))
289
sys::path::append(
290
ResolvedPath,
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 + ".",
297
&Die);
298
}
299
Entry = std::string(ResolvedPath);
300
}
301
}
302
303
Error CompileUnit::assignTypeNames(TypePool &TypePoolRef) {
304
if (!getUnitDIE().isValid())
305
return Error::success();
306
307
SyntheticTypeNameBuilder NameBuilder(TypePoolRef);
308
return assignTypeNamesRec(getDebugInfoEntry(0), NameBuilder);
309
}
310
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())
319
continue;
320
321
assert(ChildInfo.getODRAvailable());
322
if (Error Err = NameBuilder.assignName(
323
{this, CurChild},
324
ChildrenIndexAssigner.getChildIndex(*this, CurChild)))
325
return Err;
326
327
if (Error Err = assignTypeNamesRec(CurChild, NameBuilder))
328
return Err;
329
}
330
331
return Error::success();
332
}
333
334
void CompileUnit::updateDieRefPatchesWithClonedOffsets() {
335
if (std::optional<SectionDescriptor *> DebugInfoSection =
336
tryGetSectionDescriptor(DebugSectionKind::DebugInfo)) {
337
338
(*DebugInfoSection)
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);
344
});
345
346
(*DebugInfoSection)
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);
353
});
354
}
355
356
if (std::optional<SectionDescriptor *> DebugLocSection =
357
tryGetSectionDescriptor(DebugSectionKind::DebugLoc)) {
358
(*DebugLocSection)
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);
365
});
366
}
367
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);
377
});
378
}
379
}
380
381
std::optional<UnitEntryPairTy> CompileUnit::resolveDIEReference(
382
const DWARFFormValue &RefValue,
383
ResolveInterCUReferencesMode CanResolveInterCUReferences) {
384
CompileUnit *RefCU;
385
uint64_t RefDIEOffset;
386
if (std::optional<uint64_t> Offset = RefValue.getAsRelativeReference()) {
387
RefCU = this;
388
RefDIEOffset = RefValue.getUnit()->getOffset() + *Offset;
389
} else if (Offset = RefValue.getAsDebugInfoReference(); Offset) {
390
RefCU = getUnitFromOffset(*Offset);
391
RefDIEOffset = *Offset;
392
} else {
393
return std::nullopt;
394
}
395
396
if (RefCU == this) {
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.
402
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};
407
408
if (std::optional<uint32_t> RefDieIdx =
409
RefCU->getDIEIndexForOffset(RefDIEOffset))
410
return UnitEntryPairTy{RefCU, RefCU->getDebugInfoEntry(*RefDieIdx)};
411
} else {
412
return UnitEntryPairTy{RefCU, nullptr};
413
}
414
return std::nullopt;
415
}
416
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);
422
423
return std::nullopt;
424
}
425
426
void CompileUnit::addFunctionRange(uint64_t FuncLowPc, uint64_t FuncHighPc,
427
int64_t PcOffset) {
428
std::lock_guard<std::mutex> Guard(RangesMutex);
429
430
Ranges.insert({FuncLowPc, FuncHighPc}, PcOffset);
431
if (LowPc)
432
LowPc = std::min(*LowPc, FuncLowPc + PcOffset);
433
else
434
LowPc = FuncLowPc + PcOffset;
435
this->HighPc = std::max(HighPc, FuncHighPc + PcOffset);
436
}
437
438
void CompileUnit::addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset) {
439
std::lock_guard<std::mutex> Guard(LabelsMutex);
440
Labels.insert({LabelLowPc, PcOffset});
441
}
442
443
Error CompileUnit::cloneAndEmitDebugLocations() {
444
if (getGlobalData().getOptions().UpdateIndexTablesOnly)
445
return Error::success();
446
447
if (getOrigUnit().getVersion() < 5) {
448
emitLocations(DebugSectionKind::DebugLoc);
449
return Error::success();
450
}
451
452
emitLocations(DebugSectionKind::DebugLocLists);
453
return Error::success();
454
}
455
456
void CompileUnit::emitLocations(DebugSectionKind LocationSectionKind) {
457
SectionDescriptor &DebugInfoSection =
458
getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);
459
460
if (!DebugInfoSection.ListDebugLocPatch.empty()) {
461
SectionDescriptor &OutLocationSection =
462
getOrCreateSectionDescriptor(LocationSectionKind);
463
DWARFUnit &OrigUnit = getOrigUnit();
464
465
uint64_t OffsetAfterUnitLength = emitLocListHeader(OutLocationSection);
466
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(
471
Patch.PatchOffset,
472
DebugInfoSection.getFormParams().getDwarfOffsetByteSize());
473
Expected<DWARFLocationExpressionsVector> OriginalLocations =
474
OrigUnit.findLoclistFromOffset(InputDebugLocSectionOffset);
475
476
if (!OriginalLocations) {
477
warn(OriginalLocations.takeError());
478
return;
479
}
480
481
LinkedLocationExpressionsVector LinkedLocationExpressions;
482
for (DWARFLocationExpression &CurExpression : *OriginalLocations) {
483
LinkedLocationExpressionsWithOffsetPatches LinkedExpression;
484
485
if (CurExpression.Range) {
486
// Relocate address range.
487
LinkedExpression.Expression.Range = {
488
CurExpression.Range->LowPC + Patch.AddrAdjustmentValue,
489
CurExpression.Range->HighPC + Patch.AddrAdjustmentValue};
490
}
491
492
DataExtractor Data(CurExpression.Expr, OrigUnit.isLittleEndian(),
493
OrigUnit.getAddressByteSize());
494
495
DWARFExpression InputExpression(Data, OrigUnit.getAddressByteSize(),
496
OrigUnit.getFormParams().Format);
497
cloneDieAttrExpression(InputExpression,
498
LinkedExpression.Expression.Expr,
499
OutLocationSection, Patch.AddrAdjustmentValue,
500
LinkedExpression.Patches);
501
502
LinkedLocationExpressions.push_back({LinkedExpression});
503
}
504
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);
509
});
510
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);
520
}
521
}
522
}
523
524
/// Emit debug locations(.debug_loc, .debug_loclists) header.
525
uint64_t CompileUnit::emitLocListHeader(SectionDescriptor &OutLocationSection) {
526
if (getOrigUnit().getVersion() < 5)
527
return 0;
528
529
// unit_length.
530
OutLocationSection.emitUnitLength(0xBADDEF);
531
uint64_t OffsetAfterUnitLength = OutLocationSection.OS.tell();
532
533
// Version.
534
OutLocationSection.emitIntVal(5, 2);
535
536
// Address size.
537
OutLocationSection.emitIntVal(OutLocationSection.getFormParams().AddrSize, 1);
538
539
// Seg_size
540
OutLocationSection.emitIntVal(0, 1);
541
542
// Offset entry count
543
OutLocationSection.emitIntVal(0, 4);
544
545
return OffsetAfterUnitLength;
546
}
547
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;
553
554
if (getOrigUnit().getVersion() < 5) {
555
uint64_t BaseAddress = 0;
556
if (std::optional<uint64_t> LowPC = getLowPc())
557
BaseAddress = *LowPC;
558
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);
568
}
569
570
OutLocationSection.emitIntVal(LocExpression.Expression.Expr.size(), 2);
571
OffsetBeforeLocationExpression = OutLocationSection.OS.tell();
572
for (uint64_t *OffsetPtr : LocExpression.Patches)
573
*OffsetPtr += OffsetBeforeLocationExpression;
574
575
OutLocationSection.OS
576
<< StringRef((const char *)LocExpression.Expression.Expr.data(),
577
LocExpression.Expression.Expr.size());
578
}
579
580
// Emit the terminator entry.
581
OutLocationSection.emitIntVal(0,
582
OutLocationSection.getFormParams().AddrSize);
583
OutLocationSection.emitIntVal(0,
584
OutLocationSection.getFormParams().AddrSize);
585
return OffsetBeforeLocationExpression;
586
}
587
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.
594
if (!BaseAddress) {
595
BaseAddress = LocExpression.Expression.Range->LowPC;
596
597
// Emit base address.
598
OutLocationSection.emitIntVal(dwarf::DW_LLE_base_addressx, 1);
599
encodeULEB128(DebugAddrIndexMap.getValueIndex(*BaseAddress),
600
OutLocationSection.OS);
601
}
602
603
// Emit type of entry.
604
OutLocationSection.emitIntVal(dwarf::DW_LLE_offset_pair, 1);
605
606
// Emit start offset relative to base address.
607
encodeULEB128(LocExpression.Expression.Range->LowPC - *BaseAddress,
608
OutLocationSection.OS);
609
610
// Emit end offset relative to base address.
611
encodeULEB128(LocExpression.Expression.Range->HighPC - *BaseAddress,
612
OutLocationSection.OS);
613
} else
614
// Emit type of entry.
615
OutLocationSection.emitIntVal(dwarf::DW_LLE_default_location, 1);
616
617
encodeULEB128(LocExpression.Expression.Expr.size(), OutLocationSection.OS);
618
OffsetBeforeLocationExpression = OutLocationSection.OS.tell();
619
for (uint64_t *OffsetPtr : LocExpression.Patches)
620
*OffsetPtr += OffsetBeforeLocationExpression;
621
622
OutLocationSection.OS << StringRef(
623
(const char *)LocExpression.Expression.Expr.data(),
624
LocExpression.Expression.Expr.size());
625
}
626
627
// Emit the terminator entry.
628
OutLocationSection.emitIntVal(dwarf::DW_LLE_end_of_list, 1);
629
return OffsetBeforeLocationExpression;
630
}
631
632
Error CompileUnit::emitDebugAddrSection() {
633
if (GlobalData.getOptions().UpdateIndexTablesOnly)
634
return Error::success();
635
636
if (getVersion() < 5)
637
return Error::success();
638
639
if (DebugAddrIndexMap.empty())
640
return Error::success();
641
642
SectionDescriptor &OutAddrSection =
643
getOrCreateSectionDescriptor(DebugSectionKind::DebugAddr);
644
645
// Emit section header.
646
647
// Emit length.
648
OutAddrSection.emitUnitLength(0xBADDEF);
649
uint64_t OffsetAfterSectionLength = OutAddrSection.OS.tell();
650
651
// Emit version.
652
OutAddrSection.emitIntVal(5, 2);
653
654
// Emit address size.
655
OutAddrSection.emitIntVal(getFormParams().AddrSize, 1);
656
657
// Emit segment size.
658
OutAddrSection.emitIntVal(0, 1);
659
660
// Emit addresses.
661
for (uint64_t AddrValue : DebugAddrIndexMap.getValues())
662
OutAddrSection.emitIntVal(AddrValue, getFormParams().AddrSize);
663
664
// Patch section length.
665
OutAddrSection.apply(
666
OffsetAfterSectionLength -
667
OutAddrSection.getFormParams().getDwarfOffsetByteSize(),
668
dwarf::DW_FORM_sec_offset,
669
OutAddrSection.OS.tell() - OffsetAfterSectionLength);
670
671
return Error::success();
672
}
673
674
Error CompileUnit::cloneAndEmitRanges() {
675
if (getGlobalData().getOptions().UpdateIndexTablesOnly)
676
return Error::success();
677
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});
683
684
emitAranges(LinkedFunctionRanges);
685
686
if (getOrigUnit().getVersion() < 5) {
687
cloneAndEmitRangeList(DebugSectionKind::DebugRange, LinkedFunctionRanges);
688
return Error::success();
689
}
690
691
cloneAndEmitRangeList(DebugSectionKind::DebugRngLists, LinkedFunctionRanges);
692
return Error::success();
693
}
694
695
void CompileUnit::cloneAndEmitRangeList(DebugSectionKind RngSectionKind,
696
AddressRanges &LinkedFunctionRanges) {
697
SectionDescriptor &DebugInfoSection =
698
getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);
699
SectionDescriptor &OutRangeSection =
700
getOrCreateSectionDescriptor(RngSectionKind);
701
702
if (!DebugInfoSection.ListDebugRangePatch.empty()) {
703
std::optional<AddressRangeValuePair> CachedRange;
704
uint64_t OffsetAfterUnitLength = emitRangeListHeader(OutRangeSection);
705
706
DebugRangePatch *CompileUnitRangePtr = nullptr;
707
DebugInfoSection.ListDebugRangePatch.forEach([&](DebugRangePatch &Patch) {
708
if (Patch.IsCompileUnitRanges) {
709
CompileUnitRangePtr = &Patch;
710
} else {
711
// Get ranges from the source DWARF corresponding to the current
712
// attribute.
713
AddressRanges LinkedRanges;
714
uint64_t InputDebugRangesSectionOffset = DebugInfoSection.getIntVal(
715
Patch.PatchOffset,
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))
723
CachedRange =
724
getFunctionRanges().getRangeThatContains(Range.LowPC);
725
726
// All range entries should lie in the function range.
727
if (!CachedRange) {
728
warn("inconsistent range data.");
729
continue;
730
}
731
732
// Store range for emiting.
733
LinkedRanges.insert({Range.LowPC + CachedRange->Value,
734
Range.HighPC + CachedRange->Value});
735
}
736
} else {
737
llvm::consumeError(InputRanges.takeError());
738
warn("invalid range list ignored.");
739
}
740
741
// Emit linked ranges.
742
DebugInfoSection.apply(Patch.PatchOffset, dwarf::DW_FORM_sec_offset,
743
OutRangeSection.OS.tell());
744
emitRangeListFragment(LinkedRanges, OutRangeSection);
745
}
746
});
747
748
if (CompileUnitRangePtr != nullptr) {
749
// Emit compile unit ranges last to be binary compatible with classic
750
// dsymutil.
751
DebugInfoSection.apply(CompileUnitRangePtr->PatchOffset,
752
dwarf::DW_FORM_sec_offset,
753
OutRangeSection.OS.tell());
754
emitRangeListFragment(LinkedFunctionRanges, OutRangeSection);
755
}
756
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);
766
}
767
}
768
}
769
770
uint64_t CompileUnit::emitRangeListHeader(SectionDescriptor &OutRangeSection) {
771
if (OutRangeSection.getFormParams().Version < 5)
772
return 0;
773
774
// unit_length.
775
OutRangeSection.emitUnitLength(0xBADDEF);
776
uint64_t OffsetAfterUnitLength = OutRangeSection.OS.tell();
777
778
// Version.
779
OutRangeSection.emitIntVal(5, 2);
780
781
// Address size.
782
OutRangeSection.emitIntVal(OutRangeSection.getFormParams().AddrSize, 1);
783
784
// Seg_size
785
OutRangeSection.emitIntVal(0, 1);
786
787
// Offset entry count
788
OutRangeSection.emitIntVal(0, 4);
789
790
return OffsetAfterUnitLength;
791
}
792
793
void CompileUnit::emitRangeListFragment(const AddressRanges &LinkedRanges,
794
SectionDescriptor &OutRangeSection) {
795
if (OutRangeSection.getFormParams().Version < 5) {
796
// Emit ranges.
797
uint64_t BaseAddress = 0;
798
if (std::optional<uint64_t> LowPC = getLowPc())
799
BaseAddress = *LowPC;
800
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);
806
}
807
808
// Add the terminator entry.
809
OutRangeSection.emitIntVal(0, OutRangeSection.getFormParams().AddrSize);
810
OutRangeSection.emitIntVal(0, OutRangeSection.getFormParams().AddrSize);
811
return;
812
}
813
814
std::optional<uint64_t> BaseAddress;
815
for (const AddressRange &Range : LinkedRanges) {
816
if (!BaseAddress) {
817
BaseAddress = Range.start();
818
819
// Emit base address.
820
OutRangeSection.emitIntVal(dwarf::DW_RLE_base_addressx, 1);
821
encodeULEB128(getDebugAddrIndex(*BaseAddress), OutRangeSection.OS);
822
}
823
824
// Emit type of entry.
825
OutRangeSection.emitIntVal(dwarf::DW_RLE_offset_pair, 1);
826
827
// Emit start offset relative to base address.
828
encodeULEB128(Range.start() - *BaseAddress, OutRangeSection.OS);
829
830
// Emit end offset relative to base address.
831
encodeULEB128(Range.end() - *BaseAddress, OutRangeSection.OS);
832
}
833
834
// Emit the terminator entry.
835
OutRangeSection.emitIntVal(dwarf::DW_RLE_end_of_list, 1);
836
}
837
838
void CompileUnit::emitAranges(AddressRanges &LinkedFunctionRanges) {
839
if (LinkedFunctionRanges.empty())
840
return;
841
842
SectionDescriptor &DebugInfoSection =
843
getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);
844
SectionDescriptor &OutArangesSection =
845
getOrCreateSectionDescriptor(DebugSectionKind::DebugARanges);
846
847
// Emit Header.
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)
854
855
unsigned TupleSize = OutArangesSection.getFormParams().AddrSize * 2;
856
unsigned Padding = offsetToAlignment(HeaderSize, Align(TupleSize));
857
858
OutArangesSection.emitOffset(0xBADDEF); // Aranges length
859
uint64_t OffsetAfterArangesLengthField = OutArangesSection.OS.tell();
860
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,
866
1); // Address size
867
OutArangesSection.emitIntVal(0, 1); // Segment size
868
869
for (size_t Idx = 0; Idx < Padding; Idx++)
870
OutArangesSection.emitIntVal(0, 1); // Padding
871
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);
878
}
879
880
// Emit terminator.
881
OutArangesSection.emitIntVal(0, OutArangesSection.getFormParams().AddrSize);
882
OutArangesSection.emitIntVal(0, OutArangesSection.getFormParams().AddrSize);
883
884
uint64_t OffsetAfterArangesEnd = OutArangesSection.OS.tell();
885
886
// Update Aranges lentgh.
887
OutArangesSection.apply(
888
OffsetAfterArangesLengthField -
889
OutArangesSection.getFormParams().getDwarfOffsetByteSize(),
890
dwarf::DW_FORM_sec_offset,
891
OffsetAfterArangesEnd - OffsetAfterArangesLengthField);
892
}
893
894
Error CompileUnit::cloneAndEmitDebugMacro() {
895
if (getOutUnitDIE() == nullptr)
896
return Error::success();
897
898
DWARFUnit &OrigUnit = getOrigUnit();
899
DWARFDie OrigUnitDie = OrigUnit.getUnitDIE();
900
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);
907
}
908
}
909
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);
916
}
917
}
918
919
return Error::success();
920
}
921
922
void CompileUnit::emitMacroTableImpl(const DWARFDebugMacro *MacroTable,
923
uint64_t OffsetToMacroTable,
924
bool hasDWARFv5Header) {
925
SectionDescriptor &OutSection =
926
hasDWARFv5Header
927
? getOrCreateSectionDescriptor(DebugSectionKind::DebugMacro)
928
: getOrCreateSectionDescriptor(DebugSectionKind::DebugMacinfo);
929
930
bool DefAttributeIsReported = false;
931
bool UndefAttributeIsReported = false;
932
bool ImportAttributeIsReported = false;
933
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));
940
941
uint8_t Flags = List.Header.Flags;
942
943
// Check for OPCODE_OPERANDS_TABLE.
944
if (Flags &
945
DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE) {
946
Flags &=
947
~DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE;
948
warn("opcode_operands_table is not supported yet.");
949
}
950
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();
958
break;
959
}
960
}
961
962
if (!StmtListOffset) {
963
Flags &= ~DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET;
964
warn("couldn`t find line table for macro table.");
965
}
966
}
967
968
// Write flags.
969
OutSection.emitIntVal(Flags, sizeof(Flags));
970
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());
979
}
980
}
981
982
// Write macro entries.
983
for (const DWARFDebugMacro::Entry &MacroEntry : List.Macros) {
984
if (MacroEntry.Type == 0) {
985
encodeULEB128(MacroEntry.Type, OutSection.OS);
986
continue;
987
}
988
989
uint8_t MacroType = MacroEntry.Type;
990
switch (MacroType) {
991
default: {
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));
997
998
if (HasVendorSpecificExtension) {
999
// Write macinfo type.
1000
OutSection.emitIntVal(MacroType, 1);
1001
1002
// Write vendor extension constant.
1003
encodeULEB128(MacroEntry.ExtConstant, OutSection.OS);
1004
1005
// Write vendor extension string.
1006
OutSection.emitString(dwarf::DW_FORM_string, MacroEntry.ExtStr);
1007
} else
1008
warn("unknown macro type. skip.");
1009
} break;
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);
1020
1021
// Write source line.
1022
encodeULEB128(MacroEntry.Line, OutSection.OS);
1023
1024
// Write macro string.
1025
OutSection.emitString(dwarf::DW_FORM_string, MacroEntry.MacroStr);
1026
} break;
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;
1040
}
1041
} break;
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;
1048
}
1049
} break;
1050
default:
1051
// Nothing to do.
1052
break;
1053
}
1054
1055
// Write macinfo type.
1056
OutSection.emitIntVal(MacroType, 1);
1057
1058
// Write source line.
1059
encodeULEB128(MacroEntry.Line, OutSection.OS);
1060
1061
// Write macro string.
1062
OutSection.emitString(dwarf::DW_FORM_strp, MacroEntry.MacroStr);
1063
break;
1064
}
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);
1072
} break;
1073
case dwarf::DW_MACRO_end_file: {
1074
// Write macinfo type.
1075
OutSection.emitIntVal(MacroType, 1);
1076
} break;
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 "
1081
"yet. remove.");
1082
ImportAttributeIsReported = true;
1083
}
1084
} break;
1085
}
1086
}
1087
1088
return;
1089
}
1090
}
1091
}
1092
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;
1099
1100
DWARFUnit &OrigUnit = getOrigUnit();
1101
uint8_t OrigAddressByteSize = OrigUnit.getAddressByteSize();
1102
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.");
1112
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);
1120
1121
// Copy over the operation.
1122
assert(!Op.getSubCode() && "SubOps not yet supported");
1123
OutputExpression.push_back(Op.getCode());
1124
uint64_t RefOffset;
1125
if (Desc.Op.size() == 1) {
1126
RefOffset = Op.getRawOperand(0);
1127
} else {
1128
OutputExpression.push_back(Op.getRawOperand(0));
1129
RefOffset = Op.getRawOperand(1);
1130
}
1131
uint8_t ULEB[16];
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))
1142
RefDieIdx = *Idx;
1143
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;
1147
1148
RealSize = encodeULEB128(0xBADDEF, ULEB, ULEBsize);
1149
1150
Section.notePatchWithOffsetUpdate(
1151
DebugULEB128DieRefPatch(OutputExpression.size(), this, this,
1152
RefDieIdx),
1153
PatchesOffsets);
1154
} else
1155
RealSize = encodeULEB128(Offset, ULEB, ULEBsize);
1156
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.");
1161
}
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());
1182
} else
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) {
1194
case 2:
1195
OutOperandKind = dwarf::DW_OP_const2u;
1196
break;
1197
case 4:
1198
OutOperandKind = dwarf::DW_OP_const4u;
1199
break;
1200
case 8:
1201
OutOperandKind = dwarf::DW_OP_const8u;
1202
break;
1203
default:
1204
warn(
1205
formatv(("unsupported address size: {0}."), OrigAddressByteSize));
1206
break;
1207
}
1208
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());
1219
}
1220
} else
1221
warn("cann't read DW_OP_constx operand.");
1222
} else {
1223
// Copy over everything else unmodified.
1224
StringRef Bytes =
1225
InputExpression.getData().slice(OpOffset, Op.getEndOffset());
1226
OutputExpression.append(Bytes.begin(), Bytes.end());
1227
}
1228
OpOffset = Op.getEndOffset();
1229
}
1230
}
1231
1232
Error CompileUnit::cloneAndEmit(
1233
std::optional<std::reference_wrapper<const Triple>> TargetTriple,
1234
TypeUnit *ArtificialTypeUnit) {
1235
BumpPtrAllocator Allocator;
1236
1237
DWARFDie OrigUnitDIE = getOrigUnit().getUnitDIE();
1238
if (!OrigUnitDIE.isValid())
1239
return Error::success();
1240
1241
TypeEntry *RootEntry = nullptr;
1242
if (ArtificialTypeUnit)
1243
RootEntry = ArtificialTypeUnit->getTypePool().getRoot();
1244
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);
1250
1251
if (!TargetTriple.has_value() || (OutCUDie.first == nullptr))
1252
return Error::success();
1253
1254
if (Error Err = cloneAndEmitLineTable((*TargetTriple).get()))
1255
return Err;
1256
1257
if (Error Err = cloneAndEmitDebugMacro())
1258
return Err;
1259
1260
getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);
1261
if (Error Err = emitDebugInfo((*TargetTriple).get()))
1262
return Err;
1263
1264
// ASSUMPTION: .debug_info section should already be emitted at this point.
1265
// cloneAndEmitRanges & cloneAndEmitDebugLocations use .debug_info section
1266
// data.
1267
1268
if (Error Err = cloneAndEmitRanges())
1269
return Err;
1270
1271
if (Error Err = cloneAndEmitDebugLocations())
1272
return Err;
1273
1274
if (Error Err = emitDebugAddrSection())
1275
return Err;
1276
1277
// Generate Pub accelerator tables.
1278
if (llvm::is_contained(GlobalData.getOptions().AccelTables,
1279
DWARFLinker::AccelTableKind::Pub))
1280
emitPubAccelerators();
1281
1282
if (Error Err = emitDebugStringOffsetSection())
1283
return Err;
1284
1285
return emitAbbreviations();
1286
}
1287
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);
1295
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;
1301
1302
DIEGenerator PlainDIEGenerator(Allocator, *this);
1303
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
1312
// unit.
1313
assert(ArtificialTypeUnit != nullptr);
1314
DIEGenerator TypeDIEGenerator(
1315
ArtificialTypeUnit->getTypePool().getThreadLocalAllocator(), *this);
1316
1317
ClonedDIE.second = createTypeDIEandCloneAttributes(
1318
InputDieEntry, TypeDIEGenerator, ClonedParentTypeDIE,
1319
ArtificialTypeUnit);
1320
}
1321
TypeEntry *TypeParentForChild =
1322
ClonedDIE.second ? ClonedDIE.second : ClonedParentTypeDIE;
1323
1324
bool HasPlainChildrenToClone =
1325
(ClonedDIE.first && Info.getKeepPlainChildren());
1326
1327
bool HasTypeChildrenToClone =
1328
((ClonedDIE.second ||
1329
InputDieEntry->getTag() == dwarf::DW_TAG_compile_unit) &&
1330
Info.getKeepTypeChildren());
1331
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);
1341
1342
if (ClonedChild.first) {
1343
OutOffset =
1344
ClonedChild.first->getOffset() + ClonedChild.first->getSize();
1345
PlainDIEGenerator.addChild(ClonedChild.first);
1346
}
1347
}
1348
assert(ClonedDIE.first == nullptr ||
1349
HasPlainChildrenToClone == ClonedDIE.first->hasChildren());
1350
1351
// Account for the end of children marker.
1352
if (HasPlainChildrenToClone)
1353
OutOffset += sizeof(int8_t);
1354
}
1355
1356
// Update our size.
1357
if (ClonedDIE.first != nullptr)
1358
ClonedDIE.first->setSize(OutOffset - ClonedDIE.first->getOffset());
1359
1360
return ClonedDIE;
1361
}
1362
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));
1380
if (lowPC) {
1381
LabelMapTy::iterator It = Labels.find(*lowPC);
1382
if (It != Labels.end())
1383
FuncAddressAdjustment = It->second;
1384
}
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);
1390
1391
HasLocationExpressionAddress = LocExprAddrAndRelocAdjustment.first;
1392
if (LocExprAddrAndRelocAdjustment.first &&
1393
LocExprAddrAndRelocAdjustment.second)
1394
VarAddressAdjustment = *LocExprAddrAndRelocAdjustment.second;
1395
}
1396
1397
ClonedDIE = PlainDIEGenerator.createDIE(InputDieEntry->getTag(), OutOffset);
1398
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);
1402
1403
// Clone Attributes.
1404
DIEAttributeCloner AttributesCloner(ClonedDIE, *this, this, InputDieEntry,
1405
PlainDIEGenerator, FuncAddressAdjustment,
1406
VarAddressAdjustment,
1407
HasLocationExpressionAddress);
1408
AttributesCloner.clone();
1409
1410
// Remember accelerator info.
1411
AcceleratorRecordsSaver AccelRecordsSaver(getGlobalData(), *this, this);
1412
AccelRecordsSaver.save(InputDieEntry, ClonedDIE, AttributesCloner.AttrInfo,
1413
nullptr);
1414
1415
OutOffset =
1416
AttributesCloner.finalizeAbbreviations(Info.getKeepPlainChildren());
1417
1418
return ClonedDIE;
1419
}
1420
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.
1428
if (DefinitionDie)
1429
return nullptr;
1430
1431
DIE *DeclarationDie = TypeDescriptor->DeclarationDie;
1432
bool OldParentIsDeclaration = TypeDescriptor->ParentIsDeclaration;
1433
1434
if (IsDeclaration && !DeclarationDie) {
1435
// Alocate declaration DIE.
1436
DIE *NewDie = TypeDIEGenerator.createDIE(DieTag, 0);
1437
if (TypeDescriptor->DeclarationDie.compare_exchange_weak(DeclarationDie,
1438
NewDie))
1439
return NewDie;
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;
1447
return NewDie;
1448
}
1449
} else if (!IsDeclaration && IsParentDeclaration && !DeclarationDie) {
1450
// Alocate declaration DIE since parent of current DIE is marked as
1451
// declaration.
1452
DIE *NewDie = TypeDIEGenerator.createDIE(DieTag, 0);
1453
if (TypeDescriptor->DeclarationDie.compare_exchange_weak(DeclarationDie,
1454
NewDie))
1455
return NewDie;
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;
1461
return NewDie;
1462
}
1463
}
1464
1465
return nullptr;
1466
}
1467
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);
1473
1474
TypeEntry *Entry = getDieTypeEntry(InputDieIdx);
1475
assert(Entry != nullptr);
1476
assert(ClonedParentTypeDIE != nullptr);
1477
TypeEntryBody *EntryBody =
1478
ArtificialTypeUnit->getTypePool().getOrCreateTypeEntryBody(
1479
Entry, ClonedParentTypeDIE);
1480
assert(EntryBody);
1481
1482
bool IsDeclaration =
1483
dwarf::toUnsigned(find(InputDieEntry, dwarf::DW_AT_declaration), 0);
1484
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);
1489
1490
DIE *OutDIE =
1491
allocateTypeDie(EntryBody, TypeDIEGenerator, InputDieEntry->getTag(),
1492
IsDeclaration, ParentIsDeclaration);
1493
1494
if (OutDIE != nullptr) {
1495
assert(ArtificialTypeUnit != nullptr);
1496
ArtificialTypeUnit->getSectionDescriptor(DebugSectionKind::DebugInfo);
1497
1498
DIEAttributeCloner AttributesCloner(OutDIE, *this, ArtificialTypeUnit,
1499
InputDieEntry, TypeDIEGenerator,
1500
std::nullopt, std::nullopt, false);
1501
AttributesCloner.clone();
1502
1503
// Remember accelerator info.
1504
AcceleratorRecordsSaver AccelRecordsSaver(getGlobalData(), *this,
1505
ArtificialTypeUnit);
1506
AccelRecordsSaver.save(InputDieEntry, OutDIE, AttributesCloner.AttrInfo,
1507
Entry);
1508
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);
1512
}
1513
1514
return Entry;
1515
}
1516
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();
1524
}
1525
1526
DWARFDebugLine::LineTable OutLineTable;
1527
1528
// Set Line Table header.
1529
OutLineTable.Prologue = InputLineTable->Prologue;
1530
OutLineTable.Prologue.FormParams.AddrSize = getFormParams().AddrSize;
1531
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();
1539
1540
OutLineTable.Sequences = InputLineTable->Sequences;
1541
} else {
1542
// This vector is the output line table.
1543
std::vector<DWARFDebugLine::Row> NewRows;
1544
NewRows.reserve(InputLineTable->Rows.size());
1545
1546
// Current sequence of rows being extracted, before being inserted
1547
// in NewRows.
1548
std::vector<DWARFDebugLine::Row> Seq;
1549
1550
const auto &FunctionRanges = getFunctionRanges();
1551
std::optional<AddressRangeValuePair> CurrRange;
1552
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.
1561
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);
1587
}
1588
1589
if (!CurrRange)
1590
continue;
1591
}
1592
1593
// Ignore empty sequences.
1594
if (Row.EndSequence && Seq.empty())
1595
continue;
1596
1597
// Relocate row address and add it to the current sequence.
1598
Row.Address.Address += CurrRange->Value;
1599
Seq.emplace_back(Row);
1600
1601
if (Row.EndSequence)
1602
insertLineSequence(Seq, NewRows);
1603
}
1604
1605
OutLineTable.Rows = std::move(NewRows);
1606
}
1607
1608
return emitDebugLine(TargetTriple, OutLineTable);
1609
}
1610
1611
void CompileUnit::insertLineSequence(std::vector<DWARFDebugLine::Row> &Seq,
1612
std::vector<DWARFDebugLine::Row> &Rows) {
1613
if (Seq.empty())
1614
return;
1615
1616
if (!Rows.empty() && Rows.back().Address < Seq.front().Address) {
1617
llvm::append_range(Rows, Seq);
1618
Seq.clear();
1619
return;
1620
}
1621
1622
object::SectionedAddress Front = Seq.front().Address;
1623
auto InsertPoint = partition_point(
1624
Rows, [=](const DWARFDebugLine::Row &O) { return O.Address < Front; });
1625
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());
1634
} else {
1635
Rows.insert(InsertPoint, Seq.begin(), Seq.end());
1636
}
1637
1638
Seq.clear();
1639
}
1640
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()) {
1646
case NotSet:
1647
llvm::errs() << "NotSet";
1648
break;
1649
case TypeTable:
1650
llvm::errs() << "TypeTable";
1651
break;
1652
case PlainDwarf:
1653
llvm::errs() << "PlainDwarf";
1654
break;
1655
case Both:
1656
llvm::errs() << "Both";
1657
break;
1658
}
1659
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";
1669
}
1670
#endif // if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1671
1672
std::optional<std::pair<StringRef, StringRef>>
1673
CompileUnit::getDirAndFilenameFromLineTable(
1674
const DWARFFormValue &FileIdxValue) {
1675
uint64_t FileIdx;
1676
if (std::optional<uint64_t> Val = FileIdxValue.getAsUnsignedConstant())
1677
FileIdx = *Val;
1678
else if (std::optional<int64_t> Val = FileIdxValue.getAsSignedConstant())
1679
FileIdx = *Val;
1680
else if (std::optional<uint64_t> Val = FileIdxValue.getAsSectionOffset())
1681
FileIdx = *Val;
1682
else
1683
return std::nullopt;
1684
1685
return getDirAndFilenameFromLineTable(FileIdx);
1686
}
1687
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));
1694
1695
if (const DWARFDebugLine::LineTable *LineTable =
1696
getOrigUnit().getContext().getLineTableForUnit(&getOrigUnit())) {
1697
if (LineTable->hasFileAtIndex(FileIdx)) {
1698
1699
const llvm::DWARFDebugLine::FileNameEntry &Entry =
1700
LineTable->Prologue.getFileNameEntry(FileIdx);
1701
1702
Expected<const char *> Name = Entry.Name.getAsCString();
1703
if (!Name) {
1704
warn(Name.takeError());
1705
return std::nullopt;
1706
}
1707
1708
std::string FileName = *Name;
1709
if (isPathAbsoluteOnWindowsOrPosix(FileName)) {
1710
FileNamesCache::iterator FileData =
1711
FileNames
1712
.insert(std::make_pair(
1713
FileIdx,
1714
std::make_pair(std::string(""), std::move(FileName))))
1715
.first;
1716
return std::make_pair(StringRef(FileData->second.first),
1717
StringRef(FileData->second.second));
1718
}
1719
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
1725
// relative names.
1726
if ((Entry.DirIdx != 0) &&
1727
Entry.DirIdx < LineTable->Prologue.IncludeDirectories.size()) {
1728
Expected<const char *> DirName =
1729
LineTable->Prologue.IncludeDirectories[Entry.DirIdx]
1730
.getAsCString();
1731
if (DirName)
1732
IncludeDir = *DirName;
1733
else {
1734
warn(DirName.takeError());
1735
return std::nullopt;
1736
}
1737
}
1738
} else {
1739
if (0 < Entry.DirIdx &&
1740
Entry.DirIdx <= LineTable->Prologue.IncludeDirectories.size()) {
1741
Expected<const char *> DirName =
1742
LineTable->Prologue.IncludeDirectories[Entry.DirIdx - 1]
1743
.getAsCString();
1744
if (DirName)
1745
IncludeDir = *DirName;
1746
else {
1747
warn(DirName.takeError());
1748
return std::nullopt;
1749
}
1750
}
1751
}
1752
1753
StringRef CompDir = getOrigUnit().getCompilationDir();
1754
1755
if (!CompDir.empty() && !isPathAbsoluteOnWindowsOrPosix(IncludeDir)) {
1756
sys::path::append(FilePath, sys::path::Style::native, CompDir);
1757
}
1758
1759
sys::path::append(FilePath, sys::path::Style::native, IncludeDir);
1760
1761
FileNamesCache::iterator FileData =
1762
FileNames
1763
.insert(
1764
std::make_pair(FileIdx, std::make_pair(std::string(FilePath),
1765
std::move(FileName))))
1766
.first;
1767
return std::make_pair(StringRef(FileData->second.first),
1768
StringRef(FileData->second.second));
1769
}
1770
}
1771
1772
return std::nullopt;
1773
}
1774
1775
#define MAX_REFERENCIES_DEPTH 1000
1776
UnitEntryPairTy UnitEntryPairTy::getNamespaceOrigin() {
1777
UnitEntryPairTy CUDiePair(*this);
1778
std::optional<UnitEntryPairTy> RefDiePair;
1779
int refDepth = 0;
1780
do {
1781
RefDiePair = CUDiePair.CU->resolveDIEReference(
1782
CUDiePair.DieEntry, dwarf::DW_AT_extension,
1783
ResolveInterCUReferencesMode::Resolve);
1784
if (!RefDiePair || !RefDiePair->DieEntry)
1785
return CUDiePair;
1786
1787
CUDiePair = *RefDiePair;
1788
} while (refDepth++ < MAX_REFERENCIES_DEPTH);
1789
1790
return CUDiePair;
1791
}
1792
1793
std::optional<UnitEntryPairTy> UnitEntryPairTy::getParent() {
1794
if (std::optional<uint32_t> ParentIdx = DieEntry->getParentIdx())
1795
return UnitEntryPairTy{CU, CU->getDebugInfoEntry(*ParentIdx)};
1796
1797
return std::nullopt;
1798
}
1799
1800
CompileUnit::OutputUnitVariantPtr::OutputUnitVariantPtr(CompileUnit *U)
1801
: Ptr(U) {
1802
assert(U != nullptr);
1803
}
1804
1805
CompileUnit::OutputUnitVariantPtr::OutputUnitVariantPtr(TypeUnit *U) : Ptr(U) {
1806
assert(U != nullptr);
1807
}
1808
1809
DwarfUnit *CompileUnit::OutputUnitVariantPtr::operator->() {
1810
if (isCompileUnit())
1811
return getAsCompileUnit();
1812
else
1813
return getAsTypeUnit();
1814
}
1815
1816
bool CompileUnit::OutputUnitVariantPtr::isCompileUnit() {
1817
return Ptr.is<CompileUnit *>();
1818
}
1819
1820
bool CompileUnit::OutputUnitVariantPtr::isTypeUnit() {
1821
return Ptr.is<TypeUnit *>();
1822
}
1823
1824
CompileUnit *CompileUnit::OutputUnitVariantPtr::getAsCompileUnit() {
1825
return Ptr.get<CompileUnit *>();
1826
}
1827
1828
TypeUnit *CompileUnit::OutputUnitVariantPtr::getAsTypeUnit() {
1829
return Ptr.get<TypeUnit *>();
1830
}
1831
1832
bool CompileUnit::resolveDependenciesAndMarkLiveness(
1833
bool InterCUProcessingStarted, std::atomic<bool> &HasNewInterconnectedCUs) {
1834
if (!Dependencies)
1835
Dependencies.reset(new DependencyTracker(*this));
1836
1837
return Dependencies->resolveDependenciesAndMarkLiveness(
1838
InterCUProcessingStarted, HasNewInterconnectedCUs);
1839
}
1840
1841
bool CompileUnit::updateDependenciesCompleteness() {
1842
assert(Dependencies.get());
1843
1844
return Dependencies->updateDependenciesCompleteness();
1845
}
1846
1847
void CompileUnit::verifyDependencies() {
1848
assert(Dependencies.get());
1849
1850
Dependencies->verifyKeepChain();
1851
}
1852
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};
1857
1858
return ODRAttributes;
1859
}
1860
1861