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