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
);
39 #define DYLD_SHARED_CACHE_SUPPORT (__ppc__ || __i386__ || __ppc64__ || __x86_64__)
41 // deprecated APIs are still availble on Mac OS X, but not on iPhone OS
42 #if __IPHONE_OS_VERSION_MIN_REQUIRED
43 #define DEPRECATED_APIS_SUPPORTED 0
45 #define DEPRECATED_APIS_SUPPORTED 1
49 * names_match() takes an install_name from an LC_LOAD_DYLIB command and a
50 * libraryName (which is -lx or -framework Foo argument passed to the static
51 * link editor for the same library) and determines if they match. This depends
52 * on conventional use of names including major versioning.
58 const char* libraryName
)
64 * Conventional install names have these forms:
65 * /System/Library/Frameworks/AppKit.framework/Versions/A/Appkit
66 * /Local/Library/Frameworks/AppKit.framework/Appkit
67 * /lib/libsys_s.A.dylib
68 * /usr/lib/libsys_s.dylib
70 basename
= strrchr(install_name
, '/');
72 basename
= install_name
;
77 * By checking the base name matching the library name we take care
78 * of the -framework cases.
80 if(strcmp(basename
, libraryName
) == 0)
84 * Now check the base name for "lib" if so proceed to check for the
85 * -lx case dealing with a possible .X.dylib and a .dylib extension.
87 if(strncmp(basename
, "lib", 3) ==0){
88 n
= strlen(libraryName
);
89 if(strncmp(basename
+3, libraryName
, n
) == 0){
90 if(strncmp(basename
+3+n
, ".dylib", 6) == 0)
92 if(basename
[3+n
] == '.' &&
93 basename
[3+n
+1] != '\0' &&
94 strncmp(basename
+3+n
+2, ".dylib", 6) == 0)
101 #if DEPRECATED_APIS_SUPPORTED
103 void NSInstallLinkEditErrorHandlers(
104 const NSLinkEditErrorHandlers
* handlers
)
106 DYLD_LOCK_THIS_BLOCK
;
108 void (*undefined
)(const char* symbol_name
),
109 NSModule (*multiple
)(NSSymbol s
, NSModule old
, NSModule newhandler
),
110 void (*linkEdit
)(NSLinkEditErrors c
, int errorNumber
,
111 const char* fileName
, const char* errorString
)) = NULL
;
114 _dyld_func_lookup("__dyld_install_handlers", (void**)&p
);
115 p(handlers
->undefined
, handlers
->multiple
, handlers
->linkEdit
);
122 DYLD_LOCK_THIS_BLOCK
;
123 static const char* (*p
)(NSModule
module) = NULL
;
126 _dyld_func_lookup("__dyld_NSNameOfModule", (void**)&p
);
131 NSLibraryNameForModule(
134 DYLD_LOCK_THIS_BLOCK
;
135 static const char* (*p
)(NSModule
module) = NULL
;
138 _dyld_func_lookup("__dyld_NSLibraryNameForModule", (void**)&p
);
143 NSIsSymbolNameDefined(
144 const char* symbolName
)
146 DYLD_LOCK_THIS_BLOCK
;
147 static bool (*p
)(const char* symbolName
) = NULL
;
150 _dyld_func_lookup("__dyld_NSIsSymbolNameDefined", (void**)&p
);
151 return(p(symbolName
));
155 NSIsSymbolNameDefinedWithHint(
156 const char* symbolName
,
157 const char* libraryNameHint
)
159 DYLD_LOCK_THIS_BLOCK
;
160 static bool (*p
)(const char* symbolName
,
161 const char* libraryNameHint
) = NULL
;
164 _dyld_func_lookup("__dyld_NSIsSymbolNameDefinedWithHint", (void**)&p
);
165 return(p(symbolName
, libraryNameHint
));
169 NSIsSymbolNameDefinedInImage(
170 const struct mach_header
*image
,
171 const char* symbolName
)
173 DYLD_LOCK_THIS_BLOCK
;
174 static bool (*p
)(const struct mach_header
*image
,
175 const char* symbolName
) = NULL
;
178 _dyld_func_lookup("__dyld_NSIsSymbolNameDefinedInImage", (void**)&p
);
179 return(p(image
, symbolName
));
183 NSLookupAndBindSymbol(
184 const char* symbolName
)
186 DYLD_LOCK_THIS_BLOCK
;
187 static NSSymbol (*p
)(const char* symbolName
) = NULL
;
190 _dyld_func_lookup("__dyld_NSLookupAndBindSymbol", (void**)&p
);
191 return(p(symbolName
));
195 NSLookupAndBindSymbolWithHint(
196 const char* symbolName
,
197 const char* libraryNameHint
)
199 DYLD_LOCK_THIS_BLOCK
;
200 static NSSymbol (*p
)(const char* symbolName
,
201 const char* libraryNameHint
) = NULL
;
204 _dyld_func_lookup("__dyld_NSLookupAndBindSymbolWithHint", (void**)&p
);
205 return(p(symbolName
, libraryNameHint
));
209 NSLookupSymbolInModule(
211 const char* symbolName
)
213 DYLD_LOCK_THIS_BLOCK
;
214 static NSSymbol (*p
)(NSModule
module, const char* symbolName
) = NULL
;
217 _dyld_func_lookup("__dyld_NSLookupSymbolInModule", (void**)&p
);
218 return(p(module, symbolName
));
222 NSLookupSymbolInImage(
223 const struct mach_header
*image
,
224 const char* symbolName
,
227 DYLD_LOCK_THIS_BLOCK
;
228 static NSSymbol (*p
)(const struct mach_header
*image
,
229 const char* symbolName
,
230 uint32_t options
) = NULL
;
233 _dyld_func_lookup("__dyld_NSLookupSymbolInImage", (void**)&p
);
234 return(p(image
, symbolName
, options
));
241 DYLD_LOCK_THIS_BLOCK
;
242 static char * (*p
)(NSSymbol symbol
) = NULL
;
245 _dyld_func_lookup("__dyld_NSNameOfSymbol",(void**)&p
);
253 DYLD_LOCK_THIS_BLOCK
;
254 static void * (*p
)(NSSymbol symbol
) = NULL
;
257 _dyld_func_lookup("__dyld_NSAddressOfSymbol", (void**)&p
);
265 DYLD_LOCK_THIS_BLOCK
;
266 static NSModule (*p
)(NSSymbol symbol
) = NULL
;
269 _dyld_func_lookup("__dyld_NSModuleForSymbol", (void**)&p
);
275 const char* pathName
)
277 DYLD_LOCK_THIS_BLOCK
;
278 static bool (*p
)(const char* pathName
) = NULL
;
281 _dyld_func_lookup("__dyld_NSAddLibrary", (void**)&p
);
286 NSAddLibraryWithSearching(
287 const char* pathName
)
289 DYLD_LOCK_THIS_BLOCK
;
290 static bool (*p
)(const char* pathName
) = NULL
;
293 _dyld_func_lookup("__dyld_NSAddLibraryWithSearching", (void**)&p
);
297 const struct mach_header
*
299 const char* image_name
,
302 DYLD_LOCK_THIS_BLOCK
;
303 static const struct mach_header
* (*p
)(const char* image_name
,
304 uint32_t options
) = NULL
;
307 _dyld_func_lookup("__dyld_NSAddImage", (void**)&p
);
308 return(p(image_name
, options
));
310 #endif // DEPRECATED_APIS_SUPPORTED
313 * This routine returns the current version of the named shared library the
314 * executable it was built with. The libraryName parameter is the same as the
315 * -lx or -framework Foo argument passed to the static link editor when building
316 * the executable (with -lx it would be "x" and with -framework Foo it would be
317 * "Foo"). If this the executable was not built against the specified library
318 * it returns -1. It should be noted that if this only returns the value the
319 * current version of the named shared library the executable was built with
320 * and not a list of current versions that dependent libraries and bundles the
321 * program is using were built with.
324 NSVersionOfLinkTimeLibrary(
325 const char* libraryName
)
328 struct load_command
*load_commands
, *lc
;
329 struct dylib_command
*dl
;
332 static struct mach_header_64
*mh
= NULL
;
334 static struct mach_header
*mh
= NULL
;
337 mh
= _NSGetMachExecuteHeader();
338 load_commands
= (struct load_command
*)
340 ((char *)mh
+ sizeof(struct mach_header_64
));
342 ((char *)mh
+ sizeof(struct mach_header
));
345 for(i
= 0; i
< mh
->ncmds
; i
++){
348 case LC_LOAD_WEAK_DYLIB
:
349 dl
= (struct dylib_command
*)lc
;
350 install_name
= (char *)dl
+ dl
->dylib
.name
.offset
;
351 if(names_match(install_name
, libraryName
) == TRUE
)
352 return(dl
->dylib
.current_version
);
355 lc
= (struct load_command
*)((char *)lc
+ lc
->cmdsize
);
361 * This routine returns the current version of the named shared library the
362 * program it is running against. The libraryName parameter is the same as
363 * would be static link editor using the -lx or -framework Foo flags (with -lx
364 * it would be "x" and with -framework Foo it would be "Foo"). If the program
365 * is not using the specified library it returns -1.
368 NSVersionOfRunTimeLibrary(
369 const char* libraryName
)
371 unsigned long i
, j
, n
;
373 struct load_command
*load_commands
, *lc
;
374 struct dylib_command
*dl
;
375 const struct mach_header
*mh
;
377 n
= _dyld_image_count();
378 for(i
= 0; i
< n
; i
++){
379 mh
= _dyld_get_image_header(i
);
380 if(mh
->filetype
!= MH_DYLIB
)
382 load_commands
= (struct load_command
*)
384 ((char *)mh
+ sizeof(struct mach_header_64
));
386 ((char *)mh
+ sizeof(struct mach_header
));
389 for(j
= 0; j
< mh
->ncmds
; j
++){
390 if(lc
->cmd
== LC_ID_DYLIB
){
391 dl
= (struct dylib_command
*)lc
;
392 install_name
= (char *)dl
+ dl
->dylib
.name
.offset
;
393 if(names_match(install_name
, libraryName
) == TRUE
)
394 return(dl
->dylib
.current_version
);
396 lc
= (struct load_command
*)((char *)lc
+ lc
->cmdsize
);
402 #if DEPRECATED_APIS_SUPPORTED
404 * NSCreateObjectFileImageFromFile() creates an NSObjectFileImage for the
405 * specified file name if the file is a correct Mach-O file that can be loaded
406 * with NSloadModule(). For return codes of NSObjectFileImageFailure and
407 * NSObjectFileImageFormat an error message is printed to stderr. All
408 * other codes cause no printing.
410 NSObjectFileImageReturnCode
411 NSCreateObjectFileImageFromFile(
412 const char* pathName
,
413 NSObjectFileImage
*objectFileImage
)
415 DYLD_LOCK_THIS_BLOCK
;
416 static NSObjectFileImageReturnCode (*p
)(const char*, NSObjectFileImage
*) = NULL
;
419 _dyld_func_lookup("__dyld_NSCreateObjectFileImageFromFile", (void**)&p
);
420 return p(pathName
, objectFileImage
);
425 * NSCreateObjectFileImageFromMemory() creates an NSObjectFileImage for the
426 * object file mapped into memory at address of size length if the object file
427 * is a correct Mach-O file that can be loaded with NSloadModule(). For return
428 * codes of NSObjectFileImageFailure and NSObjectFileImageFormat an error
429 * message is printed to stderr. All other codes cause no printing.
431 NSObjectFileImageReturnCode
432 NSCreateObjectFileImageFromMemory(
435 NSObjectFileImage
*objectFileImage
)
437 DYLD_LOCK_THIS_BLOCK
;
438 static NSObjectFileImageReturnCode (*p
)(const void*, size_t, NSObjectFileImage
*) = NULL
;
441 _dyld_func_lookup("__dyld_NSCreateObjectFileImageFromMemory", (void**)&p
);
442 return p(address
, size
, objectFileImage
);
445 #if OBSOLETE_DYLD_API
447 * NSCreateCoreFileImageFromFile() creates an NSObjectFileImage for the
448 * specified core file name if the file is a correct Mach-O core file.
449 * For return codes of NSObjectFileImageFailure and NSObjectFileImageFormat
450 * an error message is printed to stderr. All other codes cause no printing.
452 NSObjectFileImageReturnCode
453 NSCreateCoreFileImageFromFile(
454 const char* pathName
,
455 NSObjectFileImage
*objectFileImage
)
457 DYLD_LOCK_THIS_BLOCK
;
458 static NSObjectFileImageReturnCode (*p
)(const char*, NSObjectFileImage
*) = NULL
;
461 _dyld_func_lookup("__dyld_NSCreateCoreFileImageFromFile", (void**)&p
);
462 return p(pathName
, objectFileImage
);
467 NSDestroyObjectFileImage(
468 NSObjectFileImage objectFileImage
)
470 DYLD_LOCK_THIS_BLOCK
;
471 static bool (*p
)(NSObjectFileImage
) = NULL
;
474 _dyld_func_lookup("__dyld_NSDestroyObjectFileImage", (void**)&p
);
475 return p(objectFileImage
);
481 NSObjectFileImage objectFileImage
,
482 const char* moduleName
,
485 DYLD_LOCK_THIS_BLOCK
;
486 static NSModule (*p
)(NSObjectFileImage
, const char*, unsigned long) = NULL
;
489 _dyld_func_lookup("__dyld_NSLinkModule", (void**)&p
);
491 return p(objectFileImage
, moduleName
, options
);
498 * NSSymbolDefinitionCountInObjectFileImage() returns the number of symbol
499 * definitions in the NSObjectFileImage.
502 NSSymbolDefinitionCountInObjectFileImage(
503 NSObjectFileImage objectFileImage
)
505 DYLD_LOCK_THIS_BLOCK
;
506 static unsigned long (*p
)(NSObjectFileImage
) = NULL
;
509 _dyld_func_lookup("__dyld_NSSymbolDefinitionCountInObjectFileImage", (void**)&p
);
511 return p(objectFileImage
);
515 * NSSymbolDefinitionNameInObjectFileImage() returns the name of the i'th
516 * symbol definitions in the NSObjectFileImage. If the ordinal specified is
517 * outside the range [0..NSSymbolDefinitionCountInObjectFileImage], NULL will
521 NSSymbolDefinitionNameInObjectFileImage(
522 NSObjectFileImage objectFileImage
,
525 DYLD_LOCK_THIS_BLOCK
;
526 static const char* (*p
)(NSObjectFileImage
, uint32_t) = NULL
;
529 _dyld_func_lookup("__dyld_NSSymbolDefinitionNameInObjectFileImage", (void**)&p
);
531 return p(objectFileImage
, ordinal
);
535 * NSSymbolReferenceCountInObjectFileImage() returns the number of references
536 * to undefined symbols the NSObjectFileImage.
539 NSSymbolReferenceCountInObjectFileImage(
540 NSObjectFileImage objectFileImage
)
542 DYLD_LOCK_THIS_BLOCK
;
543 static unsigned long (*p
)(NSObjectFileImage
) = NULL
;
546 _dyld_func_lookup("__dyld_NSSymbolReferenceCountInObjectFileImage", (void**)&p
);
548 return p(objectFileImage
);
552 * NSSymbolReferenceNameInObjectFileImage() returns the name of the i'th
553 * undefined symbol in the NSObjectFileImage. If the ordinal specified is
554 * outside the range [0..NSSymbolReferenceCountInObjectFileImage], NULL will be
558 NSSymbolReferenceNameInObjectFileImage(
559 NSObjectFileImage objectFileImage
,
561 bool *tentative_definition
) /* can be NULL */
563 DYLD_LOCK_THIS_BLOCK
;
564 static const char* (*p
)(NSObjectFileImage
, uint32_t, bool*) = NULL
;
567 _dyld_func_lookup("__dyld_NSSymbolReferenceNameInObjectFileImage", (void**)&p
);
569 return p(objectFileImage
, ordinal
, tentative_definition
);
573 * NSIsSymbolDefinedInObjectFileImage() returns TRUE if the specified symbol
574 * name has a definition in the NSObjectFileImage and FALSE otherwise.
577 NSIsSymbolDefinedInObjectFileImage(
578 NSObjectFileImage objectFileImage
,
579 const char* symbolName
)
581 DYLD_LOCK_THIS_BLOCK
;
582 static bool (*p
)(NSObjectFileImage
, const char*) = NULL
;
585 _dyld_func_lookup("__dyld_NSIsSymbolDefinedInObjectFileImage", (void**)&p
);
587 return p(objectFileImage
, symbolName
);
591 * NSGetSectionDataInObjectFileImage() returns a pointer to the section contents
592 * in the NSObjectFileImage for the specified segmentName and sectionName if
593 * it exists and it is not a zerofill section. If not it returns NULL. If
594 * the parameter size is not NULL the size of the section is also returned
595 * indirectly through that pointer.
598 NSGetSectionDataInObjectFileImage(
599 NSObjectFileImage objectFileImage
,
600 const char* segmentName
,
601 const char* sectionName
,
602 unsigned long *size
) /* can be NULL */
604 DYLD_LOCK_THIS_BLOCK
;
605 static void* (*p
)(NSObjectFileImage
, const char*, const char*, unsigned long*) = NULL
;
608 _dyld_func_lookup("__dyld_NSGetSectionDataInObjectFileImage", (void**)&p
);
610 return p(objectFileImage
, segmentName
, sectionName
, size
);
618 const char* *fileName
,
619 const char* *errorString
)
621 DYLD_LOCK_THIS_BLOCK
;
622 static void (*p
)(NSLinkEditErrors
*c
,
624 const char* *fileName
,
625 const char* *errorString
) = NULL
;
628 _dyld_func_lookup("__dyld_link_edit_error", (void**)&p
);
630 p(c
, errorNumber
, fileName
, errorString
);
638 DYLD_LOCK_THIS_BLOCK
;
639 static bool (*p
)(NSModule
module, uint32_t options
) = NULL
;
642 _dyld_func_lookup("__dyld_unlink_module", (void**)&p
);
644 return p(module, options
);
647 #if OBSOLETE_DYLD_API
650 NSModule moduleToReplace
,
651 NSObjectFileImage newObjectFileImage
,
659 #endif // DEPRECATED_APIS_SUPPORTED
662 *_NSGetExecutablePath copies the path of the executable into the buffer and
663 * returns 0 if the path was successfully copied in the provided buffer. If the
664 * buffer is not large enough, -1 is returned and the expected buffer size is
665 * copied in *bufsize. Note that _NSGetExecutablePath will return "a path" to
666 * the executable not a "real path" to the executable. That is the path may be
667 * a symbolic link and not the real file. And with deep directories the total
668 * bufsize needed could be more than MAXPATHLEN.
671 _NSGetExecutablePath(
675 DYLD_LOCK_THIS_BLOCK
;
676 static int (*p
)(char *buf
, uint32_t *bufsize
) = NULL
;
679 _dyld_func_lookup("__dyld__NSGetExecutablePath", (void**)&p
);
680 return(p(buf
, bufsize
));
683 #if DEPRECATED_APIS_SUPPORTED
685 _dyld_lookup_and_bind(
686 const char* symbol_name
,
690 DYLD_LOCK_THIS_BLOCK
;
691 static void (*p
)(const char*, void** , NSModule
*) = NULL
;
694 _dyld_func_lookup("__dyld_lookup_and_bind", (void**)&p
);
695 p(symbol_name
, address
, module);
699 _dyld_lookup_and_bind_with_hint(
700 const char* symbol_name
,
701 const char* library_name_hint
,
705 DYLD_LOCK_THIS_BLOCK
;
706 static void (*p
)(const char*, const char*, void**, NSModule
*) = NULL
;
709 _dyld_func_lookup("__dyld_lookup_and_bind_with_hint", (void**)&p
);
710 p(symbol_name
, library_name_hint
, address
, module);
713 #if OBSOLETE_DYLD_API
715 _dyld_lookup_and_bind_objc(
716 const char* symbol_name
,
720 DYLD_LOCK_THIS_BLOCK
;
721 static void (*p
)(const char* , void**, NSModule
*) = NULL
;
724 _dyld_func_lookup("__dyld_lookup_and_bind_objc", (void**)&p
);
725 p(symbol_name
, address
, module);
730 _dyld_lookup_and_bind_fully(
731 const char* symbol_name
,
735 DYLD_LOCK_THIS_BLOCK
;
736 static void (*p
)(const char*, void**, NSModule
*) = NULL
;
739 _dyld_func_lookup("__dyld_lookup_and_bind_fully", (void**)&p
);
740 p(symbol_name
, address
, module);
744 _dyld_bind_fully_image_containing_address(
747 DYLD_LOCK_THIS_BLOCK
;
748 static bool (*p
)(const void*) = NULL
;
751 _dyld_func_lookup("__dyld_bind_fully_image_containing_address", (void**)&p
);
754 #endif // DEPRECATED_APIS_SUPPORTED
758 * _dyld_register_func_for_add_image registers the specified function to be
759 * called when a new image is added (a bundle or a dynamic shared library) to
760 * the program. When this function is first registered it is called for once
761 * for each image that is currently part of the program.
764 _dyld_register_func_for_add_image(
765 void (*func
)(const struct mach_header
*mh
, intptr_t vmaddr_slide
))
767 DYLD_LOCK_THIS_BLOCK
;
768 static void (*p
)(void (*func
)(const struct mach_header
*mh
, intptr_t vmaddr_slide
)) = NULL
;
771 _dyld_func_lookup("__dyld_register_func_for_add_image", (void**)&p
);
776 * _dyld_register_func_for_remove_image registers the specified function to be
777 * called when an image is removed (a bundle or a dynamic shared library) from
781 _dyld_register_func_for_remove_image(
782 void (*func
)(const struct mach_header
*mh
, intptr_t vmaddr_slide
))
784 DYLD_LOCK_THIS_BLOCK
;
785 static void (*p
)(void (*func
)(const struct mach_header
*mh
, intptr_t vmaddr_slide
)) = NULL
;
788 _dyld_func_lookup("__dyld_register_func_for_remove_image", (void**)&p
);
792 #if OBSOLETE_DYLD_API
794 * _dyld_register_func_for_link_module registers the specified function to be
795 * called when a module is bound into the program. When this function is first
796 * registered it is called for once for each module that is currently bound into
800 _dyld_register_func_for_link_module(
801 void (*func
)(NSModule
module))
803 DYLD_LOCK_THIS_BLOCK
;
804 static void (*p
)(void (*func
)(NSModule
module)) = NULL
;
807 _dyld_func_lookup("__dyld_register_func_for_link_module", (void**)&p
);
812 * _dyld_register_func_for_unlink_module registers the specified function to be
813 * called when a module is unbound from the program.
816 _dyld_register_func_for_unlink_module(
817 void (*func
)(NSModule
module))
819 DYLD_LOCK_THIS_BLOCK
;
820 static void (*p
)(void (*func
)(NSModule
module)) = NULL
;
823 _dyld_func_lookup("__dyld_register_func_for_unlink_module", (void**)&p
);
828 * _dyld_register_func_for_replace_module registers the specified function to be
829 * called when a module is to be replace with another module in the program.
832 _dyld_register_func_for_replace_module(
833 void (*func
)(NSModule oldmodule
, NSModule newmodule
))
835 DYLD_LOCK_THIS_BLOCK
;
836 static void (*p
)(void (*func
)(NSModule oldmodule
,
837 NSModule newmodule
)) = NULL
;
840 _dyld_func_lookup("__dyld_register_func_for_replace_module", (void**)&p
);
846 * _dyld_get_objc_module_sect_for_module is passed a module and sets a
847 * pointer to the (__OBJC,__module) section and its size for the specified
851 _dyld_get_objc_module_sect_for_module(
856 DYLD_LOCK_THIS_BLOCK
;
857 static void (*p
)(NSModule
module,
859 unsigned long *size
) = NULL
;
862 _dyld_func_lookup("__dyld_get_objc_module_sect_for_module", (void**)&p
);
863 p(module, objc_module
, size
);
867 * _dyld_bind_objc_module() is passed a pointer to something in an (__OBJC,
868 * __module) section and causes the module that is associated with that address
872 _dyld_bind_objc_module(const void* objc_module
)
874 DYLD_LOCK_THIS_BLOCK
;
875 static void (*p
)(const void *objc_module
) = NULL
;
878 _dyld_func_lookup("__dyld_bind_objc_module", (void**)&p
);
883 #if DEPRECATED_APIS_SUPPORTED
887 // this function exists for compatiblity only
893 _dyld_image_count(void)
895 DYLD_NO_LOCK_THIS_BLOCK
;
896 static unsigned long (*p
)(void) = NULL
;
899 _dyld_func_lookup("__dyld_image_count", (void**)&p
);
903 const struct mach_header
*
904 _dyld_get_image_header(uint32_t image_index
)
906 DYLD_NO_LOCK_THIS_BLOCK
;
907 static struct mach_header
* (*p
)(uint32_t image_index
) = NULL
;
910 _dyld_func_lookup("__dyld_get_image_header", (void**)&p
);
911 return(p(image_index
));
915 _dyld_get_image_vmaddr_slide(uint32_t image_index
)
917 DYLD_NO_LOCK_THIS_BLOCK
;
918 static unsigned long (*p
)(uint32_t image_index
) = NULL
;
921 _dyld_func_lookup("__dyld_get_image_vmaddr_slide", (void**)&p
);
922 return(p(image_index
));
926 _dyld_get_image_name(uint32_t image_index
)
928 DYLD_NO_LOCK_THIS_BLOCK
;
929 static const char* (*p
)(uint32_t image_index
) = NULL
;
932 _dyld_func_lookup("__dyld_get_image_name", (void**)&p
);
933 return(p(image_index
));
936 // SPI in Mac OS X 10.6
937 intptr_t _dyld_get_image_slide(const struct mach_header
* mh
)
939 DYLD_NO_LOCK_THIS_BLOCK
;
940 static intptr_t (*p
)(const struct mach_header
*) = NULL
;
943 _dyld_func_lookup("__dyld_get_image_slide", (void**)&p
);
949 _dyld_image_containing_address(const void* address
)
951 DYLD_LOCK_THIS_BLOCK
;
952 static bool (*p
)(const void*) = NULL
;
955 _dyld_func_lookup("__dyld_image_containing_address", (void**)&p
);
959 const struct mach_header
*
960 _dyld_get_image_header_containing_address(
963 DYLD_LOCK_THIS_BLOCK
;
964 static const struct mach_header
* (*p
)(const void*) = NULL
;
967 _dyld_func_lookup("__dyld_get_image_header_containing_address", (void**)&p
);
972 void (*monaddition
)(char *lowpc
, char *highpc
))
974 DYLD_LOCK_THIS_BLOCK
;
975 static void (*p
)(void (*monaddition
)(char *lowpc
, char *highpc
)) = NULL
;
978 _dyld_func_lookup("__dyld_moninit", (void**)&p
);
982 #if DEPRECATED_APIS_SUPPORTED
983 bool _dyld_launched_prebound(void)
985 DYLD_LOCK_THIS_BLOCK
;
986 static bool (*p
)(void) = NULL
;
989 _dyld_func_lookup("__dyld_launched_prebound", (void**)&p
);
993 bool _dyld_all_twolevel_modules_prebound(void)
995 DYLD_LOCK_THIS_BLOCK
;
996 static bool (*p
)(void) = NULL
;
999 _dyld_func_lookup("__dyld_all_twolevel_modules_prebound", (void**)&p
);
1002 #endif // DEPRECATED_APIS_SUPPORTED
1007 #include <pthread.h>
1009 #include <mach-o/dyld.h>
1010 #include <servers/bootstrap.h>
1011 #include "dyldLibSystemInterface.h"
1014 // pthread key used to access per-thread dlerror message
1015 static pthread_key_t dlerrorPerThreadKey
;
1016 static bool dlerrorPerThreadKeyInitialized
= false;
1018 // data kept per-thread
1019 struct dlerrorPerThreadData
1021 uint32_t sizeAllocated
;
1025 // function called by dyld to get buffer to store dlerror message
1026 static char* getPerThreadBufferFor_dlerror(uint32_t sizeRequired
)
1028 // ok to create key lazily because this function is called within dyld lock, so there is no race condition
1029 if (!dlerrorPerThreadKeyInitialized
) {
1030 // create key and tell pthread package to call free() on any data associated with key if thread dies
1031 pthread_key_create(&dlerrorPerThreadKey
, &free
);
1032 dlerrorPerThreadKeyInitialized
= true;
1035 const int size
= (sizeRequired
< 256) ? 256 : sizeRequired
;
1036 dlerrorPerThreadData
* data
= (dlerrorPerThreadData
*)pthread_getspecific(dlerrorPerThreadKey
);
1037 if ( data
== NULL
) {
1038 //int mallocSize = offsetof(dlerrorPerThreadData, message[size]);
1039 const int mallocSize
= sizeof(dlerrorPerThreadData
)+size
;
1040 data
= (dlerrorPerThreadData
*)malloc(mallocSize
);
1041 data
->sizeAllocated
= size
;
1042 pthread_setspecific(dlerrorPerThreadKey
, data
);
1044 else if ( data
->sizeAllocated
< sizeRequired
) {
1046 //int mallocSize = offsetof(dlerrorPerThreadData, message[size]);
1047 const int mallocSize
= sizeof(dlerrorPerThreadData
)+size
;
1048 data
= (dlerrorPerThreadData
*)malloc(mallocSize
);
1049 data
->sizeAllocated
= size
;
1050 pthread_setspecific(dlerrorPerThreadKey
, data
);
1052 return data
->message
;
1056 #if DYLD_SHARED_CACHE_SUPPORT
1057 static void shared_cache_missing()
1059 // leave until dyld's that might call this are rare
1062 static void shared_cache_out_of_date()
1064 // leave until dyld's that might call this are rare
1066 #endif // DYLD_SHARED_CACHE_SUPPORT
1069 // the table passed to dyld containing thread helpers
1070 static dyld::LibSystemHelpers sHelpers
= { 6, &dyldGlobalLockAcquire
, &dyldGlobalLockRelease
,
1071 &getPerThreadBufferFor_dlerror
, &malloc
, &free
, &__cxa_atexit
,
1072 #if DYLD_SHARED_CACHE_SUPPORT
1073 &shared_cache_missing
, &shared_cache_out_of_date
,
1078 &pthread_key_create
, &pthread_setspecific
,
1083 // during initialization of libSystem this routine will run
1084 // and call dyld, registering the helper functions.
1086 extern "C" void _dyld_initializer() __attribute__((visibility("hidden")));
1087 void _dyld_initializer()
1089 DYLD_LOCK_INITIALIZER
;
1091 void (*p
)(dyld::LibSystemHelpers
*);
1093 _dyld_func_lookup("__dyld_register_thread_helpers", (void**)&p
);
1101 DYLD_LOCK_THIS_BLOCK
;
1102 static char* (*p
)() = NULL
;
1105 _dyld_func_lookup("__dyld_dlerror", (void**)&p
);
1109 int dladdr(const void* addr
, Dl_info
* info
)
1111 DYLD_LOCK_THIS_BLOCK
;
1112 static int (*p
)(const void* , Dl_info
*) = NULL
;
1115 _dyld_func_lookup("__dyld_dladdr", (void**)&p
);
1116 return(p(addr
, info
));
1119 int dlclose(void* handle
)
1121 DYLD_LOCK_THIS_BLOCK
;
1122 static int (*p
)(void* handle
) = NULL
;
1125 _dyld_func_lookup("__dyld_dlclose", (void**)&p
);
1129 void* dlopen(const char* path
, int mode
)
1131 // dlopen is special. locking is done inside dyld to allow initializer to run without lock
1132 DYLD_NO_LOCK_THIS_BLOCK
;
1134 static void* (*p
)(const char* path
, int) = NULL
;
1137 _dyld_func_lookup("__dyld_dlopen", (void**)&p
);
1138 void* result
= p(path
, mode
);
1139 // use asm block to prevent tail call optimization
1140 // this is needed because dlopen uses __builtin_return_address() and depends on this glue being in the frame chain
1141 // <rdar://problem/5313172 dlopen() looks too far up stack, can cause crash>
1142 __asm__
volatile("");
1147 bool dlopen_preflight(const char* path
)
1149 DYLD_LOCK_THIS_BLOCK
;
1150 static bool (*p
)(const char* path
) = NULL
;
1153 _dyld_func_lookup("__dyld_dlopen_preflight", (void**)&p
);
1157 void* dlsym(void* handle
, const char* symbol
)
1159 DYLD_LOCK_THIS_BLOCK
;
1160 static void* (*p
)(void* handle
, const char* symbol
) = NULL
;
1163 _dyld_func_lookup("__dyld_dlsym", (void**)&p
);
1164 return(p(handle
, symbol
));
1167 void dyld_register_image_state_change_handler(dyld_image_states state
,
1168 bool batch
, dyld_image_state_change_handler handler
)
1170 DYLD_LOCK_THIS_BLOCK
;
1171 static void* (*p
)(dyld_image_states
, bool, dyld_image_state_change_handler
) = NULL
;
1174 _dyld_func_lookup("__dyld_dyld_register_image_state_change_handler", (void**)&p
);
1175 p(state
, batch
, handler
);
1179 const struct dyld_all_image_infos
* _dyld_get_all_image_infos()
1181 DYLD_NO_LOCK_THIS_BLOCK
;
1182 static struct dyld_all_image_infos
* (*p
)() = NULL
;
1185 _dyld_func_lookup("__dyld_get_all_image_infos", (void**)&p
);
1190 __attribute__((visibility("hidden")))
1191 bool _dyld_find_unwind_sections(void* addr
, dyld_unwind_sections
* info
)
1193 DYLD_NO_LOCK_THIS_BLOCK
;
1194 static void* (*p
)(void*, dyld_unwind_sections
*) = NULL
;
1197 _dyld_func_lookup("__dyld_find_unwind_sections", (void**)&p
);
1198 return p(addr
, info
);
1203 #if __i386__ || __x86_64__
1204 __attribute__((visibility("hidden")))
1205 void* _dyld_fast_stub_entry(void* loadercache
, long lazyinfo
)
1207 DYLD_NO_LOCK_THIS_BLOCK
;
1208 static void* (*p
)(void*, long) = NULL
;
1211 _dyld_func_lookup("__dyld_fast_stub_entry", (void**)&p
);
1212 return p(loadercache
, lazyinfo
);
1217 const char* dyld_image_path_containing_address(const void* addr
)
1219 DYLD_NO_LOCK_THIS_BLOCK
;
1220 static const char* (*p
)(const void*) = NULL
;
1223 _dyld_func_lookup("__dyld_image_path_containing_address", (void**)&p
);