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 
  74 #if DEPRECATED_APIS_SUPPORTED 
  75 static char sLastErrorFilePath
[1024]; 
  76 static NSLinkEditErrors sLastErrorFileCode
; 
  77 static int sLastErrorNo
; 
  80 // In 10.3.x and earlier all the NSObjectFileImage API's were implemeneted in libSystem.dylib 
  81 // Beginning in 10.4 the NSObjectFileImage API's are implemented in dyld and libSystem just forwards 
  82 // This conditional keeps support for old libSystem's which needed some help implementing the API's 
  83 #define OLD_LIBSYSTEM_SUPPORT (__i386__) 
  85 // The following functions have no prototype in any header.  They are special cases 
  86 // where _dyld_func_lookup() is used directly. 
  87 static void _dyld_make_delayed_module_initializer_calls(); 
  88 static void registerThreadHelpers(const dyld::LibSystemHelpers
*); 
  89 #if DEPRECATED_APIS_SUPPORTED 
  90 static void _dyld_install_handlers(void* undefined
, void* multiple
, void* linkEdit
); 
  91 #if OLD_LIBSYSTEM_SUPPORT 
  92 static NSModule 
_dyld_link_module(NSObjectFileImage object_addr
, size_t object_size
, const char* moduleName
, uint32_t options
); 
  94 static void _dyld_register_binding_handler(void * (*)(const char *, const char *, void *), ImageLoader::BindingOptions
); 
  95 static bool NSMakePrivateModulePublic(NSModule 
module); 
  96 static void _dyld_call_module_initializers_for_dylib(const struct mach_header
* mh_dylib_header
); 
  98 // The following functions are dyld API's, but since dyld links with a static copy of libc.a 
  99 // the public name cannot be used. 
 100 static void             client_dyld_lookup_and_bind(const char* symbolName
, void** address
, NSModule
* module); 
 101 static bool             client_NSIsSymbolNameDefined(const char* symbolName
); 
 102 #endif // DEPRECATED_APIS_SUPPORTED 
 104 static bool client_dyld_find_unwind_sections(void* addr
, dyld_unwind_sections
* info
); 
 107 static void unimplemented() 
 109         dyld::halt("unimplemented dyld function\n"); 
 114     void*               implementation
; 
 117 static struct dyld_func dyld_funcs
[] = { 
 118     {"__dyld_register_func_for_add_image",                              (void*)_dyld_register_func_for_add_image 
}, 
 119     {"__dyld_register_func_for_remove_image",                   (void*)_dyld_register_func_for_remove_image 
}, 
 120     {"__dyld_dladdr",                                                                   (void*)dladdr 
}, 
 121     {"__dyld_dlclose",                                                                  (void*)dlclose 
}, 
 122     {"__dyld_dlerror",                                                                  (void*)dlerror 
}, 
 123     {"__dyld_dlopen",                                                                   (void*)dlopen 
}, 
 124     {"__dyld_dlsym",                                                                    (void*)dlsym 
}, 
 125     {"__dyld_dlopen_preflight",                                                 (void*)dlopen_preflight 
}, 
 126         {"__dyld_image_count",                                                          (void*)_dyld_image_count 
}, 
 127     {"__dyld_get_image_header",                                                 (void*)_dyld_get_image_header 
}, 
 128     {"__dyld_get_image_vmaddr_slide",                                   (void*)_dyld_get_image_vmaddr_slide 
}, 
 129     {"__dyld_get_image_name",                                                   (void*)_dyld_get_image_name 
}, 
 130     {"__dyld_get_image_slide",                                                  (void*)_dyld_get_image_slide 
}, 
 131     {"__dyld__NSGetExecutablePath",                                             (void*)_NSGetExecutablePath 
}, 
 134         {"__dyld_dyld_register_image_state_change_handler",     (void*)dyld_register_image_state_change_handler 
}, 
 135         {"__dyld_register_thread_helpers",                                      (void*)registerThreadHelpers 
}, 
 136         {"__dyld_fork_child",                                                           (void*)_dyld_fork_child 
}, 
 137     {"__dyld_moninit",                                                                  (void*)_dyld_moninit 
}, 
 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 
}, 
 141         {"__dyld_find_unwind_sections",                                         (void*)client_dyld_find_unwind_sections 
}, 
 143 #if __i386__ || __x86_64__ || __arm__ 
 144         {"__dyld_fast_stub_entry",                                                      (void*)dyld::fastBindLazySymbol 
}, 
 146         {"__dyld_image_path_containing_address",                        (void*)dyld_image_path_containing_address 
}, 
 147 #if __IPHONE_OS_VERSION_MIN_REQUIRED     
 148         {"__dyld_shared_cache_some_image_overridden",           (void*)dyld_shared_cache_some_image_overridden 
}, 
 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 
 242 static std::vector
<NSObjectFileImage
> sObjectFileImages
; 
 247 // __NSObjectFileImage are deleted in NSDestroyObjectFileImage() 
 248 // The contained image is delete in one of two places: 
 249 //      NSUnLinkModule deletes the image if there is no __NSObjectFileImage with a reference to it 
 250 //      NSDestroyObjectFileImage deletes the image if image is not in list of valid images 
 255 static void setLastError(NSLinkEditErrors code
, int errnum
, const char* file
, const char* message
) 
 257         dyld::setErrorMessage(message
); 
 258         strncpy(sLastErrorFilePath
, file
, 1024); 
 259         sLastErrorFilePath
[1023] = '\0'; 
 260         sLastErrorFileCode 
= code
; 
 261         sLastErrorNo 
= errnum
; 
 264 #endif // DEPRECATED_APIS_SUPPORTED 
 267  *_dyld_NSGetExecutablePath is the dyld side of _NSGetExecutablePath which 
 268  * copies the path of the executable into the buffer and returns 0 if the path 
 269  * was successfully copied in the provided buffer. If the buffer is not large 
 270  * enough, -1 is returned and the expected buffer size is copied in *bufsize. 
 271  * Note that _NSGetExecutablePath will return "a path" to the executable not a 
 272  * "real path" to the executable. That is the path may be a symbolic link and 
 273  * not the real file. And with deep directories the total bufsize needed could 
 274  * be more than MAXPATHLEN. 
 276 int _NSGetExecutablePath(char* buf
, uint32_t *bufsize
) 
 278         if ( dyld::gLogAPIs 
) 
 279                 dyld::log("%s(...)\n", __func__
); 
 280         const char* exePath 
