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