Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame^] | 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 | make_file(Args &&... args) const { |
| 102 | auto file = std::unique_ptr<T>(new T(std::forward<Args>(args)...)); |
| 103 | auto *filePtr = file.get(); |
| 104 | auto *ctx = const_cast<MachOLinkingContext *>(this); |
| 105 | ctx->getNodes().push_back(llvm::make_unique<FileNode>(std::move(file))); |
| 106 | return filePtr; |
| 107 | } |
| 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 | virtual uint64_t pageZeroSize() const { return _pageZeroSize; } |
| 118 | virtual uint64_t pageSize() const { return _pageSize; } |
| 119 | |
| 120 | mach_o::ArchHandler &archHandler() const; |
| 121 | |
| 122 | HeaderFileType outputMachOType() const { return _outputMachOType; } |
| 123 | |
| 124 | Arch arch() const { return _arch; } |
| 125 | StringRef archName() const { return nameFromArch(_arch); } |
| 126 | OS os() const { return _os; } |
| 127 | |
| 128 | ExportMode exportMode() const { return _exportMode; } |
| 129 | void setExportMode(ExportMode mode) { _exportMode = mode; } |
| 130 | void addExportSymbol(StringRef sym); |
| 131 | bool exportRestrictMode() const { return _exportMode != ExportMode::globals; } |
| 132 | bool exportSymbolNamed(StringRef sym) const; |
| 133 | |
| 134 | DebugInfoMode debugInfoMode() const { return _debugInfoMode; } |
| 135 | void setDebugInfoMode(DebugInfoMode mode) { |
| 136 | _debugInfoMode = mode; |
| 137 | } |
| 138 | |
| 139 | void appendOrderedSymbol(StringRef symbol, StringRef filename); |
| 140 | |
| 141 | bool keepPrivateExterns() const { return _keepPrivateExterns; } |
| 142 | void setKeepPrivateExterns(bool v) { _keepPrivateExterns = v; } |
| 143 | bool demangleSymbols() const { return _demangle; } |
| 144 | void setDemangleSymbols(bool d) { _demangle = d; } |
| 145 | bool mergeObjCCategories() const { return _mergeObjCCategories; } |
| 146 | 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 | void setDoNothing(bool value) { _doNothing = value; } |
| 156 | bool doNothing() const { return _doNothing; } |
| 157 | bool printAtoms() const { return _printAtoms; } |
| 158 | bool testingFileUsage() const { return _testingFileUsage; } |
| 159 | const StringRefVector &searchDirs() const { return _searchDirs; } |
| 160 | const StringRefVector &frameworkDirs() const { return _frameworkDirs; } |
| 161 | void setSysLibRoots(const StringRefVector &paths); |
| 162 | const StringRefVector &sysLibRoots() const { return _syslibRoots; } |
| 163 | bool PIE() const { return _pie; } |
| 164 | void setPIE(bool pie) { _pie = pie; } |
| 165 | bool generateVersionLoadCommand() const { |
| 166 | return _generateVersionLoadCommand; |
| 167 | } |
| 168 | void setGenerateVersionLoadCommand(bool v) { |
| 169 | _generateVersionLoadCommand = v; |
| 170 | } |
| 171 | |
| 172 | bool generateFunctionStartsLoadCommand() const { |
| 173 | return _generateFunctionStartsLoadCommand; |
| 174 | } |
| 175 | void setGenerateFunctionStartsLoadCommand(bool v) { |
| 176 | _generateFunctionStartsLoadCommand = v; |
| 177 | } |
| 178 | |
| 179 | bool generateDataInCodeLoadCommand() const { |
| 180 | return _generateDataInCodeLoadCommand; |
| 181 | } |
| 182 | void setGenerateDataInCodeLoadCommand(bool v) { |
| 183 | _generateDataInCodeLoadCommand = v; |
| 184 | } |
| 185 | |
| 186 | uint64_t stackSize() const { return _stackSize; } |
| 187 | void setStackSize(uint64_t stackSize) { _stackSize = stackSize; } |
| 188 | |
| 189 | uint64_t baseAddress() const { return _baseAddress; } |
| 190 | void setBaseAddress(uint64_t baseAddress) { _baseAddress = baseAddress; } |
| 191 | |
| 192 | ObjCConstraint objcConstraint() const { return _objcConstraint; } |
| 193 | |
| 194 | uint32_t osMinVersion() const { return _osMinVersion; } |
| 195 | |
| 196 | uint32_t sdkVersion() const { return _sdkVersion; } |
| 197 | void setSdkVersion(uint64_t v) { _sdkVersion = v; } |
| 198 | |
| 199 | uint64_t sourceVersion() const { return _sourceVersion; } |
| 200 | void setSourceVersion(uint64_t v) { _sourceVersion = v; } |
| 201 | |
| 202 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | StringRef bundleLoader() const { return _bundleLoader; } |
| 304 | |
| 305 | void setCompatibilityVersion(uint32_t vers) { _compatibilityVersion = vers; } |
| 306 | void setCurrentVersion(uint32_t vers) { _currentVersion = vers; } |
| 307 | void setInstallName(StringRef name) { _installName = name; } |
| 308 | void setDeadStrippableDylib(bool deadStrippable) { |
| 309 | _deadStrippableDylib = deadStrippable; |
| 310 | } |
| 311 | void setUseFlatNamespace(bool flatNamespace) { |
| 312 | _flatNamespace = flatNamespace; |
| 313 | } |
| 314 | |
| 315 | void setUndefinedMode(UndefinedMode undefinedMode) { |
| 316 | _undefinedMode = undefinedMode; |
| 317 | } |
| 318 | |
| 319 | void setBundleLoader(StringRef loader) { _bundleLoader = loader; } |
| 320 | void setPrintAtoms(bool value=true) { _printAtoms = value; } |
| 321 | void setTestingFileUsage(bool value = true) { |
| 322 | _testingFileUsage = value; |
| 323 | } |
| 324 | void addExistingPathForDebug(StringRef path) { |
| 325 | _existingPaths.insert(path); |
| 326 | } |
| 327 | |
| 328 | void addRpath(StringRef rpath); |
| 329 | 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 | 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 | ArrayRef<mach_o::MachODylibFile*> allDylibs() const { |
| 381 | return _allDylibs; |
| 382 | } |
| 383 | |
| 384 | /// Creates a copy (owned by this MachOLinkingContext) of a string. |
| 385 | 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 | 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 |