]> git.saurik.com Git - apple/xnu.git/blob - libkern/libkern/c++/OSMetaClass.h
ef527fdd7dce5896d3f678e68a20117c72829fb1
[apple/xnu.git] / libkern / libkern / c++ / OSMetaClass.h
1 /*
2 * Copyright (c) 2000 Apple Computer, 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
43 #if !defined(__ppc__) || __GNUC__ < 3
44 #define APPLE_KEXT_COMPATIBILITY
45 #else
46 #define APPLE_KEXT_COMPATIBILITY __attribute__ ((apple_kext_compatibility))
47 #endif
48
49 #define APPLE_KEXT_VTABLE_PADDING 1
50
51 #if defined(__LP64__)
52 #define APPLE_KEXT_LEGACY_ABI 0
53 #elif defined(__arm__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
54 #define APPLE_KEXT_LEGACY_ABI 0
55 #else
56 #define APPLE_KEXT_LEGACY_ABI 1
57 #endif
58
59 #if APPLE_KEXT_VTABLE_PADDING
60 #define APPLE_KEXT_PAD_METHOD virtual
61 #define APPLE_KEXT_PAD_IMPL(index) gMetaClass.reservedCalled(index)
62 #else
63 #define APPLE_KEXT_PAD_METHOD static
64 #define APPLE_KEXT_PAD_IMPL(index)
65 #endif
66
67 class OSMetaClassBase
68 {
69 public:
70 /*! @function OSTypeAlloc
71 @abstract Allocate an instance of the desired object.
72 @discussion The OSTypeAlloc macro can be used to break the binary compatibility difficulties presented by new. The problem is that C++ compiles the knowledge of the size of the class into the cade calling new. If you use the alloc code however the class size is determined by the callee not the caller.
73 @param type Name of the desired type to be created.
74 @result 'this' if object cas been successfully created.
75 */
76 #define OSTypeAlloc(type) ((type *) ((type::metaClass)->alloc()))
77
78 /*! @function OSTypeID
79 @abstract Given the name of a class return it's typeID
80 @param type Name of the desired type, eg. OSObject.
81 @result A unique Type ID for the class.
82 */
83 #define OSTypeID(type) (type::metaClass)
84
85 /*! @function OSTypeIDInst
86 @abstract Given a pointer to an object return it's typeID
87 @param typeinst An instance of an OSObject subclass.
88 @result The typeID, ie. OSMetaClass *.
89 */
90 #define OSTypeIDInst(typeinst) ((typeinst)->getMetaClass())
91
92 /*! @function OSDynamicCast
93 @abstract Roughly analogous to (type *) inst, but check if valid first.
94 @discussion OSDynamicCast is an attempt to implement a rudimentary equivalent to rtti's dynamic_cast<T> operator. Embedded-C++ doesn't allow the use of rtti. OSDynamicCast is build on the OSMetaClass mechanism. Note it is safe to call this with a 0 parameter.
95 @param type name of desired class name. Notice that it is assumed that you desire to cast to a pointer to an object of this type. Also type qualifiers, like const, are not recognized and will cause an, usually obscure, compile error.
96 @param inst Pointer to object that you wish to attempt to type cast. May be 0.
97 @result inst if object non-zero and it is of the desired type, otherwise 0.
98 */
99 #define OSDynamicCast(type, inst) \
100 ((type *) OSMetaClassBase::safeMetaCast((inst), OSTypeID(type)))
101
102 /*! @function OSCheckTypeInst
103 @abstract Is the target object a subclass of the reference object?
104 @param typeinst Reference instance of an object, desired type.
105 @param inst Instance of object to check for type compatibility.
106 @result false if typeinst or inst are 0 or inst is not a subclass of typeinst's class. true otherwise.
107 */
108 #define OSCheckTypeInst(typeinst, inst) \
109 OSMetaClassBase::checkTypeInst(inst, typeinst)
110
111 typedef void (*_ptf_t)(void);
112
113 #if APPLE_KEXT_LEGACY_ABI
114
115 // Arcane evil code interprets a C++ pointer to function as specified in the
116 // -fapple-kext ABI, i.e. the gcc-2.95 generated code. IT DOES NOT ALLOW
117 // the conversion of functions that are from MULTIPLY inherited classes.
118
119 static inline _ptf_t
120 _ptmf2ptf(const OSMetaClassBase *self, void (OSMetaClassBase::*func)(void))
121 {
122 union {
123 void (OSMetaClassBase::*fIn)(void);
124 struct { // Pointer to member function 2.95
125 unsigned short fToff;
126 short fVInd;
127 union {
128 _ptf_t fPFN;
129 short fVOff;
130 } u;
131 } fptmf2;
132 } map;
133
134 map.fIn = func;
135 if (map.fptmf2.fToff) {
136 panic("Multiple inheritance is not supported");
137 return 0;
138 } else if (map.fptmf2.fVInd < 0) {
139 // Not virtual, i.e. plain member func
140 return map.fptmf2.u.fPFN;
141 } else {
142 union {
143 const OSMetaClassBase *fObj;
144 _ptf_t **vtablep;
145 } u;
146 u.fObj = self;
147
148 // Virtual member function so dereference vtable
149 return (*u.vtablep)[map.fptmf2.fVInd - 1];
150 }
151 }
152
153 #else /* !APPLE_KEXT_LEGACY_ABI */
154
155
156 // Slightly less arcane and slightly less evil code to do
157 // the same for kexts compiled with the standard Itanium C++
158 // ABI
159
160 static inline _ptf_t
161 _ptmf2ptf(const OSMetaClassBase *self, void (OSMetaClassBase::*func)(void))
162 {
163 union {
164 void (OSMetaClassBase::*fIn)(void);
165 uintptr_t fVTOffset;
166 _ptf_t fPFN;
167 } map;
168
169 map.fIn = func;
170
171 if (map.fVTOffset & 1) {
172 // virtual
173 union {
174 const OSMetaClassBase *fObj;
175 _ptf_t **vtablep;
176 } u;
177 u.fObj = self;
178
179 // Virtual member function so dereference vtable
180 return *(_ptf_t *)(((uintptr_t)*u.vtablep) + map.fVTOffset - 1);
181 } else {
182 // Not virtual, i.e. plain member func
183 return map.fPFN;
184 }
185 }
186
187
188 #endif /* !APPLE_KEXT_LEGACY_ABI */
189
190 /*! @function OSMemberFunctionCast
191 @abstract Convert a pointer to a member function to a c-style pointer to function. No warnings are generated.
192 @param type The type of pointer function desired.
193 @param self The this pointer of the object whose function you wish to cache.
194 @param func The pointer to member function itself, something like &Base::func.
195 @result A pointer to function of the given type. This function will panic if an attempt is made to call it with a multiply inherited class.
196 */
197
198 #define OSMemberFunctionCast(cptrtype, self, func) \
199 (cptrtype) OSMetaClassBase:: \
200 _ptmf2ptf(self, (void (OSMetaClassBase::*)(void)) func)
201
202 protected:
203 OSMetaClassBase();
204 virtual ~OSMetaClassBase();
205
206 private:
207 // Disable copy constructors of OSMetaClassBase based objects
208 /*! @function operator =
209 @abstract Disable implicit copy constructor by making private
210 @param src Reference to source object that isn't allowed to be copied
211 */
212 void operator =(OSMetaClassBase &src);
213
214 /*! @function OSMetaClassBase
215 @abstract Disable implicit copy constructor by making private
216 @param src Reference to source object that isn't allowed to be copied
217 */
218 OSMetaClassBase(OSMetaClassBase &src);
219
220 public:
221 /*! @function release
222 @abstract Primary implementation of the release mechanism.
223 @discussion If $link retainCount <= the when argument then call $link free(). This indirect implementation of $link release allows the developer to break reference circularity. An example of this sort of problem is a parent/child mutual reference, either the parent or child can implement: void release() { release(2); } thus breaking the cirularity.
224 @param when When retainCount == when then call free(). */
225 virtual void release(int when) const = 0;
226
227 /*! @function getRetainCount
228 @abstract How many times has this object been retained?
229 @result Current retain count
230 */
231 virtual int getRetainCount() const = 0;
232
233 /*! @function retain
234 @abstract Retain a reference in this object.
235 */
236 virtual void retain() const = 0;
237 /*! @function release
238 @abstract Release a reference to this object
239 */
240 virtual void release() const = 0;
241
242 /*! @function serialize
243 @abstract
244 @discussion
245 @param s
246 @result
247 */
248 virtual bool serialize(OSSerialize *s) const = 0;
249
250 virtual const OSMetaClass * getMetaClass() const = 0;
251
252 /*! @function isEqualTo
253 @abstract Is this == anObj?
254 @discussion OSMetaClassBase::isEqualTo implements this as a shallow pointer comparison. The OS container classes do a more meaningful comparison. Your mileage may vary.
255 @param anObj Object to compare 'this' to.
256 @result true if the objects are equivalent, false otherwise.
257 */
258 virtual bool isEqualTo(const OSMetaClassBase *anObj) const;
259
260 /*! @function metaCast
261 @abstract Check to see if this object is or inherits from the given type.
262 @discussion This function is the guts of the OSMetaClass system. IODynamicCast, qv, is implemented using this function.
263 @param toMeta Pointer to a constant OSMetaClass for the desired target type.
264 @result 'this' if object is of desired type, otherwise 0.
265 */
266 OSMetaClassBase *metaCast(const OSMetaClass *toMeta) const;
267
268
269 /*! @function metaCast
270 @abstract See OSMetaClassBase::metaCast(const OSMetaClass *)
271 @param toMeta OSSymbol of the desired class' name.
272 @result 'this' if object is of desired type, otherwise 0.
273 */
274 OSMetaClassBase *metaCast(const OSSymbol *toMeta) const;
275
276 /*! @function metaCast
277 @abstract See OSMetaClassBase::metaCast(const OSMetaClass *)
278 @param toMeta OSString of the desired class' name.
279 @result 'this' if object is of desired type, otherwise 0.
280 */
281 OSMetaClassBase *metaCast(const OSString *toMeta) const;
282
283 /*! @function metaCast
284 @abstract See OSMetaClassBase::metaCast(const OSMetaClass *)
285 @param toMeta const char * C String of the desired class' name.
286 @result 'this' if object is of desired type, otherwise 0.
287 */
288 OSMetaClassBase *metaCast(const char *toMeta) const;
289
290 // Helper inlines for runtime type preprocessor macros
291 static OSMetaClassBase *
292 safeMetaCast(const OSMetaClassBase *me, const OSMetaClass *toType);
293
294 static bool
295 checkTypeInst(const OSMetaClassBase *inst, const OSMetaClassBase *typeinst);
296
297 public:
298
299 /*! @function taggedRetain
300 @abstract Retain a tagged reference in this object.
301 */
302 // WAS: virtual void _RESERVEDOSMetaClassBase0();
303 virtual void taggedRetain(const void *tag = 0) const = 0;
304
305 /*! @function taggedRelease
306 @abstract Release a tagged reference to this object
307 */
308 // WAS: virtual void _RESERVEDOSMetaClassBase1();
309 virtual void taggedRelease(const void *tag = 0) const = 0;
310
311 protected:
312 /*! @function taggedRelease
313 @abstract Release a tagged reference to this object and free if retainCount == when on entry
314 */
315 // WAS: virtual void _RESERVEDOSMetaClassBase2();
316 virtual void taggedRelease(const void *tag, const int when) const = 0;
317
318 private:
319 // Virtual Padding
320 virtual void _RESERVEDOSMetaClassBase3();
321 virtual void _RESERVEDOSMetaClassBase4();
322 virtual void _RESERVEDOSMetaClassBase5();
323 virtual void _RESERVEDOSMetaClassBase6();
324 virtual void _RESERVEDOSMetaClassBase7();
325 } APPLE_KEXT_COMPATIBILITY;
326
327 /*!
328 @class OSMetaClass : OSMetaClassBase
329 @abstract An instance of a OSMetaClass represents one class then the kernel's runtime type information system is aware of.
330 */
331 class OSMetaClass : private OSMetaClassBase
332 {
333
334 private:
335 // Can never be allocated must be created at compile time
336 static void *operator new(size_t size);
337
338 struct ExpansionData { };
339
340 /*! @var reserved Reserved for future use. (Internal use only) */
341 ExpansionData *reserved;
342
343 /*! @var superClass Handle to the superclass' meta class. */
344 const OSMetaClass *superClassLink;
345
346 /*! @var className OSSymbol of the class' name. */
347 const OSSymbol *className;
348
349 /*! @var classSize How big is a single instancde of this class. */
350 unsigned int classSize;
351
352 /*! @var instanceCount Roughly number of instances of the object. Used primarily as a code in use flag. */
353 mutable unsigned int instanceCount;
354
355 /*! @function OSMetaClass
356 @abstract Private the default constructor */
357 OSMetaClass();
358
359 // Called by postModLoad
360 /*! @function logError
361 @abstract Given an error code log an error string using printf */
362 static void logError(OSReturn result);
363
364 public:
365
366 /*! @function getMetaClassWithName
367 @abstract Lookup a meta-class in the runtime type information system
368 @param name Name of the desired class's meta-class.
369 @result pointer to a meta-class object if found, 0 otherwise. */
370
371 static const OSMetaClass *getMetaClassWithName(const OSSymbol *name);
372
373 protected:
374 /*! @function retain
375 @abstract Implement abstract but should no dynamic allocation is allowed */
376 virtual void retain() const;
377
378 /*! @function release
379 @abstract Implement abstract but should no dynamic allocation is allowed */
380 virtual void release() const;
381
382 /*! @function release
383 @abstract Implement abstract but should no dynamic allocation is allowed
384 @param when ignored. */
385 virtual void release(int when) const;
386
387 /*! @function taggedRetain
388 @abstract Retain a tagged reference in this object.
389 */
390 virtual void taggedRetain(const void *tag = 0) const;
391
392 /*! @function release
393 @abstract Release a tagged reference to this object
394 */
395 virtual void taggedRelease(const void *tag = 0) const;
396
397 /*! @function release
398 @abstract Release a tagged reference to this object
399 */
400 virtual void taggedRelease(const void *tag, const int when) const;
401
402 /*! @function getRetainCount
403 @abstract Implement abstract but should no dynamic allocation is allowed */
404 virtual int getRetainCount() const;
405
406 virtual const OSMetaClass * getMetaClass() const;
407
408 /*! @function OSMetaClass
409 @abstract Constructor for OSMetaClass objects
410 @discussion This constructor is protected and cannot not be used to instantiate an OSMetaClass object, i.e. OSMetaClass is an abstract class. This function stores the currently constructing OSMetaClass instance away for later processing. See preModLoad and postModLoad.
411 @param inClassName cString of the name of the class this meta-class represents.
412 @param inSuperClassName cString of the name of the super class.
413 @param inClassSize sizeof the class. */
414 OSMetaClass(const char *inClassName,
415 const OSMetaClass *inSuperClass,
416 unsigned int inClassSize);
417
418 /*! @function ~OSMetaClass
419 @abstract Destructor for OSMetaClass objects
420 @discussion If this function is called it means that the object code that implemented this class is actually in the process of unloading. The destructor removes all reference's to the subclass from the runtime type information system. */
421 virtual ~OSMetaClass();
422
423 // Needs to be overriden as NULL as all OSMetaClass objects are allocated
424 // statically at compile time, don't accidently try to free them.
425 void operator delete(void *, size_t) { };
426
427 public:
428 static const OSMetaClass * const metaClass;
429
430 /*! @function preModLoad
431 @abstract Prepare the runtime type system for the load of a module.
432 @discussion Prepare the runtime type information system for the loading of new all meta-classes constructed between now and the next postModLoad. preModLoad grab's a lock so that the runtime type information system loading can be protected, the lock is released by the postModLoad function. Any OSMetaClass that is constructed between the bracketing pre and post calls will be assosiated with the module name.
433 @param kmodName globally unique cString name of the kernel module being loaded.
434 @result If success full return a handle to be used in later calls 0 otherwise. */
435 static void *preModLoad(const char *kmodName);
436
437 /*! @function checkModLoad
438 @abstract Check if the current load attempt is still OK.
439 @param loadHandle Handle returned when a successful call to preModLoad is made.
440 @result true if no error's are outstanding and the system is primed to recieve more objects. */
441 static bool checkModLoad(void *loadHandle);
442
443 /*! @function postModLoad
444 @abstract Finish postprocessing on a kernel module's meta-classes.
445 @discussion As the order of static object construction is undefined it is necessary to process the constructors in two phases. These phases rely on global information that is created be the preparation step, preModLoad, which also guarantees single threading between multiple modules. Phase one was the static construction of each meta-class object one by one withing the context prepared by the preModLoad call. postModLoad is the second phase of processing. Inserts links all of the super class inheritance chains up, inserts the meta-classes into the global register of classes and records for each meta-class which kernel module caused it's construction. Finally it cleans up the temporary storage and releases the single threading lock and returns whatever error has been recorded in during the construction phase or the post processing phase.
446 @param loadHandle Handle returned when a successful call to preModLoad is made.
447 @result Error code of the first error encountered. */
448 static OSReturn postModLoad(void *loadHandle);
449
450 /*! @function modHasInstance
451 @abstract Do any of the objects represented by OSMetaClass and associated with the given kernel module name have instances?
452 @discussion Check all meta-classes associated with the module name and check their instance counts. This function is used to check to see if a module can be unloaded. Obviously if an instance is still outstanding it isn't safe to unload the code that relies on that object.
453 @param kmodName cString of the kernel module name.
454 @result true if there are any current instances of any class in the module.
455 */
456 static bool modHasInstance(const char *kmodName);
457
458 /*! @function reportModInstances
459 @abstract Log any object that has instances in a module.
460 @discussion When a developer ask for a module to be unloaded but the unload fails due to outstanding instances. This function will report which classes still have instances. It is intended mostly for developers to find problems with unloading classes and will be called automatically by 'verbose' unloads.
461 @param kmodName cString of the kernel module name. */
462 static void reportModInstances(const char *kmodName);
463
464 /*! @function considerUnloads
465 @abstract Schedule module unloading.
466 @discussion Schedule unused modules to be unloaded; called when IOKit matching goes idle. */
467
468 static void considerUnloads();
469
470 /*! @function allocClassWithName
471 @abstract Lookup a meta-class in the runtime type information system and return the results of an alloc call.
472 @param name Name of the desired class.
473 @result pointer to an new object, 0 if not found or so memory. */
474 static OSObject *allocClassWithName(const OSSymbol *name);
475
476 /*! @function allocClassWithName
477 @abstract Lookup a meta-class in the runtime type information system and return the results of an alloc call.
478 @param name Name of the desired class.
479 @result pointer to an new object, 0 if not found or so memory. */
480 static OSObject *allocClassWithName(const OSString *name);
481
482 /*! @function allocClassWithName
483 @abstract Lookup a meta-class in the runtime type information system and return the results of an alloc call.
484 @param name Name of the desired class.
485 @result pointer to an new object, 0 if not found or so memory. */
486 static OSObject *allocClassWithName(const char *name);
487
488 /*! @function checkMetaCastWithName
489 @abstract Introspect an objects inheritance tree looking for a class of the given name. Basis of MacOSX's kernel dynamic casting mechanism.
490 @param name Name of the desired class or super class.
491 @param in object to be introspected.
492 @result in parameter if cast valid, 0 otherwise. */
493 static OSMetaClassBase *
494 checkMetaCastWithName(const OSSymbol *name, const OSMetaClassBase *in);
495
496 /*! @function checkMetaCastWithName
497 @abstract Introspect an objects inheritance tree looking for a class of the given name. Basis of MacOSX's kernel dynamic casting mechanism.
498 @param name Name of the desired class or super class.
499 @param in object to be introspected.
500 @result in parameter if cast valid, 0 otherwise. */
501 static OSMetaClassBase *
502 checkMetaCastWithName(const OSString *name, const OSMetaClassBase *in);
503
504 /*! @function checkMetaCastWithName
505 @abstract Introspect an objects inheritance tree looking for a class of the given name. Basis of MacOSX's kernel dynamic casting mechanism.
506 @param name Name of the desired class or super class.
507 @param in object to be introspected.
508 @result in parameter if cast valid, 0 otherwise. */
509 static OSMetaClassBase *
510 checkMetaCastWithName(const char *name, const OSMetaClassBase *in);
511
512
513 /*! @function instanceConstructed
514 @abstract Counts the instances of the class behind this metaclass.
515 @discussion Every non-abstract class that inherits from OSObject has a default constructor that calls it's own meta-class' instanceConstructed function. This constructor is defined by the OSDefineMetaClassAndStructors macro (qv) that all OSObject subclasses must use. Also if the instance count goes from 0 to 1, ie the first instance, then increment the instance count of the super class */
516 void instanceConstructed() const;
517
518 /*! @function instanceDestructed
519 @abstract Removes one instance of the class behind this metaclass.
520 @discussion OSObject's free function calls this method just before it does a 'delete this' on itself. If the instance count transitions from 1 to 0, i.e. the last object, then one instance of the superclasses is also removed. */
521 void instanceDestructed() const;
522
523
524 /*! @function checkMetaCast
525 @abstract Ask a OSMetaClass instance if the given object is either an instance of it or an instance of a subclass of it.
526 @param check Pointer of object to introspect.
527 @result check parameter if cast valid, 0 otherwise. */
528 OSMetaClassBase *checkMetaCast(const OSMetaClassBase *check) const;
529
530
531 /*! @function getInstanceCount
532 @abstract How many instances of the class have been created.
533 @result Count of the number of instances. */
534 unsigned int getInstanceCount() const;
535
536
537 /*! @function getSuperClass
538 @abstract 'Get'ter for the super class.
539 @result Pointer to superclass, chain ends with 0 for OSObject. */
540 const OSMetaClass *getSuperClass() const;
541
542 /*! @function getKmodName
543 @abstract 'Get'ter for the name of the kmod.
544 @result OSSymbol representing the kmod name. */
545 const OSSymbol *getKmodName() const;
546
547 /*! @function getClassName
548 @abstract 'Get'ter for class name.
549 @result cString of the class name. */
550 const char *getClassName() const;
551
552 /*! @function getClassSize
553 @abstract 'Get'ter for sizeof(class).
554 @result sizeof of class that this OSMetaClass instance represents. */
555 unsigned int getClassSize() const;
556
557 /*! @function alloc
558 @abstract Allocate an instance of the class that this OSMetaClass instance represents.
559 @discussion This alloc function is analogous to the old ObjC class alloc method. Typically not used by clients as the static function allocClassWithName is more generally useful. Infact that function is implemented in terms of this virtual function. All subclass's of OSMetaClass must implement this function but that is what the OSDefineMetaClassAndStructor's families of macros does for the developer automatically.
560 @result Pointer to a new object with a retain count of 1. */
561 virtual OSObject *alloc() const = 0;
562
563 /*! @function OSDeclareCommonStructors
564 @abstract Basic helper macro for the OSDeclare for Default and Abstract macros, qv. DO NOT USE.
565 @param className Name of class. NO QUOTES. */
566 #define OSDeclareCommonStructors(className) \
567 private: \
568 static const OSMetaClass * const superClass; \
569 public: \
570 static const OSMetaClass * const metaClass; \
571 static class MetaClass : public OSMetaClass { \
572 public: \
573 MetaClass(); \
574 virtual OSObject *alloc() const; \
575 } gMetaClass; \
576 friend class className ::MetaClass; \
577 virtual const OSMetaClass * getMetaClass() const; \
578 protected: \
579 className (const OSMetaClass *); \
580 virtual ~ className ()
581
582
583 /*! @function OSDeclareDefaultStructors
584 @abstract One of the macro's used in the class declaration of all subclasses of OSObject, declares runtime type information data and interfaces.
585 @discussion Macro used in the class declaration all subclasses of OSObject, declares runtime type information data and interfaces. By convention it should be 'called' immediately after the opening brace in a class declaration. It leaves the current privacy state as 'protected:'.
586 @param className Name of class. NO QUOTES. */
587 #define OSDeclareDefaultStructors(className) \
588 OSDeclareCommonStructors(className); \
589 public: \
590 className (); \
591 protected:
592
593
594 /*! @function OSDeclareAbstractStructors
595 @abstract One of the macro's used in the class declaration of all subclasses of OSObject, declares runtime type information data and interfaces.
596 @discussion This macro is used when the class being declared has one or more '= 0' pure virtual methods and thus it is illegal to create an instance of this class. It leaves the current privacy state as 'protected:'.
597 @param className Name of class. NO QUOTES. */
598 #define OSDeclareAbstractStructors(className) \
599 OSDeclareCommonStructors(className); \
600 private: \
601 className (); /* Make primary constructor private in abstract */ \
602 protected:
603
604 /*! @function OSDefineMetaClassWithInit
605 @abstract Basic helper macro for the OSDefineMetaClass for the default and Abstract macros, qv. DO NOT USE.
606 @param className Name of class. NO QUOTES and NO MACROS.
607 @param superClassName Name of super class. NO QUOTES and NO MACROS.
608 @param init Name of a function to call after the OSMetaClass is constructed. */
609 #define OSDefineMetaClassWithInit(className, superClassName, init) \
610 /* Class global data */ \
611 className ::MetaClass className ::gMetaClass; \
612 const OSMetaClass * const className ::metaClass = \
613 & className ::gMetaClass; \
614 const OSMetaClass * const className ::superClass = \
615 & superClassName ::gMetaClass; \
616 /* Class member functions */ \
617 className :: className(const OSMetaClass *meta) \
618 : superClassName (meta) { } \
619 className ::~ className() { } \
620 const OSMetaClass * className ::getMetaClass() const \
621 { return &gMetaClass; } \
622 /* The ::MetaClass constructor */ \
623 className ::MetaClass::MetaClass() \
624 : OSMetaClass(#className, className::superClass, sizeof(className)) \
625 { init; }
626
627 /*! @function OSDefineAbstractStructors
628 @abstract Basic helper macro for the OSDefineMetaClass for the default and Abstract macros, qv. DO NOT USE.
629 @param className Name of class. NO QUOTES and NO MACROS.
630 @param superClassName Name of super class. NO QUOTES and NO MACROS. */
631 #define OSDefineAbstractStructors(className, superClassName) \
632 OSObject * className ::MetaClass::alloc() const { return 0; }
633
634 /*! @function OSDefineDefaultStructors
635 @abstract Basic helper macro for the OSDefineMetaClass for the default and Abstract macros, qv. DO NOT USE.
636 @param className Name of class. NO QUOTES and NO MACROS.
637 @param superClassName Name of super class. NO QUOTES and NO MACROS. */
638 #define OSDefineDefaultStructors(className, superClassName) \
639 OSObject * className ::MetaClass::alloc() const \
640 { return new className; } \
641 className :: className () : superClassName (&gMetaClass) \
642 { gMetaClass.instanceConstructed(); }
643
644
645 /*! @function OSDefineMetaClassAndAbstractStructorsWithInit
646 @abstract Primary definition macro for all abstract classes that a subclasses of OSObject.
647 @discussion Define an OSMetaClass subclass and the primary constructors and destructors for a subclass of OSObject that is an abstract class. In general this 'function' is 'called' at the top of the file just before the first function is implemented for a particular class. Once the OSMetaClass has been constructed, at load time, call the init routine. NB you can not rely on the order of execution of the init routines.
648 @param className Name of class. NO QUOTES and NO MACROS.
649 @param superClassName Name of super class. NO QUOTES and NO MACROS.
650 @param init Name of a function to call after the OSMetaClass is constructed. */
651 #define OSDefineMetaClassAndAbstractStructorsWithInit(className, superClassName, init) \
652 OSDefineMetaClassWithInit(className, superClassName, init) \
653 OSDefineAbstractStructors(className, superClassName)
654
655 /*! @function OSDefineMetaClassAndStructorsWithInit
656 @abstract See OSDefineMetaClassAndStructors
657 @discussion Define an OSMetaClass subclass and the primary constructors and destructors for a subclass of OSObject that isn't an abstract class. In general this 'function' is 'called' at the top of the file just before the first function is implemented for a particular class. Once the OSMetaClass has been constructed, at load time, call the init routine. NB you can not rely on the order of execution of the init routines.
658 @param className Name of class. NO QUOTES and NO MACROS.
659 @param superClassName Name of super class. NO QUOTES and NO MACROS.
660 @param init Name of a function to call after the OSMetaClass is constructed. */
661 #define OSDefineMetaClassAndStructorsWithInit(className, superClassName, init) \
662 OSDefineMetaClassWithInit(className, superClassName, init) \
663 OSDefineDefaultStructors(className, superClassName)
664
665 /* Helpers */
666 /*! @function OSDefineMetaClass
667 @abstract Define an OSMetaClass instance, used for backward compatiblility only.
668 @param className Name of class. NO QUOTES and NO MACROS.
669 @param superClassName Name of super class. NO QUOTES and NO MACROS. */
670 #define OSDefineMetaClass(className, superClassName) \
671 OSDefineMetaClassWithInit(className, superClassName, )
672
673 /*! @function OSDefineMetaClassAndStructors
674 @abstract Define an OSMetaClass subclass and the runtime system routines.
675 @discussion Define an OSMetaClass subclass and the primary constructors and destructors for a subclass of OSObject that isn't an abstract class. In general this 'function' is 'called' at the top of the file just before the first function is implemented for a particular class.
676 @param className Name of class. NO QUOTES and NO MACROS.
677 @param superClassName Name of super class. NO QUOTES and NO MACROS. */
678 #define OSDefineMetaClassAndStructors(className, superClassName) \
679 OSDefineMetaClassAndStructorsWithInit(className, superClassName, )
680
681 /*! @function OSDefineMetaClassAndAbstractStructors
682 @abstract Define an OSMetaClass subclass and the runtime system routines.
683 @discussion Define an OSMetaClass subclass and the primary constructors and destructors for a subclass of OSObject that is an abstract class. In general this 'function' is 'called' at the top of the file just before the first function is implemented for a particular class.
684 @param className Name of class. NO QUOTES and NO MACROS.
685 @param superClassName Name of super class. NO QUOTES and NO MACROS. */
686 #define OSDefineMetaClassAndAbstractStructors(className, superClassName) \
687 OSDefineMetaClassAndAbstractStructorsWithInit (className, superClassName, )
688
689 // Dynamic vtable patchup support routines and types
690 void reservedCalled(int ind) const;
691
692 #define OSMetaClassDeclareReservedUnused(classname, index) \
693 private: \
694 APPLE_KEXT_PAD_METHOD void _RESERVED ## classname ## index ()
695
696 #define OSMetaClassDeclareReservedUsed(classname, index)
697
698 #define OSMetaClassDefineReservedUnused(classname, index) \
699 void classname ::_RESERVED ## classname ## index () \
700 { APPLE_KEXT_PAD_IMPL(index); }
701
702 #define OSMetaClassDefineReservedUsed(classname, index)
703
704 // IOKit debug internal routines.
705 static void printInstanceCounts();
706 static void serializeClassDictionary(OSDictionary *dict);
707
708 private:
709 // Obsolete APIs
710 static OSDictionary *getClassDictionary();
711 virtual bool serialize(OSSerialize *s) const;
712
713 // Virtual Padding functions for MetaClass's
714 OSMetaClassDeclareReservedUnused(OSMetaClass, 0);
715 OSMetaClassDeclareReservedUnused(OSMetaClass, 1);
716 OSMetaClassDeclareReservedUnused(OSMetaClass, 2);
717 OSMetaClassDeclareReservedUnused(OSMetaClass, 3);
718 OSMetaClassDeclareReservedUnused(OSMetaClass, 4);
719 OSMetaClassDeclareReservedUnused(OSMetaClass, 5);
720 OSMetaClassDeclareReservedUnused(OSMetaClass, 6);
721 OSMetaClassDeclareReservedUnused(OSMetaClass, 7);
722 };
723
724 #endif /* !_LIBKERN_OSMETACLASS_H */