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
);
40 #ifndef LC_LOAD_UPWARD_DYLIB
41 #define LC_LOAD_UPWARD_DYLIB (0x23|LC_REQ_DYLD) /* load of dylib whose initializers run later */
44 #define DYLD_SHARED_CACHE_SUPPORT (__ppc__ || __i386__ || __ppc64__ || __x86_64__ || __arm__)
46 // deprecated APIs are still availble on Mac OS X, but not on iPhone OS
47 #if __IPHONE_OS_VERSION_MIN_REQUIRED
48 #define DEPRECATED_APIS_SUPPORTED 0
50 #define DEPRECATED_APIS_SUPPORTED 1
54 * names_match() takes an install_name from an LC_LOAD_DYLIB command and a
55 * libraryName (which is -lx or -framework Foo argument passed to the static
56 * link editor for the same library) and determines if they match. This depends
57 * on conventional use of names including major versioning.
63 const char* libraryName
)
69 * Conventional install names have these forms:
70 * /System/Library/Frameworks/AppKit.framework/Versions/A/Appkit
71 * /Local/Library/Frameworks/AppKit.framework/Appkit
72 * /lib/libsys_s.A.dylib
73 * /usr/lib/libsys_s.dylib
75 basename
= strrchr(install_name
, '/');
77 basename
= install_name
;
82 * By checking the base name matching the library name we take care
83 * of the -framework cases.
85 if(strcmp(basename
, libraryName
) == 0)
89 * Now check the base name for "lib" if so proceed to check for the
90 * -lx case dealing with a possible .X.dylib and a .dylib extension.
92 if(strncmp(basename
, "lib", 3) ==0){
93 n
= strlen(libraryName
);
94 if(strncmp(basename
+3, libraryName
, n
) == 0){
95 if(strncmp(basename
+3+n
, ".dylib", 6) == 0)
97 if(basename
[3+n
] == '.' &&
98 basename
[3+n
+1] != '\0' &&
99 strncmp(basename
+3+n
+2, ".dylib", 6) == 0)
106 #if DEPRECATED_APIS_SUPPORTED
108 void NSInstallLinkEditErrorHandlers(
109 const NSLinkEditErrorHandlers
* handlers
)
111 DYLD_LOCK_THIS_BLOCK
;
112 typedef void (*ucallback_t
)(const char* symbol_name
);
113 typedef NSModule (*mcallback_t
)(NSSymbol s
, NSModule old
, NSModule newhandler
);
114 typedef void (*lcallback_t
)(NSLinkEditErrors c
, int errorNumber
,
115 const char* fileName
, const char* errorString
);
116 static void (*p
)(ucallback_t undefined
, mcallback_t multiple
, lcallback_t linkEdit
) = NULL
;
119 _dyld_func_lookup("__dyld_install_handlers", (void**)&p
);
120 mcallback_t m
= handlers
->multiple
;
121 p(handlers
->undefined
, m
, handlers
->linkEdit
);
128 DYLD_LOCK_THIS_BLOCK
;
129 static const char* (*p
)(NSModule
module) = NULL
;
132 _dyld_func_lookup("__dyld_NSNameOfModule", (void**)&p
);
137 NSLibraryNameForModule(
140 DYLD_LOCK_THIS_BLOCK
;
141 static const char* (*p
)(NSModule
module) = NULL
;
144 _dyld_func_lookup("__dyld_NSLibraryNameForModule", (void**)&p
);
149 NSIsSymbolNameDefined(
150 const char* symbolName
)
152 DYLD_LOCK_THIS_BLOCK
;
153 static bool (*p
)(const char* symbolName
) = NULL
;
156 _dyld_func_lookup("__dyld_NSIsSymbolNameDefined", (void**)&p
);
157 return(p(symbolName
));
161 NSIsSymbolNameDefinedWithHint(
162 const char* symbolName
,
163 const char* libraryNameHint
)
165 DYLD_LOCK_THIS_BLOCK
;
166 static bool (*p
)(const char* symbolName
,
167 const char* libraryNameHint
) = NULL
;
170 _dyld_func_lookup("__dyld_NSIsSymbolNameDefinedWithHint", (void**)&p
);
171 return(p(symbolName
, libraryNameHint
));
175 NSIsSymbolNameDefinedInImage(
176 const struct mach_header
*image
,
177 const char* symbolName
)
179 DYLD_LOCK_THIS_BLOCK
;
180 static bool (*p
)(const struct mach_header
*image
,
181 const char* symbolName
) = NULL
;
184 _dyld_func_lookup("__dyld_NSIsSymbolNameDefinedInImage", (void**)&p
);
185 return(p(image
, symbolName
));
189 NSLookupAndBindSymbol(
190 const char* symbolName
)
192 DYLD_LOCK_THIS_BLOCK
;
193 static NSSymbol (*p
)(const char* symbolName
) = NULL
;
196 _dyld_func_lookup("__dyld_NSLookupAndBindSymbol", (void**)&p
);
197 return(p(symbolName
));
201 NSLookupAndBindSymbolWithHint(
202 const char* symbolName
,
203 const char* libraryNameHint
)
205 DYLD_LOCK_THIS_BLOCK
;
206 static NSSymbol (*p
)(const char* symbolName
,
207 const char* libraryNameHint
) = NULL
;
210 _dyld_func_lookup("__dyld_NSLookupAndBindSymbolWithHint", (void**)&p
);
211 return(p(symbolName
, libraryNameHint
));
215 NSLookupSymbolInModule(
217 const char* symbolName
)
219 DYLD_LOCK_THIS_BLOCK
;
220 static NSSymbol (*p
)(NSModule
module, const char* symbolName
) = NULL
;
223 _dyld_func_lookup("__dyld_NSLookupSymbolInModule", (void**)&p
);
224 return(p(module, symbolName
));
228 NSLookupSymbolInImage(
229 const struct mach_header
*image
,
230 const char* symbolName
,
233 DYLD_LOCK_THIS_BLOCK
;
234 static NSSymbol (*p
)(const struct mach_header
*image
,
235 const char* symbolName
,
236 uint32_t options
) = NULL
;
239 _dyld_func_lookup("__dyld_NSLookupSymbolInImage", (void**)&p
);
240 return(p(image
, symbolName
, options
));
247 DYLD_LOCK_THIS_BLOCK
;
248 static char * (*p
)(NSSymbol symbol
) = NULL
;
251 _dyld_func_lookup("__dyld_NSNameOfSymbol",(void**)&p
);
259 DYLD_LOCK_THIS_BLOCK
;
260 static void * (*p
)(NSSymbol symbol
) = NULL
;
263 _dyld_func_lookup("__dyld_NSAddressOfSymbol", (void**)&p
);
271 DYLD_LOCK_THIS_BLOCK
;
272 static NSModule (*p
)(NSSymbol symbol
) = NULL
;
275 _dyld_func_lookup("__dyld_NSModuleForSymbol", (void**)&p
);
281 const char* pathName
)
283 DYLD_LOCK_THIS_BLOCK
;
284 static bool (*p
)(const char* pathName
) = NULL
;
287 _dyld_func_lookup("__dyld_NSAddLibrary", (void**)&p
);
292 NSAddLibraryWithSearching(
293 const char* pathName
)
295 DYLD_LOCK_THIS_BLOCK
;
296 static bool (*p
)(const char* pathName
) = NULL
;
299 _dyld_func_lookup("__dyld_NSAddLibraryWithSearching", (void**)&p
);
303 const struct mach_header
*
305 const char* image_name
,
308 DYLD_LOCK_THIS_BLOCK
;
309 static const struct mach_header
* (*p
)(const char* image_name
,
310 uint32_t options
) = NULL
;
313 _dyld_func_lookup("__dyld_NSAddImage", (void**)&p
);
314 return(p(image_name
, options
));
316 #endif // DEPRECATED_APIS_SUPPORTED
319 * This routine returns the current version of the named shared library the
320 * executable it was built with. The libraryName parameter is the same as the
321 * -lx or -framework Foo argument passed to the static link editor when building
322 * the executable (with -lx it would be "x" and with -framework Foo it would be
323 * "Foo"). If this the executable was not built against the specified library
324 * it returns -1. It should be noted that if this only returns the value the
325 * current version of the named shared library the executable was built with
326 * and not a list of current versions that dependent libraries and bundles the
327 * program is using were built with.
330 NSVersionOfLinkTimeLibrary(
331 const char* libraryName
)
334 struct load_command
*load_commands
, *lc
;
335 struct dylib_command
*dl
;
338 static struct mach_header_64
*mh
= NULL
;
340 static struct mach_header
*mh
= NULL
;
343 mh
= _NSGetMachExecuteHeader();
344 load_commands
= (struct load_command
*)
346 ((char *)mh
+ sizeof(struct mach_header_64
));
348 ((char *)mh
+ sizeof(struct mach_header
));
351 for(i
= 0; i
< mh
->ncmds
; i
++){
354 case LC_LOAD_WEAK_DYLIB
:
355 case LC_LOAD_UPWARD_DYLIB
:
356 dl
= (struct dylib_command
*)lc
;
357 install_name
= (char *)dl
+ dl
->dylib
.name
.offset
;
358 if(names_match(install_name
, libraryName
) == TRUE
)
359 return(dl
->dylib
.current_version
);
362 lc
= (struct load_command
*)((char *)lc
+ lc
->cmdsize
);
368 * This routine returns the current version of the named shared library the
369 * program it is running against. The libraryName parameter is the same as
370 * would be static link editor using the -lx or -framework Foo flags (with -lx
371 * it would be "x" and with -framework Foo it would be "Foo"). If the program
372 * is not using the specified library it returns -1.
375 NSVersionOfRunTimeLibrary(
376 const char* libraryName
)
378 unsigned long i
, j
, n
;
380 struct load_command
*load_commands
, *lc
;
381 struct dylib_command
*dl
;
382 const struct mach_header
*mh
;
384 n
= _dyld_image_count();
385 for(i
= 0; i
< n
; i
++){
386 mh
= _dyld_get_image_header(i
);
387 if(mh
->filetype
!= MH_DYLIB
)
389 load_commands
= (struct load_command
*)
391 ((char *)mh
+ sizeof(struct mach_header_64
));
393 ((char *)mh
+ sizeof(struct mach_header
));
396 for(j
= 0; j
< mh
->ncmds
; j
++){
397 if(lc
->cmd
== LC_ID_DYLIB
){
398 dl
= (struct dylib_command
*)lc
;
399 install_name
= (char *)dl
+ dl
->dylib
.name
.offset
;
400 if(names_match(install_name
, libraryName
) == TRUE
)
401 return(dl
->dylib
.current_version
);
403 lc
= (struct load_command
*)((char *)lc
+ lc
->cmdsize
);
409 #if DEPRECATED_APIS_SUPPORTED
411 * NSCreateObjectFileImageFromFile() creates an NSObjectFileImage for the
412 * specified file name if the file is a correct Mach-O file that can be loaded
413 * with NSloadModule(). For return codes of NSObjectFileImageFailure and
414 * NSObjectFileImageFormat an error message is printed to stderr. All
415 * other codes cause no printing.
417 NSObjectFileImageReturnCode
418 NSCreateObjectFileImageFromFile(
419 const char* pathName
,
420 NSObjectFileImage
*objectFileImage
)
422 DYLD_LOCK_THIS_BLOCK
;
423 static NSObjectFileImageReturnCode (*p
)(const char*, NSObjectFileImage
*) = NULL
;
426 _dyld_func_lookup("__dyld_NSCreateObjectFileImageFromFile", (void**)&p
);
427 return p(pathName
, objectFileImage
);
432 * NSCreateObjectFileImageFromMemory() creates an NSObjectFileImage for the
433 * object file mapped into memory at address of size length if the object file
434 * is a correct Mach-O file that can be loaded with NSloadModule(). For return
435 * codes of NSObjectFileImageFailure and NSObjectFileImageFormat an error
436 * message is printed to stderr. All other codes cause no printing.
438 NSObjectFileImageReturnCode
439 NSCreateObjectFileImageFromMemory(
442 NSObjectFileImage
*objectFileImage
)
444 DYLD_LOCK_THIS_BLOCK
;
445 static NSObjectFileImageReturnCode (*p
)(const void*, size_t, NSObjectFileImage
*) = NULL
;
448 _dyld_func_lookup("__dyld_NSCreateObjectFileImageFromMemory", (void**)&p
);
449 return p(address
, size
, objectFileImage
);
452 #if OBSOLETE_DYLD_API
454 * NSCreateCoreFileImageFromFile() creates an NSObjectFileImage for the
455 * specified core file name if the file is a correct Mach-O core file.
456 * For return codes of NSObjectFileImageFailure and NSObjectFileImageFormat
457 * an error message is printed to stderr. All other codes cause no printing.
459 NSObjectFileImageReturnCode
460 NSCreateCoreFileImageFromFile(
461 const char* pathName
,
462 NSObjectFileImage
*objectFileImage
)
464 DYLD_LOCK_THIS_BLOCK
;
465 static NSObjectFileImageReturnCode (*p
)(const char*, NSObjectFileImage
*) = NULL
;
468 _dyld_func_lookup("__dyld_NSCreateCoreFileImageFromFile", (void**)&p
);
469 return p(pathName
, objectFileImage
);
474 NSDestroyObjectFileImage(
475 NSObjectFileImage objectFileImage
)
477 DYLD_LOCK_THIS_BLOCK
;
478 static bool (*p
)(NSObjectFileImage
) = NULL
;
481 _dyld_func_lookup("__dyld_NSDestroyObjectFileImage", (void**)&p
);
482 return p(objectFileImage
);
488 NSObjectFileImage objectFileImage
,
489 const char* moduleName
,
492 DYLD_LOCK_THIS_BLOCK
;
493 static NSModule (*p
)(NSObjectFileImage
, const char*, unsigned long) = NULL
;
496 _dyld_func_lookup("__dyld_NSLinkModule", (void**)&p
);
498 return p(objectFileImage
, moduleName
, options
);
505 * NSSymbolDefinitionCountInObjectFileImage() returns the number of symbol
506 * definitions in the NSObjectFileImage.
509 NSSymbolDefinitionCountInObjectFileImage(
510 NSObjectFileImage objectFileImage
)
512 DYLD_LOCK_THIS_BLOCK
;
513 static unsigned long (*p
)(NSObjectFileImage
) = NULL
;
516 _dyld_func_lookup("__dyld_NSSymbolDefinitionCountInObjectFileImage", (void**)&p
);
518 return p(objectFileImage
);
522 * NSSymbolDefinitionNameInObjectFileImage() returns the name of the i'th
523 * symbol definitions in the NSObjectFileImage. If the ordinal specified is
524 * outside the range [0..NSSymbolDefinitionCountInObjectFileImage], NULL will
528 NSSymbolDefinitionNameInObjectFileImage(
529 NSObjectFileImage objectFileImage
,
532 DYLD_LOCK_THIS_BLOCK
;
533 static const char* (*p
)(NSObjectFileImage
, uint32_t) = NULL
;
536 _dyld_func_lookup("__dyld_NSSymbolDefinitionNameInObjectFileImage", (void**)&p
);
538 return p(objectFileImage
, ordinal
);
542 * NSSymbolReferenceCountInObjectFileImage() returns the number of references
543 * to undefined symbols the NSObjectFileImage.
546 NSSymbolReferenceCountInObjectFileImage(
547 NSObjectFileImage objectFileImage
)
549 DYLD_LOCK_THIS_BLOCK
;
550 static unsigned long (*p
)(NSObjectFileImage
) = NULL
;
553 _dyld_func_lookup("__dyld_NSSymbolReferenceCountInObjectFileImage", (void**)&p
);
555 return p(objectFileImage
);
559 * NSSymbolReferenceNameInObjectFileImage() returns the name of the i'th
560 * undefined symbol in the NSObjectFileImage. If the ordinal specified is
561 * outside the range [0..NSSymbolReferenceCountInObjectFileImage], NULL will be
565 NSSymbolReferenceNameInObjectFileImage(
566 NSObjectFileImage objectFileImage
,
568 bool *tentative_definition
) /* can be NULL */
570 DYLD_LOCK_THIS_BLOCK
;
571 static const char* (*p
)(NSObjectFileImage
, uint32_t, bool*) = NULL
;
574 _dyld_func_lookup("__dyld_NSSymbolReferenceNameInObjectFileImage", (void**)&p
);
576 return p(objectFileImage
, ordinal
, tentative_definition
);
580 * NSIsSymbolDefinedInObjectFileImage() returns TRUE if the specified symbol
581 * name has a definition in the NSObjectFileImage and FALSE otherwise.
584 NSIsSymbolDefinedInObjectFileImage(
585 NSObjectFileImage objectFileImage
,
586 const char* symbolName
)
588 DYLD_LOCK_THIS_BLOCK
;
589 static bool (*p
)(NSObjectFileImage
, const char*) = NULL
;
592 _dyld_func_lookup("__dyld_NSIsSymbolDefinedInObjectFileImage", (void**)&p
);
594 return p(objectFileImage
, symbolName
);
598 * NSGetSectionDataInObjectFileImage() returns a pointer to the section contents
599 * in the NSObjectFileImage for the specified segmentName and sectionName if
600 * it exists and it is not a zerofill section. If not it returns NULL. If
601 * the parameter size is not NULL the size of the section is also returned
602 * indirectly through that pointer.
605 NSGetSectionDataInObjectFileImage(
606 NSObjectFileImage objectFileImage
,
607 const char* segmentName
,
608 const char* sectionName
,
609 unsigned long *size
) /* can be NULL */
611 DYLD_LOCK_THIS_BLOCK
;
612 static void* (*p
)(NSObjectFileImage
, const char*, const char*, unsigned long*) = NULL
;
615 _dyld_func_lookup("__dyld_NSGetSectionDataInObjectFileImage", (void**)&p
);
617 return p(objectFileImage
, segmentName
, sectionName
, size
);
625 const char* *fileName
,
626 const char* *errorString
)
628 DYLD_LOCK_THIS_BLOCK
;
629 static void (*p
)(NSLinkEditErrors
*c
,
631 const char* *fileName
,
632 const char* *errorString
) = NULL
;
635 _dyld_func_lookup("__dyld_link_edit_error", (void**)&p
);
637 p(c
, errorNumber
, fileName
, errorString
);
645 DYLD_LOCK_THIS_BLOCK
;
646 static bool (*p
)(NSModule
module, uint32_t options
) = NULL
;
649 _dyld_func_lookup("__dyld_unlink_module", (void**)&p
);
651 return p(module, options
);
654 #if OBSOLETE_DYLD_API
657 NSModule moduleToReplace
,
658 NSObjectFileImage newObjectFileImage
,
666 #endif // DEPRECATED_APIS_SUPPORTED
669 *_NSGetExecutablePath copies the path of the executable into the buffer and
670 * returns 0 if the path was successfully copied in the provided buffer. If the
671 * buffer is not large enough, -1 is returned and the expected buffer size is
672 * copied in *bufsize. Note that _NSGetExecutablePath will return "a path" to
673 * the executable not a "real path" to the executable. That is the path may be
674 * a symbolic link and not the real file. And with deep directories the total
675 * bufsize needed could be more than MAXPATHLEN.
678 _NSGetExecutablePath(
682 DYLD_LOCK_THIS_BLOCK
;
683 static int (*p
)(char *buf
, uint32_t *bufsize
) = NULL
;
686 _dyld_func_lookup("__dyld__NSGetExecutablePath", (void**)&p
);
687 return(p(buf
, bufsize
));
690 #if DEPRECATED_APIS_SUPPORTED
692 _dyld_lookup_and_bind(
693 const char* symbol_name
,
697 DYLD_LOCK_THIS_BLOCK
;
698 static void (*p
)(const char*, void** , NSModule
*) = NULL
;
701 _dyld_func_lookup("__dyld_lookup_and_bind", (void**)&p
);
702 p(symbol_name
, address
, module);
706 _dyld_lookup_and_bind_with_hint(
707 const char* symbol_name
,
708 const char* library_name_hint
,
712 DYLD_LOCK_THIS_BLOCK
;
713 static void (*p
)(const char*, const char*, void**, NSModule
*) = NULL
;
716 _dyld_func_lookup("__dyld_lookup_and_bind_with_hint", (void**)&p
);
717 p(symbol_name
, library_name_hint
, address
, module);
720 #if OBSOLETE_DYLD_API
722 _dyld_lookup_and_bind_objc(
723 const char* symbol_name
,
727 DYLD_LOCK_THIS_BLOCK
;
728 static void (*p
)(const char* , void**, NSModule
*) = NULL
;
731 _dyld_func_lookup("__dyld_lookup_and_bind_objc", (void**)&p
);
732 p(symbol_name
, address
, module);
737 _dyld_lookup_and_bind_fully(
738 const char* symbol_name
,
742 DYLD_LOCK_THIS_BLOCK
;
743 static void (*p
)(const char*, void**, NSModule
*) = NULL
;
746 _dyld_func_lookup("__dyld_lookup_and_bind_fully", (void**)&p
);
747 p(symbol_name
, address
, module);
751 _dyld_bind_fully_image_containing_address(
754 DYLD_LOCK_THIS_BLOCK
;
755 static bool (*p
)(const void*) = NULL
;
758 _dyld_func_lookup("__dyld_bind_fully_image_containing_address", (void**)&p
);
761 #endif // DEPRECATED_APIS_SUPPORTED
765 * _dyld_register_func_for_add_image registers the specified function to be
766 * called when a new image is added (a bundle or a dynamic shared library) to
767 * the program. When this function is first registered it is called for once
768 * for each image that is currently part of the program.
771 _dyld_register_func_for_add_image(
772 void (*func
)(const struct mach_header
*mh
, intptr_t vmaddr_slide
))
774 DYLD_LOCK_THIS_BLOCK
;
775 typedef void (*callback_t
)(const struct mach_header
*mh
, intptr_t vmaddr_slide
);
776 static void (*p
)(callback_t func
) = NULL
;
779 _dyld_func_lookup("__dyld_register_func_for_add_image", (void**)&p
);
784 * _dyld_register_func_for_remove_image registers the specified function to be
785 * called when an image is removed (a bundle or a dynamic shared library) from
789 _dyld_register_func_for_remove_image(
790 void (*func
)(const struct mach_header
*mh
, intptr_t vmaddr_slide
))
792 DYLD_LOCK_THIS_BLOCK
;
793 typedef void (*callback_t
)(const struct mach_header
*mh
, intptr_t vmaddr_slide
);
794 static void (*p
)(callback_t func
) = NULL
;
797 _dyld_func_lookup("__dyld_register_func_for_remove_image", (void**)&p
);
801 #if OBSOLETE_DYLD_API
803 * _dyld_register_func_for_link_module registers the specified function to be
804 * called when a module is bound into the program. When this function is first
805 * registered it is called for once for each module that is currently bound into
809 _dyld_register_func_for_link_module(
810 void (*func
)(NSModule
module))
812 DYLD_LOCK_THIS_BLOCK
;
813 static void (*p
)(void (*func
)(NSModule
module)) = NULL
;
816 _dyld_func_lookup("__dyld_register_func_for_link_module", (void**)&p
);
821 * _dyld_register_func_for_unlink_module registers the specified function to be
822 * called when a module is unbound from the program.
825 _dyld_register_func_for_unlink_module(
826 void (*func
)(NSModule
module))
828 DYLD_LOCK_THIS_BLOCK
;
829 static void (*p
)(void (*func
)(NSModule
module)) = NULL
;
832 _dyld_func_lookup("__dyld_register_func_for_unlink_module", (void**)&p
);
837 * _dyld_register_func_for_replace_module registers the specified function to be
838 * called when a module is to be replace with another module in the program.
841 _dyld_register_func_for_replace_module(
842 void (*func
)(NSModule oldmodule
, NSModule newmodule
))
844 DYLD_LOCK_THIS_BLOCK
;
845 static void (*p
)(void (*func
)(NSModule oldmodule
,
846 NSModule newmodule
)) = NULL
;
849 _dyld_func_lookup("__dyld_register_func_for_replace_module", (void**)&p
);
855 * _dyld_get_objc_module_sect_for_module is passed a module and sets a
856 * pointer to the (__OBJC,__module) section and its size for the specified
860 _dyld_get_objc_module_sect_for_module(
865 DYLD_LOCK_THIS_BLOCK
;
866 static void (*p
)(NSModule
module,
868 unsigned long *size
) = NULL
;
871 _dyld_func_lookup("__dyld_get_objc_module_sect_for_module", (void**)&p
);
872 p(module, objc_module
, size
);
876 * _dyld_bind_objc_module() is passed a pointer to something in an (__OBJC,
877 * __module) section and causes the module that is associated with that address
881 _dyld_bind_objc_module(const void* objc_module
)
883 DYLD_LOCK_THIS_BLOCK
;
884 static void (*p
)(const void *objc_module
) = NULL
;
887 _dyld_func_lookup("__dyld_bind_objc_module", (void**)&p
);
892 #if DEPRECATED_APIS_SUPPORTED
896 // this function exists for compatiblity only
902 _dyld_image_count(void)
904 DYLD_NO_LOCK_THIS_BLOCK
;
905 static unsigned long (*p
)(void) = NULL
;
908 _dyld_func_lookup("__dyld_image_count", (void**)&p
);
912 const struct mach_header
*
913 _dyld_get_image_header(uint32_t image_index
)
915 DYLD_NO_LOCK_THIS_BLOCK
;
916 static struct mach_header
* (*p
)(uint32_t image_index
) = NULL
;
919 _dyld_func_lookup("__dyld_get_image_header", (void**)&p
);
920 return(p(image_index
));
924 _dyld_get_image_vmaddr_slide(uint32_t image_index
)
926 DYLD_NO_LOCK_THIS_BLOCK
;
927 static unsigned long (*p
)(uint32_t image_index
) = NULL
;
930 _dyld_func_lookup("__dyld_get_image_vmaddr_slide", (void**)&p
);
931 return(p(image_index
));
935 _dyld_get_image_name(uint32_t image_index
)
937 DYLD_NO_LOCK_THIS_BLOCK
;
938 static const char* (*p
)(uint32_t image_index
) = NULL
;
941 _dyld_func_lookup("__dyld_get_image_name", (void**)&p
);
942 return(p(image_index
));
945 // SPI in Mac OS X 10.6
946 intptr_t _dyld_get_image_slide(const struct mach_header
* mh
)
948 DYLD_NO_LOCK_THIS_BLOCK
;
949 static intptr_t (*p
)(const struct mach_header
*) = NULL
;
952 _dyld_func_lookup("__dyld_get_image_slide", (void**)&p
);
958 _dyld_image_containing_address(const void* address
)
960 DYLD_LOCK_THIS_BLOCK
;
961 static bool (*p
)(const void*) = NULL
;
964 _dyld_func_lookup("__dyld_image_containing_address", (void**)&p
);
968 const struct mach_header
*
969 _dyld_get_image_header_containing_address(
972 DYLD_LOCK_THIS_BLOCK
;
973 static const struct mach_header
* (*p
)(const void*) = NULL
;
976 _dyld_func_lookup("__dyld_get_image_header_containing_address", (void**)&p
);
981 void (*monaddition
)(char *lowpc
, char *highpc
))
983 DYLD_LOCK_THIS_BLOCK
;
984 typedef void (*monproc
)(char *lowpc
, char *highpc
);
985 static void (*p
)(monproc monaddition
) = NULL
;
988 _dyld_func_lookup("__dyld_moninit", (void**)&p
);
992 #if DEPRECATED_APIS_SUPPORTED
993 bool _dyld_launched_prebound(void)
995 DYLD_LOCK_THIS_BLOCK
;
996 static bool (*p
)(void) = NULL
;
999 _dyld_func_lookup("__dyld_launched_prebound", (void**)&p
);
1003 bool _dyld_all_twolevel_modules_prebound(void)
1005 DYLD_LOCK_THIS_BLOCK
;
1006 static bool (*p
)(void) = NULL
;
1009 _dyld_func_lookup("__dyld_all_twolevel_modules_prebound", (void**)&p
);
1012 #endif // DEPRECATED_APIS_SUPPORTED
1017 #include <pthread.h>
1019 #include <mach-o/dyld.h>
1020 #include <servers/bootstrap.h>
1021 #include "dyldLibSystemInterface.h"
1024 // pthread key used to access per-thread dlerror message
1025 static pthread_key_t dlerrorPerThreadKey
;
1026 static bool dlerrorPerThreadKeyInitialized
= false;
1028 // data kept per-thread
1029 struct dlerrorPerThreadData
1031 uint32_t sizeAllocated
;
1035 // function called by dyld to get buffer to store dlerror message
1036 static char* getPerThreadBufferFor_dlerror(uint32_t sizeRequired
)
1038 // ok to create key lazily because this function is called within dyld lock, so there is no race condition
1039 if (!dlerrorPerThreadKeyInitialized
) {
1040 // create key and tell pthread package to call free() on any data associated with key if thread dies
1041 pthread_key_create(&dlerrorPerThreadKey
, &free
);
1042 dlerrorPerThreadKeyInitialized
= true;
1045 const int size
= (sizeRequired
< 256) ? 256 : sizeRequired
;
1046 dlerrorPerThreadData
* data
= (dlerrorPerThreadData
*)pthread_getspecific(dlerrorPerThreadKey
);
1047 if ( data
== NULL
) {
1048 //int mallocSize = offsetof(dlerrorPerThreadData, message[size]);
1049 const int mallocSize
= sizeof(dlerrorPerThreadData
)+size
;
1050 data
= (dlerrorPerThreadData
*)malloc(mallocSize
);
1051 data
->sizeAllocated
= size
;
1052 pthread_setspecific(dlerrorPerThreadKey
, data
);
1054 else if ( data
->sizeAllocated
< sizeRequired
) {
1056 //int mallocSize = offsetof(dlerrorPerThreadData, message[size]);
1057 const int mallocSize
= sizeof(dlerrorPerThreadData
)+size
;
1058 data
= (dlerrorPerThreadData
*)malloc(mallocSize
);
1059 data
->sizeAllocated
= size
;
1060 pthread_setspecific(dlerrorPerThreadKey
, data
);
1062 return data
->message
;
1066 #if DYLD_SHARED_CACHE_SUPPORT
1067 static void shared_cache_missing()
1069 // leave until dyld's that might call this are rare
1072 static void shared_cache_out_of_date()
1074 // leave until dyld's that might call this are rare
1076 #endif // DYLD_SHARED_CACHE_SUPPORT
1079 // the table passed to dyld containing thread helpers
1080 static dyld::LibSystemHelpers sHelpers
= { 8, &dyldGlobalLockAcquire
, &dyldGlobalLockRelease
,
1081 &getPerThreadBufferFor_dlerror
, &malloc
, &free
, &__cxa_atexit
,
1082 #if DYLD_SHARED_CACHE_SUPPORT
1083 &shared_cache_missing
, &shared_cache_out_of_date
,
1088 &pthread_key_create
, &pthread_setspecific
,
1090 &pthread_getspecific
,
1095 // during initialization of libSystem this routine will run
1096 // and call dyld, registering the helper functions.
1098 extern "C" void tlv_initializer();
1099 extern "C" void _dyld_initializer();
1100 void _dyld_initializer()
1102 DYLD_LOCK_INITIALIZER
;
1104 void (*p
)(dyld::LibSystemHelpers
*);
1106 _dyld_func_lookup("__dyld_register_thread_helpers", (void**)&p
);
1116 DYLD_LOCK_THIS_BLOCK
;
1117 static char* (*p
)() = NULL
;
1120 _dyld_func_lookup("__dyld_dlerror", (void**)&p
);
1124 int dladdr(const void* addr
, Dl_info
* info
)
1126 DYLD_LOCK_THIS_BLOCK
;
1127 static int (*p
)(const void* , Dl_info
*) = NULL
;
1130 _dyld_func_lookup("__dyld_dladdr", (void**)&p
);
1131 return(p(addr
, info
));
1134 int dlclose(void* handle
)
1136 DYLD_LOCK_THIS_BLOCK
;
1137 static int (*p
)(void* handle
) = NULL
;
1140 _dyld_func_lookup("__dyld_dlclose", (void**)&p
);
1144 void* dlopen(const char* path
, int mode
)
1146 // dlopen is special. locking is done inside dyld to allow initializer to run without lock
1147 DYLD_NO_LOCK_THIS_BLOCK
;
1149 static void* (*p
)(const char* path
, int) = NULL
;
1152 _dyld_func_lookup("__dyld_dlopen", (void**)&p
);
1153 void* result
= p(path
, mode
);
1154 // use asm block to prevent tail call optimization
1155 // this is needed because dlopen uses __builtin_return_address() and depends on this glue being in the frame chain
1156 // <rdar://problem/5313172 dlopen() looks too far up stack, can cause crash>
1157 __asm__
volatile("");
1162 bool dlopen_preflight(const char* path
)
1164 DYLD_LOCK_THIS_BLOCK
;
1165 static bool (*p
)(const char* path
) = NULL
;
1168 _dyld_func_lookup("__dyld_dlopen_preflight", (void**)&p
);
1172 void* dlsym(void* handle
, const char* symbol
)
1174 DYLD_LOCK_THIS_BLOCK
;
1175 static void* (*p
)(void* handle
, const char* symbol
) = NULL
;
1178 _dyld_func_lookup("__dyld_dlsym", (void**)&p
);
1179 return(p(handle
, symbol
));
1182 void dyld_register_image_state_change_handler(dyld_image_states state
,
1183 bool batch
, dyld_image_state_change_handler handler
)
1185 DYLD_LOCK_THIS_BLOCK
;
1186 static void* (*p
)(dyld_image_states
, bool, dyld_image_state_change_handler
) = NULL
;
1189 _dyld_func_lookup("__dyld_dyld_register_image_state_change_handler", (void**)&p
);
1190 p(state
, batch
, handler
);
1194 const struct dyld_all_image_infos
* _dyld_get_all_image_infos()
1196 DYLD_NO_LOCK_THIS_BLOCK
;
1197 static struct dyld_all_image_infos
* (*p
)() = NULL
;
1200 _dyld_func_lookup("__dyld_get_all_image_infos", (void**)&p
);
1205 bool _dyld_find_unwind_sections(void* addr
, dyld_unwind_sections
* info
)
1207 DYLD_NO_LOCK_THIS_BLOCK
;
1208 static void* (*p
)(void*, dyld_unwind_sections
*) = NULL
;
1211 _dyld_func_lookup("__dyld_find_unwind_sections", (void**)&p
);
1212 return p(addr
, info
);
1217 #if __i386__ || __x86_64__ || __arm__
1218 __attribute__((visibility("hidden")))
1219 void* _dyld_fast_stub_entry(void* loadercache
, long lazyinfo
)
1221 DYLD_NO_LOCK_THIS_BLOCK
;
1222 static void* (*p
)(void*, long) = NULL
;
1225 _dyld_func_lookup("__dyld_fast_stub_entry", (void**)&p
);
1226 return p(loadercache
, lazyinfo
);
1231 const char* dyld_image_path_containing_address(const void* addr
)
1233 DYLD_NO_LOCK_THIS_BLOCK
;
1234 static const char* (*p
)(const void*) = NULL
;
1237 _dyld_func_lookup("__dyld_image_path_containing_address", (void**)&p
);
1241 #if __IPHONE_OS_VERSION_MIN_REQUIRED
1242 bool dyld_shared_cache_some_image_overridden()
1244 DYLD_NO_LOCK_THIS_BLOCK
;
1245 static bool (*p
)() = NULL
;
1248 _dyld_func_lookup("__dyld_shared_cache_some_image_overridden", (void**)&p
);
1254 // SPI called __fork
1255 void _dyld_fork_child()
1257 DYLD_NO_LOCK_THIS_BLOCK
;
1258 static void (*p
)() = NULL
;
1261 _dyld_func_lookup("__dyld_fork_child", (void**)&p
);