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"
20
21namespace llvm {
22namespace dwarf_linker {
23namespace parallel {
24
25/// This class links debug info.
27public:
29 MessageHandlerTy WarningHandler);
30
31 /// Add object file to be linked. Pre-load compile unit die. Call
32 /// \p OnCUDieLoaded for each compile unit die. If specified \p File
33 /// has reference to the Clang module then such module would be
34 /// pre-loaded by \p Loader for !Update case.
35 ///
36 /// \pre NoODR, Update options should be set before call to addObjectFile.
37 void addObjectFile(
38 DWARFFile &File, ObjFileLoaderTy Loader = nullptr,
39
40 CompileUnitHandlerTy OnCUDieLoaded = [](const DWARFUnit &) {}) override;
41
42 /// Link debug info for added files.
43 Error link() override;
44
45 /// Set output DWARF handler. May be not set if output generation is not
46 /// necessary.
47 void setOutputDWARFHandler(const Triple &TargetTriple,
49 GlobalData.setTargetTriple(TargetTriple);
50 this->SectionHandler = SectionHandler;
51 }
52
53 /// \defgroup Methods setting various linking options:
54 ///
55 /// @{
56 ///
57
58 /// Allows to generate log of linking process to the standard output.
59 void setVerbosity(bool Verbose) override {
60 GlobalData.Options.Verbose = Verbose;
61 }
62
63 /// Print statistics to standard output.
64 void setStatistics(bool Statistics) override {
65 GlobalData.Options.Statistics = Statistics;
66 }
67
68 /// Verify the input DWARF.
69 void setVerifyInputDWARF(bool Verify) override {
70 GlobalData.Options.VerifyInputDWARF = Verify;
71 }
72
73 /// Do not unique types according to ODR.
74 void setNoODR(bool NoODR) override { GlobalData.Options.NoODR = NoODR; }
75
76 /// Update index tables only(do not modify rest of DWARF).
77 void setUpdateIndexTablesOnly(bool UpdateIndexTablesOnly) override {
78 GlobalData.Options.UpdateIndexTablesOnly = UpdateIndexTablesOnly;
79 }
80
81 /// Set to keep the enclosing function for a static variable.
82 void setKeepFunctionForStatic(bool KeepFunctionForStatic) override {
83 GlobalData.Options.KeepFunctionForStatic = KeepFunctionForStatic;
84 }
85
86 /// Use specified number of threads for parallel files linking.
87 void setNumThreads(unsigned NumThreads) override {
88 GlobalData.Options.Threads = NumThreads;
89 }
90
91 /// Add kind of accelerator tables to be generated.
92 void addAccelTableKind(AccelTableKind Kind) override {
93 assert(!llvm::is_contained(GlobalData.getOptions().AccelTables, Kind));
94 GlobalData.Options.AccelTables.emplace_back(Kind);
95 }
96
97 /// Set prepend path for clang modules.
98 void setPrependPath(StringRef Ppath) override {
99 GlobalData.Options.PrependPath = Ppath;
100 }
101
102 /// Set estimated objects files amount, for preliminary data allocation.
103 void setEstimatedObjfilesAmount(unsigned ObjFilesNum) override;
104
105 /// Set verification handler which would be used to report verification
106 /// errors.
107 void
109 GlobalData.Options.InputVerificationHandler = Handler;
110 }
111
112 /// Set map for Swift interfaces.
114 GlobalData.Options.ParseableSwiftInterfaces = Map;
115 }
116
117 /// Set prefix map for objects.
119 GlobalData.Options.ObjectPrefixMap = Map;
120 }
121
122 /// Set target DWARF version.
123 Error setTargetDWARFVersion(uint16_t TargetDWARFVersion) override {
124 if ((TargetDWARFVersion < 1) || (TargetDWARFVersion > 5))
125 return createStringError(std::errc::invalid_argument,
126 "unsupported DWARF version: %d",
127 TargetDWARFVersion);
128
129 GlobalData.Options.TargetDWARFVersion = TargetDWARFVersion;
130 return Error::success();
131 }
132 /// @}
133
134protected:
135 /// Verify input DWARF file.
136 void verifyInput(const DWARFFile &File);
137
138 /// Validate specified options.
140
141 /// Take already linked compile units and glue them into single file.
143
144 /// Hold the input and output of the debug info size in bytes.
149
150 friend class DependencyTracker;
151 /// Keeps track of data associated with one object during linking.
152 /// i.e. source file descriptor, compilation units, output data
153 /// for compilation units common tables.
154 struct LinkContext : public OutputSections {
156
157 /// Keep information for referenced clang module: already loaded DWARF info
158 /// of the clang module and a CompileUnit of the module.
160 RefModuleUnit(DWARFFile &File, std::unique_ptr<CompileUnit> Unit);
162 RefModuleUnit(const RefModuleUnit &) = delete;
163
165 std::unique_ptr<CompileUnit> Unit;
166 };
168
169 /// Object file descriptor.
171
172 /// Set of Compilation Units(may be accessed asynchroniously for reading).
174
175 /// Set of Compile Units for modules.
177
178 /// Index of this object file in the link order (used for deterministic
179 /// type DIE allocation).
181
182 /// Size of Debug info before optimizing.
184
185 /// Flag indicating that all inter-connected units are loaded
186 /// and the dwarf linking process for these units is started.
188
190
191 /// Flag indicating that new inter-connected compilation units were
192 /// discovered. It is used for restarting units processing
193 /// if new inter-connected units were found.
194 std::atomic<bool> HasNewInterconnectedCUs = {false};
195
196 std::atomic<bool> HasNewGlobalDependency = {false};
197
198 /// Counter for compile units ID.
199 std::atomic<size_t> &UniqueUnitID;
200
203 std::atomic<size_t> &UniqueUnitID);
204
205 /// Check whether specified \p CUDie is a Clang module reference.
206 /// if \p Quiet is false then display error messages.
207 /// \return first == true if CUDie is a Clang module reference.
208 /// second == true if module is already loaded.
209 std::pair<bool, bool> isClangModuleRef(const DWARFDie &CUDie,
210 std::string &PCMFile,
211 unsigned Indent, bool Quiet);
212
213 /// If this compile unit is really a skeleton CU that points to a
214 /// clang module, register it in ClangModules and return true.
215 ///
216 /// A skeleton CU is a CU without children, a DW_AT_gnu_dwo_name
217 /// pointing to the module, and a DW_AT_gnu_dwo_id with the module
218 /// hash.
219 bool registerModuleReference(const DWARFDie &CUDie, ObjFileLoaderTy Loader,
220 CompileUnitHandlerTy OnCUDieLoaded,
221 unsigned Indent = 0);
222
223 /// Recursively add the debug info in this clang module .pcm
224 /// file (and all the modules imported by it in a bottom-up fashion)
225 /// to ModuleUnits.
226 Error loadClangModule(ObjFileLoaderTy Loader, const DWARFDie &CUDie,
227 const std::string &PCMFile,
228 CompileUnitHandlerTy OnCUDieLoaded,
229 unsigned Indent = 0);
230
231 /// Add Compile Unit corresponding to the module.
233
234 /// Computes the total size of the debug info.
236 uint64_t Size = 0;
237
238 if (InputDWARFFile.Dwarf == nullptr)
239 return Size;
240
241 for (auto &Unit : InputDWARFFile.Dwarf->compile_units())
242 Size += Unit->getLength();
243
244 return Size;
245 }
246
247 /// Link compile units for this context.
249
250 /// Link specified compile unit until specified stage.
254
255 /// Emit invariant sections.
257
258 /// Clone and emit .debug_frame.
260
261 /// Emit FDE record.
262 void emitFDE(uint32_t CIEOffset, uint32_t AddrSize, uint64_t Address,
263 StringRef FDEBytes, SectionDescriptor &Section);
264
266 [&](uint64_t Offset) -> CompileUnit * {
267 auto CU = llvm::upper_bound(
269 [](uint64_t LHS, const std::unique_ptr<CompileUnit> &RHS) {
270 return LHS < RHS->getOrigUnit().getNextUnitOffset();
271 });
272
273 return CU != CompileUnits.end() ? CU->get() : nullptr;
274 };
275 };
276
277 /// Enumerate all compile units and assign offsets to their sections and
278 /// strings.
279 void assignOffsets();
280
281 /// Enumerate all compile units and assign offsets to their sections.
283
284 /// Enumerate all compile units and assign offsets to their strings.
286
287 /// Print statistic for processed Debug Info.
288 void printStatistic();
289
291
292 /// Enumerates all strings.
295 StringHandler);
296
297 /// Enumerates sections for modules, invariant for object files, compile
298 /// units.
300 function_ref<void(OutputSections &SectionsSet)> SectionsSetHandler);
301
302 /// Enumerates all compile and type units.
303 void forEachCompileAndTypeUnit(function_ref<void(DwarfUnit *CU)> UnitHandler);
304
305 /// Enumerates all comple units.
306 void forEachCompileUnit(function_ref<void(CompileUnit *CU)> UnitHandler);
307
308 /// Enumerates all patches and update them with the correct values.
310
311 /// Emit debug sections common for all input files.
313
314 /// Emit apple accelerator sections.
315 void emitAppleAcceleratorSections(const Triple &TargetTriple);
316
317 /// Emit .debug_names section.
318 void emitDWARFv5DebugNamesSection(const Triple &TargetTriple);
319
320 /// Emit string sections.
321 void emitStringSections();
322
323 /// Cleanup data(string pools) after output sections are generated.
325
326 /// Enumerate all compile units and put their data into the output stream.
328
329 /// Enumerate common sections and put their data into the output stream.
331
332 /// \defgroup Data members accessed asinchroniously.
333 ///
334 /// @{
335
336 /// Unique ID for compile unit.
337 std::atomic<size_t> UniqueUnitID;
338
339 /// Mapping the PCM filename to the DwoId.
342
343 /// Type unit.
344 std::unique_ptr<TypeUnit> ArtificialTypeUnit;
345 /// @}
346
347 /// \defgroup Data members accessed sequentially.
348 ///
349 /// @{
350 /// Data global for the whole linking process.
352
353 /// DwarfStringPoolEntries for .debug_str section.
355
356 /// DwarfStringPoolEntries for .debug_line_str section.
358
359 /// Keeps all linking contexts.
361
362 /// Common sections.
364
365 /// Hanler for output sections.
367
368 /// Overall compile units number.
370 /// @}
371};
372
373} // end of namespace parallel
374} // end of namespace dwarf_linker
375} // end of namespace llvm
376
377#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
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
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:55
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.
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 ...
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.
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.
std::atomic< size_t > & UniqueUnitID
Counter for compile units ID.
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.