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