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