Loading...
--- xnu/xnu-12377.101.15/libkern/c++/OSMetaClass.cpp
+++ xnu/xnu-2422.110.17/libkern/c++/OSMetaClass.cpp
@@ -1,8 +1,8 @@
/*
- * Copyright (c) 2000-2016 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2006 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_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
@@ -11,10 +11,10 @@
* 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.
- *
+ *
* 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
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -22,7 +22,7 @@
* 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.
- *
+ *
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
/* OSMetaClass.cpp created by gvdl on Fri 1998-11-17 */
@@ -37,8 +37,8 @@
#include <libkern/c++/OSCollectionIterator.h>
#include <libkern/c++/OSDictionary.h>
-#include <libkern/c++/OSArray.h>
-#include <libkern/c++/OSSet.h>
+#include <libkern/c++/OSArray.h>
+#include <libkern/c++/OSSet.h>
#include <libkern/c++/OSSymbol.h>
#include <libkern/c++/OSNumber.h>
#include <libkern/c++/OSSerialize.h>
@@ -47,9 +47,6 @@
#include <libkern/OSAtomic.h>
#include <IOKit/IOLib.h>
-
-#include <IOKit/IOKitDebug.h>
-
__BEGIN_DECLS
@@ -60,7 +57,6 @@
#include <kern/thread_call.h>
#include <kern/host.h>
#include <mach/mach_interface.h>
-#include <stddef.h>
#if PRAGMA_MARK
#pragma mark Macros
@@ -68,6 +64,13 @@
/*********************************************************************
* Macros
*********************************************************************/
+#if OSALLOCDEBUG
+extern int debug_container_malloc_size;
+#define ACCUMSIZE(s) do { debug_container_malloc_size += (s); } while (0)
+#else
+#define ACCUMSIZE(s)
+#endif /* OSALLOCDEBUG */
+
__END_DECLS
#if PRAGMA_MARK
@@ -82,9 +85,9 @@
kOSKextLogKextBookkeepingFlag;
static enum {
- kCompletedBootstrap = 0,
- kNoDictionaries = 1,
- kMakingDictionaries = 2
+ kCompletedBootstrap = 0,
+ kNoDictionaries = 1,
+ kMakingDictionaries = 2
} sBootstrapState = kNoDictionaries;
static const int kClassCapacityIncrement = 40;
@@ -100,21 +103,18 @@
* kext can be in flight at a time, guarded by sStalledClassesLock
*/
static struct StalledData {
- const char * kextIdentifier;
- OSReturn result;
- unsigned int capacity;
- unsigned int count;
- OSMetaClass ** classes;
+ const char * kextIdentifier;
+ OSReturn result;
+ unsigned int capacity;
+ unsigned int count;
+ OSMetaClass ** classes;
} * sStalled;
IOLock * sStalledClassesLock = NULL;
+
struct ExpansionData {
- OSOrderedSet * instances;
- OSKext * kext;
- uint32_t retain;
-#if IOTRACKING
- IOTrackingQueue * tracking;
-#endif
+ OSOrderedSet * instances;
+ OSKext * kext;
};
@@ -129,154 +129,26 @@
/*********************************************************************
* Reserved vtable functions.
*********************************************************************/
-#if defined(__arm64__) || defined(__arm__)
-void
-OSMetaClassBase::_RESERVEDOSMetaClassBase0()
-{
- panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 0);
-}
-void
-OSMetaClassBase::_RESERVEDOSMetaClassBase1()
-{
- panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 1);
-}
-void
-OSMetaClassBase::_RESERVEDOSMetaClassBase2()
-{
- panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 2);
-}
-void
-OSMetaClassBase::_RESERVEDOSMetaClassBase3()
-{
- panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 3);
-}
-#endif /* defined(__arm64__) || defined(__arm__) */
+#if SLOT_USED
+void OSMetaClassBase::_RESERVEDOSMetaClassBase0()
+ { panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 0); }
+void OSMetaClassBase::_RESERVEDOSMetaClassBase1()
+ { panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 1); }
+void OSMetaClassBase::_RESERVEDOSMetaClassBase2()
+ { panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 2); }
+#endif /* SLOT_USED */
// As these slots are used move them up inside the #if above
-void
-OSMetaClassBase::_RESERVEDOSMetaClassBase4()
-{
- panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 4);
-}
-void
-OSMetaClassBase::_RESERVEDOSMetaClassBase5()
-{
- panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 5);
-}
-void
-OSMetaClassBase::_RESERVEDOSMetaClassBase6()
-{
- panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 6);
-}
+void OSMetaClassBase::_RESERVEDOSMetaClassBase3()
+ { panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 3); }
+void OSMetaClassBase::_RESERVEDOSMetaClassBase4()
+ { panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 4); }
+void OSMetaClassBase::_RESERVEDOSMetaClassBase5()
+ { panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 5); }
+void OSMetaClassBase::_RESERVEDOSMetaClassBase6()
+ { panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 6); }
#endif
-/*********************************************************************
-*********************************************************************/
-
-#if defined(__arm__) || defined(__arm64__)
-
-#if defined(HAS_APPLE_PAC)
-#include <ptrauth.h>
-#endif /* defined(HAS_APPLE_PAC) */
-
-/*
- * IHI0059A "C++ Application Binary Interface Standard for the ARM 64 - bit Architecture":
- *
- * 3.2.1 Representation of pointer to member function The generic C++ ABI [GC++ABI]
- * specifies that a pointer to member function is a pair of words <ptr, adj>. The
- * least significant bit of ptr discriminates between (0) the address of a non-
- * virtual member function and (1) the offset in the class's virtual table of the
- * address of a virtual function. This encoding cannot work for the AArch64
- * instruction set where the architecture reserves all bits of code addresses. This
- * ABI specifies that adj contains twice the this adjustment, plus 1 if the member
- * function is virtual. The least significant bit of adj then makes exactly the
- * same discrimination as the least significant bit of ptr does for Itanium. A
- * pointer to member function is NULL when ptr = 0 and the least significant bit of
- * adj is zero.
- */
-
-OSMetaClassBase::_ptf_t
-#if defined(HAS_APPLE_PAC) && \
- __has_feature(ptrauth_member_function_pointer_type_discrimination)
-OSMetaClassBase::_ptmf2ptf(const OSMetaClassBase *self __attribute__((unused)),
- void (OSMetaClassBase::*func)(void))
-#else
-OSMetaClassBase::_ptmf2ptf(const OSMetaClassBase *self,
- void (OSMetaClassBase::*func)(void))
-#endif
-{
- struct ptmf_t {
- _ptf_t fPFN;
- ptrdiff_t delta;
- };
- union {
- void (OSMetaClassBase::*fIn)(void);
- struct ptmf_t pTMF;
- } map;
- _ptf_t pfn;
-
- map.fIn = func;
- pfn = map.pTMF.fPFN;
-
-#if defined(HAS_APPLE_PAC) && \
- __has_feature(ptrauth_member_function_pointer_type_discrimination)
- // Authenticate 'pfn' using the member function pointer type discriminator
- // and resign it as a C function pointer. 'pfn' can point to either a
- // non-virtual function or a virtual member function thunk.
- // It can also be NULL.
- if (pfn) {
- pfn = ptrauth_auth_and_resign(pfn, ptrauth_key_function_pointer,
- ptrauth_type_discriminator(__typeof__(func)),
- ptrauth_key_function_pointer,
- ptrauth_function_pointer_type_discriminator(_ptf_t));
- }
- return pfn;
-#else
- if (map.pTMF.delta & 1) {
- // virtual
- union {
- const OSMetaClassBase *fObj;
- _ptf_t **vtablep;
- } u;
- u.fObj = self;
-
- // Virtual member function so dereference table
-#if defined(HAS_APPLE_PAC)
- // The entity hash is stored in the top 32-bits of the vtable offset of a
- // member function pointer.
- uint32_t entity_hash = ((uintptr_t)pfn) >> 32;
- pfn = (_ptf_t)(((uintptr_t) pfn) & 0xFFFFFFFF);
-
-#if __has_builtin(__builtin_get_vtable_pointer)
- const _ptf_t *vtablep =
- (const _ptf_t *)__builtin_get_vtable_pointer(u.fObj);
-#else
- // Authenticate the vtable pointer.
- const _ptf_t *vtablep = ptrauth_auth_data(*u.vtablep,
- ptrauth_key_cxx_vtable_pointer, 0);
-#endif
- // Calculate the address of the vtable entry.
- _ptf_t *vtentryp = (_ptf_t *)(((uintptr_t)vtablep) + (uintptr_t)pfn);
- // Load the pointer from the vtable entry.
- pfn = *vtentryp;
-
- // Finally, resign the vtable entry as a function pointer.
- uintptr_t auth_data = ptrauth_blend_discriminator(vtentryp, entity_hash);
- pfn = ptrauth_auth_and_resign(pfn, ptrauth_key_function_pointer,
- auth_data, ptrauth_key_function_pointer,
- ptrauth_function_pointer_type_discriminator(_ptf_t));
-#else /* defined(HAS_APPLE_PAC) */
- pfn = *(_ptf_t *)(((uintptr_t)*u.vtablep) + (uintptr_t)pfn);
-#endif /* !defined(HAS_APPLE_PAC) */
- return pfn;
- } else {
- // Not virtual, i.e. plain member func
- return pfn;
- }
-#endif
-}
-
-#endif /* defined(__arm__) || defined(__arm64__) */
/*********************************************************************
* 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
@@ -289,57 +161,31 @@
*********************************************************************/
OSMetaClassBase *
OSMetaClassBase::safeMetaCast(
- const OSMetaClassBase * me,
- const OSMetaClass * toType)
-{
- return (me)? me->metaCast(toType) : NULL;
-}
-
-/// A helper function to crash with a kernel panic.
-__attribute__((cold, not_tail_called, noreturn))
-static inline void
-panic_crash_fail_cast(const OSMetaClassBase *me,
- const OSMetaClass *toType)
-{
- panic("Unexpected cast fail: from %p to %p", me, toType);
- __builtin_unreachable();
-}
-
-OSMetaClassBase *
-OSMetaClassBase::requiredMetaCast(
- const OSMetaClassBase * me,
- const OSMetaClass * toType)
-{
- if (!me) {
- return NULL;
- }
- OSMetaClassBase *tmp = safeMetaCast(me, toType);
- if (!tmp) {
- panic_crash_fail_cast(me, toType);
- }
- return tmp;
+ 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 && (NULL != inst->metaCast(toType));
-}
-
-/*********************************************************************
-*********************************************************************/
-void
-OSMetaClassBase::
+ 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();
- sInstancesLock = IOLockAlloc();
+ sAllClassesLock = IOLockAlloc();
+ sStalledClassesLock = IOLockAlloc();
+ sInstancesLock = IOLockAlloc();
}
#if APPLE_KEXT_VTABLE_PADDING
@@ -350,9 +196,7 @@
*********************************************************************/
void
OSMetaClassBase::_RESERVEDOSMetaClassBase7()
-{
- panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 7);
-}
+{ panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 7); }
#endif
/*********************************************************************
@@ -365,10 +209,10 @@
*********************************************************************/
OSMetaClassBase::~OSMetaClassBase()
{
- void ** thisVTable;
-
- thisVTable = (void **) this;
- *thisVTable = (void *) -1UL;
+ void ** thisVTable;
+
+ thisVTable = (void **) this;
+ *thisVTable = (void *) -1UL;
}
/*********************************************************************
@@ -376,7 +220,7 @@
bool
OSMetaClassBase::isEqualTo(const OSMetaClassBase * anObj) const
{
- return this == anObj;
+ return this == anObj;
}
/*********************************************************************
@@ -384,7 +228,7 @@
OSMetaClassBase *
OSMetaClassBase::metaCast(const OSMetaClass * toMeta) const
{
- return toMeta->checkMetaCast(this);
+ return toMeta->checkMetaCast(this);
}
/*********************************************************************
@@ -392,7 +236,7 @@
OSMetaClassBase *
OSMetaClassBase::metaCast(const OSSymbol * toMetaSymb) const
{
- return OSMetaClass::checkMetaCastWithName(toMetaSymb, this);
+ return OSMetaClass::checkMetaCastWithName(toMetaSymb, this);
}
/*********************************************************************
@@ -400,13 +244,13 @@
OSMetaClassBase *
OSMetaClassBase::metaCast(const OSString * toMetaStr) const
{
- const OSSymbol * tempSymb = OSSymbol::withString(toMetaStr);
- OSMetaClassBase * ret = NULL;
- if (tempSymb) {
- ret = metaCast(tempSymb);
- tempSymb->release();
- }
- return ret;
+ const OSSymbol * tempSymb = OSSymbol::withString(toMetaStr);
+ OSMetaClassBase * ret = 0;
+ if (tempSymb) {
+ ret = metaCast(tempSymb);
+ tempSymb->release();
+ }
+ return ret;
}
/*********************************************************************
@@ -414,13 +258,13 @@
OSMetaClassBase *
OSMetaClassBase::metaCast(const char * toMetaCStr) const
{
- const OSSymbol * tempSymb = OSSymbol::withCString(toMetaCStr);
- OSMetaClassBase * ret = NULL;
- if (tempSymb) {
- ret = metaCast(tempSymb);
- tempSymb->release();
- }
- return ret;
+ const OSSymbol * tempSymb = OSSymbol::withCString(toMetaCStr);
+ OSMetaClassBase * ret = 0;
+ if (tempSymb) {
+ ret = metaCast(tempSymb);
+ tempSymb->release();
+ }
+ return ret;
}
#if PRAGMA_MARK
@@ -429,30 +273,22 @@
/*********************************************************************
* OSMetaClassMeta - the bootstrap metaclass of OSMetaClass
*********************************************************************/
-class OSMetaClassMeta : public OSMetaClass
+class OSMetaClassMeta : public OSMetaClass
{
public:
- OSMetaClassMeta();
- OSObject * alloc() const override;
+ OSMetaClassMeta();
+ OSObject * alloc() const;
};
OSMetaClassMeta::OSMetaClassMeta()
- : OSMetaClass("OSMetaClass", NULL, sizeof(OSMetaClass))
-{
-}
-OSObject *
-OSMetaClassMeta::alloc() const
-{
- return NULL;
-}
+ : OSMetaClass("OSMetaClass", 0, sizeof(OSMetaClass))
+ { }
+OSObject * OSMetaClassMeta::alloc() const { return 0; }
static OSMetaClassMeta sOSMetaClassMeta;
const OSMetaClass * const OSMetaClass::metaClass = &sOSMetaClassMeta;
-const OSMetaClass *
-OSMetaClass::getMetaClass() const
-{
- return &sOSMetaClassMeta;
-}
+const OSMetaClass * OSMetaClass::getMetaClass() const
+ { return &sOSMetaClassMeta; }
#if PRAGMA_MARK
#pragma mark OSMetaClass
@@ -465,100 +301,76 @@
/*********************************************************************
* Reserved functions.
*********************************************************************/
-void
-OSMetaClass::_RESERVEDOSMetaClass0()
-{
- panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 0);
-}
-void
-OSMetaClass::_RESERVEDOSMetaClass1()
-{
- panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 1);
-}
-void
-OSMetaClass::_RESERVEDOSMetaClass2()
-{
- panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 2);
-}
-void
-OSMetaClass::_RESERVEDOSMetaClass3()
-{
- panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 3);
-}
-void
-OSMetaClass::_RESERVEDOSMetaClass4()
-{
- panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 4);
-}
-void
-OSMetaClass::_RESERVEDOSMetaClass5()
-{
- panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 5);
-}
-void
-OSMetaClass::_RESERVEDOSMetaClass6()
-{
- panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 6);
-}
-void
-OSMetaClass::_RESERVEDOSMetaClass7()
-{
- panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 7);
-}
+void OSMetaClass::_RESERVEDOSMetaClass0()
+ { panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 0); }
+void OSMetaClass::_RESERVEDOSMetaClass1()
+ { panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 1); }
+void OSMetaClass::_RESERVEDOSMetaClass2()
+ { panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 2); }
+void OSMetaClass::_RESERVEDOSMetaClass3()
+ { panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 3); }
+void OSMetaClass::_RESERVEDOSMetaClass4()
+ { panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 4); }
+void OSMetaClass::_RESERVEDOSMetaClass5()
+ { panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 5); }
+void OSMetaClass::_RESERVEDOSMetaClass6()
+ { panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 6); }
+void OSMetaClass::_RESERVEDOSMetaClass7()
+ { panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 7); }
#endif
/*********************************************************************
*********************************************************************/
static void
OSMetaClassLogErrorForKext(
- OSReturn error,
- OSKext * aKext)
-{
- const char * message = NULL;
-
- switch (error) {
- 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;
+ OSReturn error,
+ OSKext * aKext)
+{
+ const char * message = NULL;
+
+ switch (error) {
+ 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);
+ OSMetaClassLogErrorForKext(error, NULL);
}
/*********************************************************************
@@ -570,208 +382,148 @@
* 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)
-{
- instanceCount = 0;
- classSize = inClassSize;
- superClassLink = inSuperClass;
-
- reserved = IOMallocType(ExpansionData);
-#if IOTRACKING
- 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
- * 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
- 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);
- } else if (!sStalled->result) {
- // Grow stalled array if neccessary
- if (sStalled->count >= sStalled->capacity) {
- OSMetaClass **oldStalled = sStalled->classes;
- int oldCount = sStalled->capacity;
- int newCount = oldCount + kKModCapacityIncrement;
-
- sStalled->classes = kalloc_type_tag(OSMetaClass *, newCount,
- Z_WAITOK_ZERO, VM_KERN_MEMORY_OSKEXT);
- if (!sStalled->classes) {
- sStalled->classes = oldStalled;
- sStalled->result = kOSMetaClassNoTempData;
- return;
- }
-
- sStalled->capacity = newCount;
- memmove(sStalled->classes, oldStalled,
- sizeof(OSMetaClass *) * oldCount);
- kfree_type(OSMetaClass *, oldCount, oldStalled);
- OSMETA_ACCUMSIZE(sizeof(OSMetaClass *) * (newCount - oldCount));
- }
-
- sStalled->classes[sStalled->count++] = this;
- }
-}
-
-OSMetaClass::OSMetaClass(
- const char * inClassName,
- const OSMetaClass * inSuperClass,
- unsigned int inClassSize,
- zone_t * inZone,
- const char * zone_name,
- zone_create_flags_t zflags) : OSMetaClass(inClassName, inSuperClass,
- inClassSize)
-{
- if (!(kIOTracking & gIOKitDebug)) {
- *inZone = zone_create(zone_name, inClassSize,
- (zone_create_flags_t) (ZC_ZFREE_CLEARMEM | zflags));
- }
+ const char * inClassName,
+ const OSMetaClass * inSuperClass,
+ unsigned int inClassSize)
+{
+ instanceCount = 0;
+ classSize = inClassSize;
+ superClassLink = inSuperClass;
+
+ reserved = IONew(ExpansionData, 1);
+ bzero(reserved, sizeof(ExpansionData));
+
+ /* 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
+ 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);
+ } 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;
+ }
}
/*********************************************************************
*********************************************************************/
OSMetaClass::~OSMetaClass()
{
- OSKext * myKext = reserved->kext; // 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((const char *)className);
- }
- }
- IOLockUnlock(sAllClassesLock);
-
- if (myKext) {
- if (myKext->removeClass(this) != kOSReturnSuccess) {
- // xxx - what can we do?
- }
- className->release();
- }
-
- // sStalledClassesLock taken in preModLoad
- if (sStalled) {
- 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]) {
- break;
- }
- }
-
- /* 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 *));
- }
- }
- }
-#if IOTRACKING
- IOTrackingQueueFree(reserved->tracking);
-#endif
- IOFreeType(reserved, ExpansionData);
+ OSKext * myKext = reserved ? reserved->kext : 0; // 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
+ if (sStalled) {
+ 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]) {
+ break;
+ }
+ }
+
+ /* 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::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;
-}
+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
{
- if (!className) {
- return NULL;
- }
- return className->getCStringNoCopy();
+ if (!className) return NULL;
+ return className->getCStringNoCopy();
}
/*********************************************************************
*********************************************************************/
const OSSymbol *
OSMetaClass::getClassNameSymbol() const
{
- return className;
+ return className;
}
/*********************************************************************
*********************************************************************/
unsigned int
OSMetaClass::getClassSize() const
{
- return classSize;
+ return classSize;
}
/*********************************************************************
@@ -779,28 +531,30 @@
void *
OSMetaClass::preModLoad(const char * kextIdentifier)
{
- IOLockLock(sStalledClassesLock);
-
- assert(sStalled == NULL);
- sStalled = kalloc_type(StalledData, Z_WAITOK_ZERO_NOFAIL);
-
- sStalled->classes = kalloc_type_tag(OSMetaClass *,
- kKModCapacityIncrement, Z_WAITOK_ZERO, VM_KERN_MEMORY_OSKEXT);
- if (!sStalled->classes) {
- kfree_type(StalledData, sStalled);
- return NULL;
- }
- OSMETA_ACCUMSIZE((kKModCapacityIncrement * sizeof(OSMetaClass *)) +
- sizeof(*sStalled));
-
- sStalled->result = kOSReturnSuccess;
- sStalled->capacity = kKModCapacityIncrement;
- sStalled->count = 0;
- sStalled->kextIdentifier = kextIdentifier;
-
- // keep sStalledClassesLock locked until postModLoad
-
- return sStalled;
+ 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;
}
/*********************************************************************
@@ -808,8 +562,8 @@
bool
OSMetaClass::checkModLoad(void * loadHandle)
{
- return sStalled && loadHandle == sStalled &&
- sStalled->result == kOSReturnSuccess;
+ return sStalled && loadHandle == sStalled &&
+ sStalled->result == kOSReturnSuccess;
}
/*********************************************************************
@@ -817,165 +571,156 @@
OSReturn
OSMetaClass::postModLoad(void * loadHandle)
{
- OSReturn result = kOSReturnSuccess;
- OSSymbol * myKextName = NULL;// must release
- OSKext * myKext = NULL;// 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
- [[clang::fallthrough]];
-
- case kMakingDictionaries:
- sAllClassesDict = OSDictionary::withCapacity(kClassCapacityIncrement);
- if (!sAllClassesDict) {
- result = kOSMetaClassNoDicts;
- break;
- }
- sAllClassesDict->setOptions(OSCollection::kSort, OSCollection::kSort);
-
- // No break; fall through
- [[clang::fallthrough]];
-
- 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++) {
- const 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
- */
-#if defined(XNU_TARGET_OS_OSX)
- OSKextLog(myKext, kOSMetaClassLogSpec,
-#else
- panic(
-#endif /* defined(XNU_TARGET_OS_OSX) */
- "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->kext)->getIdentifierCString());
- result = kOSMetaClassDuplicateClass;
- break;
- }
- unsigned int depth = 1;
- while ((me = me->superClassLink)) {
- depth++;
- }
- if (depth > sDeepestClass) {
- sDeepestClass = depth;
- }
- }
- 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->kext = 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;
- }
- }
-
+ 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;
+ }
+ sAllClassesDict->setOptions(OSCollection::kSort, OSCollection::kSort);
+
+ // 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++) {
+ const 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->kext)->getIdentifierCString());
+ result = kOSMetaClassDuplicateClass;
+ break;
+ }
+ unsigned int depth = 1;
+ while ((me = me->superClassLink)) depth++;
+ if (depth > sDeepestClass) sDeepestClass = depth;
+ }
+ 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->kext = 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);
- }
-
- OSSafeReleaseNULL(myKextName);
- OSSafeReleaseNULL(myKext);
-
- if (sStalled) {
- OSMETA_ACCUMSIZE(-(sStalled->capacity * sizeof(OSMetaClass *) +
- sizeof(*sStalled)));
- kfree_type(OSMetaClass *, sStalled->capacity, sStalled->classes);
- kfree_type(StalledData, sStalled);
- sStalled = NULL;
- }
-
- IOLockUnlock(sStalledClassesLock);
-
- return result;
+ /* 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);
+
+ return result;
}
@@ -984,10 +729,10 @@
void
OSMetaClass::instanceConstructed() const
{
- // if ((0 == OSIncrementAtomic(&(((OSMetaClass *) this)->instanceCount))) && superClassLink)
- if ((0 == OSIncrementAtomic(&instanceCount)) && superClassLink) {
- superClassLink->instanceConstructed();
- }
+ // if ((0 == OSIncrementAtomic(&(((OSMetaClass *) this)->instanceCount))) && superClassLink)
+ if ((0 == OSIncrementAtomic(&instanceCount)) && superClassLink) {
+ superClassLink->instanceConstructed();
+ }
}
/*********************************************************************
@@ -995,18 +740,18 @@
void
OSMetaClass::instanceDestructed() const
{
- if ((1 == OSDecrementAtomic(&instanceCount)) && superClassLink) {
- superClassLink->instanceDestructed();
- }
-
- if (((int)instanceCount) < 0) {
- OSKext * myKext = reserved->kext;
-
- OSKextLog(myKext, kOSMetaClassLogSpec,
- // xxx - this phrasing is rather cryptic
- "OSMetaClass: Class %s - bad retain (%d)",
- getClassName(), instanceCount);
- }
+ if ((1 == OSDecrementAtomic(&instanceCount)) && superClassLink) {
+ superClassLink->instanceDestructed();
+ }
+
+ if (((int)instanceCount) < 0) {
+ OSKext * myKext = reserved->kext;
+
+ OSKextLog(myKext, kOSMetaClassLogSpec,
+ // xxx - this phrasing is rather cryptic
+ "OSMetaClass: Class %s - bad retain (%d)",
+ getClassName(), instanceCount);
+ }
}
/*********************************************************************
@@ -1014,170 +759,163 @@
bool
OSMetaClass::modHasInstance(const char * kextIdentifier)
{
- bool result = false;
- OSKext * theKext = NULL; // must release
-
- theKext = OSKext::lookupKextWithIdentifier(kextIdentifier);
- if (!theKext) {
- goto finish;
+ 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::addInstance(const OSObject * instance, bool super) const
+{
+ if (!super) IOLockLock(sInstancesLock);
+
+ if (!reserved->instances) {
+ reserved->instances = OSOrderedSet::withCapacity(16);
+ if (superClassLink) {
+ superClassLink->addInstance(reserved->instances, true);
}
-
- result = theKext->hasOSMetaClassInstances();
-
-finish:
- OSSafeReleaseNULL(theKext);
- return result;
-}
-
-/*********************************************************************
-*********************************************************************/
-void
-OSMetaClass::reportModInstances(const char * kextIdentifier)
-{
- OSKext::reportOSMetaClassInstances(kextIdentifier,
- kOSKextLogExplicitLevel);
- return;
-}
-/*********************************************************************
-*********************************************************************/
-
-void
-OSMetaClass::addInstance(const OSObject * instance, bool super) const
-{
- if (!super) {
- IOLockLock(sInstancesLock);
+ }
+ reserved->instances->setLastObject(instance);
+
+ if (!super) IOLockUnlock(sInstancesLock);
+}
+
+void
+OSMetaClass::removeInstance(const OSObject * instance, bool super) const
+{
+ if (!super) IOLockLock(sInstancesLock);
+
+ if (reserved->instances) {
+ reserved->instances->removeObject(instance);
+ if (0 == reserved->instances->getCount()) {
+ if (superClassLink) {
+ superClassLink->removeInstance(reserved->instances, true);
+ }
+ IOLockLock(sAllClassesLock);
+ reserved->instances->release();
+ reserved->instances = 0;
+ IOLockUnlock(sAllClassesLock);
}
-
- if (!reserved->instances) {
- reserved->instances = OSOrderedSet::withCapacity(16);
- if (superClassLink) {
- superClassLink->addInstance(reserved->instances, true);
- }
+ }
+
+ if (!super) IOLockUnlock(sInstancesLock);
+}
+
+void
+OSMetaClass::applyToInstances(OSOrderedSet * set,
+ OSMetaClassInstanceApplierFunction applier,
+ void * context)
+{
+ enum { kLocalDepth = 24 };
+ unsigned int _nextIndex[kLocalDepth];
+ OSOrderedSet * _sets[kLocalDepth];
+ unsigned int * nextIndex = &_nextIndex[0];
+ OSOrderedSet ** sets = &_sets[0];
+ OSObject * obj;
+ OSOrderedSet * childSet;
+ unsigned int maxDepth;
+ unsigned int idx;
+ unsigned int level;
+ bool done;
+
+ maxDepth = sDeepestClass;
+ if (maxDepth > kLocalDepth)
+ {
+ nextIndex = IONew(typeof(nextIndex[0]), maxDepth);
+ sets = IONew(typeof(sets[0]), maxDepth);
+ }
+ done = false;
+ level = 0;
+ idx = 0;
+ do
+ {
+ while (!done && (obj = set->getObject(idx++)))
+ {
+ if ((childSet = OSDynamicCast(OSOrderedSet, obj)))
+ {
+ if (level >= maxDepth) panic(">maxDepth");
+ sets[level] = set;
+ nextIndex[level] = idx;
+ level++;
+ set = childSet;
+ idx = 0;
+ break;
+ }
+ done = (*applier)(obj, context);
}
- reserved->instances->setLastObject(instance);
-
- if (!super) {
- IOLockUnlock(sInstancesLock);
+ if (!obj)
+ {
+ if (!done && level)
+ {
+ level--;
+ set = sets[level];
+ idx = nextIndex[level];
+ } else done = true;
}
-}
-
-void
-OSMetaClass::removeInstance(const OSObject * instance, bool super) const
-{
- if (!super) {
- IOLockLock(sInstancesLock);
- }
-
- if (reserved->instances) {
- reserved->instances->removeObject(instance);
- if (0 == reserved->instances->getCount()) {
- if (superClassLink) {
- superClassLink->removeInstance(reserved->instances, true);
- }
- IOLockLock(sAllClassesLock);
- reserved->instances->release();
- reserved->instances = NULL;
- IOLockUnlock(sAllClassesLock);
- }
- }
-
- if (!super) {
- IOLockUnlock(sInstancesLock);
- }
-}
-
-void
-OSMetaClass::applyToInstances(OSOrderedSet * set,
- OSMetaClassInstanceApplierFunction applier,
- void * context)
-{
- enum { kLocalDepth = 24 };
- unsigned int _nextIndex[kLocalDepth];
- OSOrderedSet * _sets[kLocalDepth];
- unsigned int * nextIndex = &_nextIndex[0];
- OSOrderedSet ** sets = &_sets[0];
- OSObject * obj;
- OSOrderedSet * childSet;
- unsigned int maxDepth;
- unsigned int idx;
- unsigned int level;
- bool done;
-
- maxDepth = sDeepestClass;
- if (maxDepth > kLocalDepth) {
- nextIndex = IONewData(typeof(nextIndex[0]), maxDepth);
- sets = IONew(typeof(sets[0]), maxDepth);
- }
- done = false;
- level = 0;
- idx = 0;
- do{
- while (!done && (obj = set->getObject(idx++))) {
- if ((childSet = OSDynamicCast(OSOrderedSet, obj))) {
- if (level >= maxDepth) {
- panic(">maxDepth");
- }
- sets[level] = set;
- nextIndex[level] = idx;
- level++;
- set = childSet;
- idx = 0;
- break;
- }
- done = (*applier)(obj, context);
- }
- if (!obj) {
- if (!done && level) {
- level--;
- set = sets[level];
- idx = nextIndex[level];
- } else {
- done = true;
- }
- }
- }while (!done);
- if (maxDepth > kLocalDepth) {
- IODeleteData(nextIndex, typeof(nextIndex[0]), maxDepth);
- IODelete(sets, typeof(sets[0]), maxDepth);
- }
+ }
+ while (!done);
+ if (maxDepth > kLocalDepth)
+ {
+ IODelete(nextIndex, typeof(nextIndex[0]), maxDepth);
+ IODelete(sets, typeof(sets[0]), maxDepth);
+ }
}
void
OSMetaClass::applyToInstances(OSMetaClassInstanceApplierFunction applier,
- void * context) const
-{
- IOLockLock(sInstancesLock);
- if (reserved->instances) {
- applyToInstances(reserved->instances, applier, context);
- }
- IOLockUnlock(sInstancesLock);
+ void * context) const
+{
+ IOLockLock(sInstancesLock);
+ if (reserved->instances) applyToInstances(reserved->instances, applier, context);
+ IOLockUnlock(sInstancesLock);
}
void
OSMetaClass::applyToInstancesOfClassName(
- const OSSymbol * name,
- OSMetaClassInstanceApplierFunction applier,
- void * context)
-{
- OSMetaClass * meta;
- OSOrderedSet * set = NULL;
-
- IOLockLock(sAllClassesLock);
- if (sAllClassesDict
- && (meta = (OSMetaClass *) sAllClassesDict->getObject(name))
- && (set = meta->reserved->instances)) {
- set->retain();
- }
- IOLockUnlock(sAllClassesLock);
-
- if (!set) {
- return;
- }
-
- IOLockLock(sInstancesLock);
- applyToInstances(set, applier, context);
- IOLockUnlock(sInstancesLock);
- set->release();
+ const OSSymbol * name,
+ OSMetaClassInstanceApplierFunction applier,
+ void * context)
+{
+ OSMetaClass * meta;
+ OSOrderedSet * set = 0;
+
+ IOLockLock(sAllClassesLock);
+ if (sAllClassesDict
+ && (meta = (OSMetaClass *) sAllClassesDict->getObject(name))
+ && (set = meta->reserved->instances))
+ {
+ set->retain();
+ }
+ IOLockUnlock(sAllClassesLock);
+
+ if (!set) return;
+
+ IOLockLock(sInstancesLock);
+ applyToInstances(set, applier, context);
+ IOLockUnlock(sInstancesLock);
+ set->release();
}
/*********************************************************************
@@ -1185,98 +923,27 @@
void
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;
-}
-
+ OSKext::considerUnloads();
+}
/*********************************************************************
*********************************************************************/
const OSMetaClass *
OSMetaClass::getMetaClassWithName(const OSSymbol * name)
{
- OSMetaClass * retMeta = NULL;
-
- if (!name) {
- return NULL;
- }
-
- IOLockLock(sAllClassesLock);
- if (sAllClassesDict) {
- retMeta = (OSMetaClass *) sAllClassesDict->getObject(name);
- }
- IOLockUnlock(sAllClassesLock);
-
- return retMeta;
-}
-
-/*********************************************************************
-*********************************************************************/
-const OSMetaClass *
-OSMetaClass::copyMetaClassWithName(const OSSymbol * name)
-{
- const OSMetaClass * meta;
-
- if (!name) {
- return NULL;
- }
-
- meta = NULL;
- 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);
+ OSMetaClass * retMeta = 0;
+
+ if (!name) {
+ return 0;
+ }
+
+ IOLockLock(sAllClassesLock);
+ if (sAllClassesDict) {
+ retMeta = (OSMetaClass *) sAllClassesDict->getObject(name);
+ }
+ IOLockUnlock(sAllClassesLock);
+
+ return retMeta;
}
/*********************************************************************
@@ -1284,17 +951,15 @@
OSObject *
OSMetaClass::allocClassWithName(const OSSymbol * name)
{
- const OSMetaClass * meta;
- OSObject * result;
-
- result = NULL;
- meta = copyMetaClassWithName(name);
- if (meta) {
- result = meta->alloc();
- meta->releaseMetaClass();
- }
-
- return result;
+ OSObject * result = 0;
+
+ const OSMetaClass * const meta = getMetaClassWithName(name);
+
+ if (meta) {
+ result = meta->alloc();
+ }
+
+ return result;
}
/*********************************************************************
@@ -1302,10 +967,10 @@
OSObject *
OSMetaClass::allocClassWithName(const OSString * name)
{
- const OSSymbol * tmpKey = OSSymbol::withString(name);
- OSObject * result = allocClassWithName(tmpKey);
- tmpKey->release();
- return result;
+ const OSSymbol * tmpKey = OSSymbol::withString(name);
+ OSObject * result = allocClassWithName(tmpKey);
+ tmpKey->release();
+ return result;
}
/*********************************************************************
@@ -1313,10 +978,10 @@
OSObject *
OSMetaClass::allocClassWithName(const char * name)
{
- const OSSymbol * tmpKey = OSSymbol::withCStringNoCopy(name);
- OSObject * result = allocClassWithName(tmpKey);
- tmpKey->release();
- return result;
+ const OSSymbol * tmpKey = OSSymbol::withCStringNoCopy(name);
+ OSObject * result = allocClassWithName(tmpKey);
+ tmpKey->release();
+ return result;
}
@@ -1324,86 +989,83 @@
*********************************************************************/
OSMetaClassBase *
OSMetaClass::checkMetaCastWithName(
- const OSSymbol * name,
- const OSMetaClassBase * in)
-{
- OSMetaClassBase * result = NULL;
-
- const OSMetaClass * const meta = getMetaClassWithName(name);
-
- if (meta) {
- result = meta->checkMetaCast(in);
- }
-
- return result;
-}
-
-/*********************************************************************
-*********************************************************************/
-OSMetaClassBase *
-OSMetaClass::
+ const OSSymbol * name,
+ const OSMetaClassBase * in)
+{
+ OSMetaClassBase * result = 0;
+
+ const OSMetaClass * const meta = getMetaClassWithName(name);
+
+ if (meta) {
+ result = meta->checkMetaCast(in);
+ }
+
+ return result;
+}
+
+/*********************************************************************
+*********************************************************************/
+OSMetaClassBase * OSMetaClass::
checkMetaCastWithName(
- const OSString * name,
- const OSMetaClassBase * in)
-{
- const OSSymbol * tmpKey = OSSymbol::withString(name);
- OSMetaClassBase * result = checkMetaCastWithName(tmpKey, in);
-
- tmpKey->release();
- return result;
+ 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);
-
- 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;
-
- for (fromMeta = check->getMetaClass();; fromMeta = fromMeta->superClassLink) {
- if (toMeta == fromMeta) {
- return const_cast<OSMetaClassBase *>(check); // Discard const
- }
- if (!fromMeta->superClassLink) {
- break;
- }
- }
-
- return NULL;
-}
-
-/*********************************************************************
-*********************************************************************/
-__dead2
+ 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;
+
+ for (fromMeta = check->getMetaClass(); ; fromMeta = fromMeta->superClassLink) {
+ if (toMeta == fromMeta) {
+ return const_cast<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 char * cname = className->getCStringNoCopy();
+ panic("%s::_RESERVED%s%d called.", cname, cname, ind);
}
/*********************************************************************
@@ -1412,27 +1074,20 @@
OSMetaClass *
OSMetaClass::getSuperClass() const
{
- return superClassLink;
-}
-
-/*********************************************************************
+ return superClassLink;
+}
+
+/*********************************************************************
+* xxx - I want to rename this :-/
*********************************************************************/
const OSSymbol *
OSMetaClass::getKmodName() const
{
- OSKext * myKext = reserved ? reserved->kext : NULL;
- if (myKext) {
- return myKext->getIdentifier();
- }
- return OSSymbol::withCStringNoCopy("unknown");
-}
-
-/*********************************************************************
-*********************************************************************/
-OSKext *
-OSMetaClass::getKext() const
-{
- return reserved ? reserved->kext : NULL;
+ OSKext * myKext = reserved ? reserved->kext : 0;
+ if (myKext) {
+ return myKext->getIdentifier();
+ }
+ return OSSymbol::withCStringNoCopy("unknown");
}
/*********************************************************************
@@ -1440,7 +1095,7 @@
unsigned int
OSMetaClass::getInstanceCount() const
{
- return instanceCount;
+ return instanceCount;
}
/*********************************************************************
@@ -1449,28 +1104,28 @@
void
OSMetaClass::printInstanceCounts()
{
- OSCollectionIterator * classes;
- OSSymbol * className;
- OSMetaClass * meta;
-
- IOLockLock(sAllClassesLock);
- classes = OSCollectionIterator::withCollection(sAllClassesDict);
- assert(classes);
-
- 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());
- }
- printf("\n");
- classes->release();
- IOLockUnlock(sAllClassesLock);
- return;
+ OSCollectionIterator * classes;
+ OSSymbol * className;
+ OSMetaClass * meta;
+
+ IOLockLock(sAllClassesLock);
+ classes = OSCollectionIterator::withCollection(sAllClassesDict);
+ assert(classes);
+
+ 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() );
+ }
+ printf("\n");
+ classes->release();
+ IOLockUnlock(sAllClassesLock);
+ return;
}
/*********************************************************************
@@ -1478,8 +1133,8 @@
OSDictionary *
OSMetaClass::getClassDictionary()
{
- panic("OSMetaClass::getClassDictionary() is obsoleted.");
- return NULL;
+ panic("OSMetaClass::getClassDictionary() is obsoleted.\n");
+ return 0;
}
/*********************************************************************
@@ -1487,8 +1142,8 @@
bool
OSMetaClass::serialize(__unused OSSerialize * s) const
{
- panic("OSMetaClass::serialize(): Obsoleted");
- return false;
+ panic("OSMetaClass::serialize(): Obsoleted\n");
+ return false;
}
/*********************************************************************
@@ -1497,115 +1152,44 @@
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);
+ 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:
- OSSafeReleaseNULL(classDict);
-
- IOLockUnlock(sAllClassesLock);
-
- return;
-}
-
-
-/*********************************************************************
-*********************************************************************/
-
-#if IOTRACKING
-
-__typed_allocators_ignore_push
-
-void *
-OSMetaClass::trackedNew(size_t size)
-{
- IOTracking * mem;
-
- mem = (typeof(mem))kheap_alloc(KHEAP_DEFAULT, size + sizeof(IOTracking),
- Z_VM_TAG_BT(Z_WAITOK, VM_KERN_MEMORY_LIBKERN));
- assert(mem);
- if (!mem) {
- return mem;
- }
-
- memset(mem, 0, size + sizeof(IOTracking));
- mem++;
-
- OSIVAR_ACCUMSIZE(size);
-
- return mem;
-}
-
-void
-OSMetaClass::trackedDelete(void * instance, size_t size)
-{
- IOTracking * mem = (typeof(mem))instance; mem--;
-
- kheap_free(KHEAP_DEFAULT, mem, size + sizeof(IOTracking));
- OSIVAR_ACCUMSIZE(-size);
-}
-
-__typed_allocators_ignore_pop
-
-void
-OSMetaClass::trackedInstance(OSObject * instance) const
-{
- IOTracking * mem = (typeof(mem))instance; mem--;
-
- return IOTrackingAdd(reserved->tracking, mem, classSize, false, VM_KERN_MEMORY_NONE);
-}
-
-void
-OSMetaClass::trackedFree(OSObject * instance) const
-{
- IOTracking * mem = (typeof(mem))instance; mem--;
-
- return IOTrackingRemove(reserved->tracking, mem, classSize);
-}
-
-void
-OSMetaClass::trackedAccumSize(OSObject * instance, size_t size) const
-{
- IOTracking * mem = (typeof(mem))instance; mem--;
-
- return IOTrackingAccumSize(reserved->tracking, mem, size);
-}
-
-IOTrackingQueue *
-OSMetaClass::getTracking() const
-{
- return reserved->tracking;
-}
-
-#endif /* IOTRACKING */
+ OSSafeRelease(classDict);
+
+ IOLockUnlock(sAllClassesLock);
+
+ return;
+}