+ // MacOSX 10.7 defaults to PIE
+ if ( ((fArchitecture == CPU_TYPE_X86_64) || (fArchitecture == CPU_TYPE_I386))
+ && (fOutputKind == kDynamicExecutable)
+ && (fMacVersionMin >= ld::mac10_7) ) {
+ fPositionIndependentExecutable = true;
+ }
+
+ // armv7 for iOS4.3 defaults to PIE
+ if ( (fArchitecture == CPU_TYPE_ARM)
+ && fArchSupportsThumb2
+ && (fOutputKind == kDynamicExecutable)
+ && (fIOSVersionMin >= ld::iOS_4_3) ) {
+ fPositionIndependentExecutable = true;
+ }
+
+ // -no_pie anywhere on command line disable PIE
+ if ( fDisablePositionIndependentExecutable )
+ fPositionIndependentExecutable = false;
+
+ // arm64 is always PIE
+ if ( (fArchitecture == CPU_TYPE_ARM64) && (fOutputKind == kDynamicExecutable) ) {
+ fPositionIndependentExecutable = true;
+ }
+
+ // set fOutputSlidable
+ switch ( fOutputKind ) {
+ case Options::kObjectFile:
+ fOutputSlidable = false;
+ break;
+ case Options::kStaticExecutable:
+ case Options::kDynamicExecutable:
+ fOutputSlidable = fPositionIndependentExecutable;
+ break;
+ case Options::kPreload:
+ fOutputSlidable = fPIEOnCommandLine;
+ break;
+ case Options::kDyld:
+ case Options::kDynamicLibrary:
+ case Options::kDynamicBundle:
+ case Options::kKextBundle:
+ fOutputSlidable = true;
+ break;
+ }
+
+ // let linker know if thread local variables are supported
+ if ( fMacVersionMin >= ld::mac10_7 ) {
+ fTLVSupport = true;
+ }
+ else if ( (fArchitecture == CPU_TYPE_ARM64) && (fIOSVersionMin >= 0x00080000) ) {
+ fTLVSupport = true;
+ }
+
+ // default to adding version load command for dynamic code, static code must opt-in
+ switch ( fOutputKind ) {
+ case Options::kObjectFile:
+ fVersionLoadCommand = false;
+ break;
+ case Options::kStaticExecutable:
+ case Options::kPreload:
+ case Options::kKextBundle:
+ if ( fVersionLoadCommandForcedOn )
+ fVersionLoadCommand = true;
+ break;
+ case Options::kDynamicExecutable:
+ case Options::kDyld:
+ case Options::kDynamicLibrary:
+ case Options::kDynamicBundle:
+ if ( !fVersionLoadCommandForcedOff )
+ fVersionLoadCommand = true;
+ break;
+ }
+
+ // support re-export of individual symbols in MacOSX 10.7 and iOS 4.2
+ if ( (fOutputKind == kDynamicLibrary) && minOS(ld::mac10_7, ld::iOS_4_2) )
+ fCanReExportSymbols = true;
+
+ // ObjC optimization is only in dynamic final linked images
+ switch ( fOutputKind ) {
+ case Options::kObjectFile:
+ case Options::kStaticExecutable:
+ case Options::kPreload:
+ case Options::kKextBundle:
+ case Options::kDyld:
+ fObjcCategoryMerging = false;
+ break;
+ case Options::kDynamicExecutable:
+ case Options::kDynamicLibrary:
+ case Options::kDynamicBundle:
+ break;
+ }
+
+ // i386 main executables linked on Mac OS X 10.7 default to NX heap
+ // regardless of target unless overriden with -allow_heap_execute anywhere
+ // on the command line
+ if ( (fArchitecture == CPU_TYPE_I386) && (fOutputKind == kDynamicExecutable) && !fDisableNonExecutableHeap)
+ fNonExecutableHeap = true;
+
+ // Use LC_MAIN instead of LC_UNIXTHREAD for newer OSs
+ switch ( fOutputKind ) {
+ case Options::kDynamicExecutable:
+ if ( fEntryPointLoadCommandForceOn ) {
+ fEntryPointLoadCommand = true;
+ fEntryName = "_main";
+ }
+ else if ( fEntryPointLoadCommandForceOff ) {
+ fNeedsThreadLoadCommand = true;
+ }
+ else {
+ if ( minOS(ld::mac10_8, ld::iOS_6_0) ) {
+ fEntryPointLoadCommand = true;
+ fEntryName = "_main";
+ }
+ else
+ fNeedsThreadLoadCommand = true;
+ }
+ break;
+ case Options::kObjectFile:
+ case Options::kKextBundle:
+ case Options::kDynamicLibrary:
+ case Options::kDynamicBundle:
+ break;
+
+ case Options::kStaticExecutable:
+ case Options::kPreload:
+ case Options::kDyld:
+ fNeedsThreadLoadCommand = true;
+ break;
+ }
+
+ // add LC_SOURCE_VERSION
+ switch ( fOutputKind ) {
+ case Options::kDynamicExecutable:
+ case Options::kKextBundle:
+ case Options::kDynamicLibrary:
+ case Options::kDynamicBundle:
+ case Options::kDyld:
+ case Options::kStaticExecutable:
+ if ( fSourceVersionLoadCommandForceOn ) {
+ fSourceVersionLoadCommand = true;
+ }
+ else if ( fSourceVersionLoadCommandForceOff ) {
+ fSourceVersionLoadCommand = false;
+ }
+ else {
+ if ( minOS(ld::mac10_8, ld::iOS_6_0) ) {
+ fSourceVersionLoadCommand = true;
+ }
+ else
+ fSourceVersionLoadCommand = false;
+ }
+ break;
+ case Options::kObjectFile:
+ case Options::kPreload:
+ fSourceVersionLoadCommand = false;
+ break;
+ }
+
+
+ // add LC_DYLIB_CODE_SIGN_DRS
+ switch ( fOutputKind ) {
+ case Options::kDynamicExecutable:
+ case Options::kDynamicLibrary:
+ case Options::kDynamicBundle:
+ if ( fDependentDRInfoForcedOn ) {
+ fDependentDRInfo = true;
+ }
+ else if ( fDependentDRInfoForcedOff ) {
+ fDependentDRInfo = false;
+ }
+ else {
+ if ( minOS(ld::mac10_8, ld::iOS_6_0) )
+ fDependentDRInfo = true;
+ else
+ fDependentDRInfo = false;
+ }
+ break;
+ case Options::kKextBundle:
+ case Options::kDyld:
+ case Options::kStaticExecutable:
+ case Options::kObjectFile:
+ case Options::kPreload:
+ fDependentDRInfo = false;
+ break;
+ }
+
+ // if -sdk_version not on command line, infer from -syslibroot
+ if ( (fSDKVersion == 0) && (fSDKPaths.size() > 0) ) {
+ const char* sdkPath = fSDKPaths.front();
+ const char* end = &sdkPath[strlen(sdkPath)-1];
+ while ( !isdigit(*end) && (end > sdkPath) )
+ --end;
+ const char* start = end-1;
+ while ( (isdigit(*start) || (*start == '.')) && (start > sdkPath))
+ --start;
+ char sdkVersionStr[32];
+ int len = end-start+1;
+ if ( len > 2 ) {
+ strlcpy(sdkVersionStr, start+1, len);
+ fSDKVersion = parseVersionNumber32(sdkVersionStr);
+ }
+ }
+
+ // if -sdk_version and -syslibroot not used, but targeting MacOSX, use current OS version
+ if ( (fSDKVersion == 0) && (fMacVersionMin != ld::macVersionUnset) ) {
+ // special case if RC_ProjectName and MACOSX_DEPLOYMENT_TARGET are both set that sdkversion=minos
+ if ( getenv("RC_ProjectName") && getenv("MACOSX_DEPLOYMENT_TARGET") ) {
+ fSDKVersion = fMacVersionMin;
+ }
+ else {
+ int mib[2] = { CTL_KERN, KERN_OSRELEASE };
+ char kernVersStr[100];
+ size_t strlen = sizeof(kernVersStr);
+ if ( sysctl(mib, 2, kernVersStr, &strlen, NULL, 0) != -1 ) {
+ uint32_t kernVers = parseVersionNumber32(kernVersStr);
+ int minor = (kernVers >> 16) - 4; // kernel major version is 4 ahead of x in 10.x
+ fSDKVersion = 0x000A0000 + (minor << 8);
+ }
+ }
+ }
+
+ // allow trie based absolute symbols if targeting new enough OS
+ if ( fMakeCompressedDyldInfo ) {
+ if ( minOS(ld::mac10_9, ld::iOS_7_0) ) {
+ // <rdar://problem/13179029> Allow absolute symbols in export trie for device but not simulator
+ if ( !fTargetIOSSimulator )
+ fAbsoluteSymbols = true;
+ }
+ }
+
+ // <rdar://problem/12959510> iOS main executables now default to 16KB page size
+ if ( (fIOSVersionMin != ld::iOSVersionUnset) && (fOutputKind == Options::kDynamicExecutable) ) {
+ // <rdar://problem/13070042> Only third party apps should have 16KB page segments by default
+ if ( fEncryptable ) {
+ if ( fSegmentAlignment == 4096 )
+ fSegmentAlignment = 4096*4;
+ }
+ }
+
+ // <rdar://problem/12258065> ARM64 needs 16KB page size for user land code
+ if ( fArchitecture == CPU_TYPE_ARM64 ) {
+ if ( fSegmentAlignment == 4096 ) {
+ switch ( fOutputKind ) {
+ case Options::kDynamicExecutable:
+ case Options::kDynamicLibrary:
+ case Options::kDynamicBundle:
+ case Options::kDyld:
+ fSegmentAlignment = 4096*4;
+ break;
+ case Options::kStaticExecutable:
+ case Options::kKextBundle:
+ case Options::kObjectFile:
+ case Options::kPreload:
+ break;
+ }
+ }
+ }
+
+ // <rdar://problem/13624134> linker should not convert dwarf unwind if .o file has compact unwind section
+ switch ( fOutputKind ) {
+ case Options::kDynamicExecutable:
+ case Options::kDynamicLibrary:
+ case Options::kDynamicBundle:
+ case Options::kDyld:
+ if ( fKeepDwarfUnwindForcedOn ) {
+ fKeepDwarfUnwind = true;
+ }
+ else if ( fKeepDwarfUnwindForcedOff ) {
+ fKeepDwarfUnwind = false;
+ }
+ else {
+ if ( minOS(ld::mac10_9, ld::iOS_7_0) )
+ fKeepDwarfUnwind = false;
+ else
+ fKeepDwarfUnwind = true;
+ }
+ break;
+ case Options::kKextBundle:
+ case Options::kStaticExecutable:
+ case Options::kObjectFile:
+ case Options::kPreload:
+ fKeepDwarfUnwind = true;
+ break;
+ }
+
+}