LLVM 23.0.0git
DWARFLinkerImpl.h
Go to the documentation of this file.
1//===- DWARFLinkerImpl.h ----------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_LIB_DWARFLINKER_PARALLEL_DWARFLINKERIMPL_H
10#define LLVM_LIB_DWARFLINKER_PARALLEL_DWARFLINKERIMPL_H
11
12#include "DWARFEmitterImpl.h"
14#include "DWARFLinkerTypeUnit.h"
21
22namespace llvm {
23namespace dwarf_linker {
24namespace parallel {
25
26/// This class links debug info.
28public:
30 MessageHandlerTy WarningHandler);
31
32 /// Add object file to be linked. Pre-load compile unit die. Call
33 /// \p OnCUDieLoaded for each compile unit die. If specified \p File
34 /// has reference to the Clang module then such module would be
35 /// pre-loaded by \p Loader for !Update case.
36 ///
37 /// \pre NoODR, Update options should be set before call to addObjectFile.
38 void addObjectFile(
39 DWARFFile &File, ObjFileLoaderTy Loader = nullptr,
40
41 CompileUnitHandlerTy OnCUDieLoaded = [](const DWARFUnit &) {}) override;
42
43 /// Link debug info for added files.
44 Error link() override;
45
46 /// Set output DWARF handler. May be not set if output generation is not
47 /// necessary.
48 void setOutputDWARFHandler(const Triple &TargetTriple,
50 GlobalData.setTargetTriple(TargetTriple);
51 this->SectionHandler = SectionHandler;
52 }
53
54 /// \defgroup Methods setting various linking options:
55 ///
56 /// @{
57 ///
58
59 /// Allows to generate log of linking process to the standard output.
60 void setVerbosity(bool Verbose) override {
61 GlobalData.Options.Verbose = Verbose;
62 }
63
64 /// Print statistics to standard output.
65 void setStatistics(bool Statistics) override {
66 GlobalData.Options.Statistics = Statistics;
67 }
68
69 /// Verify the input DWARF.
70 void setVerifyInputDWARF(bool Verify) override {
71 GlobalData.Options.VerifyInputDWARF = Verify;
72 }
73
74 /// Do not unique types according to ODR.
75 void setNoODR(bool NoODR) override { GlobalData.Options.NoODR = NoODR; }
76
77 /// Update index tables only(do not modify rest of DWARF).
78 void setUpdateIndexTablesOnly(bool UpdateIndexTablesOnly) override {
79 GlobalData.Options.UpdateIndexTablesOnly = UpdateIndexTablesOnly;
80 }
81
82 /// Set to keep the enclosing function for a static variable.
83 void setKeepFunctionForStatic(bool KeepFunctionForStatic) override {
84 GlobalData.Options.KeepFunctionForStatic = KeepFunctionForStatic;
85 }
86
87 /// Use specified number of threads for parallel files linking.
88 void setNumThreads(unsigned NumThreads) override {
89 GlobalData.Options.Threads = NumThreads;
90 }
91
92 /// Add kind of accelerator tables to be generated.
93 void addAccelTableKind(AccelTableKind Kind) override {
94 assert(!llvm::is_contained(GlobalData.getOptions().AccelTables, Kind));
95 GlobalData.Options.AccelTables.emplace_back(Kind);
96 }
97
98 /// Set prepend path for clang modules.
99 void setPrependPath(StringRef Ppath) override {
100 GlobalData.Options.PrependPath = Ppath;
101 }
102
103 /// Set estimated objects files amount, for preliminary data allocation.
104 void setEstimatedObjfilesAmount(unsigned ObjFilesNum) override;
105
106 /// Set verification handler which would be used to report verification
107 /// errors.
108 void
110 GlobalData.Options.InputVerificationHandler = Handler;
111 }
112
113 /// Set map for Swift interfaces.
115 GlobalData.Options.ParseableSwiftInterfaces = Map;
116 }
117
118 /// Set prefix map for objects.
120 GlobalData.Options.ObjectPrefixMap = Map;
121 }
122
123 /// Set target DWARF version.
124 Error setTargetDWARFVersion(uint16_t TargetDWARFVersion) override {
125 if ((TargetDWARFVersion < 1) || (TargetDWARFVersion > 5))
126 return createStringError(std::errc::invalid_argument,
127 "unsupported DWARF version: %d",
128 TargetDWARFVersion);
129
130 GlobalData.Options.TargetDWARFVersion = TargetDWARFVersion;
131 return Error::success();
132 }
133 /// @}
134
135protected:
136 /// Verify input DWARF file.
137 void verifyInput(const DWARFFile &File);
138
139 /// Validate specified options.
141
142 /// Take already linked compile units and glue them into single file.
144
145 /// Hold the input and output of the debug info size in bytes.
150
151 friend class DependencyTracker;
152 /// Keeps track of data associated with one object during linking.
153 /// i.e. source file descriptor, compilation units, output data
154 /// for compilation units common tables.
155 struct LinkContext : public OutputSections {
157
158 /// Keep information for referenced clang module: already loaded DWARF info
159 /// of the clang module and a CompileUnit of the module.
161 RefModuleUnit(DWARFFile &File, std::unique_ptr<CompileUnit> Unit);
163 RefModuleUnit(const RefModuleUnit &) = delete;
164
166 std::unique_ptr<CompileUnit> Unit;
167 };
169
170 /// Object file descriptor.
172
173 /// Set of Compilation Units(may be accessed asynchroniously for reading).
175
176 /// Set of Compile Units for modules.
178
179 /// Index of this object file in the link order (used for deterministic
180 /// type DIE allocation).
182
183 /// Size of Debug info before optimizing.
185
186 /// Flag indicating that all inter-connected units are loaded
187 /// and the dwarf linking process for these units is started.
189
191
192 /// Flag indicating that new inter-connected compilation units were
193 /// discovered. It is used for restarting units processing
194 /// if new inter-connected units were found.
195 std::atomic<bool> HasNewInterconnectedCUs = {false};
196
197 std::atomic<bool> HasNewGlobalDependency = {false};
198
199 /// Counter for compile units ID.
200 std::atomic<size_t> &UniqueUnitID;
201
204 std::atomic<size_t> &UniqueUnitID);
205
206 /// Check whether specified \p CUDie is a Clang module reference.
207 /// if \p Quiet is false then display error messages.
208 /// \return first == true if CUDie is a Clang module reference.
209 /// second == true if module is already loaded.
210 std::pair<bool, bool> isClangModuleRef(const DWARFDie &CUDie,
211 std::string &PCMFile,
212 unsigned Indent, bool Quiet);
213
214 /// If this compile unit is really a skeleton CU that points to a
215 /// clang module, register it in ClangModules and return true.
216 ///
217 /// A skeleton CU is a CU without children, a DW_AT_gnu_dwo_name
218 /// pointing to the module, and a DW_AT_gnu_dwo_id with the module
219 /// hash.
220 bool registerModuleReference(const DWARFDie &CUDie, ObjFileLoaderTy Loader,
221 CompileUnitHandlerTy OnCUDieLoaded,
222 unsigned Indent = 0);
223
224 /// Recursively add the debug info in this clang module .pcm
225 /// file (and all the modules imported by it in a bottom-up fashion)
226 /// to ModuleUnits.
227 Error loadClangModule(ObjFileLoaderTy Loader, const DWARFDie &CUDie,
228 const std::string &PCMFile,
229 CompileUnitHandlerTy OnCUDieLoaded,
230 unsigned Indent = 0);
231
232 /// Add Compile Unit corresponding to the module.
234
235 /// Computes the total size of the debug info.
237 uint64_t Size = 0;
238
239 if (InputDWARFFile.Dwarf == nullptr)
240 return Size;
241
242 for (auto &Unit : InputDWARFFile.Dwarf->compile_units())
243 Size += Unit->getLength();
244
245 return Size;
246 }
247
248 /// Section + local offset of a .debug_frame CIE that has been (or will
249 /// be) emitted by some LinkContext. Stored in CIERegistry so that any
250 /// FDE referencing the same CIE bytes can resolve its CIE_pointer to
251 /// OwnerSection->StartOffset + LocalOffset at output time, even when
252 /// the FDE lives in a different LinkContext's section.
257
258 /// Linker-wide registry for .debug_frame CIEs. The key is the raw CIE
259 /// bytes. Populated by a serial pass over ObjectContexts (so ownership
260 /// is deterministic — first LinkContext wins) and then consumed
261 /// read-only by a parallel emission pass that writes each context's
262 /// .debug_frame section. SectionDescriptor pointers remain valid until
263 /// linking completes because they live in std::map-held shared_ptrs.
265
266 /// Result of scanning one LinkContext's input .debug_frame. Produced
267 /// by scanFrameData() during the parallel link phase and consumed by
268 /// the serial CIE-registry merge and parallel emission passes. Owns a
269 /// copy of the raw frame bytes so the StringRef views below remain
270 /// valid after the input DWARFContext is unloaded.
272 /// Owning copy of the input .debug_frame bytes.
274
275 /// Address size of the input object, used by emitFDE to size the
276 /// FDE's initial_location field.
277 unsigned AddressSize = 0;
278
279 /// Unique CIEs referenced by at least one retained FDE in this
280 /// context, in first-reference order. Each element is a view into
281 /// FrameData and is a key into the linker-wide CIERegistry.
283
284 /// FDEs retained for emission. CIEBytes is the registry key;
285 /// Instructions is the FDE body after the initial_length /
286 /// CIE_pointer / initial_location fields.
293
294 /// CIEs this context owns, set during the serial CIE-registry
295 /// merge. Emission writes these at local offsets 0,
296 /// OwnedCIEs[0].size(), ... in order.
298 };
299 std::unique_ptr<FrameScanResult> FrameScan;
300
301 /// Link compile units for this context.
303
304 /// Link specified compile unit until specified stage.
308
309 /// Emit invariant sections.
311
312 /// Unload the input DWARFContext after scanning the input .debug_frame into
313 /// FrameScan.
315
316 /// Parse this context's input .debug_frame into FrameScan. Deferred
317 /// CIE/FDE emission happens later against the scan result alone.
319
320 /// Register this context's CIEs with the linker-wide registry.
321 void registerCIEs(CIERegistry &CIEs);
322
323 /// Emit this context's .debug_frame section. Safe to call in parallel
324 /// across contexts because each call writes only to its own
325 /// SectionDescriptor.
326 Error emitDebugFrame(const CIERegistry &CIEs);
327
328 /// Emit FDE record.
329 void emitFDE(uint32_t CIEOffset, uint32_t AddrSize, uint64_t Address,
330 StringRef FDEBytes, SectionDescriptor &Section);
331
333 [&](uint64_t Offset) -> CompileUnit * {
334 auto CU = llvm::upper_bound(
336 [](uint64_t LHS, const std::unique_ptr<CompileUnit> &RHS) {
337 return LHS < RHS->getOrigUnit().getNextUnitOffset();
338 });
339
340 return CU != CompileUnits.end() ? CU->get() : nullptr;
341 };
342 };
343
344 /// Enumerate all compile units and assign offsets to their sections and
345 /// strings.
346 void assignOffsets();
347
348 /// Enumerate all compile units and assign offsets to their sections.
350
351 /// Enumerate all compile units and assign offsets to their strings.
353
354 /// Print statistic for processed Debug Info.
355 void printStatistic();
356
358
359 /// Enumerates all strings.
362 StringHandler);
363
364 /// Enumerates sections for modules, invariant for object files, compile
365 /// units.
367 function_ref<void(OutputSections &SectionsSet)> SectionsSetHandler);
368
369 /// Enumerates all compile and type units.
370 void forEachCompileAndTypeUnit(function_ref<void(DwarfUnit *CU)> UnitHandler);
371
372 /// Enumerates all comple units.
373 void forEachCompileUnit(function_ref<void(CompileUnit *CU)> UnitHandler);
374
375 /// Enumerates all patches and update them with the correct values.
377
378 /// Emit debug sections common for all input files.
380
381 /// Emit apple accelerator sections.
382 void emitAppleAcceleratorSections(const Triple &TargetTriple);
383
384 /// Emit .debug_names section.
385 void emitDWARFv5DebugNamesSection(const Triple &TargetTriple);
386
387 /// Emit string sections.
388 void emitStringSections();
389
390 /// Cleanup data(string pools) after output sections are generated.
392
393 /// Enumerate all compile units and put their data into the output stream.
395
396 /// Enumerate common sections and put their data into the output stream.
398
399 /// \defgroup Data members accessed asinchroniously.
400 ///
401 /// @{
402
403 /// Unique ID for compile unit.
404 std::atomic<size_t> UniqueUnitID;
405
406 /// Mapping the PCM filename to the DwoId.
409
410 /// Type unit.
411 std::unique_ptr<TypeUnit> ArtificialTypeUnit;
412 /// @}
413
414 /// \defgroup Data members accessed sequentially.
415 ///
416 /// @{
417 /// Data global for the whole linking process.
419
420 /// DwarfStringPoolEntries for .debug_str section.
422
423 /// DwarfStringPoolEntries for .debug_line_str section.
425
426 /// Keeps all linking contexts.
428
429 /// Common sections.
431
432 /// Hanler for output sections.
434
435 /// Overall compile units number.
437 /// @}
438};
439
440} // end of namespace parallel
441} // end of namespace dwarf_linker
442} // end of namespace llvm
443
444#endif // LLVM_LIB_DWARFLINKER_PARALLEL_DWARFLINKERIMPL_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file contains support for writing accelerator tables.
static fatal_error_handler_t ErrorHandler
ppc ctr loops PowerPC CTR Loops Verify
This file defines the SmallString class.
Value * RHS
Value * LHS
Utility class that carries the DWARF compile/type unit and the debug info entry in an object.
Definition DWARFDie.h:43
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition StringMap.h:133
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:47
This class represents DWARF information for source file and it's address map.
Definition DWARFFile.h:25
std::map< std::string, std::string > ObjectPrefixMapTy
function_ref< void(const DWARFUnit &Unit)> CompileUnitHandlerTy
std::function< void( const Twine &Warning, StringRef Context, const DWARFDie *DIE)> MessageHandlerTy
AccelTableKind
The kind of accelerator tables to be emitted.
std::map< std::string, std::string > SwiftInterfacesMapTy
std::function< ErrorOr< DWARFFile & >( StringRef ContainerName, StringRef Path)> ObjFileLoaderTy
std::function< void(const DWARFFile &File, llvm::StringRef Output)> InputVerificationHandlerTy
Stores all information related to a compile unit, be it in its original instance of the object file o...
Stage
The stages of new compile unit processing.
@ Cleaned
Resources(Input DWARF, Output DWARF tree) are released.
void forEachObjectSectionsSet(function_ref< void(OutputSections &SectionsSet)> SectionsSetHandler)
Enumerates sections for modules, invariant for object files, compile units.
void emitDWARFv5DebugNamesSection(const Triple &TargetTriple)
Emit .debug_names section.
void writeCompileUnitsToTheOutput()
Enumerate all compile units and put their data into the output stream.
void forEachCompileUnit(function_ref< void(CompileUnit *CU)> UnitHandler)
Enumerates all comple units.
void assignOffsetsToStrings()
Enumerate all compile units and assign offsets to their strings.
void assignOffsets()
Enumerate all compile units and assign offsets to their sections and strings.
Error link() override
Link debug info for added files.
Error validateAndUpdateOptions()
Validate specified options.
void writeCommonSectionsToTheOutput()
Enumerate common sections and put their data into the output stream.
void assignOffsetsToSections()
Enumerate all compile units and assign offsets to their sections.
void printStatistic()
Print statistic for processed Debug Info.
void glueCompileUnitsAndWriteToTheOutput()
Take already linked compile units and glue them into single file.
void emitAppleAcceleratorSections(const Triple &TargetTriple)
Emit apple accelerator sections.
void verifyInput(const DWARFFile &File)
Verify input DWARF file.
void forEachCompileAndTypeUnit(function_ref< void(DwarfUnit *CU)> UnitHandler)
Enumerates all compile and type units.
DWARFLinkerImpl(MessageHandlerTy ErrorHandler, MessageHandlerTy WarningHandler)
void addObjectFile(DWARFFile &File, ObjFileLoaderTy Loader=nullptr, CompileUnitHandlerTy OnCUDieLoaded=[](const DWARFUnit &) {}) override
Add object file to be linked.
void cleanupDataAfterDWARFOutputIsWritten()
Cleanup data(string pools) after output sections are generated.
void forEachOutputString(function_ref< void(StringDestinationKind, const StringEntry *)> StringHandler)
Enumerates all strings.
void setOutputDWARFHandler(const Triple &TargetTriple, SectionHandlerTy SectionHandler) override
Set output DWARF handler.
void emitCommonSectionsAndWriteCompileUnitsToTheOutput()
Emit debug sections common for all input files.
void patchOffsetsAndSizes()
Enumerates all patches and update them with the correct values.
Base class for all Dwarf units(Compile unit/Type table unit).
This class keeps data and services common for the whole linking process.
This class keeps contents and offsets to the debug sections.
OutputSections(LinkingGlobalData &GlobalData)
This class creates a DwarfStringPoolEntry for the corresponding StringEntry.
Type Unit is used to represent an artificial compilation unit which keeps all type information.
An efficient, type-erasing, non-owning reference to a callable.
std::atomic< size_t > UniqueUnitID
Unique ID for compile unit.
uint64_t OverallNumberOfCU
Overall compile units number.
SmallVector< std::unique_ptr< LinkContext > > ObjectContexts
Keeps all linking contexts.
StringEntryToDwarfStringPoolEntryMap DebugLineStrStrings
DwarfStringPoolEntries for .debug_line_str section.
SectionHandlerTy SectionHandler
Hanler for output sections.
std::unique_ptr< TypeUnit > ArtificialTypeUnit
Type unit.
StringEntryToDwarfStringPoolEntryMap DebugStrStrings
DwarfStringPoolEntries for .debug_str section.
OutputSections CommonSections
Common sections.
StringMap< uint64_t > ClangModules
Mapping the PCM filename to the DwoId.
void setNumThreads(unsigned NumThreads) override
Use specified number of threads for parallel files linking.
Error setTargetDWARFVersion(uint16_t TargetDWARFVersion) override
Set target DWARF version.
void setVerbosity(bool Verbose) override
Allows to generate log of linking process to the standard output.
void setInputVerificationHandler(InputVerificationHandlerTy Handler) override
Set verification handler which would be used to report verification errors.
void setObjectPrefixMap(ObjectPrefixMapTy *Map) override
Set prefix map for objects.
void addAccelTableKind(AccelTableKind Kind) override
Add kind of accelerator tables to be generated.
void setVerifyInputDWARF(bool Verify) override
Verify the input DWARF.
void setKeepFunctionForStatic(bool KeepFunctionForStatic) override
Set to keep the enclosing function for a static variable.
void setUpdateIndexTablesOnly(bool UpdateIndexTablesOnly) override
Update index tables only(do not modify rest of DWARF).
void setSwiftInterfacesMap(SwiftInterfacesMapTy *Map) override
Set map for Swift interfaces.
void setStatistics(bool Statistics) override
Print statistics to standard output.
void setNoODR(bool NoODR) override
Do not unique types according to ODR.
void setPrependPath(StringRef Ppath) override
Set prepend path for clang modules.
void setEstimatedObjfilesAmount(unsigned ObjFilesNum) override
Set estimated objects files amount, for preliminary data allocation.
std::function< void(std::shared_ptr< SectionDescriptorBase > Section)> SectionHandlerTy
StringMapEntry< EmptyStringSetTag > StringEntry
StringEntry keeps data of the string: the length, external offset and a string body which is placed r...
Definition StringPool.h:23
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:557
auto upper_bound(R &&Range, T &&Value)
Provide wrappers to std::upper_bound which take ranges instead of having to pass begin/end explicitly...
Definition STLExtras.h:2064
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition Error.h:1321
@ Other
Any other memory.
Definition ModRef.h:68
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1946
Hold the input and output of the debug info size in bytes.
Section + local offset of a .debug_frame CIE that has been (or will be) emitted by some LinkContext.
Result of scanning one LinkContext's input .debug_frame.
SmallString< 0 > FrameData
Owning copy of the input .debug_frame bytes.
SmallVector< StringRef > OwnedCIEs
CIEs this context owns, set during the serial CIE-registry merge.
SmallVector< StringRef > CIEs
Unique CIEs referenced by at least one retained FDE in this context, in first-reference order.
unsigned AddressSize
Address size of the input object, used by emitFDE to size the FDE's initial_location field.
Keep information for referenced clang module: already loaded DWARF info of the clang module and a Com...
RefModuleUnit(DWARFFile &File, std::unique_ptr< CompileUnit > Unit)
uint64_t getInputDebugInfoSize() const
Computes the total size of the debug info.
bool InterCUProcessingStarted
Flag indicating that all inter-connected units are loaded and the dwarf linking process for these uni...
bool registerModuleReference(const DWARFDie &CUDie, ObjFileLoaderTy Loader, CompileUnitHandlerTy OnCUDieLoaded, unsigned Indent=0)
If this compile unit is really a skeleton CU that points to a clang module, register it in ClangModul...
Error loadClangModule(ObjFileLoaderTy Loader, const DWARFDie &CUDie, const std::string &PCMFile, CompileUnitHandlerTy OnCUDieLoaded, unsigned Indent=0)
Recursively add the debug info in this clang module .pcm file (and all the modules imported by it in ...
Error scanFrameData()
Parse this context's input .debug_frame into FrameScan.
uint64_t OriginalDebugInfoSize
Size of Debug info before optimizing.
std::pair< bool, bool > isClangModuleRef(const DWARFDie &CUDie, std::string &PCMFile, unsigned Indent, bool Quiet)
Check whether specified CUDie is a Clang module reference.
void addModulesCompileUnit(RefModuleUnit &&Unit)
Add Compile Unit corresponding to the module.
void emitFDE(uint32_t CIEOffset, uint32_t AddrSize, uint64_t Address, StringRef FDEBytes, SectionDescriptor &Section)
Emit FDE record.
UnitListTy CompileUnits
Set of Compilation Units(may be accessed asynchroniously for reading).
SmallVector< std::unique_ptr< CompileUnit > > UnitListTy
void linkSingleCompileUnit(CompileUnit &CU, TypeUnit *ArtificialTypeUnit, enum CompileUnit::Stage DoUntilStage=CompileUnit::Stage::Cleaned)
Link specified compile unit until specified stage.
void registerCIEs(CIERegistry &CIEs)
Register this context's CIEs with the linker-wide registry.
LinkContext(LinkingGlobalData &GlobalData, DWARFFile &File, uint64_t ObjFileIdx, StringMap< uint64_t > &ClangModules, std::atomic< size_t > &UniqueUnitID)
std::atomic< bool > HasNewInterconnectedCUs
Flag indicating that new inter-connected compilation units were discovered.
Error emitDebugFrame(const CIERegistry &CIEs)
Emit this context's .debug_frame section.
std::atomic< size_t > & UniqueUnitID
Counter for compile units ID.
StringMap< CIELocation > CIERegistry
Linker-wide registry for .debug_frame CIEs.
Error unloadInput()
Unload the input DWARFContext after scanning the input .debug_frame into FrameScan.
uint64_t ObjectFileIdx
Index of this object file in the link order (used for deterministic type DIE allocation).
std::function< CompileUnit *(uint64_t)> getUnitForOffset
ModuleUnitListTy ModulesCompileUnits
Set of Compile Units for modules.
This structure is used to keep data of the concrete section.