OSMetaClass |
Inherits from: | |
Declared In: |
OSMetaClass manages run-time type information for Libkern and I/O Kit C++ classes.
OSMetaClass manages run-time type information for Libkern and I/O Kit C++ classes. An instance of OSMetaClass exists for (nearly) every such C++ class, keeping track of inheritance relationships, class lookup by name, instance counts, and more. OSMetaClass operates almost entirely behind the scenes, and kernel extensions should rarely, if ever, have to interact directly with OSMetaClass.
Use by Kernel Extensions
While kernel extensions rarey interact directly with OSMetaClass at run time, they must register their classes with the metaclass system using the macros declared here. The class declaration should use one of these two macros before its first member function declaration:
OSDeclareDefaultStructors
-
for classes with no abstract member function declarations
OSDeclareAbstractStructors
-
for classes with at least one abstract member function declaration
OSDeclareFinalStructors
-
for classes that should not be subclassable by another kext
The class implementation should then use one of these macros:
OSDefineMetaClassAndStructors
-
for classes with no abstract member function declarations
OSDefineMetaClassAndAbstractStructors
-
for classes with at least one abstract member function declaration
OSDefineMetaClassAndFinalStructors
-
for classes that should not be subclassable by another kext
Classes in kernel extensions that are intended for use as libraries may need to reserve vtable slots to preserve binary compatibility as new functions are added. They may do so with these macros:
OSMetaClassDeclareReservedUnused
-
reserves a vtable slot
OSMetaClassDefineReservedUnused
-
defines the reserved vtable slot as an unimplemented function
OSMetaClassDeclareReservedUsed
-
documents that a formerly reserved slot is now used
OSMetaClassDefineReservedUsed
-
documents that a formerly reserved slot is now used
Use Restrictions
OSMetaClass should not be explicitly subclassed by kernel extensions (the declare/define macros do that), nor should kernel extensions call its run-time type functions directly.
OSMetaClass functions should be considered unsafe to call in a primary interrupt context.
Concurrency Protection
Kernel extensions should in general not interact with OSMetaClass objects directly, instead using the run-time type macros. Much of OSMetaClass's interface is intended for use by the run-time type information system, which handles concurrency and locking internally.
Allocates an instance of the C++ class managed by this metaclass.
Allocates an instance of a named OSObject-derived class.
Allocates an instance of a named OSObject-derived class.
Allocates an instance of a named OSObject-derived class.
Check whether a given object is an instance of the receiving metaclass's class or one derived from it.
Search the metaclass inheritance hierarchy by name for an object instance.
Search the metaclass inheritance hierarchy by name for an object instance.
Search the metaclass inheritance hierarchy by name for an object instance.
Checks whether the current kext load operation can proceed.
Schedule automatic unloading of unused kernel extensions.
Returns the name of the C++ class managed by this metaclass.
Returns the allocation size of the C++ class managed by this metaclass.
Returns the number of existing instances of the metaclass's class.
Returns the bundle identifier of the kernel extension that defines this metaclass.
Look up a metaclass in the run-time type information system.
Implements the abstract getRetainCount
function to return 0.
Returns the super-metaclass of the receiver.
Counts the instances of the class managed by this metaclass.
Counts the instances of the class managed by this metaclass.
Returns whether any classes defined by the named kernel extension (or their subclasses) have existing instances.
Constructor for OSMetaClass objects.
Registers the metaclasses created during loading of a kernel extension.
Prepares the run-time type system for the creation of new metaclasses during loading of a kernel extension (module).
Implements the abstract release
function to do nothing.
Implements the abstract release(int freeWhen)
function to do nothing.
Logs the instance counts for classes defined by a kernel extension.
Implements the abstract retain
function to do nothing.
Implements the abstract taggedRelease(const void *)
function to do nothing.
Implements the abstract taggedRelease(const void *, cont int)
function to do nothing.
Implements the abstract taggedRetain(const void *)
function to do nothing.
Destructor for OSMetaClass objects.
alloc |
Allocates an instance of the C++ class managed by this metaclass.
public
virtual OSObject * alloc() const = 0;
A pointer to the newly allocated, uninitialized instance,
with a retain count of 1; NULL
on allocation failure.
This function is automatically created by the metaclass-registration macros to enable dynamic instance allocation.
allocClassWithName |
Allocates an instance of a named OSObject-derived class.
public
static OSObject * allocClassWithName( const char *name);
name
The name of the desired class.
A pointer to the newly-allocated, uninitialized object on success;
NULL
on failure.
function allocClassWithName
allocClassWithName(const OSString *) |
Allocates an instance of a named OSObject-derived class.
name
The name of the desired class.
A pointer to the newly-allocated, uninitialized object on success;
NULL
on failure.
function allocClassWithName
allocClassWithName(const OSSymbol *) |
Allocates an instance of a named OSObject-derived class.
name
The name of the desired class.
A pointer to the newly-allocated, uninitialized object on success;
NULL
on failure.
Kernel extensions should not need to use this function directly, instead using static instance-creation functions defined by classes.
This function consults the run-time type information system
to find the metaclass for the named class.
If it exists, it calls the metaclass's alloc
function and returns the result.
checkMetaCast |
Check whether a given object is an instance of the receiving metaclass's class or one derived from it.
public
OSMetaClassBase * checkMetaCast( const OSMetaClassBase *object) const;
object
The object to check for inheritance.
object
if it is derived from the receiver's class,
NULL
if not.
checkMetaCastWithName |
Search the metaclass inheritance hierarchy by name for an object instance.
public
static OSMetaClassBase * checkMetaCastWithName( const char *className, const OSMetaClassBase *object);
className
The name of the desired class or superclass.
object
The object whose metaclass begins the search.
object
if it's derived from className
;
NULL
otherwise.
Kernel extensions should not use this function directly,
instead using OSDynamicCast
or
OSCheckTypeInst
.
checkMetaCastWithName(const OSString *, const OSMetaClassBase *) |
Search the metaclass inheritance hierarchy by name for an object instance.
public
static OSMetaClassBase * checkMetaCastWithName( const OSString *className, const OSMetaClassBase *object);
className
The name of the desired class or superclass.
object
The object whose metaclass begins the search.
object
if it's derived from className
;
NULL
otherwise.
Kernel extensions should not use this function directly,
instead using OSDynamicCast
or
OSCheckTypeInst
.
checkMetaCastWithName(const OSSymbol *, const OSMetaClassBase *) |
Search the metaclass inheritance hierarchy by name for an object instance.
public
static OSMetaClassBase * checkMetaCastWithName( const OSSymbol *className, const OSMetaClassBase *object);
className
The name of the desired class or superclass.
object
The object whose metaclass begins the search.
object
if it's derived from className
;
NULL
otherwise.
This function is the basis of the Libkern run-time type-checking system.
Kernel extensions should not use it directly,
instead using OSDynamicCast
or
OSCheckTypeInst
.
checkModLoad |
Checks whether the current kext load operation can proceed.
public
static bool checkModLoad( void *loadHandle);
loadHandle
The opaque handle returned
by preModLoad
.
true
if no errors are outstanding
and the system is ready to process more metaclasses.
Not for use by kernel extensions.
considerUnloads |
Schedule automatic unloading of unused kernel extensions.
public
static void considerUnloads();
This function schedules a check for kernel extensions that can be automatically unloaded, canceling any currently scheduled check. At that time, any such kexts with no Libkern C++ instances and no external references are unloaded.
The I/O Kit calls this function when matching goes idle.
Kernel extensions that define subclasses of IOService are eligible for automatic unloading.
(On releases of Mac OS X prior to Snow Leopard (10.6), any kernel extension defining any Libkern C++ class was eligible for automatic unloading, but that unload did not call the module stop routine. Non-I/O Kit kernel extensions that define Libkern C++ subclasses should be sure to have OSBundleLibraries declarations that ensure they will not load on releases prior to Snow Leopard.)
getClassName |
Returns the name of the C++ class managed by this metaclass.
public
const char * getClassName() const;
Returns the name of the C++ class managed by this metaclass.
getClassSize |
Returns the allocation size of the C++ class managed by this metaclass.
public
unsigned int getClassSize() const;
The allocation size of the C++ class managed by this metaclass.
getInstanceCount |
Returns the number of existing instances of the metaclass's class.
public
unsigned int getInstanceCount() const;
The number of existing instances of the metaclass's class, plus 1 for each subclass with any instance.
getKmodName |
Returns the bundle identifier of the kernel extension that defines this metaclass.
public
const OSSymbol * getKmodName() const;
The bundle identifier of the kernel extension that defines this metaclass.
"Kmod" is an older term for kernel extension.
getMetaClassWithName |
Look up a metaclass in the run-time type information system.
public
static const OSMetaClass * getMetaClassWithName( const OSSymbol *name);
name
The name of the desired class's metaclass.
A pointer to the metaclass object if found, NULL
otherwise.
getRetainCount |
Implements the abstract getRetainCount
function to return 0.
protected
virtual int getRetainCount() const;
Always returns 0.
Since an OSMetaClass instance must remain in existence for as long as its kernel extension is loaded, OSMetaClass does not use reference-counting.
getSuperClass |
Returns the super-metaclass of the receiver.
public
const OSMetaClass * getSuperClass() const;
Returns a pointer to the super-metaclass of the receiving
OSMetaClass, or NULL
for OSObject's metaclass.
instanceConstructed |
Counts the instances of the class managed by this metaclass.
public
void instanceConstructed() const;
Not for use by kernel extensions.
Every non-abstract class that inherits from OSObject
has a default constructor that calls it's own metaclass's
instanceConstructed
function.
This constructor is defined by the
OSDefineMetaClassAndStructors
macro that all OSObject subclasses must use.
If a class's instance count goes from 0 to 1--that is, upon the creation of the first instance of that class--the superclass's instance count is also incremented. This propagates reference counts up the inheritance chain so that superclasses are counted as "in use" when subclasses have instances.
instanceDestructed |
Counts the instances of the class managed by this metaclass.
public
void instanceDestructed() const;
Every non-abstract class that inherits from OSObject
has a default destructor that calls it's own metaclass's
instanceDestructed
function.
This constructor is defined by the
OSDefineMetaClassAndStructors
macro that all OSObject subclasses must use.
If a class's instance count goes from 1 to 0--that is, upon the destruction of the last instance of that class--the superclass's instance count is also decremented. This reduces "in use" counts from superclasses when their subclasses no longer have instances.
modHasInstance |
Returns whether any classes defined by the named kernel extension (or their subclasses) have existing instances.
public
static bool modHasInstance( const char *kextID);
kextID
The bundle ID of the kernel extension to check.
true
if the kext is found and
if any class defined by that kext
has a nonzero instance count,
false
otherwise.
This function is called before a kernel extension's static destructors
are invoked, prior to unloading the extension.
If any classes stil have instances or subclasses with instances,
those classes are logged
(using reportModInstances
) and
the kernel extension is not be unloaded.
OSMetaClass |
Constructor for OSMetaClass objects.
protected
OSMetaClass( const char *className, const OSMetaClass *superclass, unsigned int classSize);
className
A C string naming the C++ class that this OSMetaClass represents.
superclass
The OSMetaClass object representing the superclass of this metaclass's class.
classSize
The allocation size of the represented C++ class.
This constructor is protected and cannot be used
to instantiate OSMetaClass directly, as OSMetaClass is an abstract class.
This function is called during kext loading
to queue C++ classes for registration.
See preModLoad
and
postModLoad
.
postModLoad |
Registers the metaclasses created during loading of a kernel extension.
loadHandle
The opaque handle returned
by preModLoad
.
The error code of the first error encountered,
or
kOSReturnSuccess
if no error occurred.
Not for use by kernel extensions.
Called after all static constructors in a kernel extension
have created metaclasses,
this function checks for duplicate class names,
then registers the new metaclasses under the kext ID
that preModLoad was called with,
so that they can be dynamically allocated
and have their instance counts tracked.
postModLoad
releases the lock taken by
preModLoad
.
preModLoad |
Prepares the run-time type system for the creation of new metaclasses during loading of a kernel extension (module).
public
static void * preModLoad( const char *kextID);
kextID
The bundle ID of the kext being loaded.
An opaque handle to the load context
for the kernel extension on success;
NULL
on failure.
Not for use by kernel extensions.
Prepares the run-time type information system to record and register
metaclasses created by static constructors until a subsequent call to
postModLoad
.
preModLoad
takes a lock to ensure processing of a single
load operation at a time; the lock is released by
postModLoad
.
Any OSMetaClass constructed between these two function calls
will be associated with kextID
.
release() |
Implements the abstract release
function to do nothing.
protected
virtual void release() const;
Since an OSMetaClass instance must remain in existence for as long as its kernel extension is loaded, OSMetaClass does not use reference-counting.
release(int) |
Implements the abstract release(int freeWhen)
function to do nothing.
protected
virtual void release( int freeWhen) const;
freeWhen
Unused.
Since an OSMetaClass instance must remain in existence for as long as its kernel extension is loaded, OSMetaClass does not use reference-counting.
reportModInstances |
Logs the instance counts for classes defined by a kernel extension.
public
static void reportModInstances( const char *kextID);
kextID
The bundle ID of the kernel extension to report on.
This function prints the names and instance counts
of any class defined by kextID
that has a nonzero instance count.
It's called by modHasInstance
to help diagnose problems unloading kernel extensions.
retain |
Implements the abstract retain
function to do nothing.
protected
virtual void retain() const;
Since an OSMetaClass instance must remain in existence for as long as its kernel extension is loaded, OSMetaClass does not use reference-counting.
taggedRelease(const void *) |
Implements the abstract taggedRelease(const void *)
function to do nothing.
tag
Unused.
Since an OSMetaClass instance must remain in existence for as long as its kernel extension is loaded, OSMetaClass does not use reference-counting.
taggedRelease(const void *, const int) |
Implements the abstract taggedRelease(const void *, cont int)
function to do nothing.
tag
Unused.
freeWhen
Unused.
Since an OSMetaClass instance must remain in existence for as long as its kernel extension is loaded, OSMetaClass does not use reference-counting.
taggedRetain |
Implements the abstract taggedRetain(const void *)
function to do nothing.
tag
Unused.
Since an OSMetaClass instance must remain in existence for as long as its kernel extension is loaded, OSMetaClass does not use reference-counting.
~OSMetaClass |
Destructor for OSMetaClass objects.
protected
virtual ~OSMetaClass();
This function is called when the kernel extension that implements the metaclass's class is unloaded. The destructor removes all references to the class from the run-time type information system.
Declares run-time type information and functions for an abstract Libkern C++ class.
Declares run-time type information and functions for a concrete Libkern C++ class.
Declares run-time type information and functions for a final (non-subclassable) Libkern C++ class.
Defines an OSMetaClass and associated routines for an abstract Libkern C++ class.
Defines an OSMetaClass and associated routines for a final (non-subclassable) Libkern C++ class.
Defines an OSMetaClass and associated routines for a concrete Libkern C++ class.
Reserves vtable space for new virtual functions in a Libkern C++ class.
Documents use of reserved vtable space for new virtual functions in a Libkern C++ class.
Defines a reserved vtable slot for a Libkern C++ class.
Reserves vtable space for new virtual functions in a Libkern C++ class.
OSDeclareAbstractStructors |
Declares run-time type information and functions for an abstract Libkern C++ class.
#define OSDeclareAbstractStructors(className)
className
The name of the C++ class, as a raw token, not a string or macro.
Abstract Libkern C++ classes--those with at least one
pure virtual method--should "call" this macro
immediately after the opening brace in a class declaration.
It leaves the current privacy state as protected:
.
OSDeclareDefaultStructors |
Declares run-time type information and functions for a concrete Libkern C++ class.
#define OSDeclareDefaultStructors(className)
className
The name of the C++ class, as a raw token, not a string or macro.
Concrete Libkern C++ classes should "call" this macro
immediately after the opening brace in a class declaration.
It leaves the current privacy state as protected:
.
OSDeclareFinalStructors |
Declares run-time type information and functions for a final (non-subclassable) Libkern C++ class.
#define OSDeclareFinalStructors(className)
className
The name of the C++ class, as a raw token, not a string or macro.
Final Libkern C++ classes--those that do not allow subclassing--should
"call" this macro immediately after the opening brace in a class declaration.
(Final classes in the kernel may actually have subclasses in the kernel,
but kexts cannot define any subclasses of a final class.)
It leaves the current privacy state as protected:
.
Note: If the class is exported by a pseudokext (symbol set), the final symbol generated by this macro must be exported for the final-class attribute to be enforced.
Warning: Changing a class from "Default" to "Final" will break binary compatibility.
OSDefineMetaClassAndAbstractStructors |
Defines an OSMetaClass and associated routines for an abstract Libkern C++ class.
#define OSDefineMetaClassAndAbstractStructors(className, superclassName)
className
The name of the C++ class, as a raw token, not a string or macro.
superclassName
The name of the superclass of the C++ class, as a raw token, not a string or macro.
Abstract Libkern C++ classes--those with at least one pure virtual method--should "call" this macro at the beginning of their implementation files, before any function implementations for the class.
OSDefineMetaClassAndFinalStructors |
Defines an OSMetaClass and associated routines for a final (non-subclassable) Libkern C++ class.
#define OSDefineMetaClassAndFinalStructors(className, superclassName)
className
The name of the C++ class, as a raw token, not a string or macro.
superclassName
The name of the superclass of the C++ class, as a raw token, not a string or macro.
Final Libkern C++ classes--those that do not allow subclassing--should "call" this macro at the beginning of their implementation files, before any function implementations for the class. (Final classes in the kernel may actually have subclasses in the kernel, but kexts cannot define any subclasses of a final class.)
Note: If the class is exported by a pseudokext (symbol set), the final symbol generated by this macro must be exported for the final-class attribute to be enforced.
Warning: Changing a class from "Default" to "Final" will break binary compatibility.
OSDefineMetaClassAndStructors |
Defines an OSMetaClass and associated routines for a concrete Libkern C++ class.
#define OSDefineMetaClassAndStructors(className, superclassName)
className
The name of the C++ class, as a raw token, not a string or macro.
superclassName
The name of the superclass of the C++ class, as a raw token, not a string or macro.
Concrete Libkern C++ classes should "call" this macro at the beginning of their implementation files, before any function implementations for the class.
OSMetaClassDeclareReservedUnused |
Reserves vtable space for new virtual functions in a Libkern C++ class.
#define OSMetaClassDeclareReservedUnused(className, index)
className
The name of the C++ class, as a raw token, not a string or macro.
index
The numeric index of the vtable slot, as a raw constant, beginning from 0.
Libkern C++ classes in kernel extensions that can be used as libraries
can provide for backward compatibility by declaring a number
of reserved vtable slots
that can be replaced with new functions as they are added.
Each reserved declaration must be accompanied in the implementation
by a corresponding reference to
OSMetaClassDefineReservedUnused
.
When replacing a reserved slot, change the macro from "Unused"
to "Used" to document the fact that the slot used to be reserved,
and declare the new function immediately after the "Used" macro
to preserve vtable ordering.
See
OSMetaClassDeclareReservedUsed
.
OSMetaClassDeclareReservedUsed |
Documents use of reserved vtable space for new virtual functions in a Libkern C++ class.
#define OSMetaClassDeclareReservedUsed(className, index)
className
The name of the C++ class, as a raw token, not a string or macro.
index
The numeric index of the vtable slot, as a raw constant, beginning from 0.
This macro evaluates to nothing, and is used to document reserved
vtable slots as they are filled.
See
OSMetaClassDeclareReservedUnused
.
OSMetaClassDefineReservedUnused |
Defines a reserved vtable slot for a Libkern C++ class.
#define OSMetaClassDefineReservedUnused(className, index)
className
The name of the C++ class, as a raw token, not a string or macro.
index
The numeric index of the vtable slot, as a raw constant, beginning from 0.
Libkern C++ classes in kernel extensions that can be used as libraries
can provide for backward compatibility by declaring a number
of reserved vtable slots
that can be replaced with new functions as they are added.
Each reserved defintion accompanies
a corresponding declaration created with
OSMetaClassDeclareReservedUnused
.
This macro is used in the implementation file
to provide a placeholder definition for the reserved vtable slot,
as a function that calls panic
with an error message.
When replacing a reserved slot, change the macro from "Unused"
to "Used" to document the fact that the slot used to be reserved,
and declare the new function immediately after the "Used" macro
to preserve vtable ordering.
See
OSMetaClassDefineReservedUsed
.
OSMetaClassDefineReservedUsed |
Reserves vtable space for new virtual functions in a Libkern C++ class.
#define OSMetaClassDefineReservedUsed(className, index)
className
The name of the C++ class, as a raw token, not a string or macro.
index
The numeric index of the vtable slot, as a raw constant, beginning from 0.
This macro evaluates to nothing, and is used to document reserved
vtable slots as they are filled.
See
OSMetaClassDefineReservedUnused
.
Last Updated: 2010-07-29