File: DWARFLinkerImpl.h

package info (click to toggle)
llvm-toolchain-17 1%3A17.0.6-22
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,799,624 kB
  • sloc: cpp: 6,428,607; ansic: 1,383,196; asm: 793,408; python: 223,504; objc: 75,364; f90: 60,502; lisp: 33,869; pascal: 15,282; sh: 9,684; perl: 7,453; ml: 4,937; awk: 3,523; makefile: 2,889; javascript: 2,149; xml: 888; fortran: 619; cs: 573
file content (319 lines) | stat: -rw-r--r-- 10,591 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
//===- DWARFLinkerImpl.h ----------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_DWARFLINKERPARALLEL_DWARFLINKERIMPL_H
#define LLVM_LIB_DWARFLINKERPARALLEL_DWARFLINKERIMPL_H

#include "DWARFEmitterImpl.h"
#include "DWARFLinkerCompileUnit.h"
#include "llvm/ADT/AddressRanges.h"
#include "llvm/CodeGen/AccelTable.h"
#include "llvm/DWARFLinkerParallel/DWARFLinker.h"
#include "llvm/DWARFLinkerParallel/StringPool.h"
#include "llvm/DWARFLinkerParallel/StringTable.h"

namespace llvm {
namespace dwarflinker_parallel {

using Offset2UnitMapTy = DenseMap<uint64_t, CompileUnit *>;

struct RangeAttrPatch;
struct LocAttrPatch;

class DWARFLinkerImpl : public DWARFLinker {
public:
  DWARFLinkerImpl(MessageHandlerTy ErrorHandler,
                  MessageHandlerTy WarningHandler,
                  TranslatorFuncTy StringsTranslator)
      : UniqueUnitID(0), ErrorHandler(ErrorHandler),
        WarningHandler(WarningHandler),
        OutputStrings(Strings, StringsTranslator) {}

  Error createEmitter(const Triple &TheTriple, OutputFileType FileType,
                      raw_pwrite_stream &OutFile) override;

  ExtraDwarfEmitter *getEmitter() override;

  /// Add object file to be linked. Pre-load compile unit die. Call
  /// \p OnCUDieLoaded for each compile unit die. If specified \p File
  /// has reference to the Clang module then such module would be
  /// pre-loaded by \p Loader for !Update case.
  ///
  /// \pre NoODR, Update options should be set before call to addObjectFile.
  void addObjectFile(
      DWARFFile &File, ObjFileLoaderTy Loader = nullptr,
      CompileUnitHandlerTy OnCUDieLoaded = [](const DWARFUnit &) {}) override {}

  /// Link debug info for added files.
  Error link() override {
    reportWarning("LLVM parallel dwarflinker is not implemented yet.", "");
    return Error::success();
  }

  /// \defgroup Methods setting various linking options:
  ///
  /// @{
  ///

  /// Allows to generate log of linking process to the standard output.
  void setVerbosity(bool Verbose) override { Options.Verbose = Verbose; }

  /// Print statistics to standard output.
  void setStatistics(bool Statistics) override {
    Options.Statistics = Statistics;
  }

  /// Verify the input DWARF.
  void setVerifyInputDWARF(bool Verify) override {
    Options.VerifyInputDWARF = Verify;
  }

  /// Do not unique types according to ODR.
  void setNoODR(bool NoODR) override { Options.NoODR = NoODR; }

  /// Update index tables only(do not modify rest of DWARF).
  void setUpdateIndexTablesOnly(bool UpdateIndexTablesOnly) override {
    Options.UpdateIndexTablesOnly = UpdateIndexTablesOnly;
  }

  /// Allow generating valid, but non-deterministic output.
  void
  setAllowNonDeterministicOutput(bool AllowNonDeterministicOutput) override {
    Options.AllowNonDeterministicOutput = AllowNonDeterministicOutput;
  }

