LLVM 24.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 /// Use the specified thread pool to link the object files.
93 void setThreadPool(ThreadPoolInterface *Pool) override { ThreadPool = Pool; }
94
95 /// Add kind of accelerator tables to be generated.
96 void addAccelTableKind(AccelTableKind Kind) override {
97 assert(!llvm::is_contained(GlobalData.getOptions().AccelTables, Kind));
98 GlobalData.Options.AccelTables.emplace_back(Kind);
99 }
100
101 /// Set prepend path for clang modules.
102 void setPrependPath(StringRef Ppath) override {
103 GlobalData.Options.PrependPath = Ppath;
104 }
105
106 /// Set estimated objects files amount, for preliminary data allocation.
107 void setEstimatedObjfilesAmount(unsigned ObjFilesNum) override;
108
109 /// Set verification handler which would be used to report verification
110 /// errors.
111 void
113 GlobalData.Options.InputVerificationHandler = Handler;
114 }
115
116 /// Set map for Swift interfaces.
118 GlobalData.Options.ParseableSwiftInterfaces = Map;
119 }
120
121 /// Set prefix map for objects.
123 GlobalData.Options.ObjectPrefixMap = Map;
124 }
125
126 /// Set target DWARF version.
127 Error setTargetDWARFVersion(uint16_t TargetDWARFVersion) override {
128 if ((TargetDWARFVersion < 1) || (TargetDWARFVersion > 5))
129 return createStringError(std::errc::invalid_argument,
130 "unsupported DWARF version: %d",
131 TargetDWARFVersion);
132
133 GlobalData.Options.TargetDWARFVersion = TargetDWARFVersion;
134 return Error::success();
135 }
136 /// @}
137
138protected:
139 /// Verify input DWARF file.
140 void verifyInput(const DWARFFile &File);
141
142 /// Validate specified options.
144
145 /// Take already linked compile units and glue them into single file.
147
148 /// Hold the input and output of the debug info size in bytes.
153
154 friend class DependencyTracker;
155 /// Keeps track of data associated with one object during linking.
156 /// i.e. source file descriptor, compilation units, output data
157 /// for compilation units common tables.
158 struct LinkContext : public OutputSections {
160
161 /// Object file descriptor.
163
164 /// Set of Compilation Units(may be accessed asynchroniously for reading).
166
167 /// Set of Compile Units for modules.
169
170 /// Index of this object file in the link order (used for deterministic
171 /// type DIE allocation).
173
174 /// Size of Debug info before optimizing.
176
177 /// Flag indicating that all inter-connected units are loaded
178 /// and the dwarf linking process for these units is started.
180
182
183 /// Flag indicating that new inter-connected compilation units were
184 /// discovered. It is used for restarting units processing
185 /// if new inter-connected units were found.
186 std::atomic<bool> HasNewInterconnectedCUs = {false};
187
188 std::atomic<bool> HasNewGlobalDependency = {false};
189
190 /// Counter for compile units ID.
191 std::atomic<size_t> &UniqueUnitID;
192
195 std::atomic<size_t> &UniqueUnitID);
196
197 /// Check whether specified \p CUDie is a Clang module reference.
198 /// if \p Quiet is false then display error messages.
199 /// \return first == true if CUDie is a Clang module reference.
200 /// second == true if module is already loaded.
201 std::pair<bool, bool> isClangModuleRef(const DWARFDie &CUDie,
202 std::string &PCMFile,
203 unsigned Indent, bool Quiet);
204
205 /// If this compile unit is really a skeleton CU that points to a
206 /// clang module, register it in ClangModules and return true.
207 ///
208 /// A skeleton CU is a CU without children, a DW_AT_gnu_dwo_name
209 /// pointing to the module, and a DW_AT_gnu_dwo_id with the module
210 /// hash.
211 bool registerModuleReference(const DWARFDie &CUDie, ObjFileLoaderTy Loader,
212 CompileUnitHandlerTy OnCUDieLoaded,
213 unsigned Indent = 0);
214
215 /// Recursively add the debug info in this clang module .pcm
216 /// file (and all the modules imported by it in a bottom-up fashion)
217 /// to ModuleUnits.
218 Error loadClangModule(ObjFileLoaderTy Loader, const DWARFDie &CUDie,
219 const std::string &PCMFile,
220 CompileUnitHandlerTy OnCUDieLoaded,
221 unsigned Indent = 0);
222
223 /// Computes the total size of the debug info.
225 uint64_t Size = 0;
226
227 if (InputDWARFFile.Dwarf == nullptr)
228 return Size;
229
230 for (auto &Unit : InputDWARFFile.Dwarf->compile_units())
231 Size += Unit->getLength();
232
233 return Size;
234 }
235
236 /// Section + local offset of a .debug_frame CIE that has been (or will
237 /// be) emitted by some LinkContext. Stored in CIERegistry so that any
238 /// FDE referencing the same CIE bytes can resolve its CIE_pointer to
239 /// OwnerSection->StartOffset + LocalOffset at output time, even when
240 /// the FDE lives in a different LinkContext's section.
245
246 /// Linker-wide registry for .debug_frame CIEs. The key is the raw CIE
247 /// bytes. Populated by a serial pass over ObjectContexts (so ownership
248 /// is deterministic — first LinkContext wins) and then consumed
249 /// read-only by a parallel emission pass that writes each context's
250 /// .debug_frame section. SectionDescriptor pointers remain valid until
251 /// linking completes because they live in std::map-held shared_ptrs.
253
254 /// Result of scanning one LinkContext's input .debug_frame. Produced
255 /// by scanFrameData() during the parallel link phase and consumed by
256 /// the serial CIE-registry merge and parallel emission passes. Owns a
257 /// copy of the raw frame bytes so the StringRef views below remain
258 /// valid after the input DWARFContext is unloaded.
260 /// Owning copy of the input .debug_frame bytes.
262
263 /// Address size of the input object, used by emitFDE to size the
264 /// FDE's initial_location field.
265 unsigned AddressSize = 0;
266
267 /// Unique CIEs referenced by at least one retained FDE in this
268 /// context, in first-reference order. Each element is a view into
269 /// FrameData and is a key into the linker-wide CIERegistry.
271
272 /// FDEs retained for emission. CIEBytes is the registry key;
273 /// Instructions is the FDE body after the initial_length /
274 /// CIE_pointer / initial_location fields.
281
282 /// CIEs this context owns, set during the serial CIE-registry
283 /// merge. Emission writes these at local offsets 0,
284 /// OwnedCIEs[0].size(), ... in order.
286 };
287 std::unique_ptr<FrameScanResult> FrameScan;
288
289 /// Link compile units for this context.
291
292 /// Link specified compile unit until specified stage.
296
297 /// Emit invariant sections.
299
300 /// Unload the input DWARFContext after scanning the input .debug_frame into
301 /// FrameScan.
303
304 /// Parse this context's input .debug_frame into FrameScan. Deferred
305 /// CIE/FDE emission happens later against the scan result alone.
307
308 /// Register this context's CIEs with the linker-wide registry.
309 void registerCIEs(CIERegistry &CIEs);
310
311 /// Emit this context's .debug_frame section. Safe to call in parallel
312 /// across contexts because each call writes only to its own
313 /// SectionDescriptor.
314 Error emitDebugFrame(const CIERegistry &CIEs);
315
316 /// Emit FDE record.
317 void emitFDE(uint32_t CIEOffset, uint32_t AddrSize, uint64_t Address,
318 StringRef FDEBytes, SectionDescriptor &Section);
319
321 [&](uint64_t Offset) -> CompileUnit * {
322 auto CU = llvm::upper_bound(
324 [](uint64_t LHS, const std::unique_ptr<CompileUnit> &RHS) {
325 return LHS < RHS->getOrigUnit().getNextUnitOffset();
326 });
327
328 return CU != CompileUnits.end() ? CU->get() : nullptr;
329 };
330 };
331
332 /// Enumerate all compile units and assign offsets to their sections and
333 /// strings.
334 void assignOffsets();
335
336 /// Enumerate all compile units and assign offsets to their sections.
338
339 /// Enumerate all compile units and assign offsets to their strings.
341
342 /// Print statistic for processed Debug Info.
343 void printStatistic();
344
346
347 /// Enumerates all strings.
350 StringHandler);
351
352 /// Enumerates sections for modules, invariant for object files, compile
353 /// units.
355 function_ref<void(OutputSections &SectionsSet)> SectionsSetHandler);
356
357 /// Enumerates all compile and type units.
358 void forEachCompileAndTypeUnit(function_ref<void(DwarfUnit *CU)> UnitHandler);
359
360 /// Enumerates all comple units.
361 void forEachCompileUnit(function_ref<void(CompileUnit *CU)> UnitHandler);
362
363 /// Enumerates all patches and update them with the correct values.
365
366 /// Emit debug sections common for all input files.
368
369 /// Emit apple accelerator sections.
370 void emitAppleAcceleratorSections(const Triple &TargetTriple);
371
372 /// Emit .debug_names section.
373 void emitDWARFv5DebugNamesSection(const Triple &TargetTriple);
374
375 /// Emit string sections.
376 void emitStringSections();
377
378 /// Cleanup data(string pools) after output sections are generated.
380
381 /// Enumerate all compile units and put their data into the output stream.
383
384 /// Enumerate common sections and put their data into the output stream.
386
387 /// \defgroup Data members accessed asinchroniously.
388 ///
389 /// @{
390
391 /// Unique ID for compile unit.
392 std::atomic<size_t> UniqueUnitID;
393
394 /// Mapping the PCM filename to the DwoId. Only ever touched from
395 /// addObjectFile(), which runs serially, so it needs no synchronization.
397
398 /// Type unit.
399 std::unique_ptr<TypeUnit> ArtificialTypeUnit;
400 /// @}
401
402 /// \defgroup Data members accessed sequentially.
403 ///
404 /// @{
405 /// Data global for the whole linking process.
407
408 /// DwarfStringPoolEntries for .debug_str section.
410
411 /// DwarfStringPoolEntries for .debug_line_str section.
413
414 /// Keeps all linking contexts.
416
417 /// Common sections.
419
420 /// Hanler for output sections.
422
423 /// Thread pool that links the object files, or null to use a private pool.
425 /// @}
426};
427
428} // end of namespace parallel
429} // end of namespace dwarf_linker
430} // end of namespace llvm
431
432#endif // LLVM_LIB_DWARFLINKER_PARALLEL_DWARFLINKERIMPL_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned uint64_t
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:128
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
This defines the abstract base interface for a ThreadPool allowing asynchronous parallel execution on...
Definition ThreadPool.h:51
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
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.
ThreadPoolInterface * ThreadPool
Thread pool that links the object files, or null to use a private pool.
std::atomic< size_t > UniqueUnitID
Unique ID for compile unit.
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 setThreadPool(ThreadPoolInterface *Pool) override
Use the specified thread pool to link the object files.
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:578
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:2065
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition Error.h:1321
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1947
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.
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 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.
UnitListTy ModulesCompileUnits
Set of Compile Units for modules.
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
This structure is used to keep data of the concrete section.