Loading...
--- dyld/dyld-97.1/launch-cache/update_dyld_shared_cache.cpp
+++ dyld/dyld-95.3/launch-cache/update_dyld_shared_cache.cpp
@@ -31,11 +31,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
-#include <signal.h>
#include <errno.h>
#include <sys/uio.h>
#include <unistd.h>
-#include <dirent.h>
#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/resource.h>
@@ -392,7 +390,7 @@
{
public:
SharedCache(ArchGraph* graph, bool alphaSort, uint64_t dyldBaseAddress);
- bool update(const char* rootPath, const char* cacheDir, bool force, bool optimize, bool deleteExistingFirst, int archIndex, int archCount);
+ bool update(const char* rootPath, const char* cacheDir, bool force, bool optimize, int archIndex, int archCount);
static const char* filename(bool optimized);
private:
@@ -442,6 +440,7 @@
std::vector<LayoutInfo> fDylibs;
std::vector<shared_file_mapping_np> fMappings;
uint32_t fHeaderSize;
+ uint8_t* fMappedCacheFile;
uint64_t fDyldBaseAddress;
uint64_t fLinkEditsTotalUnoptimizedSize;
uint64_t fLinkEditsStartAddress;
@@ -1196,21 +1195,8 @@
}
-static const char* sCleanupFile = NULL;
-static void cleanup(int sig)
-{
- ::signal(sig, SIG_DFL);
- if ( sCleanupFile != NULL )
- ::unlink(sCleanupFile);
- //if ( verbose )
- // fprintf(stderr, "update_dyld_shared_cache: deleting temp file in response to a signal\n");
- if ( sig == SIGINT )
- ::exit(1);
-}
-
-
template <typename A>
-bool SharedCache<A>::update(const char* rootPath, const char* cacheDir, bool force, bool optimize, bool deleteExistingFirst, int archIndex, int archCount)
+bool SharedCache<A>::update(const char* rootPath, const char* cacheDir, bool force, bool optimize, int archIndex, int archCount)
{
bool didUpdate = false;
char cachePath[1024];
@@ -1227,28 +1213,29 @@
fprintf(stderr, "update_dyld_shared_cache: warning, empty cache not generated for arch %s\n", archName());
return false;
}
- // delete existing cache while building the new one
- // this is a flag to dyld to stop pinging update_dyld_shared_cache
- if ( deleteExistingFirst )
- ::unlink(cachePath);
- uint8_t* inMemoryCache = NULL;
- uint32_t allocatedCacheSize = 0;
char tempCachePath[strlen(cachePath)+16];
sprintf(tempCachePath, "%s.tmp%u", cachePath, getpid());
try {
- // allocate a memory block to hold cache
+ int fd = ::open(tempCachePath, O_CREAT | O_RDWR | O_TRUNC, 0644);
+ if ( fd == -1 )
+ throwf("can't create temp file %s, errnor=%d", tempCachePath, errno);
+
+ // try to allocate whole cache file contiguously
uint32_t cacheFileSize = 0;
for(std::vector<shared_file_mapping_np>::iterator it = fMappings.begin(); it != fMappings.end(); ++it) {
uint32_t end = it->sfm_file_offset + it->sfm_size;
if ( end > cacheFileSize )
cacheFileSize = end;
}
- if ( vm_allocate(mach_task_self(), (vm_address_t*)(&inMemoryCache), cacheFileSize, VM_FLAGS_ANYWHERE) != KERN_SUCCESS )
- throwf("can't vm_allocate cache of size %u", cacheFileSize);
- allocatedCacheSize = cacheFileSize;
+ fstore_t fcntlSpec = { F_ALLOCATECONTIG|F_ALLOCATEALL, F_PEOFPOSMODE, 0, cacheFileSize, 0 };
+ fcntl(fd, F_PREALLOCATE, &fcntlSpec);
+
+ // fill in cache header memory buffer
+ uint8_t buffer[pageAlign(fHeaderSize)];
+ bzero(buffer, sizeof(buffer));
// fill in header
- dyldCacheHeader<E>* header = (dyldCacheHeader<E>*)inMemoryCache;
+ dyldCacheHeader<E>* header = (dyldCacheHeader<E>*)buffer;
char temp[16];
strcpy(temp, "dyld_v1 ");
strcpy(&temp[15-strlen(archName())], archName());
@@ -1263,7 +1250,7 @@
//header->set_dependenciesCount(fDependencyPool.size());
// fill in mappings
- dyldCacheFileMapping<E>* mapping = (dyldCacheFileMapping<E>*)&inMemoryCache[sizeof(dyldCacheHeader<E>)];
+ dyldCacheFileMapping<E>* mapping = (dyldCacheFileMapping<E>*)&buffer[sizeof(dyldCacheHeader<E>)];
for(std::vector<shared_file_mapping_np>::iterator it = fMappings.begin(); it != fMappings.end(); ++it) {
if ( verbose )
fprintf(stderr, "update_dyld_shared_cache: cache mappings: address=0x%0llX, size=0x%0llX, fileOffset=0x%0llX, prot=0x%X\n",
@@ -1287,7 +1274,23 @@
++image;
}
- // copy each segment to cache buffer
+ // write whole header to disk
+ pwrite(fd, buffer, sizeof(buffer), 0);
+
+ // allocate copy buffer
+ const uint64_t kCopyBufferSize = 256*1024;
+ uint8_t* copyBuffer;
+ vm_address_t addr = 0;
+ if ( vm_allocate(mach_task_self(), &addr, kCopyBufferSize, VM_FLAGS_ANYWHERE) == KERN_SUCCESS )
+ copyBuffer = (uint8_t*)addr;
+ else
+ throw "can't allcoate copy buffer";
+
+ // make zero-fill buffer
+ uint8_t zerofill[4096];
+ bzero(zerofill, sizeof(zerofill));
+
+ // write each segment to cache file
int dylibIndex = 0;
for(typename std::vector<LayoutInfo>::const_iterator it = fDylibs.begin(); it != fDylibs.end(); ++it, ++dylibIndex) {
const char* path = it->layout->getFilePath();
@@ -1296,15 +1299,9 @@
throwf("can't open file %s, errnor=%d", it->layout->getID().name, errno);
// mark source as "don't cache"
(void)fcntl(src, F_NOCACHE, 1);
- // verify file has not changed since dependency analysis
- struct stat stat_buf;
- if ( fstat(src, &stat_buf) == -1)
- throwf("can't stat open file %s, errno=%d", path, errno);
- if ( (it->layout->getInode() != stat_buf.st_ino) || (it->layout->getLastModTime() != stat_buf.st_mtime) )
- throwf("aborting because OS dylib modified during cache creation: %s", path);
if ( verbose )
- fprintf(stderr, "update_dyld_shared_cache: copying %s to cache\n", it->layout->getID().name);
+ fprintf(stderr, "update_prebinding: copying %s to cache\n", it->layout->getID().name);
try {
const std::vector<MachOLayoutAbstraction::Segment>& segs = it->layout->getSegments();
for (int i=0; i < segs.size(); ++i) {
@@ -1315,31 +1312,21 @@
const uint64_t segmentSrcStartOffset = it->layout->getOffsetInUniversalFile()+seg.fileOffset();
const uint64_t segmentSize = seg.fileSize();
const uint64_t segmentDstStartOffset = cacheFileOffsetForAddress(seg.newAddress());
- ssize_t readResult = ::pread(src, &inMemoryCache[segmentDstStartOffset], segmentSize, segmentSrcStartOffset);
- if ( readResult != segmentSize )
- if ( readResult == -1 )
+ for(uint64_t copiedAmount=0; copiedAmount < segmentSize; copiedAmount += kCopyBufferSize) {
+ uint64_t amount = std::min(segmentSize-copiedAmount, kCopyBufferSize);
+ //fprintf(stderr, "copy 0x%08llX bytes at offset 0x%08llX for segment %s in %s to cache offset 0x%08llX\n",
+ // amount, segmentSrcStartOffset+copiedAmount, seg.name(), it->layout->getID().name, segmentDstStartOffset+copiedAmount);
+ if ( ::pread(src, copyBuffer, amount, segmentSrcStartOffset+copiedAmount) != amount )
throwf("read failure copying dylib errno=%d for %s", errno, it->layout->getID().name);
- else
- throwf("read failure copying dylib. Read of %lld bytes at file offset %lld returned %ld for %s",
- segmentSize, segmentSrcStartOffset, readResult, it->layout->getID().name);
- // verify __TEXT segment has no zeroed out pages
- if ( strcmp(seg.name(), "__TEXT") == 0 ) {
- // only scan first 128KB. Some OS dylibs have zero filled TEXT pages later in __const...
- int scanEnd = segmentSize;
- if ( scanEnd > 0x20000 )
- scanEnd = 0x20000;
- for (int pageOffset = 0; pageOffset < scanEnd; pageOffset += 4096) {
- const uint32_t* page = (uint32_t*)(&inMemoryCache[segmentDstStartOffset+pageOffset]);
- bool foundNonZero = false;
- for(int p=0; p < 1024; ++p) {
- if ( page[p] != 0 ) {
- //fprintf(stderr, "found non-zero at pageOffset=0x%08X, p=0x%08X in memory=%p for %s\n", pageOffset, p, page, it->layout->getID().name);
- foundNonZero = true;
- break;
- }
- }
- if ( !foundNonZero )
- throwf("suspected bad read. Found __TEXT segment page at offset 0x%08X that is all zeros for %s in %s", pageOffset, archName(), it->layout->getID().name);
+ if ( ::pwrite(fd, copyBuffer, amount, segmentDstStartOffset+copiedAmount) != amount )
+ throwf("write failure copying dylib errno=%d for %s", errno, it->layout->getID().name);
+ }
+ if ( seg.size() > seg.fileSize() ) {
+ // write zero-filled area
+ for(uint64_t copiedAmount=seg.fileSize(); copiedAmount < seg.size(); copiedAmount += sizeof(zerofill)) {
+ uint64_t amount = std::min(seg.size()-copiedAmount, (uint64_t)(sizeof(zerofill)));
+ if ( ::pwrite(fd, zerofill, amount, segmentDstStartOffset+copiedAmount) != amount )
+ throwf("write failure copying dylib errno=%d for %s", errno, it->layout->getID().name);
}
}
}
@@ -1350,14 +1337,26 @@
}
::close(src);
}
-
+
+ // free copy buffer
+ vm_deallocate(mach_task_self(), addr, kCopyBufferSize);
+
+ // map cache file
+ fMappedCacheFile = (uint8_t*)mmap(NULL, cacheFileSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if ( fMappedCacheFile == (uint8_t*)(-1) )
+ throw "can't mmap cache file";
+
+ // close cache file
+ ::fsync(fd);
+ ::close(fd);
+
// set mapped address for each segment
for(typename std::vector<LayoutInfo>::const_iterator it = fDylibs.begin(); it != fDylibs.end(); ++it) {
std::vector<MachOLayoutAbstraction::Segment>& segs = ((MachOLayoutAbstraction*)(it->layout))->getSegments();
for (int i=0; i < segs.size(); ++i) {
MachOLayoutAbstraction::Segment& seg = segs[i];
if ( seg.size() > 0 )
- seg.setMappedAddress(inMemoryCache + cacheFileOffsetForAddress(seg.newAddress()));
+ seg.setMappedAddress(fMappedCacheFile + cacheFileOffsetForAddress(seg.newAddress()));
//fprintf(stderr, "%s at %p to %p for %s\n", seg.name(), seg.mappedAddress(), (char*)seg.mappedAddress()+ seg.size(), it->layout->getID().name);
}
}
@@ -1378,11 +1377,11 @@
// merge/optimize all LINKEDIT segments
if ( optimize ) {
//fprintf(stderr, "update_dyld_shared_cache: original cache file size %uMB\n", cacheFileSize/(1024*1024));
- cacheFileSize = (this->optimizeLINKEDIT() - inMemoryCache);
+ cacheFileSize = (this->optimizeLINKEDIT() - fMappedCacheFile);
//fprintf(stderr, "update_dyld_shared_cache: optimized cache file size %uMB\n", cacheFileSize/(1024*1024));
// update header to reduce mapping size
- dyldCacheHeader<E>* cacheHeader = (dyldCacheHeader<E>*)inMemoryCache;
- dyldCacheFileMapping<E>* mappings = (dyldCacheFileMapping<E>*)&inMemoryCache[sizeof(dyldCacheHeader<E>)];
+ dyldCacheHeader<E>* cacheHeader = (dyldCacheHeader<E>*)fMappedCacheFile;
+ dyldCacheFileMapping<E>* mappings = (dyldCacheFileMapping<E>*)&fMappedCacheFile[sizeof(dyldCacheHeader<E>)];
dyldCacheFileMapping<E>* lastMapping = &mappings[cacheHeader->mappingCount()-1];
lastMapping->set_size(cacheFileSize-lastMapping->file_offset());
// update fMappings so .map file will print correctly
@@ -1421,53 +1420,33 @@
for(typename std::vector<Binder<A>*>::iterator it = binders.begin(); it != binders.end(); ++it) {
delete *it;
}
-
- // install signal handlers to delete temp file if program is killed
- sCleanupFile = tempCachePath;
- ::signal(SIGINT, cleanup);
- ::signal(SIGBUS, cleanup);
- ::signal(SIGSEGV, cleanup);
+
+ // close mapping
+ int result = ::msync(fMappedCacheFile, cacheFileSize, MS_SYNC);
+ if ( result != 0 )
+ throw "error syncing cache file";
+ result = ::munmap(fMappedCacheFile, cacheFileSize);
+ if ( result != 0 )
+ throw "error unmapping cache file";
- // create temp file for cache
- int fd = ::open(tempCachePath, O_CREAT | O_RDWR | O_TRUNC, 0644);
- if ( fd == -1 )
- throwf("can't create temp file %s, errnor=%d", tempCachePath, errno);
-
- // try to allocate whole cache file contiguously
- fstore_t fcntlSpec = { F_ALLOCATECONTIG|F_ALLOCATEALL, F_PEOFPOSMODE, 0, cacheFileSize, 0 };
- ::fcntl(fd, F_PREALLOCATE, &fcntlSpec);
-
- // write out cache file
- if ( verbose )
- fprintf(stderr, "update_dyld_shared_cache: writing cache to disk\n");
- if ( ::pwrite(fd, inMemoryCache, cacheFileSize, 0) != cacheFileSize )
- throwf("write() failure creating cache file, errno=%d", errno);
+ // cut back cache file to match optmized size
+ if ( optimize ) {
+ if ( ::truncate(tempCachePath, cacheFileSize) != 0 )
+ throw "error truncating cache file";
+ }
- // flush to disk and close
- int result = ::fcntl(fd, F_FULLFSYNC, NULL);
- if ( result == -1 )
- fprintf(stderr, "update_dyld_shared_cache: warning, fcntl(F_FULLFSYNC) failed with errno=%d for %s\n", errno, tempCachePath);
- result = ::close(fd);
- if ( result != 0 )
- fprintf(stderr, "update_dyld_shared_cache: warning, close() failed with errno=%d for %s\n", errno, tempCachePath);
-
- // atomically swap in new cache file, do this after F_FULLFSYNC
+ // commit
+ ::sync();
+ // flush everything to disk, otherwise if kernel panics before the cache file is completely written to disk
+ // then next reboot will use a corrupted cache and die
result = ::rename(tempCachePath, cachePath);
if ( result != 0 )
throwf("can't swap newly create dyld shared cache file: rename(%s,%s) returned errno=%d", tempCachePath, cachePath, errno);
-
// flush everything to disk to assure rename() gets recorded
::sync();
didUpdate = true;
-
- // restore default signal handlers
- ::signal(SIGINT, SIG_DFL);
- ::signal(SIGBUS, SIG_DFL);
- ::signal(SIGSEGV, SIG_DFL);
// generate human readable "map" file that shows the layout of the cache file
- if ( verbose )
- fprintf(stderr, "update_dyld_shared_cache: writing .map file to disk\n");
sprintf(tempCachePath, "%s.map", cachePath);// re-use path buffer
FILE* fmap = ::fopen(tempCachePath, "w");
if ( fmap == NULL ) {
@@ -1505,17 +1484,10 @@
}
fclose(fmap);
}
-
- // free in memory cache
- vm_deallocate(mach_task_self(), (vm_address_t)inMemoryCache, allocatedCacheSize);
- inMemoryCache = NULL;
}
catch (...){
- // remove temp cache file
+ // remove temp cache
::unlink(tempCachePath);
- // remove in memory cache
- if ( inMemoryCache != NULL )
- vm_deallocate(mach_task_self(), (vm_address_t)inMemoryCache, allocatedCacheSize);
throw;
}
}
@@ -1645,51 +1617,9 @@
}
-// If the 10.5.0 version of update_dyld_shared_cache was killed or crashed, it
-// could leave large half written cache files laying around. The function deletes
-// those files. To prevent the deletion of tmp files being created by another
-// copy of update_dyld_shared_cache, it only deletes the temp cache file if its
-// creation time was before the last restart of this machine.
-static void deleteOrphanTempCacheFiles()
-{
- DIR* dir = ::opendir(DYLD_SHARED_CACHE_DIR);
- if ( dir != NULL ) {
- std::vector<const char*> filesToDelete;
- for (dirent* entry = ::readdir(dir); entry != NULL; entry = ::readdir(dir)) {
- if ( entry->d_type == DT_REG ) {
- // only look at files with .tmp in name
- if ( strstr(entry->d_name, ".tmp") != NULL ) {
- char fullPath[strlen(DYLD_SHARED_CACHE_DIR)+entry->d_namlen+2];
- strcpy(fullPath, DYLD_SHARED_CACHE_DIR);
- strcat(fullPath, "/");
- strcat(fullPath, entry->d_name);
- struct stat tmpFileStatInfo;
- if ( stat(fullPath, &tmpFileStatInfo) != -1 ) {
- int mib[2] = {CTL_KERN, KERN_BOOTTIME};
- struct timeval boottime;
- size_t size = sizeof(boottime);
- if ( (sysctl(mib, 2, &boottime, &size, NULL, 0) != -1) && (boottime.tv_sec != 0) ) {
- // make sure this file is older than the boot time of this machine
- if ( tmpFileStatInfo.st_mtime < boottime.tv_sec ) {
- filesToDelete.push_back(strdup(fullPath));
- }
- }
- }
- }
- }
- }
- ::closedir(dir);
- for(std::vector<const char*>::iterator it = filesToDelete.begin(); it != filesToDelete.end(); ++it) {
- fprintf(stderr, "update_dyld_shared_cache: deleting old temp cache file: %s\n", *it);
- ::unlink(*it);
- }
- }
-}
-
-
static bool updateSharedeCacheFile(const char* rootPath, const char* cacheDir, const std::set<cpu_type_t>& onlyArchs,
- bool force, bool alphaSort, bool optimize, bool deleteExistingFirst)
+ bool force, bool alphaSort, bool optimize)
{
bool didUpdate = false;
// get dyld load address info
@@ -1708,35 +1638,32 @@
SharedCache<ppc> cache(ArchGraph::getArch(*a), alphaSort, dyldBaseAddress);
#if __i386__
// <rdar://problem/5217377> Rosetta does not work with optimized dyld shared cache
- didUpdate |= cache.update(rootPath, cacheDir, force, false, deleteExistingFirst, index, archCount);
+ didUpdate |= cache.update(rootPath, cacheDir, force, false, index, archCount);
#else
- didUpdate |= cache.update(rootPath, cacheDir, force, optimize, deleteExistingFirst, index, archCount);
+ didUpdate |= cache.update(rootPath, cacheDir, force, optimize, index, archCount);
#endif
}
break;
case CPU_TYPE_POWERPC64:
{
SharedCache<ppc64> cache(ArchGraph::getArch(*a), alphaSort, dyldBaseAddress);
- didUpdate |= cache.update(rootPath, cacheDir, force, optimize, deleteExistingFirst, index, archCount);
+ didUpdate |= cache.update(rootPath, cacheDir, force, optimize, index, archCount);
}
break;
case CPU_TYPE_I386:
{
SharedCache<x86> cache(ArchGraph::getArch(*a), alphaSort, dyldBaseAddress);
- didUpdate |= cache.update(rootPath, cacheDir, force, optimize, deleteExistingFirst, index, archCount);
+ didUpdate |= cache.update(rootPath, cacheDir, force, optimize, index, archCount);
}
break;
case CPU_TYPE_X86_64:
{
SharedCache<x86_64> cache(ArchGraph::getArch(*a), alphaSort, dyldBaseAddress);
- didUpdate |= cache.update(rootPath, cacheDir, force, optimize, deleteExistingFirst, index, archCount);
+ didUpdate |= cache.update(rootPath, cacheDir, force, optimize, index, archCount);
}
break;
}
}
-
- deleteOrphanTempCacheFiles();
-
return didUpdate;
}
@@ -1746,42 +1673,31 @@
fprintf(stderr, "update_dyld_shared_cache [-force] [-root dir] [-arch arch] [-debug]\n");
}
-// flag so that we only update cache once per invocation
-static bool doNothingAndDrainQueue = false;
-
-static kern_return_t do_update_cache(cpu_type_t arch, bool deleteExistingCacheFileFirst)
-{
- if ( !doNothingAndDrainQueue ) {
- std::set<cpu_type_t> onlyArchs;
- onlyArchs.insert(arch);
- try {
- scanForSharedDylibs("", "/var/db/dyld/shared_region_roots/", onlyArchs);
- if ( updateSharedeCacheFile("", DYLD_SHARED_CACHE_DIR, onlyArchs, false, false, true, deleteExistingCacheFileFirst) )
- fprintf(stderr, "update_dyld_shared_cache[%u] regenerated cache for arch=%s\n", getpid(), ArchGraph::archName(arch));
- }
- catch (const char* msg) {
- fprintf(stderr, "update_dyld_shared_cache[%u] for arch=%s failed: %s\n", getpid(), ArchGraph::archName(arch), msg);
- return KERN_FAILURE;
- }
- // <rdar://problem/6378354> only build one cache file per life of process
- doNothingAndDrainQueue = true;
+
+kern_return_t do_dyld_shared_cache_missing(mach_port_t dyld_port, cpu_type_t arch)
+{
+ std::set<cpu_type_t> onlyArchs;
+ onlyArchs.insert(arch);
+ try {
+ scanForSharedDylibs("", "/var/db/dyld/shared_region_roots/", onlyArchs);
+ if ( updateSharedeCacheFile("", DYLD_SHARED_CACHE_DIR, onlyArchs, false, false, true) )
+ fprintf(stderr, "update_dyld_shared_cache[%u] regenerated cache for arch=%s\n", getpid(), ArchGraph::archName(arch));
+ }
+ catch (const char* msg) {
+ fprintf(stderr, "update_dyld_shared_cache[%u] for arch=%s failed: %s\n", getpid(), ArchGraph::archName(arch), msg);
+ return KERN_FAILURE;
}
return KERN_SUCCESS;
}
-
-kern_return_t do_dyld_shared_cache_missing(mach_port_t dyld_port, cpu_type_t arch)
-{
- return do_update_cache(arch, false);
-}
-
-
kern_return_t do_dyld_shared_cache_out_of_date(mach_port_t dyld_port, cpu_type_t arch)
{
- // If cache exists but is out of date, delete the file while building the new one.
- // This will stop dyld from pinging update_dyld_share_cache while the cache is being built.
- return do_update_cache(arch, true);
+ // reduce priority of this process so it only runs at the lowest priority
+ setpriority(PRIO_PROCESS, 0, PRIO_MAX);
+
+ // and then rebuild cache
+ return do_dyld_shared_cache_missing(dyld_port, arch);
}
@@ -1790,18 +1706,12 @@
mach_port_t mp;
if ( bootstrap_check_in(bootstrap_port, "com.apple.dyld", &mp) == KERN_SUCCESS ) {
// started by launchd
+ // Just process one message and quit
mach_msg_size_t mxmsgsz = sizeof(union __RequestUnion__do_dyld_server_subsystem) + MAX_TRAILER_SIZE;
- doNothingAndDrainQueue = false;
- while ( mach_msg_server(dyld_server_server, mxmsgsz, mp, MACH_RCV_TIMEOUT) == KERN_SUCCESS ) {
- // keep processing messages
- doNothingAndDrainQueue = true;
- // but set flag so work is no longer done.
- // This is because the rest of the tool leaks and processing more than once
- // can hog system resources: <rdar://problem/5392427> 9A516 - Keep getting disk full errors
- // We drain the queue of messages because there is usually are a couple of duplicate messages.
- // It is ok to miss some messages. If the cache is out of date or missing, some new process
- // will discover it and send another message.
- }
+ mach_msg_server_once(dyld_server_server, mxmsgsz, mp, MACH_RCV_TIMEOUT);
+ // The problem with staying alive and processing messages is that the rest of this
+ // tool leaks mapped memory and file descriptors. Quiting will clean that up.
+ // <rdar://problem/5392427> 9A516 - Keep getting disk full errors
return 0;
}
else {
@@ -1901,7 +1811,7 @@
// build list of shared dylibs
scanForSharedDylibs(rootPath, "/var/db/dyld/shared_region_roots/", onlyArchs);
- updateSharedeCacheFile(rootPath, DYLD_SHARED_CACHE_DIR, onlyArchs, force, alphaSort, optimize, false);
+ updateSharedeCacheFile(rootPath, DYLD_SHARED_CACHE_DIR, onlyArchs, force, alphaSort, optimize);
// To make a universal bootable image with dyld caches,
// build the rosetta cache and symlink ppc to point to it.