1 //===- DWARFLinkerImpl.h ----------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_LIB_DWARFLINKERPARALLEL_DWARFLINKERIMPL_H
10 #define LLVM_LIB_DWARFLINKERPARALLEL_DWARFLINKERIMPL_H
12 #include "DWARFEmitterImpl.h"
13 #include "DWARFLinkerCompileUnit.h"
14 #include "llvm/ADT/AddressRanges.h"
15 #include "llvm/CodeGen/AccelTable.h"
16 #include "llvm/DWARFLinkerParallel/DWARFLinker.h"
17 #include "llvm/DWARFLinkerParallel/StringPool.h"
18 #include "llvm/DWARFLinkerParallel/StringTable.h"
21 namespace dwarflinker_parallel
{
23 using Offset2UnitMapTy
= DenseMap
<uint64_t, CompileUnit
*>;
25 struct RangeAttrPatch
;
28 class DWARFLinkerImpl
: public DWARFLinker
{
30 DWARFLinkerImpl(MessageHandlerTy ErrorHandler
,
31 MessageHandlerTy WarningHandler
,
32 TranslatorFuncTy StringsTranslator
)
33 : UniqueUnitID(0), ErrorHandler(ErrorHandler
),
34 WarningHandler(WarningHandler
),
35 OutputStrings(Strings
, StringsTranslator
) {}
37 Error
createEmitter(const Triple
&TheTriple
, OutputFileType FileType
,
38 raw_pwrite_stream
&OutFile
) override
;
40 ExtraDwarfEmitter
*getEmitter() override
;
42 /// Add object file to be linked. Pre-load compile unit die. Call
43 /// \p OnCUDieLoaded for each compile unit die. If specified \p File
44 /// has reference to the Clang module then such module would be
45 /// pre-loaded by \p Loader for !Update case.
47 /// \pre NoODR, Update options should be set before call to addObjectFile.
49 DWARFFile
&File
, ObjFileLoaderTy Loader
= nullptr,
50 CompileUnitHandlerTy OnCUDieLoaded
= [](const DWARFUnit
&) {}) override
{}
52 /// Link debug info for added files.
53 Error
link() override
{
54 reportWarning("LLVM parallel dwarflinker is not implemented yet.", "");
55 return Error::success();
58 /// \defgroup Methods setting various linking options:
63 /// Allows to generate log of linking process to the standard output.
64 void setVerbosity(bool Verbose
) override
{ Options
.Verbose
= Verbose
; }
66 /// Print statistics to standard output.
67 void setStatistics(bool Statistics
) override
{
68 Options
.Statistics
= Statistics
;
71 /// Verify the input DWARF.
72 void setVerifyInputDWARF(bool Verify
) override
{
73 Options
.VerifyInputDWARF
= Verify
;
76 /// Do not unique types according to ODR.
77 void setNoODR(bool NoODR
) override
{ Options
.NoODR
= NoODR
; }
79 /// Update index tables only(do not modify rest of DWARF).
80 void setUpdateIndexTablesOnly(bool UpdateIndexTablesOnly
) override
{
81 Options
.UpdateIndexTablesOnly
= UpdateIndexTablesOnly
;
84 /// Allow generating valid, but non-deterministic output.
86 setAllowNonDeterministicOutput(bool AllowNonDeterministicOutput
) override
{
87 Options
.AllowNonDeterministicOutput
= AllowNonDeterministicOutput
;
90 /// Set to keep the enclosing function for a static variable.
91 void setKeepFunctionForStatic(bool KeepFunctionForStatic
) override
{
92 Options
.KeepFunctionForStatic
= KeepFunctionForStatic
;
95 /// Use specified number of threads for parallel files linking.
96 void setNumThreads(unsigned NumThreads
) override
{
97 Options
.Threads
= NumThreads
;
100 /// Add kind of accelerator tables to be generated.
101 void addAccelTableKind(AccelTableKind Kind
) override
{
102 assert(!llvm::is_contained(Options
.AccelTables
, Kind
));
103 Options
.AccelTables
.emplace_back(Kind
);
106 /// Set prepend path for clang modules.
107 void setPrependPath(const std::string
&Ppath
) override
{
108 Options
.PrependPath
= Ppath
;
111 /// Set estimated objects files amount, for preliminary data allocation.
112 void setEstimatedObjfilesAmount(unsigned ObjFilesNum
) override
{
113 ObjectContexts
.reserve(ObjFilesNum
);
116 /// Set verification handler which would be used to report verification
119 setInputVerificationHandler(InputVerificationHandlerTy Handler
) override
{
120 Options
.InputVerificationHandler
= Handler
;
123 /// Set map for Swift interfaces.
124 void setSwiftInterfacesMap(SwiftInterfacesMapTy
*Map
) override
{
125 Options
.ParseableSwiftInterfaces
= Map
;
128 /// Set prefix map for objects.
129 void setObjectPrefixMap(ObjectPrefixMapTy
*Map
) override
{
130 Options
.ObjectPrefixMap
= Map
;
133 /// Set target DWARF version.
134 Error
setTargetDWARFVersion(uint16_t TargetDWARFVersion
) override
{
135 if ((TargetDWARFVersion
< 1) || (TargetDWARFVersion
> 5))
136 return createStringError(std::errc::invalid_argument
,
137 "unsupported DWARF version: %d",
140 Options
.TargetDWARFVersion
= TargetDWARFVersion
;
141 return Error::success();
147 void reportWarning(const Twine
&Warning
, const DWARFFile
&File
,
148 const DWARFDie
*DIE
= nullptr) const {
149 if (WarningHandler
!= nullptr)
150 WarningHandler(Warning
, File
.FileName
, DIE
);
154 void reportWarning(const Twine
&Warning
, StringRef FileName
,
155 const DWARFDie
*DIE
= nullptr) const {
156 if (WarningHandler
!= nullptr)
157 WarningHandler(Warning
, FileName
, DIE
);
161 void reportError(const Twine
&Warning
, StringRef FileName
,
162 const DWARFDie
*DIE
= nullptr) const {
163 if (ErrorHandler
!= nullptr)
164 ErrorHandler(Warning
, FileName
, DIE
);
167 /// Returns next available unique Compile Unit ID.
168 unsigned getNextUniqueUnitID() { return UniqueUnitID
.fetch_add(1); }
170 /// Keeps track of data associated with one object during linking.
171 /// i.e. source file descriptor, compilation units, output data
172 /// for compilation units common tables.
173 struct LinkContext
: public OutputSections
{
174 using UnitListTy
= SmallVector
<std::unique_ptr
<CompileUnit
>>;
176 /// Keep information for referenced clang module: already loaded DWARF info
177 /// of the clang module and a CompileUnit of the module.
178 struct RefModuleUnit
{
179 RefModuleUnit(DWARFFile
&File
, std::unique_ptr
<CompileUnit
> Unit
)
180 : File(File
), Unit(std::move(Unit
)) {}
181 RefModuleUnit(RefModuleUnit
&&Other
)
182 : File(Other
.File
), Unit(std::move(Other
.Unit
)) {}
183 RefModuleUnit(const RefModuleUnit
&) = delete;
186 std::unique_ptr
<CompileUnit
> Unit
;
188 using ModuleUnitListTy
= SmallVector
<RefModuleUnit
>;
190 /// Object file descriptor.
193 /// Set of Compilation Units(may be accessed asynchroniously for reading).
194 UnitListTy CompileUnits
;
196 /// Set of Compile Units for modules.
197 ModuleUnitListTy ModulesCompileUnits
;
199 /// Size of Debug info before optimizing.
200 uint64_t OriginalDebugInfoSize
= 0;
202 /// Output sections, common for all compilation units.
203 OutTablesFileTy OutDebugInfoBytes
;
205 /// Endianness for the final file.
206 support::endianness Endianess
= support::endianness::little
;
208 LinkContext(DWARFFile
&File
) : File(File
) {
210 if (!File
.Dwarf
->compile_units().empty())
211 CompileUnits
.reserve(File
.Dwarf
->getNumCompileUnits());
213 Endianess
= File
.Dwarf
->isLittleEndian() ? support::endianness::little
214 : support::endianness::big
;
218 /// Add Compile Unit corresponding to the module.
219 void addModulesCompileUnit(RefModuleUnit
&&Unit
) {
220 ModulesCompileUnits
.emplace_back(std::move(Unit
));
223 /// Return Endiannes of the source DWARF information.
224 support::endianness
getEndianness() { return Endianess
; }
226 /// \returns pointer to compilation unit which corresponds \p Offset.
227 CompileUnit
*getUnitForOffset(CompileUnit
&CU
, uint64_t Offset
) const;
231 struct DWARFLinkerOptions
{
232 /// DWARF version for the output.
233 uint16_t TargetDWARFVersion
= 0;
235 /// Generate processing log to the standard output.
236 bool Verbose
= false;
238 /// Print statistics.
239 bool Statistics
= false;
241 /// Verify the input DWARF.
242 bool VerifyInputDWARF
= false;
244 /// Do not unique types according to ODR
247 /// Update index tables.
248 bool UpdateIndexTablesOnly
= false;
250 /// Whether we want a static variable to force us to keep its enclosing
252 bool KeepFunctionForStatic
= false;
254 /// Allow to generate valid, but non deterministic output.
255 bool AllowNonDeterministicOutput
= false;
257 /// Number of threads.
258 unsigned Threads
= 1;
260 /// The accelerator table kinds
261 SmallVector
<AccelTableKind
, 1> AccelTables
;
263 /// Prepend path for the clang modules.
264 std::string PrependPath
;
266 /// input verification handler(it might be called asynchronously).
267 InputVerificationHandlerTy InputVerificationHandler
= nullptr;
269 /// A list of all .swiftinterface files referenced by the debug
270 /// info, mapping Module name to path on disk. The entries need to
271 /// be uniqued and sorted and there are only few entries expected
272 /// per compile unit, which is why this is a std::map.
273 /// this is dsymutil specific fag.
275 /// (it might be called asynchronously).
276 SwiftInterfacesMapTy
*ParseableSwiftInterfaces
= nullptr;
278 /// A list of remappings to apply to file paths.
280 /// (it might be called asynchronously).
281 ObjectPrefixMapTy
*ObjectPrefixMap
= nullptr;
284 /// \defgroup Data members accessed asinchroniously.
288 /// Unique ID for compile unit.
289 std::atomic
<unsigned> UniqueUnitID
;
291 /// Strings pool. Keeps all strings.
294 /// error handler(it might be called asynchronously).
295 MessageHandlerTy ErrorHandler
= nullptr;
297 /// warning handler(it might be called asynchronously).
298 MessageHandlerTy WarningHandler
= nullptr;
301 /// \defgroup Data members accessed sequentially.
305 /// Set of strings which should be emitted.
306 StringTable OutputStrings
;
308 /// Keeps all linking contexts.
309 SmallVector
<std::unique_ptr
<LinkContext
>> ObjectContexts
;
311 /// The emitter of final dwarf file.
312 std::unique_ptr
<DwarfEmitterImpl
> TheDwarfEmitter
;
316 } // end namespace dwarflinker_parallel
317 } // end namespace llvm
319 #endif // LLVM_LIB_DWARFLINKERPARALLEL_DWARFLINKERIMPL_H