  /// Set to keep the enclosing function for a static variable.
  void setKeepFunctionForStatic(bool KeepFunctionForStatic) override {
    Options.KeepFunctionForStatic = KeepFunctionForStatic;
  }

  /// Use specified number of threads for parallel files linking.
  void setNumThreads(unsigned NumThreads) override {
    Options.Threads = NumThreads;
  }

  /// Add kind of accelerator tables to be generated.
  void addAccelTableKind(AccelTableKind Kind) override {
    assert(!llvm::is_contained(Options.AccelTables, Kind));
    Options.AccelTables.emplace_back(Kind);
  }

  /// Set prepend path for clang modules.
  void setPrependPath(const std::string &Ppath) override {
    Options.PrependPath = Ppath;
  }

  /// Set estimated objects files amount, for preliminary data allocation.
  void setEstimatedObjfilesAmount(unsigned ObjFilesNum) override {
    ObjectContexts.reserve(ObjFilesNum);
  }

  /// Set verification handler which would be used to report verification
  /// errors.
  void
  setInputVerificationHandler(InputVerificationHandlerTy Handler) override {
    Options.InputVerificationHandler = Handler;
  }

  /// Set map for Swift interfaces.
  void setSwiftInterfacesMap(SwiftInterfacesMapTy *Map) override {
    Options.ParseableSwiftInterfaces = Map;
  }

  /// Set prefix map for objects.
  void setObjectPrefixMap(ObjectPrefixMapTy *Map) override {
    Options.ObjectPrefixMap = Map;
  }

  /// Set target DWARF version.
  Error setTargetDWARFVersion(uint16_t TargetDWARFVersion) override {
    if ((TargetDWARFVersion < 1) || (TargetDWARFVersion > 5))
      return createStringError(std::errc::invalid_argument,
                               "unsupported DWARF version: %d",
                               TargetDWARFVersion);

    Options.TargetDWARFVersion = TargetDWARFVersion;
    return Error::success();
  }
  /// @}

protected:
  /// Reports Warning.
  void reportWarning(const Twine &Warning, const DWARFFile &File,
                     const DWARFDie *DIE = nullptr) const {
    if (WarningHandler != nullptr)
      WarningHandler(Warning, File.FileName, DIE);
  }

  /// Reports Warning.
  void reportWarning(const Twine &Warning, StringRef FileName,
                     const DWARFDie *DIE = nullptr) const {
    if (WarningHandler != nullptr)
      WarningHandler(Warning, FileName, DIE);
  }

  /// Reports Error.
  void reportError(const Twine &Warning, StringRef FileName,
                   const DWARFDie *DIE = nullptr) const {
    if (ErrorHandler != nullptr)
      ErrorHandler(Warning, FileName, DIE);
  }

  /// Returns next available unique Compile Unit ID.
  unsigned getNextUniqueUnitID() { return UniqueUnitID.fetch_add(1); }

  /// Keeps track of data associated with one object during linking.
  /// i.e. source file descriptor, compilation units, output data
  /// for compilation units common tables.
  struct LinkContext : public OutputSections {
    using UnitListTy = SmallVector<std::unique_ptr<CompileUnit>>;

    /// Keep information for referenced clang module: already loaded DWARF info
    /// of the clang module and a CompileUnit of the module.
    struct RefModuleUnit {
      RefModuleUnit(DWARFFile &File, std::unique_ptr<CompileUnit> Unit)
          : File(File), Unit(std::move(Unit)) {}
      RefModuleUnit(RefModuleUnit &&Other)
          : File(Other.File), Unit(std::move(Other.Unit)) {}
      RefModuleUnit(const RefModuleUnit &) = delete;

      DWARFFile &File;
      std::unique_ptr<CompileUnit> Unit;
    };
    using ModuleUnitListTy = SmallVector<RefModuleUnit>;

    /// Object file descriptor.
    DWARFFile &File;

    /// Set of Compilation Units(may be accessed asynchroniously for reading).
    UnitListTy CompileUnits;

