2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
25 /***********************************************************************
27 * Copyright 1988-1996, NeXT Software, Inc.
30 **********************************************************************/
32 /***********************************************************************
33 * Class loading and connecting (GrP 2004-2-11)
35 * When images are loaded (during program startup or otherwise), the
36 * runtime needs to load classes and categories from the images, connect
37 * classes to superclasses and categories to parent classes, and call
40 * The Objective-C runtime can cope with classes arriving in any order.
41 * That is, a class may be discovered by the runtime before some
42 * superclass is known. To handle out-of-order class loads, the
43 * runtime uses a "pending class" system.
46 * Panther and earlier: many classes arrived out-of-order because of
47 * the poorly-ordered callback from dyld. However, the runtime's
48 * pending mechanism only handled "missing superclass" and not
49 * "present superclass but missing higher class". See Radar #3225652.
50 * Tiger: The runtime's pending mechanism was augmented to handle
51 * arbitrary missing classes. In addition, dyld was rewritten and
52 * now sends the callbacks in strictly bottom-up link order.
53 * The pending mechanism may now be needed only for rare and
54 * hard to construct programs.
55 * (End historical note)
57 * A class when first seen in an image is considered "unconnected".
58 * It is stored in `unconnected_class_hash`. If all of the class's
59 * superclasses exist and are already "connected", then the new class
60 * can be connected to its superclasses and moved to `class_hash` for
61 * normal use. Otherwise, the class waits in `unconnected_class_hash`
62 * until the superclasses finish connecting.
64 * A "connected" class is
65 * (1) in `class_hash`,
66 * (2) connected to its superclasses,
67 * (3) has no unconnected superclasses,
68 * (4) is otherwise initialized and ready for use, and
69 * (5) is eligible for +load if +load has not already been called.
71 * An "unconnected" class is
72 * (1) in `unconnected_class_hash`,
73 * (2) not connected to its superclasses,
74 * (3) has an immediate superclass which is either missing or unconnected,
75 * (4) is not ready for use, and
76 * (5) is not yet eligible for +load.
78 * Image mapping is NOT CURRENTLY THREAD-SAFE with respect to just about
79 * * * anything. Image mapping IS RE-ENTRANT in several places: superclass
80 * lookup may cause ZeroLink to load another image, and +load calls may
81 * cause dyld to load another image.
83 * Image mapping sequence:
85 * Read all classes in all new images.
86 * Add them all to unconnected_class_hash.
87 * Note any +load implementations before categories are attached.
88 * Fix up any pended classrefs referring to them.
89 * Attach any pending categories.
90 * Read all categories in all new images.
91 * Attach categories whose parent class exists (connected or not),
93 * Mark them all eligible for +load (if implemented), even if the
94 * parent class is missing.
95 * Try to connect all classes in all new images.
96 * If the superclass is missing, pend the class
97 * If the superclass is unconnected, try to recursively connect it
98 * If the superclass is connected:
100 * mark the class eligible for +load, if implemented
101 * connect any pended subclasses of the class
102 * Resolve selector refs and class refs in all new images.
103 * Class refs whose classes still do not exist are pended.
104 * Fix up protocol objects in all new images.
105 * Call +load for classes and categories.
106 * May include classes or categories that are not in these images,
107 * but are newly eligible because of these image.
108 * Class +loads will be called superclass-first because of the
109 * superclass-first nature of the connecting process.
110 * Category +load needs to be deferred until the parent class is
111 * connected and has had its +load called.
113 * Performance: all classes are read before any categories are read.
114 * Fewer categories need be pended for lack of a parent class.
116 * Performance: all categories are attempted to be attached before
117 * any classes are connected. Fewer class caches need be flushed.
118 * (Unconnected classes and their respective subclasses are guaranteed
119 * to be un-messageable, so their caches will be empty.)
121 * Performance: all classes are read before any classes are connected.
122 * Fewer classes need be pended for lack of a superclass.
124 * Correctness: all selector and class refs are fixed before any
125 * protocol fixups or +load methods. libobjc itself contains selector
126 * and class refs which are used in protocol fixup and +load.
128 * Correctness: +load methods are scheduled in bottom-up link order.
129 * This constraint is in addition to superclass order. Some +load
130 * implementations expect to use another class in a linked-to library,
131 * even if the two classes don't share a direct superclass relationship.
133 * Correctness: all classes are scanned for +load before any categories
134 * are attached. Otherwise, if a category implements +load and its class
135 * has no class methods, the class's +load scan would find the category's
136 * +load method, which would then be called twice.
138 **********************************************************************/
141 /***********************************************************************
143 **********************************************************************/
145 #include <mach-o/ldsyms.h>
146 #include <mach-o/dyld.h>
147 #include <mach-o/dyld_gdb.h>
148 #include <mach/mach.h>
149 #include <mach/mach_error.h>
151 // project headers first, otherwise we get the installed ones
152 #import "objc-class.h"
153 #import <objc/objc-runtime.h>
154 #import <objc/hashtable2.h>
156 #import "objc-private.h"
157 #import <objc/Object.h>
158 #import <objc/Protocol.h>
160 #import "objc-auto.h"
162 #include <sys/time.h>
163 #include <sys/resource.h>
164 #include <sys/types.h>
165 #include <sys/stat.h>
168 /* NXHashTable SPI */
169 OBJC_EXPORT unsigned _NXHashCapacity(NXHashTable *table);
170 OBJC_EXPORT void _NXHashRehashToCapacity(NXHashTable *table, unsigned newCapacity);
173 OBJC_EXPORT Class _objc_getNonexistentClass(void);
176 OBJC_EXPORT Class getOriginalClassForPosingClass(Class);
179 /***********************************************************************
180 * Constants and macros internal to this module.
181 **********************************************************************/
183 /* Turn on support for literal string objects. */
184 #define LITERAL_STRING_OBJECTS
186 /***********************************************************************
187 * Types internal to this module.
188 **********************************************************************/
190 typedef struct _objc_unresolved_category
192 struct _objc_unresolved_category * next;
193 struct objc_category * cat; // may be NULL
195 } _objc_unresolved_category;
197 typedef struct _PendingSubclass
199 struct objc_class *subclass; // subclass to finish connecting; may be NULL
200 struct _PendingSubclass *next;
203 typedef struct _PendingClassRef
205 struct objc_class **ref; // class reference to fix up; may be NULL
206 struct _PendingClassRef *next;
209 struct loadable_class {
210 struct objc_class *cls; // may be NULL
214 struct loadable_category {
215 struct objc_category *cat; // may be NULL
220 /***********************************************************************
222 **********************************************************************/
224 // Function called after class has been fixed up (MACH only)
225 void (*callbackFunction)(Class, const char *) = 0;
227 // Lock for class hashtable
228 OBJC_DECLARE_LOCK (classLock);
230 // Settings from environment variables
231 __private_extern__ int PrintImages = -1; // env OBJC_PRINT_IMAGES
232 __private_extern__ int PrintLoading = -1; // env OBJC_PRINT_LOAD_METHODS
233 __private_extern__ int PrintConnecting = -1; // env OBJC_PRINT_CONNECTION
234 __private_extern__ int PrintRTP = -1; // env OBJC_PRINT_RTP
235 __private_extern__ int PrintGC = -1; // env OBJC_PRINT_GC
236 __private_extern__ int PrintSharing = -1; // env OBJC_PRINT_SHARING
237 __private_extern__ int PrintCxxCtors = -1; // env OBJC_PRINT_CXX_CTORS
239 __private_extern__ int UseInternalZone = -1; // env OBJC_USE_INTERNAL_ZONE
240 __private_extern__ int AllowInterposing = -1;// env OBJC_ALLOW_INTERPOSING
242 __private_extern__ int DebugUnload = -1; // env OBJC_DEBUG_UNLOAD
243 __private_extern__ int DebugFragileSuperclasses = -1; // env OBJC_DEBUG_FRAGILE_SUPERCLASSES
245 __private_extern__ int ForceGC = -1; // env OBJC_FORCE_GC
246 __private_extern__ int ForceNoGC = -1; // env OBJC_FORCE_NO_GC
247 __private_extern__ int CheckFinalizers = -1; // env OBJC_CHECK_FINALIZERS
249 // objc's key for pthread_getspecific
250 __private_extern__ pthread_key_t _objc_pthread_key = 0;
252 // List of classes that need +load called (pending superclass +load)
253 // This list always has superclasses first because of the way it is constructed
254 static struct loadable_class *loadable_classes NOBSS = NULL;
255 static int loadable_classes_used NOBSS = 0;
256 static int loadable_classes_allocated NOBSS = 0;
258 // List of categories that need +load called (pending parent class +load)
259 static struct loadable_category *loadable_categories NOBSS = NULL;
260 static int loadable_categories_used NOBSS = 0;
261 static int loadable_categories_allocated NOBSS = 0;
263 // Selectors for which @selector() doesn't work
264 __private_extern__ SEL cxx_construct_sel = NULL;
265 __private_extern__ SEL cxx_destruct_sel = NULL;
266 __private_extern__ const char *cxx_construct_name = ".cxx_construct";
267 __private_extern__ const char *cxx_destruct_name = ".cxx_destruct";
270 /***********************************************************************
271 * Function prototypes internal to this module.
272 **********************************************************************/
274 static unsigned classHash (void * info, struct objc_class * data);
275 static int classIsEqual (void * info, struct objc_class * name, struct objc_class * cls);
276 static int _objc_defaultClassHandler (const char * clsName);
277 static void _objcTweakMethodListPointerForClass (struct objc_class * cls);
278 static void _objc_add_category_flush_caches(struct objc_class * cls, struct objc_category * category, int version);
279 static void _objc_add_category(struct objc_class * cls, struct objc_category * category, int version);
280 static void _objc_register_category (struct objc_category * cat, long version);
281 static void _objc_read_categories_from_image (header_info * hi);
282 static const header_info * _headerForClass (struct objc_class * cls);
283 static NXMapTable * pendingClassRefsMapTable (void);
284 static NXMapTable * pendingSubclassesMapTable (void);
285 static void _objc_read_classes_from_image (header_info * hi);
286 static void _objc_map_class_refs_for_image (header_info * hi);
287 static void _objc_fixup_protocol_objects_for_image (header_info * hi);
288 static void _objc_fixup_selector_refs (const header_info * hi);
289 static void _objc_unmap_image(const headerType *mh);
290 static BOOL connect_class(struct objc_class *cls);
291 static void add_category_to_loadable_list(struct objc_category *cat);
294 /***********************************************************************
295 * Static data internal to this module.
296 **********************************************************************/
298 // we keep a linked list of header_info's describing each image as told to us by dyld
299 static header_info *FirstHeader NOBSS = 0; // NULL means empty list
300 static header_info *LastHeader NOBSS = 0; // NULL means invalid; recompute it
302 // Hash table of classes
303 static NXHashTable * class_hash NOBSS = 0;
304 static NXHashTablePrototype classHashPrototype =
306 (unsigned (*) (const void *, const void *)) classHash,
307 (int (*)(const void *, const void *, const void *)) classIsEqual,
311 // Hash table of unconnected classes
312 static NXHashTable *unconnected_class_hash NOBSS = NULL;
314 // Exported copy of class_hash variable (hook for debugging tools)
315 NXHashTable *_objc_debug_class_hash = NULL;
317 // Function pointer objc_getClass calls through when class is not found
318 static int (*objc_classHandler) (const char *) = _objc_defaultClassHandler;
320 // Function pointer called by objc_getClass and objc_lookupClass when
321 // class is not found. _objc_classLoader is called before objc_classHandler.
322 static BOOL (*_objc_classLoader)(const char *) = NULL;
324 // Category and class registries
325 // Keys are COPIES of strings, to prevent stale pointers with unloaded bundles
326 // Use NXMapKeyCopyingInsert and NXMapKeyFreeingRemove
327 static NXMapTable * category_hash = NULL;
329 // Keys are COPIES of strings, to prevent stale pointers with unloaded bundles
330 // Use NXMapKeyCopyingInsert and NXMapKeyFreeingRemove
331 static NXMapTable * pendingClassRefsMap = NULL;
332 static NXMapTable * pendingSubclassesMap = NULL;
334 /***********************************************************************
335 * objc_dump_class_hash. Log names of all known classes.
336 **********************************************************************/
337 void objc_dump_class_hash (void)
341 struct objc_class * data;
346 state = NXInitHashState (table);
347 while (NXNextHashState (table, &state, (void **) &data))
348 printf ("class %d: %s\n", ++count, data->name);
351 /***********************************************************************
353 **********************************************************************/
354 static unsigned classHash (void * info,
355 struct objc_class * data)
357 // Nil classes hash to zero
361 // Call through to real hash function
362 return _objc_strhash ((unsigned char *) ((struct objc_class *) data)->name);
365 /***********************************************************************
366 * classIsEqual. Returns whether the class names match. If we ever
367 * check more than the name, routines like objc_lookUpClass have to
369 **********************************************************************/
370 static int classIsEqual (void * info,
371 struct objc_class * name,
372 struct objc_class * cls)
374 // Standard string comparison
375 // Our local inlined version is significantly shorter on PPC and avoids the
376 // mflr/mtlr and dyld_stub overhead when calling strcmp.
377 return _objc_strcmp(name->name, cls->name) == 0;
381 /***********************************************************************
382 * NXMapKeyCopyingInsert
383 * Like NXMapInsert, but strdups the key if necessary.
384 * Used to prevent stale pointers when bundles are unloaded.
385 **********************************************************************/
386 static void *NXMapKeyCopyingInsert(NXMapTable *table, const void *key, const void *value)
389 void *realValue = NULL;
391 if ((realKey = NXMapMember(table, key, &realValue)) != NX_MAPNOTAKEY) {
392 // key DOES exist in table - use table's key for insertion
394 // key DOES NOT exist in table - copy the new key before insertion
395 realKey = _strdup_internal(key);
397 return NXMapInsert(table, realKey, value);
401 /***********************************************************************
402 * NXMapKeyFreeingRemove
403 * Like NXMapRemove, but frees the existing key if necessary.
404 * Used to prevent stale pointers when bundles are unloaded.
405 **********************************************************************/
406 static void *NXMapKeyFreeingRemove(NXMapTable *table, const void *key)
409 void *realValue = NULL;
411 if ((realKey = NXMapMember(table, key, &realValue)) != NX_MAPNOTAKEY) {
412 // key DOES exist in table - remove pair and free key
413 realValue = NXMapRemove(table, realKey);
414 _free_internal(realKey); // the key from the table, not necessarily the one given
417 // key DOES NOT exist in table - nothing to do
423 /***********************************************************************
424 * _objc_init_class_hash. Return the class lookup table, create it if
426 **********************************************************************/
427 void _objc_init_class_hash (void)
429 // Do nothing if class hash table already exists
433 // class_hash starts small, with only enough capacity for libobjc itself.
434 // If a second library is found by map_images(), class_hash is immediately
435 // resized to capacity 1024 to cut down on rehashes.
436 // Old numbers: A smallish Foundation+AppKit program will have
437 // about 520 classes. Larger apps (like IB or WOB) have more like
438 // 800 classes. Some customers have massive quantities of classes.
439 // Foundation-only programs aren't likely to notice the ~6K loss.
440 class_hash = NXCreateHashTableFromZone (classHashPrototype,
443 _objc_internal_zone ());
444 _objc_debug_class_hash = class_hash;
447 /***********************************************************************
448 * objc_getClassList. Return the known classes.
449 **********************************************************************/
450 int objc_getClassList(Class *buffer, int bufferLen) {
452 struct objc_class * class;
455 OBJC_LOCK(&classLock);
456 num = NXCountHashTable(class_hash);
457 if (NULL == buffer) {
458 OBJC_UNLOCK(&classLock);
462 state = NXInitHashState(class_hash);
463 while (cnt < bufferLen &&
464 NXNextHashState(class_hash, &state, (void **)&class))
466 buffer[cnt++] = class;
468 OBJC_UNLOCK(&classLock);
472 /***********************************************************************
473 * objc_getClasses. Return class lookup table.
475 * NOTE: This function is very dangerous, since you cannot safely use
476 * the hashtable without locking it, and the lock is private!
477 **********************************************************************/
478 void * objc_getClasses (void)
480 // Return the class lookup hash table
484 /***********************************************************************
485 * _objc_defaultClassHandler. Default objc_classHandler. Does nothing.
486 **********************************************************************/
487 static int _objc_defaultClassHandler (const char * clsName)
489 // Return zero so objc_getClass doesn't bother re-searching
493 /***********************************************************************
494 * objc_setClassHandler. Set objc_classHandler to the specified value.
496 * NOTE: This should probably deal with userSuppliedHandler being NULL,
497 * because the objc_classHandler caller does not check... it would bus
498 * error. It would make sense to handle NULL by restoring the default
499 * handler. Is anyone hacking with this, though?
500 **********************************************************************/
501 void objc_setClassHandler (int (*userSuppliedHandler) (const char *))
503 objc_classHandler = userSuppliedHandler;
507 /***********************************************************************
509 * Map a class name to a class using various methods.
510 * This is the common implementation of objc_lookUpClass and objc_getClass,
511 * and is also used internally to get additional search options.
514 * 2. unconnected_class_hash (optional)
515 * 3. classLoader callback
516 * 4. classHandler callback (optional)
517 **********************************************************************/
518 static id look_up_class(const char *aClassName, BOOL includeUnconnected, BOOL includeClassHandler)
520 BOOL includeClassLoader = YES; // class loader cannot be skipped
522 struct objc_class query;
524 query.name = aClassName;
528 if (!result && class_hash) {
529 // Check ordinary classes
530 OBJC_LOCK (&classLock);
531 result = (id)NXHashGet(class_hash, &query);
532 OBJC_UNLOCK (&classLock);
535 if (!result && includeUnconnected && unconnected_class_hash) {
536 // Check not-yet-connected classes
537 OBJC_LOCK(&classLock);
538 result = (id)NXHashGet(unconnected_class_hash, &query);
539 OBJC_UNLOCK(&classLock);
542 if (!result && includeClassLoader && _objc_classLoader) {
543 // Try class loader callback
544 if ((*_objc_classLoader)(aClassName)) {
545 // Re-try lookup without class loader
546 includeClassLoader = NO;
551 if (!result && includeClassHandler && objc_classHandler) {
552 // Try class handler callback
553 if ((*objc_classHandler)(aClassName)) {
554 // Re-try lookup without class handler or class loader
555 includeClassLoader = NO;
556 includeClassHandler = NO;
565 /***********************************************************************
566 * objc_getClass. Return the id of the named class. If the class does
567 * not exist, call _objc_classLoader and then objc_classHandler, either of
568 * which may create a new class.
569 * Warning: doesn't work if aClassName is the name of a posed-for class's isa!
570 **********************************************************************/
571 id objc_getClass (const char * aClassName)
573 // NO unconnected, YES class handler
574 return look_up_class(aClassName, NO, YES);
578 /***********************************************************************
579 * objc_getRequiredClass.
580 * Same as objc_getClass, but kills the process if the class is not found.
581 * This is used by ZeroLink, where failing to find a class would be a
582 * compile-time link error without ZeroLink.
583 **********************************************************************/
584 id objc_getRequiredClass(const char *aClassName)
586 id cls = objc_getClass(aClassName);
587 if (!cls) _objc_fatal("link error: class '%s' not found.", aClassName);
592 /***********************************************************************
593 * objc_lookUpClass. Return the id of the named class.
594 * If the class does not exist, call _objc_classLoader, which may create
597 * Formerly objc_getClassWithoutWarning ()
598 **********************************************************************/
599 id objc_lookUpClass (const char * aClassName)
601 // NO unconnected, NO class handler
602 return look_up_class(aClassName, NO, NO);
605 /***********************************************************************
606 * objc_getMetaClass. Return the id of the meta class the named class.
607 * Warning: doesn't work if aClassName is the name of a posed-for class's isa!
608 **********************************************************************/
609 id objc_getMetaClass (const char * aClassName)
611 struct objc_class * cls;
613 cls = objc_getClass (aClassName);
616 _objc_inform ("class `%s' not linked into application", aClassName);
623 /***********************************************************************
624 * objc_addClass. Add the specified class to the table of known classes,
625 * after doing a little verification and fixup.
626 **********************************************************************/
627 void objc_addClass (struct objc_class *cls)
629 // Synchronize access to hash table
630 OBJC_LOCK (&classLock);
632 // Make sure both the class and the metaclass have caches!
633 // Clear all bits of the info fields except CLS_CLASS and CLS_META.
634 // Normally these bits are already clear but if someone tries to cons
635 // up their own class on the fly they might need to be cleared.
636 if (cls->cache == NULL) {
637 cls->cache = (Cache) &emptyCache;
638 cls->info = CLS_CLASS;
641 if (cls->isa->cache == NULL) {
642 cls->isa->cache = (Cache) &emptyCache;
643 cls->isa->info = CLS_META;
646 // methodLists should be:
647 // 1. NULL (Tiger and later only)
648 // 2. A -1 terminated method list array
649 // In either case, CLS_NO_METHOD_ARRAY remains clear.
650 // If the user manipulates the method list directly,
651 // they must use the magic private format.
653 // Add the class to the table
654 (void) NXHashInsert (class_hash, cls);
657 OBJC_UNLOCK (&classLock);
660 /***********************************************************************
661 * _objcTweakMethodListPointerForClass.
662 * Change the class's method list pointer to a method list array.
663 * Does nothing if the method list pointer is already a method list array.
664 * If the class is currently in use, methodListLock must be held by the caller.
665 **********************************************************************/
666 static void _objcTweakMethodListPointerForClass (struct objc_class * cls)
668 struct objc_method_list * originalList;
669 const int initialEntries = 4;
671 struct objc_method_list ** ptr;
673 // Do nothing if methodLists is already an array.
674 if (cls->methodLists && !(cls->info & CLS_NO_METHOD_ARRAY)) return;
676 // Remember existing list
677 originalList = (struct objc_method_list *) cls->methodLists;
679 // Allocate and zero a method list array
680 mallocSize = sizeof(struct objc_method_list *) * initialEntries;
681 ptr = (struct objc_method_list **) _calloc_internal(1, mallocSize);
683 // Insert the existing list into the array
684 ptr[initialEntries - 1] = END_OF_METHODS_LIST;
685 ptr[0] = originalList;
687 // Replace existing list with array
688 cls->methodLists = ptr;
689 _class_clearInfo(cls, CLS_NO_METHOD_ARRAY);
693 /***********************************************************************
694 * _objc_insertMethods.
695 * Adds methods to a class.
696 * Does not flush any method caches.
697 * Does not take any locks.
698 * If the class is already in use, use class_addMethods() instead.
699 **********************************************************************/
700 void _objc_insertMethods(struct objc_class *cls,
701 struct objc_method_list *mlist)
703 struct objc_method_list ***list;
704 struct objc_method_list **ptr;
709 if (!cls->methodLists) {
710 // cls has no methods - simply use this method list
711 cls->methodLists = (struct objc_method_list **)mlist;
712 _class_setInfo(cls, CLS_NO_METHOD_ARRAY);
716 // Create method list array if necessary
717 _objcTweakMethodListPointerForClass(cls);
719 list = &cls->methodLists;
721 // Locate unused entry for insertion point
723 while ((*ptr != 0) && (*ptr != END_OF_METHODS_LIST))
726 // If array is full, add to it
727 if (*ptr == END_OF_METHODS_LIST)
729 // Calculate old and new dimensions
730 endIndex = ptr - *list;
731 oldSize = (endIndex + 1) * sizeof(void *);
732 newSize = oldSize + sizeof(struct objc_method_list *); // only increase by 1
734 // Grow the method list array by one.
735 // This block may be from user code; don't use _realloc_internal
736 *list = (struct objc_method_list **)realloc(*list, newSize);
738 // Zero out addition part of new array
739 bzero (&((*list)[endIndex]), newSize - oldSize);
741 // Place new end marker
742 (*list)[(newSize/sizeof(void *)) - 1] = END_OF_METHODS_LIST;
744 // Insertion point corresponds to old array end
745 ptr = &((*list)[endIndex]);
748 // Right shift existing entries by one
749 bcopy (*list, (*list) + 1, ((void *) ptr) - ((void *) *list));
751 // Insert at method list at beginning of array
755 /***********************************************************************
756 * _objc_removeMethods.
757 * Remove methods from a class.
758 * Does not take any locks.
759 * Does not flush any method caches.
760 * If the class is currently in use, use class_removeMethods() instead.
761 **********************************************************************/
762 void _objc_removeMethods(struct objc_class *cls,
763 struct objc_method_list *mlist)
765 struct objc_method_list ***list;
766 struct objc_method_list **ptr;
768 if (cls->methodLists == NULL) {
769 // cls has no methods
772 if (cls->methodLists == (struct objc_method_list **)mlist) {
773 // mlist is the class's only method list - erase it
774 cls->methodLists = NULL;
777 if (cls->info & CLS_NO_METHOD_ARRAY) {
778 // cls has only one method list, and this isn't it - do nothing
782 // cls has a method list array - search it
784 list = &cls->methodLists;
786 // Locate list in the array
788 while (*ptr != mlist) {
789 // fix for radar # 2538790
790 if ( *ptr == END_OF_METHODS_LIST ) return;
797 // Left shift the following entries
798 while (*(++ptr) != END_OF_METHODS_LIST)
803 /***********************************************************************
804 * _objc_add_category. Install the specified category's methods and
805 * protocols into the class it augments.
806 * The class is assumed not to be in use yet: no locks are taken and
807 * no method caches are flushed.
808 **********************************************************************/
809 static inline void _objc_add_category(struct objc_class *cls, struct objc_category *category, int version)
811 if (PrintConnecting) {
812 _objc_inform("CONNECT: attaching category '%s (%s)'", cls->name, category->category_name);
815 // Augment instance methods
816 if (category->instance_methods)
817 _objc_insertMethods (cls, category->instance_methods);
819 // Augment class methods
820 if (category->class_methods)
821 _objc_insertMethods (cls->isa, category->class_methods);
824 if ((version >= 5) && category->protocols)
826 if (cls->isa->version >= 5)
828 category->protocols->next = cls->protocols;
829 cls->protocols = category->protocols;
830 cls->isa->protocols = category->protocols;
834 _objc_inform ("unable to add protocols from category %s...\n", category->category_name);
835 _objc_inform ("class `%s' must be recompiled\n", category->class_name);
840 /***********************************************************************
841 * _objc_add_category_flush_caches. Install the specified category's
842 * methods into the class it augments, and flush the class' method cache.
843 **********************************************************************/
844 static void _objc_add_category_flush_caches(struct objc_class *cls, struct objc_category *category, int version)
846 // Install the category's methods into its intended class
847 OBJC_LOCK(&methodListLock);
848 _objc_add_category (cls, category, version);
849 OBJC_UNLOCK(&methodListLock);
851 // Flush caches so category's methods can get called
852 _objc_flush_caches (cls);
856 /***********************************************************************
858 * Reverse the given linked list of pending categories.
859 * The pending category list is built backwards, and needs to be
860 * reversed before actually attaching the categories to a class.
861 * Returns the head of the new linked list.
862 **********************************************************************/
863 static _objc_unresolved_category *reverse_cat(_objc_unresolved_category *cat)
865 if (!cat) return NULL;
867 _objc_unresolved_category *prev = NULL;
868 _objc_unresolved_category *cur = cat;
869 _objc_unresolved_category *ahead = cat->next;
882 /***********************************************************************
883 * resolve_categories_for_class.
884 * Install all existing categories intended for the specified class.
885 * cls must be a true class and not a metaclass.
886 **********************************************************************/
887 static void resolve_categories_for_class(struct objc_class *cls)
889 _objc_unresolved_category * pending;
890 _objc_unresolved_category * next;
892 // Nothing to do if there are no categories at all
893 if (!category_hash) return;
895 // Locate and remove first element in category list
896 // associated with this class
897 pending = NXMapKeyFreeingRemove (category_hash, cls->name);
899 // Traverse the list of categories, if any, registered for this class
901 // The pending list is built backwards. Reverse it and walk forwards.
902 pending = reverse_cat(pending);
906 // Install the category
907 // use the non-flush-cache version since we are only
908 // called from the class intialization code
909 _objc_add_category(cls, pending->cat, pending->version);
912 // Delink and reclaim this registration
913 next = pending->next;
914 _free_internal(pending);
920 /***********************************************************************
921 * _objc_resolve_categories_for_class.
922 * Public version of resolve_categories_for_class. This was
923 * exported pre-10.4 for Omni et al. to workaround a problem
924 * with too-lazy category attachment.
925 * cls should be a class, but this function can also cope with metaclasses.
926 **********************************************************************/
927 void _objc_resolve_categories_for_class(struct objc_class *cls)
930 // If cls is a metaclass, get the class.
931 // resolve_categories_for_class() requires a real class to work correctly.
933 if (strncmp(cls->name, "_%", 2) == 0) {
934 // Posee's meta's name is smashed and isn't in the class_hash,
935 // so objc_getClass doesn't work.
936 char *baseName = strchr(cls->name, '%'); // get posee's real name
937 cls = objc_getClass(baseName);
939 cls = objc_getClass(cls->name);
943 resolve_categories_for_class(cls);
947 /***********************************************************************
948 * _objc_register_category.
949 * Process a category read from an image.
950 * If the category's class exists, attach the category immediately.
951 * If the category's class does not exist yet, pend the category for
952 * later attachment. Pending categories are attached in the order
953 * they were discovered.
954 **********************************************************************/
955 static void _objc_register_category(struct objc_category *cat, long version)
957 _objc_unresolved_category * new_cat;
958 _objc_unresolved_category * old;
959 struct objc_class *theClass;
961 // If the category's class exists, attach the category.
962 if ((theClass = objc_lookUpClass(cat->class_name))) {
963 _objc_add_category_flush_caches(theClass, cat, version);
967 // If the category's class exists but is unconnected,
968 // then attach the category to the class but don't bother
969 // flushing any method caches (because they must be empty).
970 // YES unconnected, NO class_handler
971 if ((theClass = look_up_class(cat->class_name, YES, NO))) {
972 _objc_add_category(theClass, cat, version);
977 // Category's class does not exist yet.
978 // Save the category for later attachment.
980 if (PrintConnecting) {
981 _objc_inform("CONNECT: pending category '%s (%s)'", cat->class_name, cat->category_name);
984 // Create category lookup table if needed
986 category_hash = NXCreateMapTableFromZone (NXStrValueMapPrototype,
988 _objc_internal_zone ());
990 // Locate an existing list of categories, if any, for the class.
991 old = NXMapGet (category_hash, cat->class_name);
993 // Register the category to be fixed up later.
994 // The category list is built backwards, and is reversed again
995 // by resolve_categories_for_class().
996 new_cat = _malloc_internal(sizeof(_objc_unresolved_category));
999 new_cat->version = version;
1000 (void) NXMapKeyCopyingInsert (category_hash, cat->class_name, new_cat);
1004 /***********************************************************************
1005 * _objc_read_categories_from_image.
1006 * Read all categories from the given image.
1007 * Install them on their parent classes, or register them for later
1009 * Register them for later +load, if implemented.
1010 **********************************************************************/
1011 static void _objc_read_categories_from_image (header_info * hi)
1016 if (_objcHeaderIsReplacement(hi)) {
1017 // Ignore any categories in this image
1022 // Major loop - process all modules in the header
1025 // NOTE: The module and category lists are traversed backwards
1026 // to preserve the pre-10.4 processing order. Changing the order
1027 // would have a small chance of introducing binary compatibility bugs.
1028 midx = hi->mod_count;
1029 while (midx-- > 0) {
1033 // Nothing to do for a module without a symbol table
1034 if (mods[midx].symtab == NULL)
1037 // Total entries in symbol table (class entries followed
1038 // by category entries)
1039 total = mods[midx].symtab->cls_def_cnt +
1040 mods[midx].symtab->cat_def_cnt;
1042 // Minor loop - register all categories from given module
1044 while (index-- > mods[midx].symtab->cls_def_cnt) {
1045 struct objc_category *cat = mods[midx].symtab->defs[index];
1046 _objc_register_category(cat, mods[midx].version);
1047 add_category_to_loadable_list(cat);
1053 /***********************************************************************
1054 * _headerForAddress.
1055 * addr can be a class or a category
1056 **********************************************************************/
1057 static const header_info *_headerForAddress(void *addr)
1061 header_info * hInfo;
1063 // Check all headers in the vector
1064 for (hInfo = FirstHeader; hInfo != NULL; hInfo = hInfo->next)
1066 // Locate header data, if any
1067 if (!hInfo->objcSegmentHeader) continue;
1068 seg = hInfo->objcSegmentHeader->vmaddr + hInfo->image_slide;
1069 size = hInfo->objcSegmentHeader->filesize;
1071 // Is the class in this header?
1072 if ((seg <= (unsigned long) addr) &&
1073 ((unsigned long) addr < (seg + size)))
1082 /***********************************************************************
1084 * Return the image header containing this class, or NULL.
1085 * Returns NULL on runtime-constructed classes, and the NSCF classes.
1086 **********************************************************************/
1087 static const header_info *_headerForClass(struct objc_class *cls)
1089 return _headerForAddress(cls);
1093 /***********************************************************************
1095 **********************************************************************/
1096 const char * _nameForHeader (const headerType * header)
1098 return _getObjcHeaderName ((headerType *) header);
1102 /***********************************************************************
1103 * class_is_connected.
1104 * Returns TRUE if class cls is connected.
1105 * A connected class has either a connected superclass or a NULL superclass,
1106 * and is present in class_hash.
1107 **********************************************************************/
1108 static BOOL class_is_connected(struct objc_class *cls)
1111 OBJC_LOCK(&classLock);
1112 result = NXHashMember(class_hash, cls);
1113 OBJC_UNLOCK(&classLock);
1118 /***********************************************************************
1119 * pendingClassRefsMapTable. Return a pointer to the lookup table for
1120 * pending class refs.
1121 **********************************************************************/
1122 static inline NXMapTable *pendingClassRefsMapTable(void)
1124 // Allocate table if needed
1125 if (!pendingClassRefsMap) {
1126 pendingClassRefsMap =
1127 NXCreateMapTableFromZone(NXStrValueMapPrototype,
1128 10, _objc_internal_zone ());
1131 // Return table pointer
1132 return pendingClassRefsMap;
1136 /***********************************************************************
1137 * pendingSubclassesMapTable. Return a pointer to the lookup table for
1138 * pending subclasses.
1139 **********************************************************************/
1140 static inline NXMapTable *pendingSubclassesMapTable(void)
1142 // Allocate table if needed
1143 if (!pendingSubclassesMap) {
1144 pendingSubclassesMap =
1145 NXCreateMapTableFromZone(NXStrValueMapPrototype,
1146 10, _objc_internal_zone ());
1149 // Return table pointer
1150 return pendingSubclassesMap;
1154 /***********************************************************************
1155 * pendClassInstallation
1156 * Finish connecting class cls when its superclass becomes connected.
1157 * Check for multiple pends of the same class because connect_class does not.
1158 **********************************************************************/
1159 static void pendClassInstallation(struct objc_class *cls,
1160 const char *superName)
1163 PendingSubclass *pending;
1164 PendingSubclass *oldList;
1167 // Create and/or locate pending class lookup table
1168 table = pendingSubclassesMapTable ();
1170 // Make sure this class isn't already in the pending list.
1171 oldList = NXMapGet (table, superName);
1172 for (l = oldList; l != NULL; l = l->next) {
1173 if (l->subclass == cls) return; // already here, nothing to do
1176 // Create entry referring to this class
1177 pending = _malloc_internal(sizeof(PendingSubclass));
1178 pending->subclass = cls;
1180 // Link new entry into head of list of entries for this class
1181 pending->next = oldList;
1183 // (Re)place entry list in the table
1184 (void) NXMapKeyCopyingInsert (table, superName, pending);
1188 /***********************************************************************
1189 * pendClassReference
1190 * Fix up a class ref when the class with the given name becomes connected.
1191 **********************************************************************/
1192 static void pendClassReference(struct objc_class **ref,
1193 const char *className)
1196 PendingClassRef *pending;
1198 // Create and/or locate pending class lookup table
1199 table = pendingClassRefsMapTable ();
1201 // Create entry containing the class reference
1202 pending = _malloc_internal(sizeof(PendingClassRef));
1205 // Link new entry into head of list of entries for this class
1206 pending->next = NXMapGet (table, className);
1208 // (Re)place entry list in the table
1209 (void) NXMapKeyCopyingInsert (table, className, pending);
1211 if (PrintConnecting) {
1212 _objc_inform("CONNECT: pended reference to class '%s' at %p",
1213 className, (void *)ref);
1218 /***********************************************************************
1219 * resolve_references_to_class
1220 * Fix up any pending class refs to this class.
1221 **********************************************************************/
1222 static void resolve_references_to_class(struct objc_class *cls)
1224 PendingClassRef *pending;
1226 if (!pendingClassRefsMap) return; // no unresolved refs for any class
1228 pending = NXMapGet(pendingClassRefsMap, cls->name);
1229 if (!pending) return; // no unresolved refs for this class
1231 NXMapKeyFreeingRemove(pendingClassRefsMap, cls->name);
1233 if (PrintConnecting) {
1234 _objc_inform("CONNECT: resolving references to class '%s'", cls->name);
1238 PendingClassRef *next = pending->next;
1239 if (pending->ref) *pending->ref = cls;
1240 _free_internal(pending);
1244 if (NXCountMapTable(pendingClassRefsMap) == 0) {
1245 NXFreeMapTable(pendingClassRefsMap);
1246 pendingClassRefsMap = NULL;
1251 /***********************************************************************
1252 * resolve_subclasses_of_class
1253 * Fix up any pending subclasses of this class.
1254 **********************************************************************/
1255 static void resolve_subclasses_of_class(struct objc_class *cls)
1257 PendingSubclass *pending;
1259 if (!pendingSubclassesMap) return; // no unresolved subclasses
1261 pending = NXMapGet(pendingSubclassesMap, cls->name);
1262 if (!pending) return; // no unresolved subclasses for this class
1264 NXMapKeyFreeingRemove(pendingSubclassesMap, cls->name);
1266 // Destroy the pending table if it's now empty, to save memory.
1267 if (NXCountMapTable(pendingSubclassesMap) == 0) {
1268 NXFreeMapTable(pendingSubclassesMap);
1269 pendingSubclassesMap = NULL;
1272 if (PrintConnecting) {
1273 _objc_inform("CONNECT: resolving subclasses of class '%s'", cls->name);
1277 PendingSubclass *next = pending->next;
1278 if (pending->subclass) connect_class(pending->subclass);
1279 _free_internal(pending);
1285 /***********************************************************************
1286 * get_base_method_list
1287 * Returns the method list containing the class's own methods,
1288 * ignoring any method lists added by categories or class_addMethods.
1289 * Called only by add_class_to_loadable_list.
1290 * Does not hold methodListLock because add_class_to_loadable_list
1291 * does not manipulate in-use classes.
1292 **********************************************************************/
1293 static struct objc_method_list *get_base_method_list(struct objc_class *cls)
1295 struct objc_method_list **ptr;
1297 if (!cls->methodLists) return NULL;
1298 if (cls->info & CLS_NO_METHOD_ARRAY) return (struct objc_method_list *)cls->methodLists;
1299 ptr = cls->methodLists;
1300 if (!*ptr || *ptr == END_OF_METHODS_LIST) return NULL;
1301 while ( *ptr != 0 && *ptr != END_OF_METHODS_LIST ) { ptr++; }
1307 /***********************************************************************
1308 * add_class_to_loadable_list
1309 * Class cls has just become connected. Schedule it for +load if
1310 * it implements a +load method.
1311 **********************************************************************/
1312 static void add_class_to_loadable_list(struct objc_class *cls)
1315 struct objc_method_list *mlist;
1317 if (cls->isa->info & CLS_HAS_LOAD_METHOD) {
1318 mlist = get_base_method_list(cls->isa);
1320 method = lookupNamedMethodInMethodList (mlist, "load");
1323 // Don't bother if cls has no +load method
1324 if (!method) return;
1327 _objc_inform("LOAD: class '%s' scheduled for +load", cls->name);
1330 if (loadable_classes_used == loadable_classes_allocated) {
1331 loadable_classes_allocated = loadable_classes_allocated*2 + 16;
1333 _realloc_internal(loadable_classes,
1334 loadable_classes_allocated *
1335 sizeof(struct loadable_class));
1338 loadable_classes[loadable_classes_used].cls = cls;
1339 loadable_classes[loadable_classes_used].method = method;
1340 loadable_classes_used++;
1344 /***********************************************************************
1345 * add_category_to_loadable_list
1346 * Category cat's parent class exists and the category has been attached
1347 * to its class. Schedule this category for +load after its parent class
1348 * becomes connected and has its own +load method called.
1349 **********************************************************************/
1350 static void add_category_to_loadable_list(struct objc_category *cat)
1353 struct objc_method_list *mlist;
1355 mlist = cat->class_methods;
1357 method = lookupNamedMethodInMethodList (mlist, "load");
1359 // Don't bother if cat has no +load method
1360 if (!method) return;
1363 _objc_inform("LOAD: category '%s(%s)' scheduled for +load",
1364 cat->class_name, cat->category_name);
1367 if (loadable_categories_used == loadable_categories_allocated) {
1368 loadable_categories_allocated = loadable_categories_allocated*2 + 16;
1369 loadable_categories =
1370 _realloc_internal(loadable_categories,
1371 loadable_categories_allocated *
1372 sizeof(struct loadable_category));
1375 loadable_categories[loadable_categories_used].cat = cat;
1376 loadable_categories[loadable_categories_used].method = method;
1377 loadable_categories_used++;
1381 /***********************************************************************
1382 * remove_class_from_loadable_list
1383 * Class cls may have been loadable before, but it is now no longer
1384 * loadable (because its image is being unmapped).
1385 **********************************************************************/
1386 static void remove_class_from_loadable_list(struct objc_class *cls)
1388 if (loadable_classes) {
1390 for (i = 0; i < loadable_classes_used; i++) {
1391 if (loadable_classes[i].cls == cls) {
1392 loadable_classes[i].cls = NULL;
1394 _objc_inform("LOAD: class '%s' unscheduled for +load", cls->name);
1403 /***********************************************************************
1404 * remove_category_from_loadable_list
1405 * Category cat may have been loadable before, but it is now no longer
1406 * loadable (because its image is being unmapped).
1407 **********************************************************************/
1408 static void remove_category_from_loadable_list(struct objc_category *cat)
1410 if (loadable_categories) {
1412 for (i = 0; i < loadable_categories_used; i++) {
1413 if (loadable_categories[i].cat == cat) {
1414 loadable_categories[i].cat = NULL;
1416 _objc_inform("LOAD: category '%s(%s)' unscheduled for +load",
1417 cat->class_name, cat->category_name);
1426 /***********************************************************************
1428 * Call all pending class +load methods.
1429 * If new classes become loadable, +load is NOT called for them.
1431 * Called only by call_load_methods().
1432 **********************************************************************/
1433 static void call_class_loads(void)
1437 // Detach current loadable list.
1438 struct loadable_class *classes = loadable_classes;
1439 int used = loadable_classes_used;
1440 loadable_classes = NULL;
1441 loadable_classes_allocated = 0;
1442 loadable_classes_used = 0;
1444 // Call all +loads for the detached list.
1445 for (i = 0; i < used; i++) {
1446 struct objc_class *cls = classes[i].cls;
1447 IMP load_method = classes[i].method;
1451 _objc_inform("LOAD: +[%s load]\n", cls->name);
1453 (*load_method) ((id) cls, @selector(load));
1456 // Destroy the detached list.
1457 if (classes) _free_internal(classes);
1461 /***********************************************************************
1462 * call_category_loads
1463 * Call some pending category +load methods.
1464 * The parent class of the +load-implementing categories has all of
1465 * its categories attached, in case some are lazily waiting for +initalize.
1466 * Don't call +load unless the parent class is connected.
1467 * If new categories become loadable, +load is NOT called, and they
1468 * are added to the end of the loadable list, and we return TRUE.
1469 * Return FALSE if no new categories became loadable.
1471 * Called only by call_load_methods().
1472 **********************************************************************/
1473 static BOOL call_category_loads(void)
1476 BOOL new_categories_added = NO;
1478 // Detach current loadable list.
1479 struct loadable_category *cats = loadable_categories;
1480 int used = loadable_categories_used;
1481 int allocated = loadable_categories_allocated;
1482 loadable_categories = NULL;
1483 loadable_categories_allocated = 0;
1484 loadable_categories_used = 0;
1486 // Call all +loads for the detached list.
1487 for (i = 0; i < used; i++) {
1488 struct objc_category *cat = cats[i].cat;
1489 IMP load_method = cats[i].method;
1490 struct objc_class *cls;
1493 cls = objc_getClass(cat->class_name);
1494 if (cls && class_is_connected(cls)) {
1496 _objc_inform("LOAD: +[%s(%s) load]\n",
1497 cls->name, cat->category_name);
1499 (*load_method) ((id) cls, @selector(load));
1504 // Compact detached list (order-preserving)
1506 for (i = 0; i < used; i++) {
1508 cats[i-shift] = cats[i];
1515 // Copy any new +load candidates from the new list to the detached list.
1516 new_categories_added = (loadable_categories_used > 0);
1517 for (i = 0; i < loadable_categories_used; i++) {
1518 if (used == allocated) {
1519 allocated = allocated*2 + 16;
1520 cats = _realloc_internal(cats, allocated *
1521 sizeof(struct loadable_category));
1523 cats[used++] = loadable_categories[i];
1526 // Destroy the new list.
1527 if (loadable_categories) _free_internal(loadable_categories);
1529 // Reattach the (now augmented) detached list.
1530 // But if there's nothing left to load, destroy the list.
1532 loadable_categories = cats;
1533 loadable_categories_used = used;
1534 loadable_categories_allocated = allocated;
1536 if (cats) _free_internal(cats);
1537 loadable_categories = NULL;
1538 loadable_categories_used = 0;
1539 loadable_categories_allocated = 0;
1543 if (loadable_categories_used != 0) {
1544 _objc_inform("LOAD: %d categories still waiting for +load\n",
1545 loadable_categories_used);
1549 return new_categories_added;
1553 /***********************************************************************
1555 * Call all pending class and category +load methods.
1556 * Class +load methods are called superclass-first.
1557 * Category +load methods are not called until after the parent class's +load.
1559 * This method must be RE-ENTRANT, because a +load could trigger
1560 * more image mapping. In addition, the superclass-first ordering
1561 * must be preserved in the face of re-entrant calls. Therefore,
1562 * only the OUTERMOST call of this function will do anything, and
1563 * that call will handle all loadable classes, even those generated
1564 * while it was running.
1566 * The sequence below preserves +load ordering in the face of
1567 * image loading during a +load, and make sure that no
1568 * +load method is forgotten because it was added during
1571 * 1. Repeatedly call class +loads until there aren't any more
1572 * 2. Call category +loads ONCE.
1573 * 3. Run more +loads if:
1574 * (a) there are more classes to load, OR
1575 * (b) there are some potential category +loads that have
1576 * still never been attempted.
1577 * Category +loads are only run once to ensure "parent class first"
1578 * ordering, even if a category +load triggers a new loadable class
1579 * and a new loadable category attached to that class.
1581 * fixme this is not thread-safe, but neither is the rest of image mapping.
1582 **********************************************************************/
1583 static void call_load_methods(void)
1585 static pthread_t load_method_thread NOBSS = NULL;
1586 BOOL more_categories;
1588 if (load_method_thread) {
1589 // +loads are already being called. Do nothing, but complain
1590 // if it looks like multithreaded use of this thread-unsafe code.
1592 if (! pthread_equal(load_method_thread, pthread_self())) {
1593 _objc_inform("WARNING: multi-threaded library loading detected "
1594 "(implementation is not thread-safe)");
1599 // Nobody else is calling +loads, so we should do it ourselves.
1600 load_method_thread = pthread_self();
1603 // 1. Repeatedly call class +loads until there aren't any more
1604 while (loadable_classes_used > 0) {
1608 // 2. Call category +loads ONCE
1609 more_categories = call_category_loads();
1611 // 3. Run more +loads if there are classes OR more untried categories
1612 } while (loadable_classes_used > 0 || more_categories);
1614 load_method_thread = NULL;
1618 /***********************************************************************
1619 * really_connect_class
1620 * Connect cls to superclass supercls unconditionally.
1621 * Also adjust the class hash tables and handle +load and pended subclasses.
1623 * This should be called from connect_class() ONLY.
1624 **********************************************************************/
1625 static void really_connect_class(struct objc_class *cls,
1626 struct objc_class *supercls)
1628 struct objc_class *oldCls;
1629 struct objc_class *meta = cls->isa;
1631 // Wire the classes together.
1633 cls->super_class = supercls;
1634 meta->super_class = supercls->isa;
1635 meta->isa = supercls->isa->isa;
1637 cls->super_class = NULL; // superclass of root class is NULL
1638 meta->super_class = cls; // superclass of root metaclass is root class
1639 meta->isa = meta; // metaclass of root metaclass is root metaclass
1642 OBJC_LOCK(&classLock);
1644 // Update hash tables.
1645 NXHashRemove(unconnected_class_hash, cls);
1646 oldCls = NXHashInsert(class_hash, cls);
1648 // Delete unconnected_class_hash if it is now empty.
1649 if (NXCountHashTable(unconnected_class_hash) == 0) {
1650 NXFreeHashTable(unconnected_class_hash);
1651 unconnected_class_hash = NULL;
1654 OBJC_UNLOCK(&classLock);
1656 // Warn if the new class has the same name as a previously-installed class.
1657 // The new class is kept and the old class is discarded.
1659 const header_info *oldHeader = _headerForClass(oldCls);
1660 const header_info *newHeader = _headerForClass(cls);
1661 const char *oldName = _nameForHeader(oldHeader->mhdr);
1662 const char *newName = _nameForHeader(newHeader->mhdr);
1664 _objc_inform ("Both %s and %s have implementations of class %s.",
1665 oldName, newName, oldCls->name);
1666 _objc_inform ("Using implementation from %s.", newName);
1669 // Prepare for +load and connect newly-connectable subclasses
1670 add_class_to_loadable_list(cls);
1671 resolve_subclasses_of_class(cls);
1673 // GC debugging: make sure all classes with -dealloc also have -finalize
1674 if (CheckFinalizers) {
1675 extern IMP findIMPInClass(Class cls, SEL sel);
1676 if (findIMPInClass(cls, sel_getUid("dealloc")) &&
1677 ! findIMPInClass(cls, sel_getUid("finalize")))
1679 _objc_inform("GC: class '%s' implements -dealloc but not -finalize", cls->name);
1683 // Debugging: if this class has ivars, make sure this class's ivars don't
1684 // overlap with its super's. This catches some broken fragile base classes.
1685 // Do not use super->instance_size vs. self->ivar[0] to check this.
1686 // Ivars may be packed across instance_size boundaries.
1687 if (DebugFragileSuperclasses && cls->ivars && cls->ivars->ivar_count) {
1688 struct objc_class *ivar_cls = supercls;
1690 // Find closest superclass that has some ivars, if one exists.
1692 (!ivar_cls->ivars || ivar_cls->ivars->ivar_count == 0))
1694 ivar_cls = ivar_cls->super_class;
1698 // Compare superclass's last ivar to this class's first ivar
1699 struct objc_ivar *super_ivar =
1700 &ivar_cls->ivars->ivar_list[ivar_cls->ivars->ivar_count - 1];
1701 struct objc_ivar *self_ivar =
1702 &cls->ivars->ivar_list[0];
1704 // fixme could be smarter about super's ivar size
1705 if (self_ivar->ivar_offset <= super_ivar->ivar_offset) {
1706 _objc_inform("WARNING: ivars of superclass '%s' and "
1707 "subclass '%s' overlap; superclass may have "
1708 "changed since subclass was compiled",
1709 ivar_cls->name, cls->name);
1716 /***********************************************************************
1718 * Connect class cls to its superclasses, if possible.
1719 * If cls becomes connected, move it from unconnected_class_hash
1720 * to connected_class_hash.
1721 * Returns TRUE if cls is connected.
1722 * Returns FALSE if cls could not be connected for some reason
1723 * (missing superclass or still-unconnected superclass)
1724 **********************************************************************/
1725 static BOOL connect_class(struct objc_class *cls)
1727 if (class_is_connected(cls)) {
1728 // This class is already connected to its superclass.
1732 else if (cls->super_class == NULL) {
1733 // This class is a root class.
1734 // Connect it to itself.
1736 if (PrintConnecting) {
1737 _objc_inform("CONNECT: class '%s' now connected (root class)",
1741 really_connect_class(cls, NULL);
1745 // This class is not a root class and is not yet connected.
1746 // Connect it if its superclass and root class are already connected.
1747 // Otherwise, add this class to the to-be-connected list,
1748 // pending the completion of its superclass and root class.
1750 // At this point, cls->super_class and cls->isa->isa are still STRINGS
1751 char *supercls_name = (char *)cls->super_class;
1752 struct objc_class *supercls;
1754 // YES unconnected, YES class handler
1755 if (NULL == (supercls = look_up_class(supercls_name, YES, YES))) {
1756 // Superclass does not exist yet.
1757 // pendClassInstallation will handle duplicate pends of this class
1758 pendClassInstallation(cls, supercls_name);
1760 if (PrintConnecting) {
1761 _objc_inform("CONNECT: class '%s' NOT connected (missing super)", cls->name);
1766 if (! connect_class(supercls)) {
1767 // Superclass exists but is not yet connected.
1768 // pendClassInstallation will handle duplicate pends of this class
1769 pendClassInstallation(cls, supercls_name);
1771 if (PrintConnecting) {
1772 _objc_inform("CONNECT: class '%s' NOT connected (unconnected super)", cls->name);
1777 // Superclass exists and is connected.
1778 // Connect this class to the superclass.
1780 if (PrintConnecting) {
1781 _objc_inform("CONNECT: class '%s' now connected", cls->name);
1784 really_connect_class(cls, supercls);
1790 /***********************************************************************
1791 * _objc_read_classes_from_image.
1792 * Read classes from the given image, perform assorted minor fixups,
1793 * scan for +load implementation.
1794 * Does not connect classes to superclasses.
1795 * Does attach pended categories to the classes.
1796 * Adds all classes to unconnected_class_hash. class_hash is unchanged.
1797 **********************************************************************/
1798 static void _objc_read_classes_from_image(header_info *hi)
1803 int isBundle = (hi->mhdr->filetype == MH_BUNDLE);
1805 if (_objcHeaderIsReplacement(hi)) {
1806 // Ignore any classes in this image
1810 // class_hash starts small, enough only for libobjc itself.
1811 // If other Objective-C libraries are found, immediately resize
1812 // class_hash, assuming that Foundation and AppKit are about
1813 // to add lots of classes.
1814 OBJC_LOCK(&classLock);
1815 if (hi->mhdr != &_mh_dylib_header && _NXHashCapacity(class_hash) < 1024) {
1816 _NXHashRehashToCapacity(class_hash, 1024);
1818 OBJC_UNLOCK(&classLock);
1820 // Major loop - process all modules in the image
1822 for (midx = 0; midx < hi->mod_count; midx += 1)
1824 // Skip module containing no classes
1825 if (mods[midx].symtab == NULL)
1828 // Minor loop - process all the classes in given module
1829 for (index = 0; index < mods[midx].symtab->cls_def_cnt; index += 1)
1831 struct objc_class * newCls;
1832 struct objc_method_list *mlist;
1834 // Locate the class description pointer
1835 newCls = mods[midx].symtab->defs[index];
1837 // Classes loaded from Mach-O bundles can be unloaded later.
1838 // Nothing uses this class yet, so _class_setInfo is not needed.
1839 if (isBundle) newCls->info |= CLS_FROM_BUNDLE;
1840 if (isBundle) newCls->isa->info |= CLS_FROM_BUNDLE;
1842 // Use common static empty cache instead of NULL
1843 if (newCls->cache == NULL)
1844 newCls->cache = (Cache) &emptyCache;
1845 if (newCls->isa->cache == NULL)
1846 newCls->isa->cache = (Cache) &emptyCache;
1848 // Set metaclass version
1849 newCls->isa->version = mods[midx].version;
1851 // methodLists is NULL or a single list, not an array
1852 newCls->info |= CLS_NO_METHOD_ARRAY;
1853 newCls->isa->info |= CLS_NO_METHOD_ARRAY;
1855 // Check for +load implementation before categories are attached
1856 if ((mlist = get_base_method_list(newCls->isa))) {
1857 if (lookupNamedMethodInMethodList (mlist, "load")) {
1858 newCls->isa->info |= CLS_HAS_LOAD_METHOD;
1862 // Install into unconnected_class_hash
1863 OBJC_LOCK(&classLock);
1864 if (!unconnected_class_hash) {
1865 unconnected_class_hash =
1866 NXCreateHashTableFromZone(classHashPrototype, 128, NULL,
1867 _objc_internal_zone());
1869 NXHashInsert(unconnected_class_hash, newCls);
1870 OBJC_UNLOCK(&classLock);
1872 // Fix up pended class refs to this class, if any
1873 resolve_references_to_class(newCls);
1875 // Attach pended categories for this class, if any
1876 resolve_categories_for_class(newCls);
1882 /***********************************************************************
1883 * _objc_connect_classes_from_image.
1884 * Connect the classes in the given image to their superclasses,
1885 * or register them for later connection if any superclasses are missing.
1886 **********************************************************************/
1887 static void _objc_connect_classes_from_image(header_info *hi)
1892 BOOL replacement = _objcHeaderIsReplacement(hi);
1894 // Major loop - process all modules in the image
1896 for (midx = 0; midx < hi->mod_count; midx += 1)
1898 // Skip module containing no classes
1899 if (mods[midx].symtab == NULL)
1902 // Minor loop - process all the classes in given module
1903 for (index = 0; index < mods[midx].symtab->cls_def_cnt; index += 1)
1905 struct objc_class *cls = mods[midx].symtab->defs[index];
1906 if (! replacement) {
1907 BOOL connected = connect_class(cls);
1908 if (connected && callbackFunction) {
1909 (*callbackFunction)(cls, 0);
1912 // Replacement image - fix up super_class only (#3704817)
1913 const char *super_name = (const char *) cls->super_class;
1914 if (super_name) cls->super_class = objc_getClass(super_name);
1921 /***********************************************************************
1922 * _objc_map_class_refs_for_image. Convert the class ref entries from
1923 * a class name string pointer to a class pointer. If the class does
1924 * not yet exist, the reference is added to a list of pending references
1925 * to be fixed up at a later date.
1926 **********************************************************************/
1927 static void _objc_map_class_refs_for_image (header_info * hi)
1929 struct objc_class * * cls_refs;
1933 // Locate class refs in image
1934 cls_refs = _getObjcClassRefs ((headerType *) hi->mhdr, &size);
1937 cls_refs = (struct objc_class * *) ((unsigned long) cls_refs + hi->image_slide);
1939 // Process each class ref
1940 for (index = 0; index < size; index += 1)
1943 struct objc_class * cls;
1945 // Get ref to convert from name string to class pointer
1946 ref = (const char *) cls_refs[index];
1948 // Get pointer to class of this name
1949 // YES unconnected, YES class loader
1950 cls = look_up_class(ref, YES, YES);
1952 // Referenced class exists. Fix up the reference.
1953 cls_refs[index] = cls;
1955 // Referenced class does not exist yet. Insert a placeholder
1956 // class and fix up the reference later.
1957 pendClassReference (&cls_refs[index], ref);
1958 cls_refs[index] = _objc_getNonexistentClass ();
1964 /***********************************************************************
1965 * _objc_remove_pending_class_refs_in_image
1966 * Delete any pending class ref fixups for class refs in the given image,
1967 * because the image is about to be unloaded.
1968 **********************************************************************/
1969 static void _objc_remove_pending_class_refs_in_image(header_info *hi)
1971 struct objc_class **cls_refs, **cls_refs_end;
1974 if (!pendingClassRefsMap) return;
1976 // Locate class refs in this image
1977 cls_refs = _getObjcClassRefs ((headerType *) hi->mhdr, &size);
1980 cls_refs = (struct objc_class **) ((uintptr_t)cls_refs + hi->image_slide);
1981 cls_refs_end = (struct objc_class **)(size + (uintptr_t)cls_refs);
1983 // Search the pending class ref table for class refs in this range.
1984 // The class refs may have already been stomped with nonexistentClass,
1985 // so there's no way to recover the original class name.
1988 PendingClassRef *pending;
1989 NXMapState state = NXInitMapState(pendingClassRefsMap);
1990 while(NXNextMapState(pendingClassRefsMap, &state,
1991 (const void **)&key, (const void **)&pending))
1993 for ( ; pending != NULL; pending = pending->next) {
1994 if (pending->ref >= cls_refs && pending->ref < cls_refs_end) {
1995 pending->ref = NULL;
2002 /***********************************************************************
2003 * map_selrefs. Register each selector in the specified array. If a
2004 * given selector is already registered, update this array to point to
2005 * the registered selector string.
2006 * If copy is TRUE, all selector data is always copied. This is used
2007 * for registering selectors from unloadable bundles, so the selector
2008 * can still be used after the bundle's data segment is unmapped.
2009 * Returns YES if dst was written to, NO if it was unchanged.
2010 **********************************************************************/
2011 static inline BOOL map_selrefs(SEL *src, SEL *dst, size_t size, BOOL copy)
2014 unsigned int cnt = size / sizeof(SEL);
2019 // Process each selector
2020 for (index = 0; index < cnt; index += 1)
2024 // Lookup pointer to uniqued string
2025 sel = sel_registerNameNoLock((const char *) src[index], copy);
2027 // Replace this selector with uniqued one (avoid
2028 // modifying the VM page if this would be a NOP)
2029 if (dst[index] != sel) {
2041 /***********************************************************************
2042 * map_method_descs. For each method in the specified method list,
2043 * replace the name pointer with a uniqued selector.
2044 * If copy is TRUE, all selector data is always copied. This is used
2045 * for registering selectors from unloadable bundles, so the selector
2046 * can still be used after the bundle's data segment is unmapped.
2047 **********************************************************************/
2048 static void map_method_descs (struct objc_method_description_list * methods, BOOL copy)
2054 // Process each method
2055 for (index = 0; index < methods->count; index += 1)
2057 struct objc_method_description * method;
2060 // Get method entry to fix up
2061 method = &methods->list[index];
2063 // Lookup pointer to uniqued string
2064 sel = sel_registerNameNoLock((const char *) method->name, copy);
2066 // Replace this selector with uniqued one (avoid
2067 // modifying the VM page if this would be a NOP)
2068 if (method->name != sel)
2075 /***********************************************************************
2077 **********************************************************************/
2078 @interface Protocol(RuntimePrivate)
2079 + _fixup: (OBJC_PROTOCOL_PTR)protos numElements: (int) nentries;
2082 /***********************************************************************
2083 * _objc_fixup_protocol_objects_for_image. For each protocol in the
2084 * specified image, selectorize the method names and call +_fixup.
2085 **********************************************************************/
2086 static void _objc_fixup_protocol_objects_for_image (header_info * hi)
2089 OBJC_PROTOCOL_PTR protos;
2091 int isBundle = hi->mhdr->filetype == MH_BUNDLE;
2093 // Locate protocols in the image
2094 protos = (OBJC_PROTOCOL_PTR) _getObjcProtocols ((headerType *) hi->mhdr, &size);
2098 // Apply the slide bias
2099 protos = (OBJC_PROTOCOL_PTR) ((unsigned long) protos + hi->image_slide);
2101 // Process each protocol
2102 for (index = 0; index < size; index += 1)
2104 // Selectorize the instance methods
2105 if (protos[index] OBJC_PROTOCOL_DEREF instance_methods)
2106 map_method_descs (protos[index] OBJC_PROTOCOL_DEREF instance_methods, isBundle);
2108 // Selectorize the class methods
2109 if (protos[index] OBJC_PROTOCOL_DEREF class_methods)
2110 map_method_descs (protos[index] OBJC_PROTOCOL_DEREF class_methods, isBundle);
2113 // Invoke Protocol class method to fix up the protocol
2114 [Protocol _fixup:(OBJC_PROTOCOL_PTR)protos numElements:size];
2117 /***********************************************************************
2118 * _objc_headerStart. Return what headers we know about.
2119 **********************************************************************/
2120 header_info * _objc_headerStart ()
2123 // Take advatage of our previous work
2127 void _objc_bindModuleContainingList() {
2128 /* We define this for backwards binary compat with things which should not
2129 * have been using it (cough OmniWeb), but now it does nothing for them.
2134 /***********************************************************************
2136 **********************************************************************/
2138 // tested with 2; typical case is 4, but OmniWeb & Mail push it towards 20
2139 #define HINFO_SIZE 16
2141 static int HeaderInfoCounter NOBSS = 0;
2142 static header_info HeaderInfoTable[HINFO_SIZE] NOBSS = { {0} };
2144 static header_info * _objc_addHeader(const struct mach_header *header)
2147 uintptr_t mod_unslid;
2148 uint32_t info_size = 0;
2149 uintptr_t image_info_unslid;
2150 const struct segment_command *objc_segment;
2152 header_info *result;
2154 // Locate the __OBJC segment
2155 objc_segment = getsegbynamefromheader(header, SEG_OBJC);
2156 if (!objc_segment) return NULL;
2158 // Locate some sections in the __OBJC segment
2159 mod_unslid = (uintptr_t)_getObjcModules(header, &mod_count);
2160 if (!mod_unslid) return NULL;
2161 image_info_unslid = (uintptr_t)_getObjcImageInfo(header, &info_size);
2163 // Calculate vm slide.
2164 slide = _getImageSlide(header);
2167 // Find or allocate a header_info entry.
2168 if (HeaderInfoCounter < HINFO_SIZE) {
2169 result = &HeaderInfoTable[HeaderInfoCounter++];
2171 result = _malloc_internal(sizeof(header_info));
2174 // Set up the new header_info entry.
2175 result->mhdr = header;
2176 result->mod_ptr = (Module)(mod_unslid + slide);
2177 result->mod_count = mod_count;
2178 result->image_slide = slide;
2179 result->objcSegmentHeader = objc_segment;
2180 if (image_info_unslid) {
2181 result->info = (objc_image_info *)(image_info_unslid + slide);
2183 result->info = NULL;
2186 // Make sure every copy of objc_image_info in this image is the same.
2187 // This means same version and same bitwise contents.
2189 objc_image_info *start = result->info;
2190 objc_image_info *end =
2191 (objc_image_info *)(info_size + (uint8_t *)start);
2192 objc_image_info *info = start;
2193 while (info < end) {
2194 // version is byte size, except for version 0
2195 size_t struct_size = info->version;
2196 if (struct_size == 0) struct_size = 2 * sizeof(uint32_t);
2197 if (info->version != start->version ||
2198 0 != memcmp(info, start, struct_size))
2200 _objc_fatal("'%s' has inconsistently-compiled Objective-C "
2201 "code. Please recompile all code in it.",
2202 _nameForHeader(header));
2204 info = (objc_image_info *)(struct_size + (uint8_t *)info);
2208 // Add the header to the header list.
2209 // The header is appended to the list, to preserve the bottom-up order.
2210 result->next = NULL;
2213 FirstHeader = LastHeader = result;
2216 // list is not empty, but LastHeader is invalid - recompute it
2217 LastHeader = FirstHeader;
2218 while (LastHeader->next) LastHeader = LastHeader->next;
2220 // LastHeader is now valid
2221 LastHeader->next = result;
2222 LastHeader = result;
2229 /***********************************************************************
2230 * _objc_RemoveHeader
2231 * Remove the given header from the header list.
2232 * FirstHeader is updated.
2233 * LastHeader is set to NULL. Any code that uses LastHeader must
2234 * detect this NULL and recompute LastHeader by traversing the list.
2235 **********************************************************************/
2236 static void _objc_removeHeader(header_info *hi)
2240 for (hiP = &FirstHeader; *hiP != NULL; hiP = &(**hiP).next) {
2242 header_info *deadHead = *hiP;
2244 // Remove from the linked list (updating FirstHeader if necessary).
2245 *hiP = (**hiP).next;
2247 // Update LastHeader if necessary.
2248 if (LastHeader == deadHead) {
2249 LastHeader = NULL; // will be recomputed next time it's used
2252 // Free the memory, unless it was in the static HeaderInfoTable.
2253 if (deadHead < HeaderInfoTable ||
2254 deadHead >= HeaderInfoTable + HINFO_SIZE)
2256 _free_internal(deadHead);
2265 /***********************************************************************
2267 * Check whether the executable supports or requires GC, and make sure
2268 * all already-loaded libraries support the executable's GC mode.
2269 * Returns TRUE if the executable wants GC on.
2270 **********************************************************************/
2271 static BOOL check_wants_gc(void)
2273 // GC is off in Tiger.
2276 const header_info *hi;
2279 // Environment variables can override the following.
2281 _objc_inform("GC: forcing GC ON because OBJC_FORCE_GC is set");
2284 else if (ForceNoGC) {
2285 _objc_inform("GC: forcing GC OFF because OBJC_FORCE_NO_GC is set");
2289 // Find the executable and check its GC bits.
2290 // If the executable cannot be found, default to NO.
2291 // (The executable will not be found if the executable contains
2292 // no Objective-C code.)
2294 for (hi = FirstHeader; hi != NULL; hi = hi->next) {
2295 if (hi->mhdr->filetype == MH_EXECUTE) {
2296 appWantsGC = _objcHeaderSupportsGC(hi) ? YES : NO;
2298 _objc_inform("GC: executable '%s' %s GC",
2299 _nameForHeader(hi->mhdr),
2300 appWantsGC ? "supports" : "does not support");
2309 /***********************************************************************
2310 * verify_gc_readiness
2311 * if we want gc, verify that every header describes files compiled
2312 * and presumably ready for gc.
2313 ************************************************************************/
2315 static void verify_gc_readiness(BOOL wantsGC, header_info *hi)
2319 // Find the libraries and check their GC bits against the app's request
2320 for (; hi != NULL; hi = hi->next) {
2321 if (hi->mhdr->filetype == MH_EXECUTE) {
2324 else if (hi->mhdr == &_mh_dylib_header) {
2325 // libobjc itself works with anything even though it is not
2326 // compiled with -fobjc-gc (fixme should it be?)
2328 else if (wantsGC && ! _objcHeaderSupportsGC(hi)) {
2329 // App wants GC but library does not support it - bad
2330 _objc_inform("'%s' was not compiled with -fobjc-gc, but "
2331 "the application requires GC",
2332 _nameForHeader(hi->mhdr));
2337 _objc_inform("GC: library '%s' %s GC", _nameForHeader(hi->mhdr),
2338 _objcHeaderSupportsGC(hi) ? "supports" : "does not support");
2343 // GC state is not consistent.
2344 // Kill the process unless one of the forcing flags is set.
2345 if (!ForceGC && !ForceNoGC) {
2346 _objc_fatal("*** GC capability of application and some libraries did not match");
2352 /***********************************************************************
2353 * _objc_fixup_selector_refs. Register all of the selectors in each
2354 * image, and fix them all up.
2355 **********************************************************************/
2356 static void _objc_fixup_selector_refs (const header_info * hi)
2360 vm_address_t local_sels;
2361 vm_size_t local_size;
2365 // Fix up message refs
2366 local_sels = (vm_address_t) _getObjcMessageRefs ((headerType *) hi->mhdr, &count);
2367 local_size = count * sizeof(SEL);
2370 vm_address_t aligned_start, aligned_end;
2372 local_sels = local_sels + hi->image_slide;
2373 aligned_start = round_page(local_sels);
2374 aligned_end = trunc_page(local_sels + local_size);
2376 map_selrefs((SEL *)local_sels, (SEL *)local_sels, local_size,
2377 hi->mhdr->filetype == MH_BUNDLE);
2382 /***********************************************************************
2383 * objc_setConfiguration
2384 * Read environment variables that affect the runtime.
2385 * Also print environment variable help, if requested.
2386 **********************************************************************/
2387 static void objc_setConfiguration() {
2388 int PrintHelp = (getenv("OBJC_HELP") != NULL);
2389 int PrintOptions = (getenv("OBJC_PRINT_OPTIONS") != NULL);
2392 _objc_inform("OBJC_HELP: describe Objective-C runtime environment variables");
2394 _objc_inform("OBJC_HELP is set");
2396 _objc_inform("OBJC_PRINT_OPTIONS: list which options are set");
2399 _objc_inform("OBJC_PRINT_OPTIONS is set");
2402 #define OPTION(var, env, help) \
2403 if ( var == -1 ) { \
2404 var = getenv(#env) != NULL; \
2405 if (PrintHelp) _objc_inform(#env ": " help); \
2406 if (PrintOptions && var) _objc_inform(#env " is set"); \
2409 OPTION(PrintImages, OBJC_PRINT_IMAGES,
2410 "log image and library names as the runtime loads them");
2411 OPTION(PrintConnecting, OBJC_PRINT_CONNECTION,
2412 "log progress of class and category connections");
2413 OPTION(PrintLoading, OBJC_PRINT_LOAD_METHODS,
2414 "log class and category +load methods as they are called");
2415 OPTION(PrintRTP, OBJC_PRINT_RTP,
2416 "log initialization of the Objective-C runtime pages");
2417 OPTION(PrintGC, OBJC_PRINT_GC,
2418 "log some GC operations");
2419 OPTION(PrintSharing, OBJC_PRINT_SHARING,
2420 "log cross-process memory sharing");
2421 OPTION(PrintCxxCtors, OBJC_PRINT_CXX_CTORS,
2422 "log calls to C++ ctors and dtors for instance variables");
2424 OPTION(DebugUnload, OBJC_DEBUG_UNLOAD,
2425 "warn about poorly-behaving bundles when unloaded");
2426 OPTION(DebugFragileSuperclasses, OBJC_DEBUG_FRAGILE_SUPERCLASSES,
2427 "warn about subclasses that may have been broken by subsequent changes to superclasses");
2429 OPTION(UseInternalZone, OBJC_USE_INTERNAL_ZONE,
2430 "allocate runtime data in a dedicated malloc zone");
2431 OPTION(AllowInterposing, OBJC_ALLOW_INTERPOSING,
2432 "allow function interposing of objc_msgSend()");
2434 OPTION(ForceGC, OBJC_FORCE_GC,
2435 "force GC ON, even if the executable wants it off");
2436 OPTION(ForceNoGC, OBJC_FORCE_NO_GC,
2437 "force GC OFF, even if the executable wants it on");
2438 OPTION(CheckFinalizers, OBJC_CHECK_FINALIZERS,
2439 "warn about classes that implement -dealloc but not -finalize");
2444 /***********************************************************************
2445 * objc_setMultithreaded.
2446 **********************************************************************/
2447 void objc_setMultithreaded (BOOL flag)
2449 // Nothing here. Thread synchronization in the runtime is always active.
2454 /***********************************************************************
2455 * _objc_pthread_destroyspecific
2456 * Destructor for objc's per-thread data.
2457 * arg shouldn't be NULL, but we check anyway.
2458 **********************************************************************/
2459 extern void _destroyInitializingClassList(struct _objc_initializing_classes *list);
2460 void _objc_pthread_destroyspecific(void *arg)
2462 _objc_pthread_data *data = (_objc_pthread_data *)arg;
2464 _destroyInitializingClassList(data->initializingClasses);
2466 // add further cleanup here...
2468 _free_internal(data);
2473 /***********************************************************************
2475 * Former library initializer. This function is now merely a placeholder
2476 * for external callers. All runtime initialization has now been moved
2478 **********************************************************************/
2479 void _objcInit(void)
2485 /***********************************************************************
2487 * Process the given images which are being mapped in by dyld.
2488 * All class registration and fixups are performed (or deferred pending
2489 * discovery of missing superclasses etc), and +load methods are called.
2491 * info[] is in bottom-up order i.e. libobjc will be earlier in the
2492 * array than any library that links to libobjc.
2493 **********************************************************************/
2494 static void map_images(const struct dyld_image_info infoList[],
2497 static BOOL firstTime = YES;
2498 static BOOL wantsGC NOBSS = NO;
2500 header_info *firstNewHeader = NULL;
2503 // Perform first-time initialization if necessary.
2504 // This function is called before ordinary library initializers.
2506 pthread_key_create(&_objc_pthread_key, _objc_pthread_destroyspecific);
2507 objc_setConfiguration(); // read environment variables
2508 _objc_init_class_hash (); // create class_hash
2509 // grab selectors for which @selector() doesn't work
2510 cxx_construct_sel = sel_registerName(cxx_construct_name);
2511 cxx_destruct_sel = sel_registerName(cxx_destruct_name);
2515 _objc_inform("IMAGES: processing %u newly-mapped images...\n", infoCount);
2519 // Find all images with an __OBJC segment.
2520 // firstNewHeader is set the the first one, and the header_info
2521 // linked list following firstNewHeader is the rest.
2522 for (i = 0; i < infoCount; i++) {
2523 const struct mach_header *mhdr = infoList[i].imageLoadAddress;
2525 hInfo = _objc_addHeader(mhdr);
2527 // no objc data in this entry
2529 _objc_inform("IMAGES: image '%s' contains no __OBJC segment\n",
2530 infoList[i].imageFilePath);
2535 if (!firstNewHeader) firstNewHeader = hInfo;
2538 _objc_inform("IMAGES: loading image for %s%s%s%s\n",
2539 _nameForHeader(mhdr),
2540 mhdr->filetype == MH_BUNDLE ? " (bundle)" : "",
2541 _objcHeaderIsReplacement(hInfo) ? " (replacement)":"",
2542 _objcHeaderSupportsGC(hInfo) ? " (supports GC)":"");
2546 // Perform one-time runtime initialization that must be deferred until
2547 // the executable itself is found. This needs to be done before
2548 // further initialization.
2549 // (The executable may not be present in this infoList if the
2550 // executable does not contain Objective-C code but Objective-C
2551 // is dynamically loaded later. In that case, check_wants_gc()
2552 // will do the right thing.)
2554 wantsGC = check_wants_gc();
2555 verify_gc_readiness(wantsGC, FirstHeader);
2556 // TIGER DEVELOPMENT ONLY
2557 // REQUIRE A SPECIAL NON-SHIPPING FILE TO ENABLE GC
2559 // make sure that the special file is there before proceeding with GC
2560 struct stat ignored;
2561 wantsGC = stat("/autozone", &ignored) != -1;
2562 if (!wantsGC && PrintGC)
2563 _objc_inform("GC: disabled, lacking /autozone file");
2566 gc_init(wantsGC); // needs executable for GC decision
2567 rtp_init(); // needs GC decision first
2569 verify_gc_readiness(wantsGC, firstNewHeader);
2573 // Initialize everything. Parts of this order are important for
2574 // correctness or performance.
2576 // Read classes from all images.
2577 for (hInfo = firstNewHeader; hInfo != NULL; hInfo = hInfo->next) {
2578 _objc_read_classes_from_image(hInfo);
2581 // Read categories from all images.
2582 for (hInfo = firstNewHeader; hInfo != NULL; hInfo = hInfo->next) {
2583 _objc_read_categories_from_image(hInfo);
2586 // Connect classes from all images.
2587 for (hInfo = firstNewHeader; hInfo != NULL; hInfo = hInfo->next) {
2588 _objc_connect_classes_from_image(hInfo);
2591 // Fix up class refs, selector refs, and protocol objects from all images.
2592 for (hInfo = firstNewHeader; hInfo != NULL; hInfo = hInfo->next) {
2593 _objc_map_class_refs_for_image(hInfo);
2594 _objc_fixup_selector_refs(hInfo);
2595 _objc_fixup_protocol_objects_for_image(hInfo);
2600 // Call pending +load methods.
2601 // Note that this may in turn cause map_images() to be called again.
2602 call_load_methods();
2606 /***********************************************************************
2608 * Process the given images which are about to be unmapped by dyld.
2609 * Currently we assume only MH_BUNDLE images are unmappable, and
2610 * print warnings about anything else.
2611 **********************************************************************/
2612 static void unmap_images(const struct dyld_image_info infoList[],
2618 _objc_inform("IMAGES: processing %u newly-unmapped images...\n", infoCount);
2621 for (i = 0; i < infoCount; i++) {
2622 const struct mach_header *mhdr = infoList[i].imageLoadAddress;
2624 if (mhdr->filetype == MH_BUNDLE) {
2625 _objc_unmap_image(mhdr);
2627 // currently only MH_BUNDLEs can be unmapped safely
2629 _objc_inform("IMAGES: unmapped image '%s' was not a Mach-O bundle; ignoring\n", infoList[i].imageFilePath);
2636 /***********************************************************************
2637 * _objc_notify_images
2638 * Callback from dyld informing objc of images to be added or removed.
2639 * This function is never called directly. Instead, a section
2640 * __OBJC,__image_notify contains a function pointer to this, and dyld
2641 * discovers it from there.
2642 **********************************************************************/
2644 void _objc_notify_images(enum dyld_image_mode mode, uint32_t infoCount,
2645 const struct dyld_image_info infoList[])
2647 if (mode == dyld_image_adding) {
2648 map_images(infoList, infoCount);
2649 } else if (mode == dyld_image_removing) {
2650 unmap_images(infoList, infoCount);
2655 /***********************************************************************
2656 * _objc_remove_classes_in_image
2657 * Remove all classes in the given image from the runtime, because
2658 * the image is about to be unloaded.
2659 * Things to clean up:
2661 * unconnected_class_hash
2662 * pending subclasses list (only if class is still unconnected)
2663 * loadable class list
2664 * class's method caches
2665 * class refs in all other images
2666 **********************************************************************/
2667 static void _objc_remove_classes_in_image(header_info *hi)
2673 OBJC_LOCK(&classLock);
2675 // Major loop - process all modules in the image
2677 for (midx = 0; midx < hi->mod_count; midx += 1)
2679 // Skip module containing no classes
2680 if (mods[midx].symtab == NULL)
2683 // Minor loop - process all the classes in given module
2684 for (index = 0; index < mods[midx].symtab->cls_def_cnt; index += 1)
2686 struct objc_class * cls;
2688 // Locate the class description pointer
2689 cls = mods[midx].symtab->defs[index];
2691 // Remove from loadable class list, if present
2692 remove_class_from_loadable_list(cls);
2694 // Remove from unconnected_class_hash and pending subclasses
2695 if (unconnected_class_hash && NXHashMember(unconnected_class_hash, cls)) {
2696 NXHashRemove(unconnected_class_hash, cls);
2697 if (pendingSubclassesMap) {
2698 // Find this class in its superclass's pending list
2699 char *supercls_name = (char *)cls->super_class;
2700 PendingSubclass *pending =
2701 NXMapGet(pendingSubclassesMap, supercls_name);
2702 for ( ; pending != NULL; pending = pending->next) {
2703 if (pending->subclass == cls) {
2704 pending->subclass = Nil;
2711 // Remove from class_hash
2712 NXHashRemove(class_hash, cls);
2714 // Free method list array (from objcTweakMethodListPointerForClass)
2715 // These blocks might be from user code; don't use free_internal
2716 if (cls->methodLists && !(cls->info & CLS_NO_METHOD_ARRAY)) {
2717 free(cls->methodLists);
2719 if (cls->isa->methodLists && !(cls->isa->info & CLS_NO_METHOD_ARRAY)) {
2720 free(cls->isa->methodLists);
2723 // Free method caches, if any
2724 if (cls->cache && cls->cache != &emptyCache) {
2725 _free_internal(cls->cache);
2727 if (cls->isa->cache && cls->isa->cache != &emptyCache) {
2728 _free_internal(cls->isa->cache);
2734 // Search all other images for class refs that point back to this range.
2735 // Un-fix and re-pend any such class refs.
2737 // Get the location of the dying image's __OBJC segment
2738 uintptr_t seg = hi->objcSegmentHeader->vmaddr + hi->image_slide;
2739 size_t seg_size = hi->objcSegmentHeader->filesize;
2741 header_info *other_hi;
2742 for (other_hi = FirstHeader; other_hi != NULL; other_hi = other_hi->next) {
2743 struct objc_class **other_refs;
2745 if (other_hi == hi) continue; // skip the image being unloaded
2747 // Locate class refs in the other image
2748 other_refs = _getObjcClassRefs((headerType *)other_hi->mhdr, &size);
2749 if (!other_refs) continue;
2750 other_refs = (struct objc_class **)((uintptr_t)other_refs + other_hi->image_slide);
2752 // Process each class ref
2753 for (index = 0; index < size; index++) {
2754 if ((uintptr_t)(other_refs[index]) >= seg &&
2755 (uintptr_t)(other_refs[index]) < seg+seg_size)
2757 pendClassReference(&other_refs[index],other_refs[index]->name);
2758 other_refs[index] = _objc_getNonexistentClass ();
2763 OBJC_UNLOCK(&classLock);
2767 /***********************************************************************
2768 * _objc_remove_categories_in_image
2769 * Remove all categories in the given image from the runtime, because
2770 * the image is about to be unloaded.
2771 * Things to clean up:
2772 * unresolved category list
2773 * loadable category list
2774 **********************************************************************/
2775 static void _objc_remove_categories_in_image(header_info *hi)
2780 // Major loop - process all modules in the header
2783 for (midx = 0; midx < hi->mod_count; midx++) {
2786 Symtab symtab = mods[midx].symtab;
2788 // Nothing to do for a module without a symbol table
2789 if (symtab == NULL) continue;
2791 // Total entries in symbol table (class entries followed
2792 // by category entries)
2793 total = symtab->cls_def_cnt + symtab->cat_def_cnt;
2795 // Minor loop - check all categories from given module
2796 for (index = symtab->cls_def_cnt; index < total; index++) {
2797 struct objc_category *cat = symtab->defs[index];
2799 // Clean up loadable category list
2800 remove_category_from_loadable_list(cat);
2802 // Clean up category_hash
2803 if (category_hash) {
2804 _objc_unresolved_category *cat_entry =
2805 NXMapGet(category_hash, cat->class_name);
2806 for ( ; cat_entry != NULL; cat_entry = cat_entry->next) {
2807 if (cat_entry->cat == cat) {
2808 cat_entry->cat = NULL;
2818 /***********************************************************************
2820 * Various paranoid debugging checks that look for poorly-behaving
2821 * unloadable bundles.
2822 * Called by _objc_unmap_image when OBJC_UNLOAD_DEBUG is set.
2823 **********************************************************************/
2824 static void unload_paranoia(header_info *hi)
2826 // Get the location of the dying image's __OBJC segment
2827 uintptr_t seg = hi->objcSegmentHeader->vmaddr + hi->image_slide;
2828 size_t seg_size = hi->objcSegmentHeader->filesize;
2830 _objc_inform("UNLOAD DEBUG: unloading image '%s' [%p..%p]",
2831 _nameForHeader(hi->mhdr), seg, seg+seg_size);
2833 OBJC_LOCK(&classLock);
2835 // Make sure the image contains no categories on surviving classes.
2840 // Major loop - process all modules in the header
2843 for (midx = 0; midx < hi->mod_count; midx++) {
2846 Symtab symtab = mods[midx].symtab;
2848 // Nothing to do for a module without a symbol table
2849 if (symtab == NULL) continue;
2851 // Total entries in symbol table (class entries followed
2852 // by category entries)
2853 total = symtab->cls_def_cnt + symtab->cat_def_cnt;
2855 // Minor loop - check all categories from given module
2856 for (index = symtab->cls_def_cnt; index < total; index++) {
2857 struct objc_category *cat = symtab->defs[index];
2858 struct objc_class query;
2860 query.name = cat->class_name;
2861 if (NXHashMember(class_hash, &query)) {
2862 _objc_inform("UNLOAD DEBUG: dying image contains category '%s(%s)' on surviving class '%s'!", cat->class_name, cat->category_name, cat->class_name);
2868 // Make sure no surviving class is in the dying image.
2869 // Make sure no surviving class has a superclass in the dying image.
2870 // fixme check method implementations too
2872 struct objc_class *cls;
2875 state = NXInitHashState(class_hash);
2876 while (NXNextHashState(class_hash, &state, (void **)&cls)) {
2877 if ((vm_address_t)cls >= seg &&
2878 (vm_address_t)cls < seg+seg_size)
2880 _objc_inform("UNLOAD DEBUG: dying image contains surviving class '%s'!", cls->name);
2883 if ((vm_address_t)cls->super_class >= seg &&
2884 (vm_address_t)cls->super_class < seg+seg_size)
2886 _objc_inform("UNLOAD DEBUG: dying image contains superclass '%s' of surviving class '%s'!", cls->super_class->name, cls->name);
2891 OBJC_UNLOCK(&classLock);
2895 /***********************************************************************
2896 * _objc_unmap_image.
2897 * Destroy any Objective-C data for the given image, which is about to
2898 * be unloaded by dyld.
2899 * Note: not thread-safe, but image loading isn't either.
2900 **********************************************************************/
2901 static void _objc_unmap_image(const headerType *mh)
2905 // Find the runtime's header_info struct for the image
2906 for (hi = FirstHeader; hi != NULL; hi = hi->next) {
2907 if (hi->mhdr == mh) break;
2909 if (hi == NULL) return; // no objc data for this image
2912 _objc_inform("IMAGES: unloading image for %s%s%s%s\n",
2914 mh->filetype == MH_BUNDLE ? " (bundle)" : "",
2915 _objcHeaderIsReplacement(hi) ? " (replacement)" : "",
2916 _objcHeaderSupportsGC(hi) ? " (supports GC)" : "");
2920 // Remove image's classes from the class list and free auxiliary data.
2921 // Remove image's unresolved or loadable categories and free auxiliary data
2922 // Remove image's unresolved class refs.
2923 _objc_remove_classes_in_image(hi);
2924 _objc_remove_categories_in_image(hi);
2925 _objc_remove_pending_class_refs_in_image(hi);
2927 // Perform various debugging checks if requested.
2928 if (DebugUnload) unload_paranoia(hi);
2930 // Remove header_info from header list
2931 _objc_removeHeader(hi);
2935 /***********************************************************************
2936 * _objc_setNilReceiver
2937 **********************************************************************/
2938 id _objc_setNilReceiver(id newNilReceiver)
2942 oldNilReceiver = _objc_nilReceiver;
2943 _objc_nilReceiver = newNilReceiver;
2945 return oldNilReceiver;
2948 /***********************************************************************
2949 * _objc_getNilReceiver
2950 **********************************************************************/
2951 id _objc_getNilReceiver(void)
2953 return _objc_nilReceiver;
2957 /***********************************************************************
2958 * _objc_setClassLoader
2959 * Similar to objc_setClassHandler, but objc_classLoader is used for
2960 * both objc_getClass() and objc_lookupClass(), and objc_classLoader
2961 * pre-empts objc_classHandler.
2962 **********************************************************************/
2963 void _objc_setClassLoader(BOOL (*newClassLoader)(const char *))
2965 _objc_classLoader = newClassLoader;
2969 #if defined(__ppc__)
2971 /**********************************************************************
2973 * Writes at entry a PPC branch instruction sequence that branches to target.
2974 * The sequence written will be 1 or 4 instructions long.
2975 * Returns the number of instructions written.
2976 **********************************************************************/
2977 __private_extern__ size_t objc_write_branch(void *entry, void *target)
2979 unsigned *address = (unsigned *)entry; // location to store the 32 bit PPC instructions
2980 intptr_t destination = (intptr_t)target; // destination as an absolute address
2981 intptr_t displacement = (intptr_t)destination - (intptr_t)address; // destination as a branch relative offset
2983 // Test to see if either the displacement or destination is within the +/- 2^25 range needed
2984 // for a simple PPC branch instruction. Shifting the high bit of the displacement (or destination)
2985 // left 6 bits and then 6 bits arithmetically to the right does a sign extend of the 26th bit. If
2986 // that result is equivalent to the original value, then the displacement (or destination) will fit
2987 // into a simple branch. Otherwise a four instruction branch sequence is required.
2988 if (((displacement << 6) >> 6) == displacement) {
2989 // use a relative branch with the displacement
2990 address[0] = 0x48000000 | (displacement & 0x03fffffc); // b *+displacement
2991 // issued 1 instruction
2993 } else if (((destination << 6) >> 6) == destination) {
2994 // use an absolute branch with the destination
2995 address[0] = 0x48000000 | (destination & 0x03fffffc) | 2; // ba destination (2 is the absolute flag)
2996 // issued 1 instruction
2999 // The four instruction branch sequence requires that the destination be loaded
3000 // into a register, moved to the CTR register then branch using the contents
3001 // of the CTR register.
3002 unsigned lo = destination & 0xffff;
3003 unsigned hi = (destination >> 16) & 0xffff;
3005 address[0] = 0x3d800000 | hi; // lis r12,hi ; load the hi half of destination
3006 address[1] = 0x618c0000 | lo; // ori r12,r12,lo ; merge in the lo half of destination
3007 address[2] = 0x7d8903a6; // mtctr ; move destination to the CTR register
3008 address[3] = 0x4e800420; // bctr ; branch to destination
3009 // issued 4 instructions
3018 /**********************************************************************
3020 * Securely open a file from a world-writable directory (like /tmp)
3021 * If the file does not exist, it will be atomically created with mode 0600
3022 * If the file exists, it must be, and remain after opening:
3023 * 1. a regular file (in particular, not a symlink)
3025 * 3. permissions 0600
3026 * 4. link count == 1
3027 * Returns a file descriptor or -1. Errno may or may not be set on error.
3028 **********************************************************************/
3029 __private_extern__ int secure_open(const char *filename, int flags, uid_t euid)
3036 if (flags & O_TRUNC) {
3037 // Don't truncate the file until after it is open and verified.
3041 if (flags & O_CREAT) {
3042 // Don't create except when we're ready for it
3048 if (lstat(filename, &ls) < 0) {
3049 if (errno == ENOENT && create) {
3050 // No such file - create it
3051 fd = open(filename, flags | O_CREAT | O_EXCL, 0600);
3053 // File was created successfully.
3054 // New file does not need to be truncated.
3057 // File creation failed.
3061 // lstat failed, or user doesn't want to create the file
3065 // lstat succeeded - verify attributes and open
3066 if (S_ISREG(ls.st_mode) && // regular file?
3067 ls.st_nlink == 1 && // link count == 1?
3068 ls.st_uid == euid && // owned by euid?
3069 (ls.st_mode & ALLPERMS) == (S_IRUSR | S_IWUSR)) // mode 0600?
3071 // Attributes look ok - open it and check attributes again
3072 fd = open(filename, flags, 0000);
3074 // File is open - double-check attributes
3075 if (0 == fstat(fd, &fs) &&
3076 fs.st_nlink == ls.st_nlink && // link count == 1?
3077 fs.st_uid == ls.st_uid && // owned by euid?
3078 fs.st_mode == ls.st_mode && // regular file, 0600?
3079 fs.st_ino == ls.st_ino && // same inode as before?
3080 fs.st_dev == ls.st_dev) // same device as before?
3082 // File is open and OK
3083 if (truncate) ftruncate(fd, 0);
3086 // Opened file looks funny - close it
3095 // Unopened file looks funny - don't open it