Loading...
--- dyld/dyld-360.21/src/dyld.cpp
+++ dyld/dyld-353.2.1/src/dyld.cpp
@@ -50,7 +50,6 @@
 #include <libkern/OSAtomic.h>
 #include <Availability.h>
 #include <System/sys/codesign.h>
-#include <System/sys/csr.h>
 #include <_simple.h>
 #include <os/lock_private.h>
 
@@ -98,12 +97,11 @@
 #if DYLD_SHARED_CACHE_SUPPORT
 #include "dyld_cache_format.h"
 #endif
-#include <coreSymbolicationDyldSupport.h>
 #if TARGET_IPHONE_SIMULATOR
-	extern "C" void xcoresymbolication_load_notifier(void *connection, uint64_t load_timestamp, const char *image_path, const struct mach_header *mach_header);
-	extern "C" void xcoresymbolication_unload_notifier(void *connection, uint64_t unload_timestamp, const char *image_path, const struct mach_header *mach_header);
-	#define coresymbolication_load_notifier(c, t, p, h) xcoresymbolication_load_notifier(c, t, p, h)
-	#define coresymbolication_unload_notifier(c, t, p, h) xcoresymbolication_unload_notifier(c, t, p, h)
+  void coresymbolication_load_image(void*, const ImageLoader*, uint64_t);
+  void coresymbolication_unload_image(void*, const ImageLoader*);
+#else
+  #include "coreSymbolicationDyldSupport.hpp"
 #endif
 
 // not libc header for send() syscall interface
@@ -112,18 +110,6 @@
 
 // ARM and x86_64 are the only architecture that use cpu-sub-types
 #define CPU_SUBTYPES_SUPPORTED  ((__arm__ || __x86_64__) && !TARGET_IPHONE_SIMULATOR)
-
-#if __LP64__
-	#define LC_SEGMENT_COMMAND		LC_SEGMENT_64
-	#define LC_SEGMENT_COMMAND_WRONG LC_SEGMENT
-	#define macho_segment_command	segment_command_64
-	#define macho_section			section_64
-#else
-	#define LC_SEGMENT_COMMAND		LC_SEGMENT
-	#define LC_SEGMENT_COMMAND_WRONG LC_SEGMENT_64
-	#define macho_segment_command	segment_command
-	#define macho_section			section
-#endif
 
 
 
@@ -233,7 +219,6 @@
 #endif
 static ImageLoader*					sMainExecutable = NULL;
 static bool							sProcessIsRestricted = false;
-static bool							sProcessRequiresLibraryValidation = false;
 static RestrictedReason				sRestrictedReason = restrictedNot;
 static size_t						sInsertedDylibCount = 0;
 static std::vector<ImageLoader*>	sAllImages;
@@ -247,13 +232,8 @@
 static void*						sBatchHandlers[7][3];
 static ImageLoader*					sLastImageByAddressCache;
 static EnvironmentVariables			sEnv;
-#if __MAC_OS_X_VERSION_MIN_REQUIRED
 static const char*					sFrameworkFallbackPaths[] = { "$HOME/Library/Frameworks", "/Library/Frameworks", "/Network/Library/Frameworks", "/System/Library/Frameworks", NULL };
 static const char*					sLibraryFallbackPaths[] = { "$HOME/lib", "/usr/local/lib", "/usr/lib", NULL };
-#else
-static const char*					sFrameworkFallbackPaths[] = { "/System/Library/Frameworks", NULL };
-static const char*					sLibraryFallbackPaths[] = { "/usr/local/lib", "/usr/lib", NULL };
-#endif
 static UndefinedHandler				sUndefinedHandler = NULL;
 static ImageLoader*					sBundleBeingLoaded = NULL;	// hack until OFI is reworked
 #if DYLD_SHARED_CACHE_SUPPORT
@@ -284,7 +264,6 @@
 static bool							sHaswell = false;
 #endif
 static std::vector<ImageLoader::DynamicReference> sDynamicReferences;
-static OSSpinLock					sDynamicReferencesLock = 0;
 static bool							sLogToFile = false;
 static char							sLoadingCrashMessage[1024] = "dyld: launch, loading dependent libraries";
 
@@ -530,13 +509,30 @@
 
 static void allImagesLock()
 {
+    //dyld::log("allImagesLock()\n");
+#if TARGET_IPHONE_SIMULATOR	
+	// <rdar://problem/16154256> can't use OSSpinLockLock in simulator until thread_switch is provided by host dyld
+	while ( ! OSAtomicCompareAndSwapPtrBarrier((void*)0, (void*)1, (void**)&sAllImagesLock) ) {
+        // spin
+    }
+#else
 	OSSpinLockLock(&sAllImagesLock);
+#endif
 }
 
 static void allImagesUnlock()
 {
+    //dyld::log("allImagesUnlock()\n");
+#if TARGET_IPHONE_SIMULATOR	
+	while ( ! OSAtomicCompareAndSwapPtrBarrier((void*)1, (void*)0, (void**)&sAllImagesLock) ) {
+		// spin
+	}
+#else
 	OSSpinLockUnlock(&sAllImagesLock);
-}
+#endif
+}
+
+
 
 
 // utility class to assure files are closed when an exception is thrown
@@ -703,15 +699,21 @@
 			}
 		}
 	}
-    // mach message csdlc about dynamically unloaded images
+    // mach message csdlc about dynamically loaded images 
 	if ( image->addFuncNotified() && (state == dyld_image_state_terminated) ) {
-		uint64_t loadTimestamp = mach_absolute_time();
 		if ( sEnv.DYLD_PRINT_CS_NOTIFICATIONS ) {
-			dyld::log("dyld: coresymbolication_unload_notifier(%p, 0x%016llX, %p, %s)\n",
-					  dyld::gProcessInfo->coreSymbolicationShmPage, loadTimestamp, image->machHeader(), image->getPath());
+			dyld::log("dyld core symbolication unload notification: %p %s\n", image->machHeader(), image->getPath());
 		}
 		if ( dyld::gProcessInfo->coreSymbolicationShmPage != NULL) {
-			coresymbolication_unload_notifier(dyld::gProcessInfo->coreSymbolicationShmPage, loadTimestamp, image->getPath(), image->machHeader());
+#if TARGET_IPHONE_SIMULATOR
+			void* connection = dyld::gProcessInfo->coreSymbolicationShmPage;
+			if ( *((uint32_t*)connection) == 2 ) {
+#else
+			CSCppDyldSharedMemoryPage* connection = (CSCppDyldSharedMemoryPage*)dyld::gProcessInfo->coreSymbolicationShmPage;
+			if ( connection->is_valid_version() ) {
+#endif
+				coresymbolication_unload_image(connection, image);
+			}
 		}
 	}
 }
