2 * Copyright (c) 1999-2007 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
23 /***********************************************************************
25 * Copyright 1988-1996, NeXT Software, Inc.
28 **********************************************************************/
32 /***********************************************************************
34 **********************************************************************/
36 #include <mach-o/ldsyms.h>
37 #include <mach-o/dyld.h>
38 #include <mach-o/dyld_gdb.h>
39 #include <mach-o/dyld_priv.h>
40 #include <mach/mach.h>
41 #include <mach/mach_error.h>
43 #include <sys/resource.h>
44 #include <sys/types.h>
47 #include <crt_externs.h>
50 #include <crt_externs.h>
53 #import "objc-private.h"
54 #import "hashtable2.h"
59 #import "objc-loadmethod.h"
61 OBJC_EXPORT Class getOriginalClassForPosingClass(Class);
64 /***********************************************************************
66 **********************************************************************/
68 // Settings from environment variables
69 __private_extern__ int PrintImages = -1; // env OBJC_PRINT_IMAGES
70 __private_extern__ int PrintLoading = -1; // env OBJC_PRINT_LOAD_METHODS
71 __private_extern__ int PrintInitializing = -1; // env OBJC_PRINT_INITIALIZE_METHODS
72 __private_extern__ int PrintResolving = -1; // env OBJC_PRINT_RESOLVED_METHODS
73 __private_extern__ int PrintConnecting = -1; // env OBJC_PRINT_CLASS_SETUP
74 __private_extern__ int PrintProtocols = -1; // env OBJC_PRINT_PROTOCOL_SETUP
75 __private_extern__ int PrintIvars = -1; // env OBJC_PRINT_IVAR_SETUP
76 __private_extern__ int PrintFuture = -1; // env OBJC_PRINT_FUTURE_CLASSES
77 __private_extern__ int PrintRTP = -1; // env OBJC_PRINT_RTP
78 __private_extern__ int PrintGC = -1; // env OBJC_PRINT_GC
79 __private_extern__ int PrintSharing = -1; // env OBJC_PRINT_SHARING
80 __private_extern__ int PrintCxxCtors = -1; // env OBJC_PRINT_CXX_CTORS
81 __private_extern__ int PrintExceptions = -1; // env OBJC_PRINT_EXCEPTIONS
82 __private_extern__ int PrintAltHandlers = -1; // env OBJC_PRINT_ALT_HANDLERS
83 __private_extern__ int PrintDeprecation = -1;// env OBJC_PRINT_DEPRECATION_WARNINGS
84 __private_extern__ int PrintReplacedMethods = -1; // env OBJC_PRINT_REPLACED_METHODS
85 __private_extern__ int PrintCacheCollection = -1; // env OBJC_PRINT_CACHE_COLLECTION
87 __private_extern__ int UseInternalZone = -1; // env OBJC_USE_INTERNAL_ZONE
88 __private_extern__ int AllowInterposing = -1;// env OBJC_ALLOW_INTERPOSING
90 __private_extern__ int DebugUnload = -1; // env OBJC_DEBUG_UNLOAD
91 __private_extern__ int DebugFragileSuperclasses = -1; // env OBJC_DEBUG_FRAGILE_SUPERCLASSES
92 __private_extern__ int DebugNilSync = -1; // env OBJC_DEBUG_NIL_SYNC
94 __private_extern__ int DisableGC = -1; // env OBJC_DISABLE_GC
95 __private_extern__ int DebugFinalizers = -1; // env OBJC_DEBUG_FINALIZERS
98 // objc's key for pthread_getspecific
99 static pthread_key_t _objc_pthread_key = 0;
101 // Selectors for which @selector() doesn't work
102 __private_extern__ SEL cxx_construct_sel = NULL;
103 __private_extern__ SEL cxx_destruct_sel = NULL;
104 __private_extern__ const char *cxx_construct_name = ".cxx_construct";
105 __private_extern__ const char *cxx_destruct_name = ".cxx_destruct";
108 /***********************************************************************
109 * Function prototypes internal to this module.
110 **********************************************************************/
112 static void _objc_unmap_image(header_info *hi);
115 /***********************************************************************
116 * Static data internal to this module.
117 **********************************************************************/
119 // we keep a linked list of header_info's describing each image as told to us by dyld
120 static header_info *FirstHeader NOBSS = 0; // NULL means empty list
121 static header_info *LastHeader NOBSS = 0; // NULL means invalid; recompute it
122 static int HeaderCount NOBSS = 0;
125 /***********************************************************************
126 * objc_getClass. Return the id of the named class. If the class does
127 * not exist, call _objc_classLoader and then objc_classHandler, either of
128 * which may create a new class.
129 * Warning: doesn't work if aClassName is the name of a posed-for class's isa!
130 **********************************************************************/
131 id objc_getClass(const char *aClassName)
133 if (!aClassName) return Nil;
135 // NO unconnected, YES class handler
136 return look_up_class(aClassName, NO, YES);
140 /***********************************************************************
141 * objc_getRequiredClass.
142 * Same as objc_getClass, but kills the process if the class is not found.
143 * This is used by ZeroLink, where failing to find a class would be a
144 * compile-time link error without ZeroLink.
145 **********************************************************************/
146 id objc_getRequiredClass(const char *aClassName)
148 id cls = objc_getClass(aClassName);
149 if (!cls) _objc_fatal("link error: class '%s' not found.", aClassName);
154 /***********************************************************************
155 * objc_lookUpClass. Return the id of the named class.
156 * If the class does not exist, call _objc_classLoader, which may create
159 * Formerly objc_getClassWithoutWarning ()
160 **********************************************************************/
161 id objc_lookUpClass(const char *aClassName)
163 if (!aClassName) return Nil;
165 // NO unconnected, NO class handler
166 return look_up_class(aClassName, NO, NO);
169 /***********************************************************************
170 * objc_getFutureClass. Return the id of the named class.
171 * If the class does not exist, return an uninitialized class
172 * structure that will be used for the class when and if it
175 **********************************************************************/
176 Class objc_getFutureClass(const char *name)
180 // YES unconnected, NO class handler
181 // (unconnected is OK because it will someday be the real class)
182 cls = look_up_class(name, YES, NO);
185 _objc_inform("FUTURE: found %p already in use for %s", cls, name);
190 // No class or future class with that name yet. Make one.
191 // fixme not thread-safe with respect to
192 // simultaneous library load or getFutureClass.
193 return _objc_allocateFutureClass(name);
197 /***********************************************************************
198 * objc_getMetaClass. Return the id of the meta class the named class.
199 * Warning: doesn't work if aClassName is the name of a posed-for class's isa!
200 **********************************************************************/
201 id objc_getMetaClass(const char *aClassName)
205 if (!aClassName) return Nil;
207 cls = objc_getClass (aClassName);
210 _objc_inform ("class `%s' not linked into application", aClassName);
214 return ((id)cls)->isa;
219 // Not updated for 64-bit ABI
221 /***********************************************************************
223 * addr can be a class or a category
224 **********************************************************************/
225 static const header_info *_headerForAddress(void *addr)
231 // Check all headers in the vector
232 for (hInfo = FirstHeader; hInfo != NULL; hInfo = hInfo->next)
234 // Locate header data, if any
235 if (!hInfo->objcSegmentHeader) continue;
236 seg = hInfo->objcSegmentHeader->vmaddr + hInfo->image_slide;
237 size = hInfo->objcSegmentHeader->filesize;
239 // Is the class in this header?
240 if ((seg <= (unsigned long) addr) &&
241 ((unsigned long) addr < (seg + size)))
250 /***********************************************************************
252 * Return the image header containing this class, or NULL.
253 * Returns NULL on runtime-constructed classes, and the NSCF classes.
254 **********************************************************************/
255 __private_extern__ const header_info *_headerForClass(Class cls)
257 return _headerForAddress(cls);
264 /***********************************************************************
266 **********************************************************************/
267 __private_extern__ const char *_nameForHeader(const headerType *header)
269 return _getObjcHeaderName ((headerType *) header);
273 /***********************************************************************
275 **********************************************************************/
276 __private_extern__ const char *_gcForHInfo(const header_info *hinfo)
278 if (_objcHeaderRequiresGC(hinfo)) return "requires GC";
279 else if (_objcHeaderSupportsGC(hinfo)) return "supports GC";
280 else return "does not support GC";
282 __private_extern__ const char *_gcForHInfo2(const header_info *hinfo)
284 if (_objcHeaderRequiresGC(hinfo)) return " (requires GC)";
285 else if (_objcHeaderSupportsGC(hinfo)) return " (supports GC)";
290 /***********************************************************************
292 * Return YES if the header has invalid Mach-o magic.
293 **********************************************************************/
294 static BOOL bad_magic(const headerType *mhdr)
296 return (mhdr->magic != MH_MAGIC && mhdr->magic != MH_MAGIC_64 &&
297 mhdr->magic != MH_CIGAM && mhdr->magic != MH_CIGAM_64);
301 /***********************************************************************
302 * _objc_headerStart. Return what headers we know about.
303 **********************************************************************/
304 __private_extern__ header_info *_objc_headerStart(void)
306 // Take advatage of our previous work
311 /***********************************************************************
313 * Returns NULL if the header has no ObjC metadata.
314 **********************************************************************/
316 // tested with 2; typical case is 4, but OmniWeb & Mail push it towards 20
317 #define HINFO_SIZE 16
319 static int HeaderInfoCounter NOBSS = 0;
320 static header_info HeaderInfoTable[HINFO_SIZE] NOBSS = { {0} };
322 static header_info * _objc_addHeader(const headerType *header)
324 size_t info_size = 0;
325 const segmentType *objc_segment;
326 const segmentType *objc2_segment;
327 const objc_image_info *image_info;
328 const segmentType *data_segment;
330 ptrdiff_t image_slide;
332 // Weed out duplicates
333 for (result = FirstHeader; result; result = result->next) {
334 if (header == result->mhdr) return NULL;
337 // Locate the __OBJC segment
338 image_slide = _getImageSlide(header);
339 image_info = _getObjcImageInfo(header, image_slide, &info_size);
340 objc_segment = getsegbynamefromheader(header, SEG_OBJC);
341 objc2_segment = getsegbynamefromheader(header, SEG_OBJC2);
342 data_segment = getsegbynamefromheader(header, SEG_DATA);
343 if (!objc_segment && !image_info && !objc2_segment) return NULL;
345 // Find or allocate a header_info entry.
346 if (HeaderInfoCounter < HINFO_SIZE) {
347 result = &HeaderInfoTable[HeaderInfoCounter++];
349 result = _malloc_internal(sizeof(header_info));
352 // Set up the new header_info entry.
353 result->mhdr = header;
354 result->image_slide = image_slide;
355 result->objcSegmentHeader = objc_segment;
356 result->dataSegmentHeader = data_segment;
358 result->mod_count = 0;
359 result->mod_ptr = _getObjcModules(header, result->image_slide, &result->mod_count);
361 result->info = image_info;
362 dladdr(result->mhdr, &result->dl_info);
363 result->allClassesRealized = NO;
365 // dylibs are not allowed to unload
366 if (result->mhdr->filetype == MH_DYLIB) {
367 dlopen(result->dl_info.dli_fname, RTLD_NOLOAD);
370 // Make sure every copy of objc_image_info in this image is the same.
371 // This means same version and same bitwise contents.
373 const objc_image_info *start = result->info;
374 const objc_image_info *end =
375 (objc_image_info *)(info_size + (uint8_t *)start);
376 const objc_image_info *info = start;
378 // version is byte size, except for version 0
379 size_t struct_size = info->version;
380 if (struct_size == 0) struct_size = 2 * sizeof(uint32_t);
381 if (info->version != start->version ||
382 0 != memcmp(info, start, struct_size))
384 _objc_inform("'%s' has inconsistently-compiled Objective-C "
385 "code. Please recompile all code in it.",
386 _nameForHeader(header));
388 info = (objc_image_info *)(struct_size + (uint8_t *)info);
392 // Add the header to the header list.
393 // The header is appended to the list, to preserve the bottom-up order.
398 FirstHeader = LastHeader = result;
401 // list is not empty, but LastHeader is invalid - recompute it
402 LastHeader = FirstHeader;
403 while (LastHeader->next) LastHeader = LastHeader->next;
405 // LastHeader is now valid
406 LastHeader->next = result;
414 /***********************************************************************
416 * Remove the given header from the header list.
417 * FirstHeader is updated.
418 * LastHeader is set to NULL. Any code that uses LastHeader must
419 * detect this NULL and recompute LastHeader by traversing the list.
420 **********************************************************************/
421 static void _objc_removeHeader(header_info *hi)
425 for (hiP = &FirstHeader; *hiP != NULL; hiP = &(**hiP).next) {
427 header_info *deadHead = *hiP;
429 // Remove from the linked list (updating FirstHeader if necessary).
432 // Update LastHeader if necessary.
433 if (LastHeader == deadHead) {
434 LastHeader = NULL; // will be recomputed next time it's used
437 // Free the memory, unless it was in the static HeaderInfoTable.
438 if (deadHead < HeaderInfoTable ||
439 deadHead >= HeaderInfoTable + HINFO_SIZE)
441 _free_internal(deadHead);
452 /***********************************************************************
454 * Check whether the executable supports or requires GC, and make sure
455 * all already-loaded libraries support the executable's GC mode.
456 * Returns TRUE if the executable wants GC on.
457 **********************************************************************/
458 static BOOL check_wants_gc(void)
460 const header_info *hi;
463 // Environment variables can override the following.
465 _objc_inform("GC: forcing GC OFF because OBJC_DISABLE_GC is set");
469 // Find the executable and check its GC bits.
470 // If the executable cannot be found, default to NO.
471 // (The executable will not be found if the executable contains
472 // no Objective-C code.)
474 for (hi = FirstHeader; hi != NULL; hi = hi->next) {
475 if (hi->mhdr->filetype == MH_EXECUTE) {
476 appWantsGC = _objcHeaderSupportsGC(hi) ? YES : NO;
478 _objc_inform("GC: executable '%s' %s",
479 _nameForHeader(hi->mhdr), _gcForHInfo(hi));
487 /***********************************************************************
488 * verify_gc_readiness
489 * if we want gc, verify that every header describes files compiled
490 * and presumably ready for gc.
491 ************************************************************************/
493 static void verify_gc_readiness(BOOL wantsGC, header_info **hList,
499 // Find the libraries and check their GC bits against the app's request
500 for (i = 0; i < hCount; i++) {
501 header_info *hi = hList[i];
502 if (hi->mhdr->filetype == MH_EXECUTE) {
505 else if (hi->mhdr == &_mh_dylib_header) {
506 // libobjc itself works with anything even though it is not
507 // compiled with -fobjc-gc (fixme should it be?)
509 else if (wantsGC && ! _objcHeaderSupportsGC(hi)) {
510 // App wants GC but library does not support it - bad
511 _objc_inform_now_and_on_crash
512 ("'%s' was not compiled with -fobjc-gc or -fobjc-gc-only, "
513 "but the application requires GC",
514 _nameForHeader(hi->mhdr));
517 else if (!wantsGC && _objcHeaderRequiresGC(hi)) {
518 // App doesn't want GC but library requires it - bad
519 _objc_inform_now_and_on_crash
520 ("'%s' was compiled with -fobjc-gc-only, "
521 "but the application does not support GC",
522 _nameForHeader(hi->mhdr));
527 _objc_inform("GC: library '%s' %s",
528 _nameForHeader(hi->mhdr), _gcForHInfo(hi));
533 // GC state is not consistent.
534 // Kill the process unless one of the forcing flags is set.
536 _objc_fatal("*** GC capability of application and some libraries did not match");
542 /***********************************************************************
543 * objc_setConfiguration
544 * Read environment variables that affect the runtime.
545 * Also print environment variable help, if requested.
546 **********************************************************************/
547 static void objc_setConfiguration() {
548 int PrintHelp = (getenv("OBJC_HELP") != NULL);
549 int PrintOptions = (getenv("OBJC_PRINT_OPTIONS") != NULL);
550 int secure = issetugid();
553 // All environment variables are ignored when setuid or setgid.
554 if (PrintHelp) _objc_inform("OBJC_HELP ignored when running setuid or setgid");
555 if (PrintOptions) _objc_inform("OBJC_PRINT_OPTIONS ignored when running setuid or setgid");
559 _objc_inform("OBJC_HELP: describe Objective-C runtime environment variables");
561 _objc_inform("OBJC_HELP is set");
563 _objc_inform("OBJC_PRINT_OPTIONS: list which options are set");
566 _objc_inform("OBJC_PRINT_OPTIONS is set");
570 #define OPTION(var, env, help) \
572 char *value = getenv(#env); \
573 var = value != NULL && !strcmp("YES", value); \
575 if (var) _objc_inform(#env " ignored when running setuid or setgid"); \
578 if (PrintHelp) _objc_inform(#env ": " help); \
579 if (PrintOptions && var) _objc_inform(#env " is set"); \
583 OPTION(PrintImages, OBJC_PRINT_IMAGES,
584 "log image and library names as they are loaded");
585 OPTION(PrintLoading, OBJC_PRINT_LOAD_METHODS,
586 "log calls to class and category +load methods");
587 OPTION(PrintInitializing, OBJC_PRINT_INITIALIZE_METHODS,
588 "log calls to class +initialize methods");
589 OPTION(PrintResolving, OBJC_PRINT_RESOLVED_METHODS,
590 "log methods created by +resolveClassMethod: and +resolveInstanceMethod:");
591 OPTION(PrintConnecting, OBJC_PRINT_CLASS_SETUP,
592 "log progress of class and category setup");
593 OPTION(PrintProtocols, OBJC_PRINT_PROTOCOL_SETUP,
594 "log progresso of protocol setup");
595 OPTION(PrintIvars, OBJC_PRINT_IVAR_SETUP,
596 "log processing of non-fragile ivars");
597 OPTION(PrintFuture, OBJC_PRINT_FUTURE_CLASSES,
598 "log use of future classes for toll-free bridging");
599 OPTION(PrintRTP, OBJC_PRINT_RTP,
600 "log initialization of the Objective-C runtime pages");
601 OPTION(PrintGC, OBJC_PRINT_GC,
602 "log some GC operations");
603 OPTION(PrintSharing, OBJC_PRINT_SHARING,
604 "log cross-process memory sharing");
605 OPTION(PrintCxxCtors, OBJC_PRINT_CXX_CTORS,
606 "log calls to C++ ctors and dtors for instance variables");
607 OPTION(PrintExceptions, OBJC_PRINT_EXCEPTIONS,
608 "log exception handling");
609 OPTION(PrintAltHandlers, OBJC_PRINT_ALT_HANDLERS,
610 "log processing of exception alt handlers");
611 OPTION(PrintReplacedMethods, OBJC_PRINT_REPLACED_METHODS,
612 "log methods replaced by category implementations");
613 OPTION(PrintDeprecation, OBJC_PRINT_DEPRECATION_WARNINGS,
614 "warn about calls to deprecated runtime functions");
615 OPTION(PrintCacheCollection, OBJC_PRINT_CACHE_COLLECTION,
616 "log cleanup of stale method caches");
618 OPTION(DebugUnload, OBJC_DEBUG_UNLOAD,
619 "warn about poorly-behaving bundles when unloaded");
620 OPTION(DebugFragileSuperclasses, OBJC_DEBUG_FRAGILE_SUPERCLASSES,
621 "warn about subclasses that may have been broken by subsequent changes to superclasses");
622 OPTION(DebugFinalizers, OBJC_DEBUG_FINALIZERS,
623 "warn about classes that implement -dealloc but not -finalize");
624 OPTION(DebugNilSync, OBJC_DEBUG_NIL_SYNC,
625 "warn about @synchronized(nil), which does no synchronization");
627 OPTION(UseInternalZone, OBJC_USE_INTERNAL_ZONE,
628 "allocate runtime data in a dedicated malloc zone");
629 OPTION(AllowInterposing, OBJC_ALLOW_INTERPOSING,
630 "allow function interposing of objc_msgSend()");
632 OPTION(DisableGC, OBJC_DISABLE_GC,
633 "force GC OFF, even if the executable wants it on");
639 /***********************************************************************
640 * objc_setMultithreaded.
641 **********************************************************************/
642 void objc_setMultithreaded (BOOL flag)
644 OBJC_WARN_DEPRECATED;
646 // Nothing here. Thread synchronization in the runtime is always active.
650 /***********************************************************************
651 * _objc_fetch_pthread_data
652 * Fetch objc's pthread data for this thread.
653 * If the data doesn't exist yet and create is NO, return NULL.
654 * If the data doesn't exist yet and create is YES, allocate and return it.
655 **********************************************************************/
656 __private_extern__ _objc_pthread_data *_objc_fetch_pthread_data(BOOL create)
658 _objc_pthread_data *data;
660 data = pthread_getspecific(_objc_pthread_key);
661 if (!data && create) {
662 data = _calloc_internal(1, sizeof(_objc_pthread_data));
663 pthread_setspecific(_objc_pthread_key, data);
670 /***********************************************************************
671 * _objc_pthread_destroyspecific
672 * Destructor for objc's per-thread data.
673 * arg shouldn't be NULL, but we check anyway.
674 **********************************************************************/
675 extern void _destroyInitializingClassList(struct _objc_initializing_classes *list);
676 __private_extern__ void _objc_pthread_destroyspecific(void *arg)
678 _objc_pthread_data *data = (_objc_pthread_data *)arg;
680 _destroyInitializingClassList(data->initializingClasses);
681 _destroyLockList(data->lockList);
682 _destroySyncCache(data->syncCache);
683 _destroyAltHandlerList(data->handlerList);
685 // add further cleanup here...
687 _free_internal(data);
692 /***********************************************************************
694 * Former library initializer. This function is now merely a placeholder
695 * for external callers. All runtime initialization has now been moved
696 * to map_images() and _objc_init.
697 **********************************************************************/
704 /***********************************************************************
706 * Make sure that images about to be loaded by dyld are GC-acceptable.
707 * Images linked to the executable are always permitted; they are
708 * enforced inside map_images() itself.
709 **********************************************************************/
710 static BOOL InitialDyldRegistration = NO;
711 static const char *gc_enforcer(enum dyld_image_states state,
713 const struct dyld_image_info info[])
717 // Linked images get a free pass
718 if (InitialDyldRegistration) return NULL;
721 _objc_inform("IMAGES: checking %d images for compatibility...",
725 for (i = 0; i < infoCount; i++) {
726 const headerType *mhdr = (const headerType *)info[i].imageLoadAddress;
727 if (bad_magic(mhdr)) continue;
729 objc_image_info *image_info;
732 if (mhdr == &_mh_dylib_header) {
733 // libobjc itself - OK
738 // 32-bit: __OBJC seg but no image_info means no GC support
739 if (!getsegbynamefromheader(mhdr, SEG_OBJC)) {
740 // not objc - assume OK
743 image_info = _getObjcImageInfo(mhdr, _getImageSlide(mhdr), &size);
745 // No image_info - assume GC unsupported
751 if (PrintImages || PrintGC) {
752 _objc_inform("IMAGES: rejecting %d images because %s doesn't support GC (no image_info)", infoCount, info[i].imageFilePath);
754 return "GC capability mismatch";
758 // 64-bit: no image_info means no objc at all
759 image_info = _getObjcImageInfo(mhdr, _getImageSlide(mhdr), &size);
761 // not objc - assume OK
766 if (UseGC && !_objcInfoSupportsGC(image_info)) {
767 // GC is ON, but image does not support GC
768 if (PrintImages || PrintGC) {
769 _objc_inform("IMAGES: rejecting %d images because %s doesn't support GC", infoCount, info[i].imageFilePath);
771 return "GC capability mismatch";
773 if (!UseGC && _objcInfoRequiresGC(image_info)) {
774 // GC is OFF, but image requires GC
775 if (PrintImages || PrintGC) {
776 _objc_inform("IMAGES: rejecting %d images because %s requires GC", infoCount, info[i].imageFilePath);
778 return "GC capability mismatch";
786 /***********************************************************************
788 * Process the given images which are being mapped in by dyld.
789 * All class registration and fixups are performed (or deferred pending
790 * discovery of missing superclasses etc), and +load methods are called.
792 * info[] is in bottom-up order i.e. libobjc will be earlier in the
793 * array than any library that links to libobjc.
794 **********************************************************************/
795 static const char *map_images(enum dyld_image_states state, uint32_t infoCount,
796 const struct dyld_image_info infoList[])
798 static BOOL firstTime = YES;
799 static BOOL wantsGC NOBSS = NO;
802 header_info *hList[infoCount];
805 // Perform first-time initialization if necessary.
806 // This function is called before ordinary library initializers.
808 extern SEL FwdSel; // in objc-msg-*.s
809 // workaround for rdar://5198739
810 pthread_key_t unused;
811 pthread_key_create(&unused, NULL);
812 pthread_key_create(&_objc_pthread_key, _objc_pthread_destroyspecific);
813 objc_setConfiguration(); // read environment variables
814 // grab selectors for which @selector() doesn't work
815 cxx_construct_sel = sel_registerName(cxx_construct_name);
816 cxx_destruct_sel = sel_registerName(cxx_destruct_name);
817 FwdSel = sel_registerName("forward::"); // in objc-msg-*.s
820 InitialDyldRegistration = YES;
821 dyld_register_image_state_change_handler(dyld_image_state_mapped, 0 /* batch */, &gc_enforcer);
822 InitialDyldRegistration = NO;
826 _objc_inform("IMAGES: processing %u newly-mapped images...\n", infoCount);
830 // Find all images with Objective-C metadata.
834 const headerType *mhdr = (headerType *)infoList[i].imageLoadAddress;
835 if (bad_magic(mhdr)) continue;
837 hInfo = _objc_addHeader(mhdr);
839 // no objc data in this entry
843 hList[hCount++] = hInfo;
846 _objc_inform("IMAGES: loading image for %s%s%s%s\n",
847 _nameForHeader(mhdr),
848 mhdr->filetype == MH_BUNDLE ? " (bundle)" : "",
849 _objcHeaderIsReplacement(hInfo) ? " (replacement)":"",
850 _gcForHInfo2(hInfo));
854 // Perform one-time runtime initialization that must be deferred until
855 // the executable itself is found. This needs to be done before
856 // further initialization.
857 // (The executable may not be present in this infoList if the
858 // executable does not contain Objective-C code but Objective-C
859 // is dynamically loaded later. In that case, check_wants_gc()
860 // will do the right thing.)
862 wantsGC = check_wants_gc();
864 verify_gc_readiness(wantsGC, hList, hCount);
866 gc_init(wantsGC); // needs executable for GC decision
867 rtp_init(); // needs GC decision first
869 verify_gc_readiness(wantsGC, hList, hCount);
872 _read_images(hList, hCount);
880 static const char *load_images(enum dyld_image_states state,uint32_t infoCount,
881 const struct dyld_image_info infoList[])
889 for (hi = FirstHeader; hi != NULL; hi = hi->next) {
890 const headerType *mhdr = (headerType*)infoList[i].imageLoadAddress;
891 if (hi->mhdr == mhdr) {
892 prepare_load_methods(hi);
898 if (found) call_load_methods();
903 /***********************************************************************
905 * Process the given image which is about to be unmapped by dyld.
906 * mh is mach_header instead of headerType because that's what
907 * dyld_priv.h says even for 64-bit.
908 **********************************************************************/
909 static void unmap_image(const struct mach_header *mh, intptr_t vmaddr_slide)
912 _objc_inform("IMAGES: processing 1 newly-unmapped image...\n");
917 // Find the runtime's header_info struct for the image
918 for (hi = FirstHeader; hi != NULL; hi = hi->next) {
919 if (hi->mhdr == (const headerType *)mh) {
920 _objc_unmap_image(hi);
925 // no objc data for this image
929 /***********************************************************************
931 * Static initializer. Registers our image notifier with dyld.
932 * fixme move map_images' firstTime code here - but GC code might need
933 * another earlier image notifier
934 **********************************************************************/
935 static __attribute__((constructor))
936 void _objc_init(void)
938 // Register for unmap first, in case some +load unmaps something
939 _dyld_register_func_for_remove_image(&unmap_image);
940 dyld_register_image_state_change_handler(dyld_image_state_bound,
941 1/*batch*/, &map_images);
942 dyld_register_image_state_change_handler(dyld_image_state_dependents_initialized, 0/*not batch*/, &load_images);
946 /***********************************************************************
948 * Destroy any Objective-C data for the given image, which is about to
949 * be unloaded by dyld.
950 * Note: not thread-safe, but image loading isn't either.
951 **********************************************************************/
952 static void _objc_unmap_image(header_info *hi)
955 _objc_inform("IMAGES: unloading image for %s%s%s%s\n",
956 _nameForHeader(hi->mhdr),
957 hi->mhdr->filetype == MH_BUNDLE ? " (bundle)" : "",
958 _objcHeaderIsReplacement(hi) ? " (replacement)" : "",
964 // Remove header_info from header list
965 _objc_removeHeader(hi);
969 /***********************************************************************
970 * _objc_setNilReceiver
971 **********************************************************************/
972 id _objc_setNilReceiver(id newNilReceiver)
976 oldNilReceiver = _objc_nilReceiver;
977 _objc_nilReceiver = newNilReceiver;
979 return oldNilReceiver;
982 /***********************************************************************
983 * _objc_getNilReceiver
984 **********************************************************************/
985 id _objc_getNilReceiver(void)
987 return _objc_nilReceiver;
991 /***********************************************************************
992 * objc_setForwardHandler
993 **********************************************************************/
994 void objc_setForwardHandler(void *fwd, void *fwd_stret)
996 _objc_forward_handler = fwd;
997 _objc_forward_stret_handler = fwd_stret;
1001 #if defined(__ppc__) || defined(__ppc64__)
1003 // Test to see if either the displacement or destination is within
1004 // the +/- 2^25 range needed for a PPC branch immediate instruction.
1005 // Shifting the high bit of the displacement (or destination)
1006 // left 6 bits and then 6 bits arithmetically to the right does a
1007 // sign extend of the 26th bit. If that result is equivalent to the
1008 // original value, then the displacement (or destination) will fit
1009 // into a simple branch. Otherwise a larger branch sequence is required.
1010 // ppc64: max displacement is still +/- 2^25, but intptr_t is bigger
1013 // small: b, ba (unconditional only)
1014 // 32: bctr with lis+ori only
1015 static BOOL ppc_tiny_displacement(intptr_t displacement)
1017 size_t shift = sizeof(intptr_t) - 16; // ilp32=16, lp64=48
1018 return (((displacement << shift) >> shift) == displacement);
1021 static BOOL ppc_small_displacement(intptr_t displacement)
1023 size_t shift = sizeof(intptr_t) - 26; // ilp32=6, lp64=38
1024 return (((displacement << shift) >> shift) == displacement);
1027 #if defined(__ppc64__)
1028 // Same as ppc_small_displacement, but decides whether 32 bits is big enough.
1029 static BOOL ppc_32bit_displacement(intptr_t displacement)
1031 size_t shift = sizeof(intptr_t) - 32;
1032 return (((displacement << shift) >> shift) == displacement);
1036 /**********************************************************************
1038 * Returns the number of instructions needed
1039 * for a branch from entry to target.
1040 **********************************************************************/
1041 __private_extern__ size_t objc_branch_size(void *entry, void *target)
1043 return objc_cond_branch_size(entry, target, COND_ALWAYS);
1046 __private_extern__ size_t
1047 objc_cond_branch_size(void *entry, void *target, unsigned cond)
1049 intptr_t destination = (intptr_t)target;
1050 intptr_t displacement = (intptr_t)destination - (intptr_t)entry;
1052 if (cond == COND_ALWAYS && ppc_small_displacement(displacement)) {
1053 // fits in unconditional relative branch immediate
1056 if (cond == COND_ALWAYS && ppc_small_displacement(destination)) {
1057 // fits in unconditional absolute branch immediate
1060 if (ppc_tiny_displacement(displacement)) {
1061 // fits in conditional relative branch immediate
1064 if (ppc_tiny_displacement(destination)) {
1065 // fits in conditional absolute branch immediate
1068 #if defined(__ppc64__)
1069 if (!ppc_32bit_displacement(destination)) {
1070 // fits in 64-bit absolute branch through CTR
1075 // fits in 32-bit absolute branch through CTR
1079 /**********************************************************************
1081 * Writes at entry a PPC branch instruction sequence that branches to target.
1082 * The sequence written will be objc_branch_size(entry, target) instructions.
1083 * Returns the number of instructions written.
1084 **********************************************************************/
1085 __private_extern__ size_t objc_write_branch(void *entry, void *target)
1087 return objc_write_cond_branch(entry, target, COND_ALWAYS);
1090 __private_extern__ size_t
1091 objc_write_cond_branch(void *entry, void *target, unsigned cond)
1093 unsigned *address = (unsigned *)entry; // location to store the 32 bit PPC instructions
1094 intptr_t destination = (intptr_t)target; // destination as an absolute address
1095 intptr_t displacement = (intptr_t)destination - (intptr_t)address; // destination as a branch relative offset
1097 if (cond == COND_ALWAYS && ppc_small_displacement(displacement)) {
1098 // use unconditional relative branch with the displacement
1099 address[0] = 0x48000000 | (unsigned)(displacement & 0x03fffffc); // b *+displacement
1100 // issued 1 instruction
1103 if (cond == COND_ALWAYS && ppc_small_displacement(destination)) {
1104 // use unconditional absolute branch with the destination
1105 address[0] = 0x48000000 | (unsigned)(destination & 0x03fffffc) | 2; // ba destination (2 is the absolute flag)
1106 // issued 1 instruction
1110 if (ppc_tiny_displacement(displacement)) {
1111 // use conditional relative branch with the displacement
1112 address[0] = 0x40000000 | cond | (unsigned)(displacement & 0x0000fffc); // b *+displacement
1113 // issued 1 instruction
1116 if (ppc_tiny_displacement(destination)) {
1117 // use conditional absolute branch with the destination
1118 address[0] = 0x40000000 | cond | (unsigned)(destination & 0x0000fffc) | 2; // ba destination (2 is the absolute flag)
1119 // issued 1 instruction
1124 // destination is large and far away.
1125 // Use an absolute branch via CTR.
1127 #if defined(__ppc64__)
1128 if (!ppc_32bit_displacement(destination)) {
1129 uint16_t lo = destination & 0xffff;
1130 uint16_t hi = (destination >> 16) & 0xffff;
1131 uint16_t hi2 = (destination >> 32) & 0xffff;
1132 uint16_t hi3 = (destination >> 48) & 0xffff;
1134 address[0] = 0x3d800000 | hi3; // lis r12, hi3
1135 address[1] = 0x618c0000 | hi2; // ori r12, r12, hi2
1136 address[2] = 0x798c07c6; // sldi r12, r12, 32
1137 address[3] = 0x658c0000 | hi; // oris r12, r12, hi
1138 address[4] = 0x618c0000 | lo; // ori r12, r12, lo
1139 address[5] = 0x7d8903a6; // mtctr r12
1140 address[6] = 0x4c000420 | cond; // bctr
1141 // issued 7 instructions
1147 uint16_t lo = destination & 0xffff;
1148 uint16_t hi = (destination >> 16) & 0xffff;
1150 address[0] = 0x3d800000 | hi; // lis r12,hi
1151 address[1] = 0x618c0000 | lo; // ori r12,r12,lo
1152 address[2] = 0x7d8903a6; // mtctr r12
1153 address[3] = 0x4c000420 | cond; // bctr
1154 // issued 4 instructions
1159 // defined(__ppc__) || defined(__ppc64__)
1162 #if defined(__i386__) || defined(__x86_64__)
1164 /**********************************************************************
1166 * Returns the number of BYTES needed
1167 * for a branch from entry to target.
1168 **********************************************************************/
1169 __private_extern__ size_t objc_branch_size(void *entry, void *target)
1171 return objc_cond_branch_size(entry, target, COND_ALWAYS);
1174 __private_extern__ size_t
1175 objc_cond_branch_size(void *entry, void *target, unsigned cond)
1177 // For simplicity, always use 32-bit relative jumps.
1178 if (cond == COND_ALWAYS) return 5;
1182 /**********************************************************************
1184 * Writes at entry an i386 branch instruction sequence that branches to target.
1185 * The sequence written will be objc_branch_size(entry, target) BYTES.
1186 * Returns the number of BYTES written.
1187 **********************************************************************/
1188 __private_extern__ size_t objc_write_branch(void *entry, void *target)
1190 return objc_write_cond_branch(entry, target, COND_ALWAYS);
1193 __private_extern__ size_t
1194 objc_write_cond_branch(void *entry, void *target, unsigned cond)
1196 uint8_t *address = (uint8_t *)entry; // instructions written to here
1197 intptr_t destination = (intptr_t)target; // branch dest as absolute address
1198 intptr_t displacement = (intptr_t)destination - ((intptr_t)address + objc_cond_branch_size(entry, target, cond)); // branch dest as relative offset
1200 // For simplicity, always use 32-bit relative jumps
1201 if (cond != COND_ALWAYS) {
1202 *address++ = 0x0f; // Jcc prefix
1205 *address++ = displacement & 0xff;
1206 *address++ = (displacement >> 8) & 0xff;
1207 *address++ = (displacement >> 16) & 0xff;
1208 *address++ = (displacement >> 24) & 0xff;
1210 return address - (uint8_t *)entry;
1217 /**********************************************************************
1219 * Securely open a file from a world-writable directory (like /tmp)
1220 * If the file does not exist, it will be atomically created with mode 0600
1221 * If the file exists, it must be, and remain after opening:
1222 * 1. a regular file (in particular, not a symlink)
1224 * 3. permissions 0600
1225 * 4. link count == 1
1226 * Returns a file descriptor or -1. Errno may or may not be set on error.
1227 **********************************************************************/
1228 __private_extern__ int secure_open(const char *filename, int flags, uid_t euid)
1235 if (flags & O_TRUNC) {
1236 // Don't truncate the file until after it is open and verified.
1240 if (flags & O_CREAT) {
1241 // Don't create except when we're ready for it
1247 if (lstat(filename, &ls) < 0) {
1248 if (errno == ENOENT && create) {
1249 // No such file - create it
1250 fd = open(filename, flags | O_CREAT | O_EXCL, 0600);
1252 // File was created successfully.
1253 // New file does not need to be truncated.
1256 // File creation failed.
1260 // lstat failed, or user doesn't want to create the file
1264 // lstat succeeded - verify attributes and open
1265 if (S_ISREG(ls.st_mode) && // regular file?
1266 ls.st_nlink == 1 && // link count == 1?
1267 ls.st_uid == euid && // owned by euid?
1268 (ls.st_mode & ALLPERMS) == (S_IRUSR | S_IWUSR)) // mode 0600?
1270 // Attributes look ok - open it and check attributes again
1271 fd = open(filename, flags, 0000);
1273 // File is open - double-check attributes
1274 if (0 == fstat(fd, &fs) &&
1275 fs.st_nlink == ls.st_nlink && // link count == 1?
1276 fs.st_uid == ls.st_uid && // owned by euid?
1277 fs.st_mode == ls.st_mode && // regular file, 0600?
1278 fs.st_ino == ls.st_ino && // same inode as before?
1279 fs.st_dev == ls.st_dev) // same device as before?
1281 // File is open and OK
1282 if (truncate) ftruncate(fd, 0);
1285 // Opened file looks funny - close it
1294 // Unopened file looks funny - don't open it
1303 extern Class _objc_getOrigClass(const char *name);
1305 const char *class_getImageName(Class cls)
1310 if (!cls) return NULL;
1313 cls = _objc_getOrigClass(_class_getName(cls));
1316 ok = dladdr(cls, &info);
1317 if (ok) return info.dli_fname;
1322 const char **objc_copyImageNames(unsigned int *outCount)
1326 int max = HeaderCount;
1327 const char **names = calloc(max+1, sizeof(char *));
1329 for (hi = _objc_headerStart();
1330 hi != NULL && count < max;
1333 if (hi->dl_info.dli_fname) {
1334 names[count++] = hi->dl_info.dli_fname;
1337 names[count] = NULL;
1340 // Return NULL instead of empty list if there are no images
1345 if (outCount) *outCount = count;
1350 /**********************************************************************
1352 **********************************************************************/
1354 objc_copyClassNamesForImage(const char *image, unsigned int *outCount)
1359 if (outCount) *outCount = 0;
1364 for (hi = _objc_headerStart(); hi != NULL; hi = hi->next) {
1365 if (0 == strcmp(image, hi->dl_info.dli_fname)) break;
1369 if (outCount) *outCount = 0;
1373 return _objc_copyClassNamesForImage(hi, outCount);
1377 /**********************************************************************
1378 * Fast Enumeration Support
1379 **********************************************************************/
1381 static void (*enumerationMutationHandler)(id);
1383 /**********************************************************************
1384 * objc_enumerationMutation
1385 * called by compiler when a mutation is detected during foreach iteration
1386 **********************************************************************/
1387 void objc_enumerationMutation(id object) {
1388 if (enumerationMutationHandler == nil) {
1389 _objc_fatal("mutation detected during 'for(... in ...)' enumeration of object %p.", object);
1391 (*enumerationMutationHandler)(object);
1395 /**********************************************************************
1396 * objc_setEnumerationMutationHandler
1397 * an entry point to customize mutation error handing
1398 **********************************************************************/
1399 void objc_setEnumerationMutationHandler(void (*handler)(id)) {
1400 enumerationMutationHandler = handler;