1/*
2 * Copyright (c) 2000 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28#ifndef _LIBKERN_OSMETACLASS_H
29#define _LIBKERN_OSMETACLASS_H
30
31#include <sys/types.h>
32
33#include <libkern/OSReturn.h>
34#include <kern/debug.h>
35
36class OSMetaClass;
37class OSObject;
38class OSString;
39class OSSymbol;
40class OSDictionary;
41class OSSerialize;
42#ifdef XNU_KERNEL_PRIVATE
43class OSOrderedSet;
44#endif
45
46
47/*!
48 * @header
49 *
50 * @abstract
51 * This header declares the OSMetaClassBase and OSMetaClass classes,
52 * which together form the basis of the Libkern and I/O Kit C++ class hierarchy
53 * and run-time type information facility.
54 */
55
56
57/*! @parseOnly */
58#define APPLE_KEXT_COMPATIBILITY
59
60#ifdef XNU_KERNEL_PRIVATE
61
62/*! @parseOnly */
63#define APPLE_KEXT_VTABLE_PADDING   1
64
65#else /* XNU_KERNEL_PRIVATE */
66#include <TargetConditionals.h>
67
68#if TARGET_OS_EMBEDDED
69#define APPLE_KEXT_VTABLE_PADDING   0
70#else /* TARGET_OS_EMBEDDED */
71/*! @parseOnly */
72#define APPLE_KEXT_VTABLE_PADDING   1
73#endif /* TARGET_OS_EMBEDDED */
74
75#endif /* XNU_KERNEL_PRIVATE */
76
77#if defined(__LP64__)
78/*! @parseOnly */
79#define APPLE_KEXT_LEGACY_ABI  0
80#else
81#define APPLE_KEXT_LEGACY_ABI  1
82#endif
83
84#if defined(__LP64__)
85/*! @parseOnly */
86#define APPLE_KEXT_COMPATIBILITY_VIRTUAL
87#else
88// private method made virtual only for binary compatibility
89#define APPLE_KEXT_COMPATIBILITY_VIRTUAL  virtual
90#endif
91
92/*! @parseOnly */
93#define APPLE_KEXT_DEPRECATED  __attribute__((deprecated))
94
95/*!
96 * @class OSMetaClassBase
97 *
98 * @abstract
99 * OSMetaClassBase is the abstract bootstrap class
100 * for the Libkern and I/O Kit run-time type information system.
101 *
102 * @discussion
103 * OSMetaClassBase is the abstract C++ root class
104 * underlying the entire Libkern and I/O Kit class hierarchy.
105 * It defines the run-time type information system,
106 * including dynamic class allocation and safe type-casting,
107 * as well as the abstract interface for reference counting
108 * and a few other utility functions.
109 * OSMetaClassBase is the immediate superclass of
110 * @link //apple_ref/doc/class/OSObject OSObject@/link and
111 * @link //apple_ref/doc/class/OSMetaClass OSMetaClass@/link;
112 * no other class should derive from OSMetaClassBase.
113 *
114 * For more information, see
115 * <i>@link //apple_ref/doc/uid/TP40002799
116 * I/O Kit Device Driver Design Guidelines@/link</i>.
117 *
118 * <b>Use by Kernel Extensions</b>
119 *
120 * Kernel Extensions should never interact directly with OSMetaClassBase,
121 * but they will find useful several macros that tie in
122 * to the run-time type information system, specifically:
123 * <ul>
124 * <li><code>@link OSTypeAlloc OSTypeAlloc@/link</code> - allocation of new instances</li>
125 * <li><code>@link OSDynamicCast OSDynamicCast@/link</code> - safe type casting</li>
126 * <li><code>@link OSCheckTypeInst OSCheckTypeInst@/link</code> -
127 *     checking for inheritance/derivation</li>
128 * <li><code>@link OSMemberFunctionCast OSMemberFunctionCast@/link</code> -
129 *     casting C++ member functions to C function pointers
130 *     for registration as callbacks</li>
131 * </ul>
132 *
133 * See @link //apple_ref/doc/class/OSMetaClass OSMetaClass@/link
134 * for more run-time type information interfaces.
135 *
136 * <b>Use Restrictions</b>
137 *
138 * OSMetaClassBase should not be subclassed by kernel extensions,
139 * nor should kernel extensions call its run-time type functions directly.
140 *
141 * The run-time type functions and macros are <b>not safe</b>
142 *  to call in a primary interrupt context.
143 *
144 * <b>Concurrency Protection</b>
145 *
146 * The run-time type macros and functions of OSMetaClassBase are thread-safe.
147 */
148class OSMetaClassBase
149{
150public:
151
152
153   /*!
154    * @define OSTypeAlloc
155    * @hidecontents
156    *
157    * @abstract
158    * Allocates an instance of the named object class.
159    *
160    * @param type    The name of the desired class to be created,
161    *                as a raw token, <i>not</i> a string or macro.
162    *
163    * @result
164    * A pointer to the new, uninitialized object on success;
165    * <code>NULL</code> on failure.
166    *
167    * @discussion
168    * See also
169    * <code>@link
170    * //apple_ref/cpp/clm/OSMetaClass/allocClassWithName/staticOSObject*\/(constchar*)
171    * OSMetaClass::allocClassWithName(const char *)@/link</code>
172    * and
173    * <code>@link
174    * //apple_ref/cpp/instm/OSMetaClass/alloc/virtualOSObject*\/()
175    * OSMetaClass::alloc@/link</code>.
176    *
177    * The OSTypeAlloc macro is used to avoid binary compatibility difficulties
178    * presented by the C++ <code>new</code> operator.
179    */
180#define OSTypeAlloc(type)   ((type *) ((type::metaClass)->alloc()))
181
182
183   /*!
184    * @define OSTypeID
185    * @hidecontents
186    *
187    * @abstract
188    * Returns the type ID (metaclass) of a class based on its name.
189    *
190    * @param type    The name of the desired class, as a raw token,
191    *                <i>not</i> a string or macro.
192    *
193    * @result
194    * The unique type ID (metaclass) for the class.
195    *
196    * @discussion
197    * It is typically more useful to determine whether a class is derived
198    * from another; see
199    * <code>@link //apple_ref/cpp/macro/OSDynamicCast OSDynamicCast@/link</code>
200    * and
201    * <code>@link //apple_ref/cpp/macro/OSCheckTypeInst OSCheckTypeInst@/link</code>.
202    */
203#define OSTypeID(type)   (type::metaClass)
204
205
206   /*!
207    * @define OSTypeIDInst
208    * @hidecontents
209    *
210    * @abstract
211    * Returns the type ID (metaclass) for the class of an object instance.
212    *
213    * @param typeinst An instance of an OSObject subclass.
214    *
215    * @result
216    * The type ID of that object's class; that is, its metaclass.
217    *
218    * @discussion
219    * It is typically more useful to determine whether an object is derived
220    * from a particular class; see
221    * <code>@link //apple_ref/cpp/macro/OSDynamicCast OSDynamicCast@/link</code>
222    * and
223    * <code>@link //apple_ref/cpp/macro/OSCheckTypeInst OSCheckTypeInst@/link</code>.
224    */
225#define OSTypeIDInst(typeinst)   ((typeinst)->getMetaClass())
226
227
228   /*!
229    * @define OSDynamicCast
230    * @hidecontents
231    *
232    * @abstract
233    * Safe type-casting for Libkern C++ objects.
234    *
235    * @param type    The name of the desired class type, as a raw token,
236    *                <i>not</i> a string or macro.
237    *                It is assumed you intend to cast to a pointer
238    *                to an object of this type.
239    *                Type qualifiers, such as <code>const</code>,
240    *                are not recognized and will cause
241    *                a (usually obscure) compile error.
242    * @param inst    A pointer to the object instance to be cast.
243    *                May be <code>NULL</code>.
244    *
245    * @result
246    * <code>inst</code> if it is non-<code>NULL</code>
247    * and derived from <code>type</code>;
248    * otherwise <code>NULL</code>.
249    *
250    * @discussion
251    * <code>OSDynamicCast</code> is a rough equivalent
252    * to the standard C++ RTTI <code>dynamic_cast&lt;T&gt;</code> operator.
253    * Your code should use this instead of raw C type-casting,
254    * and check the resulting value.
255    * If the result is non-<code>NULL</code>,
256    * the object is safe to use as the type-cast class;
257    * if the result is <code>NULL</code>,
258    * the object does not derive from the type-cast class
259    * and your code should take appropriate steps to handle the error.
260    */
261#define OSDynamicCast(type, inst)   \
262    ((type *) OSMetaClassBase::safeMetaCast((inst), OSTypeID(type)))
263
264
265   /*!
266    * @define OSCheckTypeInst
267    * @hidecontents
268    *
269    * @abstract
270    * Checks whether two objects are type-compatible.
271    *
272    * @param typeinst The reference object.
273    * @param inst     The object to check for type compatibility.
274    *
275    * @result
276    * <code>true</code> if both <code>inst</code> and
277    * <code>typeinst</code> are non-<code>NULL</code>
278    * and <code>inst</code> is derived from the class of <code>typeinst</code>;
279    * otherwise <code>false</code>.
280    */
281#define OSCheckTypeInst(typeinst, inst) \
282    OSMetaClassBase::checkTypeInst(inst, typeinst)
283
284/*! @function OSSafeRelease
285 *  @abstract Release an object if not <code>NULL</code>.
286 *  @param    inst  Instance of an OSObject, may be <code>NULL</code>.
287 */
288#define OSSafeRelease(inst)       do { if (inst) (inst)->release(); } while (0)
289
290/*! @function OSSafeReleaseNULL
291 *  @abstract Release an object if not <code>NULL</code>, then set it to <code>NULL</code>.
292 *  @param    inst  Instance of an OSObject, may be <code>NULL</code>.
293 */
294#define OSSafeReleaseNULL(inst)   do { if (inst) (inst)->release(); (inst) = NULL; } while (0)
295
296typedef void (*_ptf_t)(void);
297
298#if APPLE_KEXT_LEGACY_ABI
299
300// Arcane evil code interprets a C++ pointer to function as specified in the
301// -fapple-kext ABI, i.e. the gcc-2.95 generated code.  IT DOES NOT ALLOW
302// the conversion of functions that are from MULTIPLY inherited classes.
303
304static inline _ptf_t
305_ptmf2ptf(const OSMetaClassBase *self, void (OSMetaClassBase::*func)(void))
306{
307    union {
308        void (OSMetaClassBase::*fIn)(void);
309        struct {     // Pointer to member function 2.95
310            unsigned short fToff;
311            short  fVInd;
312            union {
313                _ptf_t fPFN;
314                short  fVOff;
315            } u;
316        } fptmf2;
317    } map;
318
319    map.fIn = func;
320    if (map.fptmf2.fToff) {
321        panic("Multiple inheritance is not supported");
322        return 0;
323    } else if (map.fptmf2.fVInd < 0) {
324        // Not virtual, i.e. plain member func
325        return map.fptmf2.u.fPFN;
326    } else {
327        union {
328            const OSMetaClassBase *fObj;
329            _ptf_t **vtablep;
330        } u;
331        u.fObj = self;
332
333        // Virtual member function so dereference vtable
334        return (*u.vtablep)[map.fptmf2.fVInd - 1];
335    }
336}
337
338#else /* !APPLE_KEXT_LEGACY_ABI */
339#if   defined(__i386__) || defined(__x86_64__)
340
341// Slightly less arcane and slightly less evil code to do
342// the same for kexts compiled with the standard Itanium C++
343// ABI
344
345static inline _ptf_t
346_ptmf2ptf(const OSMetaClassBase *self, void (OSMetaClassBase::*func)(void))
347{
348    union {
349        void (OSMetaClassBase::*fIn)(void);
350        uintptr_t fVTOffset;
351        _ptf_t fPFN;
352    } map;
353
354    map.fIn = func;
355
356    if (map.fVTOffset & 1) {
357        // virtual
358        union {
359            const OSMetaClassBase *fObj;
360            _ptf_t **vtablep;
361        } u;
362        u.fObj = self;
363
364        // Virtual member function so dereference vtable
365        return *(_ptf_t *)(((uintptr_t)*u.vtablep) + map.fVTOffset - 1);
366    } else {
367        // Not virtual, i.e. plain member func
368        return map.fPFN;
369    }
370}
371
372#else
373#error Unknown architecture.
374#endif /* __arm__ */
375
376#endif /* !APPLE_KEXT_LEGACY_ABI */
377
378   /*!
379    * @define OSMemberFunctionCast
380    * @hidecontents
381    *
382    * @abstract
383    * Converts a C++ member function pointer, relative to an instance,
384    * to a C-style pointer to function.
385    *
386    * @param cptrtype The function type declaration to cast to
387    *                 (typically provided as a <code>typedef</code> by  I/O KitKit classes).
388    * @param self     The <code>this</code> pointer of the object whose function
389    *                 you wish to cache.
390    * @param func     The pointer to the member function itself,
391    *                 something like <code>&Class::function</code>.
392    *
393    * @result
394    * A pointer to a function of the given type referencing <code>self</code>.
395    *
396    * @discussion
397    * This function is used to generate pointers to C++ functions for instances,
398    * such that they can be registered as callbacks with I/O Kit objects.
399    *
400    * No warnings are generated.
401    *
402    * This function will panic if an attempt is made to call it
403    * with a multiply-inheriting class.
404    */
405#define OSMemberFunctionCast(cptrtype, self, func)         \
406    (cptrtype) OSMetaClassBase::                           \
407        _ptmf2ptf(self, (void (OSMetaClassBase::*)(void)) func)
408
409protected:
410    OSMetaClassBase();
411    virtual ~OSMetaClassBase();
412
413private:
414    // Disable copy constructors of OSMetaClassBase based objects
415   /* Not to be included in headerdoc.
416    *
417    * @function operator =
418    *
419    * @abstract
420    * Disable implicit copy constructor by making private
421    *
422    * @param src Reference to source object that isn't allowed to be copied.
423    */
424    void operator =(OSMetaClassBase &src);
425
426   /* Not to be included in headerdoc.
427    *
428    * @function OSMetaClassBase
429    *
430    * @abstract
431    * Disable implicit copy constructor by making private
432    *
433    * @param src Reference to source object that isn't allowed to be copied.
434    */
435    OSMetaClassBase(OSMetaClassBase &src);
436
437public:
438
439// xx-review: the original comment for this makes it sound to me like we don't
440// xx-review: catch over-releasing an object...?
441
442   /*!
443    * @function release
444    *
445    * @abstract
446    * Abstract declaration of
447    * <code>@link
448    * //apple_ref/cpp/instm/OSObject/release/virtualvoid/(int)
449    * release(int freeWhen)@/link</code>.
450    *
451    * @discussion
452    * See
453    * <code>@link
454    * //apple_ref/cpp/instm/OSObject/release/virtualvoid/(int)
455    * release(int freeWhen)@/link</code>.
456    */
457    virtual void release(int freeWhen) const = 0;
458
459
460   /*!
461    * @function getRetainCount
462    *
463    * @abstract
464    * Abstract declaration of
465    * <code>@link
466    * //apple_ref/cpp/instm/OSObject/getRetainCount/virtualint/()
467    * getRetainCount()@/link</code>.
468    *
469    * @discussion
470    * See
471    * <code>@link
472    * //apple_ref/cpp/instm/OSObject/getRetainCount/virtualint/()
473    * OSObject::getRetainCount()@/link</code>.
474    */
475    virtual int getRetainCount() const = 0;
476
477
478   /*!
479    * @function retain
480    *
481    * @abstract
482    * Abstract declaration of
483    * <code>@link
484    * //apple_ref/cpp/instm/OSObject/retain/virtualvoid/()
485    * retain()@/link</code>.
486    *
487    * @discussion
488    * See
489    * <code>@link
490    * //apple_ref/cpp/instm/OSObject/retain/virtualvoid/()
491    * OSObject::retain()@/link</code>.
492    */
493    virtual void retain() const = 0;
494
495
496   /*!
497    * @function release
498    *
499    * @abstract
500    * Abstract declaration of
501    * <code>@link
502    * //apple_ref/cpp/instm/OSObject/release/virtualvoid/()
503    * release@/link</code>.
504    *
505    * @discussion
506    * See
507    * <code>@link
508    * //apple_ref/cpp/instm/OSObject/release/virtualvoid/()
509    * OSObject::release@/link</code>.
510    */
511    virtual void release() const = 0;
512
513
514   /*!
515    * @function serialize
516    *
517    * @abstract
518    * Abstract declaration of
519    * <code>@link
520    * //apple_ref/cpp/instm/OSObject/serialize/virtualbool/(OSSerialize*)
521    * serialize@/link</code>.
522    *
523    * @discussion
524    * See
525    * <code>@link
526    * //apple_ref/cpp/instm/OSObject/serialize/virtualbool/(OSSerialize*)
527    * OSObject::serialize@/link</code>.
528    */
529    virtual bool serialize(OSSerialize * serializer) const = 0;
530
531
532   /*!
533    * @function getMetaClass
534    *
535    * @abstract
536    * Returns the OSMetaClass representing
537    * an OSMetaClassBase subclass.
538    *
539    * @discussion
540    * OSObject overrides this abstract member function
541    * to return the OSMetaClass object that represents
542    * each class for run-time typing.
543    */
544    virtual const OSMetaClass * getMetaClass() const = 0;
545
546
547   /*!
548    * @function isEqualTo
549    *
550    * @abstract
551    * Checks whether another object is equal to the receiver.
552    *
553    * @param anObject The object to copmare to the receiver.
554    *
555    * @result
556    * <code>true</code> if the objects are equal, <code>false</code> otherwise.
557    *
558    * @discussion
559    * OSMetaClassBase implements this as a direct pointer comparison,
560    * since it has no other information to judge equality by.
561    * Subclasses generally override this function
562    * to do a more meaningful comparison.
563    * For example, OSString implements it to return
564    * <code>true</code> if <code>anObject</code>
565    * is derived from OSString and represents the same C string.
566    */
567    virtual bool isEqualTo(const OSMetaClassBase * anObject) const;
568
569
570   /*!
571    * @function metaCast
572    *
573    * @abstract
574    * Casts this object is to the class managed by the given OSMetaClass.
575    *
576    * @param toMeta A pointer to a constant OSMetaClass
577    *               for the desired target type.
578    *
579    * @result
580    * <code>this</code> if the object is derived
581    * from the class managed by <code>toMeta</code>,
582    * otherwise <code>NULL</code>.
583    *
584    * @discussion
585    * It is far more convenient to use
586    * <code>@link OSDynamicCast OSDynamicCast@/link</code>.
587    */
588    OSMetaClassBase * metaCast(const OSMetaClass * toMeta) const;
589
590
591   /*!
592    * @function metaCast
593    *
594    * @abstract
595    * Casts this object is to the class managed by the named OSMetaClass.
596    *
597    * @param toMeta An OSSymbol naming the desired target type.
598    *
599    * @result
600    * <code>this</code> if the object is derived
601    * from the class named by <code>toMeta</code>,
602    * otherwise <code>NULL</code>.
603    *
604    * @discussion
605    * It is far more convenient to use
606    * <code>@link OSDynamicCast OSDynamicCast@/link</code>.
607    */
608    OSMetaClassBase * metaCast(const OSSymbol * toMeta) const;
609
610
611   /*!
612    * @function metaCast
613    *
614    * @abstract
615    * Casts this object is to the class managed by the named OSMetaClass.
616    *
617    * @param toMeta An OSString naming the desired target type.
618    * @result
619    * <code>this</code> if the object is derived
620    * from the class named by <code>toMeta</code>,
621    * otherwise <code>NULL</code>.
622    *
623    * @discussion
624    * It is far more convenient to use
625    * <code>@link OSDynamicCast OSDynamicCast@/link</code>.
626    */
627    OSMetaClassBase * metaCast(const OSString * toMeta) const;
628
629
630   /*!
631    * @function metaCast
632    *
633    * @abstract
634    * Casts this object is to the class managed by the named OSMetaClass.
635    *
636    * @param toMeta A C string naming the desired target type.
637    * @result
638    * <code>this</code> if the object is derived
639    * from the class named by <code>toMeta</code>,
640    * otherwise <code>NULL</code>.
641    *
642    * @discussion
643    * It is far more convenient to use
644    * <code>@link OSDynamicCast OSDynamicCast@/link</code>.
645    */
646    OSMetaClassBase * metaCast(const char * toMeta) const;
647
648    // Helper inlines for run-time type preprocessor macros
649   /*!
650    * @function safeMetaCast
651    *
652    * @abstract
653    * Casts an object is to the class managed by the given OSMetaClass.
654    *
655    * @param anObject A pointer to the object to be cast.
656    * @param toMeta   A pointer to a constant OSMetaClass
657    *                 for the desired target type.
658    *
659    * @result
660    * <code>anObject</code> if the object is derived
661    * from the class managed by <code>toMeta</code>,
662    * otherwise <code>NULL</code>.
663    *
664    * @discussion
665    * It is far more convenient to use
666    * <code>@link OSDynamicCast OSDynamicCast@/link</code>.
667    */
668    static OSMetaClassBase * safeMetaCast(
669        const OSMetaClassBase * anObject,
670        const OSMetaClass     * toMeta);
671
672   /*!
673    * @function checkTypeInst
674    *
675    * @abstract
676    * Checks whether an object instance is of the same class
677    * as another object instance (or a subclass of that class).
678    *
679    * @param inst       A pointer to the object to check.
680    * @param typeinst   A pointer to an object of the class being checked.
681    *
682    * @result
683    * <code>true</code> if the object is derived
684    * from the class of <code>typeinst</code>
685    * or a subclass of that class,
686    * otherwise <code>false</code>.
687    *
688    * @discussion
689    * It is far more convenient to use
690    * <code>@link OSCheckTypeInst OSCheckTypeInst@/link</code>.
691    */
692    static bool checkTypeInst(
693        const OSMetaClassBase * inst,
694        const OSMetaClassBase * typeinst);
695
696    static void initialize(void);
697
698public:
699
700   /*!
701    * @function taggedRetain
702    *
703    * @abstract
704    * Abstract declaration of
705    * <code>@link
706    * //apple_ref/cpp/instm/OSObject/taggedRetain/virtualvoid/(constvoid*)
707    * taggedRetain(const void *)@/link</code>.
708    *
709    * @discussion
710    * See
711    * <code>@link
712    * //apple_ref/cpp/instm/OSObject/taggedRetain/virtualvoid/(constvoid*)
713    * OSObject::taggedRetain(const void *)@/link</code>.
714    */
715    // WAS: virtual void _RESERVEDOSMetaClassBase0();
716    virtual void taggedRetain(const void * tag = 0) const = 0;
717
718
719   /*!
720    * @function taggedRelease
721    *
722    * @abstract
723    * Abstract declaration of
724    * <code>@link
725    * //apple_ref/cpp/instm/OSObject/taggedRelease/virtualvoid/(constvoid*)
726    * taggedRelease(const void *)@/link</code>.
727    *
728    * @discussion
729    * See
730    * <code>@link
731    * //apple_ref/cpp/instm/OSObject/taggedRelease/virtualvoid/(constvoid*)
732    * OSObject::taggedRelease(const void *)@/link</code>.
733    */
734    // WAS:  virtual void _RESERVEDOSMetaClassBase1();
735    virtual void taggedRelease(const void * tag = 0) const = 0;
736
737protected:
738   /*!
739    * @function taggedRelease
740    *
741    * @abstract
742    * Abstract declaration of
743    * <code>@link
744    * //apple_ref/cpp/instm/OSObject/taggedRelease/virtualvoid/(constvoid*,constint)
745    * taggedRelease(const void *, const int freeWhen)@/link</code>.
746    *
747    * @discussion
748    * See
749    * <code>@link
750    * //apple_ref/cpp/instm/OSObject/taggedRelease/virtualvoid/(constvoid*,constint)
751    * OSObject::taggedRelease(const void *, const int freeWhen)@/link</code>.
752    */
753    // WAS:  virtual void _RESERVEDOSMetaClassBase2();
754    virtual void taggedRelease(
755        const void * tag,
756        const int    freeWhen) const = 0;
757
758private:
759#if APPLE_KEXT_VTABLE_PADDING
760    // Virtual Padding
761    virtual void _RESERVEDOSMetaClassBase3();
762    virtual void _RESERVEDOSMetaClassBase4();
763    virtual void _RESERVEDOSMetaClassBase5();
764    virtual void _RESERVEDOSMetaClassBase6();
765    virtual void _RESERVEDOSMetaClassBase7();
766#endif
767} APPLE_KEXT_COMPATIBILITY;
768
769
770#ifdef XNU_KERNEL_PRIVATE
771typedef bool (*OSMetaClassInstanceApplierFunction)(const OSObject * instance,
772						   void * context);
773#endif /* XNU_KERNEL_PRIVATE */
774
775/*!
776 * @class OSMetaClass
777 *
778 * @abstract
779 * OSMetaClass manages run-time type information
780 * for Libkern and I/O Kit C++ classes.
781 *
782 * @discussion
783 *
784 * OSMetaClass manages run-time type information
785 * for Libkern and I/O Kit C++ classes.
786 * An instance of OSMetaClass exists for (nearly) every such C++ class,
787 * keeping track of inheritance relationships, class lookup by name,
788 * instance counts, and more.
789 * OSMetaClass operates almost entirely behind the scenes,
790 * and kernel extensions should rarely, if ever,
791 * have to interact directly with OSMetaClass.
792 *
793 * <b>Use by Kernel Extensions</b>
794 *
795 * While kernel extensions rarey interact directly with OSMetaClass at run time,
796 * they must register their classes with the metaclass system
797 * using the macros declared here.
798 * The class declaration should use one of these two macros
799 * before its first member function declaration:
800 * <ul>
801 * <li><code>@link OSDeclareDefaultStructors OSDeclareDefaultStructors@/link</code> -
802 *     for classes with no abstract member function declarations</li>
803 * <li><code>@link OSDeclareAbstractStructors OSDeclareAbstractStructors@/link</code> -
804 *     for classes with at least one abstract member function declaration</li>
805 * <li><code>@link OSDeclareFinalStructors OSDeclareFinalStructors@/link</code> -
806 *     for classes that should not be subclassable by another kext</li>
807 * </ul>
808 *
809 * The class implementation should then use one of these macros:
810 * <ul>
811 * <li><code>@link OSDefineMetaClassAndStructors
812 *           OSDefineMetaClassAndStructors@/link</code> -
813 *     for classes with no abstract member function declarations</li>
814 * <li><code>@link OSDefineMetaClassAndAbstractStructors
815 *           OSDefineMetaClassAndAbstractStructors@/link</code> -
816 *     for classes with at least one abstract member function declaration</li>
817 * <li><code>@link OSDefineMetaClassAndFinalStructors
818 *           OSDefineMetaClassAndFinalStructors@/link</code> -
819 *     for classes that should not be subclassable by another kext</li>
820 * </ul>
821 *
822 * Classes in kernel extensions that are intended for use as libraries
823 * may need to reserve vtable slots to preserve binary compatibility
824 * as new functions are added. They may do so with these macros:
825 * <ul>
826 * <li><code>@link OSMetaClassDeclareReservedUnused
827 *           OSMetaClassDeclareReservedUnused@/link</code> -
828 *     reserves a vtable slot</li>
829 * <li><code>@link OSMetaClassDefineReservedUnused
830 *           OSMetaClassDefineReservedUnused@/link</code> -
831 *     defines the reserved vtable slot as an unimplemented function</li>
832 * <li><code>@link OSMetaClassDeclareReservedUsed
833 *           OSMetaClassDeclareReservedUsed@/link</code> -
834 *     documents that a formerly reserved slot is now used</li>
835 * <li><code>@link OSMetaClassDefineReservedUsed
836 *           OSMetaClassDefineReservedUsed@/link</code> -
837 *    documents that a formerly reserved slot is now used</li>
838 * </ul>
839 *
840 * <b>Use Restrictions</b>
841 *
842 * OSMetaClass should not be explicitly subclassed by kernel extensions
843 * (the declare/define macros do that),
844 * nor should kernel extensions call its run-time type functions directly.
845 *
846 * OSMetaClass functions should be considered
847 * <b>unsafe</b> to call in a primary interrupt context.
848 *
849 * <b>Concurrency Protection</b>
850 *
851 * Kernel extensions should in general not interact
852 * with OSMetaClass objects directly,
853 * instead using the run-time type macros.
854 * Much of OSMetaClass's interface is intended for use
855 * by the run-time type information system,
856 * which handles concurrency and locking internally.
857 */
858class OSMetaClass : private OSMetaClassBase
859{
860    friend class OSKext;
861#if IOKITSTATS
862	friend class IOStatistics;
863#endif
864
865private:
866    // Can never be allocated must be created at compile time
867    static void * operator new(size_t size);
868
869   /* Reserved for future use.  (Internal use only) */
870    struct ExpansionData *reserved;
871
872   /* superClass Handle to the superclass's meta class. */
873    const OSMetaClass *superClassLink;
874
875   /* className OSSymbol of the class' name. */
876    const OSSymbol *className;
877
878   /* classSize How big is a single instance of this class. */
879    unsigned int classSize;
880
881   /* instanceCount Roughly number of instances of the object,
882    * +1 for each direct subclass with a nonzero refcount.
883    * Used primarily as a code-in-use flag.
884    */
885    mutable unsigned int instanceCount;
886
887   /* Not to be included in headerdoc.
888    *
889    * @function OSMetaClass
890    *
891    * @abstract
892    * The default private constructor.
893    */
894    OSMetaClass();
895
896    // Called by postModLoad
897   /* Not to be included in headerdoc.
898    *
899    * @function logError
900    *
901    * @abstract
902    * Logs an error string for an <code>OSReturn</code> value
903    * using <code>printf</code>.
904    *
905    * @param result  The <code>OSReturn</code> value for which to log a message.
906    *
907    * @discussion
908    * This function is used to log errors loading kernel extensions.
909    * Kernel extensions themselves should not call it.
910    */
911    static void logError(OSReturn result);
912
913public:
914
915   /*!
916    * @function getMetaClassWithName
917    *
918    * @abstract
919    * Look up a metaclass in the run-time type information system.
920    *
921    * @param name The name of the desired class's metaclass.
922    *
923    * @result
924    * A pointer to the metaclass object if found, <code>NULL</code> otherwise.
925    */
926    static const OSMetaClass * getMetaClassWithName(const OSSymbol * name);
927
928protected:
929   /*!
930    * @function retain
931    *
932    * @abstract
933    * Implements the abstract <code>retain</code> function to do nothing.
934    *
935    * @discussion
936    * Since an OSMetaClass instance must remain in existence
937    * for as long as its kernel extension is loaded,
938    * OSMetaClass does not use reference-counting.
939    */
940    virtual void retain() const;
941
942
943   /*!
944    * @function release
945    *
946    * @abstract
947    * Implements the abstract <code>release</code> function to do nothing.
948    *
949    * @discussion
950    * Since an OSMetaClass instance must remain in existence
951    * for as long as its kernel extension is loaded,
952    * OSMetaClass does not use reference-counting.
953    */
954    virtual void release() const;
955
956
957   /*!
958    * @function release
959    *
960    * @abstract
961    * Implements the abstract <code>release(int freeWhen)</code>
962    * function to do nothing.
963    *
964    * @param freeWhen  Unused.
965    *
966    * @discussion
967    * Since an OSMetaClass instance must remain in existence
968    * for as long as its kernel extension is loaded,
969    * OSMetaClass does not use reference-counting.
970    */
971    virtual void release(int freeWhen) const;
972
973
974   /*!
975    * @function taggedRetain
976    *
977    * @abstract
978    * Implements the abstract <code>taggedRetain(const void *)</code>
979    * function to do nothing.
980    *
981    * @param tag  Unused.
982    *
983    * @discussion
984    * Since an OSMetaClass instance must remain in existence
985    * for as long as its kernel extension is loaded,
986    * OSMetaClass does not use reference-counting.
987    */
988    virtual void taggedRetain(const void * tag = 0) const;
989
990
991   /*!
992    * @function taggedRelease
993    *
994    * @abstract
995    * Implements the abstract <code>taggedRelease(const void *)</code>
996    * function to do nothing.
997    *
998    * @param tag  Unused.
999    *
1000    * @discussion
1001    * Since an OSMetaClass instance must remain in existence
1002    * for as long as its kernel extension is loaded,
1003    * OSMetaClass does not use reference-counting.
1004    */
1005    virtual void taggedRelease(const void * tag = 0) const;
1006
1007
1008   /*!
1009    * @function taggedRelease
1010    *
1011    * @abstract
1012    * Implements the abstract <code>taggedRelease(const void *, cont int)</code>
1013    * function to do nothing.
1014    *
1015    * @param tag       Unused.
1016    * @param freeWhen  Unused.
1017    *
1018    * @discussion
1019    * Since an OSMetaClass instance must remain in existence
1020    * for as long as its kernel extension is loaded,
1021    * OSMetaClass does not use reference-counting.
1022    */
1023    virtual void taggedRelease(
1024        const void * tag,
1025        const int    freeWhen) const;
1026
1027
1028   /*!
1029    * @function getRetainCount
1030    *
1031    * @abstract
1032    * Implements the abstract <code>getRetainCount</code>
1033    * function to return 0.
1034    *
1035    * @result
1036    * Always returns 0.
1037    *
1038    * @discussion
1039    * Since an OSMetaClass instance must remain in existence
1040    * for as long as its kernel extension is loaded,
1041    * OSMetaClass does not use reference-counting.
1042    */
1043    virtual int getRetainCount() const;
1044
1045
1046   /* Not to be included in headerdoc.
1047    *
1048    * @function getMetaClass
1049    *
1050    * @abstract
1051    * Returns the meta-metaclass.
1052    *
1053    * @result
1054    * The metaclass of the OSMetaClass object.
1055    */
1056    virtual const OSMetaClass * getMetaClass() const;
1057
1058
1059   /*!
1060    * @function OSMetaClass
1061    *
1062    * @abstract
1063    * Constructor for OSMetaClass objects.
1064    *
1065    * @param className  A C string naming the C++ class
1066    *                   that this OSMetaClass represents.
1067    * @param superclass The OSMetaClass object representing the superclass
1068    *                   of this metaclass's class.
1069    * @param classSize  The allocation size of the represented C++ class.
1070    *
1071    * @discussion
1072    * This constructor is protected and cannot be used
1073    * to instantiate OSMetaClass directly, as OSMetaClass is an abstract class.
1074    * This function is called during kext loading
1075    * to queue C++ classes for registration.
1076    * See <code>@link preModLoad preModLoad@/link</code> and
1077    * <code>@link postModLoad postModLoad@/link</code>.
1078    */
1079    OSMetaClass(const char * className,
1080        const OSMetaClass  * superclass,
1081        unsigned int         classSize);
1082
1083
1084   /*!
1085    * @function ~OSMetaClass
1086    *
1087    * @abstract
1088    * Destructor for OSMetaClass objects.
1089    *
1090    * @discussion
1091    * This function is called when the kernel extension that implements
1092    * the metaclass's class is unloaded.
1093    * The destructor removes all references to the class
1094    * from the run-time type information system.
1095    */
1096    virtual ~OSMetaClass();
1097
1098    // Needs to be overriden as NULL as all OSMetaClass objects are allocated
1099    // statically at compile time, don't accidently try to free them.
1100    void operator delete(void *, size_t) { };
1101
1102public:
1103    static const OSMetaClass * const metaClass;
1104
1105   /*!
1106    * @function preModLoad
1107    *
1108    * @abstract
1109    * Prepares the run-time type system
1110    * for the creation of new metaclasses
1111    * during loading of a kernel extension (module).
1112    *
1113    * @param kextID  The bundle ID of the kext being loaded.
1114    *
1115    * @result
1116    * An opaque handle to the load context
1117    * for the kernel extension on success;
1118    * <code>NULL</code> on failure.
1119    *
1120    * @discussion
1121    * <i>Not for use by kernel extensions.</i>
1122    *
1123    * Prepares the run-time type information system to record and register
1124    * metaclasses created by static constructors until a subsequent call to
1125    * <code>@link postModLoad postModLoad@/link</code>.
1126    * <code>preModLoad</code> takes a lock to ensure processing of a single
1127    * load operation at a time; the lock is released by
1128    * <code>@link postModLoad postModLoad@/link</code>.
1129    * Any OSMetaClass constructed between these two function calls
1130    * will be associated with <code>kextID</code>.
1131    */
1132    static void * preModLoad(const char * kextID);
1133
1134
1135   /*!
1136    * @function checkModLoad
1137    *
1138    * @abstract
1139    * Checks whether the current kext load operation can proceed.
1140    *
1141    * @param loadHandle The opaque handle returned
1142    *                   by <code>@link preModLoad preModLoad@/link</code>.
1143    * @result
1144    * <code>true</code> if no errors are outstanding
1145    * and the system is ready to process more metaclasses.
1146    *
1147    * @discussion
1148    * <i>Not for use by kernel extensions.</i>
1149    */
1150    static bool checkModLoad(void * loadHandle);
1151
1152
1153   /*!
1154    * @function postModLoad
1155    *
1156    * @abstract
1157    * Registers the metaclasses created during loading of a kernel extension.
1158    *
1159    * @param loadHandle The opaque handle returned
1160    *                   by <code>@link preModLoad preModLoad@/link</code>.
1161    * @result
1162    * The error code of the first error encountered,
1163    * or
1164    * <code>@link
1165    * //apple_ref/cpp/macro/kOSReturnSuccess
1166    * kOSReturnSuccess@/link</code>
1167    * if no error occurred.
1168    *
1169    * @discussion
1170    * <i>Not for use by kernel extensions.</i>
1171    *
1172    * Called after all static constructors in a kernel extension
1173    * have created metaclasses,
1174    * this function checks for duplicate class names,
1175    * then registers the new metaclasses under the kext ID
1176    * that @link preModLoad preModLoad@/link was called with,
1177    * so that they can be dynamically allocated
1178    * and have their instance counts tracked.
1179    * <code>postModLoad</code> releases the lock taken by
1180    * <code>@link preModLoad preModLoad@/link</code>.
1181    */
1182    static OSReturn postModLoad(void * loadHandle);
1183
1184   /*!
1185    * @function modHasInstance
1186    *
1187    * @abstract
1188    * Returns whether any classes defined by the named
1189    * kernel extension (or their subclasses) have existing instances.
1190    *
1191    * @param kextID   The bundle ID of the kernel extension to check.
1192    *
1193    * @result
1194    * <code>true</code> if the kext is found and
1195    * if any class defined by that kext
1196    * has a nonzero instance count,
1197    * <code>false</code> otherwise.
1198    *
1199    * @discussion
1200    * This function is called before a kernel extension's static destructors
1201    * are invoked, prior to unloading the extension.
1202    * If any classes stil have instances or subclasses with instances,
1203    * those classes are logged
1204    * (using <code>@link reportModInstances reportModInstances@/link</code>) and
1205    * the kernel extension is not be unloaded.
1206    */
1207    static bool modHasInstance(const char * kextID);
1208
1209
1210   /*!
1211    * @function reportModInstances
1212    *
1213    * @abstract
1214    * Logs the instance counts for classes
1215    * defined by a kernel extension.
1216    *
1217    * @param kextID   The bundle ID of the kernel extension to report on.
1218    *
1219    * @discussion
1220    * This function prints the names and instance counts
1221    * of any class defined by <code>kextID</code>
1222    * that has a nonzero instance count.
1223    * It's called by <code>@link modHasInstance modHasInstance@/link</code>
1224    * to help diagnose problems unloading kernel extensions.
1225    */
1226    static void reportModInstances(const char * kextID);
1227
1228
1229   /*!
1230    * @function considerUnloads
1231    *
1232    * @abstract
1233    * Schedule automatic unloading of unused kernel extensions.
1234    *
1235    * @discussion
1236    * This function schedules a check for kernel extensions
1237    * that can be automatically unloaded,
1238    * canceling any currently scheduled check.
1239    * At that time, any such kexts with no Libkern C++ instances
1240    * and no external references are unloaded.
1241    *
1242    * The I/O Kit calls this function when matching goes idle.
1243    *
1244    * Kernel extensions that define subclasses of
1245    * @link //apple_ref/doc/class/IOService IOService@/link
1246    * are eligible for automatic unloading.
1247    *
1248    * (On releases of Mac OS X prior to Snow Leopard (10.6),
1249    * any kernel extension defining any Libkern C++ class
1250    * was eligible for automatic unloading,
1251    * but that unload did not call the module stop routine.
1252    * Non-I/O Kit kernel extensions that define Libkern C++ subclasses
1253    * should be sure to have OSBundleLibraries declarations that ensure
1254    * they will not load on releases prior to Snow Leopard.)
1255    */
1256    static void considerUnloads();
1257
1258
1259   /*!
1260    * @function allocClassWithName
1261    *
1262    * @abstract
1263    * Allocates an instance of a named OSObject-derived class.
1264    *
1265    * @param name The name of the desired class.
1266    *
1267    * @result
1268    * A pointer to the newly-allocated, uninitialized object on success;
1269    * <code>NULL</code> on failure.
1270    *
1271    * @discussion
1272    * Kernel extensions should not need to use this function
1273    * directly, instead using static instance-creation functions
1274    * defined by classes.
1275    *
1276    * This function consults the run-time type information system
1277    * to find the metaclass for the named class.
1278    * If it exists, it calls the metaclass's <code>@link alloc alloc@/link</code>
1279    * function and returns the result.
1280    */
1281    static OSObject * allocClassWithName(const OSSymbol * name);
1282
1283
1284   /*!
1285    * function allocClassWithName
1286    *
1287    * @abstract
1288    * Allocates an instance of a named OSObject-derived class.
1289    *
1290    * @param name The name of the desired class.
1291    *
1292    * @result
1293    * A pointer to the newly-allocated, uninitialized object on success;
1294    * <code>NULL</code> on failure.
1295    *
1296    * @discussion
1297    * Kernel extensions should not need to use this function
1298    * directly, instead using static instance-creation functions
1299    * defined by classes.
1300    *
1301    * This function consults the run-time type information system
1302    * to find the metaclass for the named class.
1303    * If it exists, it calls the metaclass's <code>@link alloc alloc@/link</code>
1304    * function and returns the result.
1305    */
1306    static OSObject * allocClassWithName(const OSString * name);
1307
1308
1309   /*!
1310    * function allocClassWithName
1311    *
1312    * @abstract
1313    * Allocates an instance of a named OSObject-derived class.
1314    *
1315    * @param name The name of the desired class.
1316    *
1317    * @result
1318    * A pointer to the newly-allocated, uninitialized object on success;
1319    * <code>NULL</code> on failure.
1320    *
1321    * @discussion
1322    * Kernel extensions should not need to use this function
1323    * directly, instead using static instance-creation functions
1324    * defined by classes.
1325    *
1326    * This function consults the run-time type information system
1327    * to find the metaclass for the named class.
1328    * If it exists, it calls the metaclass's <code>@link alloc alloc@/link</code>
1329    * function and returns the result.
1330    */
1331    static OSObject * allocClassWithName(const char * name);
1332
1333
1334   /*!
1335    * @function checkMetaCastWithName
1336    *
1337    * @abstract
1338    * Search the metaclass inheritance hierarchy by name for an object instance.
1339    *
1340    * @param className The name of the desired class or superclass.
1341    * @param object    The object whose metaclass begins the search.
1342    *
1343    * @result
1344    * <code>object</code> if it's derived from <code>className</code>;
1345    * <code>NULL</code> otherwise.
1346    *
1347    * @discussion
1348    * This function is the basis of the Libkern run-time type-checking system.
1349    * Kernel extensions should not use it directly,
1350    * instead using <code>@link OSDynamicCast OSDynamicCast@/link</code> or
1351    * <code>@link OSCheckTypeInst OSCheckTypeInst@/link</code>.
1352    */
1353    static OSMetaClassBase * checkMetaCastWithName(
1354        const OSSymbol        * className,
1355        const OSMetaClassBase * object);
1356
1357   /*!
1358    * @function checkMetaCastWithName
1359    *
1360    * @abstract
1361    * Search the metaclass inheritance hierarchy by name for an object instance.
1362    *
1363    * @param className The name of the desired class or superclass.
1364    * @param object    The object whose metaclass begins the search.
1365    *
1366    * @result
1367    * <code>object</code> if it's derived from <code>className</code>;
1368    * <code>NULL</code> otherwise.
1369    *
1370    * @discussion
1371    * Kernel extensions should not use this function directly,
1372    * instead using <code>@link OSDynamicCast OSDynamicCast@/link</code> or
1373    * <code>@link OSCheckTypeInst OSCheckTypeInst@/link</code>.
1374    */
1375    static OSMetaClassBase * checkMetaCastWithName(
1376        const OSString        * className,
1377        const OSMetaClassBase * object);
1378
1379   /*!
1380    * @function checkMetaCastWithName
1381    *
1382    * @abstract
1383    * Search the metaclass inheritance hierarchy by name for an object instance.
1384    *
1385    * @param className The name of the desired class or superclass.
1386    * @param object    The object whose metaclass begins the search.
1387    *
1388    * @result
1389    * <code>object</code> if it's derived from <code>className</code>;
1390    * <code>NULL</code> otherwise.
1391    *
1392    * @discussion
1393    * Kernel extensions should not use this function directly,
1394    * instead using <code>@link OSDynamicCast OSDynamicCast@/link</code> or
1395    * <code>@link OSCheckTypeInst OSCheckTypeInst@/link</code>.
1396    */
1397    static OSMetaClassBase * checkMetaCastWithName(
1398        const char            * className,
1399        const OSMetaClassBase * object);
1400
1401
1402   /*!
1403    * @function instanceConstructed
1404    *
1405    * @abstract
1406    * Counts the instances of the class managed by this metaclass.
1407    *
1408    * @discussion
1409    * <i>Not for use by kernel extensions.</i>
1410    *
1411    * Every non-abstract class that inherits from OSObject
1412    * has a default constructor that calls it's own metaclass's
1413    * <code>instanceConstructed</code> function.
1414    * This constructor is defined by the
1415    * <code>@link
1416    * OSDefineMetaClassAndStructors
1417    * OSDefineMetaClassAndStructors@/link</code>
1418    * macro that all OSObject subclasses must use.
1419    *
1420    * If a class's instance count goes from 0 to 1--that is,
1421    * upon the creation of the first instance of that class--the
1422    * superclass's instance count is also incremented.
1423    * This propagates reference counts up the inheritance chain so that
1424    * superclasses are counted as "in use" when subclasses have instances.
1425    */
1426    void instanceConstructed() const;
1427
1428
1429   /*!
1430    * @function instanceDestructed
1431    *
1432    * @abstract
1433    * Counts the instances of the class managed by this metaclass.
1434    *
1435    * @discussion
1436    * Every non-abstract class that inherits from OSObject
1437    * has a default destructor that calls it's own metaclass's
1438    * <code>instanceDestructed</code> function.
1439    * This constructor is defined by the
1440    * @link OSDefineMetaClassAndStructors OSDefineMetaClassAndStructors@/link
1441    * macro that all OSObject subclasses must use.
1442    *
1443    * If a class's instance count goes from 1 to 0--that is,
1444    * upon the destruction of the last instance of that class--the
1445    * superclass's instance count is also decremented.
1446    * This reduces "in use" counts from superclasses when their subclasses
1447    * no longer have instances.
1448    */
1449    void instanceDestructed() const;
1450
1451
1452   /*!
1453    * @function checkMetaCast
1454    *
1455    * @abstract
1456    * Check whether a given object is an instance of the receiving
1457    * metaclass's class or one derived from it.
1458    *
1459    * @param object The object to check for inheritance.
1460    *
1461    * @result
1462    * <code>object</code> if it is derived from the receiver's class,
1463    * <code>NULL</code> if not.
1464    */
1465    OSMetaClassBase * checkMetaCast(const OSMetaClassBase * object) const;
1466
1467
1468   /*!
1469    * @function getInstanceCount
1470    *
1471    * @abstract
1472    * Returns the number of existing instances of the metaclass's class.
1473    *
1474    * @result
1475    * The number of existing instances of the metaclass's class,
1476    * plus 1 for each subclass with any instance.
1477    */
1478    unsigned int getInstanceCount() const;
1479
1480
1481   /*!
1482    * @function getSuperClass
1483    *
1484    * @abstract
1485    * Returns the super-metaclass of the receiver.
1486    *
1487    * @result
1488    * Returns a pointer to the super-metaclass of the receiving
1489    * OSMetaClass, or <code>NULL</code> for OSObject's metaclass.
1490    */
1491    const OSMetaClass * getSuperClass() const;
1492
1493   /*!
1494    * @function getKmodName
1495    *
1496    * @abstract
1497    * Returns the bundle identifier of the kernel extension
1498    * that defines this metaclass.
1499    *
1500    * @result
1501    * The bundle identifier of the kernel extension that defines this metaclass.
1502    *
1503    * @discussion
1504    * "Kmod" is an older term for kernel extension.
1505    */
1506    const OSSymbol * getKmodName() const;
1507
1508
1509   /*!
1510    * @function getClassName
1511    *
1512    * @abstract
1513    * Returns the name of the C++ class managed by this metaclass.
1514    *
1515    * @result
1516    * Returns the name of the C++ class managed by this metaclass.
1517    */
1518    const char * getClassName() const;
1519    const OSSymbol * getClassNameSymbol() const;
1520
1521
1522   /*!
1523    * @function getClassSize
1524    *
1525    * @abstract
1526    * Returns the allocation size of the C++ class managed by this metaclass.
1527    *
1528    * @result
1529    * The allocation size of the C++ class managed by this metaclass.
1530    */
1531    unsigned int getClassSize() const;
1532
1533
1534   /*!
1535    * @function alloc
1536    *
1537    * @abstract
1538    * Allocates an instance of the C++ class managed by this metaclass.
1539    *
1540    * @result
1541    * A pointer to the newly allocated, uninitialized instance,
1542    * with a retain count of 1; <code>NULL</code> on allocation failure.
1543    *
1544    * @discussion
1545    * This function is automatically created by the metaclass-registration macros
1546    * to enable dynamic instance allocation.
1547    */
1548    virtual OSObject * alloc() const = 0;
1549
1550#ifdef XNU_KERNEL_PRIVATE
1551    void addInstance(const OSObject * instance, bool super = false) const;
1552    void removeInstance(const OSObject * instance, bool super = false) const;
1553    void applyToInstances(OSMetaClassInstanceApplierFunction applier,
1554                          void * context) const;
1555    static void applyToInstancesOfClassName(
1556    				const OSSymbol * name,
1557    				OSMetaClassInstanceApplierFunction  applier,
1558                                void * context);
1559private:
1560    static void applyToInstances(OSOrderedSet * set,
1561			         OSMetaClassInstanceApplierFunction  applier,
1562                                 void * context);
1563public:
1564#endif
1565
1566   /* Not to be included in headerdoc.
1567    *
1568    * @define OSDeclareCommonStructors
1569    * @hidecontents
1570    *
1571    * @abstract
1572    * Helper macro for for the standard metaclass-registration macros.
1573    * DO NOT USE.
1574    *
1575    * @param className The name of the C++ class, as a raw token,
1576    *                  <i>not</i> a string or macro.
1577    */
1578#define OSDeclareCommonStructors(className)                     \
1579    private:                                                    \
1580    static const OSMetaClass * const superClass;                \
1581    public:                                                     \
1582    static const OSMetaClass * const metaClass;                 \
1583        static class MetaClass : public OSMetaClass {           \
1584        public:                                                 \
1585            MetaClass();                                        \
1586            virtual OSObject *alloc() const;                    \
1587        } gMetaClass;                                           \
1588        friend class className ::MetaClass;                     \
1589        virtual const OSMetaClass * getMetaClass() const;       \
1590    protected:                                                  \
1591    className (const OSMetaClass *);                            \
1592    virtual ~ className ()
1593
1594
1595   /*!
1596    * @define OSDeclareDefaultStructors
1597    * @hidecontents
1598    *
1599    * @abstract
1600    * Declares run-time type information and functions
1601    * for a concrete Libkern C++ class.
1602    *
1603    * @param className The name of the C++ class, as a raw token,
1604    *                  <i>not</i> a string or macro.
1605    *
1606    * @discussion
1607    * Concrete Libkern C++ classes should "call" this macro
1608    * immediately after the opening brace in a class declaration.
1609    * It leaves the current privacy state as <code>protected:</code>.
1610    */
1611#define OSDeclareDefaultStructors(className)    \
1612    OSDeclareCommonStructors(className);        \
1613    public:                                     \
1614    className ();                               \
1615    protected:
1616
1617
1618   /*!
1619    * @define OSDeclareAbstractStructors
1620    * @hidecontents
1621    *
1622    * @abstract
1623    * Declares run-time type information and functions
1624    * for an abstract Libkern C++ class.
1625    *
1626    * @param className The name of the C++ class, as a raw token,
1627    *                  <i>not</i> a string or macro.
1628    *
1629    * @discussion
1630    * Abstract Libkern C++ classes--those with at least one
1631    * pure virtual method--should "call" this macro
1632    * immediately after the opening brace in a class declaration.
1633    * It leaves the current privacy state as <code>protected:</code>.
1634    */
1635#define OSDeclareAbstractStructors(className)                          \
1636    OSDeclareCommonStructors(className);                               \
1637    private:                                                           \
1638    className (); /* Make primary constructor private in abstract */   \
1639    protected:
1640
1641   /*!
1642    * @define OSDeclareFinalStructors
1643    * @hidecontents
1644    *
1645    * @abstract
1646    * Declares run-time type information and functions
1647    * for a final (non-subclassable) Libkern C++ class.
1648    *
1649    * @param className The name of the C++ class, as a raw token,
1650    *                  <i>not</i> a string or macro.
1651    *
1652    * @discussion
1653    * Final Libkern C++ classes--those that do not allow subclassing--should
1654    * "call" this macro immediately after the opening brace in a class declaration.
1655    * (Final classes in the kernel may actually have subclasses in the kernel,
1656    * but kexts cannot define any subclasses of a final class.)
1657    * It leaves the current privacy state as <code>protected:</code>.
1658    *
1659    * <b>Note:</b> If the class is exported by a pseudokext (symbol set),
1660    * the final symbol generated by this macro must be exported
1661    * for the final-class attribute to be enforced.
1662    *
1663    * <b>Warning:</b> Changing a class from "Default" to "Final" will break
1664    * binary compatibility.
1665    */
1666#define OSDeclareFinalStructors(className)                              \
1667        OSDeclareDefaultStructors(className)                            \
1668    private:                                                            \
1669        void __OSFinalClass(void);                                      \
1670    protected:
1671
1672
1673   /* Not to be included in headerdoc.
1674    *
1675    * @define OSDefineMetaClassWithInit
1676    * @hidecontents
1677    *
1678    * @abstract
1679    * Helper macro for for the standard metaclass-registration macros.
1680    * DO NOT USE.
1681    *
1682    * @param className      The name of the C++ class, as a raw token,
1683    *                       <i>not</i> a string or macro.
1684    * @param superclassName The name of the superclass of the C++ class,
1685    *                       as a raw token,
1686    *                       <i>not</i> a string or macro.
1687    * @param init           A function to call in the constructor
1688    *                       of the class's OSMetaClass.
1689    */
1690#define OSDefineMetaClassWithInit(className, superclassName, init)            \
1691    /* Class global data */                                                   \
1692    className ::MetaClass className ::gMetaClass;                             \
1693    const OSMetaClass * const className ::metaClass =                         \
1694        & className ::gMetaClass;                                             \
1695    const OSMetaClass * const className ::superClass =                        \
1696        & superclassName ::gMetaClass;                                        \
1697    /* Class member functions */                                              \
1698    className :: className(const OSMetaClass *meta)                           \
1699        : superclassName (meta) { }                                           \
1700    className ::~ className() { }                                             \
1701    const OSMetaClass * className ::getMetaClass() const                      \
1702        { return &gMetaClass; }                                               \
1703    /* The ::MetaClass constructor */                                         \
1704    className ::MetaClass::MetaClass()                                        \
1705        : OSMetaClass(#className, className::superClass, sizeof(className))   \
1706        { init; }
1707
1708
1709   /* Not to be included in headerdoc.
1710    *
1711    * @define OSDefineAbstractStructors
1712    * @hidecontents
1713    *
1714    * @abstract
1715    * Helper macro for for the standard metaclass-registration macros.
1716    * DO NOT USE.
1717    *
1718    * @param className      The name of the C++ class, as a raw token,
1719    *                       <i>not</i> a string or macro.
1720    * @param superclassName The name of the superclass of the C++ class,
1721    *                       as a raw token,
1722    *                       <i>not</i> a string or macro.
1723    */
1724#define OSDefineAbstractStructors(className, superclassName)        \
1725    OSObject * className ::MetaClass::alloc() const { return 0; }
1726
1727
1728   /* Not to be included in headerdoc.
1729    *
1730    * @define OSDefineDefaultStructors
1731    * @hidecontents
1732    *
1733    * @abstract
1734    * Helper macro for for the standard metaclass-registration macros.
1735    * DO NOT USE.
1736    *
1737    * @param className      The name of the C++ class, as a raw token,
1738    *                       <i>not</i> a string or macro.
1739    * @param superclassName The name of the superclass of the C++ class,
1740    *                       as a raw token,
1741    *                       <i>not</i> a string or macro.
1742    */
1743#define OSDefineDefaultStructors(className, superclassName)     \
1744    OSObject * className ::MetaClass::alloc() const             \
1745    { return new className; }                                   \
1746    className :: className () : superclassName (&gMetaClass)    \
1747    { gMetaClass.instanceConstructed(); }
1748
1749   /* Not to be included in headerdoc.
1750    *
1751    * @define OSDefineDefaultStructors
1752    * @hidecontents
1753    *
1754    * @abstract
1755    * Helper macro for for the standard metaclass-registration macros.
1756    * DO NOT USE.
1757    *
1758    * @param className      The name of the C++ class, as a raw token,
1759    *                       <i>not</i> a string or macro.
1760    * @param superclassName The name of the superclass of the C++ class,
1761    *                       as a raw token,
1762    *                       <i>not</i> a string or macro.
1763    */
1764#define OSDefineFinalStructors(className, superclassName)               \
1765    OSDefineDefaultStructors(className, superclassName)                 \
1766    void className ::__OSFinalClass(void) { }
1767
1768
1769   /* Not to be included in headerdoc.
1770    *
1771    * @define OSDefineMetaClassAndStructorsWithInit
1772    * @hidecontents
1773    *
1774    * @abstract
1775    * Helper macro for for the standard metaclass-registration macros.
1776    * DO NOT USE.
1777    *
1778    * @param className      The name of the C++ class, as a raw token,
1779    *                       <i>not</i> a string or macro.
1780    * @param superclassName The name of the superclass of the C++ class,
1781    *                       as a raw token,
1782    *                       <i>not</i> a string or macro.
1783    * @param init           A function to call in the constructor
1784    *                       of the class's OSMetaClass.
1785    */
1786#define OSDefineMetaClassAndStructorsWithInit(className, superclassName, init) \
1787    OSDefineMetaClassWithInit(className, superclassName, init)        \
1788    OSDefineDefaultStructors(className, superclassName)
1789
1790
1791   /* Not to be included in headerdoc.
1792    *
1793    * @define OSDefineMetaClassAndAbstractStructorsWithInit
1794    * @hidecontents
1795    *
1796    * @abstract
1797    * Helper macro for for the standard metaclass-registration macros.
1798    * DO NOT USE.
1799    *
1800    * @param className      The name of the C++ class, as a raw token,
1801    *                       <i>not</i> a string or macro.
1802    * @param superclassName The name of the superclass of the C++ class,
1803    *                       as a raw token,
1804    *                       <i>not</i> a string or macro.
1805    * @param init           A function to call in the constructor
1806    *                       of the class's OSMetaClass.
1807    */
1808#define OSDefineMetaClassAndAbstractStructorsWithInit(className, superclassName, init) \
1809    OSDefineMetaClassWithInit(className, superclassName, init)        \
1810    OSDefineAbstractStructors(className, superclassName)
1811
1812
1813   /* Not to be included in headerdoc.
1814    *
1815    * @define OSDefineMetaClassAndFinalStructorsWithInit
1816    * @hidecontents
1817    *
1818    * @abstract
1819    * Helper macro for for the standard metaclass-registration macros.
1820    * DO NOT USE.
1821    *
1822    * @param className      The name of the C++ class, as a raw token,
1823    *                       <i>not</i> a string or macro.
1824    * @param superclassName The name of the superclass of the C++ class,
1825    *                       as a raw token,
1826    *                       <i>not</i> a string or macro.
1827    * @param init           A function to call in the constructor
1828    *                       of the class's OSMetaClass.
1829    */
1830#define OSDefineMetaClassAndFinalStructorsWithInit(className, superclassName, init) \
1831    OSDefineMetaClassWithInit(className, superclassName, init)                      \
1832    OSDefineFinalStructors(className, superclassName)
1833
1834
1835   /* Helpers */
1836
1837   /* Not to be included in headerdoc.
1838    *
1839    * @define OSDefineMetaClass
1840    * @hidecontents
1841    *
1842    * @abstract
1843    * Helper macro for for the standard metaclass-registration macros.
1844    * DO NOT USE.
1845    *
1846    * @param className      The name of the C++ class, as a raw token,
1847    *                       <i>not</i> a string or macro.
1848    * @param superclassName The name of the superclass of the C++ class,
1849    *                       as a raw token,
1850    *                       <i>not</i> a string or macro.
1851    * @param init           A function to call in the constructor
1852    *                       of the class's OSMetaClass.
1853    */
1854#define OSDefineMetaClass(className, superclassName)            \
1855    OSDefineMetaClassWithInit(className, superclassName, )
1856
1857
1858   /*!
1859    * @define OSDefineMetaClassAndStructors
1860    * @hidecontents
1861    *
1862    * @abstract
1863    * Defines an OSMetaClass and associated routines
1864    * for a concrete Libkern C++ class.
1865    *
1866    * @param className      The name of the C++ class, as a raw token,
1867    *                       <i>not</i> a string or macro.
1868    * @param superclassName The name of the superclass of the C++ class,
1869    *                       as a raw token,
1870    *                       <i>not</i> a string or macro.
1871    *
1872    * @discussion
1873    * Concrete Libkern C++ classes should "call" this macro
1874    * at the beginning of their implementation files,
1875    * before any function implementations for the class.
1876    */
1877#define OSDefineMetaClassAndStructors(className, superclassName)    \
1878    OSDefineMetaClassAndStructorsWithInit(className, superclassName, )
1879
1880
1881   /*!
1882    * @define OSDefineMetaClassAndAbstractStructors
1883    * @hidecontents
1884    *
1885    * @abstract
1886    * Defines an OSMetaClass and associated routines
1887    * for an abstract Libkern C++ class.
1888    *
1889    * @param className      The name of the C++ class, as a raw token,
1890    *                       <i>not</i> a string or macro.
1891    * @param superclassName The name of the superclass of the C++ class,
1892    *                       as a raw token,
1893    *                       <i>not</i> a string or macro.
1894    *
1895    * @discussion
1896    * Abstract Libkern C++ classes--those with at least one
1897    * pure virtual method--should "call" this macro
1898    * at the beginning of their implementation files,
1899    * before any function implementations for the class.
1900    */
1901#define OSDefineMetaClassAndAbstractStructors(className, superclassName) \
1902    OSDefineMetaClassAndAbstractStructorsWithInit (className, superclassName, )
1903
1904
1905   /*!
1906    * @define OSDefineMetaClassAndFinalStructors
1907    * @hidecontents
1908    *
1909    * @abstract
1910    * Defines an OSMetaClass and associated routines
1911    * for a final (non-subclassable) Libkern C++ class.
1912    *
1913    * @param className      The name of the C++ class, as a raw token,
1914    *                       <i>not</i> a string or macro.
1915    * @param superclassName The name of the superclass of the C++ class,
1916    *                       as a raw token,
1917    *                       <i>not</i> a string or macro.
1918    *
1919    * @discussion
1920    * Final Libkern C++ classes--those that do not allow
1921    * subclassing--should "call" this macro at the beginning
1922    * of their implementation files,
1923    * before any function implementations for the class.
1924    * (Final classes in the kernel may actually have subclasses in the kernel,
1925    * but kexts cannot define any subclasses of a final class.)
1926    *
1927    * <b>Note:</b> If the class is exported by a pseudokext (symbol set),
1928    * the final symbol generated by this macro must be exported
1929    * for the final-class attribute to be enforced.
1930    *
1931    * <b>Warning:</b> Changing a class from "Default" to "Final" will break
1932    * binary compatibility.
1933    */
1934#define OSDefineMetaClassAndFinalStructors(className, superclassName)   \
1935    OSDefineMetaClassAndFinalStructorsWithInit(className, superclassName, )
1936
1937
1938    // Dynamic vtable patchup support routines and types
1939    void reservedCalled(int ind) const;
1940
1941
1942   /*!
1943    * @define OSMetaClassDeclareReservedUnused
1944    * @hidecontents
1945    *
1946    * @abstract
1947    * Reserves vtable space for new virtual functions
1948    * in a Libkern C++ class.
1949    *
1950    * @param className      The name of the C++ class, as a raw token,
1951    *                       <i>not</i> a string or macro.
1952    * @param index          The numeric index of the vtable slot,
1953    *                       as a raw constant, beginning from 0.
1954    *
1955    * @discussion
1956    * Libkern C++ classes in kernel extensions that can be used as libraries
1957    * can provide for backward compatibility by declaring a number
1958    * of reserved vtable slots
1959    * that can be replaced with new functions as they are added.
1960    * Each reserved declaration must be accompanied in the implementation
1961    * by a corresponding reference to
1962    * <code>@link OSMetaClassDefineReservedUnused
1963    *       OSMetaClassDefineReservedUnused@/link</code>.
1964    *
1965    * When replacing a reserved slot, change the macro from "Unused"
1966    * to "Used" to document the fact that the slot used to be reserved,
1967    * and declare the new function immediately after the "Used" macro
1968    * to preserve vtable ordering.
1969    * See
1970    * <code>@link OSMetaClassDeclareReservedUsed
1971    *       OSMetaClassDeclareReservedUsed@/link</code>.
1972    */
1973#if APPLE_KEXT_VTABLE_PADDING
1974#define OSMetaClassDeclareReservedUnused(className, index)        \
1975    private:                                                      \
1976    virtual void _RESERVED ## className ## index ()
1977#else
1978#define OSMetaClassDeclareReservedUnused(className, index)
1979#endif
1980
1981
1982   /*!
1983    * @define OSMetaClassDeclareReservedUsed
1984    * @hidecontents
1985    *
1986    * @abstract
1987    * Documents use of reserved vtable space for new virtual functions
1988    * in a Libkern C++ class.
1989    *
1990    * @param className      The name of the C++ class, as a raw token,
1991    *                       <i>not</i> a string or macro.
1992    * @param index          The numeric index of the vtable slot,
1993    *                       as a raw constant, beginning from 0.
1994    *
1995    * @discussion
1996    * This macro evaluates to nothing, and is used to document reserved
1997    * vtable slots as they are filled.
1998    * See
1999    * <code>@link OSMetaClassDeclareReservedUnused
2000    *       OSMetaClassDeclareReservedUnused@/link</code>.
2001    */
2002#define OSMetaClassDeclareReservedUsed(className, index)
2003
2004
2005   /*!
2006    * @define OSMetaClassDefineReservedUnused
2007    * @hidecontents
2008    *
2009    * @abstract
2010    * Defines a reserved vtable slot for a Libkern C++ class.
2011    *
2012    * @param className      The name of the C++ class, as a raw token,
2013    *                       <i>not</i> a string or macro.
2014    * @param index          The numeric index of the vtable slot,
2015    *                       as a raw constant, beginning from 0.
2016    *
2017    * @discussion
2018    * Libkern C++ classes in kernel extensions that can be used as libraries
2019    * can provide for backward compatibility by declaring a number
2020    * of reserved vtable slots
2021    * that can be replaced with new functions as they are added.
2022    * Each reserved defintion accompanies
2023    * a corresponding declaration created with
2024    * <code>@link OSMetaClassDeclareReservedUnused
2025    *       OSMetaClassDeclareReservedUnused@/link</code>.
2026    *
2027    * This macro is used in the implementation file
2028    * to provide a placeholder definition for the reserved vtable slot,
2029    * as a function that calls <code>panic</code> with an error message.
2030    *
2031    * When replacing a reserved slot, change the macro from "Unused"
2032    * to "Used" to document the fact that the slot used to be reserved,
2033    * and declare the new function immediately after the "Used" macro
2034    * to preserve vtable ordering.
2035    * See
2036    * <code>@link OSMetaClassDefineReservedUsed
2037    *       OSMetaClassDefineReservedUsed@/link</code>.
2038    */
2039#if APPLE_KEXT_VTABLE_PADDING
2040#define OSMetaClassDefineReservedUnused(className, index)       \
2041void className ::_RESERVED ## className ## index ()             \
2042	{ gMetaClass.reservedCalled(index); }
2043#else
2044#define OSMetaClassDefineReservedUnused(className, index)
2045#endif
2046
2047
2048   /*!
2049    * @define OSMetaClassDefineReservedUsed
2050    * @hidecontents
2051    *
2052    * @abstract
2053    * Reserves vtable space for new virtual functions in a Libkern C++ class.
2054    *
2055    * @param className      The name of the C++ class, as a raw token,
2056    *                       <i>not</i> a string or macro.
2057    * @param index          The numeric index of the vtable slot,
2058    *                       as a raw constant, beginning from 0.
2059    *
2060    * @discussion
2061    * This macro evaluates to nothing, and is used to document reserved
2062    * vtable slots as they are filled.
2063    * See
2064    * <code>@link OSMetaClassDefineReservedUnused
2065    *       OSMetaClassDefineReservedUnused@/link</code>.
2066    */
2067#define OSMetaClassDefineReservedUsed(className, index)
2068
2069    // I/O Kit debug internal routines.
2070    static void printInstanceCounts();
2071    static void serializeClassDictionary(OSDictionary * dict);
2072
2073private:
2074    // Obsolete APIs
2075    static OSDictionary * getClassDictionary();
2076    virtual bool serialize(OSSerialize * serializer) const;
2077
2078    // Virtual Padding functions for MetaClass's
2079    OSMetaClassDeclareReservedUnused(OSMetaClass, 0);
2080    OSMetaClassDeclareReservedUnused(OSMetaClass, 1);
2081    OSMetaClassDeclareReservedUnused(OSMetaClass, 2);
2082    OSMetaClassDeclareReservedUnused(OSMetaClass, 3);
2083    OSMetaClassDeclareReservedUnused(OSMetaClass, 4);
2084    OSMetaClassDeclareReservedUnused(OSMetaClass, 5);
2085    OSMetaClassDeclareReservedUnused(OSMetaClass, 6);
2086    OSMetaClassDeclareReservedUnused(OSMetaClass, 7);
2087};
2088
2089#endif /* !_LIBKERN_OSMETACLASS_H */
2090