@@ -821,21 +823,36 @@
 					}
 				}
 			}
-			if ( (state == dyld_image_state_dependents_mapped) && ((dyld::gProcessInfo->coreSymbolicationShmPage != NULL) || sEnv.DYLD_PRINT_CS_NOTIFICATIONS) ) {
-				// mach message csdlc about loaded images
-				uint64_t loadTimestamp = mach_absolute_time();
-				for (unsigned j=0; j < count; ++j) {
-					if ( sEnv.DYLD_PRINT_CS_NOTIFICATIONS ) {
-						dyld::log("dyld: coresymbolication_load_notifier(%p, 0x%016llX, %p, %s)\n",
-								  dyld::gProcessInfo->coreSymbolicationShmPage, loadTimestamp, infos[j].imageLoadAddress, infos[j].imageFilePath);
-					}
-					coresymbolication_load_notifier(dyld::gProcessInfo->coreSymbolicationShmPage, loadTimestamp, infos[j].imageFilePath, infos[j].imageLoadAddress);
-				}
-			}
 		}
         allImagesUnlock();
         if ( dontLoadReason != NULL )
             throw dontLoadReason;
+	}
+	if ( state == dyld_image_state_rebased ) {
+		if ( sEnv.DYLD_PRINT_CS_NOTIFICATIONS ) {
+			for (std::vector<ImageLoader*>::iterator it=sAllImages.begin(); it != sAllImages.end(); it++) {
+				dyld_image_states imageState = (*it)->getState();
+				if ( (imageState == dyld_image_state_rebased) || (orLater && (imageState > dyld_image_state_rebased)) )
+					dyld::log("dyld core symbolication load notification: %p %s\n", (*it)->machHeader(), (*it)->getPath());
+			}
+		}
+		if ( dyld::gProcessInfo->coreSymbolicationShmPage != NULL) {
+#if TARGET_IPHONE_SIMULATOR
+			void* connection = dyld::gProcessInfo->coreSymbolicationShmPage;
+			if ( *((uint32_t*)connection) == 2 ) {
+#else
+			CSCppDyldSharedMemoryPage* connection = (CSCppDyldSharedMemoryPage*)dyld::gProcessInfo->coreSymbolicationShmPage;
+			if ( connection->is_valid_version() ) {
+#endif
+				// This needs to be captured now
+				uint64_t load_timestamp = mach_absolute_time();
+				for (std::vector<ImageLoader*>::iterator it=sAllImages.begin(); it != sAllImages.end(); it++) {
+					dyld_image_states imageState = (*it)->getState();
+					if ( (imageState == state) || (orLater && (imageState > state)) )
+						coresymbolication_load_image(connection, *it, load_timestamp);
+				}
+			}
+		}
 	}
 }
 
@@ -908,20 +925,15 @@
 		return;
 	
 	// don't add if this combination already exists
-	OSSpinLockLock(&sDynamicReferencesLock);
 	for (std::vector<ImageLoader::DynamicReference>::iterator it=sDynamicReferences.begin(); it != sDynamicReferences.end(); ++it) {
-		if ( (it->from == from) && (it->to == to) ) {
-			OSSpinLockUnlock(&sDynamicReferencesLock);
+		if ( (it->from == from) && (it->to == to) )
 			return;
-		}
-	}
-
+	}
 	//dyld::log("addDynamicReference(%s, %s\n", from->getShortName(), to->getShortName());
 	ImageLoader::DynamicReference t;
 	t.from = from;
 	t.to = to;
 	sDynamicReferences.push_back(t);
-	OSSpinLockUnlock(&sDynamicReferencesLock);
 }
 
 static void addImage(ImageLoader* image)
@@ -1017,9 +1029,7 @@
     allImagesUnlock();
 	
 	// remove from sDynamicReferences
-	OSSpinLockLock(&sDynamicReferencesLock);
-		sDynamicReferences.erase(std::remove_if(sDynamicReferences.begin(), sDynamicReferences.end(), RefUsesImage(image)), sDynamicReferences.end());
-	OSSpinLockUnlock(&sDynamicReferencesLock);
+	sDynamicReferences.erase(std::remove_if(sDynamicReferences.begin(), sDynamicReferences.end(), RefUsesImage(image)), sDynamicReferences.end());
 
 	// flush find-by-address cache (do this after removed from master list, so there is no chance it can come back)
 	if ( sLastImageByAddressCache == image )
@@ -1142,7 +1152,7 @@
 	//dyld::log("checkDylibOverride('%s')\n", dylibFile);
 	uint32_t altVersion;
  	char sysInstallName[PATH_MAX];
