Loading...
--- dyld/dyld-44.2/src/dyldAPIs.cpp
+++ dyld/dyld-46.16/src/dyldAPIs.cpp
@@ -33,6 +33,7 @@
#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
@@ -400,12 +401,11 @@
static __attribute__((noinline))
-const struct mach_header* addImage(const char* path, bool search, bool dontLoad, bool matchInstallName, bool abortOnError)
+const struct mach_header* addImage(void* callerAddress, 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,21 +447,24 @@
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 );
- return addImage(path, search, dontLoad, matchInstallName, abortOnError);
+ void* callerAddress = __builtin_return_address(1); // note layers: 1: real client, 0: libSystem glue
+ return addImage(callerAddress, path, search, dontLoad, matchInstallName, abortOnError);
}
bool NSAddLibrary(const char* path)
{
if ( dyld::gLogAPIs )
fprintf(stderr, "%s(\"%s\")\n", __func__, path);
- return (addImage(path, false, false, false, false) != NULL);
+ void* callerAddress = __builtin_return_address(1); // note layers: 1: real client, 0: libSystem glue
+ return (addImage(callerAddress, path, false, false, false, false) != NULL);
}
bool NSAddLibraryWithSearching(const char* path)
{
if ( dyld::gLogAPIs )
fprintf(stderr, "%s(\"%s\")\n", __func__, path);
- return (addImage(path, true, false, false, false) != NULL);
+ void* callerAddress = __builtin_return_address(1); // note layers: 1: real client, 0: libSystem glue
+ return (addImage(callerAddress, path, true, false, false, false) != NULL);
}
@@ -1478,7 +1481,10 @@
if ( dyld::getImageCount() != 1 )
throw "_dyld_update_prebinding cannot be called with dylib already loaded";
- const uint32_t max_allowed_link_errors = 10;
+ // note that we are prebinding
+ dyld::gLinkContext.prebinding = true;
+
+ const uint32_t max_allowed_link_errors = 100;
uint32_t link_error_count = 0;
// load and link each dylib
@@ -1510,10 +1516,12 @@
stage = "link";
fprintf(stderr, "update_prebinding: warning: could not %s %s: %s\n", stage, paths[i], msg);
}
- if ( image != NULL )
+ if ( (image != NULL) && image->isPrebindable() ) // don't count top level dylib being unprebound as an error
link_error_count++;
- if ( link_error_count > max_allowed_link_errors )
- throw;
+ if ( link_error_count > max_allowed_link_errors ) {
+ fprintf(stderr, "update_prebinding: too many errors (%d) \n", link_error_count);
+ throw "terminating";
+ }
}
}
@@ -1557,6 +1565,29 @@
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);
@@ -1566,7 +1597,7 @@
uint64_t freespace = (*it)->reprebind(dyld::gLinkContext, timestamp);
updatedImages.push_back(*it);
if(UPDATE_PREBINDING_PROGRESS & flags) {
- fprintf(stdout, "update_prebinding: progress: %3u/%u\n", imageNumber, imageCount);
+ fprintf(stdout, "update_prebinding: progress: %3u/%u\n", imageNumber+numerAddend, imageCount*denomFactor);
fflush(stdout);
imageNumber++;
}