1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
3 * Copyright (c) 2004-2012 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@
27 #include <malloc/malloc.h>
30 #include <crt_externs.h>
31 #include <Availability.h>
32 #include <vproc_priv.h>
34 #include "mach-o/dyld.h"
35 #include "mach-o/dyld_priv.h"
37 #include "ImageLoader.h"
39 #include "start_glue.h"
41 extern "C" int __cxa_atexit(void (*func
)(void *), void *arg
, void *dso
);
42 extern "C" void __cxa_finalize(const void *dso
);
43 extern "C" void __cxa_finalize_ranges(const struct __cxa_range_t ranges
[], int count
);
46 #ifndef LC_VERSION_MIN_MACOSX
47 #define LC_VERSION_MIN_MACOSX 0x24
48 struct version_min_command
{
49 uint32_t cmd
; /* LC_VERSION_MIN_MACOSX or
50 LC_VERSION_MIN_IPHONEOS */
51 uint32_t cmdsize
; /* sizeof(struct min_version_command) */
52 uint32_t version
; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */
53 uint32_t sdk
; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */
57 #ifndef LC_VERSION_MIN_IPHONEOS
58 #define LC_VERSION_MIN_IPHONEOS 0x25
61 #ifndef LC_VERSION_MIN_TVOS
62 #define LC_VERSION_MIN_TVOS 0x2F
65 #ifndef LC_VERSION_MIN_WATCHOS
66 #define LC_VERSION_MIN_WATCHOS 0x30
70 #ifndef LC_LOAD_UPWARD_DYLIB
71 #define LC_LOAD_UPWARD_DYLIB (0x23|LC_REQ_DYLD) /* load of dylib whose initializers run later */
75 // deprecated APIs are still availble on Mac OS X, but not on iPhone OS
76 #if __IPHONE_OS_VERSION_MIN_REQUIRED
77 #define DEPRECATED_APIS_SUPPORTED 0
79 #define DEPRECATED_APIS_SUPPORTED 1
83 * names_match() takes an install_name from an LC_LOAD_DYLIB command and a
84 * libraryName (which is -lx or -framework Foo argument passed to the static
85 * link editor for the same library) and determines if they match. This depends
86 * on conventional use of names including major versioning.
91 const char *install_name
,
92 const char* libraryName
)
98 * Conventional install names have these forms:
99 * /System/Library/Frameworks/AppKit.framework/Versions/A/Appkit
100 * /Local/Library/Frameworks/AppKit.framework/Appkit
101 * /lib/libsys_s.A.dylib
102 * /usr/lib/libsys_s.dylib
104 basename
= strrchr(install_name
, '/');
106 basename
= install_name
;
111 * By checking the base name matching the library name we take care
112 * of the -framework cases.
114 if(strcmp(basename
, libraryName
) == 0)
118 * Now check the base name for "lib" if so proceed to check for the
119 * -lx case dealing with a possible .X.dylib and a .dylib extension.
121 if(strncmp(basename
, "lib", 3) ==0){
122 n
= strlen(libraryName
);
123 if(strncmp(basename
+3, libraryName
, n
) == 0){
124 if(strncmp(basename
+3+n
, ".dylib", 6) == 0)
126 if(basename
[3+n
] == '.' &&
127 basename
[3+n
+1] != '\0' &&
128 strncmp(basename
+3+n
+2, ".dylib", 6) == 0)
135 #if DEPRECATED_APIS_SUPPORTED
137 void NSInstallLinkEditErrorHandlers(
138 const NSLinkEditErrorHandlers
* handlers
)
140 DYLD_LOCK_THIS_BLOCK
;
141 typedef void (*ucallback_t
)(const char* symbol_name
);
142 typedef NSModule (*mcallback_t
)(NSSymbol s
, NSModule old
, NSModule newhandler
);
143 typedef void (*lcallback_t
)(NSLinkEditErrors c
, int errorNumber
,
144 const char* fileName
, const char* errorString
);
145 static void (*p
)(ucallback_t undefined
, mcallback_t multiple
, lcallback_t linkEdit
) = NULL
;
148 _dyld_func_lookup("__dyld_install_handlers", (void**)&p
);
149 mcallback_t m
= handlers
->multiple
;
150 p(handlers
->undefined
, m
, handlers
->linkEdit
);
157 DYLD_LOCK_THIS_BLOCK
;
158 static const char* (*p
)(NSModule
module) = NULL
;
161 _dyld_func_lookup("__dyld_NSNameOfModule", (void**)&p
);
166 NSLibraryNameForModule(
169 DYLD_LOCK_THIS_BLOCK
;
170 static const char* (*p
)(NSModule
module) = NULL
;
173 _dyld_func_lookup("__dyld_NSLibraryNameForModule", (void**)&p
);
178 NSIsSymbolNameDefined(
179 const char* symbolName
)
181 DYLD_LOCK_THIS_BLOCK
;
182 static bool (*p
)(const char* symbolName
) = NULL
;
185 _dyld_func_lookup("__dyld_NSIsSymbolNameDefined", (void**)&p
);
186 return(p(symbolName
));
190 NSIsSymbolNameDefinedWithHint(
191 const char* symbolName
,
192 const char* libraryNameHint
)
194 DYLD_LOCK_THIS_BLOCK
;
195 static bool (*p
)(const char* symbolName
,
196 const char* libraryNameHint
) = NULL
;
199 _dyld_func_lookup("__dyld_NSIsSymbolNameDefinedWithHint", (void**)&p
);
200 return(p(symbolName
, libraryNameHint
));
204 NSIsSymbolNameDefinedInImage(
205 const struct mach_header
*image
,
206 const char* symbolName
)
208 DYLD_LOCK_THIS_BLOCK
;
209 static bool (*p
)(const struct mach_header
*image
,
210 const char* symbolName
) = NULL
;
213 _dyld_func_lookup("__dyld_NSIsSymbolNameDefinedInImage", (void**)&p
);
214 return(p(image
, symbolName
));
218 NSLookupAndBindSymbol(
219 const char* symbolName
)
221 DYLD_LOCK_THIS_BLOCK
;
222 static NSSymbol (*p
)(const char* symbolName
) = NULL
;
225 _dyld_func_lookup("__dyld_NSLookupAndBindSymbol", (void**)&p
);
226 return(p(symbolName
));
230 NSLookupAndBindSymbolWithHint(
231 const char* symbolName
,
232 const char* libraryNameHint
)
234 DYLD_LOCK_THIS_BLOCK
;
235 static NSSymbol (*p
)(const char* symbolName
,
236 const char* libraryNameHint
) = NULL
;
239 _dyld_func_lookup("__dyld_NSLookupAndBindSymbolWithHint", (void**)&p
);
240 return(p(symbolName
, libraryNameHint
));
244 NSLookupSymbolInModule(
246 const char* symbolName
)
248 DYLD_LOCK_THIS_BLOCK
;
249 static NSSymbol (*p
)(NSModule
module, const char* symbolName
) = NULL
;
252 _dyld_func_lookup("__dyld_NSLookupSymbolInModule", (void**)&p
);
253 return(p(module, symbolName
));
257 NSLookupSymbolInImage(
258 const struct mach_header
*image
,
259 const char* symbolName
,
262 DYLD_LOCK_THIS_BLOCK
;
263 static NSSymbol (*p
)(const struct mach_header
*image
,
264 const char* symbolName
,
265 uint32_t options
) = NULL
;
268 _dyld_func_lookup("__dyld_NSLookupSymbolInImage", (void**)&p
);
269 return(p(image
, symbolName
, options
));
276 DYLD_LOCK_THIS_BLOCK
;
277 static char * (*p
)(NSSymbol symbol
) = NULL
;
280 _dyld_func_lookup("__dyld_NSNameOfSymbol",(void**)&p
);
288 DYLD_LOCK_THIS_BLOCK
;
289 static void * (*p
)(NSSymbol symbol
) = NULL
;
292 _dyld_func_lookup("__dyld_NSAddressOfSymbol", (void**)&p
);
300 DYLD_LOCK_THIS_BLOCK
;
301 static NSModule (*p
)(NSSymbol symbol
) = NULL
;
304 _dyld_func_lookup("__dyld_NSModuleForSymbol", (void**)&p
);
310 const char* pathName
)
312 DYLD_LOCK_THIS_BLOCK
;
313 static bool (*p
)(const char* pathName
) = NULL
;
316 _dyld_func_lookup("__dyld_NSAddLibrary", (void**)&p
);
321 NSAddLibraryWithSearching(
322 const char* pathName
)
324 DYLD_LOCK_THIS_BLOCK
;
325 static bool (*p
)(const char* pathName
) = NULL
;
328 _dyld_func_lookup("__dyld_NSAddLibraryWithSearching", (void**)&p
);
332 const struct mach_header
*
334 const char* image_name
,
337 DYLD_LOCK_THIS_BLOCK
;
338 static const struct mach_header
* (*p
)(const char* image_name
,
339 uint32_t options
) = NULL
;
342 _dyld_func_lookup("__dyld_NSAddImage", (void**)&p
);
343 return(p(image_name
, options
));
345 #endif // DEPRECATED_APIS_SUPPORTED
348 * This routine returns the current version of the named shared library the
349 * executable it was built with. The libraryName parameter is the same as the
350 * -lx or -framework Foo argument passed to the static link editor when building
351 * the executable (with -lx it would be "x" and with -framework Foo it would be
352 * "Foo"). If this the executable was not built against the specified library
353 * it returns -1. It should be noted that if this only returns the value the
354 * current version of the named shared library the executable was built with
355 * and not a list of current versions that dependent libraries and bundles the
356 * program is using were built with.
358 int32_t NSVersionOfLinkTimeLibrary(const char* libraryName
)
360 // Lazily call _NSGetMachExecuteHeader() and cache result
362 static mach_header_64
* mh
= NULL
;
364 static mach_header
* mh
= NULL
;
367 mh
= _NSGetMachExecuteHeader();
369 const load_command
* lc
= (load_command
*)((char*)mh
+ sizeof(mach_header_64
));
371 const load_command
* lc
= (load_command
*)((char*)mh
+ sizeof(mach_header
));
373 for(uint32_t i
= 0; i
< mh
->ncmds
; i
++){
376 case LC_LOAD_WEAK_DYLIB
:
377 case LC_LOAD_UPWARD_DYLIB
:
378 const dylib_command
* dl
= (dylib_command
*)lc
;
379 const char* install_name
= (char*)dl
+ dl
->dylib
.name
.offset
;
380 if ( names_match(install_name
, libraryName
) )
381 return dl
->dylib
.current_version
;
384 lc
= (load_command
*)((char*)lc
+ lc
->cmdsize
);
390 * This routine returns the current version of the named shared library the
391 * program it is running against. The libraryName parameter is the same as
392 * would be static link editor using the -lx or -framework Foo flags (with -lx
393 * it would be "x" and with -framework Foo it would be "Foo"). If the program
394 * is not using the specified library it returns -1.
396 int32_t NSVersionOfRunTimeLibrary(const char* libraryName
)
398 uint32_t n
= _dyld_image_count();
399 for(uint32_t i
= 0; i
< n
; i
++){
400 const mach_header
* mh
= _dyld_get_image_header(i
);
403 if ( mh
->filetype
!= MH_DYLIB
)
406 const load_command
* lc
= (load_command
*)((char*)mh
+ sizeof(mach_header_64
));
408 const load_command
* lc
= (load_command
*)((char*)mh
+ sizeof(mach_header
));
410 for(uint32_t j
= 0; j
< mh
->ncmds
; j
++){
411 if ( lc
->cmd
== LC_ID_DYLIB
) {
412 const dylib_command
* dl
= (dylib_command
*)lc
;
413 const char* install_name
= (char *)dl
+ dl
->dylib
.name
.offset
;
414 if ( names_match(install_name
, libraryName
) )
415 return dl
->dylib
.current_version
;
417 lc
= (load_command
*)((char*)lc
+ lc
->cmdsize
);
424 #define PACKED_VERSION(major, minor, tiny) ((((major) & 0xffff) << 16) | (((minor) & 0xff) << 8) | ((tiny) & 0xff))
427 static bool getVersionLoadCommandInfo(const mach_header
* mh
, uint32_t* loadCommand
, uint32_t* minOS
, uint32_t* sdk
)
429 const load_command
* startCmds
= NULL
;
430 if ( mh
->magic
== MH_MAGIC_64
)
431 startCmds
= (load_command
*)((char *)mh
+ sizeof(mach_header_64
));
432 else if ( mh
->magic
== MH_MAGIC
)
433 startCmds
= (load_command
*)((char *)mh
+ sizeof(mach_header
));
435 return false; // not a mach-o file, or wrong endianness
437 const load_command
* const cmdsEnd
= (load_command
*)((char*)startCmds
+ mh
->sizeofcmds
);
438 const load_command
* cmd
= startCmds
;
439 for(uint32_t i
= 0; i
< mh
->ncmds
; ++i
) {
440 const load_command
* nextCmd
= (load_command
*)((char *)cmd
+ cmd
->cmdsize
);
441 if ( (cmd
->cmdsize
< 8) || (nextCmd
> cmdsEnd
) || (nextCmd
< startCmds
)) {
444 const version_min_command
* versCmd
;
445 switch ( cmd
->cmd
) {
446 case LC_VERSION_MIN_IPHONEOS
:
447 case LC_VERSION_MIN_MACOSX
:
448 case LC_VERSION_MIN_TVOS
:
449 case LC_VERSION_MIN_WATCHOS
:
450 versCmd
= (version_min_command
*)cmd
;
451 *loadCommand
= versCmd
->cmd
;
452 *minOS
= versCmd
->version
;
461 #if !__WATCH_OS_VERSION_MIN_REQUIRED && !__TV_OS_VERSION_MIN_REQUIRED
462 static uint32_t deriveSDKVersFromDylibs(const mach_header
* mh
)
464 const load_command
* startCmds
= NULL
;
465 if ( mh
->magic
== MH_MAGIC_64
)
466 startCmds
= (load_command
*)((char *)mh
+ sizeof(mach_header_64
));
467 else if ( mh
->magic
== MH_MAGIC
)
468 startCmds
= (load_command
*)((char *)mh
+ sizeof(mach_header
));
470 return 0; // not a mach-o file, or wrong endianness
472 const load_command
* const cmdsEnd
= (load_command
*)((char*)startCmds
+ mh
->sizeofcmds
);
473 const dylib_command
* dylibCmd
;
474 const load_command
* cmd
= startCmds
;
475 const char* dylibName
;
476 #if __IPHONE_OS_VERSION_MIN_REQUIRED
477 uint32_t foundationVers
= 0;
479 uint32_t libSystemVers
= 0;
481 for(uint32_t i
= 0; i
< mh
->ncmds
; ++i
) {
482 const load_command
* nextCmd
= (load_command
*)((char *)cmd
+ cmd
->cmdsize
);
483 // <rdar://problem/14381579&16050962> sanity check size of command
484 if ( (cmd
->cmdsize
< 8) || (nextCmd
> cmdsEnd
) || (nextCmd
< startCmds
)) {
487 switch ( cmd
->cmd
) {
489 case LC_LOAD_WEAK_DYLIB
:
490 case LC_LOAD_UPWARD_DYLIB
:
491 dylibCmd
= (dylib_command
*)cmd
;
492 // sanity check dylib command layout
493 if ( dylibCmd
->dylib
.name
.offset
> cmd
->cmdsize
)
495 dylibName
= (char*)dylibCmd
+ dylibCmd
->dylib
.name
.offset
;
496 #if __IPHONE_OS_VERSION_MIN_REQUIRED
497 if ( strcmp(dylibName
, "/System/Library/Frameworks/Foundation.framework/Foundation") == 0 )
498 foundationVers
= dylibCmd
->dylib
.current_version
;
500 if ( strcmp(dylibName
, "/usr/lib/libSystem.B.dylib") == 0 )
501 libSystemVers
= dylibCmd
->dylib
.current_version
;
508 struct DylibToOSMapping
{
509 uint32_t dylibVersion
;
513 #if __IPHONE_OS_VERSION_MIN_REQUIRED
514 static const DylibToOSMapping foundationMapping
[] = {
515 { PACKED_VERSION(678,24,0), DYLD_IOS_VERSION_2_0
},
516 { PACKED_VERSION(678,26,0), DYLD_IOS_VERSION_2_1
},
517 { PACKED_VERSION(678,29,0), DYLD_IOS_VERSION_2_2
},
518 { PACKED_VERSION(678,47,0), DYLD_IOS_VERSION_3_0
},
519 { PACKED_VERSION(678,51,0), DYLD_IOS_VERSION_3_1
},
520 { PACKED_VERSION(678,60,0), DYLD_IOS_VERSION_3_2
},
521 { PACKED_VERSION(751,32,0), DYLD_IOS_VERSION_4_0
},
522 { PACKED_VERSION(751,37,0), DYLD_IOS_VERSION_4_1
},
523 { PACKED_VERSION(751,49,0), DYLD_IOS_VERSION_4_2
},
524 { PACKED_VERSION(751,58,0), DYLD_IOS_VERSION_4_3
},
525 { PACKED_VERSION(881,0,0), DYLD_IOS_VERSION_5_0
},
526 { PACKED_VERSION(890,1,0), DYLD_IOS_VERSION_5_1
},
527 { PACKED_VERSION(992,0,0), DYLD_IOS_VERSION_6_0
},
528 { PACKED_VERSION(993,0,0), DYLD_IOS_VERSION_6_1
},
529 { PACKED_VERSION(1038,14,0),DYLD_IOS_VERSION_7_0
},
530 { PACKED_VERSION(0,0,0), DYLD_IOS_VERSION_7_0
}
531 // We don't need to expand this table because all recent
532 // binaries have LC_VERSION_MIN_ load command.
535 if ( foundationVers
!= 0 ) {
536 uint32_t lastOsVersion
= 0;
537 for (const DylibToOSMapping
* p
=foundationMapping
; ; ++p
) {
538 if ( p
->dylibVersion
== 0 )
540 if ( foundationVers
< p
->dylibVersion
)
541 return lastOsVersion
;
542 lastOsVersion
= p
->osVersion
;
547 // Note: versions are for the GM release. The last entry should
548 // always be zero. At the start of the next major version,
549 // a new last entry needs to be added and the previous zero
550 // updated to the GM dylib version.
551 static const DylibToOSMapping libSystemMapping
[] = {
552 { PACKED_VERSION(88,1,3), DYLD_MACOSX_VERSION_10_4
},
553 { PACKED_VERSION(111,0,0), DYLD_MACOSX_VERSION_10_5
},
554 { PACKED_VERSION(123,0,0), DYLD_MACOSX_VERSION_10_6
},
555 { PACKED_VERSION(159,0,0), DYLD_MACOSX_VERSION_10_7
},
556 { PACKED_VERSION(169,3,0), DYLD_MACOSX_VERSION_10_8
},
557 { PACKED_VERSION(1197,0,0), DYLD_MACOSX_VERSION_10_9
},
558 { PACKED_VERSION(0,0,0), DYLD_MACOSX_VERSION_10_9
}
559 // We don't need to expand this table because all recent
560 // binaries have LC_VERSION_MIN_ load command.
563 if ( libSystemVers
!= 0 ) {
564 uint32_t lastOsVersion
= 0;
565 for (const DylibToOSMapping
* p
=libSystemMapping
; ; ++p
) {
566 if ( p
->dylibVersion
== 0 )
568 if ( libSystemVers
< p
->dylibVersion
)
569 return lastOsVersion
;
570 lastOsVersion
= p
->osVersion
;
579 #if __WATCH_OS_VERSION_MIN_REQUIRED
580 static uint32_t watchVersToIOSVers(uint32_t vers
)
582 return vers
+ 0x00070000;
585 uint32_t dyld_get_program_sdk_watch_os_version()
587 const mach_header
* mh
= (mach_header
*)_NSGetMachExecuteHeader();
588 uint32_t loadCommand
;
592 if ( getVersionLoadCommandInfo(mh
, &loadCommand
, &minOS
, &sdk
) ) {
593 if ( loadCommand
== LC_VERSION_MIN_WATCHOS
)
601 * Returns the sdk version (encode as nibble XXXX.YY.ZZ) the
602 * specified binary was built against.
604 * First looks for LC_VERSION_MIN_* in binary and if sdk field is
605 * not zero, return that value.
606 * Otherwise, looks for the libSystem.B.dylib the binary linked
607 * against and uses a table to convert that to an sdk version.
609 uint32_t dyld_get_sdk_version(const mach_header
* mh
)
611 uint32_t loadCommand
;
615 if ( getVersionLoadCommandInfo(mh
, &loadCommand
, &minOS
, &sdk
) ) {
616 switch (loadCommand
) {
617 #if __WATCH_OS_VERSION_MIN_REQUIRED
618 case LC_VERSION_MIN_WATCHOS
:
619 // new binary. sdk version looks like "2.0" but API wants "9.0"
620 return watchVersToIOSVers(sdk
);
621 case LC_VERSION_MIN_IPHONEOS
:
622 // old binary. sdk matches API semantics so can return directly.
624 #elif __TV_OS_VERSION_MIN_REQUIRED
625 case LC_VERSION_MIN_TVOS
:
626 case LC_VERSION_MIN_IPHONEOS
:
628 #elif __IPHONE_OS_VERSION_MIN_REQUIRED
629 case LC_VERSION_MIN_IPHONEOS
:
630 if ( sdk
!= 0 ) // old binaries might not have SDK set
634 case LC_VERSION_MIN_MACOSX
:
635 if ( sdk
!= 0 ) // old binaries might not have SDK set
642 #if __WATCH_OS_VERSION_MIN_REQUIRED ||__TV_OS_VERSION_MIN_REQUIRED
643 // All WatchOS and tv OS binaries should have version load command.
646 // MacOSX and iOS have old binaries without version load commmand.
647 return deriveSDKVersFromDylibs(mh
);
651 uint32_t dyld_get_program_sdk_version()
653 return dyld_get_sdk_version((mach_header
*)_NSGetMachExecuteHeader());
656 uint32_t dyld_get_min_os_version(const struct mach_header
* mh
)
658 uint32_t loadCommand
;
662 if ( getVersionLoadCommandInfo(mh
, &loadCommand
, &minOS
, &sdk
) ) {
663 switch (loadCommand
) {
664 #if __WATCH_OS_VERSION_MIN_REQUIRED
665 case LC_VERSION_MIN_WATCHOS
:
666 // new binary. OS version looks like "2.0" but API wants "9.0"
667 return watchVersToIOSVers(minOS
);
668 case LC_VERSION_MIN_IPHONEOS
:
669 // old binary. OS matches API semantics so can return directly.
671 #elif __TV_OS_VERSION_MIN_REQUIRED
672 case LC_VERSION_MIN_TVOS
:
673 case LC_VERSION_MIN_IPHONEOS
:
675 #elif __IPHONE_OS_VERSION_MIN_REQUIRED
676 case LC_VERSION_MIN_IPHONEOS
:
679 case LC_VERSION_MIN_MACOSX
:
688 uint32_t dyld_get_program_min_os_version()
690 return dyld_get_min_os_version((mach_header
*)_NSGetMachExecuteHeader());
694 #if DEPRECATED_APIS_SUPPORTED
696 * NSCreateObjectFileImageFromFile() creates an NSObjectFileImage for the
697 * specified file name if the file is a correct Mach-O file that can be loaded
698 * with NSloadModule(). For return codes of NSObjectFileImageFailure and
699 * NSObjectFileImageFormat an error message is printed to stderr. All
700 * other codes cause no printing.
702 NSObjectFileImageReturnCode
703 NSCreateObjectFileImageFromFile(
704 const char* pathName
,
705 NSObjectFileImage
*objectFileImage
)
707 DYLD_LOCK_THIS_BLOCK
;
708 static NSObjectFileImageReturnCode (*p
)(const char*, NSObjectFileImage
*) = NULL
;
711 _dyld_func_lookup("__dyld_NSCreateObjectFileImageFromFile", (void**)&p
);
712 return p(pathName
, objectFileImage
);
717 * NSCreateObjectFileImageFromMemory() creates an NSObjectFileImage for the
718 * object file mapped into memory at address of size length if the object file
719 * is a correct Mach-O file that can be loaded with NSloadModule(). For return
720 * codes of NSObjectFileImageFailure and NSObjectFileImageFormat an error
721 * message is printed to stderr. All other codes cause no printing.
723 NSObjectFileImageReturnCode
724 NSCreateObjectFileImageFromMemory(
727 NSObjectFileImage
*objectFileImage
)
729 DYLD_LOCK_THIS_BLOCK
;
730 static NSObjectFileImageReturnCode (*p
)(const void*, size_t, NSObjectFileImage
*) = NULL
;
733 _dyld_func_lookup("__dyld_NSCreateObjectFileImageFromMemory", (void**)&p
);
734 return p(address
, size
, objectFileImage
);
737 #if OBSOLETE_DYLD_API
739 * NSCreateCoreFileImageFromFile() creates an NSObjectFileImage for the
740 * specified core file name if the file is a correct Mach-O core file.
741 * For return codes of NSObjectFileImageFailure and NSObjectFileImageFormat
742 * an error message is printed to stderr. All other codes cause no printing.
744 NSObjectFileImageReturnCode
745 NSCreateCoreFileImageFromFile(
746 const char* pathName
,
747 NSObjectFileImage
*objectFileImage
)
749 DYLD_LOCK_THIS_BLOCK
;
750 static NSObjectFileImageReturnCode (*p
)(const char*, NSObjectFileImage
*) = NULL
;
753 _dyld_func_lookup("__dyld_NSCreateCoreFileImageFromFile", (void**)&p
);
754 return p(pathName
, objectFileImage
);
759 NSDestroyObjectFileImage(
760 NSObjectFileImage objectFileImage
)
762 DYLD_LOCK_THIS_BLOCK
;
763 static bool (*p
)(NSObjectFileImage
) = NULL
;
766 _dyld_func_lookup("__dyld_NSDestroyObjectFileImage", (void**)&p
);
767 return p(objectFileImage
);
773 NSObjectFileImage objectFileImage
,
774 const char* moduleName
,
777 DYLD_LOCK_THIS_BLOCK
;
778 static NSModule (*p
)(NSObjectFileImage
, const char*, unsigned long) = NULL
;
781 _dyld_func_lookup("__dyld_NSLinkModule", (void**)&p
);
783 return p(objectFileImage
, moduleName
, options
);
790 * NSSymbolDefinitionCountInObjectFileImage() returns the number of symbol
791 * definitions in the NSObjectFileImage.
794 NSSymbolDefinitionCountInObjectFileImage(
795 NSObjectFileImage objectFileImage
)
797 DYLD_LOCK_THIS_BLOCK
;
798 static unsigned long (*p
)(NSObjectFileImage
) = NULL
;
801 _dyld_func_lookup("__dyld_NSSymbolDefinitionCountInObjectFileImage", (void**)&p
);
803 return p(objectFileImage
);
807 * NSSymbolDefinitionNameInObjectFileImage() returns the name of the i'th
808 * symbol definitions in the NSObjectFileImage. If the ordinal specified is
809 * outside the range [0..NSSymbolDefinitionCountInObjectFileImage], NULL will
813 NSSymbolDefinitionNameInObjectFileImage(
814 NSObjectFileImage objectFileImage
,
817 DYLD_LOCK_THIS_BLOCK
;
818 static const char* (*p
)(NSObjectFileImage
, uint32_t) = NULL
;
821 _dyld_func_lookup("__dyld_NSSymbolDefinitionNameInObjectFileImage", (void**)&p
);
823 return p(objectFileImage
, ordinal
);
827 * NSSymbolReferenceCountInObjectFileImage() returns the number of references
828 * to undefined symbols the NSObjectFileImage.
831 NSSymbolReferenceCountInObjectFileImage(
832 NSObjectFileImage objectFileImage
)
834 DYLD_LOCK_THIS_BLOCK
;
835 static unsigned long (*p
)(NSObjectFileImage
) = NULL
;
838 _dyld_func_lookup("__dyld_NSSymbolReferenceCountInObjectFileImage", (void**)&p
);
840 return p(objectFileImage
);
844 * NSSymbolReferenceNameInObjectFileImage() returns the name of the i'th
845 * undefined symbol in the NSObjectFileImage. If the ordinal specified is
846 * outside the range [0..NSSymbolReferenceCountInObjectFileImage], NULL will be
850 NSSymbolReferenceNameInObjectFileImage(
851 NSObjectFileImage objectFileImage
,
853 bool *tentative_definition
) /* can be NULL */
855 DYLD_LOCK_THIS_BLOCK
;
856 static const char* (*p
)(NSObjectFileImage
, uint32_t, bool*) = NULL
;
859 _dyld_func_lookup("__dyld_NSSymbolReferenceNameInObjectFileImage", (void**)&p
);
861 return p(objectFileImage
, ordinal
, tentative_definition
);
865 * NSIsSymbolDefinedInObjectFileImage() returns TRUE if the specified symbol
866 * name has a definition in the NSObjectFileImage and FALSE otherwise.
869 NSIsSymbolDefinedInObjectFileImage(
870 NSObjectFileImage objectFileImage
,
871 const char* symbolName
)
873 DYLD_LOCK_THIS_BLOCK
;
874 static bool (*p
)(NSObjectFileImage
, const char*) = NULL
;
877 _dyld_func_lookup("__dyld_NSIsSymbolDefinedInObjectFileImage", (void**)&p
);
879 return p(objectFileImage
, symbolName
);
883 * NSGetSectionDataInObjectFileImage() returns a pointer to the section contents
884 * in the NSObjectFileImage for the specified segmentName and sectionName if
885 * it exists and it is not a zerofill section. If not it returns NULL. If
886 * the parameter size is not NULL the size of the section is also returned
887 * indirectly through that pointer.
890 NSGetSectionDataInObjectFileImage(
891 NSObjectFileImage objectFileImage
,
892 const char* segmentName
,
893 const char* sectionName
,
894 unsigned long *size
) /* can be NULL */
896 DYLD_LOCK_THIS_BLOCK
;
897 static void* (*p
)(NSObjectFileImage
, const char*, const char*, unsigned long*) = NULL
;
900 _dyld_func_lookup("__dyld_NSGetSectionDataInObjectFileImage", (void**)&p
);
902 return p(objectFileImage
, segmentName
, sectionName
, size
);
910 const char* *fileName
,
911 const char* *errorString
)
913 DYLD_LOCK_THIS_BLOCK
;
914 static void (*p
)(NSLinkEditErrors
*c
,
916 const char* *fileName
,
917 const char* *errorString
) = NULL
;
920 _dyld_func_lookup("__dyld_link_edit_error", (void**)&p
);
922 p(c
, errorNumber
, fileName
, errorString
);
930 DYLD_LOCK_THIS_BLOCK
;
931 static bool (*p
)(NSModule
module, uint32_t options
) = NULL
;
934 _dyld_func_lookup("__dyld_unlink_module", (void**)&p
);
936 return p(module, options
);
939 #if OBSOLETE_DYLD_API
942 NSModule moduleToReplace
,
943 NSObjectFileImage newObjectFileImage
,
951 #endif // DEPRECATED_APIS_SUPPORTED
954 *_NSGetExecutablePath copies the path of the executable into the buffer and
955 * returns 0 if the path was successfully copied in the provided buffer. If the
956 * buffer is not large enough, -1 is returned and the expected buffer size is
957 * copied in *bufsize. Note that _NSGetExecutablePath will return "a path" to
958 * the executable not a "real path" to the executable. That is the path may be
959 * a symbolic link and not the real file. And with deep directories the total
960 * bufsize needed could be more than MAXPATHLEN.
963 _NSGetExecutablePath(
967 DYLD_LOCK_THIS_BLOCK
;
968 static int (*p
)(char *buf
, uint32_t *bufsize
) = NULL
;
971 _dyld_func_lookup("__dyld__NSGetExecutablePath", (void**)&p
);
972 return(p(buf
, bufsize
));
975 #if DEPRECATED_APIS_SUPPORTED
977 _dyld_lookup_and_bind(
978 const char* symbol_name
,
982 DYLD_LOCK_THIS_BLOCK
;
983 static void (*p
)(const char*, void** , NSModule
*) = NULL
;
986 _dyld_func_lookup("__dyld_lookup_and_bind", (void**)&p
);
987 p(symbol_name
, address
, module);
991 _dyld_lookup_and_bind_with_hint(
992 const char* symbol_name
,
993 const char* library_name_hint
,
997 DYLD_LOCK_THIS_BLOCK
;
998 static void (*p
)(const char*, const char*, void**, NSModule
*) = NULL
;
1001 _dyld_func_lookup("__dyld_lookup_and_bind_with_hint", (void**)&p
);
1002 p(symbol_name
, library_name_hint
, address
, module);
1005 #if OBSOLETE_DYLD_API
1007 _dyld_lookup_and_bind_objc(
1008 const char* symbol_name
,
1012 DYLD_LOCK_THIS_BLOCK
;
1013 static void (*p
)(const char* , void**, NSModule
*) = NULL
;
1016 _dyld_func_lookup("__dyld_lookup_and_bind_objc", (void**)&p
);
1017 p(symbol_name
, address
, module);
1022 _dyld_lookup_and_bind_fully(
1023 const char* symbol_name
,
1027 DYLD_LOCK_THIS_BLOCK
;
1028 static void (*p
)(const char*, void**, NSModule
*) = NULL
;
1031 _dyld_func_lookup("__dyld_lookup_and_bind_fully", (void**)&p
);
1032 p(symbol_name
, address
, module);
1036 _dyld_bind_fully_image_containing_address(
1037 const void* address
)
1039 DYLD_LOCK_THIS_BLOCK
;
1040 static bool (*p
)(const void*) = NULL
;
1043 _dyld_func_lookup("__dyld_bind_fully_image_containing_address", (void**)&p
);
1046 #endif // DEPRECATED_APIS_SUPPORTED
1050 * _dyld_register_func_for_add_image registers the specified function to be
1051 * called when a new image is added (a bundle or a dynamic shared library) to
1052 * the program. When this function is first registered it is called for once
1053 * for each image that is currently part of the program.
1056 _dyld_register_func_for_add_image(
1057 void (*func
)(const struct mach_header
*mh
, intptr_t vmaddr_slide
))
1059 DYLD_LOCK_THIS_BLOCK
;
1060 typedef void (*callback_t
)(const struct mach_header
*mh
, intptr_t vmaddr_slide
);
1061 static void (*p
)(callback_t func
) = NULL
;
1064 _dyld_func_lookup("__dyld_register_func_for_add_image", (void**)&p
);
1069 * _dyld_register_func_for_remove_image registers the specified function to be
1070 * called when an image is removed (a bundle or a dynamic shared library) from
1074 _dyld_register_func_for_remove_image(
1075 void (*func
)(const struct mach_header
*mh
, intptr_t vmaddr_slide
))
1077 DYLD_LOCK_THIS_BLOCK
;
1078 typedef void (*callback_t
)(const struct mach_header
*mh
, intptr_t vmaddr_slide
);
1079 static void (*p
)(callback_t func
) = NULL
;
1082 _dyld_func_lookup("__dyld_register_func_for_remove_image", (void**)&p
);
1086 #if OBSOLETE_DYLD_API
1088 * _dyld_register_func_for_link_module registers the specified function to be
1089 * called when a module is bound into the program. When this function is first
1090 * registered it is called for once for each module that is currently bound into
1094 _dyld_register_func_for_link_module(
1095 void (*func
)(NSModule
module))
1097 DYLD_LOCK_THIS_BLOCK
;
1098 static void (*p
)(void (*func
)(NSModule
module)) = NULL
;
1101 _dyld_func_lookup("__dyld_register_func_for_link_module", (void**)&p
);
1106 * _dyld_register_func_for_unlink_module registers the specified function to be
1107 * called when a module is unbound from the program.
1110 _dyld_register_func_for_unlink_module(
1111 void (*func
)(NSModule
module))
1113 DYLD_LOCK_THIS_BLOCK
;
1114 static void (*p
)(void (*func
)(NSModule
module)) = NULL
;
1117 _dyld_func_lookup("__dyld_register_func_for_unlink_module", (void**)&p
);
1122 * _dyld_register_func_for_replace_module registers the specified function to be
1123 * called when a module is to be replace with another module in the program.
1126 _dyld_register_func_for_replace_module(
1127 void (*func
)(NSModule oldmodule
, NSModule newmodule
))
1129 DYLD_LOCK_THIS_BLOCK
;
1130 static void (*p
)(void (*func
)(NSModule oldmodule
,
1131 NSModule newmodule
)) = NULL
;
1134 _dyld_func_lookup("__dyld_register_func_for_replace_module", (void**)&p
);
1140 * _dyld_get_objc_module_sect_for_module is passed a module and sets a
1141 * pointer to the (__OBJC,__module) section and its size for the specified
1145 _dyld_get_objc_module_sect_for_module(
1148 unsigned long *size
)
1150 DYLD_LOCK_THIS_BLOCK
;
1151 static void (*p
)(NSModule
module,
1153 unsigned long *size
) = NULL
;
1156 _dyld_func_lookup("__dyld_get_objc_module_sect_for_module", (void**)&p
);
1157 p(module, objc_module
, size
);
1161 * _dyld_bind_objc_module() is passed a pointer to something in an (__OBJC,
1162 * __module) section and causes the module that is associated with that address
1166 _dyld_bind_objc_module(const void* objc_module
)
1168 DYLD_LOCK_THIS_BLOCK
;
1169 static void (*p
)(const void *objc_module
) = NULL
;
1172 _dyld_func_lookup("__dyld_bind_objc_module", (void**)&p
);
1177 #if DEPRECATED_APIS_SUPPORTED
1181 // this function exists for compatiblity only
1187 _dyld_image_count(void)
1189 DYLD_NO_LOCK_THIS_BLOCK
;
1190 static uint32_t (*p
)(void) = NULL
;
1193 _dyld_func_lookup("__dyld_image_count", (void**)&p
);
1197 const struct mach_header
*
1198 _dyld_get_image_header(uint32_t image_index
)
1200 DYLD_NO_LOCK_THIS_BLOCK
;
1201 static struct mach_header
* (*p
)(uint32_t image_index
) = NULL
;
1204 _dyld_func_lookup("__dyld_get_image_header", (void**)&p
);
1205 return(p(image_index
));
1209 _dyld_get_image_vmaddr_slide(uint32_t image_index
)
1211 DYLD_NO_LOCK_THIS_BLOCK
;
1212 static unsigned long (*p
)(uint32_t image_index
) = NULL
;
1215 _dyld_func_lookup("__dyld_get_image_vmaddr_slide", (void**)&p
);
1216 return(p(image_index
));
1220 _dyld_get_image_name(uint32_t image_index
)
1222 DYLD_NO_LOCK_THIS_BLOCK
;
1223 static const char* (*p
)(uint32_t image_index
) = NULL
;
1226 _dyld_func_lookup("__dyld_get_image_name", (void**)&p
);
1227 return(p(image_index
));
1230 // SPI in Mac OS X 10.6
1231 intptr_t _dyld_get_image_slide(const struct mach_header
* mh
)
1233 DYLD_NO_LOCK_THIS_BLOCK
;
1234 static intptr_t (*p
)(const struct mach_header
*) = NULL
;
1237 _dyld_func_lookup("__dyld_get_image_slide", (void**)&p
);
1243 _dyld_image_containing_address(const void* address
)
1245 DYLD_LOCK_THIS_BLOCK
;
1246 static bool (*p
)(const void*) = NULL
;
1249 _dyld_func_lookup("__dyld_image_containing_address", (void**)&p
);
1253 const struct mach_header
*
1254 _dyld_get_image_header_containing_address(
1255 const void* address
)
1257 DYLD_LOCK_THIS_BLOCK
;
1258 static const struct mach_header
* (*p
)(const void*) = NULL
;
1261 _dyld_func_lookup("__dyld_get_image_header_containing_address", (void**)&p
);
1266 #if DEPRECATED_APIS_SUPPORTED
1267 bool _dyld_launched_prebound(void)
1269 DYLD_LOCK_THIS_BLOCK
;
1270 static bool (*p
)(void) = NULL
;
1273 _dyld_func_lookup("__dyld_launched_prebound", (void**)&p
);
1277 bool _dyld_all_twolevel_modules_prebound(void)
1279 DYLD_LOCK_THIS_BLOCK
;
1280 static bool (*p
)(void) = NULL
;
1283 _dyld_func_lookup("__dyld_all_twolevel_modules_prebound", (void**)&p
);
1286 #endif // DEPRECATED_APIS_SUPPORTED
1291 #include <pthread.h>
1293 #include <mach-o/dyld.h>
1294 #include <servers/bootstrap.h>
1295 #include "dyldLibSystemInterface.h"
1298 // pthread key used to access per-thread dlerror message
1299 static pthread_key_t dlerrorPerThreadKey
;
1300 static bool dlerrorPerThreadKeyInitialized
= false;
1302 // data kept per-thread
1303 struct dlerrorPerThreadData
1305 size_t sizeAllocated
;
1309 // function called by dyld to get buffer to store dlerror message
1310 static char* getPerThreadBufferFor_dlerror(size_t sizeRequired
)
1312 // ok to create key lazily because this function is called within dyld lock, so there is no race condition
1313 if (!dlerrorPerThreadKeyInitialized
) {
1314 // create key and tell pthread package to call free() on any data associated with key if thread dies
1315 pthread_key_create(&dlerrorPerThreadKey
, &free
);
1316 dlerrorPerThreadKeyInitialized
= true;
1319 const size_t size
= (sizeRequired
< 256) ? 256 : sizeRequired
;
1320 dlerrorPerThreadData
* data
= (dlerrorPerThreadData
*)pthread_getspecific(dlerrorPerThreadKey
);
1321 if ( data
== NULL
) {
1322 //int mallocSize = offsetof(dlerrorPerThreadData, message[size]);
1323 const size_t mallocSize
= sizeof(dlerrorPerThreadData
)+size
;
1324 data
= (dlerrorPerThreadData
*)malloc(mallocSize
);
1325 data
->sizeAllocated
= size
;
1326 pthread_setspecific(dlerrorPerThreadKey
, data
);
1328 else if ( data
->sizeAllocated
< sizeRequired
) {
1330 //int mallocSize = offsetof(dlerrorPerThreadData, message[size]);
1331 const size_t mallocSize
= sizeof(dlerrorPerThreadData
)+size
;
1332 data
= (dlerrorPerThreadData
*)malloc(mallocSize
);
1333 data
->sizeAllocated
= size
;
1334 pthread_setspecific(dlerrorPerThreadKey
, data
);
1336 return data
->message
;
1339 // <rdar://problem/10595338> dlerror buffer leak
1340 // Only allocate buffer if an actual error message needs to be set
1341 static bool hasPerThreadBufferFor_dlerror()
1343 if (!dlerrorPerThreadKeyInitialized
)
1346 return (pthread_getspecific(dlerrorPerThreadKey
) != NULL
);
1349 // use non-lazy pointer to vproc_swap_integer so that lazy binding does not recurse
1350 typedef vproc_err_t (*vswapproc
)(vproc_t vp
, vproc_gsk_t key
,int64_t *inval
, int64_t *outval
);
1351 static vswapproc swapProc
= &vproc_swap_integer
;
1353 static bool isLaunchdOwned() {
1354 static bool first
= true;
1358 (*swapProc
)(NULL
, VPROC_GSK_IS_MANAGED
, NULL
, &val
);
1359 result
= ( val
!= 0 );
1366 #if DYLD_SHARED_CACHE_SUPPORT
1367 static void shared_cache_missing()
1369 // leave until dyld's that might call this are rare
1372 static void shared_cache_out_of_date()
1374 // leave until dyld's that might call this are rare
1376 #endif // DYLD_SHARED_CACHE_SUPPORT
1379 // the table passed to dyld containing thread helpers
1380 static dyld::LibSystemHelpers sHelpers
= { 13, &dyldGlobalLockAcquire
, &dyldGlobalLockRelease
,
1381 &getPerThreadBufferFor_dlerror
, &malloc
, &free
, &__cxa_atexit
,
1382 #if DYLD_SHARED_CACHE_SUPPORT
1383 &shared_cache_missing
, &shared_cache_out_of_date
,
1388 &pthread_key_create
, &pthread_setspecific
,
1390 &pthread_getspecific
,
1393 &hasPerThreadBufferFor_dlerror
,
1397 &__cxa_finalize_ranges
};
1401 // during initialization of libSystem this routine will run
1402 // and call dyld, registering the helper functions.
1404 extern "C" void tlv_initializer();
1405 extern "C" void _dyld_initializer();
1406 void _dyld_initializer()
1408 void (*p
)(dyld::LibSystemHelpers
*);
1410 _dyld_func_lookup("__dyld_register_thread_helpers", (void**)&p
);
1420 DYLD_LOCK_THIS_BLOCK
;
1421 static char* (*p
)() = NULL
;
1424 _dyld_func_lookup("__dyld_dlerror", (void**)&p
);
1428 int dladdr(const void* addr
, Dl_info
* info
)
1430 DYLD_LOCK_THIS_BLOCK
;
1431 static int (*p
)(const void* , Dl_info
*) = NULL
;
1434 _dyld_func_lookup("__dyld_dladdr", (void**)&p
);
1435 return(p(addr
, info
));
1438 int dlclose(void* handle
)
1440 DYLD_LOCK_THIS_BLOCK
;
1441 static int (*p
)(void* handle
) = NULL
;
1444 _dyld_func_lookup("__dyld_dlclose", (void**)&p
);
1448 void* dlopen(const char* path
, int mode
)
1450 // dlopen is special. locking is done inside dyld to allow initializer to run without lock
1451 DYLD_NO_LOCK_THIS_BLOCK
;
1453 static void* (*p
)(const char* path
, int) = NULL
;
1456 _dyld_func_lookup("__dyld_dlopen", (void**)&p
);
1457 void* result
= p(path
, mode
);
1458 // use asm block to prevent tail call optimization
1459 // this is needed because dlopen uses __builtin_return_address() and depends on this glue being in the frame chain
1460 // <rdar://problem/5313172 dlopen() looks too far up stack, can cause crash>
1461 __asm__
volatile("");
1466 bool dlopen_preflight(const char* path
)
1468 DYLD_LOCK_THIS_BLOCK
;
1469 static bool (*p
)(const char* path
) = NULL
;
1472 _dyld_func_lookup("__dyld_dlopen_preflight", (void**)&p
);
1476 void* dlsym(void* handle
, const char* symbol
)
1478 DYLD_LOCK_THIS_BLOCK
;
1479 static void* (*p
)(void* handle
, const char* symbol
) = NULL
;
1482 _dyld_func_lookup("__dyld_dlsym", (void**)&p
);
1483 return(p(handle
, symbol
));
1486 void dyld_register_image_state_change_handler(dyld_image_states state
,
1487 bool batch
, dyld_image_state_change_handler handler
)
1489 DYLD_LOCK_THIS_BLOCK
;
1490 static void* (*p
)(dyld_image_states
, bool, dyld_image_state_change_handler
) = NULL
;
1493 _dyld_func_lookup("__dyld_dyld_register_image_state_change_handler", (void**)&p
);
1494 p(state
, batch
, handler
);
1498 const struct dyld_all_image_infos
* _dyld_get_all_image_infos()
1500 DYLD_NO_LOCK_THIS_BLOCK
;
1501 static struct dyld_all_image_infos
* (*p
)() = NULL
;
1504 _dyld_func_lookup("__dyld_get_all_image_infos", (void**)&p
);
1508 #if SUPPORT_ZERO_COST_EXCEPTIONS
1509 bool _dyld_find_unwind_sections(void* addr
, dyld_unwind_sections
* info
)
1511 DYLD_NO_LOCK_THIS_BLOCK
;
1512 static void* (*p
)(void*, dyld_unwind_sections
*) = NULL
;
1515 _dyld_func_lookup("__dyld_find_unwind_sections", (void**)&p
);
1516 return p(addr
, info
);
1521 #if __i386__ || __x86_64__ || __arm__ || __arm64__
1522 __attribute__((visibility("hidden")))
1523 void* _dyld_fast_stub_entry(void* loadercache
, long lazyinfo
)
1525 DYLD_NO_LOCK_THIS_BLOCK
;
1526 static void* (*p
)(void*, long) = NULL
;
1529 _dyld_func_lookup("__dyld_fast_stub_entry", (void**)&p
);
1530 return p(loadercache
, lazyinfo
);
1535 const char* dyld_image_path_containing_address(const void* addr
)
1537 DYLD_NO_LOCK_THIS_BLOCK
;
1538 static const char* (*p
)(const void*) = NULL
;
1541 _dyld_func_lookup("__dyld_image_path_containing_address", (void**)&p
);
1545 const struct mach_header
* dyld_image_header_containing_address(const void* addr
)
1547 DYLD_NO_LOCK_THIS_BLOCK
;
1548 static const mach_header
* (*p
)(const void*) = NULL
;
1551 _dyld_func_lookup("__dyld_get_image_header_containing_address", (void**)&p
);
1556 bool dyld_shared_cache_some_image_overridden()
1558 DYLD_NO_LOCK_THIS_BLOCK
;
1559 static bool (*p
)() = NULL
;
1562 _dyld_func_lookup("__dyld_shared_cache_some_image_overridden", (void**)&p
);
1567 bool dyld_process_is_restricted()
1569 DYLD_NO_LOCK_THIS_BLOCK
;
1570 static bool (*p
)() = NULL
;
1573 _dyld_func_lookup("__dyld_process_is_restricted", (void**)&p
);
1577 #if DYLD_SHARED_CACHE_SUPPORT
1578 const char* dyld_shared_cache_file_path()
1580 DYLD_NO_LOCK_THIS_BLOCK
;
1581 static const char* (*p
)() = NULL
;
1584 _dyld_func_lookup("__dyld_shared_cache_file_path", (void**)&p
);
1589 void dyld_dynamic_interpose(const struct mach_header
* mh
, const struct dyld_interpose_tuple array
[], size_t count
)
1591 DYLD_LOCK_THIS_BLOCK
;
1592 static void (*p
)(const struct mach_header
* mh
, const struct dyld_interpose_tuple array
[], size_t count
) = NULL
;
1595 _dyld_func_lookup("__dyld_dynamic_interpose", (void**)&p
);
1596 p(mh
, array
, count
);
1600 // SPI called __fork
1601 void _dyld_fork_child()
1603 DYLD_NO_LOCK_THIS_BLOCK
;
1604 static void (*p
)() = NULL
;
1607 _dyld_func_lookup("__dyld_fork_child", (void**)&p
);