-	if ( getDylibVersionAndInstallname(dylibFile, &altVersion, sysInstallName) && (sysInstallName[0] =='/') ) {
+	if ( getDylibVersionAndInstallname(dylibFile, &altVersion, sysInstallName) ) {
 		//dyld::log("%s has version 0x%08X and install name %s\n", dylibFile, altVersion, sysInstallName);
 		uint32_t sysVersion;
 		if ( getDylibVersionAndInstallname(sysInstallName, &sysVersion, NULL) ) {
@@ -1190,9 +1200,8 @@
 {
 	//dyld::log("checkDylibOverridesInDir('%s')\n", dirPath);
 	char dylibPath[PATH_MAX];
-	int dirPathLen = strlcpy(dylibPath, dirPath, PATH_MAX-1);
-	if ( dirPathLen >= PATH_MAX )
-		return;
+	int dirPathLen = strlen(dirPath);
+	strlcpy(dylibPath, dirPath, PATH_MAX); 
 	DIR* dirp = opendir(dirPath);
 	if ( dirp != NULL) {
 		dirent entry;
@@ -1202,9 +1211,9 @@
 				break;
 			if ( entp->d_type != DT_REG ) 
 				continue;
-			dylibPath[dirPathLen] = '/';
-			dylibPath[dirPathLen+1] = '\0';
-			if ( strlcat(dylibPath, entp->d_name, PATH_MAX) >= PATH_MAX )
+			dylibPath[dirPathLen] = '/';     
+			dylibPath[dirPathLen+1] = '\0';     
+			if ( strlcat(dylibPath, entp->d_name, PATH_MAX) > PATH_MAX ) 
 				continue;
 			checkDylibOverride(dylibPath);
 		}
@@ -1217,9 +1226,8 @@
 {
 	//dyld::log("checkFrameworkOverridesInDir('%s')\n", dirPath);
 	char frameworkPath[PATH_MAX];
-	int dirPathLen = strlcpy(frameworkPath, dirPath, PATH_MAX-1);
-	if ( dirPathLen >= PATH_MAX )
-		return;
+	int dirPathLen = strlen(dirPath);
+	strlcpy(frameworkPath, dirPath, PATH_MAX); 
 	DIR* dirp = opendir(dirPath);
 	if ( dirp != NULL) {
 		dirent entry;
@@ -1229,18 +1237,18 @@
 				break;
 			if ( entp->d_type != DT_DIR ) 
 				continue;
-			frameworkPath[dirPathLen] = '/';
+			frameworkPath[dirPathLen] = '/';     
 			frameworkPath[dirPathLen+1] = '\0';
-			int dirNameLen = (int)strlen(entp->d_name);
+			int dirNameLen = strlen(entp->d_name);
 			if ( dirNameLen < 11 )
 				continue;
 			if ( strcmp(&entp->d_name[dirNameLen-10], ".framework") != 0 )
 				continue;
-			if ( strlcat(frameworkPath, entp->d_name, PATH_MAX) >= PATH_MAX )
+			if ( strlcat(frameworkPath, entp->d_name, PATH_MAX) > PATH_MAX ) 
 				continue;
-			if ( strlcat(frameworkPath, "/", PATH_MAX) >= PATH_MAX )
+			if ( strlcat(frameworkPath, "/", PATH_MAX) > PATH_MAX ) 
 				continue;
-			if ( strlcat(frameworkPath, entp->d_name, PATH_MAX) >= PATH_MAX )
+			if ( strlcat(frameworkPath, entp->d_name, PATH_MAX) > PATH_MAX ) 
 				continue;
 			frameworkPath[strlen(frameworkPath)-10] = '\0';
 			checkDylibOverride(frameworkPath);
@@ -1577,18 +1585,9 @@
 		appendParsedColonList(value, mainExecutableDir, &sEnv.DYLD_VERSIONED_FRAMEWORK_PATH);
 	}
 #endif
-#if !TARGET_IPHONE_SIMULATOR
-	else if ( (strcmp(key, "DYLD_PRINT_TO_FILE") == 0) && (mainExecutableDir == NULL) ) {
-		int fd = open(value, O_WRONLY | O_CREAT | O_APPEND, 0644);
-		if ( fd != -1 ) {
-			sLogfile = fd;
-			sLogToFile = true;
-		}
-		else {
-			dyld::log("dyld: could not open DYLD_PRINT_TO_FILE='%s', errno=%d\n", value, errno);
-		}
-	}
-#endif
+	else if ( strcmp(key, "DYLD_PRINT_TO_FILE") == 0 ) {
+		// handled in _main()
+	}
 	else {
 		dyld::warn("unknown environment variable: %s\n", key);
 	}
@@ -1620,15 +1619,12 @@
 						if ( strncmp(&equals[-5], "_PATH", 5) == 0 ) {
 							const char* value = &equals[1];
 							const size_t keyLen = equals-keyEqualsValue;
-							// <rdar://problem/22799635> don't let malformed load command overflow stack
-							if ( keyLen < 40 ) {
-								char key[keyLen+1];
-								strncpy(key, keyEqualsValue, keyLen);
-								key[keyLen] = '\0';
-								//dyld::log("processing: %s\n", keyEqualsValue);
-								//dyld::log("mainExecutableDir: %s\n", mainExecutableDir);
-								processDyldEnvironmentVariable(key, value, mainExecutableDir);
-							}
+							char key[keyLen+1];
+							strncpy(key, keyEqualsValue, keyLen);
+							key[keyLen] = '\0';
+							//dyld::log("processing: %s\n", keyEqualsValue);
+							//dyld::log("mainExecutableDir: %s\n", mainExecutableDir);
+							processDyldEnvironmentVariable(key, value, mainExecutableDir);
 						}
 					}
 				}
@@ -1731,47 +1727,16 @@
 		strlcat(sLoadingCrashMessage, ", ignoring DYLD_* env vars", sizeof(sLoadingCrashMessage));
 }
 
-static void defaultUninitializedFallbackPaths(const char* envp[])
-{
-#if __MAC_OS_X_VERSION_MIN_REQUIRED
-	// default value for DYLD_FALLBACK_FRAMEWORK_PATH, if not set in environment
-	const char* home = _simple_getenv(envp, "HOME");;
-	if ( sEnv.DYLD_FALLBACK_FRAMEWORK_PATH == NULL ) {
-		const char** fpaths = sFrameworkFallbackPaths;
-		if ( home == NULL )
-			removePathWithPrefix(fpaths, "$HOME");
-		else
-			paths_expand_roots(fpaths, "$HOME", home);
-		sEnv.DYLD_FALLBACK_FRAMEWORK_PATH = fpaths;
-	}
-
-    // default value for DYLD_FALLBACK_LIBRARY_PATH, if not set in environment
-	if ( sEnv.DYLD_FALLBACK_LIBRARY_PATH == NULL ) {
-		const char** lpaths = sLibraryFallbackPaths;
-		if ( home == NULL )
-			removePathWithPrefix(lpaths, "$HOME");
-		else
-			paths_expand_roots(lpaths, "$HOME", home);
-		sEnv.DYLD_FALLBACK_LIBRARY_PATH = lpaths;
-	}
-#else
-	if ( sEnv.DYLD_FALLBACK_FRAMEWORK_PATH == NULL )
-		sEnv.DYLD_FALLBACK_FRAMEWORK_PATH = sFrameworkFallbackPaths;
-
-	if ( sEnv.DYLD_FALLBACK_LIBRARY_PATH == NULL )
-		sEnv.DYLD_FALLBACK_LIBRARY_PATH = sLibraryFallbackPaths;
-#endif
-}
-
-
-static void checkEnvironmentVariables(const char* envp[])
-{
+
+static void checkEnvironmentVariables(const char* envp[], bool ignoreEnviron)
+{
+	const char* home = NULL;
 	const char** p;
 	for(p = envp; *p != NULL; p++) {
 		const char* keyEqualsValue = *p;
 	    if ( strncmp(keyEqualsValue, "DYLD_", 5) == 0 ) {
 			const char* equals = strchr(keyEqualsValue, '=');
-			if ( equals != NULL ) {
+			if ( (equals != NULL) && !ignoreEnviron ) {
 				strlcat(sLoadingCrashMessage, "\n", sizeof(sLoadingCrashMessage));
 				strlcat(sLoadingCrashMessage, keyEqualsValue, sizeof(sLoadingCrashMessage));
 				const char* value = &equals[1];
@@ -1782,6 +1747,9 @@
 				processDyldEnvironmentVariable(key, value, NULL);
 			}
 		}
+	    else if ( strncmp(keyEqualsValue, "HOME=", 5) == 0 ) {
+			home = &keyEqualsValue[5];
+		}
 		else if ( strncmp(keyEqualsValue, "LD_LIBRARY_PATH=", 16) == 0 ) {
 			const char* path = &keyEqualsValue[16];
 			sEnv.LD_LIBRARY_PATH = parseColonList(path, NULL);
@@ -1791,44 +1759,40 @@
 #if SUPPORT_LC_DYLD_ENVIRONMENT
 	checkLoadCommandEnvironmentVariables();
 #endif // SUPPORT_LC_DYLD_ENVIRONMENT	
+	
+	// default value for DYLD_FALLBACK_FRAMEWORK_PATH, if not set in environment
+	if ( sEnv.DYLD_FALLBACK_FRAMEWORK_PATH == NULL ) {
+		const char** paths = sFrameworkFallbackPaths;
+		if ( home == NULL )
+			removePathWithPrefix(paths, "$HOME");
+		else
+			paths_expand_roots(paths, "$HOME", home);
+		sEnv.DYLD_FALLBACK_FRAMEWORK_PATH = paths;
+	}
+
+	// default value for DYLD_FALLBACK_LIBRARY_PATH, if not set in environment
+	if ( sEnv.DYLD_FALLBACK_LIBRARY_PATH == NULL ) {
+		const char** paths = sLibraryFallbackPaths;
+		if ( home == NULL ) 
+			removePathWithPrefix(paths, "$HOME");
+		else
+			paths_expand_roots(paths, "$HOME", home);
+		sEnv.DYLD_FALLBACK_LIBRARY_PATH = paths;
+	}
 	
 	// <rdar://problem/11281064> DYLD_IMAGE_SUFFIX and DYLD_ROOT_PATH cannot be used together
 	if ( (gLinkContext.imageSuffix != NULL) && (gLinkContext.rootPaths != NULL) ) {
 		dyld::warn("Ignoring DYLD_IMAGE_SUFFIX because DYLD_ROOT_PATH is used.\n");
 		gLinkContext.imageSuffix = NULL;
 	}
-}
-
-#if __x86_64__
-static bool isGCProgram(const macho_header* mh, uintptr_t slide)
-{
-	const uint32_t cmd_count = mh->ncmds;
-	const struct load_command* const cmds = (struct load_command*)(((char*)mh)+sizeof(macho_header));
-	const struct load_command* cmd = cmds;
-	for (uint32_t i = 0; i < cmd_count; ++i) {
-		switch (cmd->cmd) {
-			case LC_SEGMENT_COMMAND:
-			{
-				const struct macho_segment_command* seg = (struct macho_segment_command*)cmd;
-				if (strcmp(seg->segname, "__DATA") == 0) {
-					const struct macho_section* const sectionsStart = (struct macho_section*)((char*)seg + sizeof(struct macho_segment_command));
-					const struct macho_section* const sectionsEnd = &sectionsStart[seg->nsects];
-					for (const struct macho_section* sect=sectionsStart; sect < sectionsEnd; ++sect) {
-						if (strncmp(sect->sectname, "__objc_imageinfo", 16) == 0) {
-							const uint32_t*  objcInfo = (uint32_t*)(sect->addr + slide);
-							return (objcInfo[1] & 6); // 6 = (OBJC_IMAGE_SUPPORTS_GC | OBJC_IMAGE_REQUIRES_GC)
-						}
-					}
-				}
-			}
-			break;
-		}
-		cmd = (const struct load_command*)(((char*)cmd)+cmd->cmdsize);
-	}
-	return false;
-}
-#endif
-static void getHostInfo(const macho_header* mainExecutableMH, uintptr_t mainExecutableSlide)
+	
+#if SUPPORT_VERSIONED_PATHS
+	checkVersionedPaths();
+#endif	
+}
+
+
+static void getHostInfo()
 {
 #if CPU_SUBTYPES_SUPPORTED
 #if __ARM_ARCH_7K__
@@ -1856,22 +1820,6 @@
 	sHostCPU		= info.cpu_type;
 	sHostCPUsubtype = info.cpu_subtype;
 	mach_port_deallocate(mach_task_self(), hostPort);
-  #if __x86_64__
-	#if TARGET_IPHONE_SIMULATOR
-	  sHaswell = false;
-	#else
-	  sHaswell = (sHostCPUsubtype == CPU_SUBTYPE_X86_64_H);
-	  // <rdar://problem/18528074> x86_64h: Fall back to the x86_64 slice if an app requires GC.
-	  if ( sHaswell ) {
-		if ( isGCProgram(mainExecutableMH, mainExecutableSlide) ) {
-			// When running a GC program on a haswell machine, don't use and 'h slices
-			sHostCPUsubtype = CPU_SUBTYPE_X86_64_ALL;
-			sHaswell = false;
-			gLinkContext.sharedRegionMode = ImageLoader::kDontUseSharedRegion;
-		}
-	  }
-	#endif
-  #endif
 #endif
 #endif
 }
@@ -2432,13 +2380,11 @@
 	for (uint32_t i = 0; i < cmd_count; ++i) {
 		switch (cmd->cmd) {
 			case LC_VERSION_MIN_IPHONEOS:
-			case LC_VERSION_MIN_TVOS:
-			case LC_VERSION_MIN_WATCHOS:
 				return true;
 			case LC_VERSION_MIN_MACOSX:
 				// grandfather in a few libSystem dylibs
-				if (strstr(path, "/usr/lib/system") || strstr(path, "/usr/lib/libSystem"))
- 					return true;
+				if ( strncmp(path, "/usr/lib/system/libsystem_", 26) == 0 )
+					return true;
 				return false;
 		}
 		cmd = (const struct load_command*)(((char*)cmd)+cmd->cmdsize);
@@ -2502,16 +2448,12 @@
 			default:
 				throw "mach-o, but wrong filetype";
 		}
-
+		
 #if TARGET_IPHONE_SIMULATOR	
-	#if TARGET_OS_WATCH || TARGET_OS_TV
-		// disable error during bring up of these simulators
-	#else
 		// <rdar://problem/14168872> dyld_sim should restrict loading osx binaries
 		if ( !isSimulatorBinary(firstPage, path) ) {
 			throw "mach-o, but not built for iOS simulator";
 		}
-	#endif
 #endif
 
 		// instantiate an image
@@ -2787,7 +2729,7 @@
 	ImageLoader* image = NULL;
 	if ( strncmp(path, "@executable_path/", 17) == 0 ) {
 		// executable_path cannot be in used in any binary in a setuid process rdar://problem/4589305
-		if ( sProcessIsRestricted && !sProcessRequiresLibraryValidation )
+		if ( sProcessIsRestricted ) 
 			throwf("unsafe use of @executable_path in %s with restricted binary", context.origin);
 		// handle @executable_path path prefix
 		const char* executablePath = sExecPath;
@@ -2819,7 +2761,7 @@
 	}
 	else if ( (strncmp(path, "@loader_path/", 13) == 0) && (context.origin != NULL) ) {
 		// @loader_path cannot be used from the main executable of a setuid process rdar://problem/4589305
-		if ( sProcessIsRestricted && (strcmp(context.origin, sExecPath) == 0) && !sProcessRequiresLibraryValidation )
+		if ( sProcessIsRestricted && (strcmp(context.origin, sExecPath) == 0) )
 			throwf("unsafe use of @loader_path in %s with restricted binary", context.origin);
 		// handle @loader_path path prefix
 		char newPath[strlen(context.origin) + strlen(path)];
@@ -2883,7 +2825,7 @@
 		if ( (exceptions != NULL) && (trailingPath != path) )
 			return NULL;
 	}
-	else if (sProcessIsRestricted && (path[0] != '/' ) && !sProcessRequiresLibraryValidation) {
+	else if (sProcessIsRestricted && (path[0] != '/' )) {
 		throwf("unsafe use of relative rpath %s in %s with restricted binary", path, context.origin);
 	}
 	
@@ -3243,23 +3185,6 @@
 const void*	imMemorySharedCacheHeader()
 {
 	return sSharedCache;
-}
-
-const char* getStandardSharedCacheFilePath()
-{
-#if __IPHONE_OS_VERSION_MIN_REQUIRED
-	return IPHONE_DYLD_SHARED_CACHE_DIR DYLD_SHARED_CACHE_BASE_NAME ARCH_NAME;
-#else
-  #if __x86_64__
-	if ( sHaswell ) {
-		const char* path2 = MACOSX_DYLD_SHARED_CACHE_DIR DYLD_SHARED_CACHE_BASE_NAME ARCH_NAME_H;
-		struct stat statBuf;
-		if ( my_stat(path2, &statBuf) == 0 )
-			return path2;
-	}
-  #endif
-	return MACOSX_DYLD_SHARED_CACHE_DIR DYLD_SHARED_CACHE_BASE_NAME ARCH_NAME;
-#endif
 }
 
 int openSharedCacheFile()
@@ -3629,8 +3554,7 @@
 			// zero size in header means signature runs to end-of-file
 			if ( signatureSize == 0 ) {
 				struct stat stat_buf;
-				// FIXME: need size of cache file actually used
-				if ( my_stat(IPHONE_DYLD_SHARED_CACHE_DIR DYLD_SHARED_CACHE_BASE_NAME ARCH_NAME, &stat_buf) == 0 )
+				if ( my_stat(IPHONE_DYLD_SHARED_CACHE_DIR DYLD_SHARED_CACHE_BASE_NAME ARCH_NAME, &stat_buf) == 0 ) 
 					signatureSize = stat_buf.st_size - header->codeSignatureOffset;
 			}
 			if ( signatureSize != 0 ) {
@@ -4088,6 +4012,16 @@
 }
 
 
+#if __LP64__
+	#define LC_SEGMENT_COMMAND		LC_SEGMENT_64
+	#define macho_segment_command	segment_command_64
+	#define macho_section			section_64
+#else
+	#define LC_SEGMENT_COMMAND		LC_SEGMENT
+	#define macho_segment_command	segment_command
+	#define macho_section			section
+#endif
+
 
 //
 // Look for a special segment in the mach header. 
@@ -4123,18 +4057,20 @@
 	return false;
 }
 
-
 #if SUPPORT_VERSIONED_PATHS
-
-static bool readFirstPage(const char* dylibPath, uint8_t firstPage[4096]) 
-{
-	firstPage[0] = 0;
+//
+// Peeks at a dylib file and returns its current_version and install_name.
+// Returns false on error.
+//			
+static bool getDylibVersionAndInstallname(const char* dylibPath, uint32_t* version, char* installName)
+{
 	// open file (automagically closed when this function exits)
 	FileOpener file(dylibPath);
-
+	
 	if ( file.getFileDescriptor() == -1 ) 
 		return false;
 	
+	uint8_t firstPage[4096];
 	if ( pread(file.getFileDescriptor(), firstPage, 4096, 0) != 4096 )
 		return false;
 
@@ -4151,33 +4087,9 @@
 			return false;
 		}
 	}
-	
-	return true;
-}
-
-//
-// Peeks at a dylib file and returns its current_version and install_name.
-// Returns false on error.
-//
-static bool getDylibVersionAndInstallname(const char* dylibPath, uint32_t* version, char* installName)
-{
-	uint8_t firstPage[4096];
-	const macho_header* mh = (macho_header*)firstPage;
-	if ( !readFirstPage(dylibPath, firstPage) ) {
-	#if DYLD_SHARED_CACHE_SUPPORT
-		// If file cannot be read, check to see if path is in shared cache
-		const macho_header* mhInCache;
-		const char*			pathInCache;
-		long				slideInCache;
-		if ( !findInSharedCacheImage(dylibPath, true, NULL, &mhInCache, &pathInCache, &slideInCache) )
-			return false;
-		mh = mhInCache;
-	#else
-		return false;
-	#endif
-	}
 
 	// check mach-o header
+	const mach_header* mh = (mach_header*)firstPage;
 	if ( mh->magic != sMainExecutableMachHeader->magic ) 
 		return false;
 	if ( mh->cputype != sMainExecutableMachHeader->cputype )
@@ -4291,16 +4203,13 @@
 		for (std::vector<ImageLoader*>::iterator it=sAllImages.begin(); it != sAllImages.end(); it++) {
 			ImageLoader* image = *it;
 			if ( (image->dlopenCount() != 0) || image->neverUnload() ) {
-				OSSpinLockLock(&sDynamicReferencesLock);
-					image->markedUsedRecursive(sDynamicReferences);
-				OSSpinLockUnlock(&sDynamicReferencesLock);
+				image->markedUsedRecursive(sDynamicReferences);
 			}
 		}
 
 		// collect phase: build array of images not marked in-use
 		ImageLoader* deadImages[sAllImages.size()];
 		unsigned deadCount = 0;
-		int maxRangeCount = 0;
 		unsigned i = 0;
 		for (std::vector<ImageLoader*>::iterator it=sAllImages.begin(); it != sAllImages.end(); it++) {
 			ImageLoader* image = *it;
@@ -4308,11 +4217,11 @@
 				deadImages[i++] = image;
 				if (gLogAPIs) dyld::log("dlclose(), found unused image %p %s\n", image, image->getShortName());
 				++deadCount;
-				maxRangeCount += image->segmentCount();
 			}
 		}
 
 		// collect phase: run termination routines for images not marked in-use
+		const int maxRangeCount = deadCount*2;
 		__cxa_range_t ranges[maxRangeCount];
 		int rangeCount = 0;
 		for (unsigned i=0; i < deadCount; ++i) {
@@ -4391,6 +4300,25 @@
 	preflight_finally(image);
 }
 
+#if __x86_64__
+static bool isHaswell()
+{
+#if TARGET_IPHONE_SIMULATOR
+	return false;
+#else
+	// check system is capable of running x86_64h code
+	struct host_basic_info info;
+	mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT;
+	mach_port_t hostPort = mach_host_self();
+	kern_return_t result = host_info(hostPort, HOST_BASIC_INFO, (host_info_t)&info, &count);
+	mach_port_deallocate(mach_task_self(), hostPort);
+	if ( result != KERN_SUCCESS )
+		return false;
+	return ( info.cpu_subtype == CPU_SUBTYPE_X86_64_H );
+#endif
+}
+#endif
+
 static void loadInsertedDylib(const char* path)
 {
 	ImageLoader* image = NULL;
@@ -4413,10 +4341,7 @@
 #if TARGET_IPHONE_SIMULATOR
 		dyld::log("dyld: warning: could not load inserted library '%s' because %s\n", path, msg);
 #else
-		if ( sProcessRequiresLibraryValidation )
-			dyld::log("dyld: warning: could not load inserted library '%s' into library validated process because %s\n", path, msg);
-		else
-			halt(dyld::mkstringf("could not load inserted library '%s' because %s\n", path, msg));
+		halt(dyld::mkstringf("could not load inserted library '%s' because %s\n", path, msg));
 #endif
 	}
 	catch (...) {
@@ -4424,34 +4349,24 @@
 	}
 }
 
-static bool processRestricted(const macho_header* mainExecutableMH, bool* ignoreEnvVars, bool* processRequiresLibraryValidation)
+static bool processRestricted(const macho_header* mainExecutableMH)
 {	
-#if TARGET_IPHONE_SIMULATOR
-	gLinkContext.codeSigningEnforced = true;
-#else
+#if __MAC_OS_X_VERSION_MIN_REQUIRED
     // ask kernel if code signature of program makes it restricted
     uint32_t flags;
 	if ( csops(0, CS_OPS_STATUS, &flags, sizeof(flags)) != -1 ) {
-		if (flags & CS_REQUIRE_LV)
-			*processRequiresLibraryValidation = true;
-
-  #if __MAC_OS_X_VERSION_MIN_REQUIRED
 		if ( flags & CS_ENFORCEMENT ) {
 			gLinkContext.codeSigningEnforced = true;
 		}
-		if ( ((flags & CS_RESTRICT) == CS_RESTRICT) && (csr_check(CSR_ALLOW_TASK_FOR_PID) != 0) ) {
-			sRestrictedReason = restrictedByEntitlements;
-			return true;
-		}
-  #else
-		if ((flags & CS_ENFORCEMENT) && !(flags & CS_GET_TASK_ALLOW)) {
-			*ignoreEnvVars = true;
-		}
-		gLinkContext.codeSigningEnforced = true;
-  #endif
-	}
-#endif
-
+	}
+	if (flags & CS_RESTRICT) {
+		sRestrictedReason = restrictedByEntitlements;
+		return true;
+	}
+#else
+	gLinkContext.codeSigningEnforced = true;
+#endif
+	
 	// all processes with setuid or setgid bit set are restricted
     if ( issetugid() ) {
 		sRestrictedReason = restrictedBySetGUid;
@@ -4502,7 +4417,7 @@
 typedef int (*ioctl_proc_t)(int, unsigned long, void*);
 static void* getProcessInfo() { return dyld::gProcessInfo; }
 static SyscallHelpers sSysCalls = {
-		4,
+		3,
 		// added in version 1
 		(open_proc_t)&open, 
 		&close, 
@@ -4538,10 +4453,7 @@
 		// added in version 3
 		&opendir,
 		&readdir_r,
-		&closedir,
-		// added in version 4
-		&coresymbolication_load_notifier,
-		&coresymbolication_unload_notifier
+		&closedir
 };
 
 __attribute__((noinline))
@@ -4553,6 +4465,8 @@
 	// verify simulator dyld file is owned by root
 	struct stat sb;
 	if ( fstat(fd, &sb) == -1 )
+		return 0;
+	if ( sb.st_uid != 0 )
 		return 0;
 
 	// read first page of dyld file
@@ -4577,73 +4491,32 @@
 	
 	// calculate total size of dyld segments
 	const macho_header* mh = (const macho_header*)firstPage;
-	struct macho_segment_command* lastSeg = NULL;
-	struct macho_segment_command* firstSeg = NULL;
 	uintptr_t mappingSize = 0;
 	uintptr_t preferredLoadAddress = 0;
 	const uint32_t cmd_count = mh->ncmds;
-	if ( (sizeof(macho_header) + mh->sizeofcmds) > 4096 )
-		return 0;
 	const struct load_command* const cmds = (struct load_command*)(((char*)mh)+sizeof(macho_header));
-	const struct load_command* const endCmds = (struct load_command*)(((char*)mh) + sizeof(macho_header) + mh->sizeofcmds);
 	const struct load_command* cmd = cmds;
 	for (uint32_t i = 0; i < cmd_count; ++i) {
-		uint32_t cmdLength = cmd->cmdsize;
-		if ( cmdLength < 8 )
-			return 0;
-		const struct load_command* const nextCmd = (const struct load_command*)(((char*)cmd)+cmdLength);
-		if ( (nextCmd > endCmds) || (nextCmd < cmd) )
-			return 0;
 		switch (cmd->cmd) {
 			case LC_SEGMENT_COMMAND:
 				{
 					struct macho_segment_command* seg = (struct macho_segment_command*)cmd;
-					if ( seg->vmaddr + seg->vmsize < seg->vmaddr )
-						return 0;
-					if ( seg->vmsize < seg->filesize )
-						return 0;
-					if ( lastSeg == NULL ) {
-						// first segment must be __TEXT and start at beginning of file/slice
-						firstSeg = seg;
-						if ( strcmp(seg->segname, "__TEXT") != 0 )
-							return 0;
-						if ( seg->fileoff != 0 )
-							return 0;
-						if ( seg->filesize < (sizeof(macho_header) + mh->sizeofcmds) )
-							return 0;
+					mappingSize += seg->vmsize;
+					if ( seg->fileoff == 0 )
 						preferredLoadAddress = seg->vmaddr;
-					}
-					else {
-						// other sements must be continguous with previous segment and not executable
-						if ( lastSeg->fileoff + lastSeg->filesize != seg->fileoff )
-							return 0;
-						if ( lastSeg->vmaddr + lastSeg->vmsize != seg->vmaddr )
-							return 0;
-						if ( (seg->initprot & VM_PROT_EXECUTE) != 0 )
-							return 0;
-					}
-					mappingSize += seg->vmsize;
-					lastSeg = seg;
 				}
 				break;
-			case LC_SEGMENT_COMMAND_WRONG:
-				return 0;
-		}
-		cmd = nextCmd;
-	}
-	// last segment must be named __LINKEDIT and not writable
-	if ( strcmp(lastSeg->segname, "__LINKEDIT") != 0 )
-		return 0;
-	if ( lastSeg->initprot & VM_PROT_WRITE )
-		return 0;
+		}
+		cmd = (const struct load_command*)(((char*)cmd)+cmd->cmdsize);
+	}
 
 	// reserve space, then mmap each segment
 	vm_address_t loadAddress = 0;
+	uintptr_t entry = 0;
 	if ( ::vm_allocate(mach_task_self(), &loadAddress, mappingSize, VM_FLAGS_ANYWHERE) != 0 )
 		return 0;
 	cmd = cmds;
 	struct linkedit_data_command* codeSigCmd = NULL;
-	struct source_version_command* dyldVersionCmd = NULL;
 	for (uint32_t i = 0; i < cmd_count; ++i) {
 		switch (cmd->cmd) {
 			case LC_SEGMENT_COMMAND:
@@ -4654,68 +4527,38 @@
 					//dyld::log("dyld_sim %s mapped at %p\n", seg->segname, segAddress);
 					if ( segAddress == (void*)(-1) )
 						return 0;
-					if ( ((uintptr_t)segAddress < loadAddress) || ((uintptr_t)segAddress+seg->filesize > loadAddress+mappingSize) )
-						return 0;
+				}
+				break;
+			case LC_UNIXTHREAD:
+				{
+				#if __i386__
+					const i386_thread_state_t* registers = (i386_thread_state_t*)(((char*)cmd) + 16);
+					entry = (registers->__eip + loadAddress - preferredLoadAddress);
+				#elif __x86_64__
+					const x86_thread_state64_t* registers = (x86_thread_state64_t*)(((char*)cmd) + 16);
+					entry = (registers->__rip + loadAddress - preferredLoadAddress);
+				#endif
 				}
 				break;
 			case LC_CODE_SIGNATURE:
 				codeSigCmd = (struct linkedit_data_command*)cmd;
 				break;
-			case LC_SOURCE_VERSION:
-				dyldVersionCmd = (struct source_version_command*)cmd;
-				break;
 		}
 		cmd = (const struct load_command*)(((char*)cmd)+cmd->cmdsize);
 	}
-
-	// must have code signature which is contained within LINKEDIT segment
-	if ( codeSigCmd == NULL )
-		return 0;
-	if ( codeSigCmd->dataoff < lastSeg->fileoff )
-		return 0;
-	if ( (codeSigCmd->dataoff + codeSigCmd->datasize) > (lastSeg->fileoff + lastSeg->filesize) )
-		return 0;
-
-	fsignatures_t siginfo;
-	siginfo.fs_file_start=fileOffset;							// start of mach-o slice in fat file 
-	siginfo.fs_blob_start=(void*)(long)(codeSigCmd->dataoff);	// start of code-signature in mach-o file
-	siginfo.fs_blob_size=codeSigCmd->datasize;					// size of code-signature
-	int result = fcntl(fd, F_ADDFILESIGS_FOR_DYLD_SIM, &siginfo);
-	if ( result == -1 ) {
-		dyld::log("fcntl(F_ADDFILESIGS_FOR_DYLD_SIM) failed with errno=%d\n", errno);
-		return 0;
+	
+	if ( codeSigCmd != NULL ) {
+		fsignatures_t siginfo;
+		siginfo.fs_file_start=fileOffset;							// start of mach-o slice in fat file 
+		siginfo.fs_blob_start=(void*)(long)(codeSigCmd->dataoff);	// start of code-signature in mach-o file
+		siginfo.fs_blob_size=codeSigCmd->datasize;					// size of code-signature
+		int result = fcntl(fd, F_ADDFILESIGS, &siginfo);
+		if ( result == -1 ) {
+			if ( (errno == EPERM) || (errno == EBADEXEC) )
+				return 0;
+		}
 	}
 	close(fd);
-	// file range covered by code signature must extend up to code signature itself
-	if ( siginfo.fs_file_start < codeSigCmd->dataoff )
-		return 0;
-
-	// walk newly mapped dyld_sim __TEXT load commands to find entry point
-	uintptr_t entry = 0;
-	cmd = (struct load_command*)(((char*)loadAddress)+sizeof(macho_header));
-	const uint32_t count = ((macho_header*)(loadAddress))->ncmds;
-	for (uint32_t i = 0; i < count; ++i) {
-		if (cmd->cmd == LC_UNIXTHREAD) {
-		#if __i386__
-			const i386_thread_state_t* registers = (i386_thread_state_t*)(((char*)cmd) + 16);
-			// entry point must be in first segment
-			if ( registers->__eip < firstSeg->vmaddr )
-				return 0;
-			if ( registers->__eip > (firstSeg->vmaddr + firstSeg->vmsize) )
-				return 0;
-			entry = (registers->__eip + loadAddress - preferredLoadAddress);
-		#elif __x86_64__
-			const x86_thread_state64_t* registers = (x86_thread_state64_t*)(((char*)cmd) + 16);
-			// entry point must be in first segment
-			if ( registers->__rip < firstSeg->vmaddr )
-				return 0;
-			if ( registers->__rip > (firstSeg->vmaddr + firstSeg->vmsize) )
-				return 0;
-			entry = (registers->__rip + loadAddress - preferredLoadAddress);
-		#endif
-		}
-		cmd = (const struct load_command*)(((char*)cmd)+cmd->cmdsize);
-	}
 
 	// notify debugger that dyld_sim is loaded
 	dyld_image_info info;
@@ -4724,14 +4567,13 @@
 	info.imageFileModDate = sb.st_mtime;
 	addImagesToAllImages(1, &info);
 	dyld::gProcessInfo->notification(dyld_image_adding, 1, &info);
-
-	const char** appleParams = apple;
+	
 	// jump into new simulator dyld
 	typedef uintptr_t (*sim_entry_proc_t)(int argc, const char* argv[], const char* envp[], const char* apple[],
 								const macho_header* mainExecutableMH, const macho_header* dyldMH, uintptr_t dyldSlide,
 								const dyld::SyscallHelpers* vtable, uintptr_t* startGlue);
 	sim_entry_proc_t newDyld = (sim_entry_proc_t)entry;
-	return (*newDyld)(argc, argv, envp, appleParams, mainExecutableMH, (macho_header*)loadAddress,
+	return (*newDyld)(argc, argv, envp, apple, mainExecutableMH, (macho_header*)loadAddress, 
 					 loadAddress - preferredLoadAddress, 
 					 &sSysCalls, startGlue);
 }
@@ -4751,6 +4593,19 @@
 {
 	uintptr_t result = 0;
 	sMainExecutableMachHeader = mainExecutableMH;
+#if !TARGET_IPHONE_SIMULATOR
+	const char* loggingPath = _simple_getenv(envp, "DYLD_PRINT_TO_FILE");
+	if ( loggingPath != NULL ) {
+		int fd = open(loggingPath, O_WRONLY | O_CREAT | O_APPEND, 0644);
+		if ( fd != -1 ) {
+			sLogfile = fd;
+			sLogToFile = true;
+		}
+		else {
+			dyld::log("dyld: could not open DYLD_PRINT_TO_FILE='%s', errno=%d\n", loggingPath, errno);
+		}
+	}
+#endif
 #if __MAC_OS_X_VERSION_MIN_REQUIRED
 	// if this is host dyld, check to see if iOS simulator is being run
 	const char* rootPath = _simple_getenv(envp, "DYLD_ROOT_PATH");
@@ -4798,6 +4653,7 @@
 	// <rdar://problem/13868260> Remove interim apple[0] transition code from dyld
 	if (!sExecPath) sExecPath = apple[0];
 	
+	sExecPath = apple[0];
 	bool ignoreEnvironmentVariables = false;
 	if ( sExecPath[0] != '/' ) {
 		// have relative path, use cwd to make absolute
@@ -4817,25 +4673,25 @@
 		++sExecShortName;
 	else
 		sExecShortName = sExecPath;
-    sProcessIsRestricted = processRestricted(mainExecutableMH, &ignoreEnvironmentVariables, &sProcessRequiresLibraryValidation);
+    sProcessIsRestricted = processRestricted(mainExecutableMH);
     if ( sProcessIsRestricted ) {
 #if SUPPORT_LC_DYLD_ENVIRONMENT
 		checkLoadCommandEnvironmentVariables();
+#if SUPPORT_VERSIONED_PATHS
+		checkVersionedPaths();
+#endif	
 #endif 	
 		pruneEnvironmentVariables(envp, &apple);
 		// set again because envp and apple may have changed or moved
 		setContext(mainExecutableMH, argc, argv, envp, apple);
 	}
-	else {
-		if ( !ignoreEnvironmentVariables )
-			checkEnvironmentVariables(envp);
-		defaultUninitializedFallbackPaths(envp);
-	}
-	if ( sEnv.DYLD_PRINT_OPTS )
+	else
+		checkEnvironmentVariables(envp, ignoreEnvironmentVariables);
+	if ( sEnv.DYLD_PRINT_OPTS ) 
 		printOptions(argv);
 	if ( sEnv.DYLD_PRINT_ENV ) 
 		printEnvironmentVariables(envp);
-	getHostInfo(mainExecutableMH, mainExecutableSlide);
+	getHostInfo();
 	// install gdb notifier
 	stateToHandlers(dyld_image_state_dependents_mapped, sBatchHandlers)->push_back(notifyGDB);
 	stateToHandlers(dyld_image_state_mapped, sSingleHandlers)->push_back(updateAllImages);
@@ -4861,13 +4717,9 @@
 		sMainExecutable = instantiateFromLoadedImage(mainExecutableMH, mainExecutableSlide, sExecPath);
 		gLinkContext.mainExecutable = sMainExecutable;
 		gLinkContext.processIsRestricted = sProcessIsRestricted;
-		gLinkContext.processRequiresLibraryValidation = sProcessRequiresLibraryValidation;
 		gLinkContext.mainExecutableCodeSigned = hasCodeSignatureLoadCommand(mainExecutableMH);
 
 #if TARGET_IPHONE_SIMULATOR
-	#if TARGET_OS_WATCH || TARGET_OS_TV
-		// disable error during bring up of these simulators
-	#else
 		// check main executable is not too new for this OS
 		{
 			if ( ! isSimulatorBinary((uint8_t*)mainExecutableMH, sExecPath) ) {
@@ -4883,21 +4735,17 @@
 						dyldMinOS >> 16, ((dyldMinOS >> 8) & 0xFF));
 			}
 		}
+#endif
+
+		// load shared cache
+	#if __x86_64__
+		sHaswell = isHaswell();
 	#endif
-#endif
-
-		// load shared cache
 		checkSharedRegionDisable();
 	#if DYLD_SHARED_CACHE_SUPPORT
 		if ( gLinkContext.sharedRegionMode != ImageLoader::kDontUseSharedRegion )
 			mapSharedCache();
 	#endif
-
-		// Now that shared cache is loaded, setup an versioned dylib overrides
-	#if SUPPORT_VERSIONED_PATHS
-		checkVersionedPaths();
-	#endif
-
 		// load any inserted libraries
 		if	( sEnv.DYLD_INSERT_LIBRARIES != NULL ) {
 			for (const char* const* lib = sEnv.DYLD_INSERT_LIBRARIES; *lib != NULL; ++lib) 
@@ -4932,15 +4780,6 @@
 				image->registerInterposing();
 			}
 		}
-
-		// <rdar://problem/19315404> dyld should support interposition even without DYLD_INSERT_LIBRARIES
-		for (int i=sInsertedDylibCount+1; i < sAllImages.size(); ++i) {
-			ImageLoader* image = sAllImages[i];
-			if ( image->inSharedCache() )
-				continue;
-			image->registerInterposing();
-		}
-
 		// apply interposing to initial set of images
 		for(int i=0; i < sImageRoots.size(); ++i) {
 			sImageRoots[i]->applyInterposing(gLinkContext);