1c1dac77fSApple OSS Distributions /* 288cc0b97SApple OSS Distributions * Copyright (c) 2000-2016 Apple Inc. All rights reserved. 3c1dac77fSApple OSS Distributions * 4e13b1fa5SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5c1dac77fSApple OSS Distributions * 6e13b1fa5SApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code 7e13b1fa5SApple OSS Distributions * as defined in and that are subject to the Apple Public Source License 8e13b1fa5SApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in 9e13b1fa5SApple OSS Distributions * compliance with the License. The rights granted to you under the License 10e13b1fa5SApple OSS Distributions * may not be used to create, or enable the creation or redistribution of, 11e13b1fa5SApple OSS Distributions * unlawful or unlicensed copies of an Apple operating system, or to 12e13b1fa5SApple OSS Distributions * circumvent, violate, or enable the circumvention or violation of, any 13e13b1fa5SApple OSS Distributions * terms of an Apple operating system software license agreement. 14c1dac77fSApple OSS Distributions * 15e13b1fa5SApple OSS Distributions * Please obtain a copy of the License at 16e13b1fa5SApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this file. 17e13b1fa5SApple OSS Distributions * 18e13b1fa5SApple OSS Distributions * The Original Code and all software distributed under the License are 19e13b1fa5SApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20c1dac77fSApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21c1dac77fSApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22e13b1fa5SApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23e13b1fa5SApple OSS Distributions * Please see the License for the specific language governing rights and 24e13b1fa5SApple OSS Distributions * limitations under the License. 25c1dac77fSApple OSS Distributions * 26e13b1fa5SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27c1dac77fSApple OSS Distributions */ 28c1dac77fSApple OSS Distributions /* OSMetaClass.cpp created by gvdl on Fri 1998-11-17 */ 29c1dac77fSApple OSS Distributions 30c1dac77fSApple OSS Distributions #include <string.h> 31c1dac77fSApple OSS Distributions 32c1dac77fSApple OSS Distributions #include <libkern/OSReturn.h> 33c1dac77fSApple OSS Distributions 34c1dac77fSApple OSS Distributions #include <libkern/c++/OSMetaClass.h> 35c1dac77fSApple OSS Distributions #include <libkern/c++/OSObject.h> 363ca3bd55SApple OSS Distributions #include <libkern/c++/OSKext.h> 373ca3bd55SApple OSS Distributions 38c1dac77fSApple OSS Distributions #include <libkern/c++/OSCollectionIterator.h> 39c1dac77fSApple OSS Distributions #include <libkern/c++/OSDictionary.h> 40c1dac77fSApple OSS Distributions #include <libkern/c++/OSArray.h> 41c1dac77fSApple OSS Distributions #include <libkern/c++/OSSet.h> 42c1dac77fSApple OSS Distributions #include <libkern/c++/OSSymbol.h> 43c1dac77fSApple OSS Distributions #include <libkern/c++/OSNumber.h> 44c1dac77fSApple OSS Distributions #include <libkern/c++/OSSerialize.h> 453ca3bd55SApple OSS Distributions 46c1dac77fSApple OSS Distributions #include <libkern/c++/OSLib.h> 47c1dac77fSApple OSS Distributions #include <libkern/OSAtomic.h> 48c1dac77fSApple OSS Distributions 493ca3bd55SApple OSS Distributions #include <IOKit/IOLib.h> 50e13b1fa5SApple OSS Distributions 510f3703acSApple OSS Distributions #include <IOKit/IOKitDebug.h> 520f3703acSApple OSS Distributions 530f3703acSApple OSS Distributions 54c1dac77fSApple OSS Distributions __BEGIN_DECLS 55c1dac77fSApple OSS Distributions 5614e3d835SApple OSS Distributions #include <sys/systm.h> 57c1dac77fSApple OSS Distributions #include <mach/mach_types.h> 583ca3bd55SApple OSS Distributions #include <kern/locks.h> 59c1dac77fSApple OSS Distributions #include <kern/clock.h> 60c1dac77fSApple OSS Distributions #include <kern/thread_call.h> 61fad439e7SApple OSS Distributions #include <kern/host.h> 62c1dac77fSApple OSS Distributions #include <mach/mach_interface.h> 63a5e72196SApple OSS Distributions #include <stddef.h> 64c1dac77fSApple OSS Distributions 653ca3bd55SApple OSS Distributions #if PRAGMA_MARK 663ca3bd55SApple OSS Distributions #pragma mark Macros 673ca3bd55SApple OSS Distributions #endif /* PRAGMA_MARK */ 683ca3bd55SApple OSS Distributions /********************************************************************* 693ca3bd55SApple OSS Distributions * Macros 703ca3bd55SApple OSS Distributions *********************************************************************/ 71c1dac77fSApple OSS Distributions __END_DECLS 72c1dac77fSApple OSS Distributions 733ca3bd55SApple OSS Distributions #if PRAGMA_MARK 743ca3bd55SApple OSS Distributions #pragma mark Internal constants & data structs 753ca3bd55SApple OSS Distributions #endif /* PRAGMA_MARK */ 763ca3bd55SApple OSS Distributions /********************************************************************* 773ca3bd55SApple OSS Distributions * Internal constants & data structs 783ca3bd55SApple OSS Distributions *********************************************************************/ 793ca3bd55SApple OSS Distributions OSKextLogSpec kOSMetaClassLogSpec = 803ca3bd55SApple OSS Distributions kOSKextLogErrorLevel | 813ca3bd55SApple OSS Distributions kOSKextLogLoadFlag | 823ca3bd55SApple OSS Distributions kOSKextLogKextBookkeepingFlag; 833ca3bd55SApple OSS Distributions 84c1dac77fSApple OSS Distributions static enum { 85c1dac77fSApple OSS Distributions kCompletedBootstrap = 0, 86c1dac77fSApple OSS Distributions kNoDictionaries = 1, 87c1dac77fSApple OSS Distributions kMakingDictionaries = 2 88c1dac77fSApple OSS Distributions } sBootstrapState = kNoDictionaries; 89c1dac77fSApple OSS Distributions 90c1dac77fSApple OSS Distributions static const int kClassCapacityIncrement = 40; 91c1dac77fSApple OSS Distributions static const int kKModCapacityIncrement = 10; 923ca3bd55SApple OSS Distributions static OSDictionary * sAllClassesDict; 93d0c1fef6SApple OSS Distributions static unsigned int sDeepestClass; 943ca3bd55SApple OSS Distributions IOLock * sAllClassesLock = NULL; 95d0c1fef6SApple OSS Distributions IOLock * sInstancesLock = NULL; 96c1dac77fSApple OSS Distributions 973ca3bd55SApple OSS Distributions /* 983ca3bd55SApple OSS Distributions * While loading a kext and running all its constructors to register 993ca3bd55SApple OSS Distributions * all OSMetaClass classes, the classes are queued up here. Only one 1003ca3bd55SApple OSS Distributions * kext can be in flight at a time, guarded by sStalledClassesLock 1013ca3bd55SApple OSS Distributions */ 102c1dac77fSApple OSS Distributions static struct StalledData { 1033ca3bd55SApple OSS Distributions const char * kextIdentifier; 104c1dac77fSApple OSS Distributions OSReturn result; 105c1dac77fSApple OSS Distributions unsigned int capacity; 106c1dac77fSApple OSS Distributions unsigned int count; 107c1dac77fSApple OSS Distributions OSMetaClass ** classes; 108c1dac77fSApple OSS Distributions } * sStalled; 1093ca3bd55SApple OSS Distributions IOLock * sStalledClassesLock = NULL; 110c1dac77fSApple OSS Distributions 111d0c1fef6SApple OSS Distributions struct ExpansionData { 112d0c1fef6SApple OSS Distributions OSOrderedSet * instances; 113d0c1fef6SApple OSS Distributions OSKext * kext; 11476e12aa3SApple OSS Distributions uint32_t retain; 1150f3703acSApple OSS Distributions #if IOTRACKING 1160f3703acSApple OSS Distributions IOTrackingQueue * tracking; 1170f3703acSApple OSS Distributions #endif 118d0c1fef6SApple OSS Distributions }; 119d0c1fef6SApple OSS Distributions 120d0c1fef6SApple OSS Distributions 1213ca3bd55SApple OSS Distributions #if PRAGMA_MARK 1223ca3bd55SApple OSS Distributions #pragma mark OSMetaClassBase 1233ca3bd55SApple OSS Distributions #endif /* PRAGMA_MARK */ 1243ca3bd55SApple OSS Distributions /********************************************************************* 1253ca3bd55SApple OSS Distributions * OSMetaClassBase. 1263ca3bd55SApple OSS Distributions *********************************************************************/ 127c1dac77fSApple OSS Distributions 128d0c1fef6SApple OSS Distributions #if APPLE_KEXT_VTABLE_PADDING 1293ca3bd55SApple OSS Distributions /********************************************************************* 1303ca3bd55SApple OSS Distributions * Reserved vtable functions. 1313ca3bd55SApple OSS Distributions *********************************************************************/ 132*bb611c8fSApple OSS Distributions #if defined(__arm64__) || defined(__arm__) 133a5e72196SApple OSS Distributions void 134a5e72196SApple OSS Distributions OSMetaClassBase::_RESERVEDOSMetaClassBase0() 135a5e72196SApple OSS Distributions { 136a5e72196SApple OSS Distributions panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 0); 137a5e72196SApple OSS Distributions } 138a5e72196SApple OSS Distributions void 139a5e72196SApple OSS Distributions OSMetaClassBase::_RESERVEDOSMetaClassBase1() 140a5e72196SApple OSS Distributions { 141a5e72196SApple OSS Distributions panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 1); 142a5e72196SApple OSS Distributions } 143a5e72196SApple OSS Distributions void 144a5e72196SApple OSS Distributions OSMetaClassBase::_RESERVEDOSMetaClassBase2() 145a5e72196SApple OSS Distributions { 146a5e72196SApple OSS Distributions panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 2); 147a5e72196SApple OSS Distributions } 148a5e72196SApple OSS Distributions void 149a5e72196SApple OSS Distributions OSMetaClassBase::_RESERVEDOSMetaClassBase3() 150a5e72196SApple OSS Distributions { 151a5e72196SApple OSS Distributions panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 3); 152a5e72196SApple OSS Distributions } 153*bb611c8fSApple OSS Distributions #endif /* defined(__arm64__) || defined(__arm__) */ 154fad439e7SApple OSS Distributions 155fad439e7SApple OSS Distributions // As these slots are used move them up inside the #if above 156a5e72196SApple OSS Distributions void 157a5e72196SApple OSS Distributions OSMetaClassBase::_RESERVEDOSMetaClassBase4() 158a5e72196SApple OSS Distributions { 159a5e72196SApple OSS Distributions panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 4); 160a5e72196SApple OSS Distributions } 161a5e72196SApple OSS Distributions void 162a5e72196SApple OSS Distributions OSMetaClassBase::_RESERVEDOSMetaClassBase5() 163a5e72196SApple OSS Distributions { 164a5e72196SApple OSS Distributions panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 5); 165a5e72196SApple OSS Distributions } 166a5e72196SApple OSS Distributions void 167a5e72196SApple OSS Distributions OSMetaClassBase::_RESERVEDOSMetaClassBase6() 168a5e72196SApple OSS Distributions { 169a5e72196SApple OSS Distributions panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 6); 170a5e72196SApple OSS Distributions } 171d0c1fef6SApple OSS Distributions #endif 172fad439e7SApple OSS Distributions 173cc9a6355SApple OSS Distributions /********************************************************************* 174cc9a6355SApple OSS Distributions *********************************************************************/ 175cc9a6355SApple OSS Distributions 176cc9a6355SApple OSS Distributions #if defined(__arm__) || defined(__arm64__) 177cc9a6355SApple OSS Distributions 178a5e72196SApple OSS Distributions #if defined(HAS_APPLE_PAC) 179a5e72196SApple OSS Distributions #include <ptrauth.h> 180a5e72196SApple OSS Distributions #endif /* defined(HAS_APPLE_PAC) */ 181cc9a6355SApple OSS Distributions 182cc9a6355SApple OSS Distributions /* 183a5e72196SApple OSS Distributions * IHI0059A "C++ Application Binary Interface Standard for the ARM 64 - bit Architecture": 184a5e72196SApple OSS Distributions * 185a5e72196SApple OSS Distributions * 3.2.1 Representation of pointer to member function The generic C++ ABI [GC++ABI] 186a5e72196SApple OSS Distributions * specifies that a pointer to member function is a pair of words <ptr, adj>. The 187a5e72196SApple OSS Distributions * least significant bit of ptr discriminates between (0) the address of a non- 188a5e72196SApple OSS Distributions * virtual member function and (1) the offset in the class's virtual table of the 189a5e72196SApple OSS Distributions * address of a virtual function. This encoding cannot work for the AArch64 190a5e72196SApple OSS Distributions * instruction set where the architecture reserves all bits of code addresses. This 191a5e72196SApple OSS Distributions * ABI specifies that adj contains twice the this adjustment, plus 1 if the member 192a5e72196SApple OSS Distributions * function is virtual. The least significant bit of adj then makes exactly the 193a5e72196SApple OSS Distributions * same discrimination as the least significant bit of ptr does for Itanium. A 194a5e72196SApple OSS Distributions * pointer to member function is NULL when ptr = 0 and the least significant bit of 195a5e72196SApple OSS Distributions * adj is zero. 196cc9a6355SApple OSS Distributions */ 197cc9a6355SApple OSS Distributions 198cc9a6355SApple OSS Distributions OSMetaClassBase::_ptf_t 199*bb611c8fSApple OSS Distributions #if defined(HAS_APPLE_PAC) && \ 200*bb611c8fSApple OSS Distributions __has_feature(ptrauth_member_function_pointer_type_discrimination) 201a5e72196SApple OSS Distributions OSMetaClassBase::_ptmf2ptf(const OSMetaClassBase *self __attribute__((unused)), 202*bb611c8fSApple OSS Distributions void (OSMetaClassBase::*func)(void)) 203a5e72196SApple OSS Distributions #else 204a5e72196SApple OSS Distributions OSMetaClassBase::_ptmf2ptf(const OSMetaClassBase *self, 205*bb611c8fSApple OSS Distributions void (OSMetaClassBase::*func)(void)) 206a5e72196SApple OSS Distributions #endif 207cc9a6355SApple OSS Distributions { 208cc9a6355SApple OSS Distributions struct ptmf_t { 209cc9a6355SApple OSS Distributions _ptf_t fPFN; 210cc9a6355SApple OSS Distributions ptrdiff_t delta; 211cc9a6355SApple OSS Distributions }; 212cc9a6355SApple OSS Distributions union { 213cc9a6355SApple OSS Distributions void (OSMetaClassBase::*fIn)(void); 214cc9a6355SApple OSS Distributions struct ptmf_t pTMF; 215cc9a6355SApple OSS Distributions } map; 216cc9a6355SApple OSS Distributions _ptf_t pfn; 217cc9a6355SApple OSS Distributions 218cc9a6355SApple OSS Distributions map.fIn = func; 219cc9a6355SApple OSS Distributions pfn = map.pTMF.fPFN; 220cc9a6355SApple OSS Distributions 221*bb611c8fSApple OSS Distributions #if defined(HAS_APPLE_PAC) && \ 222*bb611c8fSApple OSS Distributions __has_feature(ptrauth_member_function_pointer_type_discrimination) 223a5e72196SApple OSS Distributions // Authenticate 'pfn' using the member function pointer type discriminator 224a5e72196SApple OSS Distributions // and resign it as a C function pointer. 'pfn' can point to either a 225a5e72196SApple OSS Distributions // non-virtual function or a virtual member function thunk. 226*bb611c8fSApple OSS Distributions // It can also be NULL. 227*bb611c8fSApple OSS Distributions if (pfn) { 228*bb611c8fSApple OSS Distributions pfn = ptrauth_auth_and_resign(pfn, ptrauth_key_function_pointer, 229*bb611c8fSApple OSS Distributions ptrauth_type_discriminator(__typeof__(func)), 230*bb611c8fSApple OSS Distributions ptrauth_key_function_pointer, 231*bb611c8fSApple OSS Distributions ptrauth_function_pointer_type_discriminator(_ptf_t)); 232*bb611c8fSApple OSS Distributions } 233a5e72196SApple OSS Distributions return pfn; 234a5e72196SApple OSS Distributions #else 235cc9a6355SApple OSS Distributions if (map.pTMF.delta & 1) { 236cc9a6355SApple OSS Distributions // virtual 237cc9a6355SApple OSS Distributions union { 238cc9a6355SApple OSS Distributions const OSMetaClassBase *fObj; 239cc9a6355SApple OSS Distributions _ptf_t **vtablep; 240cc9a6355SApple OSS Distributions } u; 241cc9a6355SApple OSS Distributions u.fObj = self; 242cc9a6355SApple OSS Distributions 243cc9a6355SApple OSS Distributions // Virtual member function so dereference table 244a5e72196SApple OSS Distributions #if defined(HAS_APPLE_PAC) 245a5e72196SApple OSS Distributions // The entity hash is stored in the top 32-bits of the vtable offset of a 246a5e72196SApple OSS Distributions // member function pointer. 247a5e72196SApple OSS Distributions uint32_t entity_hash = ((uintptr_t)pfn) >> 32; 248a5e72196SApple OSS Distributions pfn = (_ptf_t)(((uintptr_t) pfn) & 0xFFFFFFFF); 249cc9a6355SApple OSS Distributions 250*bb611c8fSApple OSS Distributions #if __has_builtin(__builtin_get_vtable_pointer) 251*bb611c8fSApple OSS Distributions const _ptf_t *vtablep = 252*bb611c8fSApple OSS Distributions (const _ptf_t *)__builtin_get_vtable_pointer(u.fObj); 253*bb611c8fSApple OSS Distributions #else 254a5e72196SApple OSS Distributions // Authenticate the vtable pointer. 255*bb611c8fSApple OSS Distributions const _ptf_t *vtablep = ptrauth_auth_data(*u.vtablep, 256a5e72196SApple OSS Distributions ptrauth_key_cxx_vtable_pointer, 0); 257*bb611c8fSApple OSS Distributions #endif 258a5e72196SApple OSS Distributions // Calculate the address of the vtable entry. 259a5e72196SApple OSS Distributions _ptf_t *vtentryp = (_ptf_t *)(((uintptr_t)vtablep) + (uintptr_t)pfn); 260a5e72196SApple OSS Distributions // Load the pointer from the vtable entry. 261a5e72196SApple OSS Distributions pfn = *vtentryp; 262a5e72196SApple OSS Distributions 263a5e72196SApple OSS Distributions // Finally, resign the vtable entry as a function pointer. 264a5e72196SApple OSS Distributions uintptr_t auth_data = ptrauth_blend_discriminator(vtentryp, entity_hash); 265a5e72196SApple OSS Distributions pfn = ptrauth_auth_and_resign(pfn, ptrauth_key_function_pointer, 266*bb611c8fSApple OSS Distributions auth_data, ptrauth_key_function_pointer, 267*bb611c8fSApple OSS Distributions ptrauth_function_pointer_type_discriminator(_ptf_t)); 268a5e72196SApple OSS Distributions #else /* defined(HAS_APPLE_PAC) */ 269a5e72196SApple OSS Distributions pfn = *(_ptf_t *)(((uintptr_t)*u.vtablep) + (uintptr_t)pfn); 270a5e72196SApple OSS Distributions #endif /* !defined(HAS_APPLE_PAC) */ 271a5e72196SApple OSS Distributions return pfn; 272cc9a6355SApple OSS Distributions } else { 273cc9a6355SApple OSS Distributions // Not virtual, i.e. plain member func 274cc9a6355SApple OSS Distributions return pfn; 275cc9a6355SApple OSS Distributions } 276a5e72196SApple OSS Distributions #endif 277cc9a6355SApple OSS Distributions } 278cc9a6355SApple OSS Distributions 279cc9a6355SApple OSS Distributions #endif /* defined(__arm__) || defined(__arm64__) */ 2803ca3bd55SApple OSS Distributions /********************************************************************* 281fad439e7SApple OSS Distributions * These used to be inline in the header but gcc didn't believe us 282fad439e7SApple OSS Distributions * Now we MUST pull the inline out at least until the compiler is 283fad439e7SApple OSS Distributions * repaired. 2843ca3bd55SApple OSS Distributions * 2853ca3bd55SApple OSS Distributions * Helper inlines for runtime type preprocessor macros 2863ca3bd55SApple OSS Distributions *********************************************************************/ 287fad439e7SApple OSS Distributions 2883ca3bd55SApple OSS Distributions /********************************************************************* 2893ca3bd55SApple OSS Distributions *********************************************************************/ 2903ca3bd55SApple OSS Distributions OSMetaClassBase * 2913ca3bd55SApple OSS Distributions OSMetaClassBase::safeMetaCast( 2923ca3bd55SApple OSS Distributions const OSMetaClassBase * me, 2933ca3bd55SApple OSS Distributions const OSMetaClass * toType) 2943ca3bd55SApple OSS Distributions { 295a5e72196SApple OSS Distributions return (me)? me->metaCast(toType) : NULL; 296a5e72196SApple OSS Distributions } 297a5e72196SApple OSS Distributions 298a5e72196SApple OSS Distributions /// A helper function to crash with a kernel panic. 299a5e72196SApple OSS Distributions __attribute__((cold, not_tail_called, noreturn)) 300a5e72196SApple OSS Distributions static inline void 301a5e72196SApple OSS Distributions panic_crash_fail_cast(const OSMetaClassBase *me, 302a5e72196SApple OSS Distributions const OSMetaClass *toType) 303a5e72196SApple OSS Distributions { 304a5e72196SApple OSS Distributions panic("Unexpected cast fail: from %p to %p", me, toType); 305a5e72196SApple OSS Distributions __builtin_unreachable(); 306a5e72196SApple OSS Distributions } 307a5e72196SApple OSS Distributions 308a5e72196SApple OSS Distributions OSMetaClassBase * 309a5e72196SApple OSS Distributions OSMetaClassBase::requiredMetaCast( 310a5e72196SApple OSS Distributions const OSMetaClassBase * me, 311a5e72196SApple OSS Distributions const OSMetaClass * toType) 312a5e72196SApple OSS Distributions { 313a5e72196SApple OSS Distributions if (!me) { 314a5e72196SApple OSS Distributions return NULL; 315a5e72196SApple OSS Distributions } 316a5e72196SApple OSS Distributions OSMetaClassBase *tmp = safeMetaCast(me, toType); 317a5e72196SApple OSS Distributions if (!tmp) { 318a5e72196SApple OSS Distributions panic_crash_fail_cast(me, toType); 319a5e72196SApple OSS Distributions } 320a5e72196SApple OSS Distributions return tmp; 3213ca3bd55SApple OSS Distributions } 3223ca3bd55SApple OSS Distributions 3233ca3bd55SApple OSS Distributions /********************************************************************* 3243ca3bd55SApple OSS Distributions *********************************************************************/ 3253ca3bd55SApple OSS Distributions bool 3263ca3bd55SApple OSS Distributions OSMetaClassBase::checkTypeInst( 3273ca3bd55SApple OSS Distributions const OSMetaClassBase * inst, 3283ca3bd55SApple OSS Distributions const OSMetaClassBase * typeinst) 329fad439e7SApple OSS Distributions { 330fad439e7SApple OSS Distributions const OSMetaClass * toType = OSTypeIDInst(typeinst); 331a5e72196SApple OSS Distributions return typeinst && inst && (NULL != inst->metaCast(toType)); 332fad439e7SApple OSS Distributions } 333fad439e7SApple OSS Distributions 3343ca3bd55SApple OSS Distributions /********************************************************************* 3353ca3bd55SApple OSS Distributions *********************************************************************/ 336a5e72196SApple OSS Distributions void 337a5e72196SApple OSS Distributions OSMetaClassBase:: 3383ca3bd55SApple OSS Distributions initialize() 3393ca3bd55SApple OSS Distributions { 3403ca3bd55SApple OSS Distributions sAllClassesLock = IOLockAlloc(); 3413ca3bd55SApple OSS Distributions sStalledClassesLock = IOLockAlloc(); 342d0c1fef6SApple OSS Distributions sInstancesLock = IOLockAlloc(); 3433ca3bd55SApple OSS Distributions } 344fad439e7SApple OSS Distributions 345d0c1fef6SApple OSS Distributions #if APPLE_KEXT_VTABLE_PADDING 3463ca3bd55SApple OSS Distributions /********************************************************************* 3473ca3bd55SApple OSS Distributions * If you need this slot you had better setup an IOCTL style interface. 3483ca3bd55SApple OSS Distributions * 'Cause the whole kernel world depends on OSMetaClassBase and YOU 3493ca3bd55SApple OSS Distributions * CANT change the VTABLE size ever. 3503ca3bd55SApple OSS Distributions *********************************************************************/ 3513ca3bd55SApple OSS Distributions void 3523ca3bd55SApple OSS Distributions OSMetaClassBase::_RESERVEDOSMetaClassBase7() 353a5e72196SApple OSS Distributions { 354a5e72196SApple OSS Distributions panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 7); 355a5e72196SApple OSS Distributions } 356d0c1fef6SApple OSS Distributions #endif 357c1dac77fSApple OSS Distributions 3583ca3bd55SApple OSS Distributions /********************************************************************* 3593ca3bd55SApple OSS Distributions *********************************************************************/ 360c1dac77fSApple OSS Distributions OSMetaClassBase::OSMetaClassBase() 361c1dac77fSApple OSS Distributions { 362c1dac77fSApple OSS Distributions } 363c1dac77fSApple OSS Distributions 3643ca3bd55SApple OSS Distributions /********************************************************************* 3653ca3bd55SApple OSS Distributions *********************************************************************/ 366c1dac77fSApple OSS Distributions OSMetaClassBase::~OSMetaClassBase() 367c1dac77fSApple OSS Distributions { 368c1dac77fSApple OSS Distributions void ** thisVTable; 369c1dac77fSApple OSS Distributions 370c1dac77fSApple OSS Distributions thisVTable = (void **) this; 371c1dac77fSApple OSS Distributions *thisVTable = (void *) -1UL; 372c1dac77fSApple OSS Distributions } 373c1dac77fSApple OSS Distributions 3743ca3bd55SApple OSS Distributions /********************************************************************* 3753ca3bd55SApple OSS Distributions *********************************************************************/ 3763ca3bd55SApple OSS Distributions bool 3773ca3bd55SApple OSS Distributions OSMetaClassBase::isEqualTo(const OSMetaClassBase * anObj) const 378c1dac77fSApple OSS Distributions { 379c1dac77fSApple OSS Distributions return this == anObj; 380c1dac77fSApple OSS Distributions } 381c1dac77fSApple OSS Distributions 3823ca3bd55SApple OSS Distributions /********************************************************************* 3833ca3bd55SApple OSS Distributions *********************************************************************/ 3843ca3bd55SApple OSS Distributions OSMetaClassBase * 3853ca3bd55SApple OSS Distributions OSMetaClassBase::metaCast(const OSMetaClass * toMeta) const 386c1dac77fSApple OSS Distributions { 387c1dac77fSApple OSS Distributions return toMeta->checkMetaCast(this); 388c1dac77fSApple OSS Distributions } 389c1dac77fSApple OSS Distributions 3903ca3bd55SApple OSS Distributions /********************************************************************* 3913ca3bd55SApple OSS Distributions *********************************************************************/ 3923ca3bd55SApple OSS Distributions OSMetaClassBase * 3933ca3bd55SApple OSS Distributions OSMetaClassBase::metaCast(const OSSymbol * toMetaSymb) const 394c1dac77fSApple OSS Distributions { 395c1dac77fSApple OSS Distributions return OSMetaClass::checkMetaCastWithName(toMetaSymb, this); 396c1dac77fSApple OSS Distributions } 397c1dac77fSApple OSS Distributions 3983ca3bd55SApple OSS Distributions /********************************************************************* 3993ca3bd55SApple OSS Distributions *********************************************************************/ 4003ca3bd55SApple OSS Distributions OSMetaClassBase * 4013ca3bd55SApple OSS Distributions OSMetaClassBase::metaCast(const OSString * toMetaStr) const 402c1dac77fSApple OSS Distributions { 403c1dac77fSApple OSS Distributions const OSSymbol * tempSymb = OSSymbol::withString(toMetaStr); 404a5e72196SApple OSS Distributions OSMetaClassBase * ret = NULL; 405c1dac77fSApple OSS Distributions if (tempSymb) { 406c1dac77fSApple OSS Distributions ret = metaCast(tempSymb); 407c1dac77fSApple OSS Distributions tempSymb->release(); 408c1dac77fSApple OSS Distributions } 409c1dac77fSApple OSS Distributions return ret; 410c1dac77fSApple OSS Distributions } 411c1dac77fSApple OSS Distributions 4123ca3bd55SApple OSS Distributions /********************************************************************* 4133ca3bd55SApple OSS Distributions *********************************************************************/ 4143ca3bd55SApple OSS Distributions OSMetaClassBase * 4153ca3bd55SApple OSS Distributions OSMetaClassBase::metaCast(const char * toMetaCStr) const 416c1dac77fSApple OSS Distributions { 417fad439e7SApple OSS Distributions const OSSymbol * tempSymb = OSSymbol::withCString(toMetaCStr); 418a5e72196SApple OSS Distributions OSMetaClassBase * ret = NULL; 419c1dac77fSApple OSS Distributions if (tempSymb) { 420c1dac77fSApple OSS Distributions ret = metaCast(tempSymb); 421c1dac77fSApple OSS Distributions tempSymb->release(); 422c1dac77fSApple OSS Distributions } 423c1dac77fSApple OSS Distributions return ret; 424c1dac77fSApple OSS Distributions } 425c1dac77fSApple OSS Distributions 4263ca3bd55SApple OSS Distributions #if PRAGMA_MARK 4273ca3bd55SApple OSS Distributions #pragma mark OSMetaClassMeta 4283ca3bd55SApple OSS Distributions #endif /* PRAGMA_MARK */ 4293ca3bd55SApple OSS Distributions /********************************************************************* 4303ca3bd55SApple OSS Distributions * OSMetaClassMeta - the bootstrap metaclass of OSMetaClass 4313ca3bd55SApple OSS Distributions *********************************************************************/ 432c1dac77fSApple OSS Distributions class OSMetaClassMeta : public OSMetaClass 433c1dac77fSApple OSS Distributions { 434c1dac77fSApple OSS Distributions public: 435c1dac77fSApple OSS Distributions OSMetaClassMeta(); 436c1dac77fSApple OSS Distributions OSObject * alloc() const; 437c1dac77fSApple OSS Distributions }; 438c1dac77fSApple OSS Distributions OSMetaClassMeta::OSMetaClassMeta() 439a5e72196SApple OSS Distributions : OSMetaClass("OSMetaClass", NULL, sizeof(OSMetaClass)) 440a5e72196SApple OSS Distributions { 441a5e72196SApple OSS Distributions } 442a5e72196SApple OSS Distributions OSObject * 443a5e72196SApple OSS Distributions OSMetaClassMeta::alloc() const 444a5e72196SApple OSS Distributions { 445a5e72196SApple OSS Distributions return NULL; 446a5e72196SApple OSS Distributions } 447c1dac77fSApple OSS Distributions 448c1dac77fSApple OSS Distributions static OSMetaClassMeta sOSMetaClassMeta; 449c1dac77fSApple OSS Distributions 450c1dac77fSApple OSS Distributions const OSMetaClass * const OSMetaClass::metaClass = &sOSMetaClassMeta; 451a5e72196SApple OSS Distributions const OSMetaClass * 452a5e72196SApple OSS Distributions OSMetaClass::getMetaClass() const 453a5e72196SApple OSS Distributions { 454a5e72196SApple OSS Distributions return &sOSMetaClassMeta; 455a5e72196SApple OSS Distributions } 456c1dac77fSApple OSS Distributions 4573ca3bd55SApple OSS Distributions #if PRAGMA_MARK 4583ca3bd55SApple OSS Distributions #pragma mark OSMetaClass 4593ca3bd55SApple OSS Distributions #endif /* PRAGMA_MARK */ 4603ca3bd55SApple OSS Distributions /********************************************************************* 4613ca3bd55SApple OSS Distributions * OSMetaClass 4623ca3bd55SApple OSS Distributions *********************************************************************/ 463c1dac77fSApple OSS Distributions 464d0c1fef6SApple OSS Distributions #if APPLE_KEXT_VTABLE_PADDING 4653ca3bd55SApple OSS Distributions /********************************************************************* 4663ca3bd55SApple OSS Distributions * Reserved functions. 4673ca3bd55SApple OSS Distributions *********************************************************************/ 468a5e72196SApple OSS Distributions void 469a5e72196SApple OSS Distributions OSMetaClass::_RESERVEDOSMetaClass0() 470a5e72196SApple OSS Distributions { 471a5e72196SApple OSS Distributions panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 0); 472a5e72196SApple OSS Distributions } 473a5e72196SApple OSS Distributions void 474a5e72196SApple OSS Distributions OSMetaClass::_RESERVEDOSMetaClass1() 475a5e72196SApple OSS Distributions { 476a5e72196SApple OSS Distributions panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 1); 477a5e72196SApple OSS Distributions } 478a5e72196SApple OSS Distributions void 479a5e72196SApple OSS Distributions OSMetaClass::_RESERVEDOSMetaClass2() 480a5e72196SApple OSS Distributions { 481a5e72196SApple OSS Distributions panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 2); 482a5e72196SApple OSS Distributions } 483a5e72196SApple OSS Distributions void 484a5e72196SApple OSS Distributions OSMetaClass::_RESERVEDOSMetaClass3() 485a5e72196SApple OSS Distributions { 486a5e72196SApple OSS Distributions panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 3); 487a5e72196SApple OSS Distributions } 488a5e72196SApple OSS Distributions void 489a5e72196SApple OSS Distributions OSMetaClass::_RESERVEDOSMetaClass4() 490a5e72196SApple OSS Distributions { 491a5e72196SApple OSS Distributions panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 4); 492a5e72196SApple OSS Distributions } 493a5e72196SApple OSS Distributions void 494a5e72196SApple OSS Distributions OSMetaClass::_RESERVEDOSMetaClass5() 495a5e72196SApple OSS Distributions { 496a5e72196SApple OSS Distributions panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 5); 497a5e72196SApple OSS Distributions } 498a5e72196SApple OSS Distributions void 499a5e72196SApple OSS Distributions OSMetaClass::_RESERVEDOSMetaClass6() 500a5e72196SApple OSS Distributions { 501a5e72196SApple OSS Distributions panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 6); 502a5e72196SApple OSS Distributions } 503a5e72196SApple OSS Distributions void 504a5e72196SApple OSS Distributions OSMetaClass::_RESERVEDOSMetaClass7() 505a5e72196SApple OSS Distributions { 506a5e72196SApple OSS Distributions panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 7); 507a5e72196SApple OSS Distributions } 508d0c1fef6SApple OSS Distributions #endif 509c1dac77fSApple OSS Distributions 5103ca3bd55SApple OSS Distributions /********************************************************************* 5113ca3bd55SApple OSS Distributions *********************************************************************/ 5123ca3bd55SApple OSS Distributions static void 5133ca3bd55SApple OSS Distributions OSMetaClassLogErrorForKext( 5143ca3bd55SApple OSS Distributions OSReturn error, 5153ca3bd55SApple OSS Distributions OSKext * aKext) 516c1dac77fSApple OSS Distributions { 5173ca3bd55SApple OSS Distributions const char * message = NULL; 518c1dac77fSApple OSS Distributions 5193ca3bd55SApple OSS Distributions switch (error) { 520c1dac77fSApple OSS Distributions case kOSReturnSuccess: 521c1dac77fSApple OSS Distributions return; 5223ca3bd55SApple OSS Distributions case kOSMetaClassNoInit: // xxx - never returned; logged at fail site 5233ca3bd55SApple OSS Distributions message = "OSMetaClass: preModLoad() wasn't called (runtime internal error)."; 5243ca3bd55SApple OSS Distributions break; 5253ca3bd55SApple OSS Distributions case kOSMetaClassNoDicts: 5263ca3bd55SApple OSS Distributions message = "OSMetaClass: Allocation failure for OSMetaClass internal dictionaries."; 5273ca3bd55SApple OSS Distributions break; 5283ca3bd55SApple OSS Distributions case kOSMetaClassNoKModSet: 5293ca3bd55SApple OSS Distributions message = "OSMetaClass: Allocation failure for internal kext recording set/set missing."; 5303ca3bd55SApple OSS Distributions break; 5313ca3bd55SApple OSS Distributions case kOSMetaClassNoInsKModSet: 5323ca3bd55SApple OSS Distributions message = "OSMetaClass: Failed to record class in kext."; 5333ca3bd55SApple OSS Distributions break; 5343ca3bd55SApple OSS Distributions case kOSMetaClassDuplicateClass: 5353ca3bd55SApple OSS Distributions message = "OSMetaClass: Duplicate class encountered."; 5363ca3bd55SApple OSS Distributions break; 5373ca3bd55SApple OSS Distributions case kOSMetaClassNoSuper: // xxx - never returned 5383ca3bd55SApple OSS Distributions message = "OSMetaClass: Can't associate a class with its superclass."; 5393ca3bd55SApple OSS Distributions break; 5403ca3bd55SApple OSS Distributions case kOSMetaClassInstNoSuper: // xxx - never returned 5413ca3bd55SApple OSS Distributions message = "OSMetaClass: Instance construction error; unknown superclass."; 5423ca3bd55SApple OSS Distributions break; 5433ca3bd55SApple OSS Distributions case kOSMetaClassNoKext: 5443ca3bd55SApple OSS Distributions message = "OSMetaClass: Kext not found for metaclass."; 5453ca3bd55SApple OSS Distributions break; 5463ca3bd55SApple OSS Distributions case kOSMetaClassInternal: 5473ca3bd55SApple OSS Distributions default: 5483ca3bd55SApple OSS Distributions message = "OSMetaClass: Runtime internal error."; 5493ca3bd55SApple OSS Distributions break; 550c1dac77fSApple OSS Distributions } 551c1dac77fSApple OSS Distributions 5523ca3bd55SApple OSS Distributions if (message) { 5533ca3bd55SApple OSS Distributions OSKextLog(aKext, kOSMetaClassLogSpec, "%s", message); 5543ca3bd55SApple OSS Distributions } 5553ca3bd55SApple OSS Distributions return; 5563ca3bd55SApple OSS Distributions } 5573ca3bd55SApple OSS Distributions 5583ca3bd55SApple OSS Distributions void 5593ca3bd55SApple OSS Distributions OSMetaClass::logError(OSReturn error) 5603ca3bd55SApple OSS Distributions { 5613ca3bd55SApple OSS Distributions OSMetaClassLogErrorForKext(error, NULL); 5623ca3bd55SApple OSS Distributions } 5633ca3bd55SApple OSS Distributions 5643ca3bd55SApple OSS Distributions /********************************************************************* 5653ca3bd55SApple OSS Distributions * The core constructor for a MetaClass (defined with this name always 5663ca3bd55SApple OSS Distributions * but within the scope of its represented class). 5673ca3bd55SApple OSS Distributions * 5683ca3bd55SApple OSS Distributions * MetaClass constructors are invoked in OSRuntimeInitializeCPP(), 5693ca3bd55SApple OSS Distributions * in between calls to OSMetaClass::preModLoad(), which sets up for 5703ca3bd55SApple OSS Distributions * registration, and OSMetaClass::postModLoad(), which actually 5713ca3bd55SApple OSS Distributions * records all the class/kext relationships of the new MetaClasses. 5723ca3bd55SApple OSS Distributions *********************************************************************/ 573a5e72196SApple OSS Distributions 5743ca3bd55SApple OSS Distributions OSMetaClass::OSMetaClass( 5753ca3bd55SApple OSS Distributions const char * inClassName, 576c1dac77fSApple OSS Distributions const OSMetaClass * inSuperClass, 577c1dac77fSApple OSS Distributions unsigned int inClassSize) 578c1dac77fSApple OSS Distributions { 579c1dac77fSApple OSS Distributions instanceCount = 0; 580c1dac77fSApple OSS Distributions classSize = inClassSize; 581c1dac77fSApple OSS Distributions superClassLink = inSuperClass; 582c1dac77fSApple OSS Distributions 583d0c1fef6SApple OSS Distributions reserved = IONew(ExpansionData, 1); 584d0c1fef6SApple OSS Distributions bzero(reserved, sizeof(ExpansionData)); 5850f3703acSApple OSS Distributions #if IOTRACKING 58688cc0b97SApple OSS Distributions uint32_t numSiteQs = 0; 58788cc0b97SApple OSS Distributions if ((this == &OSSymbol ::gMetaClass) 58888cc0b97SApple OSS Distributions || (this == &OSString ::gMetaClass) 58988cc0b97SApple OSS Distributions || (this == &OSNumber ::gMetaClass) 59088cc0b97SApple OSS Distributions || (this == &OSString ::gMetaClass) 59188cc0b97SApple OSS Distributions || (this == &OSData ::gMetaClass) 59288cc0b97SApple OSS Distributions || (this == &OSDictionary::gMetaClass) 59388cc0b97SApple OSS Distributions || (this == &OSArray ::gMetaClass) 594a5e72196SApple OSS Distributions || (this == &OSSet ::gMetaClass)) { 595a5e72196SApple OSS Distributions numSiteQs = 27; 596a5e72196SApple OSS Distributions } 59788cc0b97SApple OSS Distributions 59888cc0b97SApple OSS Distributions reserved->tracking = IOTrackingQueueAlloc(inClassName, (uintptr_t) this, 59988cc0b97SApple OSS Distributions inClassSize, 0, kIOTrackingQueueTypeAlloc, 60088cc0b97SApple OSS Distributions numSiteQs); 6010f3703acSApple OSS Distributions #endif 602d0c1fef6SApple OSS Distributions 6033ca3bd55SApple OSS Distributions /* Hack alert: We are just casting inClassName and storing it in 6043ca3bd55SApple OSS Distributions * an OSString * instance variable. This may be because you can't 6053ca3bd55SApple OSS Distributions * create C++ objects in static constructors, but I really don't know! 6063ca3bd55SApple OSS Distributions */ 607c1dac77fSApple OSS Distributions className = (const OSSymbol *)inClassName; 608c1dac77fSApple OSS Distributions 6093ca3bd55SApple OSS Distributions // sStalledClassesLock taken in preModLoad 610c1dac77fSApple OSS Distributions if (!sStalled) { 6113ca3bd55SApple OSS Distributions /* There's no way we can look up the kext here, unfortunately. 6123ca3bd55SApple OSS Distributions */ 6133ca3bd55SApple OSS Distributions OSKextLog(/* kext */ NULL, kOSMetaClassLogSpec, 6143ca3bd55SApple OSS Distributions "OSMetaClass: preModLoad() wasn't called for class %s " 6153ca3bd55SApple OSS Distributions "(runtime internal error).", 6163ca3bd55SApple OSS Distributions inClassName); 617c1dac77fSApple OSS Distributions } else if (!sStalled->result) { 618c1dac77fSApple OSS Distributions // Grow stalled array if neccessary 619c1dac77fSApple OSS Distributions if (sStalled->count >= sStalled->capacity) { 620c1dac77fSApple OSS Distributions OSMetaClass **oldStalled = sStalled->classes; 621c1dac77fSApple OSS Distributions int oldSize = sStalled->capacity * sizeof(OSMetaClass *); 622c1dac77fSApple OSS Distributions int newSize = oldSize 623c1dac77fSApple OSS Distributions + kKModCapacityIncrement * sizeof(OSMetaClass *); 624c1dac77fSApple OSS Distributions 6250f3703acSApple OSS Distributions sStalled->classes = (OSMetaClass **)kalloc_tag(newSize, VM_KERN_MEMORY_OSKEXT); 626c1dac77fSApple OSS Distributions if (!sStalled->classes) { 627c1dac77fSApple OSS Distributions sStalled->classes = oldStalled; 628c1dac77fSApple OSS Distributions sStalled->result = kOSMetaClassNoTempData; 629c1dac77fSApple OSS Distributions return; 630c1dac77fSApple OSS Distributions } 631c1dac77fSApple OSS Distributions 632c1dac77fSApple OSS Distributions sStalled->capacity += kKModCapacityIncrement; 633c1dac77fSApple OSS Distributions memmove(sStalled->classes, oldStalled, oldSize); 634e13b1fa5SApple OSS Distributions kfree(oldStalled, oldSize); 6350f3703acSApple OSS Distributions OSMETA_ACCUMSIZE(((size_t)newSize) - ((size_t)oldSize)); 636c1dac77fSApple OSS Distributions } 637c1dac77fSApple OSS Distributions 638c1dac77fSApple OSS Distributions sStalled->classes[sStalled->count++] = this; 639c1dac77fSApple OSS Distributions } 640c1dac77fSApple OSS Distributions } 641c1dac77fSApple OSS Distributions 642*bb611c8fSApple OSS Distributions OSMetaClass::OSMetaClass( 643*bb611c8fSApple OSS Distributions const char * inClassName, 644*bb611c8fSApple OSS Distributions const OSMetaClass * inSuperClass, 645*bb611c8fSApple OSS Distributions unsigned int inClassSize, 646*bb611c8fSApple OSS Distributions zone_t * inZone, 647*bb611c8fSApple OSS Distributions const char * zone_name, 648*bb611c8fSApple OSS Distributions zone_create_flags_t zflags) : OSMetaClass(inClassName, inSuperClass, 649*bb611c8fSApple OSS Distributions inClassSize) 650*bb611c8fSApple OSS Distributions { 651*bb611c8fSApple OSS Distributions if (!(kIOTracking & gIOKitDebug)) { 652*bb611c8fSApple OSS Distributions *inZone = zone_create(zone_name, inClassSize, 653*bb611c8fSApple OSS Distributions (zone_create_flags_t) (ZC_ZFREE_CLEARMEM | zflags)); 654*bb611c8fSApple OSS Distributions } 655*bb611c8fSApple OSS Distributions } 656*bb611c8fSApple OSS Distributions 6573ca3bd55SApple OSS Distributions /********************************************************************* 6583ca3bd55SApple OSS Distributions *********************************************************************/ 659c1dac77fSApple OSS Distributions OSMetaClass::~OSMetaClass() 660c1dac77fSApple OSS Distributions { 661*bb611c8fSApple OSS Distributions OSKext * myKext = reserved->kext; // do not release 662c1dac77fSApple OSS Distributions 6633ca3bd55SApple OSS Distributions /* Hack alert: 'className' is a C string during early C++ init, and 6643ca3bd55SApple OSS Distributions * is converted to a real OSSymbol only when we record the OSKext in 6653ca3bd55SApple OSS Distributions * OSMetaClass::postModLoad(). So only do this bit if we have an OSKext. 6663ca3bd55SApple OSS Distributions * We can't safely cast or check 'className'. 6673ca3bd55SApple OSS Distributions * 6683ca3bd55SApple OSS Distributions * Also, release className *after* calling into the kext, 6693ca3bd55SApple OSS Distributions * as removeClass() may access className. 6703ca3bd55SApple OSS Distributions */ 6713ca3bd55SApple OSS Distributions IOLockLock(sAllClassesLock); 67214e3d835SApple OSS Distributions if (sAllClassesDict) { 6733ca3bd55SApple OSS Distributions if (myKext) { 674c1dac77fSApple OSS Distributions sAllClassesDict->removeObject(className); 6753ca3bd55SApple OSS Distributions } else { 676cc9a6355SApple OSS Distributions sAllClassesDict->removeObject((const char *)className); 6773ca3bd55SApple OSS Distributions } 6783ca3bd55SApple OSS Distributions } 6793ca3bd55SApple OSS Distributions IOLockUnlock(sAllClassesLock); 6803ca3bd55SApple OSS Distributions 6813ca3bd55SApple OSS Distributions if (myKext) { 6823ca3bd55SApple OSS Distributions if (myKext->removeClass(this) != kOSReturnSuccess) { 6833ca3bd55SApple OSS Distributions // xxx - what can we do? 6843ca3bd55SApple OSS Distributions } 68514e3d835SApple OSS Distributions className->release(); 68614e3d835SApple OSS Distributions } 687c1dac77fSApple OSS Distributions 6883ca3bd55SApple OSS Distributions // sStalledClassesLock taken in preModLoad 689c1dac77fSApple OSS Distributions if (sStalled) { 690c1dac77fSApple OSS Distributions unsigned int i; 691c1dac77fSApple OSS Distributions 6923ca3bd55SApple OSS Distributions /* First pass find class in stalled list. If we find it that means 6933ca3bd55SApple OSS Distributions * we started C++ init with constructors but now we're tearing down 6943ca3bd55SApple OSS Distributions * because of some failure. 6953ca3bd55SApple OSS Distributions */ 6963ca3bd55SApple OSS Distributions for (i = 0; i < sStalled->count; i++) { 6973ca3bd55SApple OSS Distributions if (this == sStalled->classes[i]) { 698c1dac77fSApple OSS Distributions break; 6993ca3bd55SApple OSS Distributions } 7003ca3bd55SApple OSS Distributions } 701c1dac77fSApple OSS Distributions 7023ca3bd55SApple OSS Distributions /* Remove this metaclass from the stalled list so postModLoad() doesn't 7033ca3bd55SApple OSS Distributions * try to register it. 7043ca3bd55SApple OSS Distributions */ 705c1dac77fSApple OSS Distributions if (i < sStalled->count) { 706c1dac77fSApple OSS Distributions sStalled->count--; 7073ca3bd55SApple OSS Distributions if (i < sStalled->count) { 708c1dac77fSApple OSS Distributions memmove(&sStalled->classes[i], &sStalled->classes[i + 1], 709c1dac77fSApple OSS Distributions (sStalled->count - i) * sizeof(OSMetaClass *)); 710c1dac77fSApple OSS Distributions } 711c1dac77fSApple OSS Distributions } 712c1dac77fSApple OSS Distributions } 7130f3703acSApple OSS Distributions #if IOTRACKING 7140f3703acSApple OSS Distributions IOTrackingQueueFree(reserved->tracking); 7150f3703acSApple OSS Distributions #endif 7160f3703acSApple OSS Distributions IODelete(reserved, ExpansionData, 1); 7173ca3bd55SApple OSS Distributions } 718c1dac77fSApple OSS Distributions 7193ca3bd55SApple OSS Distributions /********************************************************************* 7203ca3bd55SApple OSS Distributions * Empty overrides. 7213ca3bd55SApple OSS Distributions *********************************************************************/ 722a5e72196SApple OSS Distributions void 723a5e72196SApple OSS Distributions OSMetaClass::retain() const 724a5e72196SApple OSS Distributions { 725a5e72196SApple OSS Distributions } 726a5e72196SApple OSS Distributions void 727a5e72196SApple OSS Distributions OSMetaClass::release() const 728a5e72196SApple OSS Distributions { 729a5e72196SApple OSS Distributions } 730a5e72196SApple OSS Distributions void 731a5e72196SApple OSS Distributions OSMetaClass::release(__unused int when) const 732a5e72196SApple OSS Distributions { 733a5e72196SApple OSS Distributions } 734a5e72196SApple OSS Distributions void 735a5e72196SApple OSS Distributions OSMetaClass::taggedRetain(__unused const void * tag) const 736a5e72196SApple OSS Distributions { 737a5e72196SApple OSS Distributions } 738a5e72196SApple OSS Distributions void 739a5e72196SApple OSS Distributions OSMetaClass::taggedRelease(__unused const void * tag) const 740a5e72196SApple OSS Distributions { 741a5e72196SApple OSS Distributions } 742a5e72196SApple OSS Distributions void 743a5e72196SApple OSS Distributions OSMetaClass::taggedRelease(__unused const void * tag, __unused const int when) const 744a5e72196SApple OSS Distributions { 745a5e72196SApple OSS Distributions } 746a5e72196SApple OSS Distributions int 747a5e72196SApple OSS Distributions OSMetaClass::getRetainCount() const 748a5e72196SApple OSS Distributions { 749a5e72196SApple OSS Distributions return 0; 750a5e72196SApple OSS Distributions } 751c1dac77fSApple OSS Distributions 7523ca3bd55SApple OSS Distributions /********************************************************************* 7533ca3bd55SApple OSS Distributions *********************************************************************/ 7543ca3bd55SApple OSS Distributions const char * 7553ca3bd55SApple OSS Distributions OSMetaClass::getClassName() const 756c1dac77fSApple OSS Distributions { 757a5e72196SApple OSS Distributions if (!className) { 758a5e72196SApple OSS Distributions return NULL; 759a5e72196SApple OSS Distributions } 760c1dac77fSApple OSS Distributions return className->getCStringNoCopy(); 761c1dac77fSApple OSS Distributions } 762d0c1fef6SApple OSS Distributions /********************************************************************* 763d0c1fef6SApple OSS Distributions *********************************************************************/ 764d0c1fef6SApple OSS Distributions const OSSymbol * 765d0c1fef6SApple OSS Distributions OSMetaClass::getClassNameSymbol() const 766d0c1fef6SApple OSS Distributions { 767d0c1fef6SApple OSS Distributions return className; 768d0c1fef6SApple OSS Distributions } 7693ca3bd55SApple OSS Distributions /********************************************************************* 7703ca3bd55SApple OSS Distributions *********************************************************************/ 7713ca3bd55SApple OSS Distributions unsigned int 7723ca3bd55SApple OSS Distributions OSMetaClass::getClassSize() const 773c1dac77fSApple OSS Distributions { 774c1dac77fSApple OSS Distributions return classSize; 775c1dac77fSApple OSS Distributions } 776c1dac77fSApple OSS Distributions 7773ca3bd55SApple OSS Distributions /********************************************************************* 7783ca3bd55SApple OSS Distributions *********************************************************************/ 7793ca3bd55SApple OSS Distributions void * 7803ca3bd55SApple OSS Distributions OSMetaClass::preModLoad(const char * kextIdentifier) 781c1dac77fSApple OSS Distributions { 7823ca3bd55SApple OSS Distributions IOLockLock(sStalledClassesLock); 783c1dac77fSApple OSS Distributions 7843ca3bd55SApple OSS Distributions assert(sStalled == NULL); 7850f3703acSApple OSS Distributions sStalled = (StalledData *)kalloc_tag(sizeof(*sStalled), VM_KERN_MEMORY_OSKEXT); 786c1dac77fSApple OSS Distributions if (sStalled) { 787c1dac77fSApple OSS Distributions sStalled->classes = (OSMetaClass **) 7880f3703acSApple OSS Distributions kalloc_tag(kKModCapacityIncrement * sizeof(OSMetaClass *), VM_KERN_MEMORY_OSKEXT); 789c1dac77fSApple OSS Distributions if (!sStalled->classes) { 790e13b1fa5SApple OSS Distributions kfree(sStalled, sizeof(*sStalled)); 791a5e72196SApple OSS Distributions return NULL; 792c1dac77fSApple OSS Distributions } 7930f3703acSApple OSS Distributions OSMETA_ACCUMSIZE((kKModCapacityIncrement * sizeof(OSMetaClass *)) + 7943ca3bd55SApple OSS Distributions sizeof(*sStalled)); 795c1dac77fSApple OSS Distributions 796c1dac77fSApple OSS Distributions sStalled->result = kOSReturnSuccess; 797c1dac77fSApple OSS Distributions sStalled->capacity = kKModCapacityIncrement; 798c1dac77fSApple OSS Distributions sStalled->count = 0; 7993ca3bd55SApple OSS Distributions sStalled->kextIdentifier = kextIdentifier; 800c1dac77fSApple OSS Distributions bzero(sStalled->classes, kKModCapacityIncrement * sizeof(OSMetaClass *)); 801c1dac77fSApple OSS Distributions } 802c1dac77fSApple OSS Distributions 8033ca3bd55SApple OSS Distributions // keep sStalledClassesLock locked until postModLoad 8043ca3bd55SApple OSS Distributions 805c1dac77fSApple OSS Distributions return sStalled; 806c1dac77fSApple OSS Distributions } 807c1dac77fSApple OSS Distributions 8083ca3bd55SApple OSS Distributions /********************************************************************* 8093ca3bd55SApple OSS Distributions *********************************************************************/ 8103ca3bd55SApple OSS Distributions bool 8113ca3bd55SApple OSS Distributions OSMetaClass::checkModLoad(void * loadHandle) 812c1dac77fSApple OSS Distributions { 8133ca3bd55SApple OSS Distributions return sStalled && loadHandle == sStalled && 8143ca3bd55SApple OSS Distributions sStalled->result == kOSReturnSuccess; 815c1dac77fSApple OSS Distributions } 816c1dac77fSApple OSS Distributions 8173ca3bd55SApple OSS Distributions /********************************************************************* 8183ca3bd55SApple OSS Distributions *********************************************************************/ 8193ca3bd55SApple OSS Distributions OSReturn 8203ca3bd55SApple OSS Distributions OSMetaClass::postModLoad(void * loadHandle) 821c1dac77fSApple OSS Distributions { 822c1dac77fSApple OSS Distributions OSReturn result = kOSReturnSuccess; 823a5e72196SApple OSS Distributions OSSymbol * myKextName = NULL;// must release 824a5e72196SApple OSS Distributions OSKext * myKext = NULL;// must release 825c1dac77fSApple OSS Distributions 826c1dac77fSApple OSS Distributions if (!sStalled || loadHandle != sStalled) { 8273ca3bd55SApple OSS Distributions result = kOSMetaClassInternal; 8283ca3bd55SApple OSS Distributions goto finish; 829c1dac77fSApple OSS Distributions } 830c1dac77fSApple OSS Distributions 8313ca3bd55SApple OSS Distributions if (sStalled->result) { 832c1dac77fSApple OSS Distributions result = sStalled->result; 833a5e72196SApple OSS Distributions } else { 834a5e72196SApple OSS Distributions switch (sBootstrapState) { 835c1dac77fSApple OSS Distributions case kNoDictionaries: 836c1dac77fSApple OSS Distributions sBootstrapState = kMakingDictionaries; 837c1dac77fSApple OSS Distributions // No break; fall through 83888cc0b97SApple OSS Distributions [[clang::fallthrough]]; 839c1dac77fSApple OSS Distributions 840c1dac77fSApple OSS Distributions case kMakingDictionaries: 841c1dac77fSApple OSS Distributions sAllClassesDict = OSDictionary::withCapacity(kClassCapacityIncrement); 8423ca3bd55SApple OSS Distributions if (!sAllClassesDict) { 843c1dac77fSApple OSS Distributions result = kOSMetaClassNoDicts; 844c1dac77fSApple OSS Distributions break; 845c1dac77fSApple OSS Distributions } 846d0c1fef6SApple OSS Distributions sAllClassesDict->setOptions(OSCollection::kSort, OSCollection::kSort); 8473ca3bd55SApple OSS Distributions 848c1dac77fSApple OSS Distributions // No break; fall through 84988cc0b97SApple OSS Distributions [[clang::fallthrough]]; 850c1dac77fSApple OSS Distributions 851c1dac77fSApple OSS Distributions case kCompletedBootstrap: 852c1dac77fSApple OSS Distributions { 853c1dac77fSApple OSS Distributions unsigned int i; 8543ca3bd55SApple OSS Distributions myKextName = const_cast<OSSymbol *>(OSSymbol::withCStringNoCopy( 8553ca3bd55SApple OSS Distributions sStalled->kextIdentifier)); 856c1dac77fSApple OSS Distributions 8573ca3bd55SApple OSS Distributions if (!sStalled->count) { 858c1dac77fSApple OSS Distributions break; // Nothing to do so just get out 8593ca3bd55SApple OSS Distributions } 860c1dac77fSApple OSS Distributions 8613ca3bd55SApple OSS Distributions myKext = OSKext::lookupKextWithIdentifier(myKextName); 8623ca3bd55SApple OSS Distributions if (!myKext) { 8633ca3bd55SApple OSS Distributions result = kOSMetaClassNoKext; 8643ca3bd55SApple OSS Distributions 8653ca3bd55SApple OSS Distributions /* Log this error here so we can include the kext name. 8663ca3bd55SApple OSS Distributions */ 8673ca3bd55SApple OSS Distributions OSKextLog(/* kext */ NULL, kOSMetaClassLogSpec, 8683ca3bd55SApple OSS Distributions "OSMetaClass: Can't record classes for kext %s - kext not found.", 8693ca3bd55SApple OSS Distributions sStalled->kextIdentifier); 8703ca3bd55SApple OSS Distributions break; 8713ca3bd55SApple OSS Distributions } 8723ca3bd55SApple OSS Distributions 8733ca3bd55SApple OSS Distributions /* First pass checking classes aren't already loaded. If any already 8743ca3bd55SApple OSS Distributions * exist, we don't register any, and so we don't technically have 8753ca3bd55SApple OSS Distributions * to do any C++ teardown. 8763ca3bd55SApple OSS Distributions * 8773ca3bd55SApple OSS Distributions * Hack alert: me->className has been a C string until now. 8783ca3bd55SApple OSS Distributions * We only release the OSSymbol if we store the kext. 8793ca3bd55SApple OSS Distributions */ 8803ca3bd55SApple OSS Distributions IOLockLock(sAllClassesLock); 881c1dac77fSApple OSS Distributions for (i = 0; i < sStalled->count; i++) { 882d0c1fef6SApple OSS Distributions const OSMetaClass * me = sStalled->classes[i]; 8833ca3bd55SApple OSS Distributions OSMetaClass * orig = OSDynamicCast(OSMetaClass, 8843ca3bd55SApple OSS Distributions sAllClassesDict->getObject((const char *)me->className)); 885c1dac77fSApple OSS Distributions 8863ca3bd55SApple OSS Distributions if (orig) { 8873ca3bd55SApple OSS Distributions /* Log this error here so we can include the class name. 8883ca3bd55SApple OSS Distributions * xxx - we should look up the other kext that defines the class 8893ca3bd55SApple OSS Distributions */ 890*bb611c8fSApple OSS Distributions #if defined(XNU_TARGET_OS_OSX) 8913ca3bd55SApple OSS Distributions OSKextLog(myKext, kOSMetaClassLogSpec, 892*bb611c8fSApple OSS Distributions #else 893*bb611c8fSApple OSS Distributions panic( 894*bb611c8fSApple OSS Distributions #endif /* defined(XNU_TARGET_OS_OSX) */ 8953ca3bd55SApple OSS Distributions "OSMetaClass: Kext %s class %s is a duplicate;" 8963ca3bd55SApple OSS Distributions "kext %s already has a class by that name.", 8973ca3bd55SApple OSS Distributions sStalled->kextIdentifier, (const char *)me->className, 898d0c1fef6SApple OSS Distributions ((OSKext *)orig->reserved->kext)->getIdentifierCString()); 899c1dac77fSApple OSS Distributions result = kOSMetaClassDuplicateClass; 900c1dac77fSApple OSS Distributions break; 901c1dac77fSApple OSS Distributions } 902d0c1fef6SApple OSS Distributions unsigned int depth = 1; 903a5e72196SApple OSS Distributions while ((me = me->superClassLink)) { 904a5e72196SApple OSS Distributions depth++; 905a5e72196SApple OSS Distributions } 906a5e72196SApple OSS Distributions if (depth > sDeepestClass) { 907a5e72196SApple OSS Distributions sDeepestClass = depth; 908a5e72196SApple OSS Distributions } 909c1dac77fSApple OSS Distributions } 9103ca3bd55SApple OSS Distributions IOLockUnlock(sAllClassesLock); 911c1dac77fSApple OSS Distributions 9123ca3bd55SApple OSS Distributions /* Bail if we didn't go through the entire list of new classes 9133ca3bd55SApple OSS Distributions * (if we hit a duplicate). 9143ca3bd55SApple OSS Distributions */ 9153ca3bd55SApple OSS Distributions if (i != sStalled->count) { 916c1dac77fSApple OSS Distributions break; 917c1dac77fSApple OSS Distributions } 918c1dac77fSApple OSS Distributions 919c1dac77fSApple OSS Distributions // Second pass symbolling strings and inserting classes in dictionary 9203ca3bd55SApple OSS Distributions IOLockLock(sAllClassesLock); 92114e3d835SApple OSS Distributions for (i = 0; i < sStalled->count; i++) { 922c1dac77fSApple OSS Distributions OSMetaClass * me = sStalled->classes[i]; 9233ca3bd55SApple OSS Distributions 9243ca3bd55SApple OSS Distributions /* Hack alert: me->className has been a C string until now. 9253ca3bd55SApple OSS Distributions * We only release the OSSymbol in ~OSMetaClass() 9263ca3bd55SApple OSS Distributions * if we set the reference to the kext. 9273ca3bd55SApple OSS Distributions */ 928c1dac77fSApple OSS Distributions me->className = 929c1dac77fSApple OSS Distributions OSSymbol::withCStringNoCopy((const char *)me->className); 930c1dac77fSApple OSS Distributions 9313ca3bd55SApple OSS Distributions // xxx - I suppose if these fail we're going to panic soon.... 932c1dac77fSApple OSS Distributions sAllClassesDict->setObject(me->className, me); 9333ca3bd55SApple OSS Distributions 9343ca3bd55SApple OSS Distributions /* Do not retain the kext object here. 9353ca3bd55SApple OSS Distributions */ 936d0c1fef6SApple OSS Distributions me->reserved->kext = myKext; 9373ca3bd55SApple OSS Distributions if (myKext) { 9383ca3bd55SApple OSS Distributions result = myKext->addClass(me, sStalled->count); 9393ca3bd55SApple OSS Distributions if (result != kOSReturnSuccess) { 9403ca3bd55SApple OSS Distributions /* OSKext::addClass() logs with kOSMetaClassNoInsKModSet. */ 9413ca3bd55SApple OSS Distributions break; 942c1dac77fSApple OSS Distributions } 9433ca3bd55SApple OSS Distributions } 9443ca3bd55SApple OSS Distributions } 9453ca3bd55SApple OSS Distributions IOLockUnlock(sAllClassesLock); 946c1dac77fSApple OSS Distributions sBootstrapState = kCompletedBootstrap; 947c1dac77fSApple OSS Distributions break; 948c1dac77fSApple OSS Distributions } 949c1dac77fSApple OSS Distributions 950c1dac77fSApple OSS Distributions default: 951c1dac77fSApple OSS Distributions result = kOSMetaClassInternal; 952c1dac77fSApple OSS Distributions break; 953c1dac77fSApple OSS Distributions } 954a5e72196SApple OSS Distributions } 955c1dac77fSApple OSS Distributions 9563ca3bd55SApple OSS Distributions finish: 9573ca3bd55SApple OSS Distributions /* Don't call logError() for success or the conditions logged above 9583ca3bd55SApple OSS Distributions * or by called function. 9593ca3bd55SApple OSS Distributions */ 9603ca3bd55SApple OSS Distributions if (result != kOSReturnSuccess && 9613ca3bd55SApple OSS Distributions result != kOSMetaClassNoInsKModSet && 9623ca3bd55SApple OSS Distributions result != kOSMetaClassDuplicateClass && 9633ca3bd55SApple OSS Distributions result != kOSMetaClassNoKext) { 9643ca3bd55SApple OSS Distributions OSMetaClassLogErrorForKext(result, myKext); 9653ca3bd55SApple OSS Distributions } 9663ca3bd55SApple OSS Distributions 96788cc0b97SApple OSS Distributions OSSafeReleaseNULL(myKextName); 96888cc0b97SApple OSS Distributions OSSafeReleaseNULL(myKext); 96914e3d835SApple OSS Distributions 970c1dac77fSApple OSS Distributions if (sStalled) { 9710f3703acSApple OSS Distributions OSMETA_ACCUMSIZE(-(sStalled->capacity * sizeof(OSMetaClass *) + 9723ca3bd55SApple OSS Distributions sizeof(*sStalled))); 9733ca3bd55SApple OSS Distributions kfree(sStalled->classes, sStalled->capacity * sizeof(OSMetaClass *)); 974e13b1fa5SApple OSS Distributions kfree(sStalled, sizeof(*sStalled)); 975a5e72196SApple OSS Distributions sStalled = NULL; 976c1dac77fSApple OSS Distributions } 977c1dac77fSApple OSS Distributions 9783ca3bd55SApple OSS Distributions IOLockUnlock(sStalledClassesLock); 9793ca3bd55SApple OSS Distributions 980c1dac77fSApple OSS Distributions return result; 981c1dac77fSApple OSS Distributions } 982c1dac77fSApple OSS Distributions 983c1dac77fSApple OSS Distributions 9843ca3bd55SApple OSS Distributions /********************************************************************* 9853ca3bd55SApple OSS Distributions *********************************************************************/ 9863ca3bd55SApple OSS Distributions void 9873ca3bd55SApple OSS Distributions OSMetaClass::instanceConstructed() const 988c1dac77fSApple OSS Distributions { 9893ca3bd55SApple OSS Distributions // if ((0 == OSIncrementAtomic(&(((OSMetaClass *) this)->instanceCount))) && superClassLink) 9903ca3bd55SApple OSS Distributions if ((0 == OSIncrementAtomic(&instanceCount)) && superClassLink) { 991c1dac77fSApple OSS Distributions superClassLink->instanceConstructed(); 992c1dac77fSApple OSS Distributions } 993c1dac77fSApple OSS Distributions } 994c1dac77fSApple OSS Distributions 9953ca3bd55SApple OSS Distributions /********************************************************************* 9963ca3bd55SApple OSS Distributions *********************************************************************/ 9973ca3bd55SApple OSS Distributions void 9983ca3bd55SApple OSS Distributions OSMetaClass::instanceDestructed() const 9993ca3bd55SApple OSS Distributions { 10003ca3bd55SApple OSS Distributions if ((1 == OSDecrementAtomic(&instanceCount)) && superClassLink) { 10013ca3bd55SApple OSS Distributions superClassLink->instanceDestructed(); 10023ca3bd55SApple OSS Distributions } 10033ca3bd55SApple OSS Distributions 10043ca3bd55SApple OSS Distributions if (((int)instanceCount) < 0) { 1005d0c1fef6SApple OSS Distributions OSKext * myKext = reserved->kext; 10063ca3bd55SApple OSS Distributions 10073ca3bd55SApple OSS Distributions OSKextLog(myKext, kOSMetaClassLogSpec, 10083ca3bd55SApple OSS Distributions // xxx - this phrasing is rather cryptic 10093ca3bd55SApple OSS Distributions "OSMetaClass: Class %s - bad retain (%d)", 10103ca3bd55SApple OSS Distributions getClassName(), instanceCount); 10113ca3bd55SApple OSS Distributions } 10123ca3bd55SApple OSS Distributions } 10133ca3bd55SApple OSS Distributions 10143ca3bd55SApple OSS Distributions /********************************************************************* 10153ca3bd55SApple OSS Distributions *********************************************************************/ 10163ca3bd55SApple OSS Distributions bool 10173ca3bd55SApple OSS Distributions OSMetaClass::modHasInstance(const char * kextIdentifier) 1018c1dac77fSApple OSS Distributions { 1019c1dac77fSApple OSS Distributions bool result = false; 10203ca3bd55SApple OSS Distributions OSKext * theKext = NULL; // must release 1021c1dac77fSApple OSS Distributions 10223ca3bd55SApple OSS Distributions theKext = OSKext::lookupKextWithIdentifier(kextIdentifier); 10233ca3bd55SApple OSS Distributions if (!theKext) { 10243ca3bd55SApple OSS Distributions goto finish; 1025c1dac77fSApple OSS Distributions } 1026c1dac77fSApple OSS Distributions 10273ca3bd55SApple OSS Distributions result = theKext->hasOSMetaClassInstances(); 1028c1dac77fSApple OSS Distributions 10293ca3bd55SApple OSS Distributions finish: 103088cc0b97SApple OSS Distributions OSSafeReleaseNULL(theKext); 1031c1dac77fSApple OSS Distributions return result; 1032c1dac77fSApple OSS Distributions } 1033c1dac77fSApple OSS Distributions 10343ca3bd55SApple OSS Distributions /********************************************************************* 10353ca3bd55SApple OSS Distributions *********************************************************************/ 10363ca3bd55SApple OSS Distributions void 10373ca3bd55SApple OSS Distributions OSMetaClass::reportModInstances(const char * kextIdentifier) 1038c1dac77fSApple OSS Distributions { 10393ca3bd55SApple OSS Distributions OSKext::reportOSMetaClassInstances(kextIdentifier, 10403ca3bd55SApple OSS Distributions kOSKextLogExplicitLevel); 1041e13b1fa5SApple OSS Distributions return; 1042e13b1fa5SApple OSS Distributions } 1043d0c1fef6SApple OSS Distributions /********************************************************************* 1044d0c1fef6SApple OSS Distributions *********************************************************************/ 1045d0c1fef6SApple OSS Distributions 1046d0c1fef6SApple OSS Distributions void 1047d0c1fef6SApple OSS Distributions OSMetaClass::addInstance(const OSObject * instance, bool super) const 1048d0c1fef6SApple OSS Distributions { 1049a5e72196SApple OSS Distributions if (!super) { 1050a5e72196SApple OSS Distributions IOLockLock(sInstancesLock); 1051a5e72196SApple OSS Distributions } 1052d0c1fef6SApple OSS Distributions 1053d0c1fef6SApple OSS Distributions if (!reserved->instances) { 1054d0c1fef6SApple OSS Distributions reserved->instances = OSOrderedSet::withCapacity(16); 1055d0c1fef6SApple OSS Distributions if (superClassLink) { 1056d0c1fef6SApple OSS Distributions superClassLink->addInstance(reserved->instances, true); 1057d0c1fef6SApple OSS Distributions } 1058d0c1fef6SApple OSS Distributions } 1059d0c1fef6SApple OSS Distributions reserved->instances->setLastObject(instance); 1060d0c1fef6SApple OSS Distributions 1061a5e72196SApple OSS Distributions if (!super) { 1062a5e72196SApple OSS Distributions IOLockUnlock(sInstancesLock); 1063a5e72196SApple OSS Distributions } 1064d0c1fef6SApple OSS Distributions } 1065d0c1fef6SApple OSS Distributions 1066d0c1fef6SApple OSS Distributions void 1067d0c1fef6SApple OSS Distributions OSMetaClass::removeInstance(const OSObject * instance, bool super) const 1068d0c1fef6SApple OSS Distributions { 1069a5e72196SApple OSS Distributions if (!super) { 1070a5e72196SApple OSS Distributions IOLockLock(sInstancesLock); 1071a5e72196SApple OSS Distributions } 1072d0c1fef6SApple OSS Distributions 1073d0c1fef6SApple OSS Distributions if (reserved->instances) { 1074d0c1fef6SApple OSS Distributions reserved->instances->removeObject(instance); 1075d0c1fef6SApple OSS Distributions if (0 == reserved->instances->getCount()) { 1076d0c1fef6SApple OSS Distributions if (superClassLink) { 1077d0c1fef6SApple OSS Distributions superClassLink->removeInstance(reserved->instances, true); 1078d0c1fef6SApple OSS Distributions } 1079186b8fceSApple OSS Distributions IOLockLock(sAllClassesLock); 1080d0c1fef6SApple OSS Distributions reserved->instances->release(); 1081a5e72196SApple OSS Distributions reserved->instances = NULL; 1082186b8fceSApple OSS Distributions IOLockUnlock(sAllClassesLock); 1083d0c1fef6SApple OSS Distributions } 1084d0c1fef6SApple OSS Distributions } 1085d0c1fef6SApple OSS Distributions 1086a5e72196SApple OSS Distributions if (!super) { 1087a5e72196SApple OSS Distributions IOLockUnlock(sInstancesLock); 1088a5e72196SApple OSS Distributions } 1089d0c1fef6SApple OSS Distributions } 1090d0c1fef6SApple OSS Distributions 1091d0c1fef6SApple OSS Distributions void 1092d0c1fef6SApple OSS Distributions OSMetaClass::applyToInstances(OSOrderedSet * set, 1093d0c1fef6SApple OSS Distributions OSMetaClassInstanceApplierFunction applier, 1094d0c1fef6SApple OSS Distributions void * context) 1095d0c1fef6SApple OSS Distributions { 1096d0c1fef6SApple OSS Distributions enum { kLocalDepth = 24 }; 1097d0c1fef6SApple OSS Distributions unsigned int _nextIndex[kLocalDepth]; 1098d0c1fef6SApple OSS Distributions OSOrderedSet * _sets[kLocalDepth]; 1099d0c1fef6SApple OSS Distributions unsigned int * nextIndex = &_nextIndex[0]; 1100d0c1fef6SApple OSS Distributions OSOrderedSet ** sets = &_sets[0]; 1101d0c1fef6SApple OSS Distributions OSObject * obj; 1102d0c1fef6SApple OSS Distributions OSOrderedSet * childSet; 1103d0c1fef6SApple OSS Distributions unsigned int maxDepth; 1104d0c1fef6SApple OSS Distributions unsigned int idx; 1105d0c1fef6SApple OSS Distributions unsigned int level; 1106d0c1fef6SApple OSS Distributions bool done; 1107d0c1fef6SApple OSS Distributions 1108d0c1fef6SApple OSS Distributions maxDepth = sDeepestClass; 1109a5e72196SApple OSS Distributions if (maxDepth > kLocalDepth) { 1110d0c1fef6SApple OSS Distributions nextIndex = IONew(typeof(nextIndex[0]), maxDepth); 1111d0c1fef6SApple OSS Distributions sets = IONew(typeof(sets[0]), maxDepth); 1112d0c1fef6SApple OSS Distributions } 1113d0c1fef6SApple OSS Distributions done = false; 1114d0c1fef6SApple OSS Distributions level = 0; 1115d0c1fef6SApple OSS Distributions idx = 0; 1116a5e72196SApple OSS Distributions do{ 1117a5e72196SApple OSS Distributions while (!done && (obj = set->getObject(idx++))) { 1118a5e72196SApple OSS Distributions if ((childSet = OSDynamicCast(OSOrderedSet, obj))) { 1119a5e72196SApple OSS Distributions if (level >= maxDepth) { 1120a5e72196SApple OSS Distributions panic(">maxDepth"); 1121a5e72196SApple OSS Distributions } 1122d0c1fef6SApple OSS Distributions sets[level] = set; 1123d0c1fef6SApple OSS Distributions nextIndex[level] = idx; 1124d0c1fef6SApple OSS Distributions level++; 1125d0c1fef6SApple OSS Distributions set = childSet; 1126d0c1fef6SApple OSS Distributions idx = 0; 1127d0c1fef6SApple OSS Distributions break; 1128d0c1fef6SApple OSS Distributions } 1129d0c1fef6SApple OSS Distributions done = (*applier)(obj, context); 1130d0c1fef6SApple OSS Distributions } 1131a5e72196SApple OSS Distributions if (!obj) { 1132a5e72196SApple OSS Distributions if (!done && level) { 1133d0c1fef6SApple OSS Distributions level--; 1134d0c1fef6SApple OSS Distributions set = sets[level]; 1135d0c1fef6SApple OSS Distributions idx = nextIndex[level]; 1136a5e72196SApple OSS Distributions } else { 1137a5e72196SApple OSS Distributions done = true; 1138d0c1fef6SApple OSS Distributions } 1139d0c1fef6SApple OSS Distributions } 1140a5e72196SApple OSS Distributions }while (!done); 1141a5e72196SApple OSS Distributions if (maxDepth > kLocalDepth) { 1142d0c1fef6SApple OSS Distributions IODelete(nextIndex, typeof(nextIndex[0]), maxDepth); 1143d0c1fef6SApple OSS Distributions IODelete(sets, typeof(sets[0]), maxDepth); 1144d0c1fef6SApple OSS Distributions } 1145d0c1fef6SApple OSS Distributions } 1146d0c1fef6SApple OSS Distributions 1147d0c1fef6SApple OSS Distributions void 1148d0c1fef6SApple OSS Distributions OSMetaClass::applyToInstances(OSMetaClassInstanceApplierFunction applier, 1149d0c1fef6SApple OSS Distributions void * context) const 1150d0c1fef6SApple OSS Distributions { 1151d0c1fef6SApple OSS Distributions IOLockLock(sInstancesLock); 1152a5e72196SApple OSS Distributions if (reserved->instances) { 1153a5e72196SApple OSS Distributions applyToInstances(reserved->instances, applier, context); 1154a5e72196SApple OSS Distributions } 1155d0c1fef6SApple OSS Distributions IOLockUnlock(sInstancesLock); 1156d0c1fef6SApple OSS Distributions } 1157d0c1fef6SApple OSS Distributions 1158d0c1fef6SApple OSS Distributions void 1159d0c1fef6SApple OSS Distributions OSMetaClass::applyToInstancesOfClassName( 1160d0c1fef6SApple OSS Distributions const OSSymbol * name, 1161d0c1fef6SApple OSS Distributions OSMetaClassInstanceApplierFunction applier, 1162d0c1fef6SApple OSS Distributions void * context) 1163d0c1fef6SApple OSS Distributions { 1164d0c1fef6SApple OSS Distributions OSMetaClass * meta; 1165a5e72196SApple OSS Distributions OSOrderedSet * set = NULL; 1166d0c1fef6SApple OSS Distributions 1167d0c1fef6SApple OSS Distributions IOLockLock(sAllClassesLock); 1168d0c1fef6SApple OSS Distributions if (sAllClassesDict 1169d0c1fef6SApple OSS Distributions && (meta = (OSMetaClass *) sAllClassesDict->getObject(name)) 1170a5e72196SApple OSS Distributions && (set = meta->reserved->instances)) { 1171d0c1fef6SApple OSS Distributions set->retain(); 1172d0c1fef6SApple OSS Distributions } 1173d0c1fef6SApple OSS Distributions IOLockUnlock(sAllClassesLock); 1174d0c1fef6SApple OSS Distributions 1175a5e72196SApple OSS Distributions if (!set) { 1176a5e72196SApple OSS Distributions return; 1177a5e72196SApple OSS Distributions } 1178d0c1fef6SApple OSS Distributions 1179d0c1fef6SApple OSS Distributions IOLockLock(sInstancesLock); 1180d0c1fef6SApple OSS Distributions applyToInstances(set, applier, context); 1181d0c1fef6SApple OSS Distributions IOLockUnlock(sInstancesLock); 1182d0c1fef6SApple OSS Distributions set->release(); 1183d0c1fef6SApple OSS Distributions } 1184e13b1fa5SApple OSS Distributions 11853ca3bd55SApple OSS Distributions /********************************************************************* 11863ca3bd55SApple OSS Distributions *********************************************************************/ 11873ca3bd55SApple OSS Distributions void 11883ca3bd55SApple OSS Distributions OSMetaClass::considerUnloads() 1189c1dac77fSApple OSS Distributions { 11903ca3bd55SApple OSS Distributions OSKext::considerUnloads(); 1191c1dac77fSApple OSS Distributions } 1192c1dac77fSApple OSS Distributions 11933ca3bd55SApple OSS Distributions /********************************************************************* 11943ca3bd55SApple OSS Distributions *********************************************************************/ 119576e12aa3SApple OSS Distributions bool 119676e12aa3SApple OSS Distributions OSMetaClass::removeClasses(OSCollection * metaClasses) 119776e12aa3SApple OSS Distributions { 119876e12aa3SApple OSS Distributions OSCollectionIterator * classIterator; 119976e12aa3SApple OSS Distributions OSMetaClass * checkClass; 120076e12aa3SApple OSS Distributions bool result; 120176e12aa3SApple OSS Distributions 120276e12aa3SApple OSS Distributions classIterator = OSCollectionIterator::withCollection(metaClasses); 1203a5e72196SApple OSS Distributions if (!classIterator) { 1204a5e72196SApple OSS Distributions return false; 1205a5e72196SApple OSS Distributions } 120676e12aa3SApple OSS Distributions 120776e12aa3SApple OSS Distributions IOLockLock(sAllClassesLock); 120876e12aa3SApple OSS Distributions 120976e12aa3SApple OSS Distributions result = false; 1210a5e72196SApple OSS Distributions do{ 121176e12aa3SApple OSS Distributions while ((checkClass = (OSMetaClass *)classIterator->getNextObject()) 121276e12aa3SApple OSS Distributions && !checkClass->getInstanceCount() 1213a5e72196SApple OSS Distributions && !checkClass->reserved->retain) { 1214a5e72196SApple OSS Distributions } 1215a5e72196SApple OSS Distributions if (checkClass) { 1216a5e72196SApple OSS Distributions break; 1217a5e72196SApple OSS Distributions } 121876e12aa3SApple OSS Distributions classIterator->reset(); 1219a5e72196SApple OSS Distributions while ((checkClass = (OSMetaClass *)classIterator->getNextObject())) { 122076e12aa3SApple OSS Distributions sAllClassesDict->removeObject(checkClass->className); 122176e12aa3SApple OSS Distributions } 122276e12aa3SApple OSS Distributions result = true; 1223a5e72196SApple OSS Distributions }while (false); 122476e12aa3SApple OSS Distributions 122576e12aa3SApple OSS Distributions IOLockUnlock(sAllClassesLock); 122676e12aa3SApple OSS Distributions OSSafeReleaseNULL(classIterator); 122776e12aa3SApple OSS Distributions 1228a5e72196SApple OSS Distributions return result; 122976e12aa3SApple OSS Distributions } 123076e12aa3SApple OSS Distributions 123176e12aa3SApple OSS Distributions 123276e12aa3SApple OSS Distributions /********************************************************************* 123376e12aa3SApple OSS Distributions *********************************************************************/ 12343ca3bd55SApple OSS Distributions const OSMetaClass * 12353ca3bd55SApple OSS Distributions OSMetaClass::getMetaClassWithName(const OSSymbol * name) 1236c1dac77fSApple OSS Distributions { 1237a5e72196SApple OSS Distributions OSMetaClass * retMeta = NULL; 1238c1dac77fSApple OSS Distributions 12393ca3bd55SApple OSS Distributions if (!name) { 1240a5e72196SApple OSS Distributions return NULL; 12413ca3bd55SApple OSS Distributions } 1242c1dac77fSApple OSS Distributions 12433ca3bd55SApple OSS Distributions IOLockLock(sAllClassesLock); 12443ca3bd55SApple OSS Distributions if (sAllClassesDict) { 1245c1dac77fSApple OSS Distributions retMeta = (OSMetaClass *) sAllClassesDict->getObject(name); 1246c1dac77fSApple OSS Distributions } 12473ca3bd55SApple OSS Distributions IOLockUnlock(sAllClassesLock); 1248c1dac77fSApple OSS Distributions 1249c1dac77fSApple OSS Distributions return retMeta; 1250c1dac77fSApple OSS Distributions } 1251c1dac77fSApple OSS Distributions 12523ca3bd55SApple OSS Distributions /********************************************************************* 12533ca3bd55SApple OSS Distributions *********************************************************************/ 125476e12aa3SApple OSS Distributions const OSMetaClass * 125576e12aa3SApple OSS Distributions OSMetaClass::copyMetaClassWithName(const OSSymbol * name) 125676e12aa3SApple OSS Distributions { 125776e12aa3SApple OSS Distributions const OSMetaClass * meta; 125876e12aa3SApple OSS Distributions 1259a5e72196SApple OSS Distributions if (!name) { 1260a5e72196SApple OSS Distributions return NULL; 1261a5e72196SApple OSS Distributions } 126276e12aa3SApple OSS Distributions 1263a5e72196SApple OSS Distributions meta = NULL; 126476e12aa3SApple OSS Distributions IOLockLock(sAllClassesLock); 126576e12aa3SApple OSS Distributions if (sAllClassesDict) { 126676e12aa3SApple OSS Distributions meta = (OSMetaClass *) sAllClassesDict->getObject(name); 1267a5e72196SApple OSS Distributions if (meta) { 1268a5e72196SApple OSS Distributions OSIncrementAtomic(&meta->reserved->retain); 1269a5e72196SApple OSS Distributions } 127076e12aa3SApple OSS Distributions } 127176e12aa3SApple OSS Distributions IOLockUnlock(sAllClassesLock); 127276e12aa3SApple OSS Distributions 1273a5e72196SApple OSS Distributions return meta; 127476e12aa3SApple OSS Distributions } 127576e12aa3SApple OSS Distributions 127676e12aa3SApple OSS Distributions /********************************************************************* 127776e12aa3SApple OSS Distributions *********************************************************************/ 127876e12aa3SApple OSS Distributions void 127976e12aa3SApple OSS Distributions OSMetaClass::releaseMetaClass() const 128076e12aa3SApple OSS Distributions { 128176e12aa3SApple OSS Distributions OSDecrementAtomic(&reserved->retain); 128276e12aa3SApple OSS Distributions } 128376e12aa3SApple OSS Distributions 128476e12aa3SApple OSS Distributions /********************************************************************* 128576e12aa3SApple OSS Distributions *********************************************************************/ 12863ca3bd55SApple OSS Distributions OSObject * 12873ca3bd55SApple OSS Distributions OSMetaClass::allocClassWithName(const OSSymbol * name) 1288c1dac77fSApple OSS Distributions { 128976e12aa3SApple OSS Distributions const OSMetaClass * meta; 129076e12aa3SApple OSS Distributions OSObject * result; 1291c1dac77fSApple OSS Distributions 1292a5e72196SApple OSS Distributions result = NULL; 129376e12aa3SApple OSS Distributions meta = copyMetaClassWithName(name); 1294a5e72196SApple OSS Distributions if (meta) { 1295c1dac77fSApple OSS Distributions result = meta->alloc(); 129676e12aa3SApple OSS Distributions meta->releaseMetaClass(); 12973ca3bd55SApple OSS Distributions } 1298c1dac77fSApple OSS Distributions 1299c1dac77fSApple OSS Distributions return result; 1300c1dac77fSApple OSS Distributions } 1301c1dac77fSApple OSS Distributions 13023ca3bd55SApple OSS Distributions /********************************************************************* 13033ca3bd55SApple OSS Distributions *********************************************************************/ 13043ca3bd55SApple OSS Distributions OSObject * 13053ca3bd55SApple OSS Distributions OSMetaClass::allocClassWithName(const OSString * name) 1306c1dac77fSApple OSS Distributions { 1307c1dac77fSApple OSS Distributions const OSSymbol * tmpKey = OSSymbol::withString(name); 1308c1dac77fSApple OSS Distributions OSObject * result = allocClassWithName(tmpKey); 1309c1dac77fSApple OSS Distributions tmpKey->release(); 1310c1dac77fSApple OSS Distributions return result; 1311c1dac77fSApple OSS Distributions } 1312c1dac77fSApple OSS Distributions 13133ca3bd55SApple OSS Distributions /********************************************************************* 13143ca3bd55SApple OSS Distributions *********************************************************************/ 13153ca3bd55SApple OSS Distributions OSObject * 13163ca3bd55SApple OSS Distributions OSMetaClass::allocClassWithName(const char * name) 1317c1dac77fSApple OSS Distributions { 1318c1dac77fSApple OSS Distributions const OSSymbol * tmpKey = OSSymbol::withCStringNoCopy(name); 1319c1dac77fSApple OSS Distributions OSObject * result = allocClassWithName(tmpKey); 1320c1dac77fSApple OSS Distributions tmpKey->release(); 1321c1dac77fSApple OSS Distributions return result; 1322c1dac77fSApple OSS Distributions } 1323c1dac77fSApple OSS Distributions 1324c1dac77fSApple OSS Distributions 13253ca3bd55SApple OSS Distributions /********************************************************************* 13263ca3bd55SApple OSS Distributions *********************************************************************/ 13273ca3bd55SApple OSS Distributions OSMetaClassBase * 13283ca3bd55SApple OSS Distributions OSMetaClass::checkMetaCastWithName( 13293ca3bd55SApple OSS Distributions const OSSymbol * name, 13303ca3bd55SApple OSS Distributions const OSMetaClassBase * in) 1331c1dac77fSApple OSS Distributions { 1332a5e72196SApple OSS Distributions OSMetaClassBase * result = NULL; 13333ca3bd55SApple OSS Distributions 1334c1dac77fSApple OSS Distributions const OSMetaClass * const meta = getMetaClassWithName(name); 1335c1dac77fSApple OSS Distributions 13363ca3bd55SApple OSS Distributions if (meta) { 1337c1dac77fSApple OSS Distributions result = meta->checkMetaCast(in); 13383ca3bd55SApple OSS Distributions } 1339c1dac77fSApple OSS Distributions 1340c1dac77fSApple OSS Distributions return result; 1341c1dac77fSApple OSS Distributions } 1342c1dac77fSApple OSS Distributions 13433ca3bd55SApple OSS Distributions /********************************************************************* 13443ca3bd55SApple OSS Distributions *********************************************************************/ 1345a5e72196SApple OSS Distributions OSMetaClassBase * 1346a5e72196SApple OSS Distributions OSMetaClass:: 13473ca3bd55SApple OSS Distributions checkMetaCastWithName( 13483ca3bd55SApple OSS Distributions const OSString * name, 13493ca3bd55SApple OSS Distributions const OSMetaClassBase * in) 1350c1dac77fSApple OSS Distributions { 1351c1dac77fSApple OSS Distributions const OSSymbol * tmpKey = OSSymbol::withString(name); 1352c1dac77fSApple OSS Distributions OSMetaClassBase * result = checkMetaCastWithName(tmpKey, in); 13533ca3bd55SApple OSS Distributions 1354c1dac77fSApple OSS Distributions tmpKey->release(); 1355c1dac77fSApple OSS Distributions return result; 1356c1dac77fSApple OSS Distributions } 1357c1dac77fSApple OSS Distributions 13583ca3bd55SApple OSS Distributions /********************************************************************* 13593ca3bd55SApple OSS Distributions *********************************************************************/ 13603ca3bd55SApple OSS Distributions OSMetaClassBase * 13613ca3bd55SApple OSS Distributions OSMetaClass::checkMetaCastWithName( 13623ca3bd55SApple OSS Distributions const char * name, 13633ca3bd55SApple OSS Distributions const OSMetaClassBase * in) 1364c1dac77fSApple OSS Distributions { 1365c1dac77fSApple OSS Distributions const OSSymbol * tmpKey = OSSymbol::withCStringNoCopy(name); 1366c1dac77fSApple OSS Distributions OSMetaClassBase * result = checkMetaCastWithName(tmpKey, in); 13673ca3bd55SApple OSS Distributions 1368c1dac77fSApple OSS Distributions tmpKey->release(); 1369c1dac77fSApple OSS Distributions return result; 1370c1dac77fSApple OSS Distributions } 1371c1dac77fSApple OSS Distributions 13723ca3bd55SApple OSS Distributions /********************************************************************* 13733ca3bd55SApple OSS Distributions * OSMetaClass::checkMetaCast() 13743ca3bd55SApple OSS Distributions * Check to see if the 'check' object has this object in its metaclass chain. 13753ca3bd55SApple OSS Distributions * Returns check if it is indeed a kind of the current meta class, 0 otherwise. 13763ca3bd55SApple OSS Distributions * 13773ca3bd55SApple OSS Distributions * Generally this method is not invoked directly but is used to implement 13783ca3bd55SApple OSS Distributions * the OSMetaClassBase::metaCast member function. 13793ca3bd55SApple OSS Distributions * 13803ca3bd55SApple OSS Distributions * See also OSMetaClassBase::metaCast 13813ca3bd55SApple OSS Distributions *********************************************************************/ 1382a5e72196SApple OSS Distributions OSMetaClassBase * 1383a5e72196SApple OSS Distributions OSMetaClass::checkMetaCast( 13843ca3bd55SApple OSS Distributions const OSMetaClassBase * check) const 1385c1dac77fSApple OSS Distributions { 1386c1dac77fSApple OSS Distributions const OSMetaClass * const toMeta = this; 1387c1dac77fSApple OSS Distributions const OSMetaClass * fromMeta; 1388c1dac77fSApple OSS Distributions 1389c1dac77fSApple OSS Distributions for (fromMeta = check->getMetaClass();; fromMeta = fromMeta->superClassLink) { 13903ca3bd55SApple OSS Distributions if (toMeta == fromMeta) { 13913ca3bd55SApple OSS Distributions return const_cast<OSMetaClassBase *>(check); // Discard const 13923ca3bd55SApple OSS Distributions } 13933ca3bd55SApple OSS Distributions if (!fromMeta->superClassLink) { 1394c1dac77fSApple OSS Distributions break; 1395c1dac77fSApple OSS Distributions } 13963ca3bd55SApple OSS Distributions } 1397c1dac77fSApple OSS Distributions 1398a5e72196SApple OSS Distributions return NULL; 1399c1dac77fSApple OSS Distributions } 1400c1dac77fSApple OSS Distributions 14013ca3bd55SApple OSS Distributions /********************************************************************* 14023ca3bd55SApple OSS Distributions *********************************************************************/ 1403a5e72196SApple OSS Distributions __dead2 14043ca3bd55SApple OSS Distributions void 14053ca3bd55SApple OSS Distributions OSMetaClass::reservedCalled(int ind) const 1406c1dac77fSApple OSS Distributions { 1407c1dac77fSApple OSS Distributions const char * cname = className->getCStringNoCopy(); 14083ca3bd55SApple OSS Distributions panic("%s::_RESERVED%s%d called.", cname, cname, ind); 1409c1dac77fSApple OSS Distributions } 1410c1dac77fSApple OSS Distributions 14113ca3bd55SApple OSS Distributions /********************************************************************* 14123ca3bd55SApple OSS Distributions *********************************************************************/ 14133ca3bd55SApple OSS Distributions const 14143ca3bd55SApple OSS Distributions OSMetaClass * 14153ca3bd55SApple OSS Distributions OSMetaClass::getSuperClass() const 1416c1dac77fSApple OSS Distributions { 1417c1dac77fSApple OSS Distributions return superClassLink; 1418c1dac77fSApple OSS Distributions } 1419c1dac77fSApple OSS Distributions 14203ca3bd55SApple OSS Distributions /********************************************************************* 14213ca3bd55SApple OSS Distributions *********************************************************************/ 14223ca3bd55SApple OSS Distributions const OSSymbol * 14233ca3bd55SApple OSS Distributions OSMetaClass::getKmodName() const 142414e3d835SApple OSS Distributions { 1425a5e72196SApple OSS Distributions OSKext * myKext = reserved ? reserved->kext : NULL; 14263ca3bd55SApple OSS Distributions if (myKext) { 14273ca3bd55SApple OSS Distributions return myKext->getIdentifier(); 14283ca3bd55SApple OSS Distributions } 14293ca3bd55SApple OSS Distributions return OSSymbol::withCStringNoCopy("unknown"); 143014e3d835SApple OSS Distributions } 143114e3d835SApple OSS Distributions 14323ca3bd55SApple OSS Distributions /********************************************************************* 14333ca3bd55SApple OSS Distributions *********************************************************************/ 1434*bb611c8fSApple OSS Distributions OSKext * 1435*bb611c8fSApple OSS Distributions OSMetaClass::getKext() const 1436*bb611c8fSApple OSS Distributions { 1437*bb611c8fSApple OSS Distributions return reserved ? reserved->kext : NULL; 1438*bb611c8fSApple OSS Distributions } 1439*bb611c8fSApple OSS Distributions 1440*bb611c8fSApple OSS Distributions /********************************************************************* 1441*bb611c8fSApple OSS Distributions *********************************************************************/ 14423ca3bd55SApple OSS Distributions unsigned int 14433ca3bd55SApple OSS Distributions OSMetaClass::getInstanceCount() const 1444c1dac77fSApple OSS Distributions { 1445c1dac77fSApple OSS Distributions return instanceCount; 1446c1dac77fSApple OSS Distributions } 1447c1dac77fSApple OSS Distributions 14483ca3bd55SApple OSS Distributions /********************************************************************* 14493ca3bd55SApple OSS Distributions *********************************************************************/ 14503ca3bd55SApple OSS Distributions /* static */ 14513ca3bd55SApple OSS Distributions void 14523ca3bd55SApple OSS Distributions OSMetaClass::printInstanceCounts() 1453c1dac77fSApple OSS Distributions { 1454c1dac77fSApple OSS Distributions OSCollectionIterator * classes; 1455c1dac77fSApple OSS Distributions OSSymbol * className; 1456c1dac77fSApple OSS Distributions OSMetaClass * meta; 1457c1dac77fSApple OSS Distributions 14583ca3bd55SApple OSS Distributions IOLockLock(sAllClassesLock); 1459c1dac77fSApple OSS Distributions classes = OSCollectionIterator::withCollection(sAllClassesDict); 14603ca3bd55SApple OSS Distributions assert(classes); 1461c1dac77fSApple OSS Distributions 1462c1dac77fSApple OSS Distributions while ((className = (OSSymbol *)classes->getNextObject())) { 1463c1dac77fSApple OSS Distributions meta = (OSMetaClass *)sAllClassesDict->getObject(className); 1464c1dac77fSApple OSS Distributions assert(meta); 1465c1dac77fSApple OSS Distributions 1466c1dac77fSApple OSS Distributions printf("%24s count: %03d x 0x%03x = 0x%06x\n", 1467c1dac77fSApple OSS Distributions className->getCStringNoCopy(), 1468c1dac77fSApple OSS Distributions meta->getInstanceCount(), 1469c1dac77fSApple OSS Distributions meta->getClassSize(), 1470c1dac77fSApple OSS Distributions meta->getInstanceCount() * meta->getClassSize()); 1471c1dac77fSApple OSS Distributions } 1472c1dac77fSApple OSS Distributions printf("\n"); 1473c1dac77fSApple OSS Distributions classes->release(); 14743ca3bd55SApple OSS Distributions IOLockUnlock(sAllClassesLock); 14753ca3bd55SApple OSS Distributions return; 1476c1dac77fSApple OSS Distributions } 1477c1dac77fSApple OSS Distributions 14783ca3bd55SApple OSS Distributions /********************************************************************* 14793ca3bd55SApple OSS Distributions *********************************************************************/ 14803ca3bd55SApple OSS Distributions OSDictionary * 14813ca3bd55SApple OSS Distributions OSMetaClass::getClassDictionary() 1482c1dac77fSApple OSS Distributions { 14833ca3bd55SApple OSS Distributions panic("OSMetaClass::getClassDictionary() is obsoleted.\n"); 1484a5e72196SApple OSS Distributions return NULL; 1485c1dac77fSApple OSS Distributions } 1486c1dac77fSApple OSS Distributions 14873ca3bd55SApple OSS Distributions /********************************************************************* 14883ca3bd55SApple OSS Distributions *********************************************************************/ 14893ca3bd55SApple OSS Distributions bool 14903ca3bd55SApple OSS Distributions OSMetaClass::serialize(__unused OSSerialize * s) const 1491c1dac77fSApple OSS Distributions { 1492368ad365SApple OSS Distributions panic("OSMetaClass::serialize(): Obsoleted\n"); 1493368ad365SApple OSS Distributions return false; 1494c1dac77fSApple OSS Distributions } 1495c1dac77fSApple OSS Distributions 14963ca3bd55SApple OSS Distributions /********************************************************************* 14973ca3bd55SApple OSS Distributions *********************************************************************/ 14983ca3bd55SApple OSS Distributions /* static */ 14993ca3bd55SApple OSS Distributions void 15003ca3bd55SApple OSS Distributions OSMetaClass::serializeClassDictionary(OSDictionary * serializeDictionary) 1501368ad365SApple OSS Distributions { 15023ca3bd55SApple OSS Distributions OSDictionary * classDict = NULL; 15033ca3bd55SApple OSS Distributions 15043ca3bd55SApple OSS Distributions IOLockLock(sAllClassesLock); 1505368ad365SApple OSS Distributions 1506368ad365SApple OSS Distributions classDict = OSDictionary::withCapacity(sAllClassesDict->getCount()); 15073ca3bd55SApple OSS Distributions if (!classDict) { 15083ca3bd55SApple OSS Distributions goto finish; 15093ca3bd55SApple OSS Distributions } 1510368ad365SApple OSS Distributions 1511368ad365SApple OSS Distributions do { 1512368ad365SApple OSS Distributions OSCollectionIterator * classes; 1513368ad365SApple OSS Distributions const OSSymbol * className; 1514368ad365SApple OSS Distributions 1515368ad365SApple OSS Distributions classes = OSCollectionIterator::withCollection(sAllClassesDict); 15163ca3bd55SApple OSS Distributions if (!classes) { 1517368ad365SApple OSS Distributions break; 15183ca3bd55SApple OSS Distributions } 1519368ad365SApple OSS Distributions 1520368ad365SApple OSS Distributions while ((className = (const OSSymbol *)classes->getNextObject())) { 1521368ad365SApple OSS Distributions const OSMetaClass * meta; 1522368ad365SApple OSS Distributions OSNumber * count; 1523368ad365SApple OSS Distributions 1524368ad365SApple OSS Distributions meta = (OSMetaClass *)sAllClassesDict->getObject(className); 1525368ad365SApple OSS Distributions count = OSNumber::withNumber(meta->getInstanceCount(), 32); 1526368ad365SApple OSS Distributions if (count) { 1527368ad365SApple OSS Distributions classDict->setObject(className, count); 1528368ad365SApple OSS Distributions count->release(); 1529368ad365SApple OSS Distributions } 1530368ad365SApple OSS Distributions } 1531368ad365SApple OSS Distributions classes->release(); 1532368ad365SApple OSS Distributions 1533368ad365SApple OSS Distributions serializeDictionary->setObject("Classes", classDict); 1534368ad365SApple OSS Distributions } while (0); 1535368ad365SApple OSS Distributions 15363ca3bd55SApple OSS Distributions finish: 153788cc0b97SApple OSS Distributions OSSafeReleaseNULL(classDict); 1538368ad365SApple OSS Distributions 15393ca3bd55SApple OSS Distributions IOLockUnlock(sAllClassesLock); 15403ca3bd55SApple OSS Distributions 15413ca3bd55SApple OSS Distributions return; 1542368ad365SApple OSS Distributions } 15430f3703acSApple OSS Distributions 15440f3703acSApple OSS Distributions 15450f3703acSApple OSS Distributions /********************************************************************* 15460f3703acSApple OSS Distributions *********************************************************************/ 15470f3703acSApple OSS Distributions 15480f3703acSApple OSS Distributions #if IOTRACKING 15490f3703acSApple OSS Distributions 1550a5e72196SApple OSS Distributions void * 1551a5e72196SApple OSS Distributions OSMetaClass::trackedNew(size_t size) 15520f3703acSApple OSS Distributions { 15530f3703acSApple OSS Distributions IOTracking * mem; 15540f3703acSApple OSS Distributions 15550f3703acSApple OSS Distributions mem = (typeof(mem))kalloc_tag_bt(size + sizeof(IOTracking), VM_KERN_MEMORY_LIBKERN); 15560f3703acSApple OSS Distributions assert(mem); 1557a5e72196SApple OSS Distributions if (!mem) { 1558a5e72196SApple OSS Distributions return mem; 1559a5e72196SApple OSS Distributions } 15600f3703acSApple OSS Distributions 15610f3703acSApple OSS Distributions memset(mem, 0, size + sizeof(IOTracking)); 15620f3703acSApple OSS Distributions mem++; 15630f3703acSApple OSS Distributions 15640f3703acSApple OSS Distributions OSIVAR_ACCUMSIZE(size); 15650f3703acSApple OSS Distributions 1566a5e72196SApple OSS Distributions return mem; 15670f3703acSApple OSS Distributions } 15680f3703acSApple OSS Distributions 1569a5e72196SApple OSS Distributions void 1570a5e72196SApple OSS Distributions OSMetaClass::trackedDelete(void * instance, size_t size) 15710f3703acSApple OSS Distributions { 15720f3703acSApple OSS Distributions IOTracking * mem = (typeof(mem))instance; mem--; 15730f3703acSApple OSS Distributions 15740f3703acSApple OSS Distributions kfree(mem, size + sizeof(IOTracking)); 15750f3703acSApple OSS Distributions OSIVAR_ACCUMSIZE(-size); 15760f3703acSApple OSS Distributions } 15770f3703acSApple OSS Distributions 1578a5e72196SApple OSS Distributions void 1579a5e72196SApple OSS Distributions OSMetaClass::trackedInstance(OSObject * instance) const 15800f3703acSApple OSS Distributions { 15810f3703acSApple OSS Distributions IOTracking * mem = (typeof(mem))instance; mem--; 15820f3703acSApple OSS Distributions 1583a5e72196SApple OSS Distributions return IOTrackingAdd(reserved->tracking, mem, classSize, false, VM_KERN_MEMORY_NONE); 15840f3703acSApple OSS Distributions } 15850f3703acSApple OSS Distributions 1586a5e72196SApple OSS Distributions void 1587a5e72196SApple OSS Distributions OSMetaClass::trackedFree(OSObject * instance) const 15880f3703acSApple OSS Distributions { 15890f3703acSApple OSS Distributions IOTracking * mem = (typeof(mem))instance; mem--; 15900f3703acSApple OSS Distributions 1591a5e72196SApple OSS Distributions return IOTrackingRemove(reserved->tracking, mem, classSize); 15920f3703acSApple OSS Distributions } 15930f3703acSApple OSS Distributions 1594a5e72196SApple OSS Distributions void 1595a5e72196SApple OSS Distributions OSMetaClass::trackedAccumSize(OSObject * instance, size_t size) const 15960f3703acSApple OSS Distributions { 15970f3703acSApple OSS Distributions IOTracking * mem = (typeof(mem))instance; mem--; 15980f3703acSApple OSS Distributions 1599a5e72196SApple OSS Distributions return IOTrackingAccumSize(reserved->tracking, mem, size); 16000f3703acSApple OSS Distributions } 16010f3703acSApple OSS Distributions 1602a5e72196SApple OSS Distributions IOTrackingQueue * 1603a5e72196SApple OSS Distributions OSMetaClass::getTracking() const 16040f3703acSApple OSS Distributions { 1605a5e72196SApple OSS Distributions return reserved->tracking; 16060f3703acSApple OSS Distributions } 16070f3703acSApple OSS Distributions 16080f3703acSApple OSS Distributions #endif /* IOTRACKING */ 1609