Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//===- DWARFLinker.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_DWARFLINKER_DWARFLINKER_H
10
#define LLVM_DWARFLINKER_DWARFLINKER_H
11
 
12
#include "llvm/ADT/AddressRanges.h"
13
#include "llvm/ADT/DenseMap.h"
14
#include "llvm/CodeGen/AccelTable.h"
15
#include "llvm/CodeGen/NonRelocatableStringpool.h"
16
#include "llvm/DWARFLinker/DWARFLinkerCompileUnit.h"
17
#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
18
#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
19
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
20
#include <map>
21
 
22
namespace llvm {
23
class DWARFContext;
24
class DWARFExpression;
25
class DWARFUnit;
26
class DataExtractor;
27
class DeclContextTree;
28
struct MCDwarfLineTableParams;
29
template <typename T> class SmallVectorImpl;
30
 
31
enum class DwarfLinkerClient { Dsymutil, LLD, General };
32
 
33
/// The kind of accelerator tables we should emit.
34
enum class DwarfLinkerAccelTableKind : uint8_t {
35
  Apple,     ///< .apple_names, .apple_namespaces, .apple_types, .apple_objc.
36
  Pub,       ///< .debug_pubnames, .debug_pubtypes
37
  DebugNames ///< .debug_names.
38
};
39
 
40
/// AddressesMap represents information about valid addresses used
41
/// by debug information. Valid addresses are those which points to
42
/// live code sections. i.e. relocations for these addresses point
43
/// into sections which would be/are placed into resulting binary.
44
class AddressesMap {
45
public:
46
  virtual ~AddressesMap();
47
 
48
  /// Checks that there are valid relocations against a .debug_info
49
  /// section.
50
  virtual bool hasValidRelocs() = 0;
51
 
52
  /// Checks that the specified variable \p DIE references live code section.
53
  /// Allowed kind of input die: DW_TAG_variable, DW_TAG_constant.
54
  /// \returns true and sets Info.InDebugMap if it is the case.
55
  virtual bool isLiveVariable(const DWARFDie &DIE,
56
                              CompileUnit::DIEInfo &Info) = 0;
57
 
58
  /// Checks that the specified subprogram \p DIE references live code section.
59
  /// Allowed kind of input die: DW_TAG_subprogram, DW_TAG_label.
60
  /// \returns true and sets Info.InDebugMap if it is the case.
61
  virtual bool isLiveSubprogram(const DWARFDie &DIE,
62
                                CompileUnit::DIEInfo &Info) = 0;
63
 
64
  /// Apply the valid relocations to the buffer \p Data, taking into
65
  /// account that Data is at \p BaseOffset in the .debug_info section.
66
  ///
67
  /// \returns true whether any reloc has been applied.
68
  virtual bool applyValidRelocs(MutableArrayRef<char> Data, uint64_t BaseOffset,
69
                                bool IsLittleEndian) = 0;
70
 
71
  /// Relocate the given address offset if a valid relocation exists.
72
  virtual llvm::Expected<uint64_t> relocateIndexedAddr(uint64_t StartOffset,
73
                                                       uint64_t EndOffset) = 0;
74
 
75
  /// Returns all valid functions address ranges(i.e., those ranges
76
  /// which points to sections with code).
77
  virtual RangesTy &getValidAddressRanges() = 0;
78
 
79
  /// Erases all data.
80
  virtual void clear() = 0;
81
};
82
 
83
using Offset2UnitMap = DenseMap<uint64_t, CompileUnit *>;
84
 
85
/// DwarfEmitter presents interface to generate all debug info tables.
86
class DwarfEmitter {
87
public:
88
  virtual ~DwarfEmitter();
89
 
90
  /// Emit DIE containing warnings.
91
  virtual void emitPaperTrailWarningsDie(DIE &Die) = 0;
92
 
93
  /// Emit section named SecName with data SecData.
94
  virtual void emitSectionContents(StringRef SecData, StringRef SecName) = 0;
95
 
96
  /// Emit the abbreviation table \p Abbrevs to the .debug_abbrev section.
97
  virtual void
98
  emitAbbrevs(const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs,
99
              unsigned DwarfVersion) = 0;
100
 
101
  /// Emit the string table described by \p Pool.
102
  virtual void emitStrings(const NonRelocatableStringpool &Pool) = 0;
103
 
104
  /// Emit DWARF debug names.
105
  virtual void
106
  emitDebugNames(AccelTable<DWARF5AccelTableStaticData> &Table) = 0;
107
 
108
  /// Emit Apple namespaces accelerator table.
109
  virtual void
110
  emitAppleNamespaces(AccelTable<AppleAccelTableStaticOffsetData> &Table) = 0;
111
 
112
  /// Emit Apple names accelerator table.
113
  virtual void
114
  emitAppleNames(AccelTable<AppleAccelTableStaticOffsetData> &Table) = 0;
115
 
116
  /// Emit Apple Objective-C accelerator table.
117
  virtual void
118
  emitAppleObjc(AccelTable<AppleAccelTableStaticOffsetData> &Table) = 0;
119
 
120
  /// Emit Apple type accelerator table.
121
  virtual void
122
  emitAppleTypes(AccelTable<AppleAccelTableStaticTypeData> &Table) = 0;
123
 
124
  /// Emit piece of .debug_ranges for \p Ranges.
125
  virtual void
126
  emitDwarfDebugRangesTableFragment(const CompileUnit &Unit,
127
                                    const AddressRanges &LinkedRanges) = 0;
128
 
129
  /// Emit .debug_aranges entries for \p Unit and if \p DoRangesSection is true,
130
  /// also emit the .debug_ranges entries for the DW_TAG_compile_unit's
131
  /// DW_AT_ranges attribute.
132
  virtual void emitUnitRangesEntries(CompileUnit &Unit,
133
                                     bool DoRangesSection) = 0;
134
 
135
  /// Copy the .debug_line over to the updated binary while unobfuscating the
136
  /// file names and directories.
137
  virtual void translateLineTable(DataExtractor LineData, uint64_t Offset) = 0;
138
 
139
  /// Emit the line table described in \p Rows into the .debug_line section.
140
  virtual void emitLineTableForUnit(MCDwarfLineTableParams Params,
141
                                    StringRef PrologueBytes,
142
                                    unsigned MinInstLength,
143
                                    std::vector<DWARFDebugLine::Row> &Rows,
144
                                    unsigned AdddressSize) = 0;
145
 
146
  /// Emit the .debug_pubnames contribution for \p Unit.
147
  virtual void emitPubNamesForUnit(const CompileUnit &Unit) = 0;
148
 
149
  /// Emit the .debug_pubtypes contribution for \p Unit.
150
  virtual void emitPubTypesForUnit(const CompileUnit &Unit) = 0;
151
 
152
  /// Emit a CIE.
153
  virtual void emitCIE(StringRef CIEBytes) = 0;
154
 
155
  /// Emit an FDE with data \p Bytes.
156
  virtual void emitFDE(uint32_t CIEOffset, uint32_t AddreSize, uint64_t Address,
157
                       StringRef Bytes) = 0;
158
 
159
  /// Emit the .debug_loc contribution for \p Unit by copying the entries from
160
  /// \p Dwarf and offsetting them. Update the location attributes to point to
161
  /// the new entries.
162
  virtual void emitLocationsForUnit(
163
      const CompileUnit &Unit, DWARFContext &Dwarf,
164
      std::function<void(StringRef, SmallVectorImpl<uint8_t> &)>
165
          ProcessExpr) = 0;
166
 
167
  /// Emit the compilation unit header for \p Unit in the
168
  /// .debug_info section.
169
  ///
170
  /// As a side effect, this also switches the current Dwarf version
171
  /// of the MC layer to the one of U.getOrigUnit().
172
  virtual void emitCompileUnitHeader(CompileUnit &Unit,
173
                                     unsigned DwarfVersion) = 0;
174
 
175
  /// Recursively emit the DIE tree rooted at \p Die.
176
  virtual void emitDIE(DIE &Die) = 0;
177
 
178
  /// Emit all available macro tables(DWARFv4 and DWARFv5).
179
  /// Use \p UnitMacroMap to get compilation unit by macro table offset.
180
  /// Side effects: Fill \p StringPool with macro strings, update
181
  /// DW_AT_macro_info, DW_AT_macros attributes for corresponding compile
182
  /// units.
183
  virtual void emitMacroTables(DWARFContext *Context,
184
                               const Offset2UnitMap &UnitMacroMap,
185
                               OffsetsStringPool &StringPool) = 0;
186
 
187
  /// Returns size of generated .debug_line section.
188
  virtual uint64_t getLineSectionSize() const = 0;
189
 
190
  /// Returns size of generated .debug_frame section.
191
  virtual uint64_t getFrameSectionSize() const = 0;
192
 
193
  /// Returns size of generated .debug_ranges section.
194
  virtual uint64_t getRangesSectionSize() const = 0;
195
 
196
  /// Returns size of generated .debug_info section.
197
  virtual uint64_t getDebugInfoSectionSize() const = 0;
198
 
199
  /// Returns size of generated .debug_macinfo section.
200
  virtual uint64_t getDebugMacInfoSectionSize() const = 0;
201
 
202
  /// Returns size of generated .debug_macro section.
203
  virtual uint64_t getDebugMacroSectionSize() const = 0;
204
};
205
 
206
using UnitListTy = std::vector<std::unique_ptr<CompileUnit>>;
207
 
208
/// this class represents DWARF information for source file
209
/// and it`s address map.
210
class DWARFFile {
211
public:
212
  DWARFFile(StringRef Name, DWARFContext *Dwarf, AddressesMap *Addresses,
213
            const std::vector<std::string> &Warnings)
214
      : FileName(Name), Dwarf(Dwarf), Addresses(Addresses), Warnings(Warnings) {
215
  }
216
 
217
  /// object file name.
218
  StringRef FileName;
219
  /// source DWARF information.
220
  DWARFContext *Dwarf = nullptr;
221
  /// helpful address information(list of valid address ranges, relocations).
222
  AddressesMap *Addresses = nullptr;
223
  /// warnings for object file.
224
  const std::vector<std::string> &Warnings;
225
};
226
 
227
typedef std::function<void(const Twine &Warning, StringRef Context,
228
                           const DWARFDie *DIE)>
229
    messageHandler;
230
typedef std::function<ErrorOr<DWARFFile &>(StringRef ContainerName,
231
                                           StringRef Path)>
232
    objFileLoader;
233
typedef std::map<std::string, std::string> swiftInterfacesMap;
234
typedef std::map<std::string, std::string> objectPrefixMap;
235
 
236
typedef function_ref<void(const DWARFUnit &Unit)> CompileUnitHandler;
237
 
238
/// The core of the Dwarf linking logic.
239
///
240
/// The generation of the dwarf information from the object files will be
241
/// driven by the selection of 'root DIEs', which are DIEs that
242
/// describe variables or functions that resolves to the corresponding
243
/// code section(and thus have entries in the Addresses map). All the debug
244
/// information that will be generated(the DIEs, but also the line
245
/// tables, ranges, ...) is derived from that set of root DIEs.
246
///
247
/// The root DIEs are identified because they contain relocations that
248
/// points to code section(the low_pc for a function, the location for
249
/// a variable). These relocations are called ValidRelocs in the
250
/// AddressesInfo and are gathered as a very first step when we start
251
/// processing a object file.
252
class DWARFLinker {
253
public:
254
  DWARFLinker(DwarfEmitter *Emitter,
255
              DwarfLinkerClient ClientID = DwarfLinkerClient::General)
256
      : TheDwarfEmitter(Emitter), DwarfLinkerClientID(ClientID) {}
257
 
258
  /// Add object file to be linked. Pre-load compile unit die. Call
259
  /// \p OnCUDieLoaded for each compile unit die. If specified \p File
260
  /// has reference to the Clang module then such module would be
261
  /// pre-loaded by \p Loader for !Update case.
262
  ///
263
  /// \pre NoODR, Update options should be set before call to addObjectFile.
264
  void addObjectFile(
265
      DWARFFile &File, objFileLoader Loader = nullptr,
266
      CompileUnitHandler OnCUDieLoaded = [](const DWARFUnit &) {});
267
 
268
  /// Link debug info for added objFiles. Object
269
  /// files are linked all together.
270
  Error link();
271
 
272
  /// A number of methods setting various linking options:
273
 
274
  /// Allows to generate log of linking process to the standard output.
275
  void setVerbosity(bool Verbose) { Options.Verbose = Verbose; }
276
 
277
  /// Print statistics to standard output.
278
  void setStatistics(bool Statistics) { Options.Statistics = Statistics; }
279
 
280
  /// Verify the input DWARF.
281
  void setVerifyInputDWARF(bool Verify) { Options.VerifyInputDWARF = Verify; }
282
 
283
  /// Do not emit linked dwarf info.
284
  void setNoOutput(bool NoOut) { Options.NoOutput = NoOut; }
285
 
286
  /// Do not unique types according to ODR.
287
  void setNoODR(bool NoODR) { Options.NoODR = NoODR; }
288
 
289
  /// update existing DWARF info(for the linked binary).
290
  void setUpdate(bool Update) { Options.Update = Update; }
291
 
292
  /// Set whether to keep the enclosing function for a static variable.
293
  void setKeepFunctionForStatic(bool KeepFunctionForStatic) {
294
    Options.KeepFunctionForStatic = KeepFunctionForStatic;
295
  }
296
 
297
  /// Use specified number of threads for parallel files linking.
298
  void setNumThreads(unsigned NumThreads) { Options.Threads = NumThreads; }
299
 
300
  /// Add kind of accelerator tables to be generated.
301
  void addAccelTableKind(DwarfLinkerAccelTableKind Kind) {
302
    assert(std::find(Options.AccelTables.begin(), Options.AccelTables.end(),
303
                     Kind) == Options.AccelTables.end());
304
    Options.AccelTables.emplace_back(Kind);
305
  }
306
 
307
  /// Set prepend path for clang modules.
308
  void setPrependPath(const std::string &Ppath) { Options.PrependPath = Ppath; }
309
 
310
  /// Set translator which would be used for strings.
311
  void
312
  setStringsTranslator(std::function<StringRef(StringRef)> StringsTranslator) {
313
    this->StringsTranslator = StringsTranslator;
314
  }
315
 
316
  /// Set estimated objects files amount, for preliminary data allocation.
317
  void setEstimatedObjfilesAmount(unsigned ObjFilesNum) {
318
    ObjectContexts.reserve(ObjFilesNum);
319
  }
320
 
321
  /// Set warning handler which would be used to report warnings.
322
  void setWarningHandler(messageHandler Handler) {
323
    Options.WarningHandler = Handler;
324
  }
325
 
326
  /// Set error handler which would be used to report errors.
327
  void setErrorHandler(messageHandler Handler) {
328
    Options.ErrorHandler = Handler;
329
  }
330
 
331
  /// Set map for Swift interfaces.
332
  void setSwiftInterfacesMap(swiftInterfacesMap *Map) {
333
    Options.ParseableSwiftInterfaces = Map;
334
  }
335
 
336
  /// Set prefix map for objects.
337
  void setObjectPrefixMap(objectPrefixMap *Map) {
338
    Options.ObjectPrefixMap = Map;
339
  }
340
 
341
  /// Set target DWARF version.
342
  Error setTargetDWARFVersion(uint16_t TargetDWARFVersion) {
343
    if (TargetDWARFVersion < 1 || TargetDWARFVersion > 5)
344
      return createStringError(std::errc::invalid_argument,
345
                               "unsupported DWARF version: %d",
346
                               TargetDWARFVersion);
347
 
348
    Options.TargetDWARFVersion = TargetDWARFVersion;
349
    return Error::success();
350
  }
351
 
352
private:
353
  /// Flags passed to DwarfLinker::lookForDIEsToKeep
354
  enum TraversalFlags {
355
    TF_Keep = 1 << 0,            ///< Mark the traversed DIEs as kept.
356
    TF_InFunctionScope = 1 << 1, ///< Current scope is a function scope.
357
    TF_DependencyWalk = 1 << 2,  ///< Walking the dependencies of a kept DIE.
358
    TF_ParentWalk = 1 << 3,      ///< Walking up the parents of a kept DIE.
359
    TF_ODR = 1 << 4,             ///< Use the ODR while keeping dependents.
360
    TF_SkipPC = 1 << 5,          ///< Skip all location attributes.
361
  };
362
 
363
  /// The  distinct types of work performed by the work loop.
364
  enum class WorklistItemType {
365
    /// Given a DIE, look for DIEs to be kept.
366
    LookForDIEsToKeep,
367
    /// Given a DIE, look for children of this DIE to be kept.
368
    LookForChildDIEsToKeep,
369
    /// Given a DIE, look for DIEs referencing this DIE to be kept.
370
    LookForRefDIEsToKeep,
371
    /// Given a DIE, look for parent DIEs to be kept.
372
    LookForParentDIEsToKeep,
373
    /// Given a DIE, update its incompleteness based on whether its children are
374
    /// incomplete.
375
    UpdateChildIncompleteness,
376
    /// Given a DIE, update its incompleteness based on whether the DIEs it
377
    /// references are incomplete.
378
    UpdateRefIncompleteness,
379
    /// Given a DIE, mark it as ODR Canonical if applicable.
380
    MarkODRCanonicalDie,
381
  };
382
 
383
  /// This class represents an item in the work list. The type defines what kind
384
  /// of work needs to be performed when processing the current item. The flags
385
  /// and info fields are optional based on the type.
386
  struct WorklistItem {
387
    DWARFDie Die;
388
    WorklistItemType Type;
389
    CompileUnit &CU;
390
    unsigned Flags;
391
    union {
392
      const unsigned AncestorIdx;
393
      CompileUnit::DIEInfo *OtherInfo;
394
    };
395
 
396
    WorklistItem(DWARFDie Die, CompileUnit &CU, unsigned Flags,
397
                 WorklistItemType T = WorklistItemType::LookForDIEsToKeep)
398
        : Die(Die), Type(T), CU(CU), Flags(Flags), AncestorIdx(0) {}
399
 
400
    WorklistItem(DWARFDie Die, CompileUnit &CU, WorklistItemType T,
401
                 CompileUnit::DIEInfo *OtherInfo = nullptr)
402
        : Die(Die), Type(T), CU(CU), Flags(0), OtherInfo(OtherInfo) {}
403
 
404
    WorklistItem(unsigned AncestorIdx, CompileUnit &CU, unsigned Flags)
405
        : Type(WorklistItemType::LookForParentDIEsToKeep), CU(CU), Flags(Flags),
406
          AncestorIdx(AncestorIdx) {}
407
  };
408
 
409
  /// Verify the given DWARF file.
410
  bool verify(const DWARFFile &File);
411
 
412
  /// returns true if we need to translate strings.
413
  bool needToTranslateStrings() { return StringsTranslator != nullptr; }
414
 
415
  void reportWarning(const Twine &Warning, const DWARFFile &File,
416
                     const DWARFDie *DIE = nullptr) const {
417
    if (Options.WarningHandler != nullptr)
418
      Options.WarningHandler(Warning, File.FileName, DIE);
419
  }
420
 
421
  void reportError(const Twine &Warning, const DWARFFile &File,
422
                   const DWARFDie *DIE = nullptr) const {
423
    if (Options.ErrorHandler != nullptr)
424
      Options.ErrorHandler(Warning, File.FileName, DIE);
425
  }
426
 
427
  /// Emit warnings as Dwarf compile units to leave a trail after linking.
428
  bool emitPaperTrailWarnings(const DWARFFile &File,
429
                              OffsetsStringPool &StringPool);
430
 
431
  void copyInvariantDebugSection(DWARFContext &Dwarf);
432
 
433
  /// Keep information for referenced clang module: already loaded DWARF info
434
  /// of the clang module and a CompileUnit of the module.
435
  struct RefModuleUnit {
436
    RefModuleUnit(DWARFFile &File, std::unique_ptr<CompileUnit> Unit)
437
        : File(File), Unit(std::move(Unit)) {}
438
    RefModuleUnit(RefModuleUnit &&Other)
439
        : File(Other.File), Unit(std::move(Other.Unit)) {}
440
    RefModuleUnit(const RefModuleUnit &) = delete;
441
 
442
    DWARFFile &File;
443
    std::unique_ptr<CompileUnit> Unit;
444
  };
445
  using ModuleUnitListTy = std::vector<RefModuleUnit>;
446
 
447
  /// Keeps track of data associated with one object during linking.
448
  struct LinkContext {
449
    DWARFFile &File;
450
    UnitListTy CompileUnits;
451
    ModuleUnitListTy ModuleUnits;
452
    bool Skip = false;
453
 
454
    LinkContext(DWARFFile &File) : File(File) {}
455
 
456
    /// Clear part of the context that's no longer needed when we're done with
457
    /// the debug object.
458
    void clear() {
459
      CompileUnits.clear();
460
      File.Addresses->clear();
461
    }
462
  };
463
 
464
  /// Called before emitting object data
465
  void cleanupAuxiliarryData(LinkContext &Context);
466
 
467
  /// Look at the parent of the given DIE and decide whether they should be
468
  /// kept.
469
  void lookForParentDIEsToKeep(unsigned AncestorIdx, CompileUnit &CU,
470
                               unsigned Flags,
471
                               SmallVectorImpl<WorklistItem> &Worklist);
472
 
473
  /// Look at the children of the given DIE and decide whether they should be
474
  /// kept.
475
  void lookForChildDIEsToKeep(const DWARFDie &Die, CompileUnit &CU,
476
                              unsigned Flags,
477
                              SmallVectorImpl<WorklistItem> &Worklist);
478
 
479
  /// Look at DIEs referenced by the given DIE and decide whether they should be
480
  /// kept. All DIEs referenced though attributes should be kept.
481
  void lookForRefDIEsToKeep(const DWARFDie &Die, CompileUnit &CU,
482
                            unsigned Flags, const UnitListTy &Units,
483
                            const DWARFFile &File,
484
                            SmallVectorImpl<WorklistItem> &Worklist);
485
 
486
  /// Mark context corresponding to the specified \p Die as having canonical
487
  /// die, if applicable.
488
  void markODRCanonicalDie(const DWARFDie &Die, CompileUnit &CU);
489
 
490
  /// \defgroup FindRootDIEs Find DIEs corresponding to Address map entries.
491
  ///
492
  /// @{
493
  /// Recursively walk the \p DIE tree and look for DIEs to
494
  /// keep. Store that information in \p CU's DIEInfo.
495
  ///
496
  /// The return value indicates whether the DIE is incomplete.
497
  void lookForDIEsToKeep(AddressesMap &RelocMgr, RangesTy &Ranges,
498
                         const UnitListTy &Units, const DWARFDie &DIE,
499
                         const DWARFFile &File, CompileUnit &CU,
500
                         unsigned Flags);
501
 
502
  /// Check whether specified \p CUDie is a Clang module reference.
503
  /// if \p Quiet is false then display error messages.
504
  /// \return first == true if CUDie is a Clang module reference.
505
  ///         second == true if module is already loaded.
506
  std::pair<bool, bool> isClangModuleRef(const DWARFDie &CUDie,
507
                                         std::string &PCMFile,
508
                                         LinkContext &Context, unsigned Indent,
509
                                         bool Quiet);
510
 
511
  /// If this compile unit is really a skeleton CU that points to a
512
  /// clang module, register it in ClangModules and return true.
513
  ///
514
  /// A skeleton CU is a CU without children, a DW_AT_gnu_dwo_name
515
  /// pointing to the module, and a DW_AT_gnu_dwo_id with the module
516
  /// hash.
517
  bool registerModuleReference(const DWARFDie &CUDie, LinkContext &Context,
518
                               objFileLoader Loader,
519
                               CompileUnitHandler OnCUDieLoaded,
520
                               unsigned Indent = 0);
521
 
522
  /// Recursively add the debug info in this clang module .pcm
523
  /// file (and all the modules imported by it in a bottom-up fashion)
524
  /// to ModuleUnits.
525
  Error loadClangModule(objFileLoader Loader, const DWARFDie &CUDie,
526
                        const std::string &PCMFile, LinkContext &Context,
527
                        CompileUnitHandler OnCUDieLoaded, unsigned Indent = 0);
528
 
529
  /// Clone specified Clang module unit \p Unit.
530
  Error cloneModuleUnit(LinkContext &Context, RefModuleUnit &Unit,
531
                        DeclContextTree &ODRContexts,
532
                        OffsetsStringPool &OffsetsStringPool,
533
                        unsigned Indent = 0);
534
 
535
  /// Mark the passed DIE as well as all the ones it depends on as kept.
536
  void keepDIEAndDependencies(AddressesMap &RelocMgr, RangesTy &Ranges,
537
                              const UnitListTy &Units, const DWARFDie &DIE,
538
                              CompileUnit::DIEInfo &MyInfo,
539
                              const DWARFFile &File, CompileUnit &CU,
540
                              bool UseODR);
541
 
542
  unsigned shouldKeepDIE(AddressesMap &RelocMgr, RangesTy &Ranges,
543
                         const DWARFDie &DIE, const DWARFFile &File,
544
                         CompileUnit &Unit, CompileUnit::DIEInfo &MyInfo,
545
                         unsigned Flags);
546
 
547
  /// Check if a variable describing DIE should be kept.
548
  /// \returns updated TraversalFlags.
549
  unsigned shouldKeepVariableDIE(AddressesMap &RelocMgr, const DWARFDie &DIE,
550
                                 CompileUnit::DIEInfo &MyInfo, unsigned Flags);
551
 
552
  unsigned shouldKeepSubprogramDIE(AddressesMap &RelocMgr, RangesTy &Ranges,
553
                                   const DWARFDie &DIE, const DWARFFile &File,
554
                                   CompileUnit &Unit,
555
                                   CompileUnit::DIEInfo &MyInfo,
556
                                   unsigned Flags);
557
 
558
  /// Resolve the DIE attribute reference that has been extracted in \p
559
  /// RefValue. The resulting DIE might be in another CompileUnit which is
560
  /// stored into \p ReferencedCU. \returns null if resolving fails for any
561
  /// reason.
562
  DWARFDie resolveDIEReference(const DWARFFile &File, const UnitListTy &Units,
563
                               const DWARFFormValue &RefValue,
564
                               const DWARFDie &DIE, CompileUnit *&RefCU);
565
 
566
  /// @}
567
 
568
  /// \defgroup Methods used to link the debug information
569
  ///
570
  /// @{
571
 
572
  struct DWARFLinkerOptions;
573
 
574
  class DIECloner {
575
    DWARFLinker &Linker;
576
    DwarfEmitter *Emitter;
577
    DWARFFile &ObjFile;
578
 
579
    /// Allocator used for all the DIEValue objects.
580
    BumpPtrAllocator &DIEAlloc;
581
 
582
    std::vector<std::unique_ptr<CompileUnit>> &CompileUnits;
583
 
584
    /// Keeps mapping from offset of the macro table to corresponding
585
    /// compile unit.
586
    Offset2UnitMap UnitMacroMap;
587
 
588
    bool Update;
589
 
590
  public:
591
    DIECloner(DWARFLinker &Linker, DwarfEmitter *Emitter, DWARFFile &ObjFile,
592
              BumpPtrAllocator &DIEAlloc,
593
              std::vector<std::unique_ptr<CompileUnit>> &CompileUnits,
594
              bool Update)
595
        : Linker(Linker), Emitter(Emitter), ObjFile(ObjFile),
596
          DIEAlloc(DIEAlloc), CompileUnits(CompileUnits), Update(Update) {}
597
 
598
    /// Recursively clone \p InputDIE into an tree of DIE objects
599
    /// where useless (as decided by lookForDIEsToKeep()) bits have been
600
    /// stripped out and addresses have been rewritten according to the
601
    /// address map.
602
    ///
603
    /// \param OutOffset is the offset the cloned DIE in the output
604
    /// compile unit.
605
    /// \param PCOffset (while cloning a function scope) is the offset
606
    /// applied to the entry point of the function to get the linked address.
607
    /// \param Die the output DIE to use, pass NULL to create one.
608
    /// \returns the root of the cloned tree or null if nothing was selected.
609
    DIE *cloneDIE(const DWARFDie &InputDIE, const DWARFFile &File,
610
                  CompileUnit &U, OffsetsStringPool &StringPool,
611
                  int64_t PCOffset, uint32_t OutOffset, unsigned Flags,
612
                  bool IsLittleEndian, DIE *Die = nullptr);
613
 
614
    /// Construct the output DIE tree by cloning the DIEs we
615
    /// chose to keep above. If there are no valid relocs, then there's
616
    /// nothing to clone/emit.
617
    uint64_t cloneAllCompileUnits(DWARFContext &DwarfContext,
618
                                  const DWARFFile &File,
619
                                  OffsetsStringPool &StringPool,
620
                                  bool IsLittleEndian);
621
 
622
  private:
623
    using AttributeSpec = DWARFAbbreviationDeclaration::AttributeSpec;
624
 
625
    /// Information gathered and exchanged between the various
626
    /// clone*Attributes helpers about the attributes of a particular DIE.
627
    struct AttributesInfo {
628
      /// Names.
629
      DwarfStringPoolEntryRef Name, MangledName, NameWithoutTemplate;
630
 
631
      /// Offsets in the string pool.
632
      uint32_t NameOffset = 0;
633
      uint32_t MangledNameOffset = 0;
634
 
635
      /// Value of AT_low_pc in the input DIE
636
      uint64_t OrigLowPc = std::numeric_limits<uint64_t>::max();
637
 
638
      /// Value of AT_high_pc in the input DIE
639
      uint64_t OrigHighPc = 0;
640
 
641
      /// Value of DW_AT_call_return_pc in the input DIE
642
      uint64_t OrigCallReturnPc = 0;
643
 
644
      /// Value of DW_AT_call_pc in the input DIE
645
      uint64_t OrigCallPc = 0;
646
 
647
      /// Offset to apply to PC addresses inside a function.
648
      int64_t PCOffset = 0;
649
 
650
      /// Does the DIE have a low_pc attribute?
651
      bool HasLowPc = false;
652
 
653
      /// Does the DIE have a ranges attribute?
654
      bool HasRanges = false;
655
 
656
      /// Is this DIE only a declaration?
657
      bool IsDeclaration = false;
658
 
659
      AttributesInfo() = default;
660
    };
661
 
662
    /// Helper for cloneDIE.
663
    unsigned cloneAttribute(DIE &Die, const DWARFDie &InputDIE,
664
                            const DWARFFile &File, CompileUnit &U,
665
                            OffsetsStringPool &StringPool,
666
                            const DWARFFormValue &Val,
667
                            const AttributeSpec AttrSpec, unsigned AttrSize,
668
                            AttributesInfo &AttrInfo, bool IsLittleEndian);
669
 
670
    /// Clone a string attribute described by \p AttrSpec and add
671
    /// it to \p Die.
672
    /// \returns the size of the new attribute.
673
    unsigned cloneStringAttribute(DIE &Die, AttributeSpec AttrSpec,
674
                                  const DWARFFormValue &Val, const DWARFUnit &U,
675
                                  OffsetsStringPool &StringPool,
676
                                  AttributesInfo &Info);
677
 
678
    /// Clone an attribute referencing another DIE and add
679
    /// it to \p Die.
680
    /// \returns the size of the new attribute.
681
    unsigned cloneDieReferenceAttribute(DIE &Die, const DWARFDie &InputDIE,
682
                                        AttributeSpec AttrSpec,
683
                                        unsigned AttrSize,
684
                                        const DWARFFormValue &Val,
685
                                        const DWARFFile &File,
686
                                        CompileUnit &Unit);
687
 
688
    /// Clone a DWARF expression that may be referencing another DIE.
689
    void cloneExpression(DataExtractor &Data, DWARFExpression Expression,
690
                         const DWARFFile &File, CompileUnit &Unit,
691
                         SmallVectorImpl<uint8_t> &OutputBuffer);
692
 
693
    /// Clone an attribute referencing another DIE and add
694
    /// it to \p Die.
695
    /// \returns the size of the new attribute.
696
    unsigned cloneBlockAttribute(DIE &Die, const DWARFFile &File,
697
                                 CompileUnit &Unit, AttributeSpec AttrSpec,
698
                                 const DWARFFormValue &Val, unsigned AttrSize,
699
                                 bool IsLittleEndian);
700
 
701
    /// Clone an attribute referencing another DIE and add
702
    /// it to \p Die.
703
    /// \returns the size of the new attribute.
704
    unsigned cloneAddressAttribute(DIE &Die, AttributeSpec AttrSpec,
705
                                   unsigned AttrSize, const DWARFFormValue &Val,
706
                                   const CompileUnit &Unit,
707
                                   AttributesInfo &Info);
708
 
709
    /// Clone a scalar attribute  and add it to \p Die.
710
    /// \returns the size of the new attribute.
711
    unsigned cloneScalarAttribute(DIE &Die, const DWARFDie &InputDIE,
712
                                  const DWARFFile &File, CompileUnit &U,
713
                                  AttributeSpec AttrSpec,
714
                                  const DWARFFormValue &Val, unsigned AttrSize,
715
                                  AttributesInfo &Info);
716
 
717
    /// Get the potential name and mangled name for the entity
718
    /// described by \p Die and store them in \Info if they are not
719
    /// already there.
720
    /// \returns is a name was found.
721
    bool getDIENames(const DWARFDie &Die, AttributesInfo &Info,
722
                     OffsetsStringPool &StringPool, bool StripTemplate = false);
723
 
724
    uint32_t hashFullyQualifiedName(DWARFDie DIE, CompileUnit &U,
725
                                    const DWARFFile &File,
726
                                    int RecurseDepth = 0);
727
 
728
    /// Helper for cloneDIE.
729
    void addObjCAccelerator(CompileUnit &Unit, const DIE *Die,
730
                            DwarfStringPoolEntryRef Name,
731
                            OffsetsStringPool &StringPool, bool SkipPubSection);
732
 
733
    void rememberUnitForMacroOffset(CompileUnit &Unit);
734
  };
735
 
736
  /// Assign an abbreviation number to \p Abbrev
737
  void assignAbbrev(DIEAbbrev &Abbrev);
738
 
739
  /// Compute and emit .debug_ranges section for \p Unit, and
740
  /// patch the attributes referencing it.
741
  void patchRangesForUnit(const CompileUnit &Unit, DWARFContext &Dwarf,
742
                          const DWARFFile &File) const;
743
 
744
  /// Generate and emit the DW_AT_ranges attribute for a compile_unit if it had
745
  /// one.
746
  void generateUnitRanges(CompileUnit &Unit) const;
747
 
748
  /// Extract the line tables from the original dwarf, extract the relevant
749
  /// parts according to the linked function ranges and emit the result in the
750
  /// .debug_line section.
751
  void patchLineTableForUnit(CompileUnit &Unit, DWARFContext &OrigDwarf,
752
                             const DWARFFile &File);
753
 
754
  /// Emit the accelerator entries for \p Unit.
755
  void emitAcceleratorEntriesForUnit(CompileUnit &Unit);
756
 
757
  /// Patch the frame info for an object file and emit it.
758
  void patchFrameInfoForObject(const DWARFFile &, RangesTy &Ranges,
759
                               DWARFContext &, unsigned AddressSize);
760
 
761
  /// FoldingSet that uniques the abbreviations.
762
  FoldingSet<DIEAbbrev> AbbreviationsSet;
763
 
764
  /// Storage for the unique Abbreviations.
765
  /// This is passed to AsmPrinter::emitDwarfAbbrevs(), thus it cannot be
766
  /// changed to a vector of unique_ptrs.
767
  std::vector<std::unique_ptr<DIEAbbrev>> Abbreviations;
768
 
769
  /// DIELoc objects that need to be destructed (but not freed!).
770
  std::vector<DIELoc *> DIELocs;
771
 
772
  /// DIEBlock objects that need to be destructed (but not freed!).
773
  std::vector<DIEBlock *> DIEBlocks;
774
 
775
  /// Allocator used for all the DIEValue objects.
776
  BumpPtrAllocator DIEAlloc;
777
  /// @}
778
 
779
  DwarfEmitter *TheDwarfEmitter;
780
  std::vector<LinkContext> ObjectContexts;
781
 
782
  /// The CIEs that have been emitted in the output section. The actual CIE
783
  /// data serves a the key to this StringMap, this takes care of comparing the
784
  /// semantics of CIEs defined in different object files.
785
  StringMap<uint32_t> EmittedCIEs;
786
 
787
  /// Offset of the last CIE that has been emitted in the output
788
  /// .debug_frame section.
789
  uint32_t LastCIEOffset = 0;
790
 
791
  /// Apple accelerator tables.
792
  AccelTable<DWARF5AccelTableStaticData> DebugNames;
793
  AccelTable<AppleAccelTableStaticOffsetData> AppleNames;
794
  AccelTable<AppleAccelTableStaticOffsetData> AppleNamespaces;
795
  AccelTable<AppleAccelTableStaticOffsetData> AppleObjc;
796
  AccelTable<AppleAccelTableStaticTypeData> AppleTypes;
797
 
798
  /// Mapping the PCM filename to the DwoId.
799
  StringMap<uint64_t> ClangModules;
800
 
801
  DwarfLinkerClient DwarfLinkerClientID;
802
 
803
  std::function<StringRef(StringRef)> StringsTranslator = nullptr;
804
 
805
  /// A unique ID that identifies each compile unit.
806
  unsigned UniqueUnitID = 0;
807
 
808
  /// linking options
809
  struct DWARFLinkerOptions {
810
    /// DWARF version for the output.
811
    uint16_t TargetDWARFVersion = 0;
812
 
813
    /// Generate processing log to the standard output.
814
    bool Verbose = false;
815
 
816
    /// Print statistics.
817
    bool Statistics = false;
818
 
819
    /// Verify the input DWARF.
820
    bool VerifyInputDWARF = false;
821
 
822
    /// Skip emitting output
823
    bool NoOutput = false;
824
 
825
    /// Do not unique types according to ODR
826
    bool NoODR = false;
827
 
828
    /// Update
829
    bool Update = false;
830
 
831
    /// Whether we want a static variable to force us to keep its enclosing
832
    /// function.
833
    bool KeepFunctionForStatic = false;
834
 
835
    /// Number of threads.
836
    unsigned Threads = 1;
837
 
838
    /// The accelerator table kinds
839
    SmallVector<DwarfLinkerAccelTableKind, 1> AccelTables;
840
 
841
    /// Prepend path for the clang modules.
842
    std::string PrependPath;
843
 
844
    // warning handler
845
    messageHandler WarningHandler = nullptr;
846
 
847
    // error handler
848
    messageHandler ErrorHandler = nullptr;
849
 
850
    /// A list of all .swiftinterface files referenced by the debug
851
    /// info, mapping Module name to path on disk. The entries need to
852
    /// be uniqued and sorted and there are only few entries expected
853
    /// per compile unit, which is why this is a std::map.
854
    /// this is dsymutil specific fag.
855
    swiftInterfacesMap *ParseableSwiftInterfaces = nullptr;
856
 
857
    /// A list of remappings to apply to file paths.
858
    objectPrefixMap *ObjectPrefixMap = nullptr;
859
  } Options;
860
};
861
 
862
} // end namespace llvm
863
 
864
#endif // LLVM_DWARFLINKER_DWARFLINKER_H