    /// Set of Compile Units for modules.
    ModuleUnitListTy ModulesCompileUnits;

    /// Size of Debug info before optimizing.
    uint64_t OriginalDebugInfoSize = 0;

    /// Output sections, common for all compilation units.
    OutTablesFileTy OutDebugInfoBytes;

    /// Endianness for the final file.
    support::endianness Endianess = support::endianness::little;

    LinkContext(DWARFFile &File) : File(File) {
      if (File.Dwarf) {
        if (!File.Dwarf->compile_units().empty())
          CompileUnits.reserve(File.Dwarf->getNumCompileUnits());

        Endianess = File.Dwarf->isLittleEndian() ? support::endianness::little
                                                 : support::endianness::big;
      }
    }

    /// Add Compile Unit corresponding to the module.
    void addModulesCompileUnit(RefModuleUnit &&Unit) {
      ModulesCompileUnits.emplace_back(std::move(Unit));
    }

    /// Return Endiannes of the source DWARF information.
    support::endianness getEndianness() { return Endianess; }

    /// \returns pointer to compilation unit which corresponds \p Offset.
    CompileUnit *getUnitForOffset(CompileUnit &CU, uint64_t Offset) const;
  };

  /// linking options
  struct DWARFLinkerOptions {
    /// DWARF version for the output.
    uint16_t TargetDWARFVersion = 0;

    /// Generate processing log to the standard output.
    bool Verbose = false;

    /// Print statistics.
    bool Statistics = false;

    /// Verify the input DWARF.
    bool VerifyInputDWARF = false;

    /// Do not unique types according to ODR
    bool NoODR = false;

    /// Update index tables.
    bool UpdateIndexTablesOnly = false;

    /// Whether we want a static variable to force us to keep its enclosing
    /// function.
    bool KeepFunctionForStatic = false;

    /// Allow to generate valid, but non deterministic output.
    bool AllowNonDeterministicOutput = false;

    /// Number of threads.
    unsigned Threads = 1;

    /// The accelerator table kinds
    SmallVector<AccelTableKind, 1> AccelTables;

    /// Prepend path for the clang modules.
    std::string PrependPath;

    /// input verification handler(it might be called asynchronously).
    InputVerificationHandlerTy InputVerificationHandler = nullptr;

    /// A list of all .swiftinterface files referenced by the debug
    /// info, mapping Module name to path on disk. The entries need to
    /// be uniqued and sorted and there are only few entries expected
    /// per compile unit, which is why this is a std::map.
    /// this is dsymutil specific fag.
    ///
    /// (it might be called asynchronously).
    SwiftInterfacesMapTy *ParseableSwiftInterfaces = nullptr;

    /// A list of remappings to apply to file paths.
    ///
    /// (it might be called asynchronously).
    ObjectPrefixMapTy *ObjectPrefixMap = nullptr;
  } Options;

  /// \defgroup Data members accessed asinchroniously.
  ///
  /// @{

  /// Unique ID for compile unit.
  std::atomic<unsigned> UniqueUnitID;

  /// Strings pool. Keeps all strings.
  StringPool Strings;

  /// error handler(it might be called asynchronously).
  MessageHandlerTy ErrorHandler = nullptr;

  /// warning handler(it might be called asynchronously).
  MessageHandlerTy WarningHandler = nullptr;
  /// @}

  /// \defgroup Data members accessed sequentially.
  ///
  /// @{

  /// Set of strings which should be emitted.
  StringTable OutputStrings;

  /// Keeps all linking contexts.
  SmallVector<std::unique_ptr<LinkContext>> ObjectContexts;

  /// The emitter of final dwarf file.
  std::unique_ptr<DwarfEmitterImpl> TheDwarfEmitter;
  /// @}
};

} // end namespace dwarflinker_parallel
} // end namespace llvm

#endif // LLVM_LIB_DWARFLINKERPARALLEL_DWARFLINKERIMPL_H