OSMetaClass

Inherits from
OSMetaClassBase
Availability
Available in OS X v10.0 and later.
Declared in
OSMetaClass.h

Overview

Tasks

Miscellaneous

Instance Methods

Reserves vtable space for new virtual functions in a Libkern C++ class.

#if 1
#define OSMetaClassDeclareReservedUnused(className, index)
#else
#define OSMetaClassDeclareReservedUnused(className, index)
#endif
Parameters
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.

Discussion

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.

Defines a reserved vtable slot for a Libkern C++ class.

#if 1
#define OSMetaClassDefineReservedUnused(className, index)
#else
#define OSMetaClassDefineReservedUnused(className, index)
#endif
Parameters
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.

Discussion

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.

alloc

Allocates an instance of the C++ class managed by this metaclass.

virtual OSObject * alloc() const = 0;
Return Value

A pointer to the newly allocated, uninitialized instance, with a retain count of 1; NULL on allocation failure.

Discussion

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.

static OSObject * allocClassWithName( const char *name);
Parameters
name

The name of the desired class.

Return Value

A pointer to the newly-allocated, uninitialized object on success; NULL on failure.

Discussion

function allocClassWithName

allocClassWithName(const OSString *)

Allocates an instance of a named OSObject-derived class.

static OSObject * allocClassWithName( const OSString *name);
Parameters
name

The name of the desired class.

Return Value

A pointer to the newly-allocated, uninitialized object on success; NULL on failure.

Discussion

function allocClassWithName

allocClassWithName(const OSSymbol *)

Allocates an instance of a named OSObject-derived class.

static OSObject * allocClassWithName( const OSSymbol *name);
Parameters
name

The name of the desired class.

Return Value

A pointer to the newly-allocated, uninitialized object on success; NULL on failure.

Discussion

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.

OSMetaClassBase * checkMetaCast( const OSMetaClassBase *object) const;
Parameters
object

The object to check for inheritance.

Return Value

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.

static OSMetaClassBase * checkMetaCastWithName( const char *className, const OSMetaClassBase *object);
Parameters
className

The name of the desired class or superclass.

object

The object whose metaclass begins the search.

Return Value

object if it's derived from className; NULL otherwise.

Discussion

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.

static OSMetaClassBase * checkMetaCastWithName( const OSString *className, const OSMetaClassBase *object);
Parameters
className

The name of the desired class or superclass.

object

The object whose metaclass begins the search.

Return Value

object if it's derived from className; NULL otherwise.

Discussion

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.

static OSMetaClassBase * checkMetaCastWithName( const OSSymbol *className, const OSMetaClassBase *object);
Parameters
className

The name of the desired class or superclass.

object

The object whose metaclass begins the search.

Return Value

object if it's derived from className; NULL otherwise.

Discussion

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.

static bool checkModLoad( void *loadHandle);
Parameters
loadHandle

The opaque handle returned by preModLoad.

Return Value

true if no errors are outstanding and the system is ready to process more metaclasses.

Discussion

Not for use by kernel extensions.

considerUnloads

Schedule automatic unloading of unused kernel extensions.

static void considerUnloads();
Discussion

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.

const char * getClassName() const;
Return Value

Returns the name of the C++ class managed by this metaclass.

getClassSize

Returns the allocation size of the C++ class managed by this metaclass.

unsigned int getClassSize() const;
Return Value

The allocation size of the C++ class managed by this metaclass.

getInstanceCount

Returns the number of existing instances of the metaclass's class.

unsigned int getInstanceCount() const;
Return Value

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.

const OSSymbol * getKmodName() const;
Return Value

The bundle identifier of the kernel extension that defines this metaclass.

Discussion

"Kmod" is an older term for kernel extension.

getMetaClassWithName

Look up a metaclass in the run-time type information system.

static const OSMetaClass * getMetaClassWithName( const OSSymbol *name);
Parameters
name

The name of the desired class's metaclass.

Return Value

A pointer to the metaclass object if found, NULL otherwise.

getRetainCount

Implements the abstract getRetainCount function to return 0.

virtual int getRetainCount() const;
Return Value

Always returns 0.

Discussion

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.

const OSMetaClass * getSuperClass() const;
Return Value

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.

void instanceConstructed() const;
Discussion

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.

void instanceDestructed() const;
Discussion

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.

static bool modHasInstance( const char *kextID);
Parameters
kextID

The bundle ID of the kernel extension to check.

Return Value

true if the kext is found and if any class defined by that kext has a nonzero instance count, false otherwise.

Discussion

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.

OSDeclareAbstractStructors

Declares run-time type information and functions for an abstract Libkern C++ class.

