Loading...
dyld3/SharedCacheRuntime.cpp dyld-732.8 dyld-635.2
--- dyld/dyld-732.8/dyld3/SharedCacheRuntime.cpp
+++ dyld/dyld-635.2/dyld3/SharedCacheRuntime.cpp
@@ -46,7 +46,6 @@
 #include "dyld_cache_format.h"
 #include "SharedCacheRuntime.h"
 #include "Loading.h"
-#include "BootArgs.h"
 
 #define ENABLE_DYLIBS_TO_OVERRIDE_CACHE_SIZE 1024
 
@@ -71,6 +70,7 @@
     shared_file_mapping_np  mappings[3];
     uint64_t                slideInfoAddressUnslid;
     size_t                  slideInfoSize;
+    uint64_t                cachedDylibsGroupUnslid;
     uint64_t                sharedRegionStart;
     uint64_t                sharedRegionSize;
     uint64_t                maxSlide;
@@ -110,7 +110,7 @@
 #endif
 
 
-#if !TARGET_OS_SIMULATOR
+
 static void rebaseChainV2(uint8_t* pageContent, uint16_t startOffset, uintptr_t slideAmount, const dyld_cache_slide_info2* slideInfo)
 {
     const uintptr_t   deltaMask    = (uintptr_t)(slideInfo->delta_mask);
@@ -134,9 +134,8 @@
         pageOffset += delta;
     }
 }
-#endif
-
-#if !__LP64__ && !TARGET_OS_SIMULATOR
+
+#if !__LP64__
 static void rebaseChainV4(uint8_t* pageContent, uint16_t startOffset, uintptr_t slideAmount, const dyld_cache_slide_info4* slideInfo)
 {
     const uintptr_t   deltaMask    = (uintptr_t)(slideInfo->delta_mask);
@@ -197,10 +196,9 @@
         pathBuffer[len] = '\0';
     }
 #endif
-
     strlcat(pathBuffer, DYLD_SHARED_CACHE_BASE_NAME ARCH_NAME, pathBufferSize);
 
-#if __IPHONE_OS_VERSION_MIN_REQUIRED && !TARGET_OS_SIMULATOR
+#if __IPHONE_OS_VERSION_MIN_REQUIRED && !TARGET_IPHONE_SIMULATOR
     // use .development cache if it exists
     struct stat enableStatBuf;
     struct stat devCacheStatBuf;
@@ -209,7 +207,7 @@
     bool enableFileExists = (dyld::my_stat(IPHONE_DYLD_SHARED_CACHE_DIR "enable-dylibs-to-override-cache", &enableStatBuf) == 0);
     bool devCacheExists = (dyld::my_stat(IPHONE_DYLD_SHARED_CACHE_DIR DYLD_SHARED_CACHE_BASE_NAME ARCH_NAME DYLD_SHARED_CACHE_DEVELOPMENT_EXT, &devCacheStatBuf) == 0);
     bool optCacheExists = (dyld::my_stat(IPHONE_DYLD_SHARED_CACHE_DIR DYLD_SHARED_CACHE_BASE_NAME ARCH_NAME, &optCacheStatBuf) == 0);
-    if ( !BootArgs::forceCustomerCache() && developmentDevice && ((enableFileExists && (enableStatBuf.st_size < ENABLE_DYLIBS_TO_OVERRIDE_CACHE_SIZE) && devCacheExists) || !optCacheExists) )
+    if ( developmentDevice && ((enableFileExists && (enableStatBuf.st_size < ENABLE_DYLIBS_TO_OVERRIDE_CACHE_SIZE) && devCacheExists) || !optCacheExists) )
         strlcat(pathBuffer, DYLD_SHARED_CACHE_DEVELOPMENT_EXT, pathBufferSize);
 #endif
 
@@ -246,7 +244,7 @@
     if ( cache->header.platform != (uint32_t)MachOFile::currentPlatform() )
         return false;
 
-#if TARGET_OS_SIMULATOR
+#if TARGET_IPHONE_SIMULATOR
     if ( cache->header.simulator == 0 )
         return false;
 #else
@@ -257,7 +255,7 @@
     return true;
 }
 
