Loading...
--- xnu/xnu-1456.1.26/libkern/c++/OSMetaClass.cpp
+++ xnu/xnu-344/libkern/c++/OSMetaClass.cpp
@@ -1,239 +1,164 @@
/*
- * Copyright (c) 2000-2006 Apple Inc. All rights reserved.
+ * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
*
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
+ * @APPLE_LICENSE_HEADER_START@
*
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License"). You may not use this file except in compliance with the
+ * License. Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
*
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
*
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
+ * @APPLE_LICENSE_HEADER_END@
*/
/* OSMetaClass.cpp created by gvdl on Fri 1998-11-17 */
#include <string.h>
+#include <sys/systm.h>
#include <libkern/OSReturn.h>
#include <libkern/c++/OSMetaClass.h>
+
#include <libkern/c++/OSObject.h>
-#include <libkern/c++/OSKext.h>
-
#include <libkern/c++/OSCollectionIterator.h>
#include <libkern/c++/OSDictionary.h>
#include <libkern/c++/OSArray.h>
-#include <libkern/c++/OSSet.h>
+#include <libkern/c++/OSSet.h>
#include <libkern/c++/OSSymbol.h>
#include <libkern/c++/OSNumber.h>
#include <libkern/c++/OSSerialize.h>
-
#include <libkern/c++/OSLib.h>
#include <libkern/OSAtomic.h>
-#include <IOKit/pwr_mgt/RootDomain.h>
-#include <IOKit/IOMessage.h>
-#include <IOKit/IOLib.h>
-
__BEGIN_DECLS
-#include <sys/systm.h>
#include <mach/mach_types.h>
-#include <kern/locks.h>
+#include <mach/etap_events.h>
+#include <kern/lock.h>
#include <kern/clock.h>
#include <kern/thread_call.h>
#include <kern/host.h>
+#include <mach/kmod.h>
#include <mach/mach_interface.h>
-#if PRAGMA_MARK
-#pragma mark Macros
-#endif /* PRAGMA_MARK */
-/*********************************************************************
-* Macros
-*********************************************************************/
+extern void OSRuntimeUnloadCPP(kmod_info_t *ki, void *);
+
#if OSALLOCDEBUG
extern int debug_container_malloc_size;
-#define ACCUMSIZE(s) do { debug_container_malloc_size += (s); } while (0)
+#define ACCUMSIZE(s) do { debug_container_malloc_size += (s); } while(0)
#else
#define ACCUMSIZE(s)
#endif /* OSALLOCDEBUG */
__END_DECLS
-#if PRAGMA_MARK
-#pragma mark Internal constants & data structs
-#endif /* PRAGMA_MARK */
-/*********************************************************************
-* Internal constants & data structs
-*********************************************************************/
-OSKextLogSpec kOSMetaClassLogSpec =
- kOSKextLogErrorLevel |
- kOSKextLogLoadFlag |
- kOSKextLogKextBookkeepingFlag;
-
static enum {
kCompletedBootstrap = 0,
- kNoDictionaries = 1,
+ kNoDictionaries = 1,
kMakingDictionaries = 2
} sBootstrapState = kNoDictionaries;
-static const int kClassCapacityIncrement = 40;
-static const int kKModCapacityIncrement = 10;
-static OSDictionary * sAllClassesDict;
-IOLock * sAllClassesLock = NULL;
-
-/*
- * While loading a kext and running all its constructors to register
- * all OSMetaClass classes, the classes are queued up here. Only one
- * kext can be in flight at a time, guarded by sStalledClassesLock
- */
+static const int kClassCapacityIncrement = 40;
+static const int kKModCapacityIncrement = 10;
+static OSDictionary *sAllClassesDict, *sKModClassesDict;
+
+static mutex_t *loadLock;
static struct StalledData {
- const char * kextIdentifier;
- OSReturn result;
- unsigned int capacity;
- unsigned int count;
- OSMetaClass ** classes;
-} * sStalled;
-IOLock * sStalledClassesLock = NULL;
-
-#if PRAGMA_MARK
-#pragma mark OSMetaClassBase
-#endif /* PRAGMA_MARK */
-/*********************************************************************
-* OSMetaClassBase.
-*********************************************************************/
-
-/*********************************************************************
-* Reserved vtable functions.
-*********************************************************************/
+ const char *kmodName;
+ OSReturn result;
+ unsigned int capacity;
+ unsigned int count;
+ OSMetaClass **classes;
+} *sStalled;
+
+static unsigned int sConsiderUnloadDelay = 60; /* secs */
+
+static const char OSMetaClassBasePanicMsg[] =
+ "OSMetaClassBase::_RESERVEDOSMetaClassBase%d called\n";
+
#if SLOT_USED
void OSMetaClassBase::_RESERVEDOSMetaClassBase0()
- { panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 0); }
+ { panic(OSMetaClassBasePanicMsg, 0); }
void OSMetaClassBase::_RESERVEDOSMetaClassBase1()
- { panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 1); }
+ { panic(OSMetaClassBasePanicMsg, 1); }
void OSMetaClassBase::_RESERVEDOSMetaClassBase2()
- { panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 2); }
+ { panic(OSMetaClassBasePanicMsg, 2); }
#endif /* SLOT_USED */
// As these slots are used move them up inside the #if above
void OSMetaClassBase::_RESERVEDOSMetaClassBase3()
- { panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 3); }
+ { panic(OSMetaClassBasePanicMsg, 3); }
void OSMetaClassBase::_RESERVEDOSMetaClassBase4()
- { panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 4); }
+ { panic(OSMetaClassBasePanicMsg, 4); }
void OSMetaClassBase::_RESERVEDOSMetaClassBase5()
- { panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 5); }
+ { panic(OSMetaClassBasePanicMsg, 5); }
void OSMetaClassBase::_RESERVEDOSMetaClassBase6()
- { panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 6); }
+ { panic(OSMetaClassBasePanicMsg, 6); }
-/*********************************************************************
-* These used to be inline in the header but gcc didn't believe us
-* Now we MUST pull the inline out at least until the compiler is
-* repaired.
-*
-* Helper inlines for runtime type preprocessor macros
-*********************************************************************/
-
-/*********************************************************************
-*********************************************************************/
-OSMetaClassBase *
-OSMetaClassBase::safeMetaCast(
- const OSMetaClassBase * me,
- const OSMetaClass * toType)
-{
- return (me)? me->metaCast(toType) : 0;
-}
-
-/*********************************************************************
-*********************************************************************/
-bool
-OSMetaClassBase::checkTypeInst(
- const OSMetaClassBase * inst,
- const OSMetaClassBase * typeinst)
-{
- const OSMetaClass * toType = OSTypeIDInst(typeinst);
+/*
+ * These used to be inline in the header but gcc didn't believe us
+ * Now we MUST pull the inline out at least until the compiler is
+ * repaired.
+ */
+// Helper inlines for runtime type preprocessor macros
+OSMetaClassBase *OSMetaClassBase::
+safeMetaCast(const OSMetaClassBase *me, const OSMetaClass *toType)
+ { return (me)? me->metaCast(toType) : 0; }
+
+bool OSMetaClassBase::
+checkTypeInst(const OSMetaClassBase *inst, const OSMetaClassBase *typeinst)
+{
+ const OSMetaClass *toType = OSTypeIDInst(typeinst);
return typeinst && inst && (0 != inst->metaCast(toType));
}
-/*********************************************************************
-*********************************************************************/
-void OSMetaClassBase::
-initialize()
-{
- sAllClassesLock = IOLockAlloc();
- sStalledClassesLock = IOLockAlloc();
-}
-
-/*********************************************************************
-* If you need this slot you had better setup an IOCTL style interface.
-* 'Cause the whole kernel world depends on OSMetaClassBase and YOU
-* CANT change the VTABLE size ever.
-*********************************************************************/
-void
-OSMetaClassBase::_RESERVEDOSMetaClassBase7()
-{ panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 7); }
-
-/*********************************************************************
-*********************************************************************/
+
+// If you need this slot you had better setup an IOCTL style interface.
+// 'Cause the whole kernel world depends on OSMetaClassBase and YOU
+// CANT change the VTABLE size ever.
+void OSMetaClassBase::_RESERVEDOSMetaClassBase7()
+ { panic(OSMetaClassBasePanicMsg, 7); }
+
OSMetaClassBase::OSMetaClassBase()
{
}
-/*********************************************************************
-*********************************************************************/
OSMetaClassBase::~OSMetaClassBase()
{
- void ** thisVTable;
+ void **thisVTable;
thisVTable = (void **) this;
*thisVTable = (void *) -1UL;
}
-/*********************************************************************
-*********************************************************************/
-bool
-OSMetaClassBase::isEqualTo(const OSMetaClassBase * anObj) const
+bool OSMetaClassBase::isEqualTo(const OSMetaClassBase *anObj) const
{
return this == anObj;
}
-/*********************************************************************
-*********************************************************************/
-OSMetaClassBase *
-OSMetaClassBase::metaCast(const OSMetaClass * toMeta) const
+OSMetaClassBase *OSMetaClassBase::metaCast(const OSMetaClass *toMeta) const
{
return toMeta->checkMetaCast(this);
}
-/*********************************************************************
-*********************************************************************/
-OSMetaClassBase *
-OSMetaClassBase::metaCast(const OSSymbol * toMetaSymb) const
+OSMetaClassBase *OSMetaClassBase::metaCast(const OSSymbol *toMetaSymb) const
{
return OSMetaClass::checkMetaCastWithName(toMetaSymb, this);
}
-/*********************************************************************
-*********************************************************************/
-OSMetaClassBase *
-OSMetaClassBase::metaCast(const OSString * toMetaStr) const
-{
- const OSSymbol * tempSymb = OSSymbol::withString(toMetaStr);
- OSMetaClassBase * ret = 0;
+OSMetaClassBase *OSMetaClassBase::metaCast(const OSString *toMetaStr) const
+{
+ const OSSymbol *tempSymb = OSSymbol::withString(toMetaStr);
+ OSMetaClassBase *ret = 0;
if (tempSymb) {
ret = metaCast(tempSymb);
tempSymb->release();
@@ -241,13 +166,10 @@
return ret;
}
-/*********************************************************************
-*********************************************************************/
-OSMetaClassBase *
-OSMetaClassBase::metaCast(const char * toMetaCStr) const
-{
- const OSSymbol * tempSymb = OSSymbol::withCString(toMetaCStr);
- OSMetaClassBase * ret = 0;
+OSMetaClassBase *OSMetaClassBase::metaCast(const char *toMetaCStr) const
+{
+ const OSSymbol *tempSymb = OSSymbol::withCString(toMetaCStr);
+ OSMetaClassBase *ret = 0;
if (tempSymb) {
ret = metaCast(tempSymb);
tempSymb->release();
@@ -255,22 +177,16 @@
return ret;
}
-#if PRAGMA_MARK
-#pragma mark OSMetaClassMeta
-#endif /* PRAGMA_MARK */
-/*********************************************************************
-* OSMetaClassMeta - the bootstrap metaclass of OSMetaClass
-*********************************************************************/
class OSMetaClassMeta : public OSMetaClass
{
public:
OSMetaClassMeta();
- OSObject * alloc() const;
+ OSObject *alloc() const;
};
OSMetaClassMeta::OSMetaClassMeta()
: OSMetaClass("OSMetaClass", 0, sizeof(OSMetaClass))
{ }
-OSObject * OSMetaClassMeta::alloc() const { return 0; }
+OSObject *OSMetaClassMeta::alloc() const { return 0; }
static OSMetaClassMeta sOSMetaClassMeta;
@@ -278,756 +194,635 @@
const OSMetaClass * OSMetaClass::getMetaClass() const
{ return &sOSMetaClassMeta; }
-#if PRAGMA_MARK
-#pragma mark OSMetaClass
-#endif /* PRAGMA_MARK */
-/*********************************************************************
-* OSMetaClass
-*********************************************************************/
-
-/*********************************************************************
-* Reserved functions.
-*********************************************************************/
+static const char OSMetaClassPanicMsg[] =
+ "OSMetaClass::_RESERVEDOSMetaClass%d called\n";
+
void OSMetaClass::_RESERVEDOSMetaClass0()
- { panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 0); }
+ { panic(OSMetaClassPanicMsg, 0); }
void OSMetaClass::_RESERVEDOSMetaClass1()
- { panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 1); }
+ { panic(OSMetaClassPanicMsg, 1); }
void OSMetaClass::_RESERVEDOSMetaClass2()
- { panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 2); }
+ { panic(OSMetaClassPanicMsg, 2); }
void OSMetaClass::_RESERVEDOSMetaClass3()
- { panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 3); }
+ { panic(OSMetaClassPanicMsg, 3); }
void OSMetaClass::_RESERVEDOSMetaClass4()
- { panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 4); }
+ { panic(OSMetaClassPanicMsg, 4); }
void OSMetaClass::_RESERVEDOSMetaClass5()
- { panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 5); }
+ { panic(OSMetaClassPanicMsg, 5); }
void OSMetaClass::_RESERVEDOSMetaClass6()
- { panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 6); }
+ { panic(OSMetaClassPanicMsg, 6); }
void OSMetaClass::_RESERVEDOSMetaClass7()
- { panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 7); }
-
-/*********************************************************************
-*********************************************************************/
-static void
-OSMetaClassLogErrorForKext(
- OSReturn error,
- OSKext * aKext)
-{
- const char * message = NULL;
-
- switch (error) {
+ { panic(OSMetaClassPanicMsg, 7); }
+
+void OSMetaClass::logError(OSReturn result)
+{
+ const char *msg;
+
+ switch (result) {
+ case kOSMetaClassNoInit:
+ msg="OSMetaClass::preModLoad wasn't called, runtime internal error";
+ break;
+ case kOSMetaClassNoDicts:
+ msg="Allocation failure for Metaclass internal dictionaries"; break;
+ case kOSMetaClassNoKModSet:
+ msg="Allocation failure for internal kmodule set"; break;
+ case kOSMetaClassNoInsKModSet:
+ msg="Can't insert the KMod set into the module dictionary"; break;
+ case kOSMetaClassDuplicateClass:
+ msg="Duplicate class"; break;
+ case kOSMetaClassNoSuper:
+ msg="Can't associate a class with its super class"; break;
+ case kOSMetaClassInstNoSuper:
+ msg="Instance construction, unknown super class."; break;
+ default:
+ case kOSMetaClassInternal:
+ msg="runtime internal error"; break;
case kOSReturnSuccess:
- return;
- case kOSMetaClassNoInit: // xxx - never returned; logged at fail site
- message = "OSMetaClass: preModLoad() wasn't called (runtime internal error).";
- break;
- case kOSMetaClassNoDicts:
- message = "OSMetaClass: Allocation failure for OSMetaClass internal dictionaries.";
- break;
- case kOSMetaClassNoKModSet:
- message = "OSMetaClass: Allocation failure for internal kext recording set/set missing.";
- break;
- case kOSMetaClassNoInsKModSet:
- message = "OSMetaClass: Failed to record class in kext.";
- break;
- case kOSMetaClassDuplicateClass:
- message = "OSMetaClass: Duplicate class encountered.";
- break;
- case kOSMetaClassNoSuper: // xxx - never returned
- message = "OSMetaClass: Can't associate a class with its superclass.";
- break;
- case kOSMetaClassInstNoSuper: // xxx - never returned
- message = "OSMetaClass: Instance construction error; unknown superclass.";
- break;
- case kOSMetaClassNoKext:
- message = "OSMetaClass: Kext not found for metaclass.";
- break;
- case kOSMetaClassInternal:
- default:
- message = "OSMetaClass: Runtime internal error.";
- break;
- }
-
- if (message) {
- OSKextLog(aKext, kOSMetaClassLogSpec, "%s", message);
- }
- return;
-}
-
-void
-OSMetaClass::logError(OSReturn error)
-{
- OSMetaClassLogErrorForKext(error, NULL);
-}
-
-/*********************************************************************
-* The core constructor for a MetaClass (defined with this name always
-* but within the scope of its represented class).
-*
-* MetaClass constructors are invoked in OSRuntimeInitializeCPP(),
-* in between calls to OSMetaClass::preModLoad(), which sets up for
-* registration, and OSMetaClass::postModLoad(), which actually
-* records all the class/kext relationships of the new MetaClasses.
-*********************************************************************/
-OSMetaClass::OSMetaClass(
- const char * inClassName,
- const OSMetaClass * inSuperClass,
- unsigned int inClassSize)
+ return;
+ }
+ printf("%s\n", msg);
+}
+
+OSMetaClass::OSMetaClass(const char *inClassName,
+ const OSMetaClass *inSuperClass,
+ unsigned int inClassSize)
{
instanceCount = 0;
classSize = inClassSize;
superClassLink = inSuperClass;
- /* Hack alert: We are just casting inClassName and storing it in
- * an OSString * instance variable. This may be because you can't
- * create C++ objects in static constructors, but I really don't know!
- */
- className = (const OSSymbol *)inClassName;
-
- // sStalledClassesLock taken in preModLoad
+ className = (const OSSymbol *) inClassName;
+
if (!sStalled) {
- /* There's no way we can look up the kext here, unfortunately.
- */
- OSKextLog(/* kext */ NULL, kOSMetaClassLogSpec,
- "OSMetaClass: preModLoad() wasn't called for class %s "
- "(runtime internal error).",
- inClassName);
+ printf("OSMetaClass::preModLoad wasn't called for %s, "
+ "runtime internal error\n", inClassName);
} else if (!sStalled->result) {
- // Grow stalled array if neccessary
- if (sStalled->count >= sStalled->capacity) {
- OSMetaClass **oldStalled = sStalled->classes;
- int oldSize = sStalled->capacity * sizeof(OSMetaClass *);
- int newSize = oldSize
- + kKModCapacityIncrement * sizeof(OSMetaClass *);
-
- sStalled->classes = (OSMetaClass **)kalloc(newSize);
- if (!sStalled->classes) {
- sStalled->classes = oldStalled;
- sStalled->result = kOSMetaClassNoTempData;
- return;
- }
-
- sStalled->capacity += kKModCapacityIncrement;
- memmove(sStalled->classes, oldStalled, oldSize);
- kfree(oldStalled, oldSize);
- ACCUMSIZE(newSize - oldSize);
- }
-
- sStalled->classes[sStalled->count++] = this;
- }
-}
-
-/*********************************************************************
-*********************************************************************/
+ // Grow stalled array if neccessary
+ if (sStalled->count >= sStalled->capacity) {
+ OSMetaClass **oldStalled = sStalled->classes;
+ int oldSize = sStalled->capacity * sizeof(OSMetaClass *);
+ int newSize = oldSize
+ + kKModCapacityIncrement * sizeof(OSMetaClass *);
+
+ sStalled->classes = (OSMetaClass **) kalloc(newSize);
+ if (!sStalled->classes) {
+ sStalled->classes = oldStalled;
+ sStalled->result = kOSMetaClassNoTempData;
+ return;
+ }
+
+ sStalled->capacity += kKModCapacityIncrement;
+ memmove(sStalled->classes, oldStalled, oldSize);
+ kfree((vm_offset_t)oldStalled, oldSize);
+ ACCUMSIZE(newSize - oldSize);
+ }
+
+ sStalled->classes[sStalled->count++] = this;
+ }
+}
+
OSMetaClass::~OSMetaClass()
{
- OSKext * myKext = (OSKext *)reserved; // do not release
-
- /* Hack alert: 'className' is a C string during early C++ init, and
- * is converted to a real OSSymbol only when we record the OSKext in
- * OSMetaClass::postModLoad(). So only do this bit if we have an OSKext.
- * We can't safely cast or check 'className'.
- *
- * Also, release className *after* calling into the kext,
- * as removeClass() may access className.
- */
- IOLockLock(sAllClassesLock);
- if (sAllClassesDict) {
- if (myKext) {
- sAllClassesDict->removeObject(className);
- } else {
- sAllClassesDict->removeObject((char *)className);
- }
- }
- IOLockUnlock(sAllClassesLock);
-
- if (myKext) {
- if (myKext->removeClass(this) != kOSReturnSuccess) {
- // xxx - what can we do?
- }
- className->release();
- }
-
- // sStalledClassesLock taken in preModLoad
+ do {
+ OSCollectionIterator *iter;
+
+ if (sAllClassesDict)
+ sAllClassesDict->removeObject(className);
+
+ iter = OSCollectionIterator::withCollection(sKModClassesDict);
+ if (!iter)
+ break;
+
+ OSSymbol *iterKey;
+ while ( (iterKey = (OSSymbol *) iter->getNextObject()) ) {
+ OSSet *kmodClassSet;
+ kmodClassSet = (OSSet *) sKModClassesDict->getObject(iterKey);
+ if (kmodClassSet && kmodClassSet->containsObject(this)) {
+ kmodClassSet->removeObject(this);
+ break;
+ }
+ }
+ iter->release();
+ } while (false);
+
if (sStalled) {
+ unsigned int i;
+
+ // First pass find class in stalled list
+ for (i = 0; i < sStalled->count; i++)
+ if (this == sStalled->classes[i])
+ break;
+
+ if (i < sStalled->count) {
+ sStalled->count--;
+ if (i < sStalled->count)
+ memmove(&sStalled->classes[i], &sStalled->classes[i+1],
+ (sStalled->count - i) * sizeof(OSMetaClass *));
+ }
+ return;
+ }
+}
+
+void *OSMetaClass::operator new(size_t size) { return 0; }
+void OSMetaClass::retain() const { }
+void OSMetaClass::release() const { }
+void OSMetaClass::release(int when) const { }
+void OSMetaClass::taggedRetain(const void *tag) const { }
+void OSMetaClass::taggedRelease(const void *tag) const { }
+void OSMetaClass::taggedRelease(const void *tag, const int when) const { }
+int OSMetaClass::getRetainCount() const { return 0; }
+
+const char *OSMetaClass::getClassName() const
+{
+ return className->getCStringNoCopy();
+}
+
+unsigned int OSMetaClass::getClassSize() const
+{
+ return classSize;
+}
+
+void *OSMetaClass::preModLoad(const char *kmodName)
+{
+ if (!loadLock) {
+ loadLock = mutex_alloc(ETAP_IO_AHA);
+ mutex_lock(loadLock);
+ }
+ else
+ mutex_lock(loadLock);
+
+ sStalled = (StalledData *) kalloc(sizeof(*sStalled));
+ if (sStalled) {
+ sStalled->classes = (OSMetaClass **)
+ kalloc(kKModCapacityIncrement * sizeof(OSMetaClass *));
+ if (!sStalled->classes) {
+ kfree((vm_offset_t) sStalled, sizeof(*sStalled));
+ return 0;
+ }
+ ACCUMSIZE((kKModCapacityIncrement * sizeof(OSMetaClass *)) + sizeof(*sStalled));
+
+ sStalled->result = kOSReturnSuccess;
+ sStalled->capacity = kKModCapacityIncrement;
+ sStalled->count = 0;
+ sStalled->kmodName = kmodName;
+ bzero(sStalled->classes, kKModCapacityIncrement * sizeof(OSMetaClass *));
+ }
+
+ return sStalled;
+}
+
+bool OSMetaClass::checkModLoad(void *loadHandle)
+{
+ return sStalled && loadHandle == sStalled
+ && sStalled->result == kOSReturnSuccess;
+}
+
+OSReturn OSMetaClass::postModLoad(void *loadHandle)
+{
+ OSReturn result = kOSReturnSuccess;
+ OSSet *kmodSet = 0;
+
+ if (!sStalled || loadHandle != sStalled) {
+ logError(kOSMetaClassInternal);
+ return kOSMetaClassInternal;
+ }
+
+ if (sStalled->result)
+ result = sStalled->result;
+ else switch (sBootstrapState) {
+ case kNoDictionaries:
+ sBootstrapState = kMakingDictionaries;
+ // No break; fall through
+
+ case kMakingDictionaries:
+ sKModClassesDict = OSDictionary::withCapacity(kKModCapacityIncrement);
+ sAllClassesDict = OSDictionary::withCapacity(kClassCapacityIncrement);
+ if (!sAllClassesDict || !sKModClassesDict) {
+ result = kOSMetaClassNoDicts;
+ break;
+ }
+ // No break; fall through
+
+ case kCompletedBootstrap:
+ {
unsigned int i;
-
- /* First pass find class in stalled list. If we find it that means
- * we started C++ init with constructors but now we're tearing down
- * because of some failure.
- */
- for (i = 0; i < sStalled->count; i++) {
- if (this == sStalled->classes[i]) {
+
+ if (!sStalled->count)
+ break; // Nothing to do so just get out
+
+ // First pass checking classes aren't already loaded
+ for (i = 0; i < sStalled->count; i++) {
+ OSMetaClass *me = sStalled->classes[i];
+
+ if (0 != sAllClassesDict->getObject((const char *) me->className)) {
+ printf("Class \"%s\" is duplicate\n", (const char *) me->className);
+ result = kOSMetaClassDuplicateClass;
break;
}
+ }
+ if (i != sStalled->count)
+ break;
+
+ kmodSet = OSSet::withCapacity(sStalled->count);
+ if (!kmodSet) {
+ result = kOSMetaClassNoKModSet;
+ break;
+ }
+
+ if (!sKModClassesDict->setObject(sStalled->kmodName, kmodSet)) {
+ result = kOSMetaClassNoInsKModSet;
+ break;
+ }
+
+ // Second pass symbolling strings and inserting classes in dictionary
+ for (unsigned int i = 0; i < sStalled->count; i++) {
+ OSMetaClass *me = sStalled->classes[i];
+ me->className =
+ OSSymbol::withCStringNoCopy((const char *) me->className);
+
+ sAllClassesDict->setObject(me->className, me);
+ kmodSet->setObject(me);
+ }
+ sBootstrapState = kCompletedBootstrap;
+ break;
+ }
+
+ default:
+ result = kOSMetaClassInternal;
+ break;
+ }
+
+ if (kmodSet)
+ kmodSet->release();
+
+ if (sStalled) {
+ ACCUMSIZE(-(sStalled->capacity * sizeof(OSMetaClass *)
+ + sizeof(*sStalled)));
+ kfree((vm_offset_t) sStalled->classes,
+ sStalled->capacity * sizeof(OSMetaClass *));
+ kfree((vm_offset_t) sStalled, sizeof(*sStalled));
+ sStalled = 0;
+ }
+
+ logError(result);
+ mutex_unlock(loadLock);
+ return result;
+}
+
+
+void OSMetaClass::instanceConstructed() const
+{
+ // if ((0 == OSIncrementAtomic((SInt32 *)&(((OSMetaClass *) this)->instanceCount))) && superClassLink)
+ if ((0 == OSIncrementAtomic((SInt32 *) &instanceCount)) && superClassLink)
+ superClassLink->instanceConstructed();
+}
+
+void OSMetaClass::instanceDestructed() const
+{
+ if ((1 == OSDecrementAtomic((SInt32 *) &instanceCount)) && superClassLink)
+ superClassLink->instanceDestructed();
+
+ if( ((int) instanceCount) < 0)
+ printf("%s: bad retain(%d)", getClassName(), instanceCount);
+}
+
+bool OSMetaClass::modHasInstance(const char *kmodName)
+{
+ bool result = false;
+
+ if (!loadLock) {
+ loadLock = mutex_alloc(ETAP_IO_AHA);
+ mutex_lock(loadLock);
+ }
+ else
+ mutex_lock(loadLock);
+
+ do {
+ OSSet *kmodClasses;
+ OSCollectionIterator *iter;
+ OSMetaClass *checkClass;
+
+ kmodClasses = OSDynamicCast(OSSet,
+ sKModClassesDict->getObject(kmodName));
+ if (!kmodClasses)
+ break;
+
+ iter = OSCollectionIterator::withCollection(kmodClasses);
+ if (!iter)
+ break;
+
+ while ( (checkClass = (OSMetaClass *) iter->getNextObject()) )
+ if (checkClass->getInstanceCount()) {
+ result = true;
+ break;
+ }
+
+ iter->release();
+ } while (false);
+
+ mutex_unlock(loadLock);
+
+ return result;
+}
+
+void OSMetaClass::reportModInstances(const char *kmodName)
+{
+ OSSet *kmodClasses;
+ OSCollectionIterator *iter;
+ OSMetaClass *checkClass;
+
+ kmodClasses = OSDynamicCast(OSSet,
+ sKModClassesDict->getObject(kmodName));
+ if (!kmodClasses)
+ return;
+
+ iter = OSCollectionIterator::withCollection(kmodClasses);
+ if (!iter)
+ return;
+
+ while ( (checkClass = (OSMetaClass *) iter->getNextObject()) )
+ if (checkClass->getInstanceCount()) {
+ printf("%s: %s has %d instance(s)\n",
+ kmodName,
+ checkClass->getClassName(),
+ checkClass->getInstanceCount());
+ }
+
+ iter->release();
+}
+
+static void _OSMetaClassConsiderUnloads(thread_call_param_t p0,
+ thread_call_param_t p1)
+{
+ OSSet *kmodClasses;
+ OSSymbol *kmodName;
+ OSCollectionIterator *kmods;
+ OSCollectionIterator *classes;
+ OSMetaClass *checkClass;
+ kmod_info_t *ki = 0;
+ kern_return_t ret;
+ bool didUnload;
+
+ mutex_lock(loadLock);
+
+ do {
+
+ kmods = OSCollectionIterator::withCollection(sKModClassesDict);
+ if (!kmods)
+ break;
+
+ didUnload = false;
+ while ( (kmodName = (OSSymbol *) kmods->getNextObject()) ) {
+
+ if (ki) {
+ kfree(ki, sizeof(kmod_info_t));
+ ki = 0;
+ }
+
+ ki = kmod_lookupbyname_locked((char *)kmodName->getCStringNoCopy());
+ if (!ki)
+ continue;
+
+ if (ki->reference_count) {
+ continue;
+ }
+
+ kmodClasses = OSDynamicCast(OSSet,
+ sKModClassesDict->getObject(kmodName));
+ classes = OSCollectionIterator::withCollection(kmodClasses);
+ if (!classes)
+ continue;
+
+ while ((checkClass = (OSMetaClass *) classes->getNextObject())
+ && (0 == checkClass->getInstanceCount()))
+ {}
+ classes->release();
+
+ if (0 == checkClass) {
+ OSRuntimeUnloadCPP(ki, 0); // call destructors
+ ret = kmod_destroy(host_priv_self(), ki->id);
+ didUnload = true;
+ }
+
}
-
- /* Remove this metaclass from the stalled list so postModLoad() doesn't
- * try to register it.
- */
- if (i < sStalled->count) {
- sStalled->count--;
- if (i < sStalled->count) {
- memmove(&sStalled->classes[i], &sStalled->classes[i+1],
- (sStalled->count - i) * sizeof(OSMetaClass *));
- }
- }
- }
-}
-
-/*********************************************************************
-* Empty overrides.
-*********************************************************************/
-void * OSMetaClass::operator new(__unused size_t size) { return 0; }
-void OSMetaClass::retain() const { }
-void OSMetaClass::release() const { }
-void OSMetaClass::release(__unused int when) const { }
-void OSMetaClass::taggedRetain(__unused const void * tag) const { }
-void OSMetaClass::taggedRelease(__unused const void * tag) const { }
-void OSMetaClass::taggedRelease(__unused const void * tag, __unused const int when) const { }
-int OSMetaClass::getRetainCount() const { return 0; }
-
-/*********************************************************************
-*********************************************************************/
-const char *
-OSMetaClass::getClassName() const
-{
- return className->getCStringNoCopy();
-}
-
-/*********************************************************************
-*********************************************************************/
-unsigned int
-OSMetaClass::getClassSize() const
-{
- return classSize;
-}
-
-/*********************************************************************
-*********************************************************************/
-void *
-OSMetaClass::preModLoad(const char * kextIdentifier)
-{
- IOLockLock(sStalledClassesLock);
-
- assert (sStalled == NULL);
- sStalled = (StalledData *)kalloc(sizeof(* sStalled));
- if (sStalled) {
- sStalled->classes = (OSMetaClass **)
- kalloc(kKModCapacityIncrement * sizeof(OSMetaClass *));
- if (!sStalled->classes) {
- kfree(sStalled, sizeof(*sStalled));
- return 0;
- }
- ACCUMSIZE((kKModCapacityIncrement * sizeof(OSMetaClass *)) +
- sizeof(*sStalled));
-
- sStalled->result = kOSReturnSuccess;
- sStalled->capacity = kKModCapacityIncrement;
- sStalled->count = 0;
- sStalled->kextIdentifier = kextIdentifier;
- bzero(sStalled->classes, kKModCapacityIncrement * sizeof(OSMetaClass *));
- }
-
- // keep sStalledClassesLock locked until postModLoad
-
- return sStalled;
-}
-
-/*********************************************************************
-*********************************************************************/
-bool
-OSMetaClass::checkModLoad(void * loadHandle)
-{
- return sStalled && loadHandle == sStalled &&
- sStalled->result == kOSReturnSuccess;
-}
-
-/*********************************************************************
-*********************************************************************/
-OSReturn
-OSMetaClass::postModLoad(void * loadHandle)
-{
- OSReturn result = kOSReturnSuccess;
- OSSymbol * myKextName = 0; // must release
- OSKext * myKext = 0; // must release
-
- if (!sStalled || loadHandle != sStalled) {
- result = kOSMetaClassInternal;
- goto finish;
- }
-
- if (sStalled->result) {
- result = sStalled->result;
- } else switch (sBootstrapState) {
-
- case kNoDictionaries:
- sBootstrapState = kMakingDictionaries;
- // No break; fall through
-
- case kMakingDictionaries:
- sAllClassesDict = OSDictionary::withCapacity(kClassCapacityIncrement);
- if (!sAllClassesDict) {
- result = kOSMetaClassNoDicts;
- break;
- }
-
- // No break; fall through
-
- case kCompletedBootstrap:
- {
- unsigned int i;
- myKextName = const_cast<OSSymbol *>(OSSymbol::withCStringNoCopy(
- sStalled->kextIdentifier));
-
- if (!sStalled->count) {
- break; // Nothing to do so just get out
- }
-
- myKext = OSKext::lookupKextWithIdentifier(myKextName);
- if (!myKext) {
- result = kOSMetaClassNoKext;
-
- /* Log this error here so we can include the kext name.
- */
- OSKextLog(/* kext */ NULL, kOSMetaClassLogSpec,
- "OSMetaClass: Can't record classes for kext %s - kext not found.",
- sStalled->kextIdentifier);
- break;
- }
-
- /* First pass checking classes aren't already loaded. If any already
- * exist, we don't register any, and so we don't technically have
- * to do any C++ teardown.
- *
- * Hack alert: me->className has been a C string until now.
- * We only release the OSSymbol if we store the kext.
- */
- IOLockLock(sAllClassesLock);
- for (i = 0; i < sStalled->count; i++) {
- OSMetaClass * me = sStalled->classes[i];
- OSMetaClass * orig = OSDynamicCast(OSMetaClass,
- sAllClassesDict->getObject((const char *)me->className));
-
- if (orig) {
-
- /* Log this error here so we can include the class name.
- * xxx - we should look up the other kext that defines the class
- */
- OSKextLog(myKext, kOSMetaClassLogSpec,
- "OSMetaClass: Kext %s class %s is a duplicate;"
- "kext %s already has a class by that name.",
- sStalled->kextIdentifier, (const char *)me->className,
- ((OSKext *)orig->reserved)->getIdentifierCString());
- result = kOSMetaClassDuplicateClass;
- break;
- }
- }
- IOLockUnlock(sAllClassesLock);
-
- /* Bail if we didn't go through the entire list of new classes
- * (if we hit a duplicate).
- */
- if (i != sStalled->count) {
- break;
- }
-
- // Second pass symbolling strings and inserting classes in dictionary
- IOLockLock(sAllClassesLock);
- for (i = 0; i < sStalled->count; i++) {
- OSMetaClass * me = sStalled->classes[i];
-
- /* Hack alert: me->className has been a C string until now.
- * We only release the OSSymbol in ~OSMetaClass()
- * if we set the reference to the kext.
- */
- me->className =
- OSSymbol::withCStringNoCopy((const char *)me->className);
-
- // xxx - I suppose if these fail we're going to panic soon....
- sAllClassesDict->setObject(me->className, me);
-
- /* Do not retain the kext object here.
- */
- me->reserved = (ExpansionData *)myKext;
- if (myKext) {
- result = myKext->addClass(me, sStalled->count);
- if (result != kOSReturnSuccess) {
- /* OSKext::addClass() logs with kOSMetaClassNoInsKModSet. */
- break;
- }
- }
- }
- IOLockUnlock(sAllClassesLock);
- sBootstrapState = kCompletedBootstrap;
- break;
- }
-
- default:
- result = kOSMetaClassInternal;
- break;
- }
-
-finish:
- /* Don't call logError() for success or the conditions logged above
- * or by called function.
- */
- if (result != kOSReturnSuccess &&
- result != kOSMetaClassNoInsKModSet &&
- result != kOSMetaClassDuplicateClass &&
- result != kOSMetaClassNoKext) {
-
- OSMetaClassLogErrorForKext(result, myKext);
- }
-
- OSSafeRelease(myKextName);
- OSSafeRelease(myKext);
-
- if (sStalled) {
- ACCUMSIZE(-(sStalled->capacity * sizeof(OSMetaClass *) +
- sizeof(*sStalled)));
- kfree(sStalled->classes, sStalled->capacity * sizeof(OSMetaClass *));
- kfree(sStalled, sizeof(*sStalled));
- sStalled = 0;
- }
-
- IOLockUnlock(sStalledClassesLock);
+
+ kmods->release();
+
+ } while (didUnload);
+
+ mutex_unlock(loadLock);
+}
+
+void OSMetaClass::considerUnloads()
+{
+ static thread_call_t unloadCallout;
+ AbsoluteTime when;
+
+ mutex_lock(loadLock);
+
+ if (!unloadCallout)
+ unloadCallout = thread_call_allocate(&_OSMetaClassConsiderUnloads, 0);
+
+ thread_call_cancel(unloadCallout);
+ clock_interval_to_deadline(sConsiderUnloadDelay, 1000 * 1000 * 1000, &when);
+ thread_call_enter_delayed(unloadCallout, when);
+
+ mutex_unlock(loadLock);
+}
+
+const OSMetaClass *OSMetaClass::getMetaClassWithName(const OSSymbol *name)
+{
+ OSMetaClass *retMeta = 0;
+
+ if (!name)
+ return 0;
+
+ if (sAllClassesDict)
+ retMeta = (OSMetaClass *) sAllClassesDict->getObject(name);
+
+ if (!retMeta && sStalled)
+ {
+ // Oh dear we have to scan the stalled list and walk the
+ // the stalled list manually.
+ const char *cName = name->getCStringNoCopy();
+ unsigned int i;
+
+ // find class in stalled list
+ for (i = 0; i < sStalled->count; i++) {
+ retMeta = sStalled->classes[i];
+ if (0 == strcmp(cName, (const char *) retMeta->className))
+ break;
+ }
+
+ if (i < sStalled->count)
+ retMeta = 0;
+ }
+
+ return retMeta;
+}
+
+OSObject *OSMetaClass::allocClassWithName(const OSSymbol *name)
+{
+ OSObject * result;
+ mutex_lock(loadLock);
+
+ const OSMetaClass * const meta = getMetaClassWithName(name);
+
+ if (meta)
+ result = meta->alloc();
+ else
+ result = 0;
+
+ mutex_unlock(loadLock);
return result;
}
-
-/*********************************************************************
-*********************************************************************/
-void
-OSMetaClass::instanceConstructed() const
-{
- // if ((0 == OSIncrementAtomic(&(((OSMetaClass *) this)->instanceCount))) && superClassLink)
- if ((0 == OSIncrementAtomic(&instanceCount)) && superClassLink) {
- superClassLink->instanceConstructed();
- }
-}
-
-/*********************************************************************
-*********************************************************************/
-void
-OSMetaClass::instanceDestructed() const
-{
- if ((1 == OSDecrementAtomic(&instanceCount)) && superClassLink) {
- superClassLink->instanceDestructed();
- }
-
- if (((int)instanceCount) < 0) {
- OSKext * myKext = (OSKext *)reserved;
-
- OSKextLog(myKext, kOSMetaClassLogSpec,
- // xxx - this phrasing is rather cryptic
- "OSMetaClass: Class %s - bad retain (%d)",
- getClassName(), instanceCount);
- }
-}
-
-/*********************************************************************
-*********************************************************************/
-bool
-OSMetaClass::modHasInstance(const char * kextIdentifier)
-{
- bool result = false;
- OSKext * theKext = NULL; // must release
-
- theKext = OSKext::lookupKextWithIdentifier(kextIdentifier);
- if (!theKext) {
- goto finish;
- }
-
- result = theKext->hasOSMetaClassInstances();
-
-finish:
- OSSafeRelease(theKext);
- return result;
-}
-
-/*********************************************************************
-*********************************************************************/
-void
-OSMetaClass::reportModInstances(const char * kextIdentifier)
-{
- OSKext::reportOSMetaClassInstances(kextIdentifier,
- kOSKextLogExplicitLevel);
- return;
-}
-
-/*********************************************************************
-*********************************************************************/
-void
-OSMetaClass::considerUnloads()
-{
- OSKext::considerUnloads();
-}
-
-/*********************************************************************
-*********************************************************************/
-const OSMetaClass *
-OSMetaClass::getMetaClassWithName(const OSSymbol * name)
-{
- OSMetaClass * retMeta = 0;
-
- if (!name) {
- return 0;
- }
-
- IOLockLock(sAllClassesLock);
- if (sAllClassesDict) {
- retMeta = (OSMetaClass *) sAllClassesDict->getObject(name);
- }
- IOLockUnlock(sAllClassesLock);
-
- return retMeta;
-}
-
-/*********************************************************************
-*********************************************************************/
-OSObject *
-OSMetaClass::allocClassWithName(const OSSymbol * name)
-{
- OSObject * result = 0;
-
- const OSMetaClass * const meta = getMetaClassWithName(name);
-
- if (meta) {
- result = meta->alloc();
- }
-
- return result;
-}
-
-/*********************************************************************
-*********************************************************************/
-OSObject *
-OSMetaClass::allocClassWithName(const OSString * name)
-{
- const OSSymbol * tmpKey = OSSymbol::withString(name);
- OSObject * result = allocClassWithName(tmpKey);
+OSObject *OSMetaClass::allocClassWithName(const OSString *name)
+{
+ const OSSymbol *tmpKey = OSSymbol::withString(name);
+ OSObject *result = allocClassWithName(tmpKey);
tmpKey->release();
return result;
}
-/*********************************************************************
-*********************************************************************/
-OSObject *
-OSMetaClass::allocClassWithName(const char * name)
-{
- const OSSymbol * tmpKey = OSSymbol::withCStringNoCopy(name);
- OSObject * result = allocClassWithName(tmpKey);
+OSObject *OSMetaClass::allocClassWithName(const char *name)
+{
+ const OSSymbol *tmpKey = OSSymbol::withCStringNoCopy(name);
+ OSObject *result = allocClassWithName(tmpKey);
tmpKey->release();
return result;
}
-/*********************************************************************
-*********************************************************************/
-OSMetaClassBase *
-OSMetaClass::checkMetaCastWithName(
- const OSSymbol * name,
- const OSMetaClassBase * in)
-{
- OSMetaClassBase * result = 0;
-
+OSMetaClassBase *OSMetaClass::
+checkMetaCastWithName(const OSSymbol *name, const OSMetaClassBase *in)
+{
+ OSMetaClassBase * result;
+ mutex_lock(loadLock);
const OSMetaClass * const meta = getMetaClassWithName(name);
- if (meta) {
- result = meta->checkMetaCast(in);
- }
-
+ if (meta)
+ result = meta->checkMetaCast(in);
+ else
+ result = 0;
+
+ mutex_unlock(loadLock);
return result;
}
-/*********************************************************************
-*********************************************************************/
-OSMetaClassBase * OSMetaClass::
-checkMetaCastWithName(
- const OSString * name,
- const OSMetaClassBase * in)
-{
- const OSSymbol * tmpKey = OSSymbol::withString(name);
- OSMetaClassBase * result = checkMetaCastWithName(tmpKey, in);
-
+OSMetaClassBase *OSMetaClass::
+checkMetaCastWithName(const OSString *name, const OSMetaClassBase *in)
+{
+ const OSSymbol *tmpKey = OSSymbol::withString(name);
+ OSMetaClassBase *result = checkMetaCastWithName(tmpKey, in);
tmpKey->release();
return result;
}
-/*********************************************************************
-*********************************************************************/
-OSMetaClassBase *
-OSMetaClass::checkMetaCastWithName(
- const char * name,
- const OSMetaClassBase * in)
-{
- const OSSymbol * tmpKey = OSSymbol::withCStringNoCopy(name);
- OSMetaClassBase * result = checkMetaCastWithName(tmpKey, in);
-
+OSMetaClassBase *OSMetaClass::
+checkMetaCastWithName(const char *name, const OSMetaClassBase *in)
+{
+ const OSSymbol *tmpKey = OSSymbol::withCStringNoCopy(name);
+ OSMetaClassBase *result = checkMetaCastWithName(tmpKey, in);
tmpKey->release();
return result;
}
-/*********************************************************************
- * OSMetaClass::checkMetaCast()
- * Check to see if the 'check' object has this object in its metaclass chain.
- * Returns check if it is indeed a kind of the current meta class, 0 otherwise.
- *
- * Generally this method is not invoked directly but is used to implement
- * the OSMetaClassBase::metaCast member function.
- *
- * See also OSMetaClassBase::metaCast
-*********************************************************************/
-OSMetaClassBase * OSMetaClass::checkMetaCast(
- const OSMetaClassBase * check) const
-{
- const OSMetaClass * const toMeta = this;
- const OSMetaClass * fromMeta;
+/*
+OSMetaClass::checkMetaCast
+ checkMetaCast(const OSMetaClassBase *check)
+
+Check to see if the 'check' object has this object in it's metaclass chain. Returns check if it is indeed a kind of the current meta class, 0 otherwise.
+
+Generally this method is not invoked directly but is used to implement the OSMetaClassBase::metaCast member function.
+
+See also OSMetaClassBase::metaCast
+
+ */
+OSMetaClassBase *OSMetaClass::checkMetaCast(const OSMetaClassBase *check) const
+{
+ const OSMetaClass * const toMeta = this;
+ const OSMetaClass *fromMeta;
for (fromMeta = check->getMetaClass(); ; fromMeta = fromMeta->superClassLink) {
- if (toMeta == fromMeta) {
- return const_cast<OSMetaClassBase *>(check); // Discard const
- }
- if (!fromMeta->superClassLink) {
- break;
- }
+ if (toMeta == fromMeta)
+ return (OSMetaClassBase *) check; // Discard const
+
+ if (!fromMeta->superClassLink)
+ break;
}
return 0;
}
-/*********************************************************************
-*********************************************************************/
-void
-OSMetaClass::reservedCalled(int ind) const
-{
- const char * cname = className->getCStringNoCopy();
- panic("%s::_RESERVED%s%d called.", cname, cname, ind);
-}
-
-/*********************************************************************
-*********************************************************************/
-const
-OSMetaClass *
-OSMetaClass::getSuperClass() const
+void OSMetaClass::reservedCalled(int ind) const
+{
+ const char *cname = className->getCStringNoCopy();
+ panic("%s::_RESERVED%s%d called\n", cname, cname, ind);
+}
+
+const OSMetaClass *OSMetaClass::getSuperClass() const
{
return superClassLink;
}
-/*********************************************************************
-* xxx - I want to rename this :-/
-*********************************************************************/
-const OSSymbol *
-OSMetaClass::getKmodName() const
-{
- OSKext * myKext = (OSKext *)reserved;
- if (myKext) {
- return myKext->getIdentifier();
- }
- return OSSymbol::withCStringNoCopy("unknown");
-}
-
-/*********************************************************************
-*********************************************************************/
-unsigned int
-OSMetaClass::getInstanceCount() const
+unsigned int OSMetaClass::getInstanceCount() const
{
return instanceCount;
}
-/*********************************************************************
-*********************************************************************/
-/* static */
-void
-OSMetaClass::printInstanceCounts()
-{
- OSCollectionIterator * classes;
- OSSymbol * className;
- OSMetaClass * meta;
-
- IOLockLock(sAllClassesLock);
+void OSMetaClass::printInstanceCounts()
+{
+ OSCollectionIterator *classes;
+ OSSymbol *className;
+ OSMetaClass *meta;
+
classes = OSCollectionIterator::withCollection(sAllClassesDict);
- assert(classes);
+ if (!classes)
+ return;
while( (className = (OSSymbol *)classes->getNextObject())) {
- meta = (OSMetaClass *)sAllClassesDict->getObject(className);
- assert(meta);
-
- printf("%24s count: %03d x 0x%03x = 0x%06x\n",
- className->getCStringNoCopy(),
- meta->getInstanceCount(),
- meta->getClassSize(),
- meta->getInstanceCount() * meta->getClassSize() );
+ meta = (OSMetaClass *) sAllClassesDict->getObject(className);
+ assert(meta);
+
+ printf("%24s count: %03d x 0x%03x = 0x%06x\n",
+ className->getCStringNoCopy(),
+ meta->getInstanceCount(),
+ meta->getClassSize(),
+ meta->getInstanceCount() * meta->getClassSize() );
}
printf("\n");
classes->release();
- IOLockUnlock(sAllClassesLock);
- return;
-}
-
-/*********************************************************************
-*********************************************************************/
-OSDictionary *
-OSMetaClass::getClassDictionary()
-{
- panic("OSMetaClass::getClassDictionary() is obsoleted.\n");
- return 0;
-}
-
-/*********************************************************************
-*********************************************************************/
-bool
-OSMetaClass::serialize(__unused OSSerialize * s) const
-{
- panic("OSMetaClass::serialize(): Obsoleted\n");
- return false;
-}
-
-/*********************************************************************
-*********************************************************************/
-/* static */
-void
-OSMetaClass::serializeClassDictionary(OSDictionary * serializeDictionary)
-{
- OSDictionary * classDict = NULL;
-
- IOLockLock(sAllClassesLock);
-
- classDict = OSDictionary::withCapacity(sAllClassesDict->getCount());
- if (!classDict) {
- goto finish;
- }
-
- do {
- OSCollectionIterator * classes;
- const OSSymbol * className;
-
- classes = OSCollectionIterator::withCollection(sAllClassesDict);
- if (!classes) {
- break;
- }
-
- while ((className = (const OSSymbol *)classes->getNextObject())) {
- const OSMetaClass * meta;
- OSNumber * count;
-
- meta = (OSMetaClass *)sAllClassesDict->getObject(className);
- count = OSNumber::withNumber(meta->getInstanceCount(), 32);
- if (count) {
- classDict->setObject(className, count);
- count->release();
- }
- }
- classes->release();
-
- serializeDictionary->setObject("Classes", classDict);
- } while (0);
-
-finish:
- OSSafeRelease(classDict);
-
- IOLockUnlock(sAllClassesLock);
-
- return;
-}
+}
+
+OSDictionary * OSMetaClass::getClassDictionary()
+{
+ return sAllClassesDict;
+}
+
+bool OSMetaClass::serialize(OSSerialize *s) const
+{
+ OSDictionary * dict;
+ OSNumber * off;
+ bool ok = false;
+
+ if (s->previouslySerialized(this)) return true;
+
+ dict = 0;// IODictionary::withCapacity(2);
+ off = OSNumber::withNumber(getInstanceCount(), 32);
+
+ if (dict) {
+ dict->setObject("InstanceCount", off );
+ ok = dict->serialize(s);
+ } else if( off)
+ ok = off->serialize(s);
+
+ if (dict)
+ dict->release();
+ if (off)
+ off->release();
+
+ return ok;
+}
+