Loading...
--- dyld/dyld-46.16/src/dyldAPIs.cpp
+++ dyld/dyld-43/src/dyldAPIs.cpp
@@ -33,7 +33,6 @@
#include <string.h>
#include <mach/mach.h>
#include <sys/time.h>
-#include <sys/sysctl.h>
extern "C" mach_port_name_t task_self_trap(void); // can't include <System/mach/mach_traps.h> because it is missing extern C
@@ -401,11 +400,12 @@
static __attribute__((noinline))
-const struct mach_header* addImage(void* callerAddress, const char* path, bool search, bool dontLoad, bool matchInstallName, bool abortOnError)
+const struct mach_header* addImage(const char* path, bool search, bool dontLoad, bool matchInstallName, bool abortOnError)
{
ImageLoader* image = NULL;
try {
dyld::clearErrorMessage();
+ void* callerAddress = __builtin_return_address(2); // note layers: 2: real client, 1: libSystem glue, 0: dyld API
ImageLoader* callerImage = dyld::findImageContainingAddress(callerAddress);
dyld::LoadContext context;
context.useSearchPaths = search;
@@ -447,24 +447,21 @@
const bool search = ( (options & NSADDIMAGE_OPTION_WITH_SEARCHING) != 0 );
const bool matchInstallName = ( (options & NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME) != 0 );
const bool abortOnError = ( (options & NSADDIMAGE_OPTION_RETURN_ON_ERROR) == 0 );
- void* callerAddress = __builtin_return_address(1); // note layers: 1: real client, 0: libSystem glue
- return addImage(callerAddress, path, search, dontLoad, matchInstallName, abortOnError);
+ return addImage(path, search, dontLoad, matchInstallName, abortOnError);
}
bool NSAddLibrary(const char* path)
{
if ( dyld::gLogAPIs )
fprintf(stderr, "%s(\"%s\")\n", __func__, path);
- void* callerAddress = __builtin_return_address(1); // note layers: 1: real client, 0: libSystem glue
- return (addImage(callerAddress, path, false, false, false, false) != NULL);
+ return (addImage(path, false, false, false, false) != NULL);
}
bool NSAddLibraryWithSearching(const char* path)
{
if ( dyld::gLogAPIs )
fprintf(stderr, "%s(\"%s\")\n", __func__, path);
- void* callerAddress = __builtin_return_address(1); // note layers: 1: real client, 0: libSystem glue
- return (addImage(callerAddress, path, true, false, false, false) != NULL);
+ return (addImage(path, true, false, false, false) != NULL);
}
@@ -1397,7 +1394,7 @@
if ( handle == RTLD_NEXT ) {
void* callerAddress = __builtin_return_address(1); // note layers: 1: real client, 0: libSystem glue
ImageLoader* callerImage = dyld::findImageContainingAddress(callerAddress);
- sym = callerImage->findExportedSymbolInDependentImages(underscoredName, &image); // don't search image, but do search what it links against
+ sym = callerImage->resolveSymbol(underscoredName, false, &image);
if ( sym != NULL ) {
return (void*)image->getExportedSymbolAddress(sym);
}
@@ -1412,7 +1409,11 @@
if ( handle == RTLD_SELF ) {
void* callerAddress = __builtin_return_address(1); // note layers: 1: real client, 0: libSystem glue
ImageLoader* callerImage = dyld::findImageContainingAddress(callerAddress);
- sym = callerImage->findExportedSymbolInImageOrDependentImages(underscoredName, &image); // search image and what it links against
+ sym = callerImage->findExportedSymbol(underscoredName, NULL, false, &image); // search first in calling image
+ if ( sym != NULL ) {
+ return (void*)image->getExportedSymbolAddress(sym);
+ }
+ sym = callerImage->resolveSymbol(underscoredName, false, &image); // search what calling image links against
if ( sym != NULL ) {
return (void*)image->getExportedSymbolAddress(sym);
}
@@ -1426,7 +1427,12 @@
// real handle
image = (ImageLoader*)handle;
if ( dyld::validImage(image) ) {
- sym = image->findExportedSymbolInImageOrDependentImages(underscoredName, &image); // search image and what it links against
+ ImageLoader* foundIn;
+ sym = image->findExportedSymbol(underscoredName, NULL, true, &foundIn);
+ if ( sym != NULL ) {
+ return (void*)(foundIn->getExportedSymbolAddress(sym));
+ }
+ sym = image->resolveSymbol(underscoredName, false, &image);// search what image links against
if ( sym != NULL ) {
return (void*)image->getExportedSymbolAddress(sym);
}
@@ -1439,24 +1445,6 @@
dlerrorSet("invalid handle passed to dlsym()");
}
return NULL;
-}
-
-
-static void commitRepreboundFiles(std::vector<ImageLoader*> files, bool unmapOld)
-{
- // tell file system to flush all dirty buffers to disk
- // after this sync, the _redoprebinding files will be on disk
- sync();
-
- // now commit (swap file) for each re-prebound image
- // this only updates directories, since the files have already been flushed by previous sync()
- for (std::vector<ImageLoader*>::iterator it=files.begin(); it != files.end(); it++) {
- (*it)->reprebindCommit(dyld::gLinkContext, true, unmapOld);
- }
-
- // tell file system to flush all dirty buffers to disk
- // this should flush out all directory changes caused by the file swapping
- sync();
}
@@ -1472,7 +1460,7 @@
{
if ( dyld::gLogAPIs )
fprintf(stderr, "%s()\n", __func__);
-
+
// list of requested dylibs actually loaded
std::vector<ImageLoader*> preboundImages;
@@ -1481,10 +1469,7 @@
if ( dyld::getImageCount() != 1 )
throw "_dyld_update_prebinding cannot be called with dylib already loaded";
- // note that we are prebinding
- dyld::gLinkContext.prebinding = true;
-
- const uint32_t max_allowed_link_errors = 100;
+ const uint32_t max_allowed_link_errors = 10;
uint32_t link_error_count = 0;
// load and link each dylib
@@ -1516,12 +1501,10 @@
stage = "link";
fprintf(stderr, "update_prebinding: warning: could not %s %s: %s\n", stage, paths[i], msg);
}
- if ( (image != NULL) && image->isPrebindable() ) // don't count top level dylib being unprebound as an error
+ if ( image != NULL )
link_error_count++;
- if ( link_error_count > max_allowed_link_errors ) {
- fprintf(stderr, "update_prebinding: too many errors (%d) \n", link_error_count);
- throw "terminating";
- }
+ if ( link_error_count > max_allowed_link_errors )
+ throw;
}
}
@@ -1565,63 +1548,39 @@
else {
uint32_t imageCount = preboundImages.size();
uint32_t imageNumber = 1;
-
- // on Intel system, update_prebinding is run twice: i386, then emulated ppc
- // calculate fudge factors so that progress output represents both runs
- int denomFactor = 1;
- int numerAddend = 0;
- if (UPDATE_PREBINDING_PROGRESS & flags) {
- #if __i386__
- // i386 half runs first, just double denominator
- denomFactor = 2;
- #endif
- #if __ppc__
- // if emulated ppc, double denominator and shift numerator
- int mib[] = { CTL_KERN, KERN_CLASSIC, getpid() };
- int is_emulated = 0;
- size_t len = sizeof(int);
- int ret = sysctl(mib, 3, &is_emulated, &len, NULL, 0);
- if ((ret != -1) && is_emulated) {
- denomFactor = 2;
- numerAddend = imageCount;
- }
- #endif
- }
-
// tell each image to write itself out re-prebound
struct timeval currentTime = { 0 , 0 };
gettimeofday(¤tTime, NULL);
time_t timestamp = currentTime.tv_sec;
- std::vector<ImageLoader*> updatedImages;
for (std::vector<ImageLoader*>::iterator it=preboundImages.begin(); it != preboundImages.end(); it++) {
- uint64_t freespace = (*it)->reprebind(dyld::gLinkContext, timestamp);
- updatedImages.push_back(*it);
+ (*it)->reprebind(dyld::gLinkContext, timestamp);
if(UPDATE_PREBINDING_PROGRESS & flags) {
- fprintf(stdout, "update_prebinding: progress: %3u/%u\n", imageNumber+numerAddend, imageCount*denomFactor);
+ fprintf(stdout, "update_prebinding: progress: %3u/%u\n", imageNumber, imageCount);
fflush(stdout);
imageNumber++;
}
- // see if we are running low on disk space (less than 32MB is "low")
- const uint64_t kMinFreeSpace = 32*1024*1024;
- if ( freespace < kMinFreeSpace ) {
- if ( dyld::gLinkContext.verbosePrebinding || (UPDATE_PREBINDING_DRY_RUN & flags) )
- fprintf(stderr, "update_prebinding: disk space down to %lluMB, committing %lu prebound files\n", freespace/(1024*1024), updatedImages.size());
- // commit files processed so far, to free up more disk space
- commitRepreboundFiles(updatedImages, true);
- // empty list of temp files
- updatedImages.clear();
- }
}
- // commit them, don't need to unmap old, cause we are done
- commitRepreboundFiles(updatedImages, false);
+ // tell file system to flush all dirty buffers to disk
+ // after this sync, all the _redoprebinding files will be on disk
+ sync();
+
+ // now commit (swap file) for each re-prebound image
+ // this only updates directories, since the files have already been flushed by previous sync()
+ for (std::vector<ImageLoader*>::iterator it=preboundImages.begin(); it != preboundImages.end(); it++) {
+ (*it)->reprebindCommit(dyld::gLinkContext, true);
+ }
+
+ // tell file system to flush all dirty buffers to disk
+ // this should flush out all directory changes caused by the file swapping
+ sync();
}
}
catch (const char* msg) {
// delete temp files
try {
for (std::vector<ImageLoader*>::iterator it=preboundImages.begin(); it != preboundImages.end(); it++) {
- (*it)->reprebindCommit(dyld::gLinkContext, false, false);
+ (*it)->reprebindCommit(dyld::gLinkContext, false);
}
}
catch (const char* commitMsg) {