X-Git-Url: https://git.saurik.com/apple/ld64.git/blobdiff_plain/82b4b32b1851b4bba2473356c2208bd34561ee02..e456bf1059cf7e6b8b71545d1b2f2092b55a9684:/src/ld/Options.h diff --git a/src/ld/Options.h b/src/ld/Options.h index d489fd6..62bcddf 100644 --- a/src/ld/Options.h +++ b/src/ld/Options.h @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -37,6 +38,7 @@ #include "Snapshot.h" #include "MachOFileAbstraction.hpp" + extern void throwf (const char* format, ...) __attribute__ ((noreturn,format(printf, 1, 2))); extern void warning(const char* format, ...) __attribute__((format(printf, 1, 2))); @@ -88,44 +90,35 @@ public: enum LocalSymbolHandling { kLocalSymbolsAll, kLocalSymbolsNone, kLocalSymbolsSelectiveInclude, kLocalSymbolsSelectiveExclude }; enum BitcodeMode { kBitcodeProcess, kBitcodeAsData, kBitcodeMarker, kBitcodeStrip }; enum DebugInfoStripping { kDebugInfoNone, kDebugInfoMinimal, kDebugInfoFull }; -#if SUPPORT_APPLE_TV - enum Platform { kPlatformUnknown, kPlatformOSX, kPlatformiOS, kPlatformWatchOS, kPlatform_tvOS }; -#else - enum Platform { kPlatformUnknown, kPlatformOSX, kPlatformiOS, kPlatformWatchOS }; -#endif + enum UnalignedPointerTreatment { kUnalignedPointerError, kUnalignedPointerWarning, kUnalignedPointerIgnore }; - static Platform platformForLoadCommand(uint32_t lc) { + static ld::Platform platformForLoadCommand(uint32_t lc, bool useSimulatorVariant) { switch (lc) { case LC_VERSION_MIN_MACOSX: - return kPlatformOSX; + return ld::kPlatform_macOS; case LC_VERSION_MIN_IPHONEOS: - return kPlatformiOS; + return useSimulatorVariant ? ld::kPlatform_iOSSimulator : ld::kPlatform_iOS; case LC_VERSION_MIN_WATCHOS: - return kPlatformWatchOS; - #if SUPPORT_APPLE_TV + return useSimulatorVariant ? ld::kPlatform_watchOSSimulator : ld::kPlatform_watchOS; case LC_VERSION_MIN_TVOS: - return kPlatform_tvOS; - #endif + return useSimulatorVariant ? ld::kPlatform_tvOSSimulator : ld::kPlatform_tvOS; } assert(!lc && "unknown LC_VERSION_MIN load command"); - return kPlatformUnknown; + return ld::kPlatform_unknown; } - static const char* platformName(Platform platform) { + static const char* platformName(ld::Platform platform) { switch (platform) { - case kPlatformOSX: - return "OSX"; - case kPlatformiOS: - return "iOS"; - case kPlatformWatchOS: - return "watchOS"; - #if SUPPORT_APPLE_TV - case kPlatform_tvOS: - return "tvOS"; - #endif - case kPlatformUnknown: - default: - return "(unknown)"; + case ld::kPlatform_macOS: return "OSX"; + case ld::kPlatform_iOS: return "iOS"; + case ld::kPlatform_iOSSimulator: return "iOS Simulator"; + case ld::kPlatform_iOSMac: return "iOSMac"; + case ld::kPlatform_watchOS: return "watchOS"; + case ld::kPlatform_watchOSSimulator: return "watchOS Simulator"; + case ld::kPlatform_tvOS: return "tvOS"; + case ld::kPlatform_tvOSSimulator: return "tvOS Simulator"; + case ld::kPlatform_bridgeOS: return "bridgeOS"; + case ld::kPlatform_unknown: return "(unknown)"; } } @@ -144,6 +137,9 @@ public: case 4: strcpy(versionString, "3.0"); break; + case 5: + strcpy(versionString, "4.0"); + break; default: sprintf(versionString, "unknown ABI version 0x%02X", value); } @@ -157,6 +153,7 @@ public: LibraryOptions options; ld::File::Ordinal ordinal; bool fromFileList; + bool isInlined; // These are used by the threaded input file parsing engine. mutable int inputFileSlot; // The input file "slot" assigned to this particular file @@ -165,7 +162,7 @@ public: // The use pattern for FileInfo is to create one on the stack in a leaf function and return // it to the calling frame by copy. Therefore the copy constructor steals the path string from // the source, which dies with the stack frame. - FileInfo(FileInfo const &other) : path(other.path), modTime(other.modTime), options(other.options), ordinal(other.ordinal), fromFileList(other.fromFileList), inputFileSlot(-1) { ((FileInfo&)other).path = NULL; }; + FileInfo(FileInfo const &other) : path(other.path), modTime(other.modTime), options(other.options), ordinal(other.ordinal), fromFileList(other.fromFileList), isInlined(other.isInlined), inputFileSlot(-1) { ((FileInfo&)other).path = NULL; }; FileInfo &operator=(FileInfo other) { std::swap(path, other.path); @@ -173,16 +170,17 @@ public: std::swap(options, other.options); std::swap(ordinal, other.ordinal); std::swap(fromFileList, other.fromFileList); + std::swap(isInlined, other.isInlined); std::swap(inputFileSlot, other.inputFileSlot); std::swap(readyToParse, other.readyToParse); return *this; } // Create an empty FileInfo. The path can be set implicitly by checkFileExists(). - FileInfo() : path(NULL), modTime(-1), options(), fromFileList(false) {}; + FileInfo() : path(NULL), modTime(-1), options(), fromFileList(false), isInlined(false) {}; // Create a FileInfo for a specific path, but does not stat the file. - FileInfo(const char *_path) : path(strdup(_path)), modTime(-1), options(), fromFileList(false) {}; + FileInfo(const char *_path) : path(strdup(_path)), modTime(-1), options(), fromFileList(false), isInlined(false) {}; ~FileInfo() { if (path) ::free((void*)path); } @@ -197,6 +195,19 @@ public: bool missing() const { return modTime == -1; } }; + class TAPIInterface { + public: + TAPIInterface(tapi::LinkerInterfaceFile* file, const char* path, const char *installName) : + _file(file), _tbdPath(path), _installName(installName) {} + tapi::LinkerInterfaceFile* getInterfaceFile() const { return _file; } + std::string getTAPIFilePath() const { return _tbdPath; } + const std::string &getInstallName() const { return _installName; } + private: + tapi::LinkerInterfaceFile* _file; + std::string _tbdPath; + std::string _installName; + }; + struct ExtraSection { const char* segmentName; const char* sectionName; @@ -267,7 +278,7 @@ public: depFileList=0x10, depSection=0x10, depBundleLoader=0x10, depMisc=0x10, depNotFound=0x11, depOutputFile = 0x40 }; - void dumpDependency(uint8_t, const char* path) const; + void addDependency(uint8_t, const char* path) const; typedef const char* const* UndefinesIterator; @@ -278,14 +289,16 @@ public: cpu_type_t architecture() const { return fArchitecture; } bool preferSubArchitecture() const { return fHasPreferredSubType; } cpu_subtype_t subArchitecture() const { return fSubArchitecture; } + cpu_type_t fallbackArchitecture() const { return fFallbackArchitecture; } + cpu_subtype_t fallbackSubArchitecture() const { return fFallbackSubArchitecture; } bool allowSubArchitectureMismatches() const { return fAllowCpuSubtypeMismatches; } bool enforceDylibSubtypesMatch() const { return fEnforceDylibSubtypesMatch; } + bool warnOnSwiftABIVersionMismatches() const { return fWarnOnSwiftABIVersionMismatches; } bool forceCpuSubtypeAll() const { return fForceSubtypeAll; } const char* architectureName() const { return fArchitectureName; } - void setArchitecture(cpu_type_t, cpu_subtype_t subtype, Options::Platform platform); + void setArchitecture(cpu_type_t, cpu_subtype_t subtype, ld::Platform platform, uint32_t minOsVers); bool archSupportsThumb2() const { return fArchSupportsThumb2; } OutputKind outputKind() const { return fOutputKind; } - bool prebind() const { return fPrebind; } bool bindAtLoad() const { return fBindAtLoad; } NameSpace nameSpace() const { return fNameSpace; } const char* installPath() const; // only for kDynamicLibrary @@ -297,7 +310,6 @@ public: uint64_t baseAddress() const { return fBaseAddress; } uint64_t maxAddress() const { return fMaxAddress; } bool keepPrivateExterns() const { return fKeepPrivateExterns; } // only for kObjectFile - bool needsModuleTable() const { return fNeedsModuleTable; } // only for kDynamicLibrary bool interposable(const char* name) const; bool hasExportRestrictList() const { return (fExportMode != kExportDefault); } // -exported_symbol or -unexported_symbol bool hasExportMaskList() const { return (fExportMode == kExportSome); } // just -exported_symbol @@ -314,12 +326,7 @@ public: bool traceEmitJSON() const { return fTraceEmitJSON; } bool deadCodeStrip() const { return fDeadStrip; } UndefinedTreatment undefinedTreatment() const { return fUndefinedTreatment; } - ld::MacVersionMin macosxVersionMin() const { return fMacVersionMin; } - ld::IOSVersionMin iOSVersionMin() const { return fIOSVersionMin; } - ld::WatchOSVersionMin watchOSVersionMin() const { return fWatchOSVersionMin; } - uint32_t minOSversion() const; - bool minOS(ld::MacVersionMin mac, ld::IOSVersionMin iPhoneOS); - bool min_iOS(ld::IOSVersionMin requirediOSMin); + uint32_t minOSversion(const ld::Platform& platform) const; bool messagesPrefixedWithArchitecture(); Treatment picTreatment(); WeakReferenceMismatchTreatment weakReferenceMismatchTreatment() const { return fWeakReferenceMismatchTreatment; } @@ -347,6 +354,8 @@ public: bool keepRelocations(); FileInfo findFile(const std::string &path, const ld::dylib::File* fromDylib=nullptr) const; bool findFile(const std::string &path, const std::vector &tbdExtensions, FileInfo& result) const; + bool hasInlinedTAPIFile(const std::string &path) const; + tapi::LinkerInterfaceFile* findTAPIFile(const std::string &path) const; UUIDMode UUIDMode() const { return fUUIDMode; } bool warnStabs(); bool pauseAtEnd() { return fPause; } @@ -360,7 +369,6 @@ public: unsigned long orderedSymbolsCount() const { return fOrderedSymbols.size(); } OrderedSymbolsIterator orderedSymbolsBegin() const { return &fOrderedSymbols[0]; } OrderedSymbolsIterator orderedSymbolsEnd() const { return &fOrderedSymbols[fOrderedSymbols.size()]; } - bool splitSeg() const { return fSplitSegs; } uint64_t baseWritableAddress() { return fBaseWritableAddress; } uint64_t segmentAlignment() const { return fSegmentAlignment; } uint64_t segPageSize(const char* segName) const; @@ -396,6 +404,7 @@ public: const std::vector& dyldEnvironExtras() const{ return fDyldEnvironExtras; } const std::vector& astFilePaths() const{ return fASTFilePaths; } bool makeCompressedDyldInfo() const { return fMakeCompressedDyldInfo; } + bool makeThreadedStartsSection() const { return fMakeThreadedStartsSection; } bool hasExportedSymbolOrder(); bool exportedSymbolOrder(const char* sym, unsigned int* order) const; bool orderData() { return fOrderData; } @@ -423,21 +432,26 @@ public: bool makeTentativeDefinitionsReal() const { return fMakeTentativeDefinitionsReal; } const char* dyldInstallPath() const { return fDyldInstallPath; } bool warnWeakExports() const { return fWarnWeakExports; } + bool noWeakExports() const { return fNoWeakExports; } bool objcGcCompaction() const { return fObjcGcCompaction; } bool objcGc() const { return fObjCGc; } bool objcGcOnly() const { return fObjCGcOnly; } bool canUseThreadLocalVariables() const { return fTLVSupport; } - bool addVersionLoadCommand() const { return fVersionLoadCommand && (fPlatform != kPlatformUnknown); } + bool addVersionLoadCommand() const { return fVersionLoadCommand && (platforms().count() != 0); } bool addFunctionStarts() const { return fFunctionStartsLoadCommand; } bool addDataInCodeInfo() const { return fDataInCodeInfoLoadCommand; } bool canReExportSymbols() const { return fCanReExportSymbols; } const char* ltoCachePath() const { return fLtoCachePath; } + bool ltoPruneIntervalOverwrite() const { return fLtoPruneIntervalOverwrite; } int ltoPruneInterval() const { return fLtoPruneInterval; } int ltoPruneAfter() const { return fLtoPruneAfter; } unsigned ltoMaxCacheSize() const { return fLtoMaxCacheSize; } const char* tempLtoObjectPath() const { return fTempLtoObjectPath; } const char* overridePathlibLTO() const { return fOverridePathlibLTO; } const char* mcpuLTO() const { return fLtoCpu; } + const char* kextObjectsPath() const { return fKextObjectsDirPath; } + int kextObjectsEnable() const { return fKextObjectsEnable; } + const char* toolchainPath() const { return fToolchainPath; } bool objcCategoryMerging() const { return fObjcCategoryMerging; } bool pageAlignDataAtoms() const { return fPageAlignDataAtoms; } bool keepDwarfUnwind() const { return fKeepDwarfUnwind; } @@ -455,12 +469,20 @@ public: bool renameReverseSymbolMap() const { return fReverseMapUUIDRename; } bool deduplicateFunctions() const { return fDeDupe; } bool verboseDeduplicate() const { return fVerboseDeDupe; } + bool useLinkedListBinding() const { return fUseLinkedListBinding; } +#if SUPPORT_ARCH_arm64e + bool useAuthenticatedStubs() const { return fUseAuthenticatedStubs; } + bool supportsAuthenticatedPointers() const { return fSupportsAuthenticatedPointers; } +#endif + bool noLazyBinding() const { return fNoLazyBinding; } + bool debugVariant() const { return fDebugVariant; } const char* reverseSymbolMapPath() const { return fReverseMapPath; } std::string reverseMapTempPath() const { return fReverseMapTempPath; } bool ltoCodegenOnly() const { return fLTOCodegenOnly; } bool ignoreAutoLink() const { return fIgnoreAutoLink; } bool allowDeadDuplicates() const { return fAllowDeadDups; } bool allowWeakImports() const { return fAllowWeakImports; } + Treatment initializersTreatment() const { return fInitializersTreatment; } BitcodeMode bitcodeKind() const { return fBitcodeKind; } bool sharedRegionEncodingV2() const { return fSharedRegionEncodingV2; } bool useDataConstSegment() const { return fUseDataConstSegment; } @@ -485,8 +507,8 @@ public: const char* pipelineFifo() const { return fPipelineFifo; } bool dumpDependencyInfo() const { return (fDependencyInfoPath != NULL); } const char* dependencyInfoPath() const { return fDependencyInfoPath; } - bool targetIOSSimulator() const { return fTargetIOSSimulator; } - ld::relocatable::File::LinkerOptionsList& + bool targetIOSSimulator() const { return platforms().contains(ld::simulatorPlatforms); } + ld::relocatable::File::LinkerOptionsList& linkerOptions() const { return fLinkerOptions; } FileInfo findFramework(const char* frameworkName) const; FileInfo findLibrary(const char* rootName, bool dylibsOnly=false) const; @@ -495,15 +517,21 @@ public: const std::vector& segmentRenames() const { return fSegmentRenames; } bool moveRoSymbol(const char* symName, const char* filePath, const char*& seg, bool& wildCardMatch) const; bool moveRwSymbol(const char* symName, const char* filePath, const char*& seg, bool& wildCardMatch) const; - Platform platform() const { return fPlatform; } + bool moveAXMethodList(const char* className) const; + const ld::VersionSet& platforms() const { return fPlatforms; } const std::vector& sdkPaths() const { return fSDKPaths; } std::vector writeBitcodeLinkOptions() const; std::string getSDKVersionStr() const; - std::string getPlatformStr() const; uint8_t maxDefaultCommonAlign() const { return fMaxDefaultCommonAlign; } bool hasDataSymbolMoves() const { return !fSymbolsMovesData.empty(); } bool hasCodeSymbolMoves() const { return !fSymbolsMovesCode.empty(); } void writeToTraceFile(const char* buffer, size_t len) const; + UnalignedPointerTreatment unalignedPointerTreatment() const { return fUnalignedPointerTreatment; } + bool zeroModTimeInDebugMap() const { return fZeroModTimeInDebugMap; } + void writeDependencyInfo() const; + std::vector &TAPIFiles() { return fTAPIFiles; } + void addTAPIInterface(tapi::LinkerInterfaceFile* interface, const char *path) const; + const char* buildContextName() const { return fBuildContextName; } static uint32_t parseVersionNumber32(const char*); @@ -540,10 +568,18 @@ private: SetWithWildcards symbols; }; + struct DependencyEntry { + uint8_t opcode; + std::string path; + }; + + const char* checkForNullArgument(const char* argument_name, const char* arg) const; + const char* checkForNullVersionArgument(const char* argument_name, const char* arg) const; void parse(int argc, const char* argv[]); void checkIllegalOptionCombinations(); void buildSearchPaths(int argc, const char* argv[]); void parseArch(const char* architecture); + void selectFallbackArch(const char *architecture); FileInfo findFramework(const char* rootName, const char* suffix) const; bool checkForFile(const char* format, const char* dir, const char* rootName, FileInfo& result) const; @@ -562,9 +598,7 @@ private: void parsePreCommandLineEnvironmentSettings(); void parsePostCommandLineEnvironmentSettings(); void setUndefinedTreatment(const char* treatment); - void setMacOSXVersionMin(const char* version); - void setIOSVersionMin(const char* version); - void setWatchOSVersionMin(const char* version); + void setVersionMin(const ld::Platform& platform, const char *version); void setWeakReferenceMismatchTreatment(const char* treatment); void addDylibOverride(const char* paths); void addSectionAlignment(const char* segment, const char* section, const char* alignment); @@ -588,14 +622,14 @@ private: std::vector fInputFiles; cpu_type_t fArchitecture; cpu_subtype_t fSubArchitecture; + cpu_type_t fFallbackArchitecture; + cpu_subtype_t fFallbackSubArchitecture; const char* fArchitectureName; OutputKind fOutputKind; bool fHasPreferredSubType; bool fArchSupportsThumb2; - bool fPrebind; bool fBindAtLoad; bool fKeepPrivateExterns; - bool fNeedsModuleTable; bool fIgnoreOtherArchFiles; bool fErrorOnOtherArchFiles; bool fForceSubtypeAll; @@ -610,7 +644,6 @@ private: uint64_t fBaseAddress; uint64_t fMaxAddress; uint64_t fBaseWritableAddress; - bool fSplitSegs; SetWithWildcards fExportSymbols; SetWithWildcards fDontExportSymbols; SetWithWildcards fInterposeList; @@ -636,16 +669,19 @@ private: const char* fExecutablePath; const char* fBundleLoader; const char* fDtraceScriptName; - const char* fSegAddrTablePath; const char* fMapPath; const char* fDyldInstallPath; const char* fLtoCachePath; + bool fLtoPruneIntervalOverwrite; int fLtoPruneInterval; int fLtoPruneAfter; unsigned fLtoMaxCacheSize; const char* fTempLtoObjectPath; const char* fOverridePathlibLTO; const char* fLtoCpu; + int fKextObjectsEnable; + const char* fKextObjectsDirPath; + const char* fToolchainPath; uint64_t fZeroPageSize; uint64_t fStackSize; uint64_t fStackAddr; @@ -689,9 +725,11 @@ private: bool fMarkDeadStrippableDylib; bool fMakeCompressedDyldInfo; bool fMakeCompressedDyldInfoForceOff; + bool fMakeThreadedStartsSection; bool fNoEHLabels; bool fAllowCpuSubtypeMismatches; bool fEnforceDylibSubtypesMatch; + bool fWarnOnSwiftABIVersionMismatches; bool fUseSimplifiedDylibReExports; bool fObjCABIVersion2Override; bool fObjCABIVersion1Override; @@ -722,6 +760,7 @@ private: bool fTraceEmitJSON; bool fOutputSlidable; bool fWarnWeakExports; + bool fNoWeakExports; bool fObjcGcCompaction; bool fObjCGc; bool fObjCGcOnly; @@ -741,12 +780,9 @@ private: bool fPageAlignDataAtoms; bool fNeedsThreadLoadCommand; bool fEntryPointLoadCommand; - bool fEntryPointLoadCommandForceOn; - bool fEntryPointLoadCommandForceOff; bool fSourceVersionLoadCommand; bool fSourceVersionLoadCommandForceOn; bool fSourceVersionLoadCommandForceOff; - bool fTargetIOSSimulator; bool fExportDynamic; bool fAbsoluteSymbols; bool fAllowSimulatorToLinkWithMacOSX; @@ -772,19 +808,25 @@ private: bool fReverseMapUUIDRename; bool fDeDupe; bool fVerboseDeDupe; + bool fUseLinkedListBinding; +#if SUPPORT_ARCH_arm64e + bool fUseAuthenticatedStubs = false; + bool fSupportsAuthenticatedPointers = false; +#endif + bool fNoLazyBinding; + bool fDebugVariant; const char* fReverseMapPath; std::string fReverseMapTempPath; bool fLTOCodegenOnly; bool fIgnoreAutoLink; bool fAllowDeadDups; bool fAllowWeakImports; + Treatment fInitializersTreatment; + bool fZeroModTimeInDebugMap; BitcodeMode fBitcodeKind; - Platform fPlatform; DebugInfoStripping fDebugInfoStripping; const char* fTraceOutputFile; - ld::MacVersionMin fMacVersionMin; - ld::IOSVersionMin fIOSVersionMin; - ld::WatchOSVersionMin fWatchOSVersionMin; + ld::VersionSet fPlatforms; std::vector fAliases; std::vector fInitialUndefines; NameSet fAllowedUndefined; @@ -809,14 +851,19 @@ private: std::vector fSegmentRenames; std::vector fSymbolsMovesData; std::vector fSymbolsMovesCode; + std::vector fSymbolsMovesAXMethodLists; bool fSaveTempFiles; mutable Snapshot fLinkSnapshot; bool fSnapshotRequested; const char* fPipelineFifo; const char* fDependencyInfoPath; - mutable int fDependencyFileDescriptor; + const char* fBuildContextName; mutable int fTraceFileDescriptor; uint8_t fMaxDefaultCommonAlign; + UnalignedPointerTreatment fUnalignedPointerTreatment; + mutable std::vector fDependencies; + mutable std::vector fTAPIFiles; + };