Loading...
src/dyldAPIs.cpp dyld-45.3 dyld-46.16
--- dyld/dyld-45.3/src/dyldAPIs.cpp
+++ dyld/dyld-46.16/src/dyldAPIs.cpp
@@ -401,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;
@@ -448,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);
 }
 
 
@@ -1479,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
@@ -1511,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";
+				}
 			}
 		}