= dyld::getExecutablePath(); 
 281         if(*bufsize 
< strlen(exePath
) + 1){ 
 282             *bufsize 
= strlen(exePath
) + 1; 
 285         strcpy(buf
, exePath
); 
 289 uint32_t _dyld_image_count(void) 
 291         if ( dyld::gLogAPIs 
) 
 292                 dyld::log("%s()\n", __func__
); 
 293         return dyld::getImageCount(); 
 296 const struct mach_header
* _dyld_get_image_header(uint32_t image_index
) 
 298         if ( dyld::gLogAPIs 
) 
 299                 dyld::log("%s(%u)\n", __func__
, image_index
); 
 300         ImageLoader
* image 
= dyld::getIndexedImage(image_index
); 
 302                 return (struct mach_header
*)image
->machHeader(); 
 307 intptr_t _dyld_get_image_vmaddr_slide(uint32_t image_index
) 
 309         if ( dyld::gLogAPIs 
) 
 310                 dyld::log("%s(%u)\n", __func__
, image_index
); 
 311         ImageLoader
* image 
= dyld::getIndexedImage(image_index
); 
 313                 return image
->getSlide(); 
 318 intptr_t _dyld_get_image_slide(const struct mach_header
* mh
) 
 320         if ( dyld::gLogAPIs 
) 
 321                 dyld::log("%s(%p)\n", __func__
, mh
); 
 322         ImageLoader
* image 
= dyld::findImageByMachHeader(mh
); 
 324                 return image
->getSlide(); 
 330 const char* _dyld_get_image_name(uint32_t image_index
) 
 332         if ( dyld::gLogAPIs 
) 
 333                 dyld::log("%s(%u)\n", __func__
, image_index
); 
 334         ImageLoader
* image 
= dyld::getIndexedImage(image_index
); 
 336                 return image
->getRealPath(); 
 341 const struct mach_header 
* _dyld_get_image_header_containing_address(const void* address
) 
 343         if ( dyld::gLogAPIs 
) 
 344                 dyld::log("%s(%p)\n", __func__
, address
); 
 345         ImageLoader
* image 
= dyld::findImageContainingAddress(address
); 
 347                 return image
->machHeader(); 
 352 void _dyld_register_func_for_add_image(void (*func
)(const struct mach_header 
*mh
, intptr_t vmaddr_slide
)) 
 354         if ( dyld::gLogAPIs 
) 
 355                 dyld::log("%s(%p)\n", __func__
, (void *)func
); 
 356         dyld::registerAddCallback(func
); 
 359 void _dyld_register_func_for_remove_image(void (*func
)(const struct mach_header 
*mh
, intptr_t vmaddr_slide
)) 
 361         if ( dyld::gLogAPIs 
) 
 362                 dyld::log("%s(%p)\n", __func__
, (void *)func
); 
 363         dyld::registerRemoveCallback(func
); 
 368 // called by crt before main() by programs linked with 10.4 or earlier crt1.o 
 369 static void _dyld_make_delayed_module_initializer_calls() 
 371         if ( dyld::gLogAPIs 
) 
 372                 dyld::log("%s()\n", __func__
); 
 374 #if SUPPORT_OLD_CRT_INITIALIZATION 
 375         if ( dyld::gRunInitializersOldWay 
) 
 376                 dyld::initializeMainExecutable(); 
 382 #if DEPRECATED_APIS_SUPPORTED 
 385 // _dyld_call_module_initializers_for_dylib() is the dyld side of 
 386 // __initialize_Cplusplus() which is in dylib1.o. 
 387 // It is intended to only be called inside -init rouintes. 
 388 // -init routines are called before module initializers (what C++ 
 389 // initializers use).  Calling __initialize_Cplusplus() in a -init 
 390 // routine causes the module initializers for an image to be called 
 391 // which then allows C++ to be used inside a -init routine 
 393 static void _dyld_call_module_initializers_for_dylib(const struct mach_header
* mh_dylib_header
) 
 395         if ( dyld::gLogAPIs 
) 
 396                 dyld::log("__initialize_Cplusplus()\n"); 
 398         // for now, do nothing... 
 402 void _dyld_lookup_and_bind_fully(const char* symbolName
, void** address
, NSModule
* module) 
 404         if ( dyld::gLogAPIs 
) 
 405                 dyld::log("%s(\"%s\", %p, %p)\n", __func__
, symbolName
, address
, module); 
 407         const ImageLoader::Symbol
* sym
; 
 408         dyld::clearErrorMessage(); 
 409         if ( dyld::flatFindExportedSymbol(symbolName
, &sym
, (const ImageLoader
**)&image
) ) {     
 411                         image
->bindAllLazyPointers(dyld::gLinkContext
, true); 
 412                         if ( address 
!= NULL
) 
 413                                 *address 
= (void*)image
->getExportedSymbolAddress(sym
, dyld::gLinkContext
); 
 415                                 *module = ImageLoaderToNSModule(image
); 
 417                 catch (const char* msg
) { 
 418                         dyldAPIhalt(__func__
, msg
); 
 422                 // on failure to find symbol return NULLs 
 423                 if ( address 
!= NULL
) 
 430 // Note: This cannot have public name because dyld is built with a static copy of libc.a 
 431 // which calls dyld_lookup_and_bind() and expects to find dyld's symbols not host process 
 432 static void client_dyld_lookup_and_bind(const char* symbolName
, void** address
, NSModule
* module) 
 434         if ( dyld::gLogAPIs 
) 
 435                 dyld::log("_dyld_lookup_and_bind(\"%s\", %p, %p)\n", symbolName
, address
, module); 
 436         const ImageLoader
* image
; 
 437         const ImageLoader::Symbol
* sym
; 
 438         if ( dyld::flatFindExportedSymbol(symbolName
, &sym
, &image
) ) { 
 439                 if ( address 
!= NULL
) 
 440                         *address 
= (void*)image
->getExportedSymbolAddress(sym
, dyld::gLinkContext
); 
 442                         *module = ImageLoaderToNSModule(image
); 
 445                 // on failure to find symbol return NULLs 
 446                 if ( address 
!= NULL
) 
 453 void _dyld_lookup_and_bind_with_hint(const char* symbolName
, const char* library_name_hint
, void** address
, NSModule
* module) 
 455         if ( dyld::gLogAPIs 
) 
 456                 dyld::log("%s(\"%s\", \"%s\", %p, %p)\n", __func__
, symbolName
, library_name_hint
, address
, module); 
 457         const ImageLoader
* image
; 
 458         const ImageLoader::Symbol
* sym
; 
 459         // Look for library whose path contains the hint.  If that fails search everywhere 
 460         if (  dyld::flatFindExportedSymbolWithHint(symbolName
, library_name_hint
, &sym
, &image
)  
 461           ||  dyld::flatFindExportedSymbol(symbolName
, &sym
, &image
) ) { 
 462                 if ( address 
!= NULL
) 
 463                         *address 
= (void*)image
->getExportedSymbolAddress(sym
, dyld::gLinkContext
); 
 465                         *module = ImageLoaderToNSModule(image
); 
 468                 // on failure to find symbol return NULLs 
 469                 if ( address 
!= NULL
) 
 477 NSSymbol 
NSLookupAndBindSymbol(const char *symbolName
) 
 479         if ( dyld::gLogAPIs 
) 
 480                 dyld::log("%s(\"%s\")\n", __func__
, symbolName
); 
 481         const ImageLoader
* image
; 
 482         const ImageLoader::Symbol
* sym
; 
 483         if ( dyld::flatFindExportedSymbol(symbolName
, &sym
, &image
) ) { 
 484                 return SymbolToNSSymbol(sym
); 
 486         // return NULL on failure 
 490 NSSymbol 
NSLookupAndBindSymbolWithHint(const char* symbolName
, const char* libraryNameHint
) 
 492         if ( dyld::gLogAPIs 
) 
 493                 dyld::log("%s(\"%s\", \"%s\")\n", __func__
, symbolName
, libraryNameHint
); 
 494         const ImageLoader
* image
; 
 495         const ImageLoader::Symbol
* sym
; 
 496         bool found 
= dyld::flatFindExportedSymbolWithHint(symbolName
, libraryNameHint
, &sym
, &image
); 
 498                 // hint failed, do slow search of all images 
 499                  found 
= dyld::flatFindExportedSymbol(symbolName
, &sym
, &image
); 
 502                 return SymbolToNSSymbol(sym
); 
 504         // return NULL on failure and log 
 505         if ( dyld::gLogAPIs 
) 
 506                 dyld::log("%s(\"%s\", \"%s\") => NULL \n", __func__
, symbolName
, libraryNameHint
); 
 513 static __attribute__((noinline
))  
 514 const struct mach_header
* addImage(void* callerAddress
, const char* path
, bool search
, bool dontLoad
, bool matchInstallName
, bool abortOnError
) 
 516         ImageLoader
*    image 
= NULL
; 
 517         std::vector
<const char*> rpathsFromCallerImage
; 
 519                 dyld::clearErrorMessage(); 
 520                 ImageLoader
* callerImage 
= dyld::findImageContainingAddress(callerAddress
); 
 521                 // like dlopen, use rpath from caller image and from main executable 
 522                 if ( callerImage 
!= NULL 
) 
 523                         callerImage
->getRPaths(dyld::gLinkContext
, rpathsFromCallerImage
); 
 524                 ImageLoader::RPathChain 
callersRPaths(NULL
, &rpathsFromCallerImage
); 
 525                 if ( callerImage 
!= dyld::mainExecutable() ) { 
 526                         dyld::mainExecutable()->getRPaths(dyld::gLinkContext
, rpathsFromCallerImage
); 
 528                 dyld::LoadContext context
; 
 529                 context
.useSearchPaths          
= search
; 
 530                 context
.useFallbackPaths        
= search
; 
 531                 context
.useLdLibraryPath        
= false; 
 532                 context
.implicitRPath           
= false; 
 533                 context
.matchByInstallName      
= matchInstallName
; 
 534                 context
.dontLoad                        
= dontLoad
; 
 535                 context
.mustBeBundle            
= false; 
 536                 context
.mustBeDylib                     
= true; 
 537                 context
.canBePIE                        
= false; 
 538                 context
.origin                          
= callerImage 
!= NULL 
? callerImage
->getPath() : NULL
; // caller's image's path 
 539                 context
.rpath                           
= &callersRPaths
;       // rpaths from caller and main executable 
 541                 image 
= load(path
, context
); 
 542                 if ( image 
!= NULL 
) { 
 543                         if ( context
.matchByInstallName 
) 
 544                                 image
->setMatchInstallPath(true); 
 545                         dyld::link(image
, false, callersRPaths
); 
 546                         dyld::runInitializers(image
); 
 547                         // images added with NSAddImage() can never be unloaded 
 548                         image
->setNeverUnload();  
 551         catch (const char* msg
) { 
 552                 dyld::garbageCollectImages(); 
 554                         char pathMsg
[strlen(msg
)+strlen(path
)+4]; 
 555                         strcpy(pathMsg
, msg
); 
 556                         strcat(pathMsg
, " "); 
 557                         strcat(pathMsg
, path
); 
 558                         dyldAPIhalt("NSAddImage", pathMsg
); 
 560                 // not halting, so set error state for NSLinkEditError to find 
 561                 setLastError(NSLinkEditOtherError
, 0, path
, msg
); 
 562                 free((void*)msg
);       // our free() will do nothing if msg is a string literal 
 565         // free rpaths (getRPaths() malloc'ed each string) 
 566         for(std::vector
<const char*>::iterator it
=rpathsFromCallerImage
.begin(); it 
!= rpathsFromCallerImage
.end(); ++it
) { 
 567                 const char* str 
= *it
; 
 573                 return image
->machHeader(); 
 577 const struct mach_header
* NSAddImage(const char* path
, uint32_t options
) 
 579         if ( dyld::gLogAPIs 
) 
 580                 dyld::log("%s(\"%s\", 0x%08X)\n", __func__
, path
, options
); 
 581         const bool dontLoad 
= ( (options 
& NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED
) != 0 ); 
 582         const bool search 
= ( (options 
& NSADDIMAGE_OPTION_WITH_SEARCHING
) != 0 ); 
 583         const bool matchInstallName 
= ( (options 
& NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME
) != 0 ); 
 584         const bool abortOnError 
= ( (options 
& (NSADDIMAGE_OPTION_RETURN_ON_ERROR
|NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED
)) == 0 ); 
 585         void* callerAddress 
= __builtin_return_address(1); // note layers: 1: real client, 0: libSystem glue 
 586         return addImage(callerAddress
, path
, search
, dontLoad
, matchInstallName
, abortOnError
); 
 589 bool NSAddLibrary(const char* path
) 
 591         if ( dyld::gLogAPIs 
) 
 592                 dyld::log("%s(\"%s\")\n", __func__
, path
); 
 593         void* callerAddress 
= __builtin_return_address(1); // note layers: 1: real client, 0: libSystem glue 
 594         return (addImage(callerAddress
, path
, false, false, false, false) != NULL
); 
 597 bool NSAddLibraryWithSearching(const char* path
) 
 599         if ( dyld::gLogAPIs 
) 
 600                 dyld::log("%s(\"%s\")\n", __func__
, path
); 
 601         void* callerAddress 
= __builtin_return_address(1); // note layers: 1: real client, 0: libSystem glue 
 602         return (addImage(callerAddress
, path
, true, false, false, false) != NULL
); 
 607 //#define NSADDIMAGE_OPTION_NONE                        0x0 
 608 //#define NSADDIMAGE_OPTION_RETURN_ON_ERROR             0x1 
 609 //#define NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME       0x8 
 611 bool NSIsSymbolNameDefinedInImage(const struct mach_header
* mh
, const char* symbolName
) 
 613         if ( dyld::gLogAPIs 
) 
 614                 dyld::log("%s(%p, \"%s\")\n", __func__
, (void *)mh
, symbolName
); 
 615         ImageLoader
* image 
= dyld::findImageByMachHeader(mh
); 
 616         if ( image 
!= NULL 
) { 
 617                 if ( image
->findExportedSymbol(symbolName
, true, NULL
) != NULL
) 
 624 NSSymbol 
NSLookupSymbolInImage(const struct mach_header
* mh
, const char* symbolName
, uint32_t options
) 
 626         if ( dyld::gLogAPIs 
) 
 627                 dyld::log("%s(%p, \"%s\", 0x%08X)\n", __func__
, mh
, symbolName
, options
); 
 628         const ImageLoader::Symbol
* symbol 
= NULL
; 
 629         dyld::clearErrorMessage(); 
 630         ImageLoader
* image 
= dyld::findImageByMachHeader(mh
); 
 631         if ( image 
!= NULL 
) { 
 633                         if ( options 
& NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY 
) { 
 634                                 image
->bindAllLazyPointers(dyld::gLinkContext
, true); 
 636                         else if ( options 
& NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW 
) { 
 637                                 image
->bindAllLazyPointers(dyld::gLinkContext
, false); 
 640                 catch (const char* msg
) { 
 641                         if ( (options 
& NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
) == 0 ) { 
 642                                 dyldAPIhalt(__func__
, msg
); 
 645                 symbol 
= image
->findExportedSymbol(symbolName
, true, NULL
); 
 647         if ( dyld::gLogAPIs 
&& (symbol 
== NULL
) ) 
 648                 dyld::log("%s(%p, \"%s\", 0x%08X) ==> NULL\n", __func__
, mh
, symbolName
, options
); 
 649         return SymbolToNSSymbol(symbol
); 
 653 // Note: This cannot have public name because dyld is built with a static copy of libc.a 
 654 // which calls NSIsSymbolNameDefined() and expects to find dyld's symbols not host process 
 655 static bool client_NSIsSymbolNameDefined(const char* symbolName
) 
 657         if ( dyld::gLogAPIs 
) 
 658                 dyld::log("NSIsSymbolNameDefined(\"%s\")\n", symbolName
); 
 659         const ImageLoader
* image
; 
 660         const ImageLoader::Symbol
* sym
; 
 661         return dyld::flatFindExportedSymbol(symbolName
, &sym
, &image
); 
 664 bool NSIsSymbolNameDefinedWithHint(const char* symbolName
, const char* libraryNameHint
) 
 666         if ( dyld::gLogAPIs 
) 
 667                 dyld::log("%s(\"%s\", \"%s\")\n", __func__
, symbolName
, libraryNameHint
); 
 668         const ImageLoader
* image
; 
 669         const ImageLoader::Symbol
* sym
; 
 670         bool found 
= dyld::flatFindExportedSymbolWithHint(symbolName
, libraryNameHint
, &sym
, &image
); 
 672                 // hint failed, do slow search of all images 
 673                  found 
= dyld::flatFindExportedSymbol(symbolName
, &sym
, &image
); 
 675         if ( !found 
&& dyld::gLogAPIs 
) 
 676                 dyld::log("%s(\"%s\", \"%s\") => false \n", __func__
, symbolName
, libraryNameHint
); 
 680 const char* NSNameOfSymbol(NSSymbol symbol
) 
 682         if ( dyld::gLogAPIs 
) 
 683                 dyld::log("%s(%p)\n", __func__
, (void *)symbol
); 
 684         const char* result 
= NULL
; 
 685         ImageLoader
* image 
= dyld::findImageContainingSymbol(symbol
); 
 687                 result 
= image
->getExportedSymbolName(NSSymbolToSymbol(symbol
)); 
 691 void* NSAddressOfSymbol(NSSymbol symbol
) 
 693         if ( dyld::gLogAPIs 
) 
 694                 dyld::log("%s(%p)\n", __func__
, (void *)symbol
); 
 695         if ( symbol 
== NULL 
) 
 698         ImageLoader
* image 
= dyld::findImageContainingSymbol(symbol
); 
 700                 result 
= (void*)image
->getExportedSymbolAddress(NSSymbolToSymbol(symbol
), dyld::gLinkContext
); 
 704 NSModule 
NSModuleForSymbol(NSSymbol symbol
) 
 706         if ( dyld::gLogAPIs 
) 
 707                 dyld::log("%s(%p)\n", __func__
, (void *)symbol
); 
 708         NSModule result 
= NULL
; 
 709         ImageLoader
* image 
= dyld::findImageContainingSymbol(symbol
); 
 711                 result 
= ImageLoaderToNSModule(image
); 
 718 bool _dyld_all_twolevel_modules_prebound(void) 
 720         if ( dyld::gLogAPIs 
) 
 721                 dyld::log("%s()\n", __func__
); 
 725 void _dyld_bind_objc_module(const void *objc_module
) 
 727         if ( dyld::gLogAPIs 
) 
 728                 dyld::log("%s(%p)\n", __func__
, objc_module
); 
 729         // do nothing, with new dyld everything already bound 
 733 bool _dyld_bind_fully_image_containing_address(const void* address
) 
 735         if ( dyld::gLogAPIs 
) 
 736                 dyld::log("%s(%p)\n", __func__
, address
); 
 737         dyld::clearErrorMessage(); 
 738         ImageLoader
* image 
= dyld::findImageContainingAddress(address
); 
 739         if ( image 
!= NULL 
) { 
 741                         image
->bindAllLazyPointers(dyld::gLinkContext
, true); 
 744                 catch (const char* msg
) { 
 745                         dyldAPIhalt(__func__
, msg
); 
 751 bool _dyld_image_containing_address(const void* address
) 
 753         if ( dyld::gLogAPIs 
) 
 754                 dyld::log("%s(%p)\n", __func__
, address
); 
 755         ImageLoader 
*imageLoader 
= dyld::findImageContainingAddress(address
); 
 756         return (NULL 
!= imageLoader
); 
 759 static NSObjectFileImage 
createObjectImageFile(ImageLoader
* image
, const void* address 
= NULL
, size_t len
=0) 
 761         NSObjectFileImage result 
= new __NSObjectFileImage(); 
 762         result
->image 
= image
; 
 763         result
->imageBaseAddress 
= address
; 
 764         result
->imageLength 
= len
; 
 765         sObjectFileImages
.push_back(result
); 
 769 NSObjectFileImageReturnCode 
NSCreateObjectFileImageFromFile(const char* pathName
, NSObjectFileImage 
*objectFileImage
) 
 771         if ( dyld::gLogAPIs 
) 
 772                 dyld::log("%s(\"%s\", ...)\n", __func__
, pathName
); 
 774                 void* callerAddress 
= __builtin_return_address(1); // note layers: 1: real client, 0: libSystem glue 
 775                 ImageLoader
* callerImage 
= dyld::findImageContainingAddress(callerAddress
); 
 777                 dyld::LoadContext context
; 
 778                 context
.useSearchPaths          
= false; 
 779                 context
.useFallbackPaths        
= false; 
 780                 context
.useLdLibraryPath        
= false; 
 781                 context
.implicitRPath           
= false; 
 782                 context
.matchByInstallName      
= false; 
 783                 context
.dontLoad                        
= false; 
 784                 context
.mustBeBundle            
= true; 
 785                 context
.mustBeDylib                     
= false; 
 786                 context
.canBePIE                        
= false; 
 787                 context
.origin                          
= callerImage 
!= NULL 
? callerImage
->getPath() : NULL
; // caller's image's path 
 788                 context
.rpath                           
= NULL
; // support not yet implemented 
 790                 ImageLoader
* image 
= dyld::load(pathName
, context
); 
 791                 // Note:  We DO NOT link the image!  NSLinkModule will do that 
 792                 if ( image 
!= NULL 
) { 
 793                         if ( !image
->isBundle() ) { 
 794                                 // the image must have been already loaded (since context.mustBeBundle will prevent it from being loaded) 
 795                                 return NSObjectFileImageInappropriateFile
; 
 797                         *objectFileImage 
= createObjectImageFile(image
); 
 798                         return NSObjectFileImageSuccess
; 
 801         catch (const char* msg
) { 
 802                 //dyld::log("dyld: NSCreateObjectFileImageFromFile() error: %s\n", msg); 
 803                 dyld::garbageCollectImages(); 
 805                 return NSObjectFileImageInappropriateFile
; 
 807         return NSObjectFileImageFailure
; 
 811 NSObjectFileImageReturnCode 
NSCreateObjectFileImageFromMemory(const void* address
, size_t size
, NSObjectFileImage 
*objectFileImage
) 
 813         if ( dyld::gLogAPIs 
) 
 814                 dyld::log("%s(%p, %lu, %p)\n", __func__
, address
, size
, objectFileImage
); 
 817                 ImageLoader
* image 
= dyld::loadFromMemory((const uint8_t*)address
, size
, NULL
);  
 818                 if ( ! image
->isBundle() ) { 
 819                         // this API can only be used with bundles... 
 820                         dyld::garbageCollectImages(); 
 821                         return NSObjectFileImageInappropriateFile
; 
 823                 // Note:  We DO NOT link the image!  NSLinkModule will do that 
 824                 if ( image 
!= NULL 
) { 
 825                         *objectFileImage 
= createObjectImageFile(image
, address
, size
); 
 826                         return NSObjectFileImageSuccess
; 
 829         catch (const char* msg
) { 
 831                 dyld::garbageCollectImages(); 
 832                 //dyld::log("dyld: NSCreateObjectFileImageFromMemory() error: %s\n", msg); 
 834         return NSObjectFileImageFailure
; 
 837 static bool validOFI(NSObjectFileImage objectFileImage
) 
 839         const int ofiCount 
= sObjectFileImages
.size(); 
 840         for (int i
=0; i 
< ofiCount
; ++i
) { 
 841                 if ( sObjectFileImages
[i
] == objectFileImage 
) 
 847 bool NSDestroyObjectFileImage(NSObjectFileImage objectFileImage
) 
 849         if ( dyld::gLogAPIs 
) 
 850                 dyld::log("%s(%p)\n", __func__
, objectFileImage
); 
 852         if ( validOFI(objectFileImage
) ) { 
 853                 // a failure during NSLinkModule will delete the image 
 854                 if ( objectFileImage
->image 
!= NULL 
) { 
 855                         // if the image has never been linked or has been unlinked, the image is not in the list of valid images 
 856                         // and we should delete it 
 857                         bool linkedImage 
= dyld::validImage(objectFileImage
->image
); 
 858                         if ( ! linkedImage 
)  { 
 859                                 ImageLoader::deleteImage(objectFileImage
->image
); 
 860                                 objectFileImage
->image 
= NULL
; 
 864                 // remove from list of ofi's 
 865                 for (std::vector
<NSObjectFileImage
>::iterator it
=sObjectFileImages
.begin(); it 
!= sObjectFileImages
.end(); it
++) { 
 866                         if ( *it 
== objectFileImage 
) { 
 867                                 sObjectFileImages
.erase(it
); 
 872                 // if object was created from a memory, release that memory 
 873                 // NOTE: this is the way dyld has always done this. NSCreateObjectFileImageFromMemory() hands over ownership of the memory to dyld 
 874                 if ( objectFileImage
->imageBaseAddress 
!= NULL 
) { 
 876                         if ( (dyld::gLibSystemHelpers 
!= NULL
) && (dyld::gLibSystemHelpers
->version 
>= 6) ) { 
 877                                 size_t sz 
= (*dyld::gLibSystemHelpers
->malloc_size
)(objectFileImage
->imageBaseAddress
); 
 879                                         (*dyld::gLibSystemHelpers
->free
)((void*)(objectFileImage
->imageBaseAddress
)); 
 884                                 vm_deallocate(mach_task_self(), (vm_address_t
)objectFileImage
->imageBaseAddress
, objectFileImage
->imageLength
); 
 888                 delete objectFileImage
; 
 895 bool NSHasModInitObjectFileImage(NSObjectFileImage objectFileImage
) 
 897         if ( dyld::gLogAPIs 
) 
 898                 dyld::log("%s(%p)\n", __func__
, objectFileImage
); 
 899         return objectFileImage
->image
->needsInitialization(); 
 902 uint32_t NSSymbolDefinitionCountInObjectFileImage(NSObjectFileImage objectFileImage
) 
 904         if ( dyld::gLogAPIs 
) 
 905                 dyld::log("%s(%p)\n", __func__
, objectFileImage
); 
 906         return objectFileImage
->image
->getExportedSymbolCount(); 
 909 const char* NSSymbolDefinitionNameInObjectFileImage(NSObjectFileImage objectFileImage
, uint32_t ordinal
) 
 911         if ( dyld::gLogAPIs 
) 
 912                 dyld::log("%s(%p,%d)\n", __func__
, objectFileImage
, ordinal
); 
 913         const ImageLoader::Symbol
* sym 
= objectFileImage
->image
->getIndexedExportedSymbol(ordinal
); 
 914         return objectFileImage
->image
->getExportedSymbolName(sym
);       
 917 uint32_t NSSymbolReferenceCountInObjectFileImage(NSObjectFileImage objectFileImage
) 
 919         if ( dyld::gLogAPIs 
) 
 920                 dyld::log("%s(%p)\n", __func__
, objectFileImage
); 
 921         return objectFileImage
->image
->getImportedSymbolCount(); 
 924 const char * NSSymbolReferenceNameInObjectFileImage(NSObjectFileImage objectFileImage
, uint32_t ordinal
,  
 925                                                                                                         bool* tentative_definition
) 
 927         if ( dyld::gLogAPIs 
) 
 928                 dyld::log("%s(%p,%d)\n", __func__
, objectFileImage
, ordinal
); 
 929         const ImageLoader::Symbol
* sym 
= objectFileImage
->image
->getIndexedImportedSymbol(ordinal
); 
 930         if ( tentative_definition 
!= NULL 
) { 
 931                 ImageLoader::ReferenceFlags flags 
= objectFileImage
->image
->getImportedSymbolInfo(sym
); 
 932                 if ( (flags 
& ImageLoader::kTentativeDefinition
) != 0 ) 
 933                         *tentative_definition 
= true; 
 935                         *tentative_definition 
= false; 
 937         return objectFileImage
->image
->getImportedSymbolName(sym
);       
 940 void* NSGetSectionDataInObjectFileImage(NSObjectFileImage objectFileImage
, 
 941                                                                                 const char* segmentName
, const char* sectionName
, unsigned long* size
) 
 943         if ( dyld::gLogAPIs 
) 
 944                 dyld::log("%s(%p,%s, %s)\n", __func__
, objectFileImage
, segmentName
, sectionName
); 
 948         if ( objectFileImage
->image
->getSectionContent(segmentName
, sectionName
, &start
, &length
) ) { 
 958 bool NSIsSymbolDefinedInObjectFileImage(NSObjectFileImage objectFileImage
, const char* symbolName
) 
 960         if ( dyld::gLogAPIs 
) 
 961                 dyld::log("%s(%p,%s)\n", __func__
, objectFileImage
, symbolName
); 
 962         const ImageLoader::Symbol
* sym 
= objectFileImage
->image
->findExportedSymbol(symbolName
, true, NULL
); 
 963         return ( sym 
!= NULL 
); 
 968 NSModule 
NSLinkModule(NSObjectFileImage objectFileImage
, const char* moduleName
, uint32_t options
) 
 970         if ( dyld::gLogAPIs 
) 
 971                 dyld::log("%s(%p, \"%s\", 0x%08X)\n", __func__
, objectFileImage
, moduleName
, options
);  
 973         dyld::clearErrorMessage(); 
 975                 // NSLinkModule allows a bundle to be link multpile times 
 976                 // each link causes the bundle to be copied to a new address 
 977                 if ( objectFileImage
->image
->isLinked() ) { 
 978                         // already linked, so clone a new one and link it 
 979                         objectFileImage
->image 
= dyld::cloneImage(objectFileImage
->image
); 
 982                 // for memory based images, set moduleName as the name anyone calling _dyld_get_image_name() will see 
 983                 if ( objectFileImage
->image
->getPath() == NULL 
) { 
 984                         objectFileImage
->image
->setPath(moduleName
); 
 985                         // <rdar://problem/8812589> dyld has NULL paths in image info array 
 986                         dyld_image_info info
; 
 987                         info
.imageLoadAddress 
= objectFileImage
->image
->machHeader(); 
 988                         info
.imageFilePath 
= moduleName
; 
 989                         info
.imageFileModDate 
= 0; 
 990                         addImagesToAllImages(1, &info
); 
 993                 // support private bundles 
 994                 if ( (options 
& NSLINKMODULE_OPTION_PRIVATE
) != 0 ) 
 995                         objectFileImage
->image
->setHideExports(); 
 997                 // set up linking options 
 998                 bool forceLazysBound 
= ( (options 
& NSLINKMODULE_OPTION_BINDNOW
) != 0 ); 
1000                 // load libraries, rebase, bind, to make this image usable 
1001                 dyld::link(objectFileImage
->image
, forceLazysBound
, ImageLoader::RPathChain(NULL
,NULL
)); 
1003                 // bump reference count to keep this bundle from being garbage collected 
1004                 objectFileImage
->image
->incrementDlopenReferenceCount(); 
1006                 // run initializers unless magic flag says not to 
1007                 if ( (options 
& NSLINKMODULE_OPTION_DONT_CALL_MOD_INIT_ROUTINES
) == 0 ) 
1008                         dyld::runInitializers(objectFileImage
->image
); 
1010                 return ImageLoaderToNSModule(objectFileImage
->image
); 
1012         catch (const char* msg
) { 
1013                 dyld::garbageCollectImages(); 
1014                 if ( (options 
& NSLINKMODULE_OPTION_RETURN_ON_ERROR
) == 0 ) 
1015                         dyldAPIhalt(__func__
, msg
); 
1016                 // not halting, so set error state for NSLinkEditError to find 
1017                 setLastError(NSLinkEditOtherError
, 0, moduleName
, msg
); 
1018                 // dyld::link() deleted the image so lose our reference 
1019                 objectFileImage
->image 
= NULL
; 
1026 #if OLD_LIBSYSTEM_SUPPORT 
1027 // This is for compatibility with old libSystems (libdyld.a) which process ObjectFileImages outside dyld 
1028 static NSModule 
_dyld_link_module(NSObjectFileImage object_addr
, size_t object_size
, const char* moduleName
, uint32_t options
) 
1030         if ( dyld::gLogAPIs 
) 
1031                 dyld::log("%s(%p, \"%s\", 0x%08X)\n", "NSLinkModule", object_addr
,  moduleName
, options
); // note name/args translation 
1032         ImageLoader
* image 
= NULL
; 
1033         dyld::clearErrorMessage(); 
1035                 const char* imageName 
= moduleName
;                      
1036                 image 
= dyld::loadFromMemory((const uint8_t*)object_addr
, object_size
, imageName
);  
1038                 if ( image 
!= NULL 
) {           
1039                         // support private bundles 
1040                         if ( (options 
& NSLINKMODULE_OPTION_PRIVATE
) != 0 ) 
1041                                 image
->setHideExports(); 
1043                         // set up linking options 
1044                         bool forceLazysBound 
= ( (options 
& NSLINKMODULE_OPTION_BINDNOW
) != 0 ); 
1046                         // load libraries, rebase, bind, to make this image usable 
1047                         dyld::link(image
, forceLazysBound
, ImageLoader::RPathChain(NULL
,NULL
)); 
1049                         // run initializers unless magic flag says not to 
1050                         if ( (options 
& NSLINKMODULE_OPTION_DONT_CALL_MOD_INIT_ROUTINES
) == 0 ) 
1051                                 dyld::runInitializers(image
); 
1054         catch (const char* msg
) { 
1055                 if ( (options 
& NSLINKMODULE_OPTION_RETURN_ON_ERROR
) == 0 ) 
1056                         dyldAPIhalt("NSLinkModule", msg
); 
1057                 // not halting, so set error state for NSLinkEditError to find 
1058                 setLastError(NSLinkEditOtherError
, 0, moduleName
, msg
); 
1059                 // if image was created for this bundle, destroy it 
1060                 if ( image 
!= NULL 
) { 
1061                         dyld::removeImage(image
); 
1062                         ImageLoader::deleteImage(image
); 
1067         return ImageLoaderToNSModule(image
); 
1071 NSSymbol 
NSLookupSymbolInModule(NSModule 
module, const char* symbolName
) 
1073         if ( dyld::gLogAPIs 
) 
1074                 dyld::log("%s(%p, \"%s\")\n", __func__
, (void *)module, symbolName
); 
1075         ImageLoader
* image 
= NSModuleToImageLoader(module); 
1076         if ( image 
== NULL 
)  
1078         return SymbolToNSSymbol(image
->findExportedSymbol(symbolName
, false, NULL
)); 
1081 const char* NSNameOfModule(NSModule 
module) 
1083         if ( dyld::gLogAPIs 
) 
1084                 dyld::log("%s(%p)\n", __func__
, module); 
1085         ImageLoader
* image 
= NSModuleToImageLoader(module); 
1086         if ( image 
== NULL 
)  
1088         return image
->getPath(); 
1091 const char* NSLibraryNameForModule(NSModule 
module) 
1093         if ( dyld::gLogAPIs 
) 
1094                 dyld::log("%s(%p)\n", __func__
, module); 
1095         ImageLoader
* image 
= NSModuleToImageLoader(module); 
1096         if ( image 
== NULL 
)  
1098         return image
->getPath(); 
1101 bool NSUnLinkModule(NSModule 
module, uint32_t options
) 
1103         if ( dyld::gLogAPIs 
) 
1104                 dyld::log("%s(%p, 0x%08X)\n", __func__
, module, options
);  
1105         if ( module == NULL 
) 
1107         ImageLoader
* image 
= NSModuleToImageLoader(module); 
1108         if ( image 
== NULL 
)  
1110         dyld::removeImage(image
); 
1112         if ( (options 
& NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED
) != 0 ) 
1113                 image
->setLeaveMapped(); 
1115         // TODO: NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES 
1117         // Only delete image if there is no ofi referencing it 
1118         // That means the ofi was destroyed after linking, so no one is left to delete this image        
1119         const int ofiCount 
= sObjectFileImages
.size(); 
1121         for (int i
=0; i 
< ofiCount
; ++i
) { 
1122                 NSObjectFileImage ofi 
= sObjectFileImages
[i
]; 
1123                 if ( ofi
->image 
== image 
) 
1127                 ImageLoader::deleteImage(image
); 
1132 // internal name and parameters do not match public name and parameters... 
1133 static void _dyld_install_handlers(void* undefined
, void* multiple
, void* linkEdit
) 
1135         if ( dyld::gLogAPIs 
) 
1136                 dyld::log("NSLinkEditErrorHandlers()\n"); 
1138         dyld::registerUndefinedHandler((dyld::UndefinedHandler
)undefined
); 
1139         // no support for multiple or linkedit handlers 
1145 void NSLinkEditError(NSLinkEditErrors
* c
, int* errorNumber
, const char** fileName
, const char** errorString
) 
1148         *c 
= sLastErrorFileCode
; 
1149         *errorNumber 
= sLastErrorNo
; 
1150         *fileName 
= sLastErrorFilePath
; 
1151         *errorString 
= dyld::getErrorMessage(); 
1156 static void _dyld_register_binding_handler(void * (*bindingHandler
)(const char *, const char *, void *), ImageLoader::BindingOptions bindingOptions
) 
1158         if ( dyld::gLogAPIs 
) 
1159                 dyld::log("%s()\n", __func__
); 
1160         dyld::gLinkContext
.bindingHandler 
= bindingHandler
; 
1161         dyld::gLinkContext
.bindingOptions 
= bindingOptions
; 
1164 #endif //DEPRECATED_APIS_SUPPORTED 
1167 // Call by fork() in libSystem after the kernel trap is done on the child side 
1168 void _dyld_fork_child() 
1170         if ( dyld::gLogAPIs 
) 
1171                 dyld::log("%s()\n", __func__
); 
1172         // The implementation of fork() in libSystem knows to reset the variable mach_task_self_ 
1173         // in libSystem for the child of a fork.  But dyld is built with a static copy 
1174         // of libc.a and has its own copy of mach_task_self_ which we reset here. 
1176         // In mach_init.h mach_task_self() is #defined to mach_task_self_ and 
1177         // in mach_init() mach_task_self_ is initialized to task_self_trap(). 
1179         extern mach_port_t      mach_task_self_
; 
1180         mach_task_self_ 
= task_self_trap(); 
1182         // If dyld is sending load/unload notices to CoreSymbolication, the shared memory 
1183         // page is not copied on fork. <rdar://problem/6797342> 
1184         // NULL the CoreSymbolication shared memory pointer to prevent a crash. 
1185         dyld_all_image_infos
.coreSymbolicationShmPage 
= NULL
; 
1186         // for safety, make sure child starts with clean systemOrderFlag 
1187         dyld_all_image_infos
.systemOrderFlag 
= 0; 
1190 typedef void (*MonitorProc
)(char *lowpc
, char *highpc
); 
1192 static void monInitCallback(ImageLoader
* image
, void* userData
) 
1194         MonitorProc proc 
= (MonitorProc
)userData
; 
1197         if ( image
->getSectionContent("__TEXT", "__text", &start
, &length
) ) { 
1198                 proc((char*)start
, (char*)start
+length
); 
1203 // _dyld_moninit is called from profiling runtime routine moninit(). 
1204 // dyld calls back with the range of each __TEXT/__text section in every 
1207 void _dyld_moninit(MonitorProc proc
) 
1209         dyld::forEachImageDo(&monInitCallback
, (void*)proc
); 
1212 #if DEPRECATED_APIS_SUPPORTED 
1213 // returns true if prebinding was used in main executable 
1214 bool _dyld_launched_prebound() 
1216         if ( dyld::gLogAPIs 
) 
1217                 dyld::log("%s()\n", __func__
); 
1219         // ¥¥¥Êif we deprecate prebinding, we may want to consider always returning true or false here 
1220         return dyld::mainExecutablePrebound(); 
1225 // _dyld_NSMakePrivateModulePublic() is the dyld side of the hack 
1226 // NSMakePrivateModulePublic() needed for the dlopen() to turn it's 
1227 // RTLD_LOCAL handles into RTLD_GLOBAL.  It just simply turns off the private 
1228 // flag on the image for this module.  If the module was found and it was 
1229 // private then everything worked and TRUE is returned else FALSE is returned. 
1231 static bool NSMakePrivateModulePublic(NSModule 
module) 
1233         ImageLoader
* image 
= NSModuleToImageLoader(module); 
1234         if ( image 
!= NULL 
) { 
1235                 if ( image
->hasHiddenExports() ) { 
1236                         image
->setHideExports(false); 
1243 #endif // DEPRECATED_APIS_SUPPORTED 
1245 bool lookupDyldFunction(const char* name
, uintptr_t* address
) 
1247         for (const dyld_func
* p 
= dyld_funcs
; p
->name 
!= NULL
; ++p
) { 
1248             if ( strcmp(p
->name
, name
) == 0 ) { 
1249                         if( p
->implementation 
== unimplemented 
) 
1250                                 dyld::log("unimplemented dyld function: %s\n", p
->name
); 
1251                         *address 
= (uintptr_t)p
->implementation
; 
1260 static void registerThreadHelpers(const dyld::LibSystemHelpers
* helpers
) 
1262         dyld::gLibSystemHelpers 
= helpers
; 
1264         // let gdb know it is safe to run code in inferior that might call malloc() 
1265         dyld_all_image_infos
.libSystemInitialized 
= true;        
1268         if ( helpers
->version 
>= 5 )  { 
1269                 // create key use by dyld exception handling 
1271                 int result 
= helpers
->pthread_key_create(&key
, NULL
); 
1273                         __Unwind_SjLj_SetThreadKey(key
); 
1279 static void dlerrorClear() 
1281         if ( dyld::gLibSystemHelpers 
!= NULL 
) { 
1282                 // first char of buffer is flag whether string (starting at second char) is valid 
1283                 char* buffer 
= (*dyld::gLibSystemHelpers
->getThreadBufferFor_dlerror
)(2); 
1289 static void dlerrorSet(const char* msg
) 
1291         if ( dyld::gLibSystemHelpers 
!= NULL 
) { 
1292                 // first char of buffer is flag whether string (starting at second char) is valid 
1293                 char* buffer 
= (*dyld::gLibSystemHelpers
->getThreadBufferFor_dlerror
)(strlen(msg
)+2); 
1295                 strcpy(&buffer
[1], msg
); 
1300 bool dlopen_preflight(const char* path
) 
1302         if ( dyld::gLogAPIs 
) 
1303                 dyld::log("%s(%s)\n", __func__
, path
); 
1307 #if DYLD_SHARED_CACHE_SUPPORT 
1308         // <rdar://problem/5910137> dlopen_preflight() on image in shared cache leaves it loaded but not objc initialized 
1309         // if requested path is to something in the dyld shared cache, always succeed 
1310         if ( dyld::inSharedCache(path
) ) 
1314         CRSetCrashLogMessage("dyld: in dlopen_preflight()"); 
1316         bool result 
= false; 
1317         std::vector
<const char*> rpathsFromCallerImage
; 
1319                 void* callerAddress 
= __builtin_return_address(1); // note layers: 1: real client, 0: libSystem glue 
1320                 ImageLoader
* callerImage 
= dyld::findImageContainingAddress(callerAddress
); 
1321                 // for dlopen, use rpath from caller image and from main executable 
1322                 if ( callerImage 
!= NULL 
) 
1323                         callerImage
->getRPaths(dyld::gLinkContext
, rpathsFromCallerImage
); 
1324                 ImageLoader::RPathChain 
callersRPaths(NULL
, &rpathsFromCallerImage
); 
1325                 if ( callerImage 
!= dyld::mainExecutable() ) { 
1326                         dyld::mainExecutable()->getRPaths(dyld::gLinkContext
, rpathsFromCallerImage
); 
1329                 ImageLoader
*    image 
= NULL
; 
1330                 const bool leafName 
= (strchr(path
, '/') == NULL
); 
1331                 const bool absolutePath 
= (path
[0] == '/'); 
1332 #if __IPHONE_OS_VERSION_MIN_REQUIRED 
1333                 char canonicalPath
[PATH_MAX
];  
1334                 // <rdar://problem/7017050> dlopen() not opening frameworks from shared cache with // or ./ in path 
1336                         // make path canonical if it contains a // or ./ 
1337                         if ( (strstr(path
, "//") != NULL
) || (strstr(path
, "./") != NULL
) ) { 
1338                                 const char* lastSlash 
= strrchr(path
, '/'); 
1339                                 char dirPath
[PATH_MAX
];  
1340                                 if ( strlcpy(dirPath
, path
, sizeof(dirPath
)) < sizeof(dirPath
) ) { 
1341                                         dirPath
[lastSlash
-path
] = '\0'; 
1342                                         if ( realpath(dirPath
, canonicalPath
) ) { 
1343                                                 strlcat(canonicalPath
, "/", sizeof(canonicalPath
)); 
1344                                                 if ( strlcat(canonicalPath
, lastSlash
+1, sizeof(canonicalPath
)) < sizeof(canonicalPath
) ) { 
1345                                                         // if all fit in buffer, use new canonical path 
1346                                                         path 
= canonicalPath
; 
1353                 dyld::LoadContext context
; 
1354                 context
.useSearchPaths  
= true; 
1355                 context
.useFallbackPaths
= leafName
;                                     // a partial path implies don't use fallback paths 
1356                 context
.useLdLibraryPath
= leafName
;                                     // a leafname implies should search  
1357                 context
.implicitRPath   
= !absolutePath
;                        // a non-absolute path implies try rpath searching  
1358                 context
.matchByInstallName 
= true; 
1359                 context
.dontLoad                
= false; 
1360                 context
.mustBeBundle    
= false; 
1361                 context
.mustBeDylib             
= false; 
1362                 context
.canBePIE                
= true; 
1363                 context
.origin                  
= callerImage 
!= NULL 
? callerImage
->getPath() : NULL
; // caller's image's path 
1364                 context
.rpath                   
= &callersRPaths
;       // rpaths from caller and main executable 
1366                 image 
= load(path
, context
); 
1367                 if ( image 
!= NULL 
) { 
1368                         dyld::preflight(image
, callersRPaths
);  // image object deleted by dyld::preflight() 
1372         catch (const char* msg
) { 
1373                 const char* str 
= dyld::mkstringf("dlopen_preflight(%s): %s", path
, msg
); 
1376                 free((void*)msg
);       // our free() will do nothing if msg is a string literal 
1378         // free rpaths (getRPaths() malloc'ed each string) 
1379         for(std::vector
<const char*>::iterator it
=rpathsFromCallerImage
.begin(); it 
!= rpathsFromCallerImage
.end(); ++it
) { 
1380                 const char* str 
= *it
; 
1383         CRSetCrashLogMessage(NULL
); 
1388 void* dlopen(const char* path
, int mode
) 
1390         if ( dyld::gLogAPIs 
) 
1391                 dyld::log("%s(%s, 0x%08X)\n", __func__
, ((path
==NULL
) ? "NULL" : path
), mode
); 
1395         // passing NULL for path means return magic object 
1396         if ( path 
== NULL 
) { 
1397                 // RTLD_FIRST means any dlsym() calls on the handle should only search that handle and not subsequent images 
1398                 if ( (mode 
& RTLD_FIRST
) != 0 ) 
1399                         return RTLD_MAIN_ONLY
; 
1401                         return RTLD_DEFAULT
; 
1404         // acquire global dyld lock (dlopen is special - libSystem glue does not do locking) 
1405         bool lockHeld 
= false; 
1406         if ( (dyld::gLibSystemHelpers 
!= NULL
) && (dyld::gLibSystemHelpers
->version 
>= 4) ) { 
1407                 dyld::gLibSystemHelpers
->acquireGlobalDyldLock(); 
1408                 CRSetCrashLogMessage("dyld: in dlopen()"); 
1412         void* result 
= NULL
; 
1413         ImageLoader
* image 
= NULL
; 
1414         std::vector
<const char*> rpathsFromCallerImage
; 
1416                 void* callerAddress 
= __builtin_return_address(1); // note layers: 1: real client, 0: libSystem glue 
1417                 ImageLoader
* callerImage 
= dyld::findImageContainingAddress(callerAddress
); 
1418                 // for dlopen, use rpath from caller image and from main executable 
1419                 if ( callerImage 
!= NULL 
) 
1420                         callerImage
->getRPaths(dyld::gLinkContext
, rpathsFromCallerImage
); 
1421                 ImageLoader::RPathChain 
callersRPaths(NULL
, &rpathsFromCallerImage
); 
1422                 if ( callerImage 
!= dyld::mainExecutable() ) { 
1423                         dyld::mainExecutable()->getRPaths(dyld::gLinkContext
, rpathsFromCallerImage
); 
1426                 const bool leafName 
= (strchr(path
, '/') == NULL
); 
1427                 const bool absolutePath 
= (path
[0] == '/'); 
1428 #if __IPHONE_OS_VERSION_MIN_REQUIRED 
1429                 char canonicalPath
[PATH_MAX
];  
1430                 // <rdar://problem/7017050> dlopen() not opening frameworks from shared cache with // or ./ in path 
1432                         // make path canonical if it contains a // or ./ 
1433                         if ( (strstr(path
, "//") != NULL
) || (strstr(path
, "./") != NULL
) ) { 
1434                                 const char* lastSlash 
= strrchr(path
, '/'); 
1435                                 char dirPath
[PATH_MAX
];  
1436                                 if ( strlcpy(dirPath
, path
, sizeof(dirPath
)) < sizeof(dirPath
) ) { 
1437                                         dirPath
[lastSlash
-path
] = '\0'; 
1438                                         if ( realpath(dirPath
, canonicalPath
) ) { 
1439                                                 strlcat(canonicalPath
, "/", sizeof(canonicalPath
)); 
1440                                                 if ( strlcat(canonicalPath
, lastSlash
+1, sizeof(canonicalPath
)) < sizeof(canonicalPath
) ) { 
1441                                                         // if all fit in buffer, use new canonical path 
1442                                                         path 
= canonicalPath
; 
1449                 dyld::LoadContext context
; 
1450                 context
.useSearchPaths  
= true; 
1451                 context
.useFallbackPaths
= leafName
;                             // a partial path means no fallback paths 
1452                 context
.useLdLibraryPath
= leafName
;                             // a leafname implies should search  
1453                 context
.implicitRPath   
= !absolutePath
;                // a non-absolute path implies try rpath searching  
1454                 context
.matchByInstallName 
= true; 
1455                 context
.dontLoad                
= ( (mode 
& RTLD_NOLOAD
) != 0 ); 
1456                 context
.mustBeBundle    
= false; 
1457                 context
.mustBeDylib             
= false; 
1458                 context
.canBePIE                
= true; 
1459                 context
.origin                  
= callerImage 
!= NULL 
? callerImage
->getPath() : NULL
; // caller's image's path 
1460                 context
.rpath                   
= &callersRPaths
;                               // rpaths from caller and main executable 
1462                 image 
= load(path
, context
); 
1463                 if ( image 
!= NULL 
) { 
1464                         // bump reference count.  Do this before link() so that if an initializer calls dlopen and fails 
1465                         // this image is not garbage collected 
1466                         image
->incrementDlopenReferenceCount(); 
1467                         // link in all dependents 
1468                         if ( (mode 
& RTLD_NOLOAD
) == 0 ) { 
1469                                 bool alreadyLinked 
= image
->isLinked(); 
1470                                 bool forceLazysBound 
= ( (mode 
& RTLD_NOW
) != 0 ); 
1471                                 dyld::link(image
, forceLazysBound
, callersRPaths
); 
1472                                 if ( ! alreadyLinked 
) { 
1473                                         // only hide exports if image is not already in use 
1474                                         if ( (mode 
& RTLD_LOCAL
) != 0 ) 
1475                                                 image
->setHideExports(true); 
1479                         // RTLD_NODELETE means don't unmap image even after dlclosed. This is what dlcompat did on Mac OS X 10.3 
1480                         // On other *nix OS's, it means dlclose() should do nothing, but the handle should be invalidated.  
1481                         // The subtle differences are:  
1482                         //  1) if the image has any termination routines, whether they are run during dlclose or when the process terminates 
1483                         //  2) If someone does a supsequent dlopen() on the same image, whether the same address should be used.  
1484                         if ( (mode 
& RTLD_NODELETE
) != 0 ) 
1485                                 image
->setLeaveMapped(); 
1487                         // release global dyld lock early, this enables initializers to do threaded operations 
1489                                 CRSetCrashLogMessage(NULL
); 
1490                                 dyld::gLibSystemHelpers
->releaseGlobalDyldLock(); 
1494                         // RTLD_NOLOAD means dlopen should fail unless path is already loaded.  
1495                         // don't run initializers when RTLD_NOLOAD is set.  This only matters if dlopen() is 
1496                         // called from within an initializer because it can cause initializers to run 
1497                         // out of order. Most uses of RTLD_NOLOAD are "probes".  If they want initialzers 
1498                         // to run, then don't use RTLD_NOLOAD. 
1499                         if ( (mode 
& RTLD_NOLOAD
) == 0 ) { 
1501                                 dyld::runInitializers(image
); 
1504                         // RTLD_FIRST means any dlsym() calls on the handle should only search that handle and not subsequent images 
1505                         // this is tracked by setting the low bit of the handle, which is usually zero by malloc alignment 
1506                         if ( (mode 
& RTLD_FIRST
) != 0 ) 
1507                                 result 
= (void*)(((uintptr_t)image
)|1); 
1512         catch (const char* msg
) { 
1513                 if ( image 
!= NULL 
) { 
1514                         // load() succeeded but, link() failed 
1515                         // back down reference count and do GC 
1516                         image
->decrementDlopenReferenceCount(); 
1517                         dyld::garbageCollectImages(); 
1519                 const char* str 
= dyld::mkstringf("dlopen(%s, %d): %s", path
, mode
, msg
); 
1522                 free((void*)msg
);       // our free() will do nothing if msg is a string literal 
1525         // free rpaths (getRPaths() malloc'ed each string) 
1526         for(std::vector
<const char*>::iterator it
=rpathsFromCallerImage
.begin(); it 
!= rpathsFromCallerImage
.end(); ++it
) { 
1527                 const char* str 
= *it
; 
1531         // when context.dontLoad is set, load() returns NULL instead of throwing an exception  
1532         if ( (mode 
& RTLD_NOLOAD
) && (result 
== NULL
) ) { 
1533                 dlerrorSet("image not already loaded"); 
1537                 CRSetCrashLogMessage(NULL
); 
1538                 dyld::gLibSystemHelpers
->releaseGlobalDyldLock(); 
1545 int dlclose(void* handle
) 
1547         if ( dyld::gLogAPIs 
) 
1548                 dyld::log("%s(%p)\n", __func__
, handle
); 
1550         // silently accept magic handles for main executable 
1551         if ( handle 
== RTLD_MAIN_ONLY 
) 
1553         if ( handle 
== RTLD_DEFAULT 
) 
1556         ImageLoader
* image 
= (ImageLoader
*)(((uintptr_t)handle
) & (-4));        // clear mode bits 
1557         if ( dyld::validImage(image
) ) { 
1559                 // decrement use count 
1560                 if ( image
->decrementDlopenReferenceCount() ) { 
1561                         dlerrorSet("dlclose() called too many times"); 
1564                 // remove image if reference count went to zero 
1565                 dyld::garbageCollectImages(); 
1569                 dlerrorSet("invalid handle passed to dlclose()"); 
1576 int dladdr(const void* address
, Dl_info
* info
) 
1578         if ( dyld::gLogAPIs 
) 
1579                 dyld::log("%s(%p, %p)\n", __func__
, address
, info
); 
1581         CRSetCrashLogMessage("dyld: in dladdr()"); 
1582         ImageLoader
* image 
= dyld::findImageContainingAddress(address
); 
1583         if ( image 
!= NULL 
) { 
1584                 info
->dli_fname 
= image
->getRealPath(); 
1585                 info
->dli_fbase 
= (void*)image
->machHeader(); 
1586                 if ( address 
== info
->dli_fbase 
) { 
1587                         // special case lookup of header 
1588                         info
->dli_sname 
= "__dso_handle"; 
1589                         info
->dli_saddr 
= info
->dli_fbase
; 
1590                         CRSetCrashLogMessage(NULL
); 
1591                         return 1; // success 
1593                 // find closest symbol in the image 
1594                 info
->dli_sname 
= image
->findClosestSymbol(address
, (const void**)&info
->dli_saddr
); 
1595                 // never return the mach_header symbol 
1596                 if ( info
->dli_saddr 
== info
->dli_fbase 
) { 
1597                         info
->dli_sname 
= NULL
; 
1598                         info
->dli_saddr 
= NULL
; 
1599                         CRSetCrashLogMessage(NULL
); 
1600                         return 1; // success 
1602                 if ( info
->dli_sname 
!= NULL 
) { 
1603                         if ( info
->dli_sname
[0] == '_' ) 
1604                                 info
->dli_sname 
= info
->dli_sname 
+1; // strip off leading underscore 
1605                         //dyld::log("dladdr(%p) => %p %s\n", address, info->dli_saddr, info->dli_sname); 
1606                         CRSetCrashLogMessage(NULL
); 
1607                         return 1; // success 
1609                 info
->dli_sname 
= NULL
; 
1610                 info
->dli_saddr 
= NULL
; 
1611                 CRSetCrashLogMessage(NULL
); 
1612                 return 1; // success 
1614         CRSetCrashLogMessage(NULL
); 
1615         return 0;  // failure 
1621         if ( dyld::gLogAPIs 
) 
1622                 dyld::log("%s()\n", __func__
); 
1624         if ( dyld::gLibSystemHelpers 
!= NULL 
) { 
1625                 // first char of buffer is flag whether string (starting at second char) is valid 
1626                 char* buffer 
= (*dyld::gLibSystemHelpers
->getThreadBufferFor_dlerror
)(2); 
1627                 if ( buffer
[0] != '\0' ) {      // if valid buffer 
1628                         buffer
[0] = '\0';               // mark invalid, so next call to dlerror returns NULL 
1629                         return &buffer
[1];              // return message 
1635 void* dlsym(void* handle
, const char* symbolName
) 
1637         if ( dyld::gLogAPIs 
) 
1638                 dyld::log("%s(%p, %s)\n", __func__
, handle
, symbolName
); 
1640         CRSetCrashLogMessage("dyld: in dlsym()"); 
1643         const ImageLoader
* image
; 
1644         const ImageLoader::Symbol
* sym
; 
1646         // dlsym() assumes symbolName passed in is same as in C source code 
1647         // dyld assumes all symbol names have an underscore prefix 
1648         char underscoredName
[strlen(symbolName
)+2]; 
1649         underscoredName
[0] = '_'; 
1650         strcpy(&underscoredName
[1], symbolName
); 
1652         // magic "search all" handle 
1653         if ( handle 
== RTLD_DEFAULT 
) { 
1654                 if ( dyld::flatFindExportedSymbol(underscoredName
, &sym
, &image
) ) { 
1655                         CRSetCrashLogMessage(NULL
); 
1656                         return (void*)image
->getExportedSymbolAddress(sym
, dyld::gLinkContext
); 
1658                 const char* str 
= dyld::mkstringf("dlsym(RTLD_DEFAULT, %s): symbol not found", symbolName
); 
1661                 CRSetCrashLogMessage(NULL
); 
1665         // magic "search only main executable" handle 
1666         if ( handle 
== RTLD_MAIN_ONLY 
) { 
1667                 image 
= dyld::mainExecutable(); 
1668                 sym 
= image
->findExportedSymbol(underscoredName
, true, &image
); // search RTLD_FIRST way 
1669                 if ( sym 
!= NULL 
) { 
1670                         CRSetCrashLogMessage(NULL
); 
1671                         return (void*)image
->getExportedSymbolAddress(sym
, dyld::gLinkContext
); 
1673                 const char* str 
= dyld::mkstringf("dlsym(RTLD_MAIN_ONLY, %s): symbol not found", symbolName
); 
1676                 CRSetCrashLogMessage(NULL
); 
1680         // magic "search what I would see" handle 
1681         if ( handle 
== RTLD_NEXT 
) { 
1682                 void* callerAddress 
= __builtin_return_address(1); // note layers: 1: real client, 0: libSystem glue 
1683                 ImageLoader
* callerImage 
= dyld::findImageContainingAddress(callerAddress
); 
1684                 sym 
= callerImage
->findExportedSymbolInDependentImages(underscoredName
, dyld::gLinkContext
, &image
); // don't search image, but do search what it links against 
1685                 if ( sym 
!= NULL 
) { 
1686                         CRSetCrashLogMessage(NULL
); 
1687                         return (void*)image
->getExportedSymbolAddress(sym
, dyld::gLinkContext
); 
1689                 const char* str 
= dyld::mkstringf("dlsym(RTLD_NEXT, %s): symbol not found", symbolName
); 
1692                 CRSetCrashLogMessage(NULL
); 
1695         // magic "search me, then what I would see" handle 
1696         if ( handle 
== RTLD_SELF 
) { 
1697                 void* callerAddress 
= __builtin_return_address(1); // note layers: 1: real client, 0: libSystem glue 
1698                 ImageLoader
* callerImage 
= dyld::findImageContainingAddress(callerAddress
); 
1699                 sym 
= callerImage
->findExportedSymbolInImageOrDependentImages(underscoredName
, dyld::gLinkContext
, &image
); // search image and what it links against 
1700                 if ( sym 
!= NULL 
) { 
1701                         CRSetCrashLogMessage(NULL
); 
1702                         return (void*)image
->getExportedSymbolAddress(sym
, dyld::gLinkContext
); 
1704                 const char* str 
= dyld::mkstringf("dlsym(RTLD_SELF, %s): symbol not found", symbolName
); 
1707                 CRSetCrashLogMessage(NULL
); 
1711         image 
= (ImageLoader
*)(((uintptr_t)handle
) & (-4));     // clear mode bits 
1712         if ( dyld::validImage(image
) ) { 
1713                 if ( (((uintptr_t)handle
) & 1) != 0 ) 
1714                         sym 
= image
->findExportedSymbol(underscoredName
, true, &image
); // search RTLD_FIRST way 
1716                         sym 
= image
->findExportedSymbolInImageOrDependentImages(underscoredName
, dyld::gLinkContext
, &image
); // search image and what it links against 
1718                 if ( sym 
!= NULL 
) { 
1719                         CRSetCrashLogMessage(NULL
); 
1720                         return (void*)image
->getExportedSymbolAddress(sym
, dyld::gLinkContext
); 
1722                 const char* str 
= dyld::mkstringf("dlsym(%p, %s): symbol not found", handle
, symbolName
); 
1727                 dlerrorSet("invalid handle passed to dlsym()"); 
1729         CRSetCrashLogMessage(NULL
); 
1742 const struct dyld_all_image_infos
* _dyld_get_all_image_infos() 
1744         return &dyld_all_image_infos
; 
1748 static bool client_dyld_find_unwind_sections(void* addr
, dyld_unwind_sections
* info
) 
1750         //if ( dyld::gLogAPIs ) 
1751         //      dyld::log("%s(%p, %p)\n", __func__, addr, info); 
1753         ImageLoader
* image 
= dyld::findImageContainingAddress(addr
); 
1754         if ( image 
!= NULL 
) { 
1755                 image
->getUnwindInfo(info
); 
1763 void dyld_register_image_state_change_handler(dyld_image_states state
, bool batch
,  
1764                                                                                         dyld_image_state_change_handler handler
) 
1766         if ( dyld::gLogAPIs 
) 
1767                 dyld::log("%s(%d, %d, %p)\n", __func__
, state
, batch
, handler
); 
1769                 dyld::registerImageStateBatchChangeHandler(state
, handler
); 
1771                 dyld::registerImageStateSingleChangeHandler(state
, handler
); 
1774 const char* dyld_image_path_containing_address(const void* address
) 
1776         if ( dyld::gLogAPIs 
) 
1777                 dyld::log("%s(%p)\n", __func__
, address
); 
1779         ImageLoader
* image 
= dyld::findImageContainingAddress(address
); 
1780         if ( image 
!= NULL 
) 
1781                 return image
->getRealPath(); 
1787 #if __IPHONE_OS_VERSION_MIN_REQUIRED     
1788 bool dyld_shared_cache_some_image_overridden() 
1790         return dyld::gSharedCacheOverridden
;