1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
3 * Copyright (c) 2004-2009 Apple Inc. All rights reserved.
5 * @APPLE_LICENSE_HEADER_START@
7 * This file contains Original Code and/or Modifications of Original Code
8 * as defined in and that are subject to the Apple Public Source License
9 * Version 2.0 (the 'License'). You may not use this file except in
10 * compliance with the License. Please obtain a copy of the License at
11 * http://www.opensource.apple.com/apsl/ and read it before using this
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
19 * Please see the License for the specific language governing rights and
20 * limitations under the License.
22 * @APPLE_LICENSE_HEADER_END@
26 // This file implements that API's in <mach-o/dyld.h>
30 #define __STDC_LIMIT_MACROS
34 #include <sys/param.h>
35 #include <sys/mount.h>
36 #include <Availability.h>
43 #include <mach/mach.h>
45 #include <sys/sysctl.h>
46 #include <mach/mach_traps.h> // for task_self_trap()
49 #include "mach-o/dyld_images.h"
50 #include "mach-o/dyld.h"
51 #include "mach-o/dyld_priv.h"
53 #include "ImageLoader.h"
55 #include "dyldLibSystemInterface.h"
57 #undef _POSIX_C_SOURCE
60 // from dyldExceptions.c
61 extern "C" void __Unwind_SjLj_SetThreadKey(pthread_key_t key
);
64 extern void addImagesToAllImages(uint32_t infoCount
, const dyld_image_info info
[]);
66 // deprecated APIs are still availble on Mac OS X, but not on iPhone OS
67 #if __IPHONE_OS_VERSION_MIN_REQUIRED
68 #define DEPRECATED_APIS_SUPPORTED 0
70 #define DEPRECATED_APIS_SUPPORTED 1
73 static bool sDynamicInterposing
= false;
75 #if DEPRECATED_APIS_SUPPORTED
76 static char sLastErrorFilePath
[1024];
77 static NSLinkEditErrors sLastErrorFileCode
;
78 static int sLastErrorNo
;
81 // In 10.3.x and earlier all the NSObjectFileImage API's were implemeneted in libSystem.dylib
82 // Beginning in 10.4 the NSObjectFileImage API's are implemented in dyld and libSystem just forwards
83 // This conditional keeps support for old libSystem's which needed some help implementing the API's
84 #define OLD_LIBSYSTEM_SUPPORT (__i386__)
86 // The following functions have no prototype in any header. They are special cases
87 // where _dyld_func_lookup() is used directly.
88 static void _dyld_make_delayed_module_initializer_calls();
89 static void registerThreadHelpers(const dyld::LibSystemHelpers
*);
90 #if DEPRECATED_APIS_SUPPORTED
91 static void _dyld_install_handlers(void* undefined
, void* multiple
, void* linkEdit
);
92 #if OLD_LIBSYSTEM_SUPPORT
93 static NSModule
_dyld_link_module(NSObjectFileImage object_addr
, size_t object_size
, const char* moduleName
, uint32_t options
);
95 static void _dyld_register_binding_handler(void * (*)(const char *, const char *, void *), ImageLoader::BindingOptions
);
96 static bool NSMakePrivateModulePublic(NSModule
module);
97 static void _dyld_call_module_initializers_for_dylib(const struct mach_header
* mh_dylib_header
);
99 // The following functions are dyld API's, but since dyld links with a static copy of libc.a
100 // the public name cannot be used.
101 static void client_dyld_lookup_and_bind(const char* symbolName
, void** address
, NSModule
* module);
102 static bool client_NSIsSymbolNameDefined(const char* symbolName
);
103 #endif // DEPRECATED_APIS_SUPPORTED
104 #if SUPPORT_ZERO_COST_EXCEPTIONS
105 static bool client_dyld_find_unwind_sections(void* addr
, dyld_unwind_sections
* info
);
108 static void unimplemented()
110 dyld::halt("unimplemented dyld function\n");
115 void* implementation
;
118 static struct dyld_func dyld_funcs
[] = {
119 {"__dyld_register_func_for_add_image", (void*)_dyld_register_func_for_add_image
},
120 {"__dyld_register_func_for_remove_image", (void*)_dyld_register_func_for_remove_image
},
121 {"__dyld_dladdr", (void*)dladdr
},
122 {"__dyld_dlclose", (void*)dlclose
},
123 {"__dyld_dlerror", (void*)dlerror
},
124 {"__dyld_dlopen", (void*)dlopen
},
125 {"__dyld_dlsym", (void*)dlsym
},
126 {"__dyld_dlopen_preflight", (void*)dlopen_preflight
},
127 {"__dyld_image_count", (void*)_dyld_image_count
},
128 {"__dyld_get_image_header", (void*)_dyld_get_image_header
},
129 {"__dyld_get_image_vmaddr_slide", (void*)_dyld_get_image_vmaddr_slide
},
130 {"__dyld_get_image_name", (void*)_dyld_get_image_name
},
131 {"__dyld_get_image_slide", (void*)_dyld_get_image_slide
},
132 {"__dyld__NSGetExecutablePath", (void*)_NSGetExecutablePath
},
135 {"__dyld_dyld_register_image_state_change_handler", (void*)dyld_register_image_state_change_handler
},
136 {"__dyld_register_thread_helpers", (void*)registerThreadHelpers
},
137 {"__dyld_fork_child", (void*)_dyld_fork_child
},
138 {"__dyld_make_delayed_module_initializer_calls", (void*)_dyld_make_delayed_module_initializer_calls
},
139 {"__dyld_get_all_image_infos", (void*)_dyld_get_all_image_infos
},
140 #if SUPPORT_ZERO_COST_EXCEPTIONS
141 {"__dyld_find_unwind_sections", (void*)client_dyld_find_unwind_sections
},
143 #if __i386__ || __x86_64__ || __arm__ || __arm64__
144 {"__dyld_fast_stub_entry", (void*)dyld::fastBindLazySymbol
},
146 {"__dyld_image_path_containing_address", (void*)dyld_image_path_containing_address
},
147 {"__dyld_shared_cache_some_image_overridden", (void*)dyld_shared_cache_some_image_overridden
},
148 {"__dyld_process_is_restricted", (void*)dyld::processIsRestricted
},
149 {"__dyld_dynamic_interpose", (void*)dyld_dynamic_interpose
},
152 #if DEPRECATED_APIS_SUPPORTED
153 {"__dyld_get_image_header_containing_address", (void*)_dyld_get_image_header_containing_address
},
154 {"__dyld_lookup_and_bind", (void*)client_dyld_lookup_and_bind
},
155 {"__dyld_lookup_and_bind_with_hint", (void*)_dyld_lookup_and_bind_with_hint
},
156 {"__dyld_lookup_and_bind_fully", (void*)_dyld_lookup_and_bind_fully
},
157 {"__dyld_install_handlers", (void*)_dyld_install_handlers
},
158 {"__dyld_link_edit_error", (void*)NSLinkEditError
},
159 {"__dyld_unlink_module", (void*)NSUnLinkModule
},
160 {"__dyld_bind_objc_module", (void*)_dyld_bind_objc_module
},
161 {"__dyld_bind_fully_image_containing_address", (void*)_dyld_bind_fully_image_containing_address
},
162 {"__dyld_image_containing_address", (void*)_dyld_image_containing_address
},
163 {"__dyld_register_binding_handler", (void*)_dyld_register_binding_handler
},
164 {"__dyld_NSNameOfSymbol", (void*)NSNameOfSymbol
},
165 {"__dyld_NSAddressOfSymbol", (void*)NSAddressOfSymbol
},
166 {"__dyld_NSModuleForSymbol", (void*)NSModuleForSymbol
},
167 {"__dyld_NSLookupAndBindSymbol", (void*)NSLookupAndBindSymbol
},
168 {"__dyld_NSLookupAndBindSymbolWithHint", (void*)NSLookupAndBindSymbolWithHint
},
169 {"__dyld_NSLookupSymbolInModule", (void*)NSLookupSymbolInModule
},
170 {"__dyld_NSLookupSymbolInImage", (void*)NSLookupSymbolInImage
},
171 {"__dyld_NSMakePrivateModulePublic", (void*)NSMakePrivateModulePublic
},
172 {"__dyld_NSIsSymbolNameDefined", (void*)client_NSIsSymbolNameDefined
},
173 {"__dyld_NSIsSymbolNameDefinedWithHint", (void*)NSIsSymbolNameDefinedWithHint
},
174 {"__dyld_NSIsSymbolNameDefinedInImage", (void*)NSIsSymbolNameDefinedInImage
},
175 {"__dyld_NSNameOfModule", (void*)NSNameOfModule
},
176 {"__dyld_NSLibraryNameForModule", (void*)NSLibraryNameForModule
},
177 {"__dyld_NSAddLibrary", (void*)NSAddLibrary
},
178 {"__dyld_NSAddLibraryWithSearching", (void*)NSAddLibraryWithSearching
},
179 {"__dyld_NSAddImage", (void*)NSAddImage
},
180 {"__dyld_launched_prebound", (void*)_dyld_launched_prebound
},
181 {"__dyld_all_twolevel_modules_prebound", (void*)_dyld_all_twolevel_modules_prebound
},
182 {"__dyld_call_module_initializers_for_dylib", (void*)_dyld_call_module_initializers_for_dylib
},
183 {"__dyld_NSCreateObjectFileImageFromFile", (void*)NSCreateObjectFileImageFromFile
},
184 {"__dyld_NSCreateObjectFileImageFromMemory", (void*)NSCreateObjectFileImageFromMemory
},
185 {"__dyld_NSDestroyObjectFileImage", (void*)NSDestroyObjectFileImage
},
186 {"__dyld_NSLinkModule", (void*)NSLinkModule
},
187 {"__dyld_NSHasModInitObjectFileImage", (void*)NSHasModInitObjectFileImage
},
188 {"__dyld_NSSymbolDefinitionCountInObjectFileImage", (void*)NSSymbolDefinitionCountInObjectFileImage
},
189 {"__dyld_NSSymbolDefinitionNameInObjectFileImage", (void*)NSSymbolDefinitionNameInObjectFileImage
},
190 {"__dyld_NSIsSymbolDefinedInObjectFileImage", (void*)NSIsSymbolDefinedInObjectFileImage
},
191 {"__dyld_NSSymbolReferenceNameInObjectFileImage", (void*)NSSymbolReferenceNameInObjectFileImage
},
192 {"__dyld_NSSymbolReferenceCountInObjectFileImage", (void*)NSSymbolReferenceCountInObjectFileImage
},
193 {"__dyld_NSGetSectionDataInObjectFileImage", (void*)NSGetSectionDataInObjectFileImage
},
194 #if OLD_LIBSYSTEM_SUPPORT
195 {"__dyld_link_module", (void*)_dyld_link_module
},
197 #endif //DEPRECATED_APIS_SUPPORTED
204 #if DEPRECATED_APIS_SUPPORTED
206 static void dyldAPIhalt(const char* apiName
, const char* errorMsg
)
208 dyld::log("dyld: %s() error\n", apiName
);
209 dyld::halt(errorMsg
);
212 // dyld's abstract type NSSymbol is implemented as const ImageLoader::Symbol*
213 inline NSSymbol
SymbolToNSSymbol(const ImageLoader::Symbol
* sym
)
215 return (NSSymbol
)sym
;
217 inline const ImageLoader::Symbol
* NSSymbolToSymbol(NSSymbol sym
)
219 return (const ImageLoader::Symbol
*)sym
;
222 // dyld's abstract type NSModule is implemented as ImageLoader*
223 inline NSModule
ImageLoaderToNSModule(const ImageLoader
* image
)
225 return (NSModule
)image
;
227 inline ImageLoader
* NSModuleToImageLoader(NSModule
module)
229 ImageLoader
* image
= (ImageLoader
*)module;
230 if ( dyld::validImage(image
) )
235 // actual definition for opaque type
236 struct __NSObjectFileImage
239 const void* imageBaseAddress
; // not used with OFI created from files
240 size_t imageLength
; // not used with OFI created from files
244 VECTOR_NEVER_DESTRUCTED(NSObjectFileImage
);
245 static std::vector
<NSObjectFileImage
> sObjectFileImages
;
250 // __NSObjectFileImage are deleted in NSDestroyObjectFileImage()
251 // The contained image is delete in one of two places:
252 // NSUnLinkModule deletes the image if there is no __NSObjectFileImage with a reference to it
253 // NSDestroyObjectFileImage deletes the image if image is not in list of valid images
258 static void setLastError(NSLinkEditErrors code
, int errnum
, const char* file
, const char* message
)
260 dyld::setErrorMessage(message
);
261 strncpy(sLastErrorFilePath
, file
, 1024);
262 sLastErrorFilePath
[1023] = '\0';
263 sLastErrorFileCode
= code
;
264 sLastErrorNo
= errnum
;
267 #endif // DEPRECATED_APIS_SUPPORTED
270 *_dyld_NSGetExecutablePath is the dyld side of _NSGetExecutablePath which
271 * copies the path of the executable into the buffer and returns 0 if the path
272 * was successfully copied in the provided buffer. If the buffer is not large
273 * enough, -1 is returned and the expected buffer size is copied in *bufsize.
274 * Note that _NSGetExecutablePath will return "a path" to the executable not a
275 * "real path" to the executable. That is the path may be a symbolic link and
276 * not the real file. And with deep directories the total bufsize needed could
277 * be more than MAXPATHLEN.
279 int _NSGetExecutablePath(char* buf
, uint32_t *bufsize
)
281 if ( dyld::gLogAPIs
)
282 dyld::log("%s(...)\n", __func__
);
283 const char* exePath
= dyld::getExecutablePath();
284 if(*bufsize
< strlen(exePath
) + 1){
285 *bufsize
= (uint32_t)(strlen(exePath
) + 1);
288 strcpy(buf
, exePath
);
292 uint32_t _dyld_image_count(void)
294 if ( dyld::gLogAPIs
)
295 dyld::log("%s()\n", __func__
);
296 return dyld::getImageCount();
299 const struct mach_header
* _dyld_get_image_header(uint32_t image_index
)
301 if ( dyld::gLogAPIs
)
302 dyld::log("%s(%u)\n", __func__
, image_index
);
303 ImageLoader
* image
= dyld::getIndexedImage(image_index
);
305 return (struct mach_header
*)image
->machHeader();
310 intptr_t _dyld_get_image_vmaddr_slide(uint32_t image_index
)
312 if ( dyld::gLogAPIs
)
313 dyld::log("%s(%u)\n", __func__
, image_index
);
314 ImageLoader
* image
= dyld::getIndexedImage(image_index
);
316 return image
->getSlide();
321 intptr_t _dyld_get_image_slide(const struct mach_header
* mh
)
323 if ( dyld::gLogAPIs
)
324 dyld::log("%s(%p)\n", __func__
, mh
);
325 ImageLoader
* image
= dyld::findImageByMachHeader(mh
);
327 return image
->getSlide();
333 const char* _dyld_get_image_name(uint32_t image_index
)
335 if ( dyld::gLogAPIs
)
336 dyld::log("%s(%u)\n", __func__
, image_index
);
337 ImageLoader
* image
= dyld::getIndexedImage(image_index
);
339 return image
->getRealPath();
344 const struct mach_header
* _dyld_get_image_header_containing_address(const void* address
)
346 if ( dyld::gLogAPIs
)
347 dyld::log("%s(%p)\n", __func__
, address
);
348 ImageLoader
* image
= dyld::findImageContainingAddress(address
);
350 return image
->machHeader();
355 void _dyld_register_func_for_add_image(void (*func
)(const struct mach_header
*mh
, intptr_t vmaddr_slide
))
357 if ( dyld::gLogAPIs
)
358 dyld::log("%s(%p)\n", __func__
, (void *)func
);
359 dyld::registerAddCallback(func
);
362 void _dyld_register_func_for_remove_image(void (*func
)(const struct mach_header
*mh
, intptr_t vmaddr_slide
))
364 if ( dyld::gLogAPIs
)
365 dyld::log("%s(%p)\n", __func__
, (void *)func
);
366 dyld::registerRemoveCallback(func
);
371 // called by crt before main() by programs linked with 10.4 or earlier crt1.o
372 static void _dyld_make_delayed_module_initializer_calls()
374 if ( dyld::gLogAPIs
)
375 dyld::log("%s()\n", __func__
);
377 #if SUPPORT_OLD_CRT_INITIALIZATION
378 if ( dyld::gRunInitializersOldWay
)
379 dyld::initializeMainExecutable();
385 #if DEPRECATED_APIS_SUPPORTED
388 // _dyld_call_module_initializers_for_dylib() is the dyld side of
389 // __initialize_Cplusplus() which is in dylib1.o.
390 // It is intended to only be called inside -init rouintes.
391 // -init routines are called before module initializers (what C++
392 // initializers use). Calling __initialize_Cplusplus() in a -init
393 // routine causes the module initializers for an image to be called
394 // which then allows C++ to be used inside a -init routine
396 static void _dyld_call_module_initializers_for_dylib(const struct mach_header
* mh_dylib_header
)
398 if ( dyld::gLogAPIs
)
399 dyld::log("__initialize_Cplusplus()\n");
401 // for now, do nothing...
405 void _dyld_lookup_and_bind_fully(const char* symbolName
, void** address
, NSModule
* module)
407 if ( dyld::gLogAPIs
)
408 dyld::log("%s(\"%s\", %p, %p)\n", __func__
, symbolName
, address
, module);
410 const ImageLoader::Symbol
* sym
;
411 dyld::clearErrorMessage();
412 if ( dyld::flatFindExportedSymbol(symbolName
, &sym
, (const ImageLoader
**)&image
) ) {
414 image
->bindAllLazyPointers(dyld::gLinkContext
, true);
415 if ( address
!= NULL
)
416 *address
= (void*)image
->getExportedSymbolAddress(sym
, dyld::gLinkContext
);
418 *module = ImageLoaderToNSModule(image
);
420 catch (const char* msg
) {
421 dyldAPIhalt(__func__
, msg
);
425 // on failure to find symbol return NULLs
426 if ( address
!= NULL
)
433 // Note: This cannot have public name because dyld is built with a static copy of libc.a
434 // which calls dyld_lookup_and_bind() and expects to find dyld's symbols not host process
435 static void client_dyld_lookup_and_bind(const char* symbolName
, void** address
, NSModule
* module)
437 if ( dyld::gLogAPIs
)
438 dyld::log("_dyld_lookup_and_bind(\"%s\", %p, %p)\n", symbolName
, address
, module);
439 const ImageLoader
* image
;
440 const ImageLoader::Symbol
* sym
;
441 if ( dyld::flatFindExportedSymbol(symbolName
, &sym
, &image
) ) {
442 if ( address
!= NULL
)
443 *address
= (void*)image
->getExportedSymbolAddress(sym
, dyld::gLinkContext
);
445 *module = ImageLoaderToNSModule(image
);
448 // on failure to find symbol return NULLs
449 if ( address
!= NULL
)
456 void _dyld_lookup_and_bind_with_hint(const char* symbolName
, const char* library_name_hint
, void** address
, NSModule
* module)
458 if ( dyld::gLogAPIs
)
459 dyld::log("%s(\"%s\", \"%s\", %p, %p)\n", __func__
, symbolName
, library_name_hint
, address
, module);
460 const ImageLoader
* image
;
461 const ImageLoader::Symbol
* sym
;
462 // Look for library whose path contains the hint. If that fails search everywhere
463 if ( dyld::flatFindExportedSymbolWithHint(symbolName
, library_name_hint
, &sym
, &image
)
464 || dyld::flatFindExportedSymbol(symbolName
, &sym
, &image
) ) {
465 if ( address
!= NULL
)
466 *address
= (void*)image
->getExportedSymbolAddress(sym
, dyld::gLinkContext
);
468 *module = ImageLoaderToNSModule(image
);
471 // on failure to find symbol return NULLs
472 if ( address
!= NULL
)
480 NSSymbol
NSLookupAndBindSymbol(const char *symbolName
)
482 if ( dyld::gLogAPIs
)
483 dyld::log("%s(\"%s\")\n", __func__
, symbolName
);
484 const ImageLoader
* image
;
485 const ImageLoader::Symbol
* sym
;
486 if ( dyld::flatFindExportedSymbol(symbolName
, &sym
, &image
) ) {
487 return SymbolToNSSymbol(sym
);
489 // return NULL on failure
493 NSSymbol
NSLookupAndBindSymbolWithHint(const char* symbolName
, const char* libraryNameHint
)
495 if ( dyld::gLogAPIs
)
496 dyld::log("%s(\"%s\", \"%s\")\n", __func__
, symbolName
, libraryNameHint
);
497 const ImageLoader
* image
;
498 const ImageLoader::Symbol
* sym
;
499 bool found
= dyld::flatFindExportedSymbolWithHint(symbolName
, libraryNameHint
, &sym
, &image
);
501 // hint failed, do slow search of all images
502 found
= dyld::flatFindExportedSymbol(symbolName
, &sym
, &image
);
505 return SymbolToNSSymbol(sym
);
507 // return NULL on failure and log
508 if ( dyld::gLogAPIs
)
509 dyld::log("%s(\"%s\", \"%s\") => NULL \n", __func__
, symbolName
, libraryNameHint
);
516 static __attribute__((noinline
))
517 const struct mach_header
* addImage(void* callerAddress
, const char* path
, bool search
, bool dontLoad
, bool matchInstallName
, bool abortOnError
)
519 ImageLoader
* image
= NULL
;
520 std::vector
<const char*> rpathsFromCallerImage
;
522 dyld::clearErrorMessage();
523 ImageLoader
* callerImage
= dyld::findImageContainingAddress(callerAddress
);
524 // like dlopen, use rpath from caller image and from main executable
525 if ( callerImage
!= NULL
)
526 callerImage
->getRPaths(dyld::gLinkContext
, rpathsFromCallerImage
);
527 ImageLoader::RPathChain
callersRPaths(NULL
, &rpathsFromCallerImage
);
528 if ( callerImage
!= dyld::mainExecutable() ) {
529 dyld::mainExecutable()->getRPaths(dyld::gLinkContext
, rpathsFromCallerImage
);
531 dyld::LoadContext context
;
532 context
.useSearchPaths
= search
;
533 context
.useFallbackPaths
= search
;
534 context
.useLdLibraryPath
= false;
535 context
.implicitRPath
= false;
536 context
.matchByInstallName
= matchInstallName
;
537 context
.dontLoad
= dontLoad
;
538 context
.mustBeBundle
= false;
539 context
.mustBeDylib
= true;
540 context
.canBePIE
= false;
541 context
.origin
= callerImage
!= NULL
? callerImage
->getPath() : NULL
; // caller's image's path
542 context
.rpath
= &callersRPaths
; // rpaths from caller and main executable
544 image
= load(path
, context
);
545 if ( image
!= NULL
) {
546 if ( context
.matchByInstallName
)
547 image
->setMatchInstallPath(true);
548 dyld::link(image
, false, false, callersRPaths
);
549 dyld::runInitializers(image
);
550 // images added with NSAddImage() can never be unloaded
551 image
->setNeverUnload();
554 catch (const char* msg
) {
555 dyld::garbageCollectImages();
557 char pathMsg
[strlen(msg
)+strlen(path
)+4];
558 strcpy(pathMsg
, msg
);
559 strcat(pathMsg
, " ");
560 strcat(pathMsg
, path
);
561 dyldAPIhalt("NSAddImage", pathMsg
);
563 // not halting, so set error state for NSLinkEditError to find
564 setLastError(NSLinkEditOtherError
, 0, path
, msg
);
565 free((void*)msg
); // our free() will do nothing if msg is a string literal
568 // free rpaths (getRPaths() malloc'ed each string)
569 for(std::vector
<const char*>::iterator it
=rpathsFromCallerImage
.begin(); it
!= rpathsFromCallerImage
.end(); ++it
) {
570 const char* str
= *it
;
576 return image
->machHeader();
580 const struct mach_header
* NSAddImage(const char* path
, uint32_t options
)
582 if ( dyld::gLogAPIs
)
583 dyld::log("%s(\"%s\", 0x%08X)\n", __func__
, path
, options
);
584 const bool dontLoad
= ( (options
& NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED
) != 0 );
585 const bool search
= ( (options
& NSADDIMAGE_OPTION_WITH_SEARCHING
) != 0 );
586 const bool matchInstallName
= ( (options
& NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME
) != 0 );
587 const bool abortOnError
= ( (options
& (NSADDIMAGE_OPTION_RETURN_ON_ERROR
|NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED
)) == 0 );
588 void* callerAddress
= __builtin_return_address(1); // note layers: 1: real client, 0: libSystem glue
589 return addImage(callerAddress
, path
, search
, dontLoad
, matchInstallName
, abortOnError
);
592 bool NSAddLibrary(const char* path
)
594 if ( dyld::gLogAPIs
)
595 dyld::log("%s(\"%s\")\n", __func__
, path
);
596 void* callerAddress
= __builtin_return_address(1); // note layers: 1: real client, 0: libSystem glue
597 return (addImage(callerAddress
, path
, false, false, false, false) != NULL
);
600 bool NSAddLibraryWithSearching(const char* path
)
602 if ( dyld::gLogAPIs
)
603 dyld::log("%s(\"%s\")\n", __func__
, path
);
604 void* callerAddress
= __builtin_return_address(1); // note layers: 1: real client, 0: libSystem glue
605 return (addImage(callerAddress
, path
, true, false, false, false) != NULL
);
610 //#define NSADDIMAGE_OPTION_NONE 0x0
611 //#define NSADDIMAGE_OPTION_RETURN_ON_ERROR 0x1
612 //#define NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME 0x8
614 bool NSIsSymbolNameDefinedInImage(const struct mach_header
* mh
, const char* symbolName
)
616 if ( dyld::gLogAPIs
)
617 dyld::log("%s(%p, \"%s\")\n", __func__
, (void *)mh
, symbolName
);
618 ImageLoader
* image
= dyld::findImageByMachHeader(mh
);
619 if ( image
!= NULL
) {
620 if ( image
->findExportedSymbol(symbolName
, true, NULL
) != NULL
)
627 NSSymbol
NSLookupSymbolInImage(const struct mach_header
* mh
, const char* symbolName
, uint32_t options
)
629 if ( dyld::gLogAPIs
)
630 dyld::log("%s(%p, \"%s\", 0x%08X)\n", __func__
, mh
, symbolName
, options
);
631 const ImageLoader::Symbol
* symbol
= NULL
;
632 dyld::clearErrorMessage();
633 ImageLoader
* image
= dyld::findImageByMachHeader(mh
);
634 if ( image
!= NULL
) {
636 if ( options
& NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY
) {
637 image
->bindAllLazyPointers(dyld::gLinkContext
, true);
639 else if ( options
& NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW
) {
640 image
->bindAllLazyPointers(dyld::gLinkContext
, false);
643 catch (const char* msg
) {
644 if ( (options
& NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
) == 0 ) {
645 dyldAPIhalt(__func__
, msg
);
648 symbol
= image
->findExportedSymbol(symbolName
, true, NULL
);
650 if ( dyld::gLogAPIs
&& (symbol
== NULL
) )
651 dyld::log("%s(%p, \"%s\", 0x%08X) ==> NULL\n", __func__
, mh
, symbolName
, options
);
652 return SymbolToNSSymbol(symbol
);
656 // Note: This cannot have public name because dyld is built with a static copy of libc.a
657 // which calls NSIsSymbolNameDefined() and expects to find dyld's symbols not host process
658 static bool client_NSIsSymbolNameDefined(const char* symbolName
)
660 if ( dyld::gLogAPIs
)
661 dyld::log("NSIsSymbolNameDefined(\"%s\")\n", symbolName
);
662 const ImageLoader
* image
;
663 const ImageLoader::Symbol
* sym
;
664 return dyld::flatFindExportedSymbol(symbolName
, &sym
, &image
);
667 bool NSIsSymbolNameDefinedWithHint(const char* symbolName
, const char* libraryNameHint
)
669 if ( dyld::gLogAPIs
)
670 dyld::log("%s(\"%s\", \"%s\")\n", __func__
, symbolName
, libraryNameHint
);
671 const ImageLoader
* image
;
672 const ImageLoader::Symbol
* sym
;
673 bool found
= dyld::flatFindExportedSymbolWithHint(symbolName
, libraryNameHint
, &sym
, &image
);
675 // hint failed, do slow search of all images
676 found
= dyld::flatFindExportedSymbol(symbolName
, &sym
, &image
);
678 if ( !found
&& dyld::gLogAPIs
)
679 dyld::log("%s(\"%s\", \"%s\") => false \n", __func__
, symbolName
, libraryNameHint
);
683 const char* NSNameOfSymbol(NSSymbol symbol
)
685 if ( dyld::gLogAPIs
)
686 dyld::log("%s(%p)\n", __func__
, (void *)symbol
);
687 const char* result
= NULL
;
688 ImageLoader
* image
= dyld::findImageContainingSymbol(symbol
);
690 result
= image
->getExportedSymbolName(NSSymbolToSymbol(symbol
));
694 void* NSAddressOfSymbol(NSSymbol symbol
)
696 if ( dyld::gLogAPIs
)
697 dyld::log("%s(%p)\n", __func__
, (void *)symbol
);
698 if ( symbol
== NULL
)
701 ImageLoader
* image
= dyld::findImageContainingSymbol(symbol
);
703 result
= (void*)image
->getExportedSymbolAddress(NSSymbolToSymbol(symbol
), dyld::gLinkContext
);
707 NSModule
NSModuleForSymbol(NSSymbol symbol
)
709 if ( dyld::gLogAPIs
)
710 dyld::log("%s(%p)\n", __func__
, (void *)symbol
);
711 NSModule result
= NULL
;
712 ImageLoader
* image
= dyld::findImageContainingSymbol(symbol
);
714 result
= ImageLoaderToNSModule(image
);
721 bool _dyld_all_twolevel_modules_prebound(void)
723 if ( dyld::gLogAPIs
)
724 dyld::log("%s()\n", __func__
);
728 void _dyld_bind_objc_module(const void *objc_module
)
730 if ( dyld::gLogAPIs
)
731 dyld::log("%s(%p)\n", __func__
, objc_module
);
732 // do nothing, with new dyld everything already bound
736 bool _dyld_bind_fully_image_containing_address(const void* address
)
738 if ( dyld::gLogAPIs
)
739 dyld::log("%s(%p)\n", __func__
, address
);
740 dyld::clearErrorMessage();
741 ImageLoader
* image
= dyld::findImageContainingAddress(address
);
742 if ( image
!= NULL
) {
744 image
->bindAllLazyPointers(dyld::gLinkContext
, true);
747 catch (const char* msg
) {
748 dyldAPIhalt(__func__
, msg
);
754 bool _dyld_image_containing_address(const void* address
)
756 if ( dyld::gLogAPIs
)
757 dyld::log("%s(%p)\n", __func__
, address
);
758 ImageLoader
*imageLoader
= dyld::findImageContainingAddress(address
);
759 return (NULL
!= imageLoader
);
762 static NSObjectFileImage
createObjectImageFile(ImageLoader
* image
, const void* address
= NULL
, size_t len
=0)
764 NSObjectFileImage result
= new __NSObjectFileImage();
765 result
->image
= image
;
766 result
->imageBaseAddress
= address
;
767 result
->imageLength
= len
;
768 sObjectFileImages
.push_back(result
);
772 NSObjectFileImageReturnCode
NSCreateObjectFileImageFromFile(const char* pathName
, NSObjectFileImage
*objectFileImage
)
774 if ( dyld::gLogAPIs
)
775 dyld::log("%s(\"%s\", ...)\n", __func__
, pathName
);
777 void* callerAddress
= __builtin_return_address(1); // note layers: 1: real client, 0: libSystem glue
778 ImageLoader
* callerImage
= dyld::findImageContainingAddress(callerAddress
);
780 dyld::LoadContext context
;
781 context
.useSearchPaths
= false;
782 context
.useFallbackPaths
= false;
783 context
.useLdLibraryPath
= false;
784 context
.implicitRPath
= false;
785 context
.matchByInstallName
= false;
786 context
.dontLoad
= false;
787 context
.mustBeBundle
= true;
788 context
.mustBeDylib
= false;
789 context
.canBePIE
= false;
790 context
.origin
= callerImage
!= NULL
? callerImage
->getPath() : NULL
; // caller's image's path
791 context
.rpath
= NULL
; // support not yet implemented
793 ImageLoader
* image
= dyld::load(pathName
, context
);
794 // Note: We DO NOT link the image! NSLinkModule will do that
795 if ( image
!= NULL
) {
796 if ( !image
->isBundle() ) {
797 // the image must have been already loaded (since context.mustBeBundle will prevent it from being loaded)
798 return NSObjectFileImageInappropriateFile
;
800 *objectFileImage
= createObjectImageFile(image
);
801 return NSObjectFileImageSuccess
;
804 catch (const char* msg
) {
805 //dyld::log("dyld: NSCreateObjectFileImageFromFile() error: %s\n", msg);
806 dyld::garbageCollectImages();
808 return NSObjectFileImageInappropriateFile
;
810 return NSObjectFileImageFailure
;
814 NSObjectFileImageReturnCode
NSCreateObjectFileImageFromMemory(const void* address
, size_t size
, NSObjectFileImage
*objectFileImage
)
816 if ( dyld::gLogAPIs
)
817 dyld::log("%s(%p, %lu, %p)\n", __func__
, address
, size
, objectFileImage
);
820 ImageLoader
* image
= dyld::loadFromMemory((const uint8_t*)address
, size
, NULL
);
821 if ( ! image
->isBundle() ) {
822 // this API can only be used with bundles...
823 dyld::garbageCollectImages();
824 return NSObjectFileImageInappropriateFile
;
826 // Note: We DO NOT link the image! NSLinkModule will do that
827 if ( image
!= NULL
) {
828 *objectFileImage
= createObjectImageFile(image
, address
, size
);
829 return NSObjectFileImageSuccess
;
832 catch (const char* msg
) {
834 dyld::garbageCollectImages();
835 //dyld::log("dyld: NSCreateObjectFileImageFromMemory() error: %s\n", msg);
837 return NSObjectFileImageFailure
;
840 static bool validOFI(NSObjectFileImage objectFileImage
)
842 const int ofiCount
= sObjectFileImages
.size();
843 for (int i
=0; i
< ofiCount
; ++i
) {
844 if ( sObjectFileImages
[i
] == objectFileImage
)
850 bool NSDestroyObjectFileImage(NSObjectFileImage objectFileImage
)
852 if ( dyld::gLogAPIs
)
853 dyld::log("%s(%p)\n", __func__
, objectFileImage
);
855 if ( validOFI(objectFileImage
) ) {
856 // a failure during NSLinkModule will delete the image
857 if ( objectFileImage
->image
!= NULL
) {
858 // if the image has never been linked or has been unlinked, the image is not in the list of valid images
859 // and we should delete it
860 bool linkedImage
= dyld::validImage(objectFileImage
->image
);
861 if ( ! linkedImage
) {
862 ImageLoader::deleteImage(objectFileImage
->image
);
863 objectFileImage
->image
= NULL
;
867 // remove from list of ofi's
868 for (std::vector
<NSObjectFileImage
>::iterator it
=sObjectFileImages
.begin(); it
!= sObjectFileImages
.end(); it
++) {
869 if ( *it
== objectFileImage
) {
870 sObjectFileImages
.erase(it
);
875 // if object was created from a memory, release that memory
876 // NOTE: this is the way dyld has always done this. NSCreateObjectFileImageFromMemory() hands over ownership of the memory to dyld
877 if ( objectFileImage
->imageBaseAddress
!= NULL
) {
879 if ( (dyld::gLibSystemHelpers
!= NULL
) && (dyld::gLibSystemHelpers
->version
>= 6) ) {
880 size_t sz
= (*dyld::gLibSystemHelpers
->malloc_size
)(objectFileImage
->imageBaseAddress
);
882 (*dyld::gLibSystemHelpers
->free
)((void*)(objectFileImage
->imageBaseAddress
));
887 vm_deallocate(mach_task_self(), (vm_address_t
)objectFileImage
->imageBaseAddress
, objectFileImage
->imageLength
);
891 delete objectFileImage
;
898 bool NSHasModInitObjectFileImage(NSObjectFileImage objectFileImage
)
900 if ( dyld::gLogAPIs
)
901 dyld::log("%s(%p)\n", __func__
, objectFileImage
);
902 return objectFileImage
->image
->needsInitialization();
905 uint32_t NSSymbolDefinitionCountInObjectFileImage(NSObjectFileImage objectFileImage
)
907 if ( dyld::gLogAPIs
)
908 dyld::log("%s(%p)\n", __func__
, objectFileImage
);
909 return objectFileImage
->image
->getExportedSymbolCount();
912 const char* NSSymbolDefinitionNameInObjectFileImage(NSObjectFileImage objectFileImage
, uint32_t ordinal
)
914 if ( dyld::gLogAPIs
)
915 dyld::log("%s(%p,%d)\n", __func__
, objectFileImage
, ordinal
);
916 const ImageLoader::Symbol
* sym
= objectFileImage
->image
->getIndexedExportedSymbol(ordinal
);
917 return objectFileImage
->image
->getExportedSymbolName(sym
);
920 uint32_t NSSymbolReferenceCountInObjectFileImage(NSObjectFileImage objectFileImage
)
922 if ( dyld::gLogAPIs
)
923 dyld::log("%s(%p)\n", __func__
, objectFileImage
);
924 return objectFileImage
->image
->getImportedSymbolCount();
927 const char * NSSymbolReferenceNameInObjectFileImage(NSObjectFileImage objectFileImage
, uint32_t ordinal
,
928 bool* tentative_definition
)
930 if ( dyld::gLogAPIs
)
931 dyld::log("%s(%p,%d)\n", __func__
, objectFileImage
, ordinal
);
932 const ImageLoader::Symbol
* sym
= objectFileImage
->image
->getIndexedImportedSymbol(ordinal
);
933 if ( tentative_definition
!= NULL
) {
934 ImageLoader::ReferenceFlags flags
= objectFileImage
->image
->getImportedSymbolInfo(sym
);
935 if ( (flags
& ImageLoader::kTentativeDefinition
) != 0 )
936 *tentative_definition
= true;
938 *tentative_definition
= false;
940 return objectFileImage
->image
->getImportedSymbolName(sym
);
943 void* NSGetSectionDataInObjectFileImage(NSObjectFileImage objectFileImage
,
944 const char* segmentName
, const char* sectionName
, unsigned long* size
)
946 if ( dyld::gLogAPIs
)
947 dyld::log("%s(%p,%s, %s)\n", __func__
, objectFileImage
, segmentName
, sectionName
);
951 if ( objectFileImage
->image
->getSectionContent(segmentName
, sectionName
, &start
, &length
) ) {
961 bool NSIsSymbolDefinedInObjectFileImage(NSObjectFileImage objectFileImage
, const char* symbolName
)
963 if ( dyld::gLogAPIs
)
964 dyld::log("%s(%p,%s)\n", __func__
, objectFileImage
, symbolName
);
965 const ImageLoader::Symbol
* sym
= objectFileImage
->image
->findExportedSymbol(symbolName
, true, NULL
);
966 return ( sym
!= NULL
);
971 NSModule
NSLinkModule(NSObjectFileImage objectFileImage
, const char* moduleName
, uint32_t options
)
973 if ( dyld::gLogAPIs
)
974 dyld::log("%s(%p, \"%s\", 0x%08X)\n", __func__
, objectFileImage
, moduleName
, options
);
976 dyld::clearErrorMessage();
978 if ( (options
& NSLINKMODULE_OPTION_CAN_UNLOAD
) != 0 )
979 objectFileImage
->image
->setCanUnload();
981 // NSLinkModule allows a bundle to be link multpile times
982 // each link causes the bundle to be copied to a new address
983 if ( objectFileImage
->image
->isLinked() ) {
984 // already linked, so clone a new one and link it
985 objectFileImage
->image
= dyld::cloneImage(objectFileImage
->image
);
988 // for memory based images, set moduleName as the name anyone calling _dyld_get_image_name() will see
989 if ( objectFileImage
->image
->getPath() == NULL
) {
990 objectFileImage
->image
->setPath(moduleName
);
991 // <rdar://problem/8812589> dyld has NULL paths in image info array
992 dyld_image_info info
;
993 info
.imageLoadAddress
= objectFileImage
->image
->machHeader();
994 info
.imageFilePath
= moduleName
;
995 info
.imageFileModDate
= 0;
996 addImagesToAllImages(1, &info
);
999 // support private bundles
1000 if ( (options
& NSLINKMODULE_OPTION_PRIVATE
) != 0 )
1001 objectFileImage
->image
->setHideExports();
1003 // set up linking options
1004 bool forceLazysBound
= ( (options
& NSLINKMODULE_OPTION_BINDNOW
) != 0 );
1006 // load libraries, rebase, bind, to make this image usable
1007 dyld::link(objectFileImage
->image
, forceLazysBound
, false, ImageLoader::RPathChain(NULL
,NULL
));
1009 // bump reference count to keep this bundle from being garbage collected
1010 objectFileImage
->image
->incrementDlopenReferenceCount();
1012 // run initializers unless magic flag says not to
1013 if ( (options
& NSLINKMODULE_OPTION_DONT_CALL_MOD_INIT_ROUTINES
) == 0 )
1014 dyld::runInitializers(objectFileImage
->image
);
1016 return ImageLoaderToNSModule(objectFileImage
->image
);
1018 catch (const char* msg
) {
1019 dyld::garbageCollectImages();
1020 if ( (options
& NSLINKMODULE_OPTION_RETURN_ON_ERROR
) == 0 )
1021 dyldAPIhalt(__func__
, msg
);
1022 // not halting, so set error state for NSLinkEditError to find
1023 setLastError(NSLinkEditOtherError
, 0, moduleName
, msg
);
1024 // dyld::link() deleted the image so lose our reference
1025 objectFileImage
->image
= NULL
;
1032 #if OLD_LIBSYSTEM_SUPPORT
1033 // This is for compatibility with old libSystems (libdyld.a) which process ObjectFileImages outside dyld
1034 static NSModule
_dyld_link_module(NSObjectFileImage object_addr
, size_t object_size
, const char* moduleName
, uint32_t options
)
1036 if ( dyld::gLogAPIs
)
1037 dyld::log("%s(%p, \"%s\", 0x%08X)\n", "NSLinkModule", object_addr
, moduleName
, options
); // note name/args translation
1038 ImageLoader
* image
= NULL
;
1039 dyld::clearErrorMessage();
1041 const char* imageName
= moduleName
;
1042 image
= dyld::loadFromMemory((const uint8_t*)object_addr
, object_size
, imageName
);
1044 if ( image
!= NULL
) {
1045 // support private bundles
1046 if ( (options
& NSLINKMODULE_OPTION_PRIVATE
) != 0 )
1047 image
->setHideExports();
1049 // set up linking options
1050 bool forceLazysBound
= ( (options
& NSLINKMODULE_OPTION_BINDNOW
) != 0 );
1052 // load libraries, rebase, bind, to make this image usable
1053 dyld::link(image
, forceLazysBound
, false, ImageLoader::RPathChain(NULL
,NULL
));
1055 // run initializers unless magic flag says not to
1056 if ( (options
& NSLINKMODULE_OPTION_DONT_CALL_MOD_INIT_ROUTINES
) == 0 )
1057 dyld::runInitializers(image
);
1060 catch (const char* msg
) {
1061 if ( (options
& NSLINKMODULE_OPTION_RETURN_ON_ERROR
) == 0 )
1062 dyldAPIhalt("NSLinkModule", msg
);
1063 // not halting, so set error state for NSLinkEditError to find
1064 setLastError(NSLinkEditOtherError
, 0, moduleName
, msg
);
1065 // if image was created for this bundle, destroy it
1066 if ( image
!= NULL
) {
1067 dyld::removeImage(image
);
1068 ImageLoader::deleteImage(image
);
1073 return ImageLoaderToNSModule(image
);
1077 NSSymbol
NSLookupSymbolInModule(NSModule
module, const char* symbolName
)
1079 if ( dyld::gLogAPIs
)
1080 dyld::log("%s(%p, \"%s\")\n", __func__
, (void *)module, symbolName
);
1081 ImageLoader
* image
= NSModuleToImageLoader(module);
1082 if ( image
== NULL
)
1084 return SymbolToNSSymbol(image
->findExportedSymbol(symbolName
, false, NULL
));
1087 const char* NSNameOfModule(NSModule
module)
1089 if ( dyld::gLogAPIs
)
1090 dyld::log("%s(%p)\n", __func__
, module);
1091 ImageLoader
* image
= NSModuleToImageLoader(module);
1092 if ( image
== NULL
)
1094 return image
->getPath();
1097 const char* NSLibraryNameForModule(NSModule
module)
1099 if ( dyld::gLogAPIs
)
1100 dyld::log("%s(%p)\n", __func__
, module);
1101 ImageLoader
* image
= NSModuleToImageLoader(module);
1102 if ( image
== NULL
)
1104 return image
->getPath();
1107 bool NSUnLinkModule(NSModule
module, uint32_t options
)
1109 if ( dyld::gLogAPIs
)
1110 dyld::log("%s(%p, 0x%08X)\n", __func__
, module, options
);
1111 if ( module == NULL
)
1113 ImageLoader
* image
= NSModuleToImageLoader(module);
1114 if ( image
== NULL
)
1116 dyld::runImageStaticTerminators(image
);
1117 if ( (dyld::gLibSystemHelpers
!= NULL
) && (dyld::gLibSystemHelpers
->version
>= 13) ) {
1118 __cxa_range_t ranges
[3];
1120 for (unsigned int j
=0; j
< image
->segmentCount(); ++j
) {
1121 if ( !image
->segExecutable(j
) )
1123 ranges
[rangeCount
].addr
= (const void*)image
->segActualLoadAddress(j
);
1124 ranges
[rangeCount
].length
= image
->segSize(j
);
1127 (*dyld::gLibSystemHelpers
->cxa_finalize_ranges
)(ranges
, rangeCount
);
1129 dyld::removeImage(image
);
1131 if ( (options
& NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED
) != 0 )
1132 image
->setLeaveMapped();
1134 // TODO: NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES
1136 // Only delete image if there is no ofi referencing it
1137 // That means the ofi was destroyed after linking, so no one is left to delete this image
1138 const int ofiCount
= sObjectFileImages
.size();
1140 for (int i
=0; i
< ofiCount
; ++i
) {
1141 NSObjectFileImage ofi
= sObjectFileImages
[i
];
1142 if ( ofi
->image
== image
)
1146 ImageLoader::deleteImage(image
);
1151 // internal name and parameters do not match public name and parameters...
1152 static void _dyld_install_handlers(void* undefined
, void* multiple
, void* linkEdit
)
1154 if ( dyld::gLogAPIs
)
1155 dyld::log("NSLinkEditErrorHandlers()\n");
1157 dyld::registerUndefinedHandler((dyld::UndefinedHandler
)undefined
);
1158 // no support for multiple or linkedit handlers
1164 void NSLinkEditError(NSLinkEditErrors
* c
, int* errorNumber
, const char** fileName
, const char** errorString
)
1167 *c
= sLastErrorFileCode
;
1168 *errorNumber
= sLastErrorNo
;
1169 *fileName
= sLastErrorFilePath
;
1170 *errorString
= dyld::getErrorMessage();
1175 static void _dyld_register_binding_handler(void * (*bindingHandler
)(const char *, const char *, void *), ImageLoader::BindingOptions bindingOptions
)
1177 if ( dyld::gLogAPIs
)
1178 dyld::log("%s()\n", __func__
);
1179 dyld::gLinkContext
.bindingHandler
= bindingHandler
;
1180 dyld::gLinkContext
.bindingOptions
= bindingOptions
;
1183 #endif //DEPRECATED_APIS_SUPPORTED
1186 // Call by fork() in libSystem after the kernel trap is done on the child side
1187 void _dyld_fork_child()
1189 if ( dyld::gLogAPIs
)
1190 dyld::log("%s()\n", __func__
);
1191 // The implementation of fork() in libSystem knows to reset the variable mach_task_self_
1192 // in libSystem for the child of a fork. But dyld is built with a static copy
1193 // of libc.a and has its own copy of mach_task_self_ which we reset here.
1195 // In mach_init.h mach_task_self() is #defined to mach_task_self_ and
1196 // in mach_init() mach_task_self_ is initialized to task_self_trap().
1198 extern mach_port_t mach_task_self_
;
1199 mach_task_self_
= task_self_trap();
1201 // If dyld is sending load/unload notices to CoreSymbolication, the shared memory
1202 // page is not copied on fork. <rdar://problem/6797342>
1203 // NULL the CoreSymbolication shared memory pointer to prevent a crash.
1204 dyld::gProcessInfo
->coreSymbolicationShmPage
= NULL
;
1205 // for safety, make sure child starts with clean systemOrderFlag
1206 dyld::gProcessInfo
->systemOrderFlag
= 0;
1210 #if DEPRECATED_APIS_SUPPORTED
1211 // returns true if prebinding was used in main executable
1212 bool _dyld_launched_prebound()
1214 if ( dyld::gLogAPIs
)
1215 dyld::log("%s()\n", __func__
);
1217 // ¥¥¥Êif we deprecate prebinding, we may want to consider always returning true or false here
1218 return dyld::mainExecutablePrebound();
1223 // _dyld_NSMakePrivateModulePublic() is the dyld side of the hack
1224 // NSMakePrivateModulePublic() needed for the dlopen() to turn it's
1225 // RTLD_LOCAL handles into RTLD_GLOBAL. It just simply turns off the private
1226 // flag on the image for this module. If the module was found and it was
1227 // private then everything worked and TRUE is returned else FALSE is returned.
1229 static bool NSMakePrivateModulePublic(NSModule
module)
1231 ImageLoader
* image
= NSModuleToImageLoader(module);
1232 if ( image
!= NULL
) {
1233 if ( image
->hasHiddenExports() ) {
1234 image
->setHideExports(false);
1241 #endif // DEPRECATED_APIS_SUPPORTED
1243 int _dyld_func_lookup(const char* name
, void** address
)
1245 for (const dyld_func
* p
= dyld_funcs
; p
->name
!= NULL
; ++p
) {
1246 if ( strcmp(p
->name
, name
) == 0 ) {
1247 if( p
->implementation
== unimplemented
)
1248 dyld::log("unimplemented dyld function: %s\n", p
->name
);
1249 *address
= p
->implementation
;
1258 static void registerThreadHelpers(const dyld::LibSystemHelpers
* helpers
)
1260 dyld::gLibSystemHelpers
= helpers
;
1262 // let gdb know it is safe to run code in inferior that might call malloc()
1263 dyld::gProcessInfo
->libSystemInitialized
= true;
1265 #if !SUPPORT_ZERO_COST_EXCEPTIONS
1266 if ( helpers
->version
>= 5 ) {
1267 // create key use by dyld exception handling
1269 int result
= helpers
->pthread_key_create(&key
, NULL
);
1271 __Unwind_SjLj_SetThreadKey(key
);
1277 static void dlerrorClear()
1279 if ( dyld::gLibSystemHelpers
!= NULL
) {
1280 // <rdar://problem/10595338> dlerror buffer leak
1281 // dlerrorClear() should not force allocation, but zero it if already allocated
1282 if ( dyld::gLibSystemHelpers
->version
>= 10 ) {
1283 if ( ! (*dyld::gLibSystemHelpers
->hasPerThreadBufferFor_dlerror
)() )
1287 // first char of buffer is flag whether string (starting at second char) is valid
1288 char* buffer
= (*dyld::gLibSystemHelpers
->getThreadBufferFor_dlerror
)(2);
1294 static void dlerrorSet(const char* msg
)
1296 if ( dyld::gLibSystemHelpers
!= NULL
) {
1297 // first char of buffer is flag whether string (starting at second char) is valid
1298 char* buffer
= (*dyld::gLibSystemHelpers
->getThreadBufferFor_dlerror
)(strlen(msg
)+2);
1300 strcpy(&buffer
[1], msg
);
1305 bool dlopen_preflight(const char* path
)
1307 if ( dyld::gLogAPIs
)
1308 dyld::log("%s(%s)\n", __func__
, path
);
1312 #if DYLD_SHARED_CACHE_SUPPORT
1313 // <rdar://problem/5910137> dlopen_preflight() on image in shared cache leaves it loaded but not objc initialized
1314 // if requested path is to something in the dyld shared cache, always succeed
1315 if ( dyld::inSharedCache(path
) )
1319 CRSetCrashLogMessage("dyld: in dlopen_preflight()");
1321 bool result
= false;
1322 std::vector
<const char*> rpathsFromCallerImage
;
1324 void* callerAddress
= __builtin_return_address(1); // note layers: 1: real client, 0: libSystem glue
1325 ImageLoader
* callerImage
= dyld::findImageContainingAddress(callerAddress
);
1326 // for dlopen, use rpath from caller image and from main executable
1327 if ( callerImage
!= NULL
)
1328 callerImage
->getRPaths(dyld::gLinkContext
, rpathsFromCallerImage
);
1329 ImageLoader::RPathChain
callersRPaths(NULL
, &rpathsFromCallerImage
);
1330 if ( callerImage
!= dyld::mainExecutable() ) {
1331 dyld::mainExecutable()->getRPaths(dyld::gLinkContext
, rpathsFromCallerImage
);
1334 ImageLoader
* image
= NULL
;
1335 const bool leafName
= (strchr(path
, '/') == NULL
);
1336 const bool absolutePath
= (path
[0] == '/');
1337 #if __IPHONE_OS_VERSION_MIN_REQUIRED
1338 char canonicalPath
[PATH_MAX
];
1339 // <rdar://problem/7017050> dlopen() not opening frameworks from shared cache with // or ./ in path
1341 // make path canonical if it contains a // or ./
1342 if ( (strstr(path
, "//") != NULL
) || (strstr(path
, "./") != NULL
) ) {
1343 const char* lastSlash
= strrchr(path
, '/');
1344 char dirPath
[PATH_MAX
];
1345 if ( strlcpy(dirPath
, path
, sizeof(dirPath
)) < sizeof(dirPath
) ) {
1346 dirPath
[lastSlash
-path
] = '\0';
1347 if ( realpath(dirPath
, canonicalPath
) ) {
1348 strlcat(canonicalPath
, "/", sizeof(canonicalPath
));
1349 if ( strlcat(canonicalPath
, lastSlash
+1, sizeof(canonicalPath
)) < sizeof(canonicalPath
) ) {
1350 // if all fit in buffer, use new canonical path
1351 path
= canonicalPath
;
1358 dyld::LoadContext context
;
1359 context
.useSearchPaths
= true;
1360 context
.useFallbackPaths
= leafName
; // a partial path implies don't use fallback paths
1361 context
.useLdLibraryPath
= leafName
; // a leafname implies should search
1362 context
.implicitRPath
= !absolutePath
; // a non-absolute path implies try rpath searching
1363 context
.matchByInstallName
= true;
1364 context
.dontLoad
= false;
1365 context
.mustBeBundle
= false;
1366 context
.mustBeDylib
= false;
1367 context
.canBePIE
= true;
1368 context
.origin
= callerImage
!= NULL
? callerImage
->getPath() : NULL
; // caller's image's path
1369 context
.rpath
= &callersRPaths
; // rpaths from caller and main executable
1371 image
= load(path
, context
);
1372 if ( image
!= NULL
) {
1373 dyld::preflight(image
, callersRPaths
); // image object deleted by dyld::preflight()
1377 catch (const char* msg
) {
1378 const char* str
= dyld::mkstringf("dlopen_preflight(%s): %s", path
, msg
);
1381 free((void*)msg
); // our free() will do nothing if msg is a string literal
1383 // free rpaths (getRPaths() malloc'ed each string)
1384 for(std::vector
<const char*>::iterator it
=rpathsFromCallerImage
.begin(); it
!= rpathsFromCallerImage
.end(); ++it
) {
1385 const char* str
= *it
;
1388 CRSetCrashLogMessage(NULL
);
1393 void* dlopen(const char* path
, int mode
)
1395 if ( dyld::gLogAPIs
)
1396 dyld::log("%s(%s, 0x%08X)\n", __func__
, ((path
==NULL
) ? "NULL" : path
), mode
);
1400 // passing NULL for path means return magic object
1401 if ( path
== NULL
) {
1402 // RTLD_FIRST means any dlsym() calls on the handle should only search that handle and not subsequent images
1403 if ( (mode
& RTLD_FIRST
) != 0 )
1404 return RTLD_MAIN_ONLY
;
1406 return RTLD_DEFAULT
;
1409 // acquire global dyld lock (dlopen is special - libSystem glue does not do locking)
1410 bool lockHeld
= false;
1411 if ( (dyld::gLibSystemHelpers
!= NULL
) && (dyld::gLibSystemHelpers
->version
>= 4) ) {
1412 dyld::gLibSystemHelpers
->acquireGlobalDyldLock();
1413 CRSetCrashLogMessage("dyld: in dlopen()");
1417 void* result
= NULL
;
1418 ImageLoader
* image
= NULL
;
1419 std::vector
<const char*> rpathsFromCallerImage
;
1421 void* callerAddress
= __builtin_return_address(1); // note layers: 1: real client, 0: libSystem glue
1422 ImageLoader
* callerImage
= dyld::findImageContainingAddress(callerAddress
);
1423 // for dlopen, use rpath from caller image and from main executable
1424 if ( callerImage
!= NULL
)
1425 callerImage
->getRPaths(dyld::gLinkContext
, rpathsFromCallerImage
);
1426 ImageLoader::RPathChain
callersRPaths(NULL
, &rpathsFromCallerImage
);
1427 if ( callerImage
!= dyld::mainExecutable() ) {
1428 dyld::mainExecutable()->getRPaths(dyld::gLinkContext
, rpathsFromCallerImage
);
1431 const bool leafName
= (strchr(path
, '/') == NULL
);
1432 const bool absolutePath
= (path
[0] == '/');
1433 #if __IPHONE_OS_VERSION_MIN_REQUIRED
1434 char canonicalPath
[PATH_MAX
];
1435 // <rdar://problem/7017050> dlopen() not opening frameworks from shared cache with // or ./ in path
1437 // make path canonical if it contains a // or ./
1438 if ( (strstr(path
, "//") != NULL
) || (strstr(path
, "./") != NULL
) ) {
1439 const char* lastSlash
= strrchr(path
, '/');
1440 char dirPath
[PATH_MAX
];
1441 if ( strlcpy(dirPath
, path
, sizeof(dirPath
)) < sizeof(dirPath
) ) {
1442 dirPath
[lastSlash
-path
] = '\0';
1443 if ( realpath(dirPath
, canonicalPath
) ) {
1444 strlcat(canonicalPath
, "/", sizeof(canonicalPath
));
1445 if ( strlcat(canonicalPath
, lastSlash
+1, sizeof(canonicalPath
)) < sizeof(canonicalPath
) ) {
1446 // if all fit in buffer, use new canonical path
1447 path
= canonicalPath
;
1454 dyld::LoadContext context
;
1455 context
.useSearchPaths
= true;
1456 context
.useFallbackPaths
= leafName
; // a partial path means no fallback paths
1457 context
.useLdLibraryPath
= leafName
; // a leafname implies should search
1458 context
.implicitRPath
= !absolutePath
; // a non-absolute path implies try rpath searching
1459 context
.matchByInstallName
= true;
1460 context
.dontLoad
= ( (mode
& RTLD_NOLOAD
) != 0 );
1461 context
.mustBeBundle
= false;
1462 context
.mustBeDylib
= false;
1463 context
.canBePIE
= true;
1464 context
.origin
= callerImage
!= NULL
? callerImage
->getPath() : NULL
; // caller's image's path
1465 context
.rpath
= &callersRPaths
; // rpaths from caller and main executable
1467 image
= load(path
, context
);
1468 if ( image
!= NULL
) {
1469 // bump reference count. Do this before link() so that if an initializer calls dlopen and fails
1470 // this image is not garbage collected
1471 image
->incrementDlopenReferenceCount();
1472 // link in all dependents
1473 if ( (mode
& RTLD_NOLOAD
) == 0 ) {
1474 bool alreadyLinked
= image
->isLinked();
1475 bool forceLazysBound
= ( (mode
& RTLD_NOW
) != 0 );
1476 dyld::link(image
, forceLazysBound
, false, callersRPaths
);
1477 if ( ! alreadyLinked
) {
1478 // only hide exports if image is not already in use
1479 if ( (mode
& RTLD_LOCAL
) != 0 )
1480 image
->setHideExports(true);
1484 // RTLD_NODELETE means don't unmap image even after dlclosed. This is what dlcompat did on Mac OS X 10.3
1485 // On other *nix OS's, it means dlclose() should do nothing, but the handle should be invalidated.
1486 // The subtle differences are:
1487 // 1) if the image has any termination routines, whether they are run during dlclose or when the process terminates
1488 // 2) If someone does a supsequent dlopen() on the same image, whether the same address should be used.
1489 if ( (mode
& RTLD_NODELETE
) != 0 )
1490 image
->setLeaveMapped();
1492 // release global dyld lock early, this enables initializers to do threaded operations
1494 CRSetCrashLogMessage(NULL
);
1495 dyld::gLibSystemHelpers
->releaseGlobalDyldLock();
1499 // RTLD_NOLOAD means dlopen should fail unless path is already loaded.
1500 // don't run initializers when RTLD_NOLOAD is set. This only matters if dlopen() is
1501 // called from within an initializer because it can cause initializers to run
1502 // out of order. Most uses of RTLD_NOLOAD are "probes". If they want initialzers
1503 // to run, then don't use RTLD_NOLOAD.
1504 if ( (mode
& RTLD_NOLOAD
) == 0 ) {
1506 dyld::runInitializers(image
);
1509 // RTLD_FIRST means any dlsym() calls on the handle should only search that handle and not subsequent images
1510 // this is tracked by setting the low bit of the handle, which is usually zero by malloc alignment
1511 if ( (mode
& RTLD_FIRST
) != 0 )
1512 result
= (void*)(((uintptr_t)image
)|1);
1517 catch (const char* msg
) {
1518 if ( image
!= NULL
) {
1519 // load() succeeded but, link() failed
1520 // back down reference count and do GC
1521 image
->decrementDlopenReferenceCount();
1522 if ( image
->dlopenCount() == 0 )
1523 dyld::garbageCollectImages();
1525 const char* str
= dyld::mkstringf("dlopen(%s, %d): %s", path
, mode
, msg
);
1526 if ( dyld::gLogAPIs
)
1527 dyld::log(" %s() failed, error: '%s'\n", __func__
, str
);
1530 free((void*)msg
); // our free() will do nothing if msg is a string literal
1533 // free rpaths (getRPaths() malloc'ed each string)
1534 for(std::vector
<const char*>::iterator it
=rpathsFromCallerImage
.begin(); it
!= rpathsFromCallerImage
.end(); ++it
) {
1535 const char* str
= *it
;
1539 // when context.dontLoad is set, load() returns NULL instead of throwing an exception
1540 if ( (mode
& RTLD_NOLOAD
) && (result
== NULL
) ) {
1541 dlerrorSet("image not already loaded");
1545 CRSetCrashLogMessage(NULL
);
1546 dyld::gLibSystemHelpers
->releaseGlobalDyldLock();
1548 if ( dyld::gLogAPIs
&& (result
!= NULL
) )
1549 dyld::log(" %s(%s) ==> %p\n", __func__
, path
, result
);
1555 int dlclose(void* handle
)
1557 if ( dyld::gLogAPIs
)
1558 dyld::log("%s(%p)\n", __func__
, handle
);
1560 // silently accept magic handles for main executable
1561 if ( handle
== RTLD_MAIN_ONLY
)
1563 if ( handle
== RTLD_DEFAULT
)
1566 ImageLoader
* image
= (ImageLoader
*)(((uintptr_t)handle
) & (-4)); // clear mode bits
1567 if ( dyld::validImage(image
) ) {
1569 // decrement use count
1570 if ( image
->decrementDlopenReferenceCount() ) {
1571 dlerrorSet("dlclose() called too many times");
1574 // remove image if reference count went to zero
1575 if ( image
->dlopenCount() == 0 )
1576 dyld::garbageCollectImages();
1580 dlerrorSet("invalid handle passed to dlclose()");
1587 int dladdr(const void* address
, Dl_info
* info
)
1589 if ( dyld::gLogAPIs
)
1590 dyld::log("%s(%p, %p)\n", __func__
, address
, info
);
1592 CRSetCrashLogMessage("dyld: in dladdr()");
1593 ImageLoader
* image
= dyld::findImageContainingAddress(address
);
1594 if ( image
!= NULL
) {
1595 info
->dli_fname
= image
->getRealPath();
1596 info
->dli_fbase
= (void*)image
->machHeader();
1597 if ( address
== info
->dli_fbase
) {
1598 // special case lookup of header
1599 info
->dli_sname
= "__dso_handle";
1600 info
->dli_saddr
= info
->dli_fbase
;
1601 CRSetCrashLogMessage(NULL
);
1602 return 1; // success
1604 // find closest symbol in the image
1605 info
->dli_sname
= image
->findClosestSymbol(address
, (const void**)&info
->dli_saddr
);
1606 // never return the mach_header symbol
1607 if ( info
->dli_saddr
== info
->dli_fbase
) {
1608 info
->dli_sname
= NULL
;
1609 info
->dli_saddr
= NULL
;
1610 CRSetCrashLogMessage(NULL
);
1611 return 1; // success
1613 if ( info
->dli_sname
!= NULL
) {
1614 if ( info
->dli_sname
[0] == '_' )
1615 info
->dli_sname
= info
->dli_sname
+1; // strip off leading underscore
1616 //dyld::log("dladdr(%p) => %p %s\n", address, info->dli_saddr, info->dli_sname);
1617 CRSetCrashLogMessage(NULL
);
1618 return 1; // success
1620 info
->dli_sname
= NULL
;
1621 info
->dli_saddr
= NULL
;
1622 CRSetCrashLogMessage(NULL
);
1623 return 1; // success
1625 CRSetCrashLogMessage(NULL
);
1626 return 0; // failure
1632 if ( dyld::gLogAPIs
)
1633 dyld::log("%s()\n", __func__
);
1635 if ( dyld::gLibSystemHelpers
!= NULL
) {
1636 // if using newer libdyld.dylib and buffer if buffer not yet allocated, return NULL
1637 if ( dyld::gLibSystemHelpers
->version
>= 10 ) {
1638 if ( ! (*dyld::gLibSystemHelpers
->hasPerThreadBufferFor_dlerror
)() )
1642 // first char of buffer is flag whether string (starting at second char) is valid
1643 char* buffer
= (*dyld::gLibSystemHelpers
->getThreadBufferFor_dlerror
)(2);
1644 if ( buffer
[0] != '\0' ) { // if valid buffer
1645 buffer
[0] = '\0'; // mark invalid, so next call to dlerror returns NULL
1646 return &buffer
[1]; // return message
1652 void* dlsym(void* handle
, const char* symbolName
)
1654 if ( dyld::gLogAPIs
)
1655 dyld::log("%s(%p, %s)\n", __func__
, handle
, symbolName
);
1657 CRSetCrashLogMessage("dyld: in dlsym()");
1660 const ImageLoader
* image
;
1661 const ImageLoader::Symbol
* sym
;
1663 // dlsym() assumes symbolName passed in is same as in C source code
1664 // dyld assumes all symbol names have an underscore prefix
1665 char underscoredName
[strlen(symbolName
)+2];
1666 underscoredName
[0] = '_';
1667 strcpy(&underscoredName
[1], symbolName
);
1669 // magic "search all" handle
1670 if ( handle
== RTLD_DEFAULT
) {
1671 if ( dyld::flatFindExportedSymbol(underscoredName
, &sym
, &image
) ) {
1672 CRSetCrashLogMessage(NULL
);
1673 return (void*)image
->getExportedSymbolAddress(sym
, dyld::gLinkContext
);
1675 const char* str
= dyld::mkstringf("dlsym(RTLD_DEFAULT, %s): symbol not found", symbolName
);
1678 CRSetCrashLogMessage(NULL
);
1682 // magic "search only main executable" handle
1683 if ( handle
== RTLD_MAIN_ONLY
) {
1684 image
= dyld::mainExecutable();
1685 sym
= image
->findExportedSymbol(underscoredName
, true, &image
); // search RTLD_FIRST way
1686 if ( sym
!= NULL
) {
1687 CRSetCrashLogMessage(NULL
);
1688 return (void*)image
->getExportedSymbolAddress(sym
, dyld::gLinkContext
);
1690 const char* str
= dyld::mkstringf("dlsym(RTLD_MAIN_ONLY, %s): symbol not found", symbolName
);
1693 CRSetCrashLogMessage(NULL
);
1697 // magic "search what I would see" handle
1698 if ( handle
== RTLD_NEXT
) {
1699 void* callerAddress
= __builtin_return_address(1); // note layers: 1: real client, 0: libSystem glue
1700 ImageLoader
* callerImage
= dyld::findImageContainingAddress(callerAddress
);
1701 sym
= callerImage
->findExportedSymbolInDependentImages(underscoredName
, dyld::gLinkContext
, &image
); // don't search image, but do search what it links against
1702 if ( sym
!= NULL
) {
1703 CRSetCrashLogMessage(NULL
);
1704 return (void*)image
->getExportedSymbolAddress(sym
, dyld::gLinkContext
);
1706 const char* str
= dyld::mkstringf("dlsym(RTLD_NEXT, %s): symbol not found", symbolName
);
1709 CRSetCrashLogMessage(NULL
);
1712 // magic "search me, then what I would see" handle
1713 if ( handle
== RTLD_SELF
) {
1714 void* callerAddress
= __builtin_return_address(1); // note layers: 1: real client, 0: libSystem glue
1715 ImageLoader
* callerImage
= dyld::findImageContainingAddress(callerAddress
);
1716 sym
= callerImage
->findExportedSymbolInImageOrDependentImages(underscoredName
, dyld::gLinkContext
, &image
); // search image and what it links against
1717 if ( sym
!= NULL
) {
1718 CRSetCrashLogMessage(NULL
);
1719 return (void*)image
->getExportedSymbolAddress(sym
, dyld::gLinkContext
);
1721 const char* str
= dyld::mkstringf("dlsym(RTLD_SELF, %s): symbol not found", symbolName
);
1724 CRSetCrashLogMessage(NULL
);
1728 image
= (ImageLoader
*)(((uintptr_t)handle
) & (-4)); // clear mode bits
1729 if ( dyld::validImage(image
) ) {
1730 if ( (((uintptr_t)handle
) & 1) != 0 )
1731 sym
= image
->findExportedSymbol(underscoredName
, true, &image
); // search RTLD_FIRST way
1733 sym
= image
->findExportedSymbolInImageOrDependentImages(underscoredName
, dyld::gLinkContext
, &image
); // search image and what it links against
1735 if ( sym
!= NULL
) {
1736 CRSetCrashLogMessage(NULL
);
1737 ImageLoader
* callerImage
= NULL
;
1738 if ( sDynamicInterposing
) {
1739 // only take time to look up caller, if dynamic interposing in use
1740 void* callerAddress
= __builtin_return_address(1); // note layers: 1: real client, 0: libSystem glue
1741 callerImage
= dyld::findImageContainingAddress(callerAddress
);
1743 return (void*)image
->getExportedSymbolAddress(sym
, dyld::gLinkContext
, callerImage
);
1745 const char* str
= dyld::mkstringf("dlsym(%p, %s): symbol not found", handle
, symbolName
);
1750 dlerrorSet("invalid handle passed to dlsym()");
1752 CRSetCrashLogMessage(NULL
);
1765 const struct dyld_all_image_infos
* _dyld_get_all_image_infos()
1767 return dyld::gProcessInfo
;
1770 #if SUPPORT_ZERO_COST_EXCEPTIONS
1771 static bool client_dyld_find_unwind_sections(void* addr
, dyld_unwind_sections
* info
)
1773 //if ( dyld::gLogAPIs )
1774 // dyld::log("%s(%p, %p)\n", __func__, addr, info);
1776 ImageLoader
* image
= dyld::findImageContainingAddress(addr
);
1777 if ( image
!= NULL
) {
1778 image
->getUnwindInfo(info
);
1786 void dyld_register_image_state_change_handler(dyld_image_states state
, bool batch
,
1787 dyld_image_state_change_handler handler
)
1789 if ( dyld::gLogAPIs
)
1790 dyld::log("%s(%d, %d, %p)\n", __func__
, state
, batch
, handler
);
1792 dyld::registerImageStateBatchChangeHandler(state
, handler
);
1794 dyld::registerImageStateSingleChangeHandler(state
, handler
);
1797 const char* dyld_image_path_containing_address(const void* address
)
1799 if ( dyld::gLogAPIs
)
1800 dyld::log("%s(%p)\n", __func__
, address
);
1802 ImageLoader
* image
= dyld::findImageContainingAddress(address
);
1803 if ( image
!= NULL
)
1804 return image
->getRealPath();
1810 bool dyld_shared_cache_some_image_overridden()
1812 #if DYLD_SHARED_CACHE_SUPPORT
1813 return dyld::gSharedCacheOverridden
;
1820 void dyld_dynamic_interpose(const struct mach_header
* mh
, const struct dyld_interpose_tuple array
[], size_t count
)
1824 if ( array
== NULL
)
1828 ImageLoader
* image
= dyld::findImageByMachHeader(mh
);
1829 if ( image
== NULL
)
1832 // make pass at bound references in this image and update them
1833 dyld::gLinkContext
.dynamicInterposeArray
= array
;
1834 dyld::gLinkContext
.dynamicInterposeCount
= count
;
1835 image
->dynamicInterpose(dyld::gLinkContext
);
1836 dyld::gLinkContext
.dynamicInterposeArray
= NULL
;
1837 dyld::gLinkContext
.dynamicInterposeCount
= 0;
1839 // leave interposing info so any future (lazy) binding will get it too
1840 image
->addDynamicInterposingTuples(array
, count
);
1842 sDynamicInterposing
= true;