Movatterモバイル変換


[0]ホーム

URL:


LLVM 20.0.0git
DWARFLinkerCompileUnit.cpp
Go to the documentation of this file.
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
24using namespacellvm;
25using namespacedwarf_linker;
26using namespacedwarf_linker::parallel;
27
28CompileUnit::CompileUnit(LinkingGlobalData &GlobalData,unsignedID,
29StringRef ClangModuleName,DWARFFile &File,
30OffsetToUnitTy UnitFromOffset,
31dwarf::FormParams Format,llvm::endianness Endianess)
32 :DwarfUnit(GlobalData,ID, ClangModuleName), File(File),
33 getUnitFromOffset(UnitFromOffset),Stage(Stage::CreatedNotLoaded),
34 AcceleratorRecords(&GlobalData.getAllocator()) {
35UnitName = File.FileName;
36setOutputFormat(Format, Endianess);
37getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);
38}
39
40CompileUnit::CompileUnit(LinkingGlobalData &GlobalData,DWARFUnit &OrigUnit,
41unsignedID,StringRef ClangModuleName,
42DWARFFile &File,OffsetToUnitTy UnitFromOffset,
43dwarf::FormParamsFormat,llvm::endianness Endianess)
44 :DwarfUnit(GlobalData,ID, ClangModuleName), File(File),
45 OrigUnit(&OrigUnit), getUnitFromOffset(UnitFromOffset),
46Stage(Stage::CreatedNotLoaded),
47 AcceleratorRecords(&GlobalData.getAllocator()) {
48setOutputFormat(Format, Endianess);
49getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);
50
51DWARFDie CUDie = OrigUnit.getUnitDIE();
52if (!CUDie)
53return;
54
55if (std::optional<DWARFFormValue> Val = CUDie.find(dwarf::DW_AT_language)) {
56uint16_t LangVal =dwarf::toUnsigned(Val, 0);
57if (isODRLanguage(LangVal))
58 Language = LangVal;
59 }
60
61if (!GlobalData.getOptions().NoODR && Language.has_value())
62 NoODR =false;
63
64if (constchar *CUName = CUDie.getName(DINameKind::ShortName))
65UnitName = CUName;
66else
67UnitName = File.FileName;
68SysRoot =dwarf::toStringRef(CUDie.find(dwarf::DW_AT_LLVM_sysroot)).str();
69}
70
71voidCompileUnit::loadLineTable() {
72 LineTablePtr = File.Dwarf->getLineTableForUnit(&getOrigUnit());
73}
74
75voidCompileUnit::maybeResetToLoadedStage() {
76// Nothing to reset if stage is less than "Loaded".
77if (getStage() <Stage::Loaded)
78return;
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
85for (DIEInfo &Info : DieInfoArray)
86Info.unsetFlagsWhichSetDuringLiveAnalysis();
87
88 LowPc = std::nullopt;
89 HighPc = 0;
90 Labels.clear();
91 Ranges.clear();
92 Dependencies.reset(nullptr);
93
94if (getStage() <Stage::Cloned) {
95setStage(Stage::Loaded);
96return;
97 }
98
99 AcceleratorRecords.erase();
100AbbreviationsSet.clear();
101Abbreviations.clear();
102OutUnitDIE =nullptr;
103 DebugAddrIndexMap.clear();
104
105for (uint64_t &Offset : OutDieOffsetArray)
106Offset = 0;
107for (TypeEntry *&Name : TypeEntries)
108Name =nullptr;
109eraseSections();
110
111setStage(Stage::CreatedNotLoaded);
112}
113
114boolCompileUnit::loadInputDIEs() {
115DWARFDie InputUnitDIE =getUnitDIE(false);
116if (!InputUnitDIE)
117returnfalse;
118
119// load input dies, resize Info structures array.
120 DieInfoArray.resize(getOrigUnit().getNumDIEs());
121 OutDieOffsetArray.resize(getOrigUnit().getNumDIEs(), 0);
122if (!NoODR)
123 TypeEntries.resize(getOrigUnit().getNumDIEs());
124returntrue;
125}
126
127void CompileUnit::analyzeDWARFStructureRec(constDWARFDebugInfoEntry *DieEntry,
128bool IsODRUnavailableFunctionScope) {
129CompileUnit::DIEInfo &DieInfo =getDIEInfo(DieEntry);
130
131for (constDWARFDebugInfoEntry *CurChild =getFirstChildEntry(DieEntry);
132 CurChild && CurChild->getAbbreviationDeclarationPtr();
133 CurChild =getSiblingEntry(CurChild)) {
134CompileUnit::DIEInfo &ChildInfo =getDIEInfo(CurChild);
135bool ChildIsODRUnavailableFunctionScope = IsODRUnavailableFunctionScope;
136
137if (DieInfo.getIsInMouduleScope())
138 ChildInfo.setIsInMouduleScope();
139
140if (DieInfo.getIsInFunctionScope())
141 ChildInfo.setIsInFunctionScope();
142
143if (DieInfo.getIsInAnonNamespaceScope())
144 ChildInfo.setIsInAnonNamespaceScope();
145
146switch (CurChild->getTag()) {
147case dwarf::DW_TAG_module:
148 ChildInfo.setIsInMouduleScope();
149if (DieEntry->getTag() == dwarf::DW_TAG_compile_unit &&
150dwarf::toString(find(CurChild, dwarf::DW_AT_name),"") !=
151getClangModuleName())
152analyzeImportedModule(CurChild);
153break;
154case dwarf::DW_TAG_subprogram:
155 ChildInfo.setIsInFunctionScope();
156if (!ChildIsODRUnavailableFunctionScope &&
157 !ChildInfo.getIsInMouduleScope()) {
158if (find(CurChild,
159 {dwarf::DW_AT_abstract_origin, dwarf::DW_AT_specification}))
160 ChildIsODRUnavailableFunctionScope =true;
161 }
162break;
163case dwarf::DW_TAG_namespace: {
164UnitEntryPairTy NamespaceEntry = {this, CurChild};
165
166if (find(CurChild, dwarf::DW_AT_extension))
167 NamespaceEntry = NamespaceEntry.getNamespaceOrigin();
168
169if (!NamespaceEntry.CU->find(NamespaceEntry.DieEntry, dwarf::DW_AT_name))
170 ChildInfo.setIsInAnonNamespaceScope();
171 }break;
172default:
173break;
174 }
175
176if (!isClangModule() && !getGlobalData().getOptions().UpdateIndexTablesOnly)
177 ChildInfo.setTrackLiveness();
178
179if ((!ChildInfo.getIsInAnonNamespaceScope() &&
180 !ChildIsODRUnavailableFunctionScope && !NoODR))
181 ChildInfo.setODRAvailable();
182
183if (CurChild->hasChildren())
184 analyzeDWARFStructureRec(CurChild, ChildIsODRUnavailableFunctionScope);
185 }
186}
187
188StringEntry *CompileUnit::getFileName(unsigned FileIdx,
189StringPool &GlobalStrings) {
190if (LineTablePtr) {
191if (LineTablePtr->hasFileAtIndex(FileIdx)) {
192// Cache the resolved paths based on the index in the line table,
193// because calling realpath is expensive.
194ResolvedPathsMap::const_iterator It = ResolvedFullPaths.find(FileIdx);
195if (It == ResolvedFullPaths.end()) {
196 std::string OrigFileName;
197bool FoundFileName = LineTablePtr->getFileNameByIndex(
198 FileIdx,getOrigUnit().getCompilationDir(),
199 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
200 OrigFileName);
201 (void)FoundFileName;
202assert(FoundFileName &&"Must get file name from line table");
203
204// Second level of caching, this time based on the file's parent
205// path.
206StringRef FileName =sys::path::filename(OrigFileName);
207StringRef 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.
211StringMap<StringEntry *>::iterator ParentIt =
212 ResolvedParentPaths.find(ParentPath);
213if (ParentIt == ResolvedParentPaths.end()) {
214SmallString<256> RealPath;
215sys::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.
223SmallString<256> ResolvedPath(ParentIt->second->first());
224sys::path::append(ResolvedPath, FileName);
225
226 It = ResolvedFullPaths
227 .insert(std::make_pair(
228 FileIdx, GlobalStrings.insert(ResolvedPath).first))
229 .first;
230 }
231
232return It->second;
233 }
234 }
235
236returnnullptr;
237}
238
239voidCompileUnit::cleanupDataAfterClonning() {
240AbbreviationsSet.clear();
241 ResolvedFullPaths.shrink_and_clear();
242 ResolvedParentPaths.clear();
243FileNames.shrink_and_clear();
244 DieInfoArray =SmallVector<DIEInfo>();
245 OutDieOffsetArray =SmallVector<uint64_t>();
246 TypeEntries =SmallVector<TypeEntry *>();
247 Dependencies.reset(nullptr);
248getOrigUnit().clear();
249}
250
251/// Collect references to parseable Swift interfaces in imported
252/// DW_TAG_module blocks.
253voidCompileUnit::analyzeImportedModule(constDWARFDebugInfoEntry *DieEntry) {
254if (!Language || Language != dwarf::DW_LANG_Swift)
255return;
256
257if (!GlobalData.getOptions().ParseableSwiftInterfaces)
258return;
259
260StringRef Path =
261dwarf::toStringRef(find(DieEntry, dwarf::DW_AT_LLVM_include_path));
262if (!Path.ends_with(".swiftinterface"))
263return;
264// Don't track interfaces that are part of the SDK.
265StringRefSysRoot =
266dwarf::toStringRef(find(DieEntry, dwarf::DW_AT_LLVM_sysroot));
267if (SysRoot.empty())
268SysRoot =getSysRoot();
269if (!SysRoot.empty() && Path.starts_with(SysRoot))
270return;
271// Don't track interfaces that are part of the toolchain.
272// For example: Swift, _Concurrency, ...
273StringRef DeveloperDir =guessDeveloperDir(SysRoot);
274if (!DeveloperDir.empty() && Path.starts_with(DeveloperDir))
275return;
276if (isInToolchainDir(Path))
277return;
278if (std::optional<DWARFFormValue> Val =find(DieEntry, dwarf::DW_AT_name)) {
279Expected<const char *>Name = Val->getAsCString();
280if (!Name) {
281warn(Name.takeError());
282return;
283 }
284
285auto &Entry = (*GlobalData.getOptions().ParseableSwiftInterfaces)[*Name];
286// The prepend path is applied later when copying.
287SmallString<128> ResolvedPath;
288if (sys::path::is_relative(Path))
289sys::path::append(
290 ResolvedPath,
291dwarf::toString(getUnitDIE().find(dwarf::DW_AT_comp_dir),""));
292sys::path::append(ResolvedPath, Path);
293if (!Entry.empty() && Entry != ResolvedPath) {
294DWARFDie Die =getDIE(DieEntry);
295warn(Twine("conflicting parseable interfaces for Swift Module ") + *Name +
296": " + Entry +" and " + Path +".",
297 &Die);
298 }
299 Entry = std::string(ResolvedPath);
300 }
301}
302
303ErrorCompileUnit::assignTypeNames(TypePool &TypePoolRef) {
304if (!getUnitDIE().isValid())
305returnError::success();
306
307SyntheticTypeNameBuilder NameBuilder(TypePoolRef);
308return assignTypeNamesRec(getDebugInfoEntry(0), NameBuilder);
309}
310
311Error CompileUnit::assignTypeNamesRec(constDWARFDebugInfoEntry *DieEntry,
312SyntheticTypeNameBuilder &NameBuilder) {
313OrderedChildrenIndexAssigner ChildrenIndexAssigner(*this, DieEntry);
314for (constDWARFDebugInfoEntry *CurChild =getFirstChildEntry(DieEntry);
315 CurChild && CurChild->getAbbreviationDeclarationPtr();
316 CurChild =getSiblingEntry(CurChild)) {
317CompileUnit::DIEInfo &ChildInfo =getDIEInfo(CurChild);
318if (!ChildInfo.needToPlaceInTypeTable())
319continue;
320
321assert(ChildInfo.getODRAvailable());
322if (Error Err = NameBuilder.assignName(
323 {this, CurChild},
324 ChildrenIndexAssigner.getChildIndex(*this, CurChild)))
325return Err;
326
327if (Error Err = assignTypeNamesRec(CurChild, NameBuilder))
328return Err;
329 }
330
331returnError::success();
332}
333
334voidCompileUnit::updateDieRefPatchesWithClonedOffsets() {
335if (std::optional<SectionDescriptor *> DebugInfoSection =
336tryGetSectionDescriptor(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
356if (std::optional<SectionDescriptor *> DebugLocSection =
357tryGetSectionDescriptor(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
368if (std::optional<SectionDescriptor *> DebugLocListsSection =
369tryGetSectionDescriptor(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
381std::optional<UnitEntryPairTy>CompileUnit::resolveDIEReference(
382constDWARFFormValue &RefValue,
383ResolveInterCUReferencesMode CanResolveInterCUReferences) {
384CompileUnit *RefCU;
385uint64_t RefDIEOffset;
386if (std::optional<uint64_t>Offset = RefValue.getAsRelativeReference()) {
387 RefCU =this;
388 RefDIEOffset = RefValue.getUnit()->getOffset() + *Offset;
389 }elseif (Offset = RefValue.getAsDebugInfoReference();Offset) {
390 RefCU = getUnitFromOffset(*Offset);
391 RefDIEOffset = *Offset;
392 }else {
393return std::nullopt;
394 }
395
396if (RefCU ==this) {
397// Referenced DIE is in current compile unit.
398if (std::optional<uint32_t> RefDieIdx =getDIEIndexForOffset(RefDIEOffset))
399returnUnitEntryPairTy{this,getDebugInfoEntry(*RefDieIdx)};
400 }elseif (RefCU && CanResolveInterCUReferences) {
401// Referenced DIE is in other compile unit.
402
403// Check whether DIEs are loaded for that compile unit.
404enumStage ReferredCUStage = RefCU->getStage();
405if (ReferredCUStage < Stage::Loaded || ReferredCUStage >Stage::Cloned)
406returnUnitEntryPairTy{RefCU,nullptr};
407
408if (std::optional<uint32_t> RefDieIdx =
409 RefCU->getDIEIndexForOffset(RefDIEOffset))
410returnUnitEntryPairTy{RefCU, RefCU->getDebugInfoEntry(*RefDieIdx)};
411 }else {
412returnUnitEntryPairTy{RefCU,nullptr};
413 }
414return std::nullopt;
415}
416
417std::optional<UnitEntryPairTy>CompileUnit::resolveDIEReference(
418constDWARFDebugInfoEntry *DieEntry,dwarf::Attribute Attr,
419ResolveInterCUReferencesMode CanResolveInterCUReferences) {
420if (std::optional<DWARFFormValue> AttrVal =find(DieEntry, Attr))
421returnresolveDIEReference(*AttrVal, CanResolveInterCUReferences);
422
423return std::nullopt;
424}
425
426voidCompileUnit::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);
431if (LowPc)
432 LowPc = std::min(*LowPc, FuncLowPc + PcOffset);
433else
434 LowPc = FuncLowPc + PcOffset;
435 this->HighPc = std::max(HighPc, FuncHighPc + PcOffset);
436}
437
438voidCompileUnit::addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset) {
439 std::lock_guard<std::mutex> Guard(LabelsMutex);
440 Labels.insert({LabelLowPc, PcOffset});
441}
442
443ErrorCompileUnit::cloneAndEmitDebugLocations() {
444if (getGlobalData().getOptions().UpdateIndexTablesOnly)
445returnError::success();
446
447if (getOrigUnit().getVersion() < 5) {
448 emitLocations(DebugSectionKind::DebugLoc);
449returnError::success();
450 }
451
452 emitLocations(DebugSectionKind::DebugLocLists);
453returnError::success();
454}
455
456void CompileUnit::emitLocations(DebugSectionKind LocationSectionKind) {
457SectionDescriptor &DebugInfoSection =
458getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);
459
460if (!DebugInfoSection.ListDebugLocPatch.empty()) {
461SectionDescriptor &OutLocationSection =
462getOrCreateSectionDescriptor(LocationSectionKind);
463DWARFUnit &OrigUnit =getOrigUnit();
464
465uint64_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.
470uint64_t InputDebugLocSectionOffset = DebugInfoSection.getIntVal(
471 Patch.PatchOffset,
472 DebugInfoSection.getFormParams().getDwarfOffsetByteSize());
473Expected<DWARFLocationExpressionsVector> OriginalLocations =
474 OrigUnit.findLoclistFromOffset(InputDebugLocSectionOffset);
475
476if (!OriginalLocations) {
477warn(OriginalLocations.takeError());
478return;
479 }
480
481 LinkedLocationExpressionsVector LinkedLocationExpressions;
482for (DWARFLocationExpression &CurExpression : *OriginalLocations) {
483 LinkedLocationExpressionsWithOffsetPatches LinkedExpression;
484
485if (CurExpression.Range) {
486// Relocate address range.
487 LinkedExpression.Expression.Range = {
488 CurExpression.Range->LowPC + Patch.AddrAdjustmentValue,
489 CurExpression.Range->HighPC + Patch.AddrAdjustmentValue};
490 }
491
492DataExtractorData(CurExpression.Expr, OrigUnit.isLittleEndian(),
493 OrigUnit.getAddressByteSize());
494
495DWARFExpression InputExpression(Data, OrigUnit.getAddressByteSize(),
496 OrigUnit.getFormParams().Format);
497cloneDieAttrExpression(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
511if (OffsetAfterUnitLength > 0) {
512assert(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.
525uint64_t CompileUnit::emitLocListHeader(SectionDescriptor &OutLocationSection) {
526if (getOrigUnit().getVersion() < 5)
527return 0;
528
529// unit_length.
530 OutLocationSection.emitUnitLength(0xBADDEF);
531uint64_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
545return OffsetAfterUnitLength;
546}
547
548/// Emit debug locations(.debug_loc, .debug_loclists) fragment.
549uint64_t CompileUnit::emitLocListFragment(
550const LinkedLocationExpressionsVector &LinkedLocationExpression,
551SectionDescriptor &OutLocationSection) {
552uint64_t OffsetBeforeLocationExpression = 0;
553
554if (getOrigUnit().getVersion() < 5) {
555uint64_t BaseAddress = 0;
556if (std::optional<uint64_t> LowPC =getLowPc())
557 BaseAddress = *LowPC;
558
559for (const LinkedLocationExpressionsWithOffsetPatches &LocExpression :
560 LinkedLocationExpression) {
561if (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();
572for (uint64_t *OffsetPtr : LocExpression.Patches)
573 *OffsetPtr += OffsetBeforeLocationExpression;
574
575 OutLocationSection.OS
576 <<StringRef((constchar *)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);
585return OffsetBeforeLocationExpression;
586 }
587
588 std::optional<uint64_t> BaseAddress;
589for (const LinkedLocationExpressionsWithOffsetPatches &LocExpression :
590 LinkedLocationExpression) {
591if (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.
594if (!BaseAddress) {
595 BaseAddress = LocExpression.Expression.Range->LowPC;
596
597// Emit base address.
598 OutLocationSection.emitIntVal(dwarf::DW_LLE_base_addressx, 1);
599encodeULEB128(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.
607encodeULEB128(LocExpression.Expression.Range->LowPC - *BaseAddress,
608 OutLocationSection.OS);
609
610// Emit end offset relative to base address.
611encodeULEB128(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
617encodeULEB128(LocExpression.Expression.Expr.size(), OutLocationSection.OS);
618 OffsetBeforeLocationExpression = OutLocationSection.OS.tell();
619for (uint64_t *OffsetPtr : LocExpression.Patches)
620 *OffsetPtr += OffsetBeforeLocationExpression;
621
622 OutLocationSection.OS <<StringRef(
623 (constchar *)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);
629return OffsetBeforeLocationExpression;
630}
631
632Error CompileUnit::emitDebugAddrSection() {
633if (GlobalData.getOptions().UpdateIndexTablesOnly)
634returnError::success();
635
636if (getVersion() < 5)
637returnError::success();
638
639if (DebugAddrIndexMap.empty())
640returnError::success();
641
642SectionDescriptor &OutAddrSection =
643getOrCreateSectionDescriptor(DebugSectionKind::DebugAddr);
644
645// Emit section header.
646
647// Emit length.
648 OutAddrSection.emitUnitLength(0xBADDEF);
649uint64_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.
661for (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
671returnError::success();
672}
673
674ErrorCompileUnit::cloneAndEmitRanges() {
675if (getGlobalData().getOptions().UpdateIndexTablesOnly)
676returnError::success();
677
678// Build set of linked address ranges for unit function ranges.
679AddressRanges LinkedFunctionRanges;
680for (constAddressRangeValuePair &Range :getFunctionRanges())
681 LinkedFunctionRanges.insert(
682 {Range.Range.start() +Range.Value,Range.Range.end() +Range.Value});
683
684 emitAranges(LinkedFunctionRanges);
685
686if (getOrigUnit().getVersion() < 5) {
687 cloneAndEmitRangeList(DebugSectionKind::DebugRange, LinkedFunctionRanges);
688returnError::success();
689 }
690
691 cloneAndEmitRangeList(DebugSectionKind::DebugRngLists, LinkedFunctionRanges);
692returnError::success();
693}
694
695void CompileUnit::cloneAndEmitRangeList(DebugSectionKind RngSectionKind,
696AddressRanges &LinkedFunctionRanges) {
697SectionDescriptor &DebugInfoSection =
698getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);
699SectionDescriptor &OutRangeSection =
700getOrCreateSectionDescriptor(RngSectionKind);
701
702if (!DebugInfoSection.ListDebugRangePatch.empty()) {
703 std::optional<AddressRangeValuePair> CachedRange;
704uint64_t OffsetAfterUnitLength = emitRangeListHeader(OutRangeSection);
705
706DebugRangePatch *CompileUnitRangePtr =nullptr;
707 DebugInfoSection.ListDebugRangePatch.forEach([&](DebugRangePatch &Patch) {
708if (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
748if (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
757if (OffsetAfterUnitLength > 0) {
758assert(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
770uint64_t CompileUnit::emitRangeListHeader(SectionDescriptor &OutRangeSection) {
771if (OutRangeSection.getFormParams().Version < 5)
772return 0;
773
774// unit_length.
775 OutRangeSection.emitUnitLength(0xBADDEF);
776uint64_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
790return OffsetAfterUnitLength;
791}
792
793void CompileUnit::emitRangeListFragment(constAddressRanges &LinkedRanges,
794SectionDescriptor &OutRangeSection) {
795if (OutRangeSection.getFormParams().Version < 5) {
796// Emit ranges.
797uint64_t BaseAddress = 0;
798if (std::optional<uint64_t> LowPC =getLowPc())
799 BaseAddress = *LowPC;
800
801for (constAddressRange &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);
811return;
812 }
813
814 std::optional<uint64_t> BaseAddress;
815for (constAddressRange &Range : LinkedRanges) {
816if (!BaseAddress) {
817 BaseAddress =Range.start();
818
819// Emit base address.
820 OutRangeSection.emitIntVal(dwarf::DW_RLE_base_addressx, 1);
821encodeULEB128(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.
828encodeULEB128(Range.start() - *BaseAddress, OutRangeSection.OS);
829
830// Emit end offset relative to base address.
831encodeULEB128(Range.end() - *BaseAddress, OutRangeSection.OS);
832 }
833
834// Emit the terminator entry.
835 OutRangeSection.emitIntVal(dwarf::DW_RLE_end_of_list, 1);
836}
837
838void CompileUnit::emitAranges(AddressRanges &LinkedFunctionRanges) {
839if (LinkedFunctionRanges.empty())
840return;
841
842SectionDescriptor &DebugInfoSection =
843getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);
844SectionDescriptor &OutArangesSection =
845getOrCreateSectionDescriptor(DebugSectionKind::DebugARanges);
846
847// Emit Header.
848unsignedHeaderSize =
849sizeof(int32_t) +// Size of contents (w/o this field
850sizeof(int16_t) +// DWARF ARange version number
851sizeof(int32_t) +// Offset of CU in the .debug_info section
852sizeof(int8_t) +// Pointer Size (in bytes)
853sizeof(int8_t);// Segment Size (in bytes)
854
855unsigned TupleSize = OutArangesSection.getFormParams().AddrSize * 2;
856unsignedPadding =offsetToAlignment(HeaderSize,Align(TupleSize));
857
858 OutArangesSection.emitOffset(0xBADDEF);// Aranges length
859uint64_t OffsetAfterArangesLengthField = OutArangesSection.OS.tell();
860
861 OutArangesSection.emitIntVal(dwarf::DW_ARANGES_VERSION, 2);// Version number
862 OutArangesSection.notePatch(
863DebugOffsetPatch{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
869for (size_tIdx = 0;Idx <Padding;Idx++)
870 OutArangesSection.emitIntVal(0, 1);// Padding
871
872// Emit linked ranges.
873for (constAddressRange &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
884uint64_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
894ErrorCompileUnit::cloneAndEmitDebugMacro() {
895if (getOutUnitDIE() ==nullptr)
896returnError::success();
897
898DWARFUnit &OrigUnit =getOrigUnit();
899DWARFDie OrigUnitDie = OrigUnit.getUnitDIE();
900
901// Check for .debug_macro table.
902if (std::optional<uint64_t> MacroAttr =
903dwarf::toSectionOffset(OrigUnitDie.find(dwarf::DW_AT_macros))) {
904if (constDWARFDebugMacro *Table =
905getContaingFile().Dwarf->getDebugMacro()) {
906 emitMacroTableImpl(Table, *MacroAttr,true);
907 }
908 }
909
910// Check for .debug_macinfo table.
911if (std::optional<uint64_t> MacroAttr =
912dwarf::toSectionOffset(OrigUnitDie.find(dwarf::DW_AT_macro_info))) {
913if (constDWARFDebugMacro *Table =
914getContaingFile().Dwarf->getDebugMacinfo()) {
915 emitMacroTableImpl(Table, *MacroAttr,false);
916 }
917 }
918
919returnError::success();
920}
921
922void CompileUnit::emitMacroTableImpl(constDWARFDebugMacro *MacroTable,
923uint64_t OffsetToMacroTable,
924bool hasDWARFv5Header) {
925SectionDescriptor &OutSection =
926 hasDWARFv5Header
927 ?getOrCreateSectionDescriptor(DebugSectionKind::DebugMacro)
928 :getOrCreateSectionDescriptor(DebugSectionKind::DebugMacinfo);
929
930bool DefAttributeIsReported =false;
931bool UndefAttributeIsReported =false;
932bool ImportAttributeIsReported =false;
933
934for (const DWARFDebugMacro::MacroList &List : MacroTable->MacroLists) {
935if (OffsetToMacroTable ==List.Offset) {
936// Write DWARFv5 header.
937if (hasDWARFv5Header) {
938// Write header version.
939 OutSection.emitIntVal(List.Header.Version,sizeof(List.Header.Version));
940
941uint8_t Flags =List.Header.Flags;
942
943// Check for OPCODE_OPERANDS_TABLE.
944if (Flags &
945 DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE) {
946 Flags &=
947~DWARFDebugMacro::HeaderFlagMask::MACRO_OPCODE_OPERANDS_TABLE;
948warn("opcode_operands_table is not supported yet.");
949 }
950
951// Check for DEBUG_LINE_OFFSET.
952 std::optional<uint64_t> StmtListOffset;
953if (Flags & DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET) {
954// Get offset to the line table from the cloned compile unit.
955for (auto &V :getOutUnitDIE()->values()) {
956if (V.getAttribute() == dwarf::DW_AT_stmt_list) {
957 StmtListOffset = V.getDIEInteger().getValue();
958break;
959 }
960 }
961
962if (!StmtListOffset) {
963 Flags &=~DWARFDebugMacro::HeaderFlagMask::MACRO_DEBUG_LINE_OFFSET;
964warn("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.
972if (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.
983for (const DWARFDebugMacro::Entry &MacroEntry :List.Macros) {
984if (MacroEntry.Type == 0) {
985encodeULEB128(MacroEntry.Type, OutSection.OS);
986continue;
987 }
988
989uint8_t MacroType = MacroEntry.Type;
990switch (MacroType) {
991default: {
992bool 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
998if (HasVendorSpecificExtension) {
999// Write macinfo type.
1000 OutSection.emitIntVal(MacroType, 1);
1001
1002// Write vendor extension constant.
1003encodeULEB128(MacroEntry.ExtConstant, OutSection.OS);
1004
1005// Write vendor extension string.
1006 OutSection.emitString(dwarf::DW_FORM_string, MacroEntry.ExtStr);
1007 }else
1008warn("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_*.
1016case dwarf::DW_MACRO_define:
1017case dwarf::DW_MACRO_undef: {
1018// Write macinfo type.
1019 OutSection.emitIntVal(MacroType, 1);
1020
1021// Write source line.
1022encodeULEB128(MacroEntry.Line, OutSection.OS);
1023
1024// Write macro string.
1025 OutSection.emitString(dwarf::DW_FORM_string, MacroEntry.MacroStr);
1026 }break;
1027case dwarf::DW_MACRO_define_strp:
1028case dwarf::DW_MACRO_undef_strp:
1029case dwarf::DW_MACRO_define_strx:
1030case dwarf::DW_MACRO_undef_strx: {
1031// DW_MACRO_*_strx forms are not supported currently.
1032// Convert to *_strp.
1033switch (MacroType) {
1034case dwarf::DW_MACRO_define_strx: {
1035 MacroType = dwarf::DW_MACRO_define_strp;
1036if (!DefAttributeIsReported) {
1037warn("DW_MACRO_define_strx unsupported yet. Convert to "
1038"DW_MACRO_define_strp.");
1039 DefAttributeIsReported =true;
1040 }
1041 }break;
1042case dwarf::DW_MACRO_undef_strx: {
1043 MacroType = dwarf::DW_MACRO_undef_strp;
1044if (!UndefAttributeIsReported) {
1045warn("DW_MACRO_undef_strx unsupported yet. Convert to "
1046"DW_MACRO_undef_strp.");
1047 UndefAttributeIsReported =true;
1048 }
1049 }break;
1050default:
1051// Nothing to do.
1052break;
1053 }
1054
1055// Write macinfo type.
1056 OutSection.emitIntVal(MacroType, 1);
1057
1058// Write source line.
1059encodeULEB128(MacroEntry.Line, OutSection.OS);
1060
1061// Write macro string.
1062 OutSection.emitString(dwarf::DW_FORM_strp, MacroEntry.MacroStr);
1063break;
1064 }
1065case dwarf::DW_MACRO_start_file: {
1066// Write macinfo type.
1067 OutSection.emitIntVal(MacroType, 1);
1068// Write source line.
1069encodeULEB128(MacroEntry.Line, OutSection.OS);
1070// Write source file id.
1071encodeULEB128(MacroEntry.File, OutSection.OS);
1072 }break;
1073case dwarf::DW_MACRO_end_file: {
1074// Write macinfo type.
1075 OutSection.emitIntVal(MacroType, 1);
1076 }break;
1077case dwarf::DW_MACRO_import:
1078case dwarf::DW_MACRO_import_sup: {
1079if (!ImportAttributeIsReported) {
1080warn("DW_MACRO_import and DW_MACRO_import_sup are unsupported "
1081"yet. remove.");
1082 ImportAttributeIsReported =true;
1083 }
1084 }break;
1085 }
1086 }
1087
1088return;
1089 }
1090 }
1091}
1092
1093voidCompileUnit::cloneDieAttrExpression(
1094constDWARFExpression &InputExpression,
1095SmallVectorImpl<uint8_t> &OutputExpression,SectionDescriptor &Section,
1096 std::optional<int64_t> VarAddressAdjustment,
1097OffsetsPtrVector &PatchesOffsets) {
1098usingEncoding =DWARFExpression::Operation::Encoding;
1099
1100DWARFUnit &OrigUnit =getOrigUnit();
1101uint8_t OrigAddressByteSize = OrigUnit.getAddressByteSize();
1102
1103uint64_t OpOffset = 0;
1104for (auto &Op : InputExpression) {
1105autoDesc =Op.getDescription();
1106// DW_OP_const_type is variable-length and has 3
1107// operands. Thus far we only support 2.
1108if ((Desc.Op.size() == 2 &&Desc.Op[0] == Encoding::BaseTypeRef) ||
1109 (Desc.Op.size() == 2 &&Desc.Op[1] == Encoding::BaseTypeRef &&
1110Desc.Op[0] != Encoding::Size1))
1111warn("unsupported DW_OP encoding.");
1112
1113if ((Desc.Op.size() == 1 &&Desc.Op[0] == Encoding::BaseTypeRef) ||
1114 (Desc.Op.size() == 2 &&Desc.Op[1] == Encoding::BaseTypeRef &&
1115Desc.Op[0] == Encoding::Size1)) {
1116// This code assumes that the other non-typeref operand fits into 1 byte.
1117assert(OpOffset <Op.getEndOffset());
1118uint32_t ULEBsize =Op.getEndOffset() - OpOffset - 1;
1119assert(ULEBsize <= 16);
1120
1121// Copy over the operation.
1122assert(!Op.getSubCode() &&"SubOps not yet supported");
1123 OutputExpression.push_back(Op.getCode());
1124uint64_t RefOffset;
1125if (Desc.Op.size() == 1) {
1126 RefOffset =Op.getRawOperand(0);
1127 }else {
1128 OutputExpression.push_back(Op.getRawOperand(0));
1129 RefOffset =Op.getRawOperand(1);
1130 }
1131uint8_t ULEB[16];
1132uint32_tOffset = 0;
1133unsigned 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.
1137if (RefOffset > 0 ||Op.getCode() != dwarf::DW_OP_convert) {
1138 RefOffset += OrigUnit.getOffset();
1139uint32_t RefDieIdx = 0;
1140if (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(
1151DebugULEB128DieRefPatch(OutputExpression.size(),this,this,
1152 RefDieIdx),
1153 PatchesOffsets);
1154 }else
1155 RealSize =encodeULEB128(Offset, ULEB, ULEBsize);
1156
1157if (RealSize > ULEBsize) {
1158// Emit the generic type as a fallback.
1159 RealSize =encodeULEB128(0, ULEB, ULEBsize);
1160warn("base type ref doesn't fit.");
1161 }
1162assert(RealSize == ULEBsize &&"padding failed");
1163ArrayRef<uint8_t> ULEBbytes(ULEB, ULEBsize);
1164 OutputExpression.append(ULEBbytes.begin(), ULEBbytes.end());
1165 }elseif (!getGlobalData().getOptions().UpdateIndexTablesOnly &&
1166Op.getCode() == dwarf::DW_OP_addrx) {
1167if (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);
1174uint64_t LinkedAddress = SA->Address + VarAddressAdjustment.value_or(0);
1175if (getEndianness() !=llvm::endianness::native)
1176sys::swapByteOrder(LinkedAddress);
1177ArrayRef<uint8_t> AddressBytes(
1178reinterpret_cast<constuint8_t *>(&LinkedAddress),
1179 OrigAddressByteSize);
1180 OutputExpression.append(AddressBytes.begin(), AddressBytes.end());
1181 }else
1182warn("cann't read DW_OP_addrx operand.");
1183 }elseif (!getGlobalData().getOptions().UpdateIndexTablesOnly &&
1184Op.getCode() == dwarf::DW_OP_constx) {
1185if (std::optional<object::SectionedAddress> SA =
1186 OrigUnit.getAddrOffsetSectionItem(Op.getRawOperand(0))) {
1187// DWARFLinker does not use constx forms since it generates relocated
1188// addresses. Replace DW_OP_constx with DW_OP_const[*]u here.
1189// Argument of DW_OP_constx should be relocated here as it is not
1190// processed by applyValidRelocs.
1191 std::optional<uint8_t> OutOperandKind;
1192switch (OrigAddressByteSize) {
1193case 2:
1194 OutOperandKind = dwarf::DW_OP_const2u;
1195break;
1196case 4:
1197 OutOperandKind = dwarf::DW_OP_const4u;
1198break;
1199case 8:
1200 OutOperandKind = dwarf::DW_OP_const8u;
1201break;
1202default:
1203warn(
1204formatv(("unsupported address size: {0}."), OrigAddressByteSize));
1205break;
1206 }
1207
1208if (OutOperandKind) {
1209 OutputExpression.push_back(*OutOperandKind);
1210uint64_t LinkedAddress =
1211 SA->Address + VarAddressAdjustment.value_or(0);
1212if (getEndianness() !=llvm::endianness::native)
1213sys::swapByteOrder(LinkedAddress);
1214ArrayRef<uint8_t> AddressBytes(
1215reinterpret_cast<constuint8_t *>(&LinkedAddress),
1216 OrigAddressByteSize);
1217 OutputExpression.append(AddressBytes.begin(), AddressBytes.end());
1218 }
1219 }else
1220warn("cann't read DW_OP_constx operand.");
1221 }else {
1222// Copy over everything else unmodified.
1223StringRef Bytes =
1224 InputExpression.getData().slice(OpOffset,Op.getEndOffset());
1225 OutputExpression.append(Bytes.begin(), Bytes.end());
1226 }
1227 OpOffset =Op.getEndOffset();
1228 }
1229}
1230
1231ErrorCompileUnit::cloneAndEmit(
1232 std::optional<std::reference_wrapper<const Triple>> TargetTriple,
1233TypeUnit *ArtificialTypeUnit) {
1234BumpPtrAllocatorAllocator;
1235
1236DWARFDie OrigUnitDIE =getOrigUnit().getUnitDIE();
1237if (!OrigUnitDIE.isValid())
1238returnError::success();
1239
1240TypeEntry *RootEntry =nullptr;
1241if (ArtificialTypeUnit)
1242 RootEntry = ArtificialTypeUnit->getTypePool().getRoot();
1243
1244// Clone input DIE entry recursively.
1245 std::pair<DIE *, TypeEntry *> OutCUDie =cloneDIE(
1246 OrigUnitDIE.getDebugInfoEntry(), RootEntry,getDebugInfoHeaderSize(),
1247 std::nullopt, std::nullopt,Allocator, ArtificialTypeUnit);
1248setOutUnitDIE(OutCUDie.first);
1249
1250if (!TargetTriple.has_value() || (OutCUDie.first ==nullptr))
1251returnError::success();
1252
1253if (Error Err =cloneAndEmitLineTable((*TargetTriple).get()))
1254return Err;
1255
1256if (Error Err =cloneAndEmitDebugMacro())
1257return Err;
1258
1259getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo);
1260if (Error Err =emitDebugInfo((*TargetTriple).get()))
1261return Err;
1262
1263// ASSUMPTION: .debug_info section should already be emitted at this point.
1264// cloneAndEmitRanges & cloneAndEmitDebugLocations use .debug_info section
1265// data.
1266
1267if (Error Err =cloneAndEmitRanges())
1268return Err;
1269
1270if (Error Err =cloneAndEmitDebugLocations())
1271return Err;
1272
1273if (Error Err = emitDebugAddrSection())
1274return Err;
1275
1276// Generate Pub accelerator tables.
1277if (llvm::is_contained(GlobalData.getOptions().AccelTables,
1278DWARFLinker::AccelTableKind::Pub))
1279emitPubAccelerators();
1280
1281if (Error Err =emitDebugStringOffsetSection())
1282return Err;
1283
1284returnemitAbbreviations();
1285}
1286
1287std::pair<DIE *, TypeEntry *>CompileUnit::cloneDIE(
1288constDWARFDebugInfoEntry *InputDieEntry,TypeEntry *ClonedParentTypeDIE,
1289uint64_t OutOffset, std::optional<int64_t> FuncAddressAdjustment,
1290 std::optional<int64_t> VarAddressAdjustment,BumpPtrAllocator &Allocator,
1291TypeUnit *ArtificialTypeUnit) {
1292uint32_t InputDieIdx =getDIEIndex(InputDieEntry);
1293CompileUnit::DIEInfo &Info =getDIEInfo(InputDieIdx);
1294
1295bool NeedToClonePlainDIE =Info.needToKeepInPlainDwarf();
1296bool NeedToCloneTypeDIE =
1297 (InputDieEntry->getTag() != dwarf::DW_TAG_compile_unit) &&
1298Info.needToPlaceInTypeTable();
1299 std::pair<DIE *, TypeEntry *> ClonedDIE;
1300
1301DIEGenerator PlainDIEGenerator(Allocator, *this);
1302
1303if (NeedToClonePlainDIE)
1304// Create a cloned DIE which would be placed into the cloned version
1305// of input compile unit.
1306 ClonedDIE.first = createPlainDIEandCloneAttributes(
1307 InputDieEntry, PlainDIEGenerator, OutOffset, FuncAddressAdjustment,
1308 VarAddressAdjustment);
1309if (NeedToCloneTypeDIE) {
1310// Create a cloned DIE which would be placed into the artificial type
1311// unit.
1312assert(ArtificialTypeUnit !=nullptr);
1313DIEGenerator TypeDIEGenerator(
1314 ArtificialTypeUnit->getTypePool().getThreadLocalAllocator(), *this);
1315
1316 ClonedDIE.second = createTypeDIEandCloneAttributes(
1317 InputDieEntry, TypeDIEGenerator, ClonedParentTypeDIE,
1318 ArtificialTypeUnit);
1319 }
1320TypeEntry *TypeParentForChild =
1321 ClonedDIE.second ? ClonedDIE.second : ClonedParentTypeDIE;
1322
1323bool HasPlainChildrenToClone =
1324 (ClonedDIE.first &&Info.getKeepPlainChildren());
1325
1326bool HasTypeChildrenToClone =
1327 ((ClonedDIE.second ||
1328 InputDieEntry->getTag() == dwarf::DW_TAG_compile_unit) &&
1329Info.getKeepTypeChildren());
1330
1331// Recursively clone children.
1332if (HasPlainChildrenToClone || HasTypeChildrenToClone) {
1333for (constDWARFDebugInfoEntry *CurChild =
1334getFirstChildEntry(InputDieEntry);
1335 CurChild && CurChild->getAbbreviationDeclarationPtr();
1336 CurChild =getSiblingEntry(CurChild)) {
1337 std::pair<DIE *, TypeEntry *> ClonedChild =cloneDIE(
1338 CurChild, TypeParentForChild, OutOffset, FuncAddressAdjustment,
1339 VarAddressAdjustment,Allocator, ArtificialTypeUnit);
1340
1341if (ClonedChild.first) {
1342 OutOffset =
1343 ClonedChild.first->getOffset() + ClonedChild.first->getSize();
1344 PlainDIEGenerator.addChild(ClonedChild.first);
1345 }
1346 }
1347assert(ClonedDIE.first ==nullptr ||
1348 HasPlainChildrenToClone == ClonedDIE.first->hasChildren());
1349
1350// Account for the end of children marker.
1351if (HasPlainChildrenToClone)
1352 OutOffset +=sizeof(int8_t);
1353 }
1354
1355// Update our size.
1356if (ClonedDIE.first !=nullptr)
1357 ClonedDIE.first->setSize(OutOffset - ClonedDIE.first->getOffset());
1358
1359return ClonedDIE;
1360}
1361
1362DIE *CompileUnit::createPlainDIEandCloneAttributes(
1363constDWARFDebugInfoEntry *InputDieEntry,DIEGenerator &PlainDIEGenerator,
1364uint64_t &OutOffset, std::optional<int64_t> &FuncAddressAdjustment,
1365 std::optional<int64_t> &VarAddressAdjustment) {
1366uint32_t InputDieIdx =getDIEIndex(InputDieEntry);
1367CompileUnit::DIEInfo &Info =getDIEInfo(InputDieIdx);
1368DIE *ClonedDIE =nullptr;
1369bool HasLocationExpressionAddress =false;
1370if (InputDieEntry->getTag() == dwarf::DW_TAG_subprogram) {
1371// Get relocation adjustment value for the current function.
1372 FuncAddressAdjustment =
1373getContaingFile().Addresses->getSubprogramRelocAdjustment(
1374getDIE(InputDieEntry),false);
1375 }elseif (InputDieEntry->getTag() == dwarf::DW_TAG_label) {
1376// Get relocation adjustment value for the current label.
1377 std::optional<uint64_t> lowPC =
1378dwarf::toAddress(find(InputDieEntry, dwarf::DW_AT_low_pc));
1379if (lowPC) {
1380LabelMapTy::iterator It = Labels.find(*lowPC);
1381if (It != Labels.end())
1382 FuncAddressAdjustment = It->second;
1383 }
1384 }elseif (InputDieEntry->getTag() == dwarf::DW_TAG_variable) {
1385// Get relocation adjustment value for the current variable.
1386 std::pair<bool, std::optional<int64_t>> LocExprAddrAndRelocAdjustment =
1387getContaingFile().Addresses->getVariableRelocAdjustment(
1388getDIE(InputDieEntry),false);
1389
1390 HasLocationExpressionAddress = LocExprAddrAndRelocAdjustment.first;
1391if (LocExprAddrAndRelocAdjustment.first &&
1392 LocExprAddrAndRelocAdjustment.second)
1393 VarAddressAdjustment = *LocExprAddrAndRelocAdjustment.second;
1394 }
1395
1396 ClonedDIE = PlainDIEGenerator.createDIE(InputDieEntry->getTag(), OutOffset);
1397
1398// Offset to the DIE would be used after output DIE tree is deleted.
1399// Thus we need to remember DIE offset separately.
1400rememberDieOutOffset(InputDieIdx, OutOffset);
1401
1402// Clone Attributes.
1403DIEAttributeCloner AttributesCloner(ClonedDIE, *this,this, InputDieEntry,
1404 PlainDIEGenerator, FuncAddressAdjustment,
1405 VarAddressAdjustment,
1406 HasLocationExpressionAddress);
1407 AttributesCloner.clone();
1408
1409// Remember accelerator info.
1410AcceleratorRecordsSaver AccelRecordsSaver(getGlobalData(), *this,this);
1411 AccelRecordsSaver.save(InputDieEntry, ClonedDIE, AttributesCloner.AttrInfo,
1412nullptr);
1413
1414 OutOffset =
1415 AttributesCloner.finalizeAbbreviations(Info.getKeepPlainChildren());
1416
1417return ClonedDIE;
1418}
1419
1420/// Allocates output DIE for the specified \p TypeDescriptor.
1421DIE *CompileUnit::allocateTypeDie(TypeEntryBody *TypeDescriptor,
1422DIEGenerator &TypeDIEGenerator,
1423dwarf::Tag DieTag,bool IsDeclaration,
1424bool IsParentDeclaration) {
1425DIE *DefinitionDie = TypeDescriptor->Die;
1426// Do not allocate any new DIE if definition DIE is already met.
1427if (DefinitionDie)
1428returnnullptr;
1429
1430DIE *DeclarationDie = TypeDescriptor->DeclarationDie;
1431bool OldParentIsDeclaration = TypeDescriptor->ParentIsDeclaration;
1432
1433if (IsDeclaration && !DeclarationDie) {
1434// Alocate declaration DIE.
1435DIE *NewDie = TypeDIEGenerator.createDIE(DieTag, 0);
1436if (TypeDescriptor->DeclarationDie.compare_exchange_weak(DeclarationDie,
1437 NewDie))
1438return NewDie;
1439 }elseif (IsDeclaration && !IsParentDeclaration && OldParentIsDeclaration) {
1440// Overwrite existing declaration DIE if it's parent is also an declaration
1441// while parent of current declaration DIE is a definition.
1442if (TypeDescriptor->ParentIsDeclaration.compare_exchange_weak(
1443 OldParentIsDeclaration,false)) {
1444DIE *NewDie = TypeDIEGenerator.createDIE(DieTag, 0);
1445 TypeDescriptor->DeclarationDie = NewDie;
1446return NewDie;
1447 }
1448 }elseif (!IsDeclaration && IsParentDeclaration && !DeclarationDie) {
1449// Alocate declaration DIE since parent of current DIE is marked as
1450// declaration.
1451DIE *NewDie = TypeDIEGenerator.createDIE(DieTag, 0);
1452if (TypeDescriptor->DeclarationDie.compare_exchange_weak(DeclarationDie,
1453 NewDie))
1454return NewDie;
1455 }elseif (!IsDeclaration && !IsParentDeclaration) {
1456// Allocate definition DIE.
1457DIE *NewDie = TypeDIEGenerator.createDIE(DieTag, 0);
1458if (TypeDescriptor->Die.compare_exchange_weak(DefinitionDie, NewDie)) {
1459 TypeDescriptor->ParentIsDeclaration =false;
1460return NewDie;
1461 }
1462 }
1463
1464returnnullptr;
1465}
1466
1467TypeEntry *CompileUnit::createTypeDIEandCloneAttributes(
1468constDWARFDebugInfoEntry *InputDieEntry,DIEGenerator &TypeDIEGenerator,
1469TypeEntry *ClonedParentTypeDIE,TypeUnit *ArtificialTypeUnit) {
1470assert(ArtificialTypeUnit !=nullptr);
1471uint32_t InputDieIdx =getDIEIndex(InputDieEntry);
1472
1473TypeEntry *Entry =getDieTypeEntry(InputDieIdx);
1474assert(Entry !=nullptr);
1475assert(ClonedParentTypeDIE !=nullptr);
1476TypeEntryBody *EntryBody =
1477 ArtificialTypeUnit->getTypePool().getOrCreateTypeEntryBody(
1478 Entry, ClonedParentTypeDIE);
1479assert(EntryBody);
1480
1481bool IsDeclaration =
1482dwarf::toUnsigned(find(InputDieEntry, dwarf::DW_AT_declaration), 0);
1483
1484bool ParentIsDeclaration =false;
1485if (std::optional<uint32_t> ParentIdx = InputDieEntry->getParentIdx())
1486 ParentIsDeclaration =
1487dwarf::toUnsigned(find(*ParentIdx, dwarf::DW_AT_declaration), 0);
1488
1489DIE *OutDIE =
1490 allocateTypeDie(EntryBody, TypeDIEGenerator, InputDieEntry->getTag(),
1491 IsDeclaration, ParentIsDeclaration);
1492
1493if (OutDIE !=nullptr) {
1494assert(ArtificialTypeUnit !=nullptr);
1495 ArtificialTypeUnit->getSectionDescriptor(DebugSectionKind::DebugInfo);
1496
1497DIEAttributeCloner AttributesCloner(OutDIE, *this, ArtificialTypeUnit,
1498 InputDieEntry, TypeDIEGenerator,
1499 std::nullopt, std::nullopt,false);
1500 AttributesCloner.clone();
1501
1502// Remember accelerator info.
1503AcceleratorRecordsSaver AccelRecordsSaver(getGlobalData(), *this,
1504 ArtificialTypeUnit);
1505 AccelRecordsSaver.save(InputDieEntry, OutDIE, AttributesCloner.AttrInfo,
1506 Entry);
1507
1508// if AttributesCloner.getOutOffset() == 0 then we need to add
1509// 1 to avoid assertion for zero size. We will subtract it back later.
1510 OutDIE->setSize(AttributesCloner.getOutOffset() + 1);
1511 }
1512
1513returnEntry;
1514}
1515
1516ErrorCompileUnit::cloneAndEmitLineTable(constTriple &TargetTriple) {
1517constDWARFDebugLine::LineTable *InputLineTable =
1518getContaingFile().Dwarf->getLineTableForUnit(&getOrigUnit());
1519if (InputLineTable ==nullptr) {
1520if (getOrigUnit().getUnitDIE().find(dwarf::DW_AT_stmt_list))
1521warn("cann't load line table.");
1522returnError::success();
1523 }
1524
1525DWARFDebugLine::LineTable OutLineTable;
1526
1527// Set Line Table header.
1528 OutLineTable.Prologue = InputLineTable->Prologue;
1529 OutLineTable.Prologue.FormParams.AddrSize =getFormParams().AddrSize;
1530
1531// Set Line Table Rows.
1532if (getGlobalData().getOptions().UpdateIndexTablesOnly) {
1533 OutLineTable.Rows = InputLineTable->Rows;
1534// If all the line table contains is a DW_LNE_end_sequence, clear the line
1535// table rows, it will be inserted again in the DWARFStreamer.
1536if (OutLineTable.Rows.size() == 1 && OutLineTable.Rows[0].EndSequence)
1537 OutLineTable.Rows.clear();
1538
1539 OutLineTable.Sequences = InputLineTable->Sequences;
1540 }else {
1541// This vector is the output line table.
1542 std::vector<DWARFDebugLine::Row> NewRows;
1543 NewRows.reserve(InputLineTable->Rows.size());
1544
1545// Current sequence of rows being extracted, before being inserted
1546// in NewRows.
1547 std::vector<DWARFDebugLine::Row> Seq;
1548
1549constauto &FunctionRanges =getFunctionRanges();
1550 std::optional<AddressRangeValuePair> CurrRange;
1551
1552// FIXME: This logic is meant to generate exactly the same output as
1553// Darwin's classic dsymutil. There is a nicer way to implement this
1554// by simply putting all the relocated line info in NewRows and simply
1555// sorting NewRows before passing it to emitLineTableForUnit. This
1556// should be correct as sequences for a function should stay
1557// together in the sorted output. There are a few corner cases that
1558// look suspicious though, and that required to implement the logic
1559// this way. Revisit that once initial validation is finished.
1560
1561// Iterate over the object file line info and extract the sequences
1562// that correspond to linked functions.
1563for (DWARFDebugLine::Row Row : InputLineTable->Rows) {
1564// Check whether we stepped out of the range. The range is
1565// half-open, but consider accept the end address of the range if
1566// it is marked as end_sequence in the input (because in that
1567// case, the relocation offset is accurate and that entry won't
1568// serve as the start of another function).
1569if (!CurrRange || !CurrRange->Range.contains(Row.Address.Address)) {
1570// We just stepped out of a known range. Insert a end_sequence
1571// corresponding to the end of the range.
1572uint64_t StopAddress =
1573 CurrRange ? CurrRange->Range.end() + CurrRange->Value : -1ULL;
1574 CurrRange = FunctionRanges.getRangeThatContains(Row.Address.Address);
1575if (StopAddress != -1ULL && !Seq.empty()) {
1576// Insert end sequence row with the computed end address, but
1577// the same line as the previous one.
1578auto NextLine = Seq.back();
1579 NextLine.Address.Address = StopAddress;
1580 NextLine.EndSequence = 1;
1581 NextLine.PrologueEnd = 0;
1582 NextLine.BasicBlock = 0;
1583 NextLine.EpilogueBegin = 0;
1584 Seq.push_back(NextLine);
1585 insertLineSequence(Seq, NewRows);
1586 }
1587
1588if (!CurrRange)
1589continue;
1590 }
1591
1592// Ignore empty sequences.
1593if (Row.EndSequence && Seq.empty())
1594continue;
1595
1596// Relocate row address and add it to the current sequence.
1597 Row.Address.Address += CurrRange->Value;
1598 Seq.emplace_back(Row);
1599
1600if (Row.EndSequence)
1601 insertLineSequence(Seq, NewRows);
1602 }
1603
1604 OutLineTable.Rows = std::move(NewRows);
1605 }
1606
1607returnemitDebugLine(TargetTriple, OutLineTable);
1608}
1609
1610void CompileUnit::insertLineSequence(std::vector<DWARFDebugLine::Row> &Seq,
1611 std::vector<DWARFDebugLine::Row> &Rows) {
1612if (Seq.empty())
1613return;
1614
1615if (!Rows.empty() && Rows.back().Address < Seq.front().Address) {
1616llvm::append_range(Rows, Seq);
1617 Seq.clear();
1618return;
1619 }
1620
1621object::SectionedAddress Front = Seq.front().Address;
1622auto InsertPoint =partition_point(
1623 Rows, [=](constDWARFDebugLine::Row &O) {return O.Address < Front; });
1624
1625// FIXME: this only removes the unneeded end_sequence if the
1626// sequences have been inserted in order. Using a global sort like
1627// described in cloneAndEmitLineTable() and delaying the end_sequene
1628// elimination to DebugLineEmitter::emit() we can get rid of all of them.
1629if (InsertPoint != Rows.end() && InsertPoint->Address == Front &&
1630 InsertPoint->EndSequence) {
1631 *InsertPoint = Seq.front();
1632 Rows.insert(InsertPoint + 1, Seq.begin() + 1, Seq.end());
1633 }else {
1634 Rows.insert(InsertPoint, Seq.begin(), Seq.end());
1635 }
1636
1637 Seq.clear();
1638}
1639
1640#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1641LLVM_DUMP_METHODvoidCompileUnit::DIEInfo::dump() {
1642llvm::errs() <<"{";
1643llvm::errs() <<" Placement: ";
1644switch (getPlacement()) {
1645caseNotSet:
1646llvm::errs() <<"NotSet";
1647break;
1648caseTypeTable:
1649llvm::errs() <<"TypeTable";
1650break;
1651casePlainDwarf:
1652llvm::errs() <<"PlainDwarf";
1653break;
1654caseBoth:
1655llvm::errs() <<"Both";
1656break;
1657 }
1658
1659llvm::errs() <<" Keep: " << getKeep();
1660llvm::errs() <<" KeepPlainChildren: " << getKeepPlainChildren();
1661llvm::errs() <<" KeepTypeChildren: " << getKeepTypeChildren();
1662llvm::errs() <<" IsInMouduleScope: " << getIsInMouduleScope();
1663llvm::errs() <<" IsInFunctionScope: " << getIsInFunctionScope();
1664llvm::errs() <<" IsInAnonNamespaceScope: " << getIsInAnonNamespaceScope();
1665llvm::errs() <<" ODRAvailable: " << getODRAvailable();
1666llvm::errs() <<" TrackLiveness: " << getTrackLiveness();
1667llvm::errs() <<"}\n";
1668}
1669#endif// if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1670
1671std::optional<std::pair<StringRef, StringRef>>
1672CompileUnit::getDirAndFilenameFromLineTable(
1673constDWARFFormValue &FileIdxValue) {
1674uint64_t FileIdx;
1675if (std::optional<uint64_t> Val = FileIdxValue.getAsUnsignedConstant())
1676 FileIdx = *Val;
1677elseif (std::optional<int64_t> Val = FileIdxValue.getAsSignedConstant())
1678 FileIdx = *Val;
1679elseif (std::optional<uint64_t> Val = FileIdxValue.getAsSectionOffset())
1680 FileIdx = *Val;
1681else
1682return std::nullopt;
1683
1684returngetDirAndFilenameFromLineTable(FileIdx);
1685}
1686
1687std::optional<std::pair<StringRef, StringRef>>
1688CompileUnit::getDirAndFilenameFromLineTable(uint64_t FileIdx) {
1689FileNamesCache::iterator FileData =FileNames.find(FileIdx);
1690if (FileData !=FileNames.end())
1691return std::make_pair(StringRef(FileData->second.first),
1692StringRef(FileData->second.second));
1693
1694if (constDWARFDebugLine::LineTable *LineTable =
1695getOrigUnit().getContext().getLineTableForUnit(&getOrigUnit())) {
1696if (LineTable->hasFileAtIndex(FileIdx)) {
1697
1698constllvm::DWARFDebugLine::FileNameEntry &Entry =
1699 LineTable->Prologue.getFileNameEntry(FileIdx);
1700
1701Expected<const char *>Name = Entry.Name.getAsCString();
1702if (!Name) {
1703warn(Name.takeError());
1704return std::nullopt;
1705 }
1706
1707 std::string FileName = *Name;
1708if (isPathAbsoluteOnWindowsOrPosix(FileName)) {
1709FileNamesCache::iterator FileData =
1710FileNames
1711 .insert(std::make_pair(
1712 FileIdx,
1713 std::make_pair(std::string(""), std::move(FileName))))
1714 .first;
1715return std::make_pair(StringRef(FileData->second.first),
1716StringRef(FileData->second.second));
1717 }
1718
1719SmallString<256> FilePath;
1720StringRef IncludeDir;
1721// Be defensive about the contents of Entry.
1722if (getVersion() >= 5) {
1723// DirIdx 0 is the compilation directory, so don't include it for
1724// relative names.
1725if ((Entry.DirIdx != 0) &&
1726 Entry.DirIdx < LineTable->Prologue.IncludeDirectories.size()) {
1727Expected<const char *> DirName =
1728 LineTable->Prologue.IncludeDirectories[Entry.DirIdx]
1729 .getAsCString();
1730if (DirName)
1731 IncludeDir = *DirName;
1732else {
1733warn(DirName.takeError());
1734return std::nullopt;
1735 }
1736 }
1737 }else {
1738if (0 < Entry.DirIdx &&
1739 Entry.DirIdx <= LineTable->Prologue.IncludeDirectories.size()) {
1740Expected<const char *> DirName =
1741 LineTable->Prologue.IncludeDirectories[Entry.DirIdx - 1]
1742 .getAsCString();
1743if (DirName)
1744 IncludeDir = *DirName;
1745else {
1746warn(DirName.takeError());
1747return std::nullopt;
1748 }
1749 }
1750 }
1751
1752StringRef CompDir =getOrigUnit().getCompilationDir();
1753
1754if (!CompDir.empty() && !isPathAbsoluteOnWindowsOrPosix(IncludeDir)) {
1755sys::path::append(FilePath,sys::path::Style::native, CompDir);
1756 }
1757
1758sys::path::append(FilePath,sys::path::Style::native, IncludeDir);
1759
1760FileNamesCache::iterator FileData =
1761FileNames
1762 .insert(
1763 std::make_pair(FileIdx, std::make_pair(std::string(FilePath),
1764 std::move(FileName))))
1765 .first;
1766return std::make_pair(StringRef(FileData->second.first),
1767StringRef(FileData->second.second));
1768 }
1769 }
1770
1771return std::nullopt;
1772}
1773
1774#define MAX_REFERENCIES_DEPTH 1000
1775UnitEntryPairTyUnitEntryPairTy::getNamespaceOrigin() {
1776UnitEntryPairTy CUDiePair(*this);
1777 std::optional<UnitEntryPairTy> RefDiePair;
1778int refDepth = 0;
1779do {
1780 RefDiePair = CUDiePair.CU->resolveDIEReference(
1781 CUDiePair.DieEntry, dwarf::DW_AT_extension,
1782ResolveInterCUReferencesMode::Resolve);
1783if (!RefDiePair || !RefDiePair->DieEntry)
1784return CUDiePair;
1785
1786 CUDiePair = *RefDiePair;
1787 }while (refDepth++ <MAX_REFERENCIES_DEPTH);
1788
1789return CUDiePair;
1790}
1791
1792std::optional<UnitEntryPairTy>UnitEntryPairTy::getParent() {
1793if (std::optional<uint32_t> ParentIdx = DieEntry->getParentIdx())
1794returnUnitEntryPairTy{CU,CU->getDebugInfoEntry(*ParentIdx)};
1795
1796return std::nullopt;
1797}
1798
1799CompileUnit::OutputUnitVariantPtr::OutputUnitVariantPtr(CompileUnit *U)
1800 :Ptr(U) {
1801assert(U !=nullptr);
1802}
1803
1804CompileUnit::OutputUnitVariantPtr::OutputUnitVariantPtr(TypeUnit *U) :Ptr(U) {
1805assert(U !=nullptr);
1806}
1807
1808DwarfUnit *CompileUnit::OutputUnitVariantPtr::operator->() {
1809if (isCompileUnit())
1810return getAsCompileUnit();
1811else
1812return getAsTypeUnit();
1813}
1814
1815boolCompileUnit::OutputUnitVariantPtr::isCompileUnit() {
1816return isa<CompileUnit *>(Ptr);
1817}
1818
1819boolCompileUnit::OutputUnitVariantPtr::isTypeUnit() {
1820return isa<TypeUnit *>(Ptr);
1821}
1822
1823CompileUnit *CompileUnit::OutputUnitVariantPtr::getAsCompileUnit() {
1824return cast<CompileUnit *>(Ptr);
1825}
1826
1827TypeUnit *CompileUnit::OutputUnitVariantPtr::getAsTypeUnit() {
1828return cast<TypeUnit *>(Ptr);
1829}
1830
1831boolCompileUnit::resolveDependenciesAndMarkLiveness(
1832bool InterCUProcessingStarted, std::atomic<bool> &HasNewInterconnectedCUs) {
1833if (!Dependencies)
1834 Dependencies.reset(newDependencyTracker(*this));
1835
1836return Dependencies->resolveDependenciesAndMarkLiveness(
1837 InterCUProcessingStarted, HasNewInterconnectedCUs);
1838}
1839
1840boolCompileUnit::updateDependenciesCompleteness() {
1841assert(Dependencies.get());
1842
1843return Dependencies->updateDependenciesCompleteness();
1844}
1845
1846voidCompileUnit::verifyDependencies() {
1847assert(Dependencies.get());
1848
1849 Dependencies->verifyKeepChain();
1850}
1851
1852ArrayRef<dwarf::Attribute>dwarf_linker::parallel::getODRAttributes() {
1853staticdwarf::Attribute ODRAttributes[] = {
1854 dwarf::DW_AT_type, dwarf::DW_AT_specification,
1855 dwarf::DW_AT_abstract_origin, dwarf::DW_AT_import};
1856
1857return ODRAttributes;
1858}
AcceleratorRecordsSaver.h
Info
Analysis containing CSE Info
Definition:CSEInfo.cpp:27
LLVM_DUMP_METHOD
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition:Compiler.h:622
DIEAttributeCloner.h
DIEGenerator.h
DJB.h
DWARFDebugAbbrev.h
DWARFDebugMacro.h
Utils.h
Idx
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
Definition:DeadArgumentElimination.cpp:353
values
Mark the given Function as meaning that it cannot be changed in any way mark any values that are used as this function s parameters or by its return values(according to Uses) live as well. void DeadArgumentEliminationPass
Definition:DeadArgumentElimination.cpp:685
DependencyTracker.h
FileSystem.h
FormatVariadic.h
Range
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
MAX_REFERENCIES_DEPTH
#define MAX_REFERENCIES_DEPTH
Definition:DWARFLinkerCompileUnit.cpp:1774
if
if(PassOpts->AAPipeline)
Definition:PassBuilderBindings.cpp:64
Path.h
Allocator
Basic Register Allocator
Definition:RegAllocBasic.cpp:146
isValid
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
Definition:RustDemangle.cpp:181
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SyntheticTypeNameBuilder.h
Ptr
@ Ptr
Definition:TargetLibraryInfo.cpp:77
llvm::AddressRangeValuePair
Definition:AddressRanges.h:145
llvm::AddressRange
A class that represents an address range.
Definition:AddressRanges.h:22
llvm::AddressRangesBase::clear
void clear()
Definition:AddressRanges.h:64
llvm::AddressRangesBase::empty
bool empty() const
Definition:AddressRanges.h:65
llvm::AddressRangesMap::insert
void insert(AddressRange Range, int64_t Value)
Definition:AddressRanges.h:167
llvm::AddressRanges
The AddressRanges class helps normalize address range collections.
Definition:AddressRanges.h:121
llvm::AddressRanges::insert
Collection::const_iterator insert(AddressRange Range)
Definition:AddressRanges.h:123
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition:ArrayRef.h:41
llvm::ArrayRef::end
iterator end() const
Definition:ArrayRef.h:157
llvm::ArrayRef::begin
iterator begin() const
Definition:ArrayRef.h:156
llvm::BumpPtrAllocatorImpl
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition:Allocator.h:66
llvm::ConcurrentHashTableByPtr::insert
std::pair< KeyDataTy *, bool > insert(const KeyTy &NewValue)
Insert new value NewValue or return already existing entry.
Definition:ConcurrentHashtable.h:172
llvm::DIE
A structured debug information entry.
Definition:DIE.h:819
llvm::DIE::setSize
void setSize(unsigned S)
Definition:DIE.h:931
llvm::DWARFDebugInfoEntry
DWARFDebugInfoEntry - A DIE with only the minimum required data.
Definition:DWARFDebugInfoEntry.h:22
llvm::DWARFDebugInfoEntry::getTag
dwarf::Tag getTag() const
Definition:DWARFDebugInfoEntry.h:66
llvm::DWARFDebugInfoEntry::getParentIdx
std::optional< uint32_t > getParentIdx() const
Returns index of the parent die.
Definition:DWARFDebugInfoEntry.h:48
llvm::DWARFDebugInfoEntry::getAbbreviationDeclarationPtr
const DWARFAbbreviationDeclaration * getAbbreviationDeclarationPtr() const
Definition:DWARFDebugInfoEntry.h:72
llvm::DWARFDebugMacro
Definition:DWARFDebugMacro.h:28
llvm::DWARFDie
Utility class that carries the DWARF compile/type unit and the debug info entry in an object.
Definition:DWARFDie.h:42
llvm::DWARFDie::find
std::optional< DWARFFormValue > find(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE.
Definition:DWARFDie.cpp:249
llvm::DWARFDie::getDebugInfoEntry
const DWARFDebugInfoEntry * getDebugInfoEntry() const
Definition:DWARFDie.h:53
llvm::DWARFDie::getName
const char * getName(DINameKind Kind) const
Return the DIE name resolving DW_AT_specification or DW_AT_abstract_origin references if necessary.
Definition:DWARFDie.cpp:462
llvm::DWARFDie::isValid
bool isValid() const
Definition:DWARFDie.h:51
llvm::DWARFExpression::Operation
This class represents an Operation in the Expression.
Definition:DWARFExpression.h:32
llvm::DWARFExpression::Operation::getSubCode
std::optional< unsigned > getSubCode() const
Definition:DWARFExpression.cpp:296
llvm::DWARFExpression::Operation::getCode
uint8_t getCode() const
Definition:DWARFExpression.h:88
llvm::DWARFExpression::Operation::getEndOffset
uint64_t getEndOffset() const
Definition:DWARFExpression.h:99
llvm::DWARFExpression::Operation::Encoding
Encoding
Size and signedness of expression operations' operands.
Definition:DWARFExpression.h:35
llvm::DWARFExpression::Operation::getDescription
const Description & getDescription() const
Definition:DWARFExpression.h:87
llvm::DWARFExpression::Operation::getRawOperand
uint64_t getRawOperand(unsigned Idx) const
Definition:DWARFExpression.h:92
llvm::DWARFExpression
Definition:DWARFExpression.h:23
llvm::DWARFExpression::getData
StringRef getData() const
Definition:DWARFExpression.h:170
llvm::DWARFFormValue
Definition:DWARFFormValue.h:26
llvm::DWARFFormValue::getAsSectionOffset
std::optional< uint64_t > getAsSectionOffset() const
Definition:DWARFFormValue.cpp:706
llvm::DWARFFormValue::getAsSignedConstant
std::optional< int64_t > getAsSignedConstant() const
Definition:DWARFFormValue.cpp:719
llvm::DWARFFormValue::getAsRelativeReference
std::optional< uint64_t > getAsRelativeReference() const
getAsFoo functions below return the extracted value as Foo if only DWARFFormValue has form class is s...
Definition:DWARFFormValue.cpp:668
llvm::DWARFFormValue::getAsDebugInfoReference
std::optional< uint64_t > getAsDebugInfoReference() const
Definition:DWARFFormValue.cpp:683
llvm::DWARFFormValue::getAsUnsignedConstant
std::optional< uint64_t > getAsUnsignedConstant() const
Definition:DWARFFormValue.cpp:712
llvm::DWARFFormValue::getUnit
const DWARFUnit * getUnit() const
Definition:DWARFFormValue.h:84
llvm::DWARFUnit
Definition:DWARFUnit.h:211
llvm::DWARFUnit::getFormParams
const dwarf::FormParams & getFormParams() const
Definition:DWARFUnit.h:322
llvm::DWARFUnit::getUnitDIE
DWARFDie getUnitDIE(bool ExtractUnitDIEOnly=true)
Definition:DWARFUnit.h:443
llvm::DWARFUnit::getAddressByteSize
uint8_t getAddressByteSize() const
Definition:DWARFUnit.h:326
llvm::DWARFUnit::clear
void clear()
Definition:DWARFUnit.cpp:387
llvm::DWARFUnit::getCompilationDir
const char * getCompilationDir()
Definition:DWARFUnit.cpp:401
llvm::DWARFUnit::getDIEIndexForOffset
std::optional< uint32_t > getDIEIndexForOffset(uint64_t Offset)
Return the DIE index for a given offset Offset inside the unit's DIE vector.
Definition:DWARFUnit.h:542
llvm::DWARFUnit::findLoclistFromOffset
Expected< DWARFLocationExpressionsVector > findLoclistFromOffset(uint64_t Offset)
Definition:DWARFUnit.cpp:709
llvm::DWARFUnit::isLittleEndian
bool isLittleEndian() const
Definition:DWARFUnit.h:317
llvm::DWARFUnit::getAddrOffsetSectionItem
std::optional< object::SectionedAddress > getAddrOffsetSectionItem(uint32_t Index) const
Definition:DWARFUnit.cpp:215
llvm::DWARFUnit::getOffset
uint64_t getOffset() const
Definition:DWARFUnit.h:321
llvm::DataExtractor
Definition:DataExtractor.h:41
llvm::DenseMapBase::find
iterator find(const_arg_type_t< KeyT > Val)
Definition:DenseMap.h:156
llvm::DenseMapBase::iterator
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT > iterator
Definition:DenseMap.h:71
llvm::DenseMapBase::end
iterator end()
Definition:DenseMap.h:84
llvm::DenseMapBase::insert
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition:DenseMap.h:211
llvm::DenseMapBase::clear
void clear()
Definition:DenseMap.h:110
llvm::DenseMapIterator
Definition:DenseMap.h:1189
llvm::DenseMap::shrink_and_clear
void shrink_and_clear()
Definition:DenseMap.h:832
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition:Error.h:160
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition:Error.h:337
llvm::Expected
Tagged union holding either a T or a Error.
Definition:Error.h:481
llvm::Expected::takeError
Error takeError()
Take ownership of the stored error.
Definition:Error.h:608
llvm::SmallString
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition:SmallString.h:26
llvm::SmallVectorBase::size
size_t size() const
Definition:SmallVector.h:78
llvm::SmallVectorImpl
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition:SmallVector.h:573
llvm::SmallVectorImpl::append
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
Definition:SmallVector.h:683
llvm::SmallVectorImpl::resize
void resize(size_type N)
Definition:SmallVector.h:638
llvm::SmallVectorTemplateBase::push_back
void push_back(const T &Elt)
Definition:SmallVector.h:413
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition:SmallVector.h:1196
llvm::StringMapEntryStorage::second
ValueTy second
Definition:StringMapEntry.h:71
llvm::StringMapEntry
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
Definition:StringMapEntry.h:102
llvm::StringMapIterator
Definition:StringMap.h:496
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition:StringRef.h:51
llvm::StringRef::str
std::string str() const
str - Get the contents as an std::string.
Definition:StringRef.h:229
llvm::StringRef::empty
constexpr bool empty() const
empty - Check if the string is empty.
Definition:StringRef.h:147
llvm::StringRef::begin
iterator begin() const
Definition:StringRef.h:116
llvm::StringRef::slice
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
Definition:StringRef.h:684
llvm::StringRef::end
iterator end() const
Definition:StringRef.h:118
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition:Triple.h:44
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition:Twine.h:81
llvm::dwarf_linker::DWARFFile
This class represents DWARF information for source file and it's address map.
Definition:DWARFFile.h:25
llvm::dwarf_linker::DWARFFile::Addresses
std::unique_ptr< AddressesMap > Addresses
Helpful address information(list of valid address ranges, relocations).
Definition:DWARFFile.h:42
llvm::dwarf_linker::DWARFFile::Dwarf
std::unique_ptr< DWARFContext > Dwarf
Source DWARF information.
Definition:DWARFFile.h:39
llvm::dwarf_linker::DWARFLinkerBase::AccelTableKind::Pub
@ Pub
.debug_pubnames, .debug_pubtypes
llvm::dwarf_linker::IndexedValuesMap::getValueIndex
uint64_t getValueIndex(T Value)
Definition:IndexedValuesMap.h:23
llvm::dwarf_linker::IndexedValuesMap::empty
bool empty()
Definition:IndexedValuesMap.h:37
llvm::dwarf_linker::IndexedValuesMap::getValues
const SmallVector< T > & getValues() const
Definition:IndexedValuesMap.h:30
llvm::dwarf_linker::IndexedValuesMap::clear
void clear()
Definition:IndexedValuesMap.h:32
llvm::dwarf_linker::StringPool
Definition:StringPool.h:53
llvm::dwarf_linker::classic::CompileUnit::CompileUnit
CompileUnit(DWARFUnit &OrigUnit, unsigned ID, bool CanUseODR, StringRef ClangModuleName)
Definition:DWARFLinkerCompileUnit.h:108
llvm::dwarf_linker::parallel::AcceleratorRecordsSaver
This class helps to store information for accelerator entries.
Definition:AcceleratorRecordsSaver.h:24
llvm::dwarf_linker::parallel::ArrayList::erase
void erase()
Erase list.
Definition:ArrayList.h:75
llvm::dwarf_linker::parallel::CompileUnit::OutputUnitVariantPtr::getAsTypeUnit
TypeUnit * getAsTypeUnit()
Returns TypeUnit if applicable.
Definition:DWARFLinkerCompileUnit.cpp:1827
llvm::dwarf_linker::parallel::CompileUnit::OutputUnitVariantPtr::isTypeUnit
bool isTypeUnit()
Definition:DWARFLinkerCompileUnit.cpp:1819
llvm::dwarf_linker::parallel::CompileUnit::OutputUnitVariantPtr::operator->
DwarfUnit * operator->()
Accessor for common functionality.
Definition:DWARFLinkerCompileUnit.cpp:1808
llvm::dwarf_linker::parallel::CompileUnit::OutputUnitVariantPtr::getAsCompileUnit
CompileUnit * getAsCompileUnit()
Returns CompileUnit if applicable.
Definition:DWARFLinkerCompileUnit.cpp:1823
llvm::dwarf_linker::parallel::CompileUnit::OutputUnitVariantPtr::OutputUnitVariantPtr
OutputUnitVariantPtr(CompileUnit *U)
Definition:DWARFLinkerCompileUnit.cpp:1799
llvm::dwarf_linker::parallel::CompileUnit::OutputUnitVariantPtr::isCompileUnit
bool isCompileUnit()
Definition:DWARFLinkerCompileUnit.cpp:1815
llvm::dwarf_linker::parallel::CompileUnit
Stores all information related to a compile unit, be it in its original instance of the object file o...
Definition:DWARFLinkerCompileUnit.h:53
llvm::dwarf_linker::parallel::CompileUnit::addLabelLowPc
void addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset)
Add the low_pc of a label that is relocated by applying offset PCOffset.
llvm::dwarf_linker::parallel::CompileUnit::cloneAndEmitDebugLocations
Error cloneAndEmitDebugLocations()
Clone and emit debug locations(.debug_loc/.debug_loclists).
Definition:DWARFLinkerCompileUnit.cpp:443
llvm::dwarf_linker::parallel::CompileUnit::cloneDieAttrExpression
void cloneDieAttrExpression(const DWARFExpression &InputExpression, SmallVectorImpl< uint8_t > &OutputExpression, SectionDescriptor &Section, std::optional< int64_t > VarAddressAdjustment, OffsetsPtrVector &PatchesOffsets)
Clone attribute location axpression.
Definition:DWARFLinkerCompileUnit.cpp:1093
llvm::dwarf_linker::parallel::CompileUnit::maybeResetToLoadedStage
void maybeResetToLoadedStage()
Reset compile units data(results of liveness analysis, clonning) if current stage greater than Stage:...
Definition:DWARFLinkerCompileUnit.cpp:75
llvm::dwarf_linker::parallel::CompileUnit::addFunctionRange
void addFunctionRange(uint64_t LowPC, uint64_t HighPC, int64_t PCOffset)
Add a function range [LowPC, HighPC) that is relocated by applying offset PCOffset.
llvm::dwarf_linker::parallel::CompileUnit::analyzeImportedModule
void analyzeImportedModule(const DWARFDebugInfoEntry *DieEntry)
Collect references to parseable Swift interfaces in imported DW_TAG_module blocks.
Definition:DWARFLinkerCompileUnit.cpp:253
llvm::dwarf_linker::parallel::CompileUnit::cloneDIE
std::pair< DIE *, TypeEntry * > cloneDIE(const DWARFDebugInfoEntry *InputDieEntry, TypeEntry *ClonedParentTypeDIE, uint64_t OutOffset, std::optional< int64_t > FuncAddressAdjustment, std::optional< int64_t > VarAddressAdjustment, BumpPtrAllocator &Allocator, TypeUnit *ArtificialTypeUnit)
Definition:DWARFLinkerCompileUnit.cpp:1287
llvm::dwarf_linker::parallel::CompileUnit::cleanupDataAfterClonning
void cleanupDataAfterClonning()
Cleanup unneeded resources after compile unit is cloned.
Definition:DWARFLinkerCompileUnit.cpp:239
llvm::dwarf_linker::parallel::CompileUnit::assignTypeNames
Error assignTypeNames(TypePool &TypePoolRef)
Search for type entries and assign names.
Definition:DWARFLinkerCompileUnit.cpp:303
llvm::dwarf_linker::parallel::CompileUnit::Both
@ Both
Corresponding DIE goes to type table and to plain dwarf.
Definition:DWARFLinkerCompileUnit.h:165
llvm::dwarf_linker::parallel::CompileUnit::TypeTable
@ TypeTable
Corresponding DIE goes to the type table only.
Definition:DWARFLinkerCompileUnit.h:159
llvm::dwarf_linker::parallel::CompileUnit::NotSet
@ NotSet
Definition:DWARFLinkerCompileUnit.h:156
llvm::dwarf_linker::parallel::CompileUnit::PlainDwarf
@ PlainDwarf
Corresponding DIE goes to the plain dwarf only.
Definition:DWARFLinkerCompileUnit.h:162
llvm::dwarf_linker::parallel::CompileUnit::cloneAndEmitLineTable
Error cloneAndEmitLineTable(const Triple &TargetTriple)
Definition:DWARFLinkerCompileUnit.cpp:1516
llvm::dwarf_linker::parallel::CompileUnit::cloneAndEmitRanges
Error cloneAndEmitRanges()
Clone and emit ranges.
Definition:DWARFLinkerCompileUnit.cpp:674
llvm::dwarf_linker::parallel::CompileUnit::updateDieRefPatchesWithClonedOffsets
void updateDieRefPatchesWithClonedOffsets()
After cloning stage the output DIEs offsets are deallocated.
Definition:DWARFLinkerCompileUnit.cpp:334
llvm::dwarf_linker::parallel::CompileUnit::getDebugAddrIndex
uint64_t getDebugAddrIndex(uint64_t Addr)
Returns index(inside .debug_addr) of an address.
Definition:DWARFLinkerCompileUnit.h:436
llvm::dwarf_linker::parallel::CompileUnit::getContaingFile
const DWARFFile & getContaingFile() const
Returns DWARFFile containing this compile unit.
Definition:DWARFLinkerCompileUnit.h:111
llvm::dwarf_linker::parallel::CompileUnit::resolveDependenciesAndMarkLiveness
bool resolveDependenciesAndMarkLiveness(bool InterCUProcessingStarted, std::atomic< bool > &HasNewInterconnectedCUs)
Search for subprograms and variables referencing live code and discover dependend DIEs.
Definition:DWARFLinkerCompileUnit.cpp:1831
llvm::dwarf_linker::parallel::CompileUnit::updateDependenciesCompleteness
bool updateDependenciesCompleteness()
Check dependend DIEs for incompatible placement.
Definition:DWARFLinkerCompileUnit.cpp:1840
llvm::dwarf_linker::parallel::CompileUnit::loadInputDIEs
bool loadInputDIEs()
Load DIEs of input compilation unit.
Definition:DWARFLinkerCompileUnit.cpp:114
llvm::dwarf_linker::parallel::CompileUnit::getFunctionRanges
const RangesTy & getFunctionRanges() const
Returns function ranges of this unit.
Definition:DWARFLinkerCompileUnit.h:401
llvm::dwarf_linker::parallel::CompileUnit::cloneAndEmitDebugMacro
Error cloneAndEmitDebugMacro()
Clone and emit debug macros(.debug_macinfo/.debug_macro).
Definition:DWARFLinkerCompileUnit.cpp:894
llvm::dwarf_linker::parallel::CompileUnit::cloneAndEmit
Error cloneAndEmit(std::optional< std::reference_wrapper< const Triple > > TargetTriple, TypeUnit *ArtificialTypeUnit)
Clone and emit this compilation unit.
Definition:DWARFLinkerCompileUnit.cpp:1231
llvm::dwarf_linker::parallel::CompileUnit::setStage
void setStage(Stage Stage)
Set stage of overall processing.
Definition:DWARFLinkerCompileUnit.h:101
llvm::dwarf_linker::parallel::CompileUnit::getStage
Stage getStage() const
Returns stage of overall processing.
Definition:DWARFLinkerCompileUnit.h:98
llvm::dwarf_linker::parallel::CompileUnit::CompileUnit
CompileUnit(LinkingGlobalData &GlobalData, unsigned ID, StringRef ClangModuleName, DWARFFile &File, OffsetToUnitTy UnitFromOffset, dwarf::FormParams Format, llvm::endianness Endianess)
Definition:DWARFLinkerCompileUnit.cpp:28
llvm::dwarf_linker::parallel::CompileUnit::verifyDependencies
void verifyDependencies()
Check DIEs to have a consistent marking(keep marking, placement marking).
Definition:DWARFLinkerCompileUnit.cpp:1846
llvm::dwarf_linker::parallel::CompileUnit::Stage
Stage
The stages of new compile unit processing.
Definition:DWARFLinkerCompileUnit.h:56
llvm::dwarf_linker::parallel::CompileUnit::Stage::Cloned
@ Cloned
Output DWARF is generated.
llvm::dwarf_linker::parallel::CompileUnit::Stage::CreatedNotLoaded
@ CreatedNotLoaded
Created, linked with input DWARF file.
llvm::dwarf_linker::parallel::CompileUnit::Stage::Loaded
@ Loaded
Input DWARF is loaded.
llvm::dwarf_linker::parallel::CompileUnit::getLowPc
std::optional< uint64_t > getLowPc() const
Returns value of DW_AT_low_pc attribute.
Definition:DWARFLinkerCompileUnit.h:369
llvm::dwarf_linker::parallel::CompileUnit::getDirAndFilenameFromLineTable
std::optional< std::pair< StringRef, StringRef > > getDirAndFilenameFromLineTable(const DWARFFormValue &FileIdxValue)
Returns directory and file from the line table by index.
Definition:DWARFLinkerCompileUnit.cpp:1672
llvm::dwarf_linker::parallel::CompileUnit::resolveDIEReference
std::optional< UnitEntryPairTy > resolveDIEReference(const DWARFFormValue &RefValue, ResolveInterCUReferencesMode CanResolveInterCUReferences)
Resolve the DIE attribute reference that has been extracted in RefValue.
Definition:DWARFLinkerCompileUnit.cpp:381
llvm::dwarf_linker::parallel::CompileUnit::loadLineTable
void loadLineTable()
Loads unit line table.
Definition:DWARFLinkerCompileUnit.cpp:71
llvm::dwarf_linker::parallel::CompileUnit::getFileName
StringEntry * getFileName(unsigned FileIdx, StringPool &GlobalStrings)
Returns name of the file for the FileIdx from the unit`s line table.
Definition:DWARFLinkerCompileUnit.cpp:188
llvm::dwarf_linker::parallel::DIEAttributeCloner
This class creates clones of input DIE attributes.
Definition:DIEAttributeCloner.h:47
llvm::dwarf_linker::parallel::DIEGenerator
This class is a helper to create output DIE tree.
Definition:DIEGenerator.h:22
llvm::dwarf_linker::parallel::DIEGenerator::addChild
void addChild(DIE *Child)
Adds a specified Child to the current DIE.
Definition:DIEGenerator.h:42
llvm::dwarf_linker::parallel::DIEGenerator::createDIE
DIE * createDIE(dwarf::Tag DieTag, uint32_t OutOffset)
Creates a DIE of specified tag DieTag and OutOffset.
Definition:DIEGenerator.h:31
llvm::dwarf_linker::parallel::DependencyTracker
This class discovers DIEs dependencies: marks "live" DIEs, marks DIE locations (whether DIE should be...
Definition:DependencyTracker.h:26
llvm::dwarf_linker::parallel::DwarfUnit
Base class for all Dwarf units(Compile unit/Type table unit).
Definition:DWARFLinkerUnit.h:29
llvm::dwarf_linker::parallel::DwarfUnit::FileNames
FileNamesCache FileNames
Definition:DWARFLinkerUnit.h:206
llvm::dwarf_linker::parallel::DwarfUnit::UnitName
std::string UnitName
The name of this unit.
Definition:DWARFLinkerUnit.h:178
llvm::dwarf_linker::parallel::DwarfUnit::getGlobalData
LinkingGlobalData & getGlobalData()
Return global data.
Definition:DWARFLinkerUnit.h:56
llvm::dwarf_linker::parallel::DwarfUnit::Abbreviations
std::vector< std::unique_ptr< DIEAbbrev > > Abbreviations
Storage for the unique Abbreviations.
Definition:DWARFLinkerUnit.h:198
llvm::dwarf_linker::parallel::DwarfUnit::OutUnitDIE
DIE * OutUnitDIE
Output unit DIE.
Definition:DWARFLinkerUnit.h:201
llvm::dwarf_linker::parallel::DwarfUnit::SysRoot
std::string SysRoot
The DW_AT_LLVM_sysroot of this unit.
Definition:DWARFLinkerUnit.h:181
llvm::dwarf_linker::parallel::DwarfUnit::isClangModule
bool isClangModule() const
Return true if this compile unit is from Clang module.
Definition:DWARFLinkerUnit.h:50
llvm::dwarf_linker::parallel::DwarfUnit::getClangModuleName
const std::string & getClangModuleName() const
Return Clang module name;.
Definition:DWARFLinkerUnit.h:53
llvm::dwarf_linker::parallel::DwarfUnit::setOutUnitDIE
void setOutUnitDIE(DIE *UnitDie)
Set output unit DIE.
Definition:DWARFLinkerUnit.h:77
llvm::dwarf_linker::parallel::DwarfUnit::AbbreviationsSet
FoldingSet< DIEAbbrev > AbbreviationsSet
FoldingSet that uniques the abbreviations.
Definition:DWARFLinkerUnit.h:195
llvm::dwarf_linker::parallel::DwarfUnit::getSysRoot
StringRef getSysRoot()
Return the DW_AT_LLVM_sysroot of the compile unit or an empty StringRef.
Definition:DWARFLinkerUnit.h:47
llvm::dwarf_linker::parallel::DwarfUnit::getOutUnitDIE
DIE * getOutUnitDIE()
Returns output unit DIE.
Definition:DWARFLinkerUnit.h:74
llvm::dwarf_linker::parallel::LinkingGlobalData
This class keeps data and services common for the whole linking process.
Definition:DWARFLinkerGlobalData.h:85
llvm::dwarf_linker::parallel::LinkingGlobalData::getOptions
const DWARFLinkerOptions & getOptions() const
Returns linking options.
Definition:DWARFLinkerGlobalData.h:98
llvm::dwarf_linker::parallel::OrderedChildrenIndexAssigner
This class helps to assign indexes for DIE children.
Definition:SyntheticTypeNameBuilder.h:132
llvm::dwarf_linker::parallel::OutputSections::GlobalData
LinkingGlobalData & GlobalData
Definition:OutputSections.h:451
llvm::dwarf_linker::parallel::OutputSections::Format
dwarf::FormParams Format
Format for sections.
Definition:OutputSections.h:454
llvm::dwarf_linker::parallel::OutputSections::getFormParams
const dwarf::FormParams & getFormParams() const
Return size of address.
Definition:OutputSections.h:448
llvm::dwarf_linker::parallel::OutputSections::eraseSections
void eraseSections()
Erases data of all sections.
Definition:OutputSections.h:384
llvm::dwarf_linker::parallel::OutputSections::tryGetSectionDescriptor
std::optional< const SectionDescriptor * > tryGetSectionDescriptor(DebugSectionKind SectionKind) const
Returns descriptor for the specified section of SectionKind.
Definition:OutputSections.h:349
llvm::dwarf_linker::parallel::OutputSections::setOutputFormat
void setOutputFormat(dwarf::FormParams Format, llvm::endianness Endianness)
Sets output format for all keeping sections.
Definition:OutputSections.h:308
llvm::dwarf_linker::parallel::OutputSections::getVersion
uint16_t getVersion() const
Return DWARF version.
Definition:OutputSections.h:428
llvm::dwarf_linker::parallel::OutputSections::getDebugInfoHeaderSize
uint16_t getDebugInfoHeaderSize() const
Return size of header of debug_info table.
Definition:OutputSections.h:431
llvm::dwarf_linker::parallel::OutputSections::getEndianness
llvm::endianness getEndianness() const
Endiannes for the sections.
Definition:OutputSections.h:425
llvm::dwarf_linker::parallel::OutputSections::getOrCreateSectionDescriptor
SectionDescriptor & getOrCreateSectionDescriptor(DebugSectionKind SectionKind)
Returns descriptor for the specified section of SectionKind.
Definition:OutputSections.h:373
llvm::dwarf_linker::parallel::OutputSections::getSectionDescriptor
const SectionDescriptor & getSectionDescriptor(DebugSectionKind SectionKind) const
Returns descriptor for the specified section of SectionKind.
Definition:OutputSections.h:317
llvm::dwarf_linker::parallel::SyntheticTypeNameBuilder
The helper class to build type name based on DIE properties.
Definition:SyntheticTypeNameBuilder.h:46
llvm::dwarf_linker::parallel::SyntheticTypeNameBuilder::assignName
Error assignName(UnitEntryPairTy InputUnitEntryPair, std::optional< std::pair< size_t, size_t > > ChildIndex)
Create synthetic name for the specified DIE InputUnitEntryPair and assign created name to the DIE typ...
Definition:SyntheticTypeNameBuilder.cpp:19
llvm::dwarf_linker::parallel::TypeEntryBody
Keeps cloned data for the type DIE.
Definition:TypePool.h:30
llvm::dwarf_linker::parallel::TypeEntryBody::ParentIsDeclaration
std::atomic< bool > ParentIsDeclaration
Definition:TypePool.h:65
llvm::dwarf_linker::parallel::TypeEntryBody::DeclarationDie
std::atomic< DIE * > DeclarationDie
Definition:TypePool.h:62
llvm::dwarf_linker::parallel::TypeEntryBody::Die
std::atomic< DIE * > Die
TypeEntryBody keeps partially cloned DIEs corresponding to this type.
Definition:TypePool.h:59
llvm::dwarf_linker::parallel::TypePool
TypePool keeps type descriptors which contain partially cloned DIE correspinding to each type.
Definition:TypePool.h:111
llvm::dwarf_linker::parallel::TypePool::getThreadLocalAllocator
BumpPtrAllocator & getThreadLocalAllocator()
Return thread local allocator used by pool.
Definition:TypePool.h:161
llvm::dwarf_linker::parallel::TypePool::getOrCreateTypeEntryBody
TypeEntryBody * getOrCreateTypeEntryBody(TypeEntry *Entry, TypeEntry *ParentEntry)
Create or return existing type entry body for the specified Entry.
Definition:TypePool.h:131
llvm::dwarf_linker::parallel::TypePool::getRoot
TypeEntry * getRoot() const
Return root for all type entries.
Definition:TypePool.h:158
llvm::dwarf_linker::parallel::TypeUnit
Type Unit is used to represent an artificial compilation unit which keeps all type information.
Definition:DWARFLinkerTypeUnit.h:24
llvm::dwarf_linker::parallel::TypeUnit::getTypePool
TypePool & getTypePool()
Returns global type pool.
Definition:DWARFLinkerTypeUnit.h:37
llvm::function_ref< CompileUnit *(uint64_t Offset)>
llvm::raw_ostream::tell
uint64_t tell() const
tell - Return the current offset with the file.
Definition:raw_ostream.h:147
uint16_t
uint32_t
uint64_t
uint8_t
unsigned
llvm::dwarf_linker::parallel::CompileUnit::rememberDieOutOffset
void rememberDieOutOffset(uint32_t Idx, uint64_t Offset)
Idx index of the DIE.
Definition:DWARFLinkerCompileUnit.h:345
llvm::dwarf_linker::parallel::CompileUnit::getDieTypeEntry
TypeEntry * getDieTypeEntry(uint32_t Idx)
Idx index of the DIE.
Definition:DWARFLinkerCompileUnit.h:322
llvm::dwarf_linker::parallel::CompileUnit::getDIEInfo
DIEInfo & getDIEInfo(unsigned Idx)
Idx index of the DIE.
Definition:DWARFLinkerCompileUnit.h:283
llvm::dwarf_linker::parallel::CompileUnit::getDieOutOffset
uint64_t getDieOutOffset(uint32_t Idx)
Idx index of the DIE.
Definition:DWARFLinkerCompileUnit.h:315
llvm::dwarf_linker::parallel::CompileUnit::getSiblingEntry
const DWARFDebugInfoEntry * getSiblingEntry(const DWARFDebugInfoEntry *Die) const
Definition:DWARFLinkerCompileUnit.h:465
llvm::dwarf_linker::parallel::CompileUnit::getFirstChildEntry
const DWARFDebugInfoEntry * getFirstChildEntry(const DWARFDebugInfoEntry *Die) const
Definition:DWARFLinkerCompileUnit.h:459
llvm::dwarf_linker::parallel::CompileUnit::getDIEIndexForOffset
std::optional< uint32_t > getDIEIndexForOffset(uint64_t Offset)
Definition:DWARFLinkerCompileUnit.h:526
llvm::dwarf_linker::parallel::CompileUnit::getDIE
DWARFDie getDIE(const DWARFDebugInfoEntry *Die)
Definition:DWARFLinkerCompileUnit.h:490
llvm::dwarf_linker::parallel::CompileUnit::getDebugInfoEntry
const DWARFDebugInfoEntry * getDebugInfoEntry(unsigned Index) const
Definition:DWARFLinkerCompileUnit.h:480
llvm::dwarf_linker::parallel::CompileUnit::getOrigUnit
DWARFUnit & getOrigUnit() const
Returns paired compile unit from input DWARF.
Definition:DWARFLinkerCompileUnit.h:453
llvm::dwarf_linker::parallel::CompileUnit::getUnitDIE
DWARFDie getUnitDIE(bool ExtractUnitDIEOnly=true)
Definition:DWARFLinkerCompileUnit.h:485
llvm::dwarf_linker::parallel::CompileUnit::getDIEIndex
uint32_t getDIEIndex(const DWARFDebugInfoEntry *Die) const
Definition:DWARFLinkerCompileUnit.h:495
llvm::dwarf_linker::parallel::CompileUnit::find
std::optional< DWARFFormValue > find(uint32_t DieIdx, ArrayRef< dwarf::Attribute > Attrs) const
Definition:DWARFLinkerCompileUnit.h:505
llvm::dwarf_linker::parallel::DwarfUnit::emitDebugInfo
Error emitDebugInfo(const Triple &TargetTriple)
Emit .debug_info section for unit DIEs.
Definition:DWARFLinkerUnit.cpp:90
llvm::dwarf_linker::parallel::DwarfUnit::emitDebugStringOffsetSection
Error emitDebugStringOffsetSection()
Emit the .debug_str_offsets section for current unit.
Definition:DWARFLinkerUnit.cpp:128
llvm::dwarf_linker::parallel::DwarfUnit::emitPubAccelerators
void emitPubAccelerators()
Emit .debug_pubnames and .debug_pubtypes for Unit.
Definition:DWARFLinkerUnit.cpp:200
llvm::dwarf_linker::parallel::CompileUnit::warn
void warn(const Twine &Warning, const DWARFDie *DIE=nullptr)
Definition:DWARFLinkerCompileUnit.h:536
llvm::dwarf_linker::parallel::DwarfUnit::emitAbbreviations
Error emitAbbreviations()
Definition:DWARFLinkerUnit.cpp:41
llvm::dwarf_linker::parallel::DwarfUnit::emitDebugLine
Error emitDebugLine(const Triple &TargetTriple, const DWARFDebugLine::LineTable &OutLineTable)
Emit .debug_line section.
Definition:DWARFLinkerUnit.cpp:121
llvm::dwarf_linker::parallel::DwarfUnit::AccelType::Name
@ Name
DWARFLinkerCompileUnit.h
CU
Definition:AArch64AsmBackend.cpp:549
llvm::BTF::HeaderSize
@ HeaderSize
Definition:BTF.h:61
llvm::COFF::Entry
@ Entry
Definition:COFF.h:844
llvm::dwarf_linker::parallel::isODRLanguage
bool isODRLanguage(uint16_t Language)
Definition:DWARFLinkerUnit.h:212
llvm::dwarf_linker::parallel::getODRAttributes
ArrayRef< dwarf::Attribute > getODRAttributes()
Definition:DWARFLinkerCompileUnit.cpp:1852
llvm::dwarf_linker::parallel::ResolveInterCUReferencesMode
ResolveInterCUReferencesMode
Definition:DWARFLinkerCompileUnit.h:44
llvm::dwarf_linker::parallel::Resolve
@ Resolve
Definition:DWARFLinkerCompileUnit.h:45
llvm::dwarf_linker::guessDeveloperDir
StringRef guessDeveloperDir(StringRef SysRoot)
Make a best effort to guess the Xcode.app/Contents/Developer path from an SDK path.
Definition:Utils.h:41
llvm::dwarf_linker::DebugSectionKind
DebugSectionKind
List of tracked debug tables.
Definition:DWARFLinkerBase.h:27
llvm::dwarf_linker::DebugSectionKind::DebugLocLists
@ DebugLocLists
llvm::dwarf_linker::DebugSectionKind::DebugMacinfo
@ DebugMacinfo
llvm::dwarf_linker::DebugSectionKind::DebugARanges
@ DebugARanges
llvm::dwarf_linker::DebugSectionKind::DebugRange
@ DebugRange
llvm::dwarf_linker::DebugSectionKind::DebugLine
@ DebugLine
llvm::dwarf_linker::DebugSectionKind::DebugRngLists
@ DebugRngLists
llvm::dwarf_linker::DebugSectionKind::DebugLoc
@ DebugLoc
llvm::dwarf_linker::DebugSectionKind::DebugMacro
@ DebugMacro
llvm::dwarf_linker::DebugSectionKind::DebugAddr
@ DebugAddr
llvm::dwarf_linker::DebugSectionKind::DebugInfo
@ DebugInfo
llvm::dwarf_linker::isInToolchainDir
bool isInToolchainDir(StringRef Path)
Make a best effort to determine whether Path is inside a toolchain.
Definition:Utils.h:77
llvm::dwarf_linker::isPathAbsoluteOnWindowsOrPosix
bool isPathAbsoluteOnWindowsOrPosix(const Twine &Path)
Definition:Utils.h:98
llvm::dwarf::toAddress
std::optional< uint64_t > toAddress(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an address.
Definition:DWARFFormValue.h:369
llvm::dwarf::DW_MACRO_lo_user
@ DW_MACRO_lo_user
Definition:Dwarf.h:807
llvm::dwarf::DW_MACRO_hi_user
@ DW_MACRO_hi_user
Definition:Dwarf.h:808
llvm::dwarf::Attribute
Attribute
Attributes.
Definition:Dwarf.h:123
llvm::dwarf::toString
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
Definition:DWARFFormValue.h:177
llvm::dwarf::DW_MACINFO_vendor_ext
@ DW_MACINFO_vendor_ext
Definition:Dwarf.h:800
llvm::dwarf::toSectionOffset
std::optional< uint64_t > toSectionOffset(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an section offset.
Definition:DWARFFormValue.h:399
llvm::dwarf::toStringRef
StringRef toStringRef(const std::optional< DWARFFormValue > &V, StringRef Default={})
Take an optional DWARFFormValue and try to extract a string value from it.
Definition:DWARFFormValue.h:193
llvm::dwarf::Tag
Tag
Definition:Dwarf.h:103
llvm::dwarf::toUnsigned
std::optional< uint64_t > toUnsigned(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an unsigned constant.
Definition:DWARFFormValue.h:226
llvm::dwarf::DW_ARANGES_VERSION
@ DW_ARANGES_VERSION
Section version number for .debug_aranges.
Definition:Dwarf.h:64
llvm::pdb::PDB_ColorItem::Padding
@ Padding
llvm::sys::fs::real_path
std::error_code real_path(const Twine &path, SmallVectorImpl< char > &output, bool expand_tilde=false)
Collapse all .
llvm::sys::path::parent_path
StringRef parent_path(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get parent path.
Definition:Path.cpp:467
llvm::sys::path::Style::native
@ native
llvm::sys::path::is_relative
bool is_relative(const Twine &path, Style style=Style::native)
Is path relative?
Definition:Path.cpp:699
llvm::sys::path::filename
StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get filename.
Definition:Path.cpp:577
llvm::sys::path::append
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition:Path.cpp:456
llvm::sys::swapByteOrder
void swapByteOrder(T &Value)
Definition:SwapByteOrder.h:61
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition:AddressRanges.h:18
llvm::Offset
@ Offset
Definition:DWP.cpp:480
llvm::partition_point
auto partition_point(R &&Range, Predicate P)
Binary search for the first iterator in a range where a predicate is false.
Definition:STLExtras.h:2050
llvm::append_range
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition:STLExtras.h:2115
llvm::formatv
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
Definition:FormatVariadic.h:252
llvm::AccelTableKind::Dwarf
@ Dwarf
DWARF v5 .debug_names.
llvm::offsetToAlignment
uint64_t offsetToAlignment(uint64_t Value, Align Alignment)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
Definition:Alignment.h:197
llvm::errs
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Definition:raw_ostream.cpp:907
llvm::DINameKind::ShortName
@ ShortName
llvm::ReplacementType::Format
@ Format
llvm::is_contained
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition:STLExtras.h:1903
llvm::BasicBlockSection::List
@ List
llvm::encodeULEB128
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
Definition:LEB128.h:80
llvm::isCompileUnit
bool isCompileUnit(const std::unique_ptr< DWARFUnit > &U)
Definition:DWARFUnit.h:595
llvm::endianness
endianness
Definition:bit.h:70
llvm::endianness::native
@ native
llvm::Data
@ Data
Definition:SIMachineScheduler.h:55
llvm::Align
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition:Alignment.h:39
llvm::DWARFDebugLine::FileNameEntry
Definition:DWARFDebugLine.h:30
llvm::DWARFDebugLine::LineTable
Definition:DWARFDebugLine.h:229
llvm::DWARFDebugLine::LineTable::Rows
RowVector Rows
Definition:DWARFDebugLine.h:295
llvm::DWARFDebugLine::LineTable::hasFileAtIndex
bool hasFileAtIndex(uint64_t FileIndex) const
Definition:DWARFDebugLine.h:249
llvm::DWARFDebugLine::LineTable::getFileNameByIndex
bool getFileNameByIndex(uint64_t FileIndex, StringRef CompDir, DILineInfoSpecifier::FileLineInfoKind Kind, std::string &Result) const
Extracts filename by its index in filename table in prologue.
Definition:DWARFDebugLine.h:262
llvm::DWARFDebugLine::LineTable::Sequences
SequenceVector Sequences
Definition:DWARFDebugLine.h:296
llvm::DWARFDebugLine::LineTable::Prologue
struct Prologue Prologue
Definition:DWARFDebugLine.h:294
llvm::DWARFDebugLine::Prologue::FormParams
dwarf::FormParams FormParams
Version, address size (starting in v5), and DWARF32/64 format; these parameters affect interpretation...
Definition:DWARFDebugLine.h:68
llvm::DWARFDebugLine::Row
Standard .debug_line state machine structure.
Definition:DWARFDebugLine.h:132
llvm::DWARFExpression::Operation::Description
Description of the encoding of one expression Op.
Definition:DWARFExpression.h:66
llvm::DWARFExpression::Operation::Description::Op
SmallVector< Encoding > Op
Encoding for Op operands.
Definition:DWARFExpression.h:68
llvm::DWARFLocationExpression
Represents a single DWARF expression, whose value is location-dependent.
Definition:DWARFLocationExpression.h:21
llvm::dwarf::FormParams
A helper struct providing information about the byte size of DW_FORM values that vary in size dependi...
Definition:Dwarf.h:1084
llvm::dwarf::FormParams::Format
DwarfFormat Format
Definition:Dwarf.h:1087
llvm::dwarf::FormParams::getDwarfOffsetByteSize
uint8_t getDwarfOffsetByteSize() const
The size of a reference is determined by the DWARF 32/64-bit format.
Definition:Dwarf.h:1102
llvm::dwarf::FormParams::AddrSize
uint8_t AddrSize
Definition:Dwarf.h:1086
llvm::dwarf::FormParams::Version
uint16_t Version
Definition:Dwarf.h:1085
llvm::dwarf_linker::parallel::CompileUnit::DIEInfo
Information gathered about source DIEs.
Definition:DWARFLinkerCompileUnit.h:169
llvm::dwarf_linker::parallel::CompileUnit::DIEInfo::dump
LLVM_DUMP_METHOD void dump()
Definition:DWARFLinkerCompileUnit.cpp:22
llvm::dwarf_linker::parallel::CompileUnit::DIEInfo::needToPlaceInTypeTable
bool needToPlaceInTypeTable() const
Definition:DWARFLinkerCompileUnit.h:264
llvm::dwarf_linker::parallel::CompileUnit::DIEInfo::getPlacement
DieOutputPlacement getPlacement() const
Definition:DWARFLinkerCompileUnit.h:181
llvm::dwarf_linker::parallel::DWARFLinkerOptions::ParseableSwiftInterfaces
DWARFLinkerBase::SwiftInterfacesMapTy * ParseableSwiftInterfaces
A list of all .swiftinterface files referenced by the debug info, mapping Module name to path on disk...
Definition:DWARFLinkerGlobalData.h:74
llvm::dwarf_linker::parallel::DWARFLinkerOptions::AccelTables
SmallVector< DWARFLinkerBase::AccelTableKind, 1 > AccelTables
The accelerator table kinds.
Definition:DWARFLinkerGlobalData.h:58
llvm::dwarf_linker::parallel::DWARFLinkerOptions::NoODR
bool NoODR
Do not unique types according to ODR.
Definition:DWARFLinkerGlobalData.h:42
llvm::dwarf_linker::parallel::DWARFLinkerOptions::UpdateIndexTablesOnly
bool UpdateIndexTablesOnly
Update index tables.
Definition:DWARFLinkerGlobalData.h:45
llvm::dwarf_linker::parallel::DebugDieRefPatch
This structure is used to update reference to the DIE.
Definition:OutputSections.h:79
llvm::dwarf_linker::parallel::DebugDieRefPatch::RefDieIdxOrClonedOffset
uint64_t RefDieIdxOrClonedOffset
Definition:OutputSections.h:84
llvm::dwarf_linker::parallel::DebugDieRefPatch::RefCU
PointerIntPair< CompileUnit *, 1 > RefCU
Definition:OutputSections.h:83
llvm::dwarf_linker::parallel::DebugLocPatch
This structure is used to update location list offset into .debug_loc/.debug_loclists.
Definition:OutputSections.h:64
llvm::dwarf_linker::parallel::DebugLocPatch::AddrAdjustmentValue
int64_t AddrAdjustmentValue
Definition:OutputSections.h:65
llvm::dwarf_linker::parallel::DebugOffsetPatch
Definition:OutputSections.h:70
llvm::dwarf_linker::parallel::DebugRangePatch
This structure is used to update range list offset into .debug_ranges/.debug_rnglists.
Definition:OutputSections.h:57
llvm::dwarf_linker::parallel::DebugRangePatch::IsCompileUnitRanges
bool IsCompileUnitRanges
Indicates patch which points to immediate compile unit's attribute.
Definition:OutputSections.h:59
llvm::dwarf_linker::parallel::DebugULEB128DieRefPatch
This structure is used to update reference to the DIE of ULEB128 form.
Definition:OutputSections.h:88
llvm::dwarf_linker::parallel::DebugULEB128DieRefPatch::RefDieIdxOrClonedOffset
uint64_t RefDieIdxOrClonedOffset
Definition:OutputSections.h:93
llvm::dwarf_linker::parallel::DebugULEB128DieRefPatch::RefCU
PointerIntPair< CompileUnit *, 1 > RefCU
Definition:OutputSections.h:92
llvm::dwarf_linker::parallel::SectionDescriptorBase::getFormParams
dwarf::FormParams getFormParams() const
Returns FormParams used by section.
Definition:DWARFLinker.h:107
llvm::dwarf_linker::parallel::SectionDescriptor
This structure is used to keep data of the concrete section.
Definition:OutputSections.h:152
llvm::dwarf_linker::parallel::SectionDescriptor::OS
raw_svector_ostream OS
Stream which stores data to the Contents.
Definition:OutputSections.h:185
llvm::dwarf_linker::parallel::SectionDescriptor::emitUnitLength
void emitUnitLength(uint64_t Length)
Emit unit length into the current section contents.
Definition:OutputSections.h:230
llvm::dwarf_linker::parallel::SectionDescriptor::emitOffset
void emitOffset(uint64_t Val)
Emit specified offset value into the current section contents.
Definition:OutputSections.h:243
llvm::dwarf_linker::parallel::SectionDescriptor::emitString
void emitString(dwarf::Form StringForm, const char *StringVal)
Definition:OutputSections.cpp:116
llvm::dwarf_linker::parallel::SectionDescriptor::emitIntVal
void emitIntVal(uint64_t Val, unsigned Size)
Emit specified integer value into the current section contents.
Definition:OutputSections.cpp:140
llvm::dwarf_linker::parallel::SectionDescriptor::apply
void apply(uint64_t PatchOffset, dwarf::Form AttrForm, uint64_t Val)
Write specified Value of AttrForm to the PatchOffset.
Definition:OutputSections.cpp:171
llvm::dwarf_linker::parallel::SectionDescriptor::getIntVal
uint64_t getIntVal(uint64_t PatchOffset, unsigned Size)
Returns integer value of Size located by specified PatchOffset.
Definition:OutputSections.cpp:226
llvm::dwarf_linker::parallel::SectionPatch::PatchOffset
uint64_t PatchOffset
Definition:OutputSections.h:42
llvm::dwarf_linker::parallel::UnitEntryPairTy
This is a helper structure which keeps a debug info entry with it's containing compilation unit.
Definition:DWARFLinkerCompileUnit.h:32
llvm::dwarf_linker::parallel::UnitEntryPairTy::CU
CompileUnit * CU
Definition:DWARFLinkerCompileUnit.h:37
llvm::dwarf_linker::parallel::UnitEntryPairTy::getParent
std::optional< UnitEntryPairTy > getParent()
Definition:DWARFLinkerCompileUnit.cpp:1792
llvm::dwarf_linker::parallel::UnitEntryPairTy::getNamespaceOrigin
UnitEntryPairTy getNamespaceOrigin()
Definition:DWARFLinkerCompileUnit.cpp:1775
llvm::dwarf_linker::parallel::UnitEntryPairTy::DieEntry
const DWARFDebugInfoEntry * DieEntry
Definition:DWARFLinkerCompileUnit.h:38
llvm::object::SectionedAddress
Definition:ObjectFile.h:145
llvm::object::SectionedAddress::Address
uint64_t Address
Definition:ObjectFile.h:148

Generated on Fri Jul 18 2025 11:18:01 for LLVM by doxygen 1.9.6
[8]ページ先頭

©2009-2025 Movatter.jp