1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
3 * Copyright (c) 2004-2005 Apple Computer, 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 <crt_externs.h>
29 #include "mach-o/dyld.h"
30 #include "mach-o/dyld_priv.h"
35 * names_match() takes an install_name from an LC_LOAD_DYLIB command and a
36 * libraryName (which is -lx or -framework Foo argument passed to the static
37 * link editor for the same library) and determines if they match. This depends
38 * on conventional use of names including major versioning.
44 const char* libraryName
)
50 * Conventional install names have these forms:
51 * /System/Library/Frameworks/AppKit.framework/Versions/A/Appkit
52 * /Local/Library/Frameworks/AppKit.framework/Appkit
53 * /lib/libsys_s.A.dylib
54 * /usr/lib/libsys_s.dylib
56 basename
= strrchr(install_name
, '/');
58 basename
= install_name
;
63 * By checking the base name matching the library name we take care
64 * of the -framework cases.
66 if(strcmp(basename
, libraryName
) == 0)
70 * Now check the base name for "lib" if so proceed to check for the
71 * -lx case dealing with a possible .X.dylib and a .dylib extension.
73 if(strncmp(basename
, "lib", 3) ==0){
74 n
= strlen(libraryName
);
75 if(strncmp(basename
+3, libraryName
, n
) == 0){
76 if(strncmp(basename
+3+n
, ".dylib", 6) == 0)
78 if(basename
[3+n
] == '.' &&
79 basename
[3+n
+1] != '\0' &&
80 strncmp(basename
+3+n
+2, ".dylib", 6) == 0)
87 void NSInstallLinkEditErrorHandlers(
88 const NSLinkEditErrorHandlers
* handlers
)
90 DYLD_WRITER_LOCK_THIS_BLOCK
;
92 void (*undefined
)(const char* symbol_name
),
93 NSModule (*multiple
)(NSSymbol s
, NSModule old
, NSModule newhandler
),
94 void (*linkEdit
)(NSLinkEditErrors c
, int errorNumber
,
95 const char* fileName
, const char* errorString
)) = NULL
;
98 _dyld_func_lookup("__dyld_install_handlers", (void**)&p
);
99 p(handlers
->undefined
, handlers
->multiple
, handlers
->linkEdit
);
106 DYLD_READER_LOCK_THIS_BLOCK
;
107 static const char* (*p
)(NSModule
module) = NULL
;
110 _dyld_func_lookup("__dyld_NSNameOfModule", (void**)&p
);
115 NSLibraryNameForModule(
118 DYLD_READER_LOCK_THIS_BLOCK
;
119 static const char* (*p
)(NSModule
module) = NULL
;
122 _dyld_func_lookup("__dyld_NSLibraryNameForModule", (void**)&p
);
127 NSIsSymbolNameDefined(
128 const char* symbolName
)
130 DYLD_READER_LOCK_THIS_BLOCK
;
131 static bool (*p
)(const char* symbolName
) = NULL
;
134 _dyld_func_lookup("__dyld_NSIsSymbolNameDefined", (void**)&p
);
135 return(p(symbolName
));
139 NSIsSymbolNameDefinedWithHint(
140 const char* symbolName
,
141 const char* libraryNameHint
)
143 DYLD_READER_LOCK_THIS_BLOCK
;
144 static bool (*p
)(const char* symbolName
,
145 const char* libraryNameHint
) = NULL
;
148 _dyld_func_lookup("__dyld_NSIsSymbolNameDefinedWithHint", (void**)&p
);
149 return(p(symbolName
, libraryNameHint
));
153 NSIsSymbolNameDefinedInImage(
154 const struct mach_header
*image
,
155 const char* symbolName
)
157 DYLD_READER_LOCK_THIS_BLOCK
;
158 static bool (*p
)(const struct mach_header
*image
,
159 const char* symbolName
) = NULL
;
162 _dyld_func_lookup("__dyld_NSIsSymbolNameDefinedInImage", (void**)&p
);
163 return(p(image
, symbolName
));
167 NSLookupAndBindSymbol(
168 const char* symbolName
)
170 DYLD_WRITER_LOCK_THIS_BLOCK
;
171 static NSSymbol (*p
)(const char* symbolName
) = NULL
;
174 _dyld_func_lookup("__dyld_NSLookupAndBindSymbol", (void**)&p
);
175 return(p(symbolName
));
179 NSLookupAndBindSymbolWithHint(
180 const char* symbolName
,
181 const char* libraryNameHint
)
183 DYLD_WRITER_LOCK_THIS_BLOCK
;
184 static NSSymbol (*p
)(const char* symbolName
,
185 const char* libraryNameHint
) = NULL
;
188 _dyld_func_lookup("__dyld_NSLookupAndBindSymbolWithHint", (void**)&p
);
189 return(p(symbolName
, libraryNameHint
));
193 NSLookupSymbolInModule(
195 const char* symbolName
)
197 DYLD_READER_LOCK_THIS_BLOCK
;
198 static NSSymbol (*p
)(NSModule
module, const char* symbolName
) = NULL
;
201 _dyld_func_lookup("__dyld_NSLookupSymbolInModule", (void**)&p
);
202 return(p(module, symbolName
));
206 NSLookupSymbolInImage(
207 const struct mach_header
*image
,
208 const char* symbolName
,
211 DYLD_READER_LOCK_THIS_BLOCK
;
212 static NSSymbol (*p
)(const struct mach_header
*image
,
213 const char* symbolName
,
214 uint32_t options
) = NULL
;
217 _dyld_func_lookup("__dyld_NSLookupSymbolInImage", (void**)&p
);
218 return(p(image
, symbolName
, options
));
225 DYLD_READER_LOCK_THIS_BLOCK
;
226 static char * (*p
)(NSSymbol symbol
) = NULL
;
229 _dyld_func_lookup("__dyld_NSNameOfSymbol",(void**)&p
);
237 DYLD_READER_LOCK_THIS_BLOCK
;
238 static void * (*p
)(NSSymbol symbol
) = NULL
;
241 _dyld_func_lookup("__dyld_NSAddressOfSymbol", (void**)&p
);
249 DYLD_READER_LOCK_THIS_BLOCK
;
250 static NSModule (*p
)(NSSymbol symbol
) = NULL
;
253 _dyld_func_lookup("__dyld_NSModuleForSymbol", (void**)&p
);
259 const char* pathName
)
261 DYLD_WRITER_LOCK_THIS_BLOCK
;
262 static bool (*p
)(const char* pathName
) = NULL
;
265 _dyld_func_lookup("__dyld_NSAddLibrary", (void**)&p
);
270 NSAddLibraryWithSearching(
271 const char* pathName
)
273 DYLD_WRITER_LOCK_THIS_BLOCK
;
274 static bool (*p
)(const char* pathName
) = NULL
;
277 _dyld_func_lookup("__dyld_NSAddLibraryWithSearching", (void**)&p
);
281 const struct mach_header
*
283 const char* image_name
,
286 DYLD_WRITER_LOCK_THIS_BLOCK
;
287 static const struct mach_header
* (*p
)(const char* image_name
,
288 uint32_t options
) = NULL
;
291 _dyld_func_lookup("__dyld_NSAddImage", (void**)&p
);
292 return(p(image_name
, options
));
296 * This routine returns the current version of the named shared library the
297 * executable it was built with. The libraryName parameter is the same as the
298 * -lx or -framework Foo argument passed to the static link editor when building
299 * the executable (with -lx it would be "x" and with -framework Foo it would be
300 * "Foo"). If this the executable was not built against the specified library
301 * it returns -1. It should be noted that if this only returns the value the
302 * current version of the named shared library the executable was built with
303 * and not a list of current versions that dependent libraries and bundles the
304 * program is using were built with.
307 NSVersionOfLinkTimeLibrary(
308 const char* libraryName
)
311 struct load_command
*load_commands
, *lc
;
312 struct dylib_command
*dl
;
315 static struct mach_header
*mh
= NULL
;
317 mh
= _NSGetMachExecuteHeader();
318 #else /* defined(__OPENSTEP__) */
320 static struct mach_header
*mh
= NULL
;
322 _dyld_lookup_and_bind("__mh_execute_header", &mh
, NULL
);
324 struct mach_header
*mh
;
325 mh
= (struct mach_header
*)&_mh_execute_header
;
327 #endif /* __OPENSTEP__ */
328 load_commands
= (struct load_command
*)
329 ((char *)mh
+ sizeof(struct mach_header
));
331 for(i
= 0; i
< mh
->ncmds
; i
++){
332 if(lc
->cmd
== LC_LOAD_DYLIB
){
333 dl
= (struct dylib_command
*)lc
;
334 install_name
= (char *)dl
+ dl
->dylib
.name
.offset
;
335 if(names_match(install_name
, libraryName
) == TRUE
)
336 return(dl
->dylib
.current_version
);
338 lc
= (struct load_command
*)((char *)lc
+ lc
->cmdsize
);
344 * This routine returns the current version of the named shared library the
345 * program it is running against. The libraryName parameter is the same as
346 * would be static link editor using the -lx or -framework Foo flags (with -lx
347 * it would be "x" and with -framework Foo it would be "Foo"). If the program
348 * is not using the specified library it returns -1.
351 NSVersionOfRunTimeLibrary(
352 const char* libraryName
)
354 unsigned long i
, j
, n
;
356 struct load_command
*load_commands
, *lc
;
357 struct dylib_command
*dl
;
358 const struct mach_header
*mh
;
360 n
= _dyld_image_count();
361 for(i
= 0; i
< n
; i
++){
362 mh
= _dyld_get_image_header(i
);
363 if(mh
->filetype
!= MH_DYLIB
)
365 load_commands
= (struct load_command
*)
366 ((char *)mh
+ sizeof(struct mach_header
));
368 for(j
= 0; j
< mh
->ncmds
; j
++){
369 if(lc
->cmd
== LC_ID_DYLIB
){
370 dl
= (struct dylib_command
*)lc
;
371 install_name
= (char *)dl
+ dl
->dylib
.name
.offset
;
372 if(names_match(install_name
, libraryName
) == TRUE
)
373 return(dl
->dylib
.current_version
);
375 lc
= (struct load_command
*)((char *)lc
+ lc
->cmdsize
);
382 * NSCreateObjectFileImageFromFile() creates an NSObjectFileImage for the
383 * specified file name if the file is a correct Mach-O file that can be loaded
384 * with NSloadModule(). For return codes of NSObjectFileImageFailure and
385 * NSObjectFileImageFormat an error message is printed to stderr. All
386 * other codes cause no printing.
388 NSObjectFileImageReturnCode
389 NSCreateObjectFileImageFromFile(
390 const char* pathName
,
391 NSObjectFileImage
*objectFileImage
)
393 DYLD_WRITER_LOCK_THIS_BLOCK
;
394 static NSObjectFileImageReturnCode (*p
)(const char*, NSObjectFileImage
*) = NULL
;
397 _dyld_func_lookup("__dyld_NSCreateObjectFileImageFromFile", (void**)&p
);
398 return p(pathName
, objectFileImage
);
403 * NSCreateObjectFileImageFromMemory() creates an NSObjectFileImage for the
404 * object file mapped into memory at address of size length if the object file
405 * is a correct Mach-O file that can be loaded with NSloadModule(). For return
406 * codes of NSObjectFileImageFailure and NSObjectFileImageFormat an error
407 * message is printed to stderr. All other codes cause no printing.
409 NSObjectFileImageReturnCode
410 NSCreateObjectFileImageFromMemory(
413 NSObjectFileImage
*objectFileImage
)
415 DYLD_WRITER_LOCK_THIS_BLOCK
;
416 static NSObjectFileImageReturnCode (*p
)(const void*, size_t, NSObjectFileImage
*) = NULL
;
419 _dyld_func_lookup("__dyld_NSCreateObjectFileImageFromMemory", (void**)&p
);
420 return p(address
, size
, objectFileImage
);
424 * NSCreateCoreFileImageFromFile() creates an NSObjectFileImage for the
425 * specified core file name if the file is a correct Mach-O core file.
426 * For return codes of NSObjectFileImageFailure and NSObjectFileImageFormat
427 * an error message is printed to stderr. All other codes cause no printing.
429 NSObjectFileImageReturnCode
430 NSCreateCoreFileImageFromFile(
431 const char* pathName
,
432 NSObjectFileImage
*objectFileImage
)
434 DYLD_WRITER_LOCK_THIS_BLOCK
;
435 static NSObjectFileImageReturnCode (*p
)(const char*, NSObjectFileImage
*) = NULL
;
438 _dyld_func_lookup("__dyld_NSCreateCoreFileImageFromFile", (void**)&p
);
439 return p(pathName
, objectFileImage
);
443 NSDestroyObjectFileImage(
444 NSObjectFileImage objectFileImage
)
446 DYLD_WRITER_LOCK_THIS_BLOCK
;
447 static bool (*p
)(NSObjectFileImage
) = NULL
;
450 _dyld_func_lookup("__dyld_NSDestroyObjectFileImage", (void**)&p
);
451 return p(objectFileImage
);
457 NSObjectFileImage objectFileImage
,
458 const char* moduleName
,
461 DYLD_WRITER_LOCK_THIS_BLOCK
;
462 static NSModule (*p
)(NSObjectFileImage
, const char*, unsigned long) = NULL
;
465 _dyld_func_lookup("__dyld_NSLinkModule", (void**)&p
);
467 return p(objectFileImage
, moduleName
, options
);
472 * NSFindSectionAndOffsetInObjectFileImage() takes the specified imageOffset
473 * into the specified ObjectFileImage and returns the segment/section name and
474 * offset into that section of that imageOffset. Returns FALSE if the
475 * imageOffset is not in any section. You can used the resulting sectionOffset
476 * to index into the data returned by NSGetSectionDataInObjectFileImage.
478 * SPI: currently only used by ZeroLink to detect +load methods
481 NSFindSectionAndOffsetInObjectFileImage(
482 NSObjectFileImage objectFileImage
,
483 unsigned long imageOffset
,
484 const char** segmentName
, /* can be NULL */
485 const char** sectionName
, /* can be NULL */
486 unsigned long* sectionOffset
) /* can be NULL */
488 DYLD_READER_LOCK_THIS_BLOCK
;
489 static bool (*p
)(NSObjectFileImage
, unsigned long, const char**, const char**, unsigned long*) = NULL
;
492 _dyld_func_lookup("__dyld_NSFindSectionAndOffsetInObjectFileImage", (void**)&p
);
494 return p(objectFileImage
, imageOffset
, segmentName
, sectionName
, sectionOffset
);
499 * NSSymbolDefinitionCountInObjectFileImage() returns the number of symbol
500 * definitions in the NSObjectFileImage.
503 NSSymbolDefinitionCountInObjectFileImage(
504 NSObjectFileImage objectFileImage
)
506 DYLD_READER_LOCK_THIS_BLOCK
;
507 static unsigned long (*p
)(NSObjectFileImage
) = NULL
;
510 _dyld_func_lookup("__dyld_NSSymbolDefinitionCountInObjectFileImage", (void**)&p
);
512 return p(objectFileImage
);
516 * NSSymbolDefinitionNameInObjectFileImage() returns the name of the i'th
517 * symbol definitions in the NSObjectFileImage. If the ordinal specified is
518 * outside the range [0..NSSymbolDefinitionCountInObjectFileImage], NULL will
522 NSSymbolDefinitionNameInObjectFileImage(
523 NSObjectFileImage objectFileImage
,
526 DYLD_READER_LOCK_THIS_BLOCK
;
527 static const char* (*p
)(NSObjectFileImage
, uint32_t) = NULL
;
530 _dyld_func_lookup("__dyld_NSSymbolDefinitionNameInObjectFileImage", (void**)&p
);
532 return p(objectFileImage
, ordinal
);
536 * NSSymbolReferenceCountInObjectFileImage() returns the number of references
537 * to undefined symbols the NSObjectFileImage.
540 NSSymbolReferenceCountInObjectFileImage(
541 NSObjectFileImage objectFileImage
)
543 DYLD_READER_LOCK_THIS_BLOCK
;
544 static unsigned long (*p
)(NSObjectFileImage
) = NULL
;
547 _dyld_func_lookup("__dyld_NSSymbolReferenceCountInObjectFileImage", (void**)&p
);
549 return p(objectFileImage
);
553 * NSSymbolReferenceNameInObjectFileImage() returns the name of the i'th
554 * undefined symbol in the NSObjectFileImage. If the ordinal specified is
555 * outside the range [0..NSSymbolReferenceCountInObjectFileImage], NULL will be
559 NSSymbolReferenceNameInObjectFileImage(
560 NSObjectFileImage objectFileImage
,
562 bool *tentative_definition
) /* can be NULL */
564 DYLD_READER_LOCK_THIS_BLOCK
;
565 static const char* (*p
)(NSObjectFileImage
, uint32_t, bool*) = NULL
;
568 _dyld_func_lookup("__dyld_NSSymbolReferenceNameInObjectFileImage", (void**)&p
);
570 return p(objectFileImage
, ordinal
, tentative_definition
);
574 * NSIsSymbolDefinedInObjectFileImage() returns TRUE if the specified symbol
575 * name has a definition in the NSObjectFileImage and FALSE otherwise.
578 NSIsSymbolDefinedInObjectFileImage(
579 NSObjectFileImage objectFileImage
,
580 const char* symbolName
)
582 DYLD_READER_LOCK_THIS_BLOCK
;
583 static bool (*p
)(NSObjectFileImage
, const char*) = NULL
;
586 _dyld_func_lookup("__dyld_NSIsSymbolDefinedInObjectFileImage", (void**)&p
);
588 return p(objectFileImage
, symbolName
);
592 * NSGetSectionDataInObjectFileImage() returns a pointer to the section contents
593 * in the NSObjectFileImage for the specified segmentName and sectionName if
594 * it exists and it is not a zerofill section. If not it returns NULL. If
595 * the parameter size is not NULL the size of the section is also returned
596 * indirectly through that pointer.
599 NSGetSectionDataInObjectFileImage(
600 NSObjectFileImage objectFileImage
,
601 const char* segmentName
,
602 const char* sectionName
,
603 unsigned long *size
) /* can be NULL */
605 DYLD_READER_LOCK_THIS_BLOCK
;
606 static void* (*p
)(NSObjectFileImage
, const char*, const char*, unsigned long*) = NULL
;
609 _dyld_func_lookup("__dyld_NSGetSectionDataInObjectFileImage", (void**)&p
);
611 return p(objectFileImage
, segmentName
, sectionName
, size
);
615 * NSHasModInitObjectFileImage() returns TRUE if the NSObjectFileImage has any
616 * module initialization sections and FALSE it it does not.
618 * SPI: currently only used by ZeroLink to detect C++ initializers
621 NSHasModInitObjectFileImage(
622 NSObjectFileImage objectFileImage
)
624 DYLD_READER_LOCK_THIS_BLOCK
;
625 static bool (*p
)(NSObjectFileImage
) = NULL
;
628 _dyld_func_lookup("__dyld_NSHasModInitObjectFileImage", (void**)&p
);
630 return p(objectFileImage
);
637 const char* *fileName
,
638 const char* *errorString
)
640 DYLD_WRITER_LOCK_THIS_BLOCK
;
641 static void (*p
)(NSLinkEditErrors
*c
,
643 const char* *fileName
,
644 const char* *errorString
) = NULL
;
647 _dyld_func_lookup("__dyld_link_edit_error", (void**)&p
);
649 p(c
, errorNumber
, fileName
, errorString
);
657 DYLD_WRITER_LOCK_THIS_BLOCK
;
658 static bool (*p
)(NSModule
module, uint32_t options
) = NULL
;
661 _dyld_func_lookup("__dyld_unlink_module", (void**)&p
);
663 return p(module, options
);
668 NSModule moduleToReplace
,
669 NSObjectFileImage newObjectFileImage
,
676 *_NSGetExecutablePath copies the path of the executable into the buffer and
677 * returns 0 if the path was successfully copied in the provided buffer. If the
678 * buffer is not large enough, -1 is returned and the expected buffer size is
679 * copied in *bufsize. Note that _NSGetExecutablePath will return "a path" to
680 * the executable not a "real path" to the executable. That is the path may be
681 * a symbolic link and not the real file. And with deep directories the total
682 * bufsize needed could be more than MAXPATHLEN.
685 _NSGetExecutablePath(
689 DYLD_READER_LOCK_THIS_BLOCK
;
690 static int (*p
)(char *buf
, uint32_t *bufsize
) = NULL
;
693 _dyld_func_lookup("__dyld__NSGetExecutablePath", (void**)&p
);
694 return(p(buf
, bufsize
));
698 _dyld_lookup_and_bind(
699 const char* symbol_name
,
703 DYLD_WRITER_LOCK_THIS_BLOCK
;
704 static void (*p
)(const char*, void** , NSModule
*) = NULL
;
707 _dyld_func_lookup("__dyld_lookup_and_bind", (void**)&p
);
708 p(symbol_name
, address
, module);
712 _dyld_lookup_and_bind_with_hint(
713 const char* symbol_name
,
714 const char* library_name_hint
,
718 DYLD_WRITER_LOCK_THIS_BLOCK
;
719 static void (*p
)(const char*, const char*, void**, NSModule
*) = NULL
;
722 _dyld_func_lookup("__dyld_lookup_and_bind_with_hint", (void**)&p
);
723 p(symbol_name
, library_name_hint
, address
, module);
727 _dyld_lookup_and_bind_objc(
728 const char* symbol_name
,
732 DYLD_WRITER_LOCK_THIS_BLOCK
;
733 static void (*p
)(const char* , void**, NSModule
*) = NULL
;
736 _dyld_func_lookup("__dyld_lookup_and_bind_objc", (void**)&p
);
737 p(symbol_name
, address
, module);
741 _dyld_lookup_and_bind_fully(
742 const char* symbol_name
,
746 DYLD_WRITER_LOCK_THIS_BLOCK
;
747 static void (*p
)(const char*, void**, NSModule
*) = NULL
;
750 _dyld_func_lookup("__dyld_lookup_and_bind_fully", (void**)&p
);
751 p(symbol_name
, address
, module);
755 _dyld_bind_fully_image_containing_address(
758 DYLD_WRITER_LOCK_THIS_BLOCK
;
759 static bool (*p
)(const void*) = NULL
;
762 _dyld_func_lookup("__dyld_bind_fully_image_containing_address", (void**)&p
);
768 * _dyld_register_func_for_add_image registers the specified function to be
769 * called when a new image is added (a bundle or a dynamic shared library) to
770 * the program. When this function is first registered it is called for once
771 * for each image that is currently part of the program.
774 _dyld_register_func_for_add_image(
775 void (*func
)(const struct mach_header
*mh
, intptr_t vmaddr_slide
))
777 DYLD_WRITER_LOCK_THIS_BLOCK
;
778 static void (*p
)(void (*func
)(const struct mach_header
*mh
, intptr_t vmaddr_slide
)) = NULL
;
781 _dyld_func_lookup("__dyld_register_func_for_add_image", (void**)&p
);
786 * _dyld_register_func_for_remove_image registers the specified function to be
787 * called when an image is removed (a bundle or a dynamic shared library) from
791 _dyld_register_func_for_remove_image(
792 void (*func
)(const struct mach_header
*mh
, intptr_t vmaddr_slide
))
794 DYLD_WRITER_LOCK_THIS_BLOCK
;
795 static void (*p
)(void (*func
)(const struct mach_header
*mh
, intptr_t vmaddr_slide
)) = NULL
;
798 _dyld_func_lookup("__dyld_register_func_for_remove_image", (void**)&p
);
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_WRITER_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_WRITER_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_WRITER_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_READER_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(
882 const void* objc_module
)
884 DYLD_READER_LOCK_THIS_BLOCK
;
885 static void (*p
)(const void *objc_module
) = NULL
;
888 _dyld_func_lookup("__dyld_bind_objc_module", (void**)&p
);
898 // hmmm, this code is in libSystem.dylib, which is loaded by dyld...
907 DYLD_NO_LOCK_THIS_BLOCK
;
908 static unsigned long (*p
)(void) = NULL
;
910 if(_dyld_present() == 0)
913 _dyld_func_lookup("__dyld_image_count", (void**)&p
);
917 const struct mach_header
*
918 _dyld_get_image_header(
919 uint32_t image_index
)
921 DYLD_NO_LOCK_THIS_BLOCK
;
922 static struct mach_header
* (*p
)(uint32_t image_index
) = NULL
;
925 _dyld_func_lookup("__dyld_get_image_header", (void**)&p
);
926 return(p(image_index
));
930 _dyld_get_image_vmaddr_slide(
931 uint32_t image_index
)
933 DYLD_NO_LOCK_THIS_BLOCK
;
934 static unsigned long (*p
)(uint32_t image_index
) = NULL
;
937 _dyld_func_lookup("__dyld_get_image_vmaddr_slide", (void**)&p
);
938 return(p(image_index
));
942 _dyld_get_image_name(
943 uint32_t image_index
)
945 DYLD_NO_LOCK_THIS_BLOCK
;
946 static const char* (*p
)(uint32_t image_index
) = NULL
;
949 _dyld_func_lookup("__dyld_get_image_name", (void**)&p
);
950 return(p(image_index
));
954 _dyld_image_containing_address(
957 DYLD_READER_LOCK_THIS_BLOCK
;
958 static bool (*p
)(const void*) = NULL
;
961 _dyld_func_lookup("__dyld_image_containing_address", (void**)&p
);
965 const struct mach_header
*
966 _dyld_get_image_header_containing_address(
969 DYLD_READER_LOCK_THIS_BLOCK
;
970 static const struct mach_header
* (*p
)(const void*) = NULL
;
973 _dyld_func_lookup("__dyld_get_image_header_containing_address", (void**)&p
);
978 void (*monaddition
)(char *lowpc
, char *highpc
))
980 DYLD_READER_LOCK_THIS_BLOCK
;
981 static void (*p
)(void (*monaddition
)(char *lowpc
, char *highpc
)) = NULL
;
984 _dyld_func_lookup("__dyld_moninit", (void**)&p
);
988 bool _dyld_launched_prebound(
991 DYLD_READER_LOCK_THIS_BLOCK
;
992 static bool (*p
)(void) = NULL
;
995 _dyld_func_lookup("__dyld_launched_prebound", (void**)&p
);
999 bool _dyld_all_twolevel_modules_prebound(
1002 DYLD_READER_LOCK_THIS_BLOCK
;
1003 static bool (*p
)(void) = NULL
;
1006 _dyld_func_lookup("__dyld_all_twolevel_modules_prebound", (void**)&p
);
1013 #include <pthread.h>
1015 #include <mach-o/dyld.h>
1016 #include "dyldLock.h"
1017 #include "dyldLibSystemThreadHelpers.h"
1019 // pthread key used to access per-thread dlerror message
1020 static pthread_key_t dlerrorPerThreadKey
;
1022 // data kept per-thread
1023 struct dlerrorPerThreadData
1025 uint32_t sizeAllocated
;
1029 // function called by dyld to get buffer to store dlerror message
1030 static char* getPerThreadBufferFor_dlerror(uint32_t sizeRequired
)
1032 const int size
= (sizeRequired
< 256) ? 256 : sizeRequired
;
1033 dlerrorPerThreadData
* data
= (dlerrorPerThreadData
*)pthread_getspecific(dlerrorPerThreadKey
);
1034 if ( data
== NULL
) {
1035 //int mallocSize = offsetof(dlerrorPerThreadData, message[size]);
1036 const int mallocSize
= sizeof(dlerrorPerThreadData
)+size
;
1037 data
= (dlerrorPerThreadData
*)malloc(mallocSize
);
1038 data
->sizeAllocated
= size
;
1039 pthread_setspecific(dlerrorPerThreadKey
, data
);
1041 else if ( data
->sizeAllocated
< sizeRequired
) {
1043 //int mallocSize = offsetof(dlerrorPerThreadData, message[size]);
1044 const int mallocSize
= sizeof(dlerrorPerThreadData
)+size
;
1045 data
= (dlerrorPerThreadData
*)malloc(mallocSize
);
1046 data
->sizeAllocated
= size
;
1047 pthread_setspecific(dlerrorPerThreadKey
, data
);
1049 return data
->message
;
1052 // that table passed to dyld containing thread helpers
1053 static dyld::ThreadingHelpers sThreadHelpers
= { 1, &lockForLazyBinding
, &unlockForLazyBinding
, &getPerThreadBufferFor_dlerror
};
1056 // during initialization of libSystem this routine will run
1057 // and call dyld, registering the threading helpers.
1060 static int registerWithDyld()
1062 static void (*p
)(dyld::ThreadingHelpers
*) = NULL
;
1064 // create key and tell pthread package to call free() on any data associated with key if thread dies
1065 pthread_key_create(&dlerrorPerThreadKey
, &free
);
1068 _dyld_func_lookup("__dyld_register_thread_helpers", (void**)&p
);
1075 // should be able to use __attribute__((constructor)) on registerWithDyld, but compiler has bug (3679135)
1076 // instead use initialization of global to force it to run.
1077 static int hack
= registerWithDyld();
1082 DYLD_READER_LOCK_THIS_BLOCK
;
1083 static char* (*p
)() = NULL
;
1086 _dyld_func_lookup("__dyld_dlerror", (void**)&p
);
1090 int dladdr(const void* addr
, Dl_info
* info
)
1092 DYLD_READER_LOCK_THIS_BLOCK
;
1093 static int (*p
)(const void* , Dl_info
*) = NULL
;
1096 _dyld_func_lookup("__dyld_dladdr", (void**)&p
);
1097 return(p(addr
, info
));
1100 int dlclose(void* handle
)
1102 DYLD_WRITER_LOCK_THIS_BLOCK
;
1103 static int (*p
)(void* handle
) = NULL
;
1106 _dyld_func_lookup("__dyld_dlclose", (void**)&p
);
1110 void* dlopen(const char* path
, int mode
)
1112 DYLD_WRITER_LOCK_THIS_BLOCK
;
1113 static void* (*p
)(const char* path
, int) = NULL
;
1116 _dyld_func_lookup("__dyld_dlopen", (void**)&p
);
1117 return(p(path
, mode
));
1120 void* dlsym(void* handle
, const char* symbol
)
1122 DYLD_READER_LOCK_THIS_BLOCK
;
1123 static void* (*p
)(void* handle
, const char* symbol
) = NULL
;
1126 _dyld_func_lookup("__dyld_dlsym", (void**)&p
);
1127 return(p(handle
, symbol
));