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@
27 #include <malloc/malloc.h>
29 #include <crt_externs.h>
30 #include <Availability.h>
32 #include "mach-o/dyld.h"
33 #include "mach-o/dyld_priv.h"
37 extern "C" int __cxa_atexit(void (*func
)(void *), void *arg
, void *dso
);
38 extern "C" void __cxa_finalize(const void *dso
);
41 #ifndef LC_VERSION_MIN_MACOSX
42 #define LC_VERSION_MIN_MACOSX 0x24
43 struct version_min_command
{
44 uint32_t cmd
; /* LC_VERSION_MIN_MACOSX or
45 LC_VERSION_MIN_IPHONEOS */
46 uint32_t cmdsize
; /* sizeof(struct min_version_command) */
47 uint32_t version
; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */
48 uint32_t sdk
; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */
52 #ifndef LC_VERSION_MIN_IPHONEOS
53 #define LC_VERSION_MIN_IPHONEOS 0x25
57 #ifndef LC_LOAD_UPWARD_DYLIB
58 #define LC_LOAD_UPWARD_DYLIB (0x23|LC_REQ_DYLD) /* load of dylib whose initializers run later */
61 #define DYLD_SHARED_CACHE_SUPPORT (__i386__ || __x86_64__ || __arm__)
63 // deprecated APIs are still availble on Mac OS X, but not on iPhone OS
64 #if __IPHONE_OS_VERSION_MIN_REQUIRED
65 #define DEPRECATED_APIS_SUPPORTED 0
67 #define DEPRECATED_APIS_SUPPORTED 1
71 * names_match() takes an install_name from an LC_LOAD_DYLIB command and a
72 * libraryName (which is -lx or -framework Foo argument passed to the static
73 * link editor for the same library) and determines if they match. This depends
74 * on conventional use of names including major versioning.
80 const char* libraryName
)
86 * Conventional install names have these forms:
87 * /System/Library/Frameworks/AppKit.framework/Versions/A/Appkit
88 * /Local/Library/Frameworks/AppKit.framework/Appkit
89 * /lib/libsys_s.A.dylib
90 * /usr/lib/libsys_s.dylib
92 basename
= strrchr(install_name
, '/');
94 basename
= install_name
;
99 * By checking the base name matching the library name we take care
100 * of the -framework cases.
102 if(strcmp(basename
, libraryName
) == 0)
106 * Now check the base name for "lib" if so proceed to check for the
107 * -lx case dealing with a possible .X.dylib and a .dylib extension.
109 if(strncmp(basename
, "lib", 3) ==0){
110 n
= strlen(libraryName
);
111 if(strncmp(basename
+3, libraryName
, n
) == 0){
112 if(strncmp(basename
+3+n
, ".dylib", 6) == 0)
114 if(basename
[3+n
] == '.' &&
115 basename
[3+n
+1] != '\0' &&
116 strncmp(basename
+3+n
+2, ".dylib", 6) == 0)
123 #if DEPRECATED_APIS_SUPPORTED
125 void NSInstallLinkEditErrorHandlers(
126 const NSLinkEditErrorHandlers
* handlers
)
128 DYLD_LOCK_THIS_BLOCK
;
129 typedef void (*ucallback_t
)(const char* symbol_name
);
130 typedef NSModule (*mcallback_t
)(NSSymbol s
, NSModule old
, NSModule newhandler
);
131 typedef void (*lcallback_t
)(NSLinkEditErrors c
, int errorNumber
,
132 const char* fileName
, const char* errorString
);
133 static void (*p
)(ucallback_t undefined
, mcallback_t multiple
, lcallback_t linkEdit
) = NULL
;
136 _dyld_func_lookup("__dyld_install_handlers", (void**)&p
);
137 mcallback_t m
= handlers
->multiple
;
138 p(handlers
->undefined
, m
, handlers
->linkEdit
);
145 DYLD_LOCK_THIS_BLOCK
;
146 static const char* (*p
)(NSModule
module) = NULL
;
149 _dyld_func_lookup("__dyld_NSNameOfModule", (void**)&p
);
154 NSLibraryNameForModule(
157 DYLD_LOCK_THIS_BLOCK
;
158 static const char* (*p
)(NSModule
module) = NULL
;
161 _dyld_func_lookup("__dyld_NSLibraryNameForModule", (void**)&p
);
166 NSIsSymbolNameDefined(
167 const char* symbolName
)
169 DYLD_LOCK_THIS_BLOCK
;
170 static bool (*p
)(const char* symbolName
) = NULL
;
173 _dyld_func_lookup("__dyld_NSIsSymbolNameDefined", (void**)&p
);
174 return(p(symbolName
));
178 NSIsSymbolNameDefinedWithHint(
179 const char* symbolName
,
180 const char* libraryNameHint
)
182 DYLD_LOCK_THIS_BLOCK
;
183 static bool (*p
)(const char* symbolName
,
184 const char* libraryNameHint
) = NULL
;
187 _dyld_func_lookup("__dyld_NSIsSymbolNameDefinedWithHint", (void**)&p
);
188 return(p(symbolName
, libraryNameHint
));
192 NSIsSymbolNameDefinedInImage(
193 const struct mach_header
*image
,
194 const char* symbolName
)
196 DYLD_LOCK_THIS_BLOCK
;
197 static bool (*p
)(const struct mach_header
*image
,
198 const char* symbolName
) = NULL
;
201 _dyld_func_lookup("__dyld_NSIsSymbolNameDefinedInImage", (void**)&p
);
202 return(p(image
, symbolName
));
206 NSLookupAndBindSymbol(
207 const char* symbolName
)
209 DYLD_LOCK_THIS_BLOCK
;
210 static NSSymbol (*p
)(const char* symbolName
) = NULL
;
213 _dyld_func_lookup("__dyld_NSLookupAndBindSymbol", (void**)&p
);
214 return(p(symbolName
));
218 NSLookupAndBindSymbolWithHint(
219 const char* symbolName
,
220 const char* libraryNameHint
)
222 DYLD_LOCK_THIS_BLOCK
;
223 static NSSymbol (*p
)(const char* symbolName
,
224 const char* libraryNameHint
) = NULL
;
227 _dyld_func_lookup("__dyld_NSLookupAndBindSymbolWithHint", (void**)&p
);
228 return(p(symbolName
, libraryNameHint
));
232 NSLookupSymbolInModule(
234 const char* symbolName
)
236 DYLD_LOCK_THIS_BLOCK
;
237 static NSSymbol (*p
)(NSModule
module, const char* symbolName
) = NULL
;
240 _dyld_func_lookup("__dyld_NSLookupSymbolInModule", (void**)&p
);
241 return(p(module, symbolName
));
245 NSLookupSymbolInImage(
246 const struct mach_header
*image
,
247 const char* symbolName
,
250 DYLD_LOCK_THIS_BLOCK
;
251 static NSSymbol (*p
)(const struct mach_header
*image
,
252 const char* symbolName
,
253 uint32_t options
) = NULL
;
256 _dyld_func_lookup("__dyld_NSLookupSymbolInImage", (void**)&p
);
257 return(p(image
, symbolName
, options
));
264 DYLD_LOCK_THIS_BLOCK
;
265 static char * (*p
)(NSSymbol symbol
) = NULL
;
268 _dyld_func_lookup("__dyld_NSNameOfSymbol",(void**)&p
);
276 DYLD_LOCK_THIS_BLOCK
;
277 static void * (*p
)(NSSymbol symbol
) = NULL
;
280 _dyld_func_lookup("__dyld_NSAddressOfSymbol", (void**)&p
);
288 DYLD_LOCK_THIS_BLOCK
;
289 static NSModule (*p
)(NSSymbol symbol
) = NULL
;
292 _dyld_func_lookup("__dyld_NSModuleForSymbol", (void**)&p
);
298 const char* pathName
)
300 DYLD_LOCK_THIS_BLOCK
;
301 static bool (*p
)(const char* pathName
) = NULL
;
304 _dyld_func_lookup("__dyld_NSAddLibrary", (void**)&p
);
309 NSAddLibraryWithSearching(
310 const char* pathName
)
312 DYLD_LOCK_THIS_BLOCK
;
313 static bool (*p
)(const char* pathName
) = NULL
;
316 _dyld_func_lookup("__dyld_NSAddLibraryWithSearching", (void**)&p
);
320 const struct mach_header
*
322 const char* image_name
,
325 DYLD_LOCK_THIS_BLOCK
;
326 static const struct mach_header
* (*p
)(const char* image_name
,
327 uint32_t options
) = NULL
;
330 _dyld_func_lookup("__dyld_NSAddImage", (void**)&p
);
331 return(p(image_name
, options
));
333 #endif // DEPRECATED_APIS_SUPPORTED
336 * This routine returns the current version of the named shared library the
337 * executable it was built with. The libraryName parameter is the same as the
338 * -lx or -framework Foo argument passed to the static link editor when building
339 * the executable (with -lx it would be "x" and with -framework Foo it would be
340 * "Foo"). If this the executable was not built against the specified library
341 * it returns -1. It should be noted that if this only returns the value the
342 * current version of the named shared library the executable was built with
343 * and not a list of current versions that dependent libraries and bundles the
344 * program is using were built with.
347 NSVersionOfLinkTimeLibrary(
348 const char* libraryName
)
351 struct load_command
*load_commands
, *lc
;
352 struct dylib_command
*dl
;
355 static struct mach_header_64
*mh
= NULL
;
357 static struct mach_header
*mh
= NULL
;
360 mh
= _NSGetMachExecuteHeader();
361 load_commands
= (struct load_command
*)
363 ((char *)mh
+ sizeof(struct mach_header_64
));
365 ((char *)mh
+ sizeof(struct mach_header
));
368 for(i
= 0; i
< mh
->ncmds
; i
++){
371 case LC_LOAD_WEAK_DYLIB
:
372 case LC_LOAD_UPWARD_DYLIB
:
373 dl
= (struct dylib_command
*)lc
;
374 install_name
= (char *)dl
+ dl
->dylib
.name
.offset
;
375 if(names_match(install_name
, libraryName
) == TRUE
)
376 return(dl
->dylib
.current_version
);
379 lc
= (struct load_command
*)((char *)lc
+ lc
->cmdsize
);
385 * This routine returns the current version of the named shared library the
386 * program it is running against. The libraryName parameter is the same as
387 * would be static link editor using the -lx or -framework Foo flags (with -lx
388 * it would be "x" and with -framework Foo it would be "Foo"). If the program
389 * is not using the specified library it returns -1.
392 NSVersionOfRunTimeLibrary(
393 const char* libraryName
)
395 unsigned long i
, j
, n
;
397 struct load_command
*load_commands
, *lc
;
398 struct dylib_command
*dl
;
399 const struct mach_header
*mh
;
401 n
= _dyld_image_count();
402 for(i
= 0; i
< n
; i
++){
403 mh
= _dyld_get_image_header(i
);
404 if(mh
->filetype
!= MH_DYLIB
)
406 load_commands
= (struct load_command
*)
408 ((char *)mh
+ sizeof(struct mach_header_64
));
410 ((char *)mh
+ sizeof(struct mach_header
));
413 for(j
= 0; j
< mh
->ncmds
; j
++){
414 if(lc
->cmd
== LC_ID_DYLIB
){
415 dl
= (struct dylib_command
*)lc
;
416 install_name
= (char *)dl
+ dl
->dylib
.name
.offset
;
417 if(names_match(install_name
, libraryName
) == TRUE
)
418 return(dl
->dylib
.current_version
);
420 lc
= (struct load_command
*)((char *)lc
+ lc
->cmdsize
);
428 * Returns the sdk version (encode as nibble XXXX.YY.ZZ) the
429 * specified binary was built against.
431 * First looks for LC_VERSION_MIN_MACOSX/LC_VERSION_MIN_IPHONEOS
432 * in binary and if sdk field is not zero, return that value.
433 * Otherwise, looks for the libSystem.B.dylib the binary linked
434 * against and uses a table to convert that to an sdk version.
436 uint32_t dyld_get_sdk_version(const mach_header
* mh
)
439 const load_command
* cmds
= (load_command
*)((char *)mh
+ sizeof(mach_header_64
));
441 const load_command
* cmds
= (load_command
*)((char *)mh
+ sizeof(mach_header
));
443 const version_min_command
* versCmd
;
444 const dylib_command
* dylibCmd
;
445 const load_command
* cmd
= cmds
;
446 uint32_t libSystemVers
= 0;
447 for(uint32_t i
= 0; i
< mh
->ncmds
; ++i
) {
448 switch ( cmd
->cmd
) {
449 case LC_VERSION_MIN_MACOSX
:
450 case LC_VERSION_MIN_IPHONEOS
:
451 versCmd
= (version_min_command
*)cmd
;
452 if ( versCmd
->sdk
!= 0 )
453 return versCmd
->sdk
; // found explicit SDK version
456 case LC_LOAD_WEAK_DYLIB
:
457 case LC_LOAD_UPWARD_DYLIB
:
458 dylibCmd
= (dylib_command
*)cmd
;
459 if ( strcmp((char*)dylibCmd
+ dylibCmd
->dylib
.name
.offset
, "/usr/lib/libSystem.B.dylib") == 0 )
460 libSystemVers
= dylibCmd
->dylib
.current_version
;
461 else if ( strcmp((char*)dylibCmd
+ dylibCmd
->dylib
.name
.offset
, "/usr/lib/libSystem.dylib") == 0 )
462 return 0x00040000; // all iOS simulator have same libSystem.dylib version
465 cmd
= (load_command
*)((char *)cmd
+ cmd
->cmdsize
);
468 if ( libSystemVers
!= 0 ) {
469 // found linked libSystem.B.dylib version linked against
470 #if __IPHONE_OS_VERSION_MIN_REQUIRED
471 // convert libSystem.B.dylib version to iOS sdk version
472 if ( libSystemVers
< 0x006F0010 ) // libSystem 111.0.16 in 3.0
473 return 0x00020000; // 2.0
474 else if ( libSystemVers
< 0x006F0201 ) // libSystem 111.2.1 in 3.1
475 return 0x00030000; // 3.0
476 else if ( libSystemVers
< 0x007D020B ) // libSystem 125.2.11 in 4.0
477 return 0x00030100; // 3.1
478 else if ( libSystemVers
< 0x007D0400 ) // libSystem 125.4 in 4.1 and in 4.2
479 return 0x00040000; // 4.0
480 else if ( libSystemVers
< 0x009F0000 ) // libSystem 159 in 4.3
481 return 0x00040100; // 4.1
482 else if ( libSystemVers
< 0x00A10000 ) // libSystem 161 in 5.0
483 return 0x00040300; // 4.3
487 // convert libSystem.B.dylib version to MacOSX sdk version
488 if ( libSystemVers
< 0x006F0000 ) // libSystem 111 in 10.5
489 return 0x000A0400; // 10.4
490 else if ( libSystemVers
< 0x007B0000 ) // libSystem 123 in 10.6
491 return 0x000A0500; // 10.5
492 else if ( libSystemVers
< 0x009F0000 ) // libSystem 159 in 10.7
493 return 0x000A0600; // 10.6
494 else if ( libSystemVers
< 0x00A10000 ) // libSystem 161 in 10.8
495 return 0x000A0700; // 10.7
497 return 0x000A0800; // 10.8
504 uint32_t dyld_get_program_sdk_version()
506 return dyld_get_sdk_version((mach_header
*)_NSGetMachExecuteHeader());
510 uint32_t dyld_get_min_os_version(const struct mach_header
* mh
)
513 const load_command
* cmds
= (load_command
*)((char *)mh
+ sizeof(mach_header_64
));
515 const load_command
* cmds
= (load_command
*)((char *)mh
+ sizeof(mach_header
));
517 const version_min_command
* versCmd
;
518 const load_command
* cmd
= cmds
;
519 for(uint32_t i
= 0; i
< mh
->ncmds
; ++i
) {
520 switch ( cmd
->cmd
) {
521 case LC_VERSION_MIN_MACOSX
:
522 case LC_VERSION_MIN_IPHONEOS
:
523 versCmd
= (version_min_command
*)cmd
;
524 return versCmd
->version
; // found explicit min OS version
527 cmd
= (load_command
*)((char *)cmd
+ cmd
->cmdsize
);
533 uint32_t dyld_get_program_min_os_version()
535 return dyld_get_min_os_version((mach_header
*)_NSGetMachExecuteHeader());
539 #if DEPRECATED_APIS_SUPPORTED
541 * NSCreateObjectFileImageFromFile() creates an NSObjectFileImage for the
542 * specified file name if the file is a correct Mach-O file that can be loaded
543 * with NSloadModule(). For return codes of NSObjectFileImageFailure and
544 * NSObjectFileImageFormat an error message is printed to stderr. All
545 * other codes cause no printing.
547 NSObjectFileImageReturnCode
548 NSCreateObjectFileImageFromFile(
549 const char* pathName
,
550 NSObjectFileImage
*objectFileImage
)
552 DYLD_LOCK_THIS_BLOCK
;
553 static NSObjectFileImageReturnCode (*p
)(const char*, NSObjectFileImage
*) = NULL
;
556 _dyld_func_lookup("__dyld_NSCreateObjectFileImageFromFile", (void**)&p
);
557 return p(pathName
, objectFileImage
);
562 * NSCreateObjectFileImageFromMemory() creates an NSObjectFileImage for the
563 * object file mapped into memory at address of size length if the object file
564 * is a correct Mach-O file that can be loaded with NSloadModule(). For return
565 * codes of NSObjectFileImageFailure and NSObjectFileImageFormat an error
566 * message is printed to stderr. All other codes cause no printing.
568 NSObjectFileImageReturnCode
569 NSCreateObjectFileImageFromMemory(
572 NSObjectFileImage
*objectFileImage
)
574 DYLD_LOCK_THIS_BLOCK
;
575 static NSObjectFileImageReturnCode (*p
)(const void*, size_t, NSObjectFileImage
*) = NULL
;
578 _dyld_func_lookup("__dyld_NSCreateObjectFileImageFromMemory", (void**)&p
);
579 return p(address
, size
, objectFileImage
);
582 #if OBSOLETE_DYLD_API
584 * NSCreateCoreFileImageFromFile() creates an NSObjectFileImage for the
585 * specified core file name if the file is a correct Mach-O core file.
586 * For return codes of NSObjectFileImageFailure and NSObjectFileImageFormat
587 * an error message is printed to stderr. All other codes cause no printing.
589 NSObjectFileImageReturnCode
590 NSCreateCoreFileImageFromFile(
591 const char* pathName
,
592 NSObjectFileImage
*objectFileImage
)
594 DYLD_LOCK_THIS_BLOCK
;
595 static NSObjectFileImageReturnCode (*p
)(const char*, NSObjectFileImage
*) = NULL
;
598 _dyld_func_lookup("__dyld_NSCreateCoreFileImageFromFile", (void**)&p
);
599 return p(pathName
, objectFileImage
);
604 NSDestroyObjectFileImage(
605 NSObjectFileImage objectFileImage
)
607 DYLD_LOCK_THIS_BLOCK
;
608 static bool (*p
)(NSObjectFileImage
) = NULL
;
611 _dyld_func_lookup("__dyld_NSDestroyObjectFileImage", (void**)&p
);
612 return p(objectFileImage
);
618 NSObjectFileImage objectFileImage
,
619 const char* moduleName
,
622 DYLD_LOCK_THIS_BLOCK
;
623 static NSModule (*p
)(NSObjectFileImage
, const char*, unsigned long) = NULL
;
626 _dyld_func_lookup("__dyld_NSLinkModule", (void**)&p
);
628 return p(objectFileImage
, moduleName
, options
);
635 * NSSymbolDefinitionCountInObjectFileImage() returns the number of symbol
636 * definitions in the NSObjectFileImage.
639 NSSymbolDefinitionCountInObjectFileImage(
640 NSObjectFileImage objectFileImage
)
642 DYLD_LOCK_THIS_BLOCK
;
643 static unsigned long (*p
)(NSObjectFileImage
) = NULL
;
646 _dyld_func_lookup("__dyld_NSSymbolDefinitionCountInObjectFileImage", (void**)&p
);
648 return p(objectFileImage
);
652 * NSSymbolDefinitionNameInObjectFileImage() returns the name of the i'th
653 * symbol definitions in the NSObjectFileImage. If the ordinal specified is
654 * outside the range [0..NSSymbolDefinitionCountInObjectFileImage], NULL will
658 NSSymbolDefinitionNameInObjectFileImage(
659 NSObjectFileImage objectFileImage
,
662 DYLD_LOCK_THIS_BLOCK
;
663 static const char* (*p
)(NSObjectFileImage
, uint32_t) = NULL
;
666 _dyld_func_lookup("__dyld_NSSymbolDefinitionNameInObjectFileImage", (void**)&p
);
668 return p(objectFileImage
, ordinal
);
672 * NSSymbolReferenceCountInObjectFileImage() returns the number of references
673 * to undefined symbols the NSObjectFileImage.
676 NSSymbolReferenceCountInObjectFileImage(
677 NSObjectFileImage objectFileImage
)
679 DYLD_LOCK_THIS_BLOCK
;
680 static unsigned long (*p
)(NSObjectFileImage
) = NULL
;
683 _dyld_func_lookup("__dyld_NSSymbolReferenceCountInObjectFileImage", (void**)&p
);
685 return p(objectFileImage
);
689 * NSSymbolReferenceNameInObjectFileImage() returns the name of the i'th
690 * undefined symbol in the NSObjectFileImage. If the ordinal specified is
691 * outside the range [0..NSSymbolReferenceCountInObjectFileImage], NULL will be
695 NSSymbolReferenceNameInObjectFileImage(
696 NSObjectFileImage objectFileImage
,
698 bool *tentative_definition
) /* can be NULL */
700 DYLD_LOCK_THIS_BLOCK
;
701 static const char* (*p
)(NSObjectFileImage
, uint32_t, bool*) = NULL
;
704 _dyld_func_lookup("__dyld_NSSymbolReferenceNameInObjectFileImage", (void**)&p
);
706 return p(objectFileImage
, ordinal
, tentative_definition
);
710 * NSIsSymbolDefinedInObjectFileImage() returns TRUE if the specified symbol
711 * name has a definition in the NSObjectFileImage and FALSE otherwise.
714 NSIsSymbolDefinedInObjectFileImage(
715 NSObjectFileImage objectFileImage
,
716 const char* symbolName
)
718 DYLD_LOCK_THIS_BLOCK
;
719 static bool (*p
)(NSObjectFileImage
, const char*) = NULL
;
722 _dyld_func_lookup("__dyld_NSIsSymbolDefinedInObjectFileImage", (void**)&p
);
724 return p(objectFileImage
, symbolName
);
728 * NSGetSectionDataInObjectFileImage() returns a pointer to the section contents
729 * in the NSObjectFileImage for the specified segmentName and sectionName if
730 * it exists and it is not a zerofill section. If not it returns NULL. If
731 * the parameter size is not NULL the size of the section is also returned
732 * indirectly through that pointer.
735 NSGetSectionDataInObjectFileImage(
736 NSObjectFileImage objectFileImage
,
737 const char* segmentName
,
738 const char* sectionName
,
739 unsigned long *size
) /* can be NULL */
741 DYLD_LOCK_THIS_BLOCK
;
742 static void* (*p
)(NSObjectFileImage
, const char*, const char*, unsigned long*) = NULL
;
745 _dyld_func_lookup("__dyld_NSGetSectionDataInObjectFileImage", (void**)&p
);
747 return p(objectFileImage
, segmentName
, sectionName
, size
);
755 const char* *fileName
,
756 const char* *errorString
)
758 DYLD_LOCK_THIS_BLOCK
;
759 static void (*p
)(NSLinkEditErrors
*c
,
761 const char* *fileName
,
762 const char* *errorString
) = NULL
;
765 _dyld_func_lookup("__dyld_link_edit_error", (void**)&p
);
767 p(c
, errorNumber
, fileName
, errorString
);
775 DYLD_LOCK_THIS_BLOCK
;
776 static bool (*p
)(NSModule
module, uint32_t options
) = NULL
;
779 _dyld_func_lookup("__dyld_unlink_module", (void**)&p
);
781 return p(module, options
);
784 #if OBSOLETE_DYLD_API
787 NSModule moduleToReplace
,
788 NSObjectFileImage newObjectFileImage
,
796 #endif // DEPRECATED_APIS_SUPPORTED
799 *_NSGetExecutablePath copies the path of the executable into the buffer and
800 * returns 0 if the path was successfully copied in the provided buffer. If the
801 * buffer is not large enough, -1 is returned and the expected buffer size is
802 * copied in *bufsize. Note that _NSGetExecutablePath will return "a path" to
803 * the executable not a "real path" to the executable. That is the path may be
804 * a symbolic link and not the real file. And with deep directories the total
805 * bufsize needed could be more than MAXPATHLEN.
808 _NSGetExecutablePath(
812 DYLD_LOCK_THIS_BLOCK
;
813 static int (*p
)(char *buf
, uint32_t *bufsize
) = NULL
;
816 _dyld_func_lookup("__dyld__NSGetExecutablePath", (void**)&p
);
817 return(p(buf
, bufsize
));
820 #if DEPRECATED_APIS_SUPPORTED
822 _dyld_lookup_and_bind(
823 const char* symbol_name
,
827 DYLD_LOCK_THIS_BLOCK
;
828 static void (*p
)(const char*, void** , NSModule
*) = NULL
;
831 _dyld_func_lookup("__dyld_lookup_and_bind", (void**)&p
);
832 p(symbol_name
, address
, module);
836 _dyld_lookup_and_bind_with_hint(
837 const char* symbol_name
,
838 const char* library_name_hint
,
842 DYLD_LOCK_THIS_BLOCK
;
843 static void (*p
)(const char*, const char*, void**, NSModule
*) = NULL
;
846 _dyld_func_lookup("__dyld_lookup_and_bind_with_hint", (void**)&p
);
847 p(symbol_name
, library_name_hint
, address
, module);
850 #if OBSOLETE_DYLD_API
852 _dyld_lookup_and_bind_objc(
853 const char* symbol_name
,
857 DYLD_LOCK_THIS_BLOCK
;
858 static void (*p
)(const char* , void**, NSModule
*) = NULL
;
861 _dyld_func_lookup("__dyld_lookup_and_bind_objc", (void**)&p
);
862 p(symbol_name
, address
, module);
867 _dyld_lookup_and_bind_fully(
868 const char* symbol_name
,
872 DYLD_LOCK_THIS_BLOCK
;
873 static void (*p
)(const char*, void**, NSModule
*) = NULL
;
876 _dyld_func_lookup("__dyld_lookup_and_bind_fully", (void**)&p
);
877 p(symbol_name
, address
, module);
881 _dyld_bind_fully_image_containing_address(
884 DYLD_LOCK_THIS_BLOCK
;
885 static bool (*p
)(const void*) = NULL
;
888 _dyld_func_lookup("__dyld_bind_fully_image_containing_address", (void**)&p
);
891 #endif // DEPRECATED_APIS_SUPPORTED
895 * _dyld_register_func_for_add_image registers the specified function to be
896 * called when a new image is added (a bundle or a dynamic shared library) to
897 * the program. When this function is first registered it is called for once
898 * for each image that is currently part of the program.
901 _dyld_register_func_for_add_image(
902 void (*func
)(const struct mach_header
*mh
, intptr_t vmaddr_slide
))
904 DYLD_LOCK_THIS_BLOCK
;
905 typedef void (*callback_t
)(const struct mach_header
*mh
, intptr_t vmaddr_slide
);
906 static void (*p
)(callback_t func
) = NULL
;
909 _dyld_func_lookup("__dyld_register_func_for_add_image", (void**)&p
);
914 * _dyld_register_func_for_remove_image registers the specified function to be
915 * called when an image is removed (a bundle or a dynamic shared library) from
919 _dyld_register_func_for_remove_image(
920 void (*func
)(const struct mach_header
*mh
, intptr_t vmaddr_slide
))
922 DYLD_LOCK_THIS_BLOCK
;
923 typedef void (*callback_t
)(const struct mach_header
*mh
, intptr_t vmaddr_slide
);
924 static void (*p
)(callback_t func
) = NULL
;
927 _dyld_func_lookup("__dyld_register_func_for_remove_image", (void**)&p
);
931 #if OBSOLETE_DYLD_API
933 * _dyld_register_func_for_link_module registers the specified function to be
934 * called when a module is bound into the program. When this function is first
935 * registered it is called for once for each module that is currently bound into
939 _dyld_register_func_for_link_module(
940 void (*func
)(NSModule
module))
942 DYLD_LOCK_THIS_BLOCK
;
943 static void (*p
)(void (*func
)(NSModule
module)) = NULL
;
946 _dyld_func_lookup("__dyld_register_func_for_link_module", (void**)&p
);
951 * _dyld_register_func_for_unlink_module registers the specified function to be
952 * called when a module is unbound from the program.
955 _dyld_register_func_for_unlink_module(
956 void (*func
)(NSModule
module))
958 DYLD_LOCK_THIS_BLOCK
;
959 static void (*p
)(void (*func
)(NSModule
module)) = NULL
;
962 _dyld_func_lookup("__dyld_register_func_for_unlink_module", (void**)&p
);
967 * _dyld_register_func_for_replace_module registers the specified function to be
968 * called when a module is to be replace with another module in the program.
971 _dyld_register_func_for_replace_module(
972 void (*func
)(NSModule oldmodule
, NSModule newmodule
))
974 DYLD_LOCK_THIS_BLOCK
;
975 static void (*p
)(void (*func
)(NSModule oldmodule
,
976 NSModule newmodule
)) = NULL
;
979 _dyld_func_lookup("__dyld_register_func_for_replace_module", (void**)&p
);
985 * _dyld_get_objc_module_sect_for_module is passed a module and sets a
986 * pointer to the (__OBJC,__module) section and its size for the specified
990 _dyld_get_objc_module_sect_for_module(
995 DYLD_LOCK_THIS_BLOCK
;
996 static void (*p
)(NSModule
module,
998 unsigned long *size
) = NULL
;
1001 _dyld_func_lookup("__dyld_get_objc_module_sect_for_module", (void**)&p
);
1002 p(module, objc_module
, size
);
1006 * _dyld_bind_objc_module() is passed a pointer to something in an (__OBJC,
1007 * __module) section and causes the module that is associated with that address
1011 _dyld_bind_objc_module(const void* objc_module
)
1013 DYLD_LOCK_THIS_BLOCK
;
1014 static void (*p
)(const void *objc_module
) = NULL
;
1017 _dyld_func_lookup("__dyld_bind_objc_module", (void**)&p
);
1022 #if DEPRECATED_APIS_SUPPORTED
1026 // this function exists for compatiblity only
1032 _dyld_image_count(void)
1034 DYLD_NO_LOCK_THIS_BLOCK
;
1035 static unsigned long (*p
)(void) = NULL
;
1038 _dyld_func_lookup("__dyld_image_count", (void**)&p
);
1042 const struct mach_header
*
1043 _dyld_get_image_header(uint32_t image_index
)
1045 DYLD_NO_LOCK_THIS_BLOCK
;
1046 static struct mach_header
* (*p
)(uint32_t image_index
) = NULL
;
1049 _dyld_func_lookup("__dyld_get_image_header", (void**)&p
);
1050 return(p(image_index
));
1054 _dyld_get_image_vmaddr_slide(uint32_t image_index
)
1056 DYLD_NO_LOCK_THIS_BLOCK
;
1057 static unsigned long (*p
)(uint32_t image_index
) = NULL
;
1060 _dyld_func_lookup("__dyld_get_image_vmaddr_slide", (void**)&p
);
1061 return(p(image_index
));
1065 _dyld_get_image_name(uint32_t image_index
)
1067 DYLD_NO_LOCK_THIS_BLOCK
;
1068 static const char* (*p
)(uint32_t image_index
) = NULL
;
1071 _dyld_func_lookup("__dyld_get_image_name", (void**)&p
);
1072 return(p(image_index
));
1075 // SPI in Mac OS X 10.6
1076 intptr_t _dyld_get_image_slide(const struct mach_header
* mh
)
1078 DYLD_NO_LOCK_THIS_BLOCK
;
1079 static intptr_t (*p
)(const struct mach_header
*) = NULL
;
1082 _dyld_func_lookup("__dyld_get_image_slide", (void**)&p
);
1088 _dyld_image_containing_address(const void* address
)
1090 DYLD_LOCK_THIS_BLOCK
;
1091 static bool (*p
)(const void*) = NULL
;
1094 _dyld_func_lookup("__dyld_image_containing_address", (void**)&p
);
1098 const struct mach_header
*
1099 _dyld_get_image_header_containing_address(
1100 const void* address
)
1102 DYLD_LOCK_THIS_BLOCK
;
1103 static const struct mach_header
* (*p
)(const void*) = NULL
;
1106 _dyld_func_lookup("__dyld_get_image_header_containing_address", (void**)&p
);
1111 void (*monaddition
)(char *lowpc
, char *highpc
))
1113 DYLD_LOCK_THIS_BLOCK
;
1114 typedef void (*monproc
)(char *lowpc
, char *highpc
);
1115 static void (*p
)(monproc monaddition
) = NULL
;
1118 _dyld_func_lookup("__dyld_moninit", (void**)&p
);
1122 #if DEPRECATED_APIS_SUPPORTED
1123 bool _dyld_launched_prebound(void)
1125 DYLD_LOCK_THIS_BLOCK
;
1126 static bool (*p
)(void) = NULL
;
1129 _dyld_func_lookup("__dyld_launched_prebound", (void**)&p
);
1133 bool _dyld_all_twolevel_modules_prebound(void)
1135 DYLD_LOCK_THIS_BLOCK
;
1136 static bool (*p
)(void) = NULL
;
1139 _dyld_func_lookup("__dyld_all_twolevel_modules_prebound", (void**)&p
);
1142 #endif // DEPRECATED_APIS_SUPPORTED
1147 #include <pthread.h>
1149 #include <mach-o/dyld.h>
1150 #include <servers/bootstrap.h>
1151 #include "dyldLibSystemInterface.h"
1154 // pthread key used to access per-thread dlerror message
1155 static pthread_key_t dlerrorPerThreadKey
;
1156 static bool dlerrorPerThreadKeyInitialized
= false;
1158 // data kept per-thread
1159 struct dlerrorPerThreadData
1161 uint32_t sizeAllocated
;
1165 // function called by dyld to get buffer to store dlerror message
1166 static char* getPerThreadBufferFor_dlerror(uint32_t sizeRequired
)
1168 // ok to create key lazily because this function is called within dyld lock, so there is no race condition
1169 if (!dlerrorPerThreadKeyInitialized
) {
1170 // create key and tell pthread package to call free() on any data associated with key if thread dies
1171 pthread_key_create(&dlerrorPerThreadKey
, &free
);
1172 dlerrorPerThreadKeyInitialized
= true;
1175 const int size
= (sizeRequired
< 256) ? 256 : sizeRequired
;
1176 dlerrorPerThreadData
* data
= (dlerrorPerThreadData
*)pthread_getspecific(dlerrorPerThreadKey
);
1177 if ( data
== NULL
) {
1178 //int mallocSize = offsetof(dlerrorPerThreadData, message[size]);
1179 const int mallocSize
= sizeof(dlerrorPerThreadData
)+size
;
1180 data
= (dlerrorPerThreadData
*)malloc(mallocSize
);
1181 data
->sizeAllocated
= size
;
1182 pthread_setspecific(dlerrorPerThreadKey
, data
);
1184 else if ( data
->sizeAllocated
< sizeRequired
) {
1186 //int mallocSize = offsetof(dlerrorPerThreadData, message[size]);
1187 const int mallocSize
= sizeof(dlerrorPerThreadData
)+size
;
1188 data
= (dlerrorPerThreadData
*)malloc(mallocSize
);
1189 data
->sizeAllocated
= size
;
1190 pthread_setspecific(dlerrorPerThreadKey
, data
);
1192 return data
->message
;
1196 #if DYLD_SHARED_CACHE_SUPPORT
1197 static void shared_cache_missing()
1199 // leave until dyld's that might call this are rare
1202 static void shared_cache_out_of_date()
1204 // leave until dyld's that might call this are rare
1206 #endif // DYLD_SHARED_CACHE_SUPPORT
1210 // the table passed to dyld containing thread helpers
1211 static dyld::LibSystemHelpers sHelpers
= { 9, &dyldGlobalLockAcquire
, &dyldGlobalLockRelease
,
1212 &getPerThreadBufferFor_dlerror
, &malloc
, &free
, &__cxa_atexit
,
1213 #if DYLD_SHARED_CACHE_SUPPORT
1214 &shared_cache_missing
, &shared_cache_out_of_date
,
1219 &pthread_key_create
, &pthread_setspecific
,
1221 &pthread_getspecific
,
1227 // during initialization of libSystem this routine will run
1228 // and call dyld, registering the helper functions.
1230 extern "C" void tlv_initializer();
1231 extern "C" void _dyld_initializer();
1232 void _dyld_initializer()
1234 DYLD_LOCK_INITIALIZER
;
1236 void (*p
)(dyld::LibSystemHelpers
*);
1238 _dyld_func_lookup("__dyld_register_thread_helpers", (void**)&p
);
1248 DYLD_LOCK_THIS_BLOCK
;
1249 static char* (*p
)() = NULL
;
1252 _dyld_func_lookup("__dyld_dlerror", (void**)&p
);
1256 int dladdr(const void* addr
, Dl_info
* info
)
1258 DYLD_LOCK_THIS_BLOCK
;
1259 static int (*p
)(const void* , Dl_info
*) = NULL
;
1262 _dyld_func_lookup("__dyld_dladdr", (void**)&p
);
1263 return(p(addr
, info
));
1266 int dlclose(void* handle
)
1268 DYLD_LOCK_THIS_BLOCK
;
1269 static int (*p
)(void* handle
) = NULL
;
1272 _dyld_func_lookup("__dyld_dlclose", (void**)&p
);
1276 void* dlopen(const char* path
, int mode
)
1278 // dlopen is special. locking is done inside dyld to allow initializer to run without lock
1279 DYLD_NO_LOCK_THIS_BLOCK
;
1281 static void* (*p
)(const char* path
, int) = NULL
;
1284 _dyld_func_lookup("__dyld_dlopen", (void**)&p
);
1285 void* result
= p(path
, mode
);
1286 // use asm block to prevent tail call optimization
1287 // this is needed because dlopen uses __builtin_return_address() and depends on this glue being in the frame chain
1288 // <rdar://problem/5313172 dlopen() looks too far up stack, can cause crash>
1289 __asm__
volatile("");
1294 bool dlopen_preflight(const char* path
)
1296 DYLD_LOCK_THIS_BLOCK
;
1297 static bool (*p
)(const char* path
) = NULL
;
1300 _dyld_func_lookup("__dyld_dlopen_preflight", (void**)&p
);
1304 void* dlsym(void* handle
, const char* symbol
)
1306 DYLD_LOCK_THIS_BLOCK
;
1307 static void* (*p
)(void* handle
, const char* symbol
) = NULL
;
1310 _dyld_func_lookup("__dyld_dlsym", (void**)&p
);
1311 return(p(handle
, symbol
));
1314 void dyld_register_image_state_change_handler(dyld_image_states state
,
1315 bool batch
, dyld_image_state_change_handler handler
)
1317 DYLD_LOCK_THIS_BLOCK
;
1318 static void* (*p
)(dyld_image_states
, bool, dyld_image_state_change_handler
) = NULL
;
1321 _dyld_func_lookup("__dyld_dyld_register_image_state_change_handler", (void**)&p
);
1322 p(state
, batch
, handler
);
1326 const struct dyld_all_image_infos
* _dyld_get_all_image_infos()
1328 DYLD_NO_LOCK_THIS_BLOCK
;
1329 static struct dyld_all_image_infos
* (*p
)() = NULL
;
1332 _dyld_func_lookup("__dyld_get_all_image_infos", (void**)&p
);
1337 bool _dyld_find_unwind_sections(void* addr
, dyld_unwind_sections
* info
)
1339 DYLD_NO_LOCK_THIS_BLOCK
;
1340 static void* (*p
)(void*, dyld_unwind_sections
*) = NULL
;
1343 _dyld_func_lookup("__dyld_find_unwind_sections", (void**)&p
);
1344 return p(addr
, info
);
1349 #if __i386__ || __x86_64__ || __arm__
1350 __attribute__((visibility("hidden")))
1351 void* _dyld_fast_stub_entry(void* loadercache
, long lazyinfo
)
1353 DYLD_NO_LOCK_THIS_BLOCK
;
1354 static void* (*p
)(void*, long) = NULL
;
1357 _dyld_func_lookup("__dyld_fast_stub_entry", (void**)&p
);
1358 return p(loadercache
, lazyinfo
);
1363 const char* dyld_image_path_containing_address(const void* addr
)
1365 DYLD_NO_LOCK_THIS_BLOCK
;
1366 static const char* (*p
)(const void*) = NULL
;
1369 _dyld_func_lookup("__dyld_image_path_containing_address", (void**)&p
);
1373 #if __IPHONE_OS_VERSION_MIN_REQUIRED
1374 bool dyld_shared_cache_some_image_overridden()
1376 DYLD_NO_LOCK_THIS_BLOCK
;
1377 static bool (*p
)() = NULL
;
1380 _dyld_func_lookup("__dyld_shared_cache_some_image_overridden", (void**)&p
);
1386 // SPI called __fork
1387 void _dyld_fork_child()
1389 DYLD_NO_LOCK_THIS_BLOCK
;
1390 static void (*p
)() = NULL
;
1393 _dyld_func_lookup("__dyld_fork_child", (void**)&p
);