-#if !TARGET_OS_SIMULATOR
+
 static void verboseSharedCacheMappings(const shared_file_mapping_np mappings[3])
 {
     for (int i=0; i < 3; ++i) {
@@ -269,21 +267,19 @@
             ((mappings[i].sfm_init_prot & VM_PROT_EXECUTE) ? "execute " : ""));
     }
 }
-#endif
 
 static bool preflightCacheFile(const SharedCacheOptions& options, SharedCacheLoadInfo* results, CacheInfo* info)
 {
-    
     // find and open shared cache file
     int fd = openSharedCacheFile(options, results);
     if ( fd == -1 ) {
-        results->errorMessage = "shared cache file open() failed";
+        results->errorMessage = "shared cache file cannot be opened";
         return false;
     }
 
     struct stat cacheStatBuf;
     if ( dyld::my_stat(results->path, &cacheStatBuf) != 0 ) {
-        results->errorMessage = "shared cache file stat() failed";
+        results->errorMessage = "shared cache file cannot be stat()ed";
         ::close(fd);
         return false;
     }
@@ -292,7 +288,7 @@
     // sanity check header and mappings
     uint8_t firstPage[0x4000];
     if ( ::pread(fd, firstPage, sizeof(firstPage), 0) != sizeof(firstPage) ) {
-        results->errorMessage = "shared cache file pread() failed";
+        results->errorMessage = "shared cache header could not be read";
         ::close(fd);
         return false;
     }
@@ -387,6 +383,10 @@
     info->mappings[1].sfm_init_prot |= VM_PROT_SLIDE;
     info->slideInfoAddressUnslid  = fileMappings[2].address + cache->header.slideInfoOffset - fileMappings[2].fileOffset;
     info->slideInfoSize           = (long)cache->header.slideInfoSize;
+    if ( cache->header.mappingOffset > 0xD0 )
+        info->cachedDylibsGroupUnslid = cache->header.dylibsImageGroupAddr;
+    else
+        info->cachedDylibsGroupUnslid = 0;
     if ( cache->header.mappingOffset >= 0xf8 ) {
         info->sharedRegionStart = cache->header.sharedRegionStart;
         info->sharedRegionSize  = cache->header.sharedRegionSize;
@@ -401,7 +401,7 @@
 }
 
 
-#if !TARGET_OS_SIMULATOR
+#if !TARGET_IPHONE_SIMULATOR
 
 // update all __DATA pages with slide info
 static bool rebaseDataPages(bool isVerbose, CacheInfo& info, SharedCacheLoadInfo* results)
@@ -461,17 +461,15 @@
 #if __has_feature(ptrauth_calls)
                         uint64_t target = info.sharedRegionStart + loc->auth.offsetFromSharedCacheBase + results->slide;
                         MachOLoaded::ChainedFixupPointerOnDisk ptr;
-                        ptr.raw64 = *((uint64_t*)loc);
-                        loc->raw = ptr.arm64e.signPointer(loc, target);
+                        ptr.raw = *((uint64_t*)loc);
+                        loc->raw = ptr.signPointer(loc, target);
 #else
                         results->errorMessage = "invalid pointer kind in cache file";
                         return false;
 #endif
                      }
                      else {
-                        MachOLoaded::ChainedFixupPointerOnDisk ptr;
-                        ptr.raw64 = *((uint64_t*)loc);
-                        loc->raw = ptr.arm64e.unpackTarget() + results->slide;
+                         loc->raw = MachOLoaded::ChainedFixupPointerOnDisk::signExtend51(loc->plain.pointerValue) + results->slide;
                      }
                 } while (delta != 0);
             }
@@ -561,7 +559,7 @@
 #endif
 
     // <rdar://problem/32031197> respect -disable_aslr boot-arg
-    if ( BootArgs::contains("-disable_aslr") )
+    if ( dyld3::bootArgsContains("-disable_aslr") )
         slide = 0;
 
     // update mappings
@@ -605,7 +603,7 @@
     }
     return true;
 }
