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