X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/3e170ce000f1506b7b5d2c5c7faec85ceabb573d..5ba3f43ea354af8ad55bea84372a2bc834d8757c:/libkern/c%20%20/OSMetaClass.cpp/apple/xnu.git/blobdiff_plain/3e170ce000f1506b7b5d2c5c7faec85ceabb573d..5ba3f43ea354af8ad55bea84372a2bc834d8757c:/libkern/c++/OSMetaClass.cpp diff --git a/libkern/c++/OSMetaClass.cpp b/libkern/c++/OSMetaClass.cpp index b32ab8c9b..3d7c2f6e4 100644 --- a/libkern/c++/OSMetaClass.cpp +++ b/libkern/c++/OSMetaClass.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2006 Apple Inc. All rights reserved. + * Copyright (c) 2000-2016 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -110,6 +110,7 @@ IOLock * sStalledClassesLock = NULL; struct ExpansionData { OSOrderedSet * instances; OSKext * kext; + uint32_t retain; #if IOTRACKING IOTrackingQueue * tracking; #endif @@ -392,7 +393,19 @@ OSMetaClass::OSMetaClass( reserved = IONew(ExpansionData, 1); bzero(reserved, sizeof(ExpansionData)); #if IOTRACKING - reserved->tracking = IOTrackingQueueAlloc(inClassName, inClassSize, 0, true); + uint32_t numSiteQs = 0; + if ((this == &OSSymbol ::gMetaClass) + || (this == &OSString ::gMetaClass) + || (this == &OSNumber ::gMetaClass) + || (this == &OSString ::gMetaClass) + || (this == &OSData ::gMetaClass) + || (this == &OSDictionary::gMetaClass) + || (this == &OSArray ::gMetaClass) + || (this == &OSSet ::gMetaClass)) numSiteQs = 27; + + reserved->tracking = IOTrackingQueueAlloc(inClassName, (uintptr_t) this, + inClassSize, 0, kIOTrackingQueueTypeAlloc, + numSiteQs); #endif /* Hack alert: We are just casting inClassName and storing it in @@ -591,6 +604,7 @@ OSMetaClass::postModLoad(void * loadHandle) case kNoDictionaries: sBootstrapState = kMakingDictionaries; // No break; fall through + [[clang::fallthrough]]; case kMakingDictionaries: sAllClassesDict = OSDictionary::withCapacity(kClassCapacityIncrement); @@ -600,7 +614,8 @@ OSMetaClass::postModLoad(void * loadHandle) } sAllClassesDict->setOptions(OSCollection::kSort, OSCollection::kSort); - // No break; fall through + // No break; fall through + [[clang::fallthrough]]; case kCompletedBootstrap: { @@ -642,7 +657,11 @@ OSMetaClass::postModLoad(void * loadHandle) /* Log this error here so we can include the class name. * xxx - we should look up the other kext that defines the class */ +#if CONFIG_EMBEDDED + panic( +#else OSKextLog(myKext, kOSMetaClassLogSpec, +#endif /* CONFIG_EMBEDDED */ "OSMetaClass: Kext %s class %s is a duplicate;" "kext %s already has a class by that name.", sStalled->kextIdentifier, (const char *)me->className, @@ -711,8 +730,8 @@ finish: OSMetaClassLogErrorForKext(result, myKext); } - OSSafeRelease(myKextName); - OSSafeRelease(myKext); + OSSafeReleaseNULL(myKextName); + OSSafeReleaseNULL(myKext); if (sStalled) { OSMETA_ACCUMSIZE(-(sStalled->capacity * sizeof(OSMetaClass *) + @@ -774,7 +793,7 @@ OSMetaClass::modHasInstance(const char * kextIdentifier) result = theKext->hasOSMetaClassInstances(); finish: - OSSafeRelease(theKext); + OSSafeReleaseNULL(theKext); return result; } @@ -930,6 +949,43 @@ OSMetaClass::considerUnloads() OSKext::considerUnloads(); } +/********************************************************************* +*********************************************************************/ +bool +OSMetaClass::removeClasses(OSCollection * metaClasses) +{ + OSCollectionIterator * classIterator; + OSMetaClass * checkClass; + bool result; + + classIterator = OSCollectionIterator::withCollection(metaClasses); + if (!classIterator) return (false); + + IOLockLock(sAllClassesLock); + + result = false; + do + { + while ((checkClass = (OSMetaClass *)classIterator->getNextObject()) + && !checkClass->getInstanceCount() + && !checkClass->reserved->retain) {} + if (checkClass) break; + classIterator->reset(); + while ((checkClass = (OSMetaClass *)classIterator->getNextObject())) + { + sAllClassesDict->removeObject(checkClass->className); + } + result = true; + } + while (false); + + IOLockUnlock(sAllClassesLock); + OSSafeReleaseNULL(classIterator); + + return (result); +} + + /********************************************************************* *********************************************************************/ const OSMetaClass * @@ -950,17 +1006,48 @@ OSMetaClass::getMetaClassWithName(const OSSymbol * name) return retMeta; } +/********************************************************************* +*********************************************************************/ +const OSMetaClass * +OSMetaClass::copyMetaClassWithName(const OSSymbol * name) +{ + const OSMetaClass * meta; + + if (!name) return (0); + + meta = 0; + IOLockLock(sAllClassesLock); + if (sAllClassesDict) { + meta = (OSMetaClass *) sAllClassesDict->getObject(name); + if (meta) OSIncrementAtomic(&meta->reserved->retain); + } + IOLockUnlock(sAllClassesLock); + + return (meta); +} + +/********************************************************************* +*********************************************************************/ +void +OSMetaClass::releaseMetaClass() const +{ + OSDecrementAtomic(&reserved->retain); +} + /********************************************************************* *********************************************************************/ OSObject * OSMetaClass::allocClassWithName(const OSSymbol * name) { - OSObject * result = 0; - - const OSMetaClass * const meta = getMetaClassWithName(name); + const OSMetaClass * meta; + OSObject * result; - if (meta) { + result = 0; + meta = copyMetaClassWithName(name); + if (meta) + { result = meta->alloc(); + meta->releaseMetaClass(); } return result; @@ -1191,7 +1278,7 @@ OSMetaClass::serializeClassDictionary(OSDictionary * serializeDictionary) } while (0); finish: - OSSafeRelease(classDict); + OSSafeReleaseNULL(classDict); IOLockUnlock(sAllClassesLock); @@ -1232,7 +1319,7 @@ void OSMetaClass::trackedInstance(OSObject * instance) const { IOTracking * mem = (typeof(mem)) instance; mem--; - return (IOTrackingAdd(reserved->tracking, mem, classSize, false)); + return (IOTrackingAdd(reserved->tracking, mem, classSize, false, VM_KERN_MEMORY_NONE)); } void OSMetaClass::trackedFree(OSObject * instance) const @@ -1254,4 +1341,4 @@ IOTrackingQueue * OSMetaClass::getTracking() const return (reserved->tracking); } -#endif /* IOTRACKING */ \ No newline at end of file +#endif /* IOTRACKING */