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