diff -Naur dyld-96.2.orig/src/ImageLoader.cpp dyld-96.2/src/ImageLoader.cpp --- dyld-96.2.orig/src/ImageLoader.cpp 2008-03-01 12:02:14.000000000 +1100 +++ dyld-96.2/src/ImageLoader.cpp 2008-11-27 10:58:12.000000000 +1100 @@ -530,7 +530,7 @@ // map in all segments for(ImageLoader::SegmentIterator it = this->beginSegments(); it != this->endSegments(); ++it ) { Segment* seg = *it; - seg->map(fd, offsetInFat, slide, this, context); + seg->map(fd, offsetInFat, lenInFat, slide, this, context); } // update slide to reflect load location this->setSlide(slide); @@ -982,10 +982,15 @@ } } +#define SYS_map_text_segment_sys 8 -void Segment::map(int fd, uint64_t offsetInFatWrapper, intptr_t slide, const ImageLoader* image, const ImageLoader::LinkContext& context) +#define MTS_MODE_DEFAULT 1 +#define MTS_MODE_FIXED 2 +#define MTS_MODE_ANYWHERE 3 + +void Segment::map(int fd, uint64_t offsetInFat, uint64_t lenInFat, intptr_t slide, const ImageLoader* image, const ImageLoader::LinkContext& context) { - vm_offset_t fileOffset = this->getFileOffset() + offsetInFatWrapper; + vm_offset_t fileOffset = this->getFileOffset() + offsetInFat; vm_size_t size = this->getFileSize(); void* requestedLoadAddress = (void*)(this->getPreferredLoadAddress() + slide); int protection = 0; @@ -1004,9 +1009,45 @@ #endif // wholly zero-fill segments have nothing to mmap() in if ( size > 0 ) { - void* loadAddress = mmap(requestedLoadAddress, size, protection, MAP_FIXED | MAP_PRIVATE, fd, fileOffset); - if ( loadAddress == ((void*)(-1)) ) - dyld::throwf("mmap() error %d at address=0x%08lX, size=0x%08lX segment=%s in Segment::map() mapping %s", errno, (uintptr_t)requestedLoadAddress, (uintptr_t)size, this->getName(), image->getPath()); +#if (__x86_64__ || __i386__) + if (strcmp(this->getName(), "__TEXT") == 0) { + uint32_t archOffset = (uint32_t) offsetInFat; + uint32_t archLen = (uint32_t) lenInFat; +# if 0 + uint32_t patcherOpts = 0; + size_t patcherOptsLen = 4; + static int32_t patcherOptsMib[3] = { 0 }; + size_t patcherOptsMibLen = 3; + if (!patcherOptsMib[0]) { + if ((sysctlnametomib("hw.optional.patcher_opts", patcherOptsMib, &patcherOptsMibLen) != 0) || + (patcherOptsMibLen != 3)) + throw "sysctlnametomib() for hw.optional.patcher_opts failed"; + } + if (sysctl(patcherOptsMib, patcherOptsMibLen, &patcherOpts, &patcherOptsLen, NULL, 0) != 0) + throw "sysctl() for hw.optional.patcher_opts failed"; + /* unfortunately, using syslog() here causes linking errors */ + if (patcherOpts & OPT_PATCHER_DEBUG) + dyld::log("dyld: loading %s\n", image->getShortName()); +# endif + void *loadAddress = (void *) ((uint64_t (*)(int, ...)) syscall)(SYS_map_text_segment_sys, fd, archOffset, + archLen, requestedLoadAddress, MTS_MODE_FIXED); + if (loadAddress == (void *) (-1)) + dyld::throwf("map_text_segment_sys() error %d (offset: 0x%x, len: 0x%x, addr: %p) mapping %s", + errno, archOffset, archLen, requestedLoadAddress, image->getPath()); + if (loadAddress != requestedLoadAddress) + dyld::throwf("loadAddress (%p) not requestedLoadAddress (%p) mapping %s", loadAddress, + requestedLoadAddress, image->getPath()); + kern_return_t ret = vm_protect(mach_task_self(), (vm_address_t) loadAddress, size, false, protection); + if (ret != KERN_SUCCESS) + throw "can't set vm permissions for mapped segment"; + } else +#endif + { + void *loadAddress = mmap(requestedLoadAddress, size, protection, MAP_FIXED | MAP_PRIVATE, fd, fileOffset); + if (loadAddress == (void *) (-1)) + dyld::throwf("mmap() error %d at address=0x%08lX, size=0x%08lX segment=%s in Segment::map() mapping %s", + errno, (uintptr_t) requestedLoadAddress, (uintptr_t) size, this->getName(), image->getPath()); + } } // update stats ++ImageLoader::fgTotalSegmentsMapped; diff -Naur dyld-96.2.orig/src/ImageLoader.h dyld-96.2/src/ImageLoader.h --- dyld-96.2.orig/src/ImageLoader.h 2008-03-01 12:02:14.000000000 +1100 +++ dyld-96.2/src/ImageLoader.h 2008-11-27 10:58:12.000000000 +1100 @@ -40,7 +40,8 @@ #define SPLIT_SEG_SHARED_REGION_SUPPORT 0 #define SPLIT_SEG_DYLIB_SUPPORT (__ppc__ || __i386__) #define TEXT_RELOC_SUPPORT (__ppc__ || __i386__) -#define DYLD_SHARED_CACHE_SUPPORT (__ppc__ || __i386__ || __ppc64__ || __x86_64__) +/* #define DYLD_SHARED_CACHE_SUPPORT (__ppc__ || __i386__ || __ppc64__ || __x86_64__) */ +#define DYLD_SHARED_CACHE_SUPPORT (__ppc__ || __ppc64__) #define IMAGE_NOTIFY_SUPPORT 0 #define RECURSIVE_INITIALIZER_LOCK 1 #define SUPPORT_OLD_CRT_INITIALIZATION (__ppc__ || __i386__) @@ -623,7 +624,7 @@ virtual bool hasPreferredLoadAddress() = 0; //virtual void setActualLoadAddress(uint64_t addr) = 0; - virtual void map(int fd, uint64_t offsetInFatWrapper, intptr_t slide, const ImageLoader* image, const ImageLoader::LinkContext& context); + virtual void map(int fd, uint64_t offsetInFat, uint64_t lenInFat, intptr_t slide, const ImageLoader* image, const ImageLoader::LinkContext& context); static bool reserveAddressRange(uintptr_t start, size_t length); static uintptr_t reserveAnAddressRange(size_t length, const class ImageLoader::LinkContext& context); diff -Naur dyld-96.2.orig/src/dyld.cpp dyld-96.2/src/dyld.cpp --- dyld-96.2.orig/src/dyld.cpp 2008-03-01 12:02:14.000000000 +1100 +++ dyld-96.2/src/dyld.cpp 2008-11-27 10:58:12.000000000 +1100 @@ -169,10 +169,12 @@ static ImageLoader* sBundleBeingLoaded = NULL; // hack until OFI is reworked #if DYLD_SHARED_CACHE_SUPPORT static const dyld_cache_header* sSharedCache = NULL; +#endif +/* #if DYLD_SHARED_CACHE_SUPPORT */ bool gSharedCacheNotFound = false; bool gSharedCacheNeedsUpdating = false; bool gSharedCacheDontNotify = false; -#endif +/* #endif */ ImageLoader::LinkContext gLinkContext; bool gLogAPIs = false; const struct LibSystemHelpers* gLibSystemHelpers = NULL; diff -Naur dyld-96.2.orig/src/dyldAPIs.cpp dyld-96.2/src/dyldAPIs.cpp --- dyld-96.2.orig/src/dyldAPIs.cpp 2008-03-01 12:02:14.000000000 +1100 +++ dyld-96.2/src/dyldAPIs.cpp 2008-11-27 10:58:12.000000000 +1100 @@ -1221,6 +1221,7 @@ return false; } +#if DYLD_SHARED_CACHE_SUPPORT static bool readOnlyBootVolume() { struct statfs sfs; @@ -1230,7 +1231,7 @@ // if statfs() fails, something is wrong, so don't rebuild dyld cache return true; } - +#endif static void registerThreadHelpers(const dyld::LibSystemHelpers* helpers) {