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