#define OSDeclareAbstractStructors(className)
Parameters
className

The name of the C++ class, as a raw token, not a string or macro.

Discussion

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:.

Availability
  • Available in OS X v10.0 and later.
Declared In
OSMetaClass.h

OSDeclareDefaultStructors

Declares run-time type information and functions for a concrete Libkern C++ class.

#define OSDeclareDefaultStructors(className)
Parameters
className

The name of the C++ class, as a raw token, not a string or macro.

Discussion

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:.

Availability
  • Available in OS X v10.0 and later.
Declared In
OSMetaClass.h

OSDeclareFinalStructors

Declares run-time type information and functions for a final (non-subclassable) Libkern C++ class.

#define OSDeclareFinalStructors(className)
Parameters
className

The name of the C++ class, as a raw token, not a string or macro.

Discussion

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.

Availability
  • Available in OS X v10.6 and later.
Declared In
OSMetaClass.h

OSDefineMetaClassAndAbstractStructors

Defines an OSMetaClass and associated routines for an abstract Libkern C++ class.

#define OSDefineMetaClassAndAbstractStructors(className, superclassName)
Parameters
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.

Discussion

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.

Availability
  • Available in OS X v10.0 and later.
Declared In
OSMetaClass.h

OSDefineMetaClassAndFinalStructors

Defines an OSMetaClass and associated routines for a final (non-subclassable) Libkern C++ class.

#define OSDefineMetaClassAndFinalStructors(className, superclassName)
Parameters
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.

Discussion

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.

Availability
  • Available in OS X v10.6 and later.
Declared In
OSMetaClass.h

OSDefineMetaClassAndStructors

Defines an OSMetaClass and associated routines for a concrete Libkern C++ class.

#define OSDefineMetaClassAndStructors(className, superclassName)
Parameters
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.

Discussion

Concrete Libkern C++ classes should "call" this macro at the beginning of their implementation files, before any function implementations for the class.

Availability
  • Available in OS X v10.0 and later.
Declared In
OSMetaClass.h

OSMetaClass

Constructor for OSMetaClass objects.

OSMetaClass( const char *className, const OSMetaClass *superclass, unsigned int classSize);
Parameters
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.

Discussion

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.

OSMetaClassDeclareReservedUsed

Documents use of reserved vtable space for new virtual functions in a Libkern C++ class.

#define OSMetaClassDeclareReservedUsed(className, index)
Parameters
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.

Discussion

This macro evaluates to nothing, and is used to document reserved vtable slots as they are filled. See OSMetaClassDeclareReservedUnused.

Availability
  • Available in OS X v10.0 and later.
Declared In
OSMetaClass.h

OSMetaClassDefineReservedUsed

Reserves vtable space for new virtual functions in a Libkern C++ class.

#define OSMetaClassDefineReservedUsed(className, index)
Parameters
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.

Discussion

This macro evaluates to nothing, and is used to document reserved vtable slots as they are filled. See OSMetaClassDefineReservedUnused.

Availability
  • Available in OS X v10.0 and later.
Declared In
OSMetaClass.h

postModLoad

Registers the metaclasses created during loading of a kernel extension.

static OSReturn postModLoad( void *loadHandle);
Parameters
loadHandle

The opaque handle returned by preModLoad.

Return Value

The error code of the first error encountered, or kOSReturnSuccess if no error occurred.

Discussion

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).

static void * preModLoad( const char *kextID);
Parameters
kextID

The bundle ID of the kext being loaded.

Return Value

An opaque handle to the load context for the kernel extension on success; NULL on failure.

Discussion

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.

virtual void release() const;
Discussion

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.

virtual void release( int freeWhen) const;
Parameters
freeWhen

Unused.

Discussion

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.

static void reportModInstances( const char *kextID);
Parameters
kextID

The bundle ID of the kernel extension to report on.

Discussion

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.

virtual void retain() const;
Discussion

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.

virtual void taggedRelease( const void *tag = 0) const;
Parameters
tag

Unused.

Discussion

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.

virtual void taggedRelease( const void *tag, const int freeWhen) const;
Parameters
tag

Unused.

freeWhen

Unused.

Discussion

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.

virtual void taggedRetain( const void *tag = 0) const;
Parameters
tag

Unused.

Discussion

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.

virtual ~OSMetaClass();
Discussion

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.

Constants

OSMetaClassDeclareReservedUnused

OSMetaClass manages run-time type information for Libkern and I/O Kit C++ classes.

Constants
Discussion

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:

The class implementation should then use one of these macros:

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:

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.

OSMetaClassDefineReservedUnused

Constants