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