1 /*********************************************************************** 2 * static_init 3 * Run C++ static constructor functions. 4 * libc calls _objc_init() before dyld would call our static constructors, 5 * so we have to do it ourselves. 6 **********************************************************************/ 7 static void static_init() 8 { 9 size_t count; 10 auto inits = getLibobjcInitializers(&_mh_dylib_header, &count); 11 for (size_t i = 0; i < count; i++) { 12 inits[i](); 13 } 14 }
1/// Initialize the trampoline machinery. Normally this does nothing, as 2/// everything is initialized lazily, but for certain processes we eagerly load 3 /// the trampolines dylib. 4void 5 _imp_implementationWithBlock_init(void) 6 { 7#if TARGET_OS_OSX 8// Eagerly load libobjc-trampolines.dylib in certain processes. Some 9// programs (most notably QtWebEngineProcess used by older versions of 10// embedded Chromium) enable a highly restrictive sandbox profile which 11// blocks access to that dylib. If anything calls 12// imp_implementationWithBlock (as AppKit has started doing) then we'll 13// crash trying to load it. Loading it here sets it up before the sandbox 14// profile is enabled and blocks it. 15// 16// This fixes EA Origin (rdar://problem/50813789) 17// and Steam (rdar://problem/55286131) 18if (__progname && 19 (strcmp(__progname, "QtWebEngineProcess") == 0 || 20strcmp(__progname, "Steam Helper") == 0)) { 21 Trampolines.Initialize(); 22 } 23#endif 24 }
1/*********************************************************************** 2 * readClass 3 * Read a class and metaclass as written by a compiler. 4 * Returns the new class pointer. This could be: 5 * - cls 6 * - nil (cls has a missing weak-linked superclass) 7 * - something else (space for this class was reserved by a future class) 8 * 9 * Note that all work performed by this function is preflighted by 10 * mustReadClasses(). Do not change this function without updating that one. 11 * 12 * Locking: runtimeLock acquired by map_images or objc_readClassPair 13 **********************************************************************/ 14 Class readClass(Class cls, bool headerIsBundle, bool headerIsPreoptimized) 15 { 16const char *mangledName = cls->mangledName(); 18if (missingWeakSuperclass(cls)) { 19// No superclass (probably weak-linked). 20// Disavow any knowledge of this subclass. 21if (PrintConnecting) { 22 _objc_inform("CLASS: IGNORING class '%s' with " 23"missing weak-linked superclass", 24cls->nameForLogging()); 25 } 26 addRemappedClass(cls, nil); 27cls->superclass = nil; 28 return nil; 29 } 31cls->fixupBackwardDeployingStableSwift(); 33 Class replacing = nil; 34if (Class newCls = popFutureNamedClass(mangledName)) { 35// This name was previously allocated as a future class. 36// Copy objc_class to future class's struct. 37// Preserve future's rw data block. 39if (newCls->isAnySwift()) { 40 _objc_fatal("Can't complete future class request for '%s' " 41"because the real class is too big.", 42cls->nameForLogging()); 43 } 45class_rw_t *rw = newCls->data(); 46const class_ro_t *old_ro = rw->ro(); 47 memcpy(newCls, cls, sizeof(objc_class)); 48rw->set_ro((class_ro_t *)newCls->data()); 49newCls->setData(rw); 50freeIfMutable((char *)old_ro->name); 51 free((void *)old_ro); 53 addRemappedClass(cls, newCls); 55 replacing = cls; 56 cls = newCls; 57 } 59if (headerIsPreoptimized && !replacing) { 60// class list built in shared cache 61// fixme strict assert doesn't work because of duplicates 62// ASSERT(cls == getClass(name)); 63 ASSERT(getClassExceptSomeSwift(mangledName)); 64 } else { 65 addNamedClass(cls, mangledName, replacing); 66 addClassTableEntry(cls); 67 } 69// for future reference: shared cache never contains MH_BUNDLEs 70if (headerIsBundle) { 71cls->data()->flags |= RO_FROM_BUNDLE; 72cls->ISA()->data()->flags |= RO_FROM_BUNDLE; 73 } 75 return cls; 76 }
1/*********************************************************************** 2 * addNamedClass 3 * Adds name => cls to the named non-meta class map.// 将 name=>cls 添加到费元类的映射 4 * Warns about duplicate class names and keeps the old mapping.// 重复的类名将保留旧的映射 5 * Locking: runtimeLock must be held by the caller 6 **********************************************************************/ 7 static void addNamedClass(Class cls, constchar*name, Class replacing = nil) 8 { 9 runtimeLock.assertLocked(); 10 Class old; 11if ((old = getClassExceptSomeSwift(name)) && old != replacing) { 12 inform_duplicate(name, old, cls); 14// getMaybeUnrealizedNonMetaClass uses name lookups. 15// Classes not found by name lookup must be in the 16// secondary meta->nonmeta table. 17 addNonMetaClass(cls); 18 } else { 19NXMapInsert(gdb_objc_realized_classes, name, cls);// 插入 20 } 21ASSERT(!(cls->data()->flags & RO_META)); 23// wrong: constructed classes are already realized when they get here 24// ASSERT(!cls->isRealized()); 25 }
类名来自于 mangleName:–> 已经初始化 or 未来类则从 ro 里面读,否则从 macho 的 data 里面读:
2.2)addClassTableEntry(cls)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
1 /*********************************************************************** 2 * addClassTableEntry 3 * Add a class to the table of all classes. If addMeta is true, 4 * automatically adds the metaclass of the class as well. 5 * Locking: runtimeLock must be held by the caller. 6 **********************************************************************/ 7 static void 8 addClassTableEntry(Class cls, bool addMeta = true) 9 { 10 runtimeLock.assertLocked(); 12 // This class is allowed to be a known class via the shared cache or via 13 // data segments, but it is not allowed to be in the dynamic table already. 14 auto &set = objc::allocatedClasses.get();// 初始化位置在 runtime_init() 16 ASSERT(set.find(cls) == set.end()); 18 if (!isKnownClass(cls)) 19 set.insert(cls);// 添加 insert 20 if (addMeta) 21 addClassTableEntry(cls->ISA(), false);// 元类就添加到元类 22 }