-#endif // TARGET_OS_SIMULATOR
+#endif // TARGET_IPHONE_SIMULATOR
 
 static bool mapCachePrivate(const SharedCacheOptions& options, SharedCacheLoadInfo* results)
 {
@@ -616,23 +614,16 @@
 
     // compute ALSR slide
     results->slide = 0;
-#if !TARGET_OS_SIMULATOR // simulator caches do not support sliding
+#if !TARGET_IPHONE_SIMULATOR // simulator caches do not support sliding
     if ( info.slideInfoSize != 0 ) {
         results->slide = pickCacheASLR(info);
     }
 #endif
     results->loadAddress = (const DyldSharedCache*)(info.mappings[0].sfm_address);
 
-    // deallocate any existing system wide shared cache
-    deallocateExistingSharedCache();
-
-#if TARGET_OS_SIMULATOR && TARGET_OS_WATCH
-    // <rdar://problem/50887685> watchOS 32-bit cache does not overlap macOS dyld cache address range
-    // mmap() of a file needs a vm_allocation behind it, so make one
-    vm_address_t loadAddress = 0x40000000;
-    ::vm_allocate(mach_task_self(), &loadAddress, 0x40000000, VM_FLAGS_FIXED);
-#endif
-
+    // remove the shared region sub-map
+    vm_deallocate(mach_task_self(), (vm_address_t)info.sharedRegionStart, (vm_size_t)info.sharedRegionSize);
+    
     // map cache just for this process with mmap()
     for (int i=0; i < 3; ++i) {
         void* mmapAddress = (void*)(uintptr_t)(info.mappings[i].sfm_address);
@@ -649,17 +640,15 @@
         if ( ::mmap(mmapAddress, size, protection, MAP_FIXED | MAP_PRIVATE, info.fd, offset) != mmapAddress ) {
             // failed to map some chunk of this shared cache file
             // clear shared region
-            ::mmap((void*)((long)SHARED_REGION_BASE), SHARED_REGION_SIZE, PROT_NONE, MAP_FIXED | MAP_PRIVATE| MAP_ANON, 0, 0);
+            vm_deallocate(mach_task_self(), (vm_address_t)info.sharedRegionStart, (vm_size_t)info.sharedRegionSize);
             // return failure
             results->loadAddress        = nullptr;
             results->errorMessage       = "could not mmap() part of dyld cache";
-            ::close(info.fd);
             return false;
         }
     }
-    ::close(info.fd);
-
-#if TARGET_OS_SIMULATOR // simulator caches do not support sliding
+
+#if TARGET_IPHONE_SIMULATOR // simulator caches do not support sliding
     return true;
 #else
     bool success = rebaseDataPages(options.verbose, info, results);
@@ -680,7 +669,7 @@
     results->slide              = 0;
     results->errorMessage       = nullptr;
 
-#if TARGET_OS_SIMULATOR
+#if TARGET_IPHONE_SIMULATOR
     // simulator only supports mmap()ing cache privately into process
     return mapCachePrivate(options, results);
 #else
@@ -781,26 +770,13 @@
 
 bool pathIsInSharedCacheImage(const SharedCacheLoadInfo& loadInfo, const char* dylibPathToFind)
 {
-    if ( (loadInfo.loadAddress == nullptr) )
+    if ( (loadInfo.loadAddress == nullptr) || (loadInfo.loadAddress->header.formatVersion != closure::kFormatVersion) )
         return false;
 
     uint32_t imageIndex;
     return loadInfo.loadAddress->hasImagePath(dylibPathToFind, imageIndex);
 }
 
-void deallocateExistingSharedCache()
-{
-#if TARGET_OS_SIMULATOR
-    // dyld deallocated macOS shared cache before jumping into dyld_sim
-#else
-    // <rdar://problem/5077374> remove the shared region sub-map
-    uint64_t existingCacheAddress = 0;
-    if ( __shared_region_check_np(&existingCacheAddress) == 0 ) {
-        ::mmap((void*)((long)SHARED_REGION_BASE), SHARED_REGION_SIZE, PROT_NONE, MAP_FIXED | MAP_PRIVATE| MAP_ANON, 0, 0);
-    }
-#endif
-
-}
 
 } // namespace dyld3