Coverage Report

Created: 2017-09-19 22:28

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/lld/include/lld/ReaderWriter/MachOLinkingContext.h
Line
Count
Source (jump to first uncovered line)
1
//===- lld/ReaderWriter/MachOLinkingContext.h -----------------------------===//
2
//
3
//                             The LLVM Linker
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
10
#ifndef LLD_READER_WRITER_MACHO_LINKING_CONTEXT_H
11
#define LLD_READER_WRITER_MACHO_LINKING_CONTEXT_H
12
13
#include "lld/Core/LinkingContext.h"
14
#include "lld/Core/Reader.h"
15
#include "lld/Core/Writer.h"
16
#include "llvm/ADT/STLExtras.h"
17
#include "llvm/ADT/StringMap.h"
18
#include "llvm/ADT/StringSet.h"
19
#include "llvm/BinaryFormat/MachO.h"
20
#include "llvm/Support/ErrorHandling.h"
21
#include <set>
22
23
using llvm::MachO::HeaderFileType;
24
25
namespace lld {
26
27
namespace mach_o {
28
class ArchHandler;
29
class MachODylibFile;
30
class MachOFile;
31
class SectCreateFile;
32
}
33
34
class MachOLinkingContext : public LinkingContext {
35
public:
36
  MachOLinkingContext();
37
  ~MachOLinkingContext() override;
38
39
  enum Arch {
40
    arch_unknown,
41
    arch_ppc,
42
    arch_x86,
43
    arch_x86_64,
44
    arch_armv6,
45
    arch_armv7,
46
    arch_armv7s,
47
    arch_arm64,
48
  };
49
50
  enum class OS {
51
    unknown,
52
    macOSX,
53
    iOS,
54
    iOS_simulator
55
  };
56
57
  enum class ExportMode {
58
    globals,    // Default, all global symbols exported.
59
    whiteList,  // -exported_symbol[s_list], only listed symbols exported.
60
    blackList   // -unexported_symbol[s_list], no listed symbol exported.
61
  };
62
63
  enum class DebugInfoMode {
64
    addDebugMap,    // Default
65
    noDebugMap      // -S option
66
  };
67
68
  enum class UndefinedMode {
69
    error,
70
    warning,
71
    suppress,
72
    dynamicLookup
73
  };
74
75
  enum ObjCConstraint {
76
    objc_unknown = 0,
77
    objc_supports_gc = 2,
78
    objc_gc_only = 4,
79
    // Image optimized by dyld = 8
80
    // GC compaction = 16
81
    objc_retainReleaseForSimulator = 32,
82
    objc_retainRelease
83
  };
84
85
  /// Initializes the context to sane default values given the specified output
86
  /// file type, arch, os, and minimum os version.  This should be called before
87
  /// other setXXX() methods.
88
  void configure(HeaderFileType type, Arch arch, OS os, uint32_t minOSVersion,
89
                 bool exportDynamicSymbols);
90
91
  void addPasses(PassManager &pm) override;
92
  bool validateImpl(raw_ostream &diagnostics) override;
93
  std::string demangle(StringRef symbolName) const override;
94
95
  void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override;
96
97
  /// Creates a new file which is owned by the context.  Returns a pointer to
98
  /// the new file.
99
  template <class T, class... Args>
100
  typename std::enable_if<!std::is_array<T>::value, T *>::type
101
372
  make_file(Args &&... args) const {
102
372
    auto file = std::unique_ptr<T>(new T(std::forward<Args>(args)...));
103
372
    auto *filePtr = file.get();
104
372
    auto *ctx = const_cast<MachOLinkingContext *>(this);
105
372
    ctx->getNodes().push_back(llvm::make_unique<FileNode>(std::move(file)));
106
372
    return filePtr;
107
372
  }
std::__1::enable_if<!(std::is_array<lld::mach_o::MachOFile>::value), lld::mach_o::MachOFile*>::type lld::MachOLinkingContext::make_file<lld::mach_o::MachOFile, char const (&) [29]>(char const (&&&) [29]) const
Line
Count
Source
101
86
  make_file(Args &&... args) const {
102
86
    auto file = std::unique_ptr<T>(new T(std::forward<Args>(args)...));
103
86
    auto *filePtr = file.get();
104
86
    auto *ctx = const_cast<MachOLinkingContext *>(this);
105
86
    ctx->getNodes().push_back(llvm::make_unique<FileNode>(std::move(file)));
106
86
    return filePtr;
107
86
  }
std::__1::enable_if<!(std::is_array<lld::mach_o::MachOFile>::value), lld::mach_o::MachOFile*>::type lld::MachOLinkingContext::make_file<lld::mach_o::MachOFile, char const (&) [18]>(char const (&&&) [18]) const
Line
Count
Source
101
182
  make_file(Args &&... args) const {
102
182
    auto file = std::unique_ptr<T>(new T(std::forward<Args>(args)...));
103
182
    auto *filePtr = file.get();
104
182
    auto *ctx = const_cast<MachOLinkingContext *>(this);
105
182
    ctx->getNodes().push_back(llvm::make_unique<FileNode>(std::move(file)));
106
182
    return filePtr;
107
182
  }
std::__1::enable_if<!(std::is_array<lld::mach_o::MachOFile>::value), lld::mach_o::MachOFile*>::type lld::MachOLinkingContext::make_file<lld::mach_o::MachOFile, char const (&) [19]>(char const (&&&) [19]) const
Line
Count
Source
101
8
  make_file(Args &&... args) const {
102
8
    auto file = std::unique_ptr<T>(new T(std::forward<Args>(args)...));
103
8
    auto *filePtr = file.get();
104
8
    auto *ctx = const_cast<MachOLinkingContext *>(this);
105
8
    ctx->getNodes().push_back(llvm::make_unique<FileNode>(std::move(file)));
106
8
    return filePtr;
107
8
  }
std::__1::enable_if<!(std::is_array<lld::mach_o::MachOFile>::value), lld::mach_o::MachOFile*>::type lld::MachOLinkingContext::make_file<lld::mach_o::MachOFile, char const (&) [20]>(char const (&&&) [20]) const
Line
Count
Source
101
96
  make_file(Args &&... args) const {
102
96
    auto file = std::unique_ptr<T>(new T(std::forward<Args>(args)...));
103
96
    auto *filePtr = file.get();
104
96
    auto *ctx = const_cast<MachOLinkingContext *>(this);
105
96
    ctx->getNodes().push_back(llvm::make_unique<FileNode>(std::move(file)));
106
96
    return filePtr;
107
96
  }
108
109
  uint32_t getCPUType() const;
110
  uint32_t getCPUSubType() const;
111
112
  bool addEntryPointLoadCommand() const;
113
  bool addUnixThreadLoadCommand() const;
114
  bool outputTypeHasEntry() const;
115
  bool is64Bit() const;
116
117
54
  virtual uint64_t pageZeroSize() const { return _pageZeroSize; }
118
1.21k
  virtual uint64_t pageSize() const { return _pageSize; }
119
120
  mach_o::ArchHandler &archHandler() const;
121
122
3.52k
  HeaderFileType outputMachOType() const { return _outputMachOType; }
123
124
514
  Arch arch() const { return _arch; }
125
3
  StringRef archName() const { return nameFromArch(_arch); }
126
726
  OS os() const { return _os; }
127
128
80
  ExportMode exportMode() const { return _exportMode; }
129
11
  void setExportMode(ExportMode mode) { _exportMode = mode; }
130
  void addExportSymbol(StringRef sym);
131
498
  bool exportRestrictMode() const { return _exportMode != ExportMode::globals; }
132
  bool exportSymbolNamed(StringRef sym) const;
133
134
167
  DebugInfoMode debugInfoMode() const { return _debugInfoMode; }
135
0
  void setDebugInfoMode(DebugInfoMode mode) {
136
0
    _debugInfoMode = mode;
137
0
  }
138
139
  void appendOrderedSymbol(StringRef symbol, StringRef filename);
140
141
17
  bool keepPrivateExterns() const { return _keepPrivateExterns; }
142
2
  void setKeepPrivateExterns(bool v) { _keepPrivateExterns = v; }
143
8
  bool demangleSymbols() const { return _demangle; }
144
1
  void setDemangleSymbols(bool d) { _demangle = d; }
145
0
  bool mergeObjCCategories() const { return _mergeObjCCategories; }
146
0
  void setMergeObjCCategories(bool v) { _mergeObjCCategories = v; }
147
  /// Create file at specified path which will contain a binary encoding
148
  /// of all input and output file paths.
149
  std::error_code createDependencyFile(StringRef path);
150
  void addInputFileDependency(StringRef path) const;
151
  void addInputFileNotFound(StringRef path) const;
152
  void addOutputFileDependency(StringRef path) const;
153
154
  bool minOS(StringRef mac, StringRef iOS) const;
155
11
  void setDoNothing(bool value) { _doNothing = value; }
156
426
  bool doNothing() const { return _doNothing; }
157
166
  bool printAtoms() const { return _printAtoms; }
158
28
  bool testingFileUsage() const { return _testingFileUsage; }
159
24
  const StringRefVector &searchDirs() const { return _searchDirs; }
160
15
  const StringRefVector &frameworkDirs() const { return _frameworkDirs; }
161
  void setSysLibRoots(const StringRefVector &paths);
162
0
  const StringRefVector &sysLibRoots() const { return _syslibRoots; }
163
51
  bool PIE() const { return _pie; }
164
2
  void setPIE(bool pie) { _pie = pie; }
165
396
  bool generateVersionLoadCommand() const {
166
396
    return _generateVersionLoadCommand;
167
396
  }
168
220
  void setGenerateVersionLoadCommand(bool v) {
169
220
    _generateVersionLoadCommand = v;
170
220
  }
171
172
166
  bool generateFunctionStartsLoadCommand() const {
173
166
    return _generateFunctionStartsLoadCommand;
174
166
  }
175
220
  void setGenerateFunctionStartsLoadCommand(bool v) {
176
220
    _generateFunctionStartsLoadCommand = v;
177
220
  }
178
179
333
  bool generateDataInCodeLoadCommand() const {
180
333
    return _generateDataInCodeLoadCommand;
181
333
  }
182
219
  void setGenerateDataInCodeLoadCommand(bool v) {
183
219
    _generateDataInCodeLoadCommand = v;
184
219
  }
185
186
167
  uint64_t stackSize() const { return _stackSize; }
187
1
  void setStackSize(uint64_t stackSize) { _stackSize = stackSize; }
188
189
1.21k
  uint64_t baseAddress() const { return _baseAddress; }
190
1
  void setBaseAddress(uint64_t baseAddress) { _baseAddress = baseAddress; }
191
192
2
  ObjCConstraint objcConstraint() const { return _objcConstraint; }
193
194
296
  uint32_t osMinVersion() const { return _osMinVersion; }
195
196
167
  uint32_t sdkVersion() const { return _sdkVersion; }
197
130
  void setSdkVersion(uint64_t v) { _sdkVersion = v; }
198
199
167
  uint64_t sourceVersion() const { return _sourceVersion; }
200
1
  void setSourceVersion(uint64_t v) { _sourceVersion = v; }
201
202
2
  uint32_t swiftVersion() const { return _swiftVersion; }
203
204
  /// \brief Checks whether a given path on the filesystem exists.
205
  ///
206
  /// When running in -test_file_usage mode, this method consults an
207
  /// internally maintained list of files that exist (provided by -path_exists)
208
  /// instead of the actual filesystem.
209
  bool pathExists(StringRef path) const;
210
211
  /// Like pathExists() but only used on files - not directories.
212
  bool fileExists(StringRef path) const;
213
214
  /// \brief Adds any library search paths derived from the given base, possibly
215
  /// modified by -syslibroots.
216
  ///
217
  /// The set of paths added consists of approximately all syslibroot-prepended
218
  /// versions of libPath that exist, or the original libPath if there are none
219
  /// for whatever reason. With various edge-cases for compatibility.
220
  void addModifiedSearchDir(StringRef libPath, bool isSystemPath = false);
221
222
  /// \brief Determine whether -lFoo can be resolve within the given path, and
223
  /// return the filename if so.
224
  ///
225
  /// The -lFoo option is documented to search for libFoo.dylib and libFoo.a in
226
  /// that order, unless Foo ends in ".o", in which case only the exact file
227
  /// matches (e.g. -lfoo.o would only find foo.o).
228
  llvm::Optional<StringRef> searchDirForLibrary(StringRef path,
229
                                                StringRef libName) const;
230
231
  /// \brief Iterates through all search path entries looking for libName (as
232
  /// specified by -lFoo).
233
  llvm::Optional<StringRef> searchLibrary(StringRef libName) const;
234
235
  /// Add a framework search path.  Internally, this method may be prepended
236
  /// the path with syslibroot.
237
  void addFrameworkSearchDir(StringRef fwPath, bool isSystemPath = false);
238
239
  /// \brief Iterates through all framework directories looking for
240
  /// Foo.framework/Foo (when fwName = "Foo").
241
  llvm::Optional<StringRef> findPathForFramework(StringRef fwName) const;
242
243
  /// \brief The dylib's binary compatibility version, in the raw uint32 format.
244
  ///
245
  /// When building a dynamic library, this is the compatibility version that
246
  /// gets embedded into the result. Other Mach-O binaries that link against
247
  /// this library will store the compatibility version in its load command. At
248
  /// runtime, the loader will verify that the binary is compatible with the
249
  /// installed dynamic library.
250
168
  uint32_t compatibilityVersion() const { return _compatibilityVersion; }
251
252
  /// \brief The dylib's current version, in the the raw uint32 format.
253
  ///
254
  /// When building a dynamic library, this is the current version that gets
255
  /// embedded into the result. Other Mach-O binaries that link against
256
  /// this library will store the compatibility version in its load command.
257
168
  uint32_t currentVersion() const { return _currentVersion; }
258
259
  /// \brief The dylib's install name.
260
  ///
261
  /// Binaries that link against the dylib will embed this path into the dylib
262
  /// load command. When loading the binaries at runtime, this is the location
263
  /// on disk that the loader will look for the dylib.
264
167
  StringRef installName() const { return _installName; }
265
266
  /// \brief Whether or not the dylib has side effects during initialization.
267
  ///
268
  /// Dylibs marked as being dead strippable provide the guarantee that loading
269
  /// the dylib has no side effects, allowing the linker to strip out the dylib
270
  /// when linking a binary that does not use any of its symbols.
271
0
  bool deadStrippableDylib() const { return _deadStrippableDylib; }
272
273
  /// \brief Whether or not to use flat namespace.
274
  ///
275
  /// MachO usually uses a two-level namespace, where each external symbol
276
  /// referenced by the target is associated with the dylib that will provide
277
  /// the symbol's definition at runtime. Using flat namespace overrides this
278
  /// behavior: the linker searches all dylibs on the command line and all
279
  /// dylibs those original dylibs depend on, but does not record which dylib
280
  /// an external symbol came from. At runtime dyld again searches all images
281
  /// and uses the first definition it finds. In addition, any undefines in
282
  /// loaded flat_namespace dylibs must be resolvable at build time.
283
342
  bool useFlatNamespace() const { return _flatNamespace; }
284
285
  /// \brief How to handle undefined symbols.
286
  ///
287
  /// Options are:
288
  ///  * error: Report an error and terminate linking.
289
  ///  * warning: Report a warning, but continue linking.
290
  ///  * suppress: Ignore and continue linking.
291
  ///  * dynamic_lookup: For use with -twolevel namespace: Records source dylibs
292
  ///    for symbols that are defined in a linked dylib at static link time.
293
  ///    Undefined symbols are handled by searching all loaded images at
294
  ///    runtime.
295
182
  UndefinedMode undefinedMode() const { return _undefinedMode; }
296
297
  /// \brief The path to the executable that will load the bundle at runtime.
298
  ///
299
  /// When building a Mach-O bundle, this executable will be examined if there
300
  /// are undefined symbols after the main link phase. It is expected that this
301
  /// binary will be loading the bundle at runtime and will provide the symbols
302
  /// at that point.
303
0
  StringRef bundleLoader() const { return _bundleLoader; }
304
305
4
  void setCompatibilityVersion(uint32_t vers) { _compatibilityVersion = vers; }
306
4
  void setCurrentVersion(uint32_t vers) { _currentVersion = vers; }
307
238
  void setInstallName(StringRef name) { _installName = name; }
308
2
  void setDeadStrippableDylib(bool deadStrippable) {
309
2
    _deadStrippableDylib = deadStrippable;
310
2
  }
311
2
  void setUseFlatNamespace(bool flatNamespace) {
312
2
    _flatNamespace = flatNamespace;
313
2
  }
314
315
3
  void setUndefinedMode(UndefinedMode undefinedMode) {
316
3
    _undefinedMode = undefinedMode;
317
3
  }
318
319
2
  void setBundleLoader(StringRef loader) { _bundleLoader = loader; }
320
61
  void setPrintAtoms(bool value=true) { _printAtoms = value; }
321
11
  void setTestingFileUsage(bool value = true) {
322
11
    _testingFileUsage = value;
323
11
  }
324
65
  void addExistingPathForDebug(StringRef path) {
325
65
    _existingPaths.insert(path);
326
65
  }
327
328
  void addRpath(StringRef rpath);
329
167
  const StringRefVector &rpaths() const { return _rpaths; }
330
331
  /// Add section alignment constraint on final layout.
332
  void addSectionAlignment(StringRef seg, StringRef sect, uint16_t align);
333
334
  /// \brief Add a section based on a command-line sectcreate option.
335
  void addSectCreateSection(StringRef seg, StringRef sect,
336
                            std::unique_ptr<MemoryBuffer> content);
337
338
  /// Returns true if specified section had alignment constraints.
339
  bool sectionAligned(StringRef seg, StringRef sect, uint16_t &align) const;
340
341
0
  StringRef dyldPath() const { return "/usr/lib/dyld"; }
342
343
  /// Stub creation Pass should be run.
344
  bool needsStubsPass() const;
345
346
  // GOT creation Pass should be run.
347
  bool needsGOTPass() const;
348
349
  /// Pass to add TLV sections.
350
  bool needsTLVPass() const;
351
352
  /// Pass to transform __compact_unwind into __unwind_info should be run.
353
  bool needsCompactUnwindPass() const;
354
355
  /// Pass to add shims switching between thumb and arm mode.
356
  bool needsShimPass() const;
357
358
  /// Pass to add objc image info and optimized objc data.
359
  bool needsObjCPass() const;
360
361
  /// Magic symbol name stubs will need to help lazy bind.
362
  StringRef binderSymbolName() const;
363
364
  /// Used to keep track of direct and indirect dylibs.
365
  void registerDylib(mach_o::MachODylibFile *dylib, bool upward) const;
366
367
  // Reads a file from disk to memory. Returns only a needed chunk
368
  // if a fat binary.
369
  ErrorOr<std::unique_ptr<MemoryBuffer>> getMemoryBuffer(StringRef path);
370
371
  /// Used to find indirect dylibs. Instantiates a MachODylibFile if one
372
  /// has not already been made for the requested dylib.  Uses -L and -F
373
  /// search paths to allow indirect dylibs to be overridden.
374
  mach_o::MachODylibFile* findIndirectDylib(StringRef path);
375
376
  uint32_t dylibCurrentVersion(StringRef installName) const;
377
378
  uint32_t dylibCompatVersion(StringRef installName) const;
379
380
167
  ArrayRef<mach_o::MachODylibFile*> allDylibs() const {
381
167
    return _allDylibs;
382
167
  }
383
384
  /// Creates a copy (owned by this MachOLinkingContext) of a string.
385
9
  StringRef copy(StringRef str) { return str.copy(_allocator); }
386
387
  /// If the memoryBuffer is a fat file with a slice for the current arch,
388
  /// this method will return the offset and size of that slice.
389
  bool sliceFromFatFile(MemoryBufferRef mb, uint32_t &offset, uint32_t &size);
390
391
  /// Returns if a command line option specified dylib is an upward link.
392
  bool isUpwardDylib(StringRef installName) const;
393
394
  static bool isThinObjectFile(StringRef path, Arch &arch);
395
  static Arch archFromCpuType(uint32_t cputype, uint32_t cpusubtype);
396
  static Arch archFromName(StringRef archName);
397
  static StringRef nameFromArch(Arch arch);
398
  static uint32_t cpuTypeFromArch(Arch arch);
399
  static uint32_t cpuSubtypeFromArch(Arch arch);
400
  static bool is64Bit(Arch arch);
401
  static bool isHostEndian(Arch arch);
402
  static bool isBigEndian(Arch arch);
403
404
  /// Construct 32-bit value from string "X.Y.Z" where
405
  /// bits are xxxx.yy.zz.  Largest number is 65535.255.255
406
  static bool parsePackedVersion(StringRef str, uint32_t &result);
407
408
  /// Construct 64-bit value from string "A.B.C.D.E" where
409
  /// bits are aaaa.bb.cc.dd.ee.  Largest number is 16777215.1023.1023.1023.1023
410
  static bool parsePackedVersion(StringRef str, uint64_t &result);
411
412
  void finalizeInputFiles() override;
413
414
  llvm::Error handleLoadedFile(File &file) override;
415
416
  bool customAtomOrderer(const DefinedAtom *left, const DefinedAtom *right,
417
                         bool &leftBeforeRight) const;
418
419
  /// Return the 'flat namespace' file. This is the file that supplies
420
  /// atoms for otherwise undefined symbols when the -flat_namespace or
421
  /// -undefined dynamic_lookup options are used.
422
110
  File* flatNamespaceFile() const { return _flatNamespaceFile; }
423
424
private:
425
  Writer &writer() const override;
426
  mach_o::MachODylibFile* loadIndirectDylib(StringRef path);
427
  void checkExportWhiteList(const DefinedAtom *atom) const;
428
  void checkExportBlackList(const DefinedAtom *atom) const;
429
  struct ArchInfo {
430
    StringRef                 archName;
431
    MachOLinkingContext::Arch arch;
432
    bool                      littleEndian;
433
    uint32_t                  cputype;
434
    uint32_t                  cpusubtype;
435
  };
436
437
  struct SectionAlign {
438
    StringRef segmentName;
439
    StringRef sectionName;
440
    uint16_t  align;
441
  };
442
443
  struct OrderFileNode {
444
    StringRef fileFilter;
445
    unsigned  order;
446
  };
447
448
  static bool findOrderOrdinal(const std::vector<OrderFileNode> &nodes,
449
                             const DefinedAtom *atom, unsigned &ordinal);
450
451
  static ArchInfo _s_archInfos[];
452
453
  std::set<StringRef> _existingPaths; // For testing only.
454
  StringRefVector _searchDirs;
455
  StringRefVector _syslibRoots;
456
  StringRefVector _frameworkDirs;
457
  HeaderFileType _outputMachOType = llvm::MachO::MH_EXECUTE;
458
  bool _outputMachOTypeStatic = false; // Disambiguate static vs dynamic prog
459
  bool _doNothing = false;             // for -help and -v which just print info
460
  bool _pie = false;
461
  Arch _arch = arch_unknown;
462
  OS _os = OS::macOSX;
463
  uint32_t _osMinVersion = 0;
464
  uint32_t _sdkVersion = 0;
465
  uint64_t _sourceVersion = 0;
466
  uint64_t _pageZeroSize = 0;
467
  uint64_t _pageSize = 4096;
468
  uint64_t _baseAddress = 0;
469
  uint64_t _stackSize = 0;
470
  uint32_t _compatibilityVersion = 0;
471
  uint32_t _currentVersion = 0;
472
  ObjCConstraint _objcConstraint = objc_unknown;
473
  uint32_t _swiftVersion = 0;
474
  StringRef _installName;
475
  StringRefVector _rpaths;
476
  bool _flatNamespace = false;
477
  UndefinedMode _undefinedMode = UndefinedMode::error;
478
  bool _deadStrippableDylib = false;
479
  bool _printAtoms = false;
480
  bool _testingFileUsage = false;
481
  bool _keepPrivateExterns = false;
482
  bool _demangle = false;
483
  bool _mergeObjCCategories = true;
484
  bool _generateVersionLoadCommand = false;
485
  bool _generateFunctionStartsLoadCommand = false;
486
  bool _generateDataInCodeLoadCommand = false;
487
  StringRef _bundleLoader;
488
  mutable std::unique_ptr<mach_o::ArchHandler> _archHandler;
489
  mutable std::unique_ptr<Writer> _writer;
490
  std::vector<SectionAlign> _sectAligns;
491
  mutable llvm::StringMap<mach_o::MachODylibFile*> _pathToDylibMap;
492
  mutable std::vector<mach_o::MachODylibFile*> _allDylibs;
493
  mutable std::set<mach_o::MachODylibFile*> _upwardDylibs;
494
  mutable std::vector<std::unique_ptr<File>> _indirectDylibs;
495
  mutable std::mutex _dylibsMutex;
496
  ExportMode _exportMode = ExportMode::globals;
497
  llvm::StringSet<> _exportedSymbols;
498
  DebugInfoMode _debugInfoMode = DebugInfoMode::addDebugMap;
499
  std::unique_ptr<llvm::raw_fd_ostream> _dependencyInfo;
500
  llvm::StringMap<std::vector<OrderFileNode>> _orderFiles;
501
  unsigned _orderFileEntries = 0;
502
  File *_flatNamespaceFile = nullptr;
503
  mach_o::SectCreateFile *_sectCreateFile = nullptr;
504
};
505
506
} // end namespace lld
507
508
#endif // LLD_READER_WRITER_MACHO_LINKING_CONTEXT_H