]> git.saurik.com Git - apple/xnu.git/blame - libkern/c++/OSMetaClass.cpp
xnu-4570.1.46.tar.gz
[apple/xnu.git] / libkern / c++ / OSMetaClass.cpp
CommitLineData
1c79356b 1/*
39037602 2 * Copyright (c) 2000-2016 Apple Inc. All rights reserved.
1c79356b 3 *
2d21ac55 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
1c79356b 5 *
2d21ac55
A
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.
8f6c56a5 14 *
2d21ac55
A
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
8f6c56a5
A
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
2d21ac55
A
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.
8f6c56a5 25 *
2d21ac55 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
1c79356b
A
27 */
28/* OSMetaClass.cpp created by gvdl on Fri 1998-11-17 */
29
30#include <string.h>
1c79356b
A
31
32#include <libkern/OSReturn.h>
33
34#include <libkern/c++/OSMetaClass.h>
1c79356b 35#include <libkern/c++/OSObject.h>
b0d623f7
A
36#include <libkern/c++/OSKext.h>
37
1c79356b
A
38#include <libkern/c++/OSCollectionIterator.h>
39#include <libkern/c++/OSDictionary.h>
40#include <libkern/c++/OSArray.h>
b0d623f7 41#include <libkern/c++/OSSet.h>
1c79356b
A
42#include <libkern/c++/OSSymbol.h>
43#include <libkern/c++/OSNumber.h>
44#include <libkern/c++/OSSerialize.h>
b0d623f7 45
1c79356b
A
46#include <libkern/c++/OSLib.h>
47#include <libkern/OSAtomic.h>
48
b0d623f7 49#include <IOKit/IOLib.h>
0c530ab8 50
3e170ce0
A
51#include <IOKit/IOKitDebug.h>
52
53
1c79356b
A
54__BEGIN_DECLS
55
91447636 56#include <sys/systm.h>
1c79356b 57#include <mach/mach_types.h>
b0d623f7 58#include <kern/locks.h>
1c79356b
A
59#include <kern/clock.h>
60#include <kern/thread_call.h>
9bccf70c 61#include <kern/host.h>
1c79356b
A
62#include <mach/mach_interface.h>
63
b0d623f7
A
64#if PRAGMA_MARK
65#pragma mark Macros
66#endif /* PRAGMA_MARK */
67/*********************************************************************
68* Macros
69*********************************************************************/
1c79356b
A
70__END_DECLS
71
b0d623f7
A
72#if PRAGMA_MARK
73#pragma mark Internal constants & data structs
74#endif /* PRAGMA_MARK */
75/*********************************************************************
76* Internal constants & data structs
77*********************************************************************/
78OSKextLogSpec kOSMetaClassLogSpec =
79 kOSKextLogErrorLevel |
80 kOSKextLogLoadFlag |
81 kOSKextLogKextBookkeepingFlag;
82
1c79356b
A
83static enum {
84 kCompletedBootstrap = 0,
b0d623f7 85 kNoDictionaries = 1,
1c79356b
A
86 kMakingDictionaries = 2
87} sBootstrapState = kNoDictionaries;
88
b0d623f7
A
89static const int kClassCapacityIncrement = 40;
90static const int kKModCapacityIncrement = 10;
91static OSDictionary * sAllClassesDict;
316670eb 92static unsigned int sDeepestClass;
b0d623f7 93IOLock * sAllClassesLock = NULL;
316670eb 94IOLock * sInstancesLock = NULL;
1c79356b 95
b0d623f7
A
96/*
97 * While loading a kext and running all its constructors to register
98 * all OSMetaClass classes, the classes are queued up here. Only one
99 * kext can be in flight at a time, guarded by sStalledClassesLock
100 */
1c79356b 101static struct StalledData {
b0d623f7
A
102 const char * kextIdentifier;
103 OSReturn result;
104 unsigned int capacity;
105 unsigned int count;
106 OSMetaClass ** classes;
107} * sStalled;
108IOLock * sStalledClassesLock = NULL;
109
316670eb 110struct ExpansionData {
3e170ce0
A
111 OSOrderedSet * instances;
112 OSKext * kext;
5ba3f43e 113 uint32_t retain;
3e170ce0
A
114#if IOTRACKING
115 IOTrackingQueue * tracking;
116#endif
316670eb
A
117};
118
119
b0d623f7
A
120#if PRAGMA_MARK
121#pragma mark OSMetaClassBase
122#endif /* PRAGMA_MARK */
123/*********************************************************************
124* OSMetaClassBase.
125*********************************************************************/
126
316670eb 127#if APPLE_KEXT_VTABLE_PADDING
b0d623f7
A
128/*********************************************************************
129* Reserved vtable functions.
130*********************************************************************/
9bccf70c 131#if SLOT_USED
1c79356b 132void OSMetaClassBase::_RESERVEDOSMetaClassBase0()
b0d623f7 133 { panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 0); }
1c79356b 134void OSMetaClassBase::_RESERVEDOSMetaClassBase1()
b0d623f7 135 { panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 1); }
1c79356b 136void OSMetaClassBase::_RESERVEDOSMetaClassBase2()
b0d623f7 137 { panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 2); }
9bccf70c
A
138#endif /* SLOT_USED */
139
140// As these slots are used move them up inside the #if above
1c79356b 141void OSMetaClassBase::_RESERVEDOSMetaClassBase3()
b0d623f7 142 { panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 3); }
1c79356b 143void OSMetaClassBase::_RESERVEDOSMetaClassBase4()
b0d623f7 144 { panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 4); }
1c79356b 145void OSMetaClassBase::_RESERVEDOSMetaClassBase5()
b0d623f7 146 { panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 5); }
1c79356b 147void OSMetaClassBase::_RESERVEDOSMetaClassBase6()
b0d623f7 148 { panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 6); }
316670eb
A
149#endif
150
b0d623f7
A
151/*********************************************************************
152* These used to be inline in the header but gcc didn't believe us
153* Now we MUST pull the inline out at least until the compiler is
154* repaired.
155*
156* Helper inlines for runtime type preprocessor macros
157*********************************************************************/
158
159/*********************************************************************
160*********************************************************************/
161OSMetaClassBase *
162OSMetaClassBase::safeMetaCast(
163 const OSMetaClassBase * me,
164 const OSMetaClass * toType)
165{
166 return (me)? me->metaCast(toType) : 0;
167}
9bccf70c 168
b0d623f7
A
169/*********************************************************************
170*********************************************************************/
171bool
172OSMetaClassBase::checkTypeInst(
173 const OSMetaClassBase * inst,
174 const OSMetaClassBase * typeinst)
9bccf70c 175{
b0d623f7 176 const OSMetaClass * toType = OSTypeIDInst(typeinst);
9bccf70c
A
177 return typeinst && inst && (0 != inst->metaCast(toType));
178}
179
b0d623f7
A
180/*********************************************************************
181*********************************************************************/
182void OSMetaClassBase::
183initialize()
184{
185 sAllClassesLock = IOLockAlloc();
186 sStalledClassesLock = IOLockAlloc();
316670eb 187 sInstancesLock = IOLockAlloc();
b0d623f7 188}
9bccf70c 189
316670eb 190#if APPLE_KEXT_VTABLE_PADDING
b0d623f7
A
191/*********************************************************************
192* If you need this slot you had better setup an IOCTL style interface.
193* 'Cause the whole kernel world depends on OSMetaClassBase and YOU
194* CANT change the VTABLE size ever.
195*********************************************************************/
196void
197OSMetaClassBase::_RESERVEDOSMetaClassBase7()
198{ panic("OSMetaClassBase::_RESERVEDOSMetaClassBase%d called.", 7); }
316670eb 199#endif
b0d623f7
A
200
201/*********************************************************************
202*********************************************************************/
1c79356b
A
203OSMetaClassBase::OSMetaClassBase()
204{
205}
206
b0d623f7
A
207/*********************************************************************
208*********************************************************************/
1c79356b
A
209OSMetaClassBase::~OSMetaClassBase()
210{
b0d623f7 211 void ** thisVTable;
1c79356b
A
212
213 thisVTable = (void **) this;
214 *thisVTable = (void *) -1UL;
215}
216
b0d623f7
A
217/*********************************************************************
218*********************************************************************/
219bool
220OSMetaClassBase::isEqualTo(const OSMetaClassBase * anObj) const
1c79356b
A
221{
222 return this == anObj;
223}
224
b0d623f7
A
225/*********************************************************************
226*********************************************************************/
227OSMetaClassBase *
228OSMetaClassBase::metaCast(const OSMetaClass * toMeta) const
1c79356b
A
229{
230 return toMeta->checkMetaCast(this);
231}
232
b0d623f7
A
233/*********************************************************************
234*********************************************************************/
235OSMetaClassBase *
236OSMetaClassBase::metaCast(const OSSymbol * toMetaSymb) const
1c79356b
A
237{
238 return OSMetaClass::checkMetaCastWithName(toMetaSymb, this);
239}
240
b0d623f7
A
241/*********************************************************************
242*********************************************************************/
243OSMetaClassBase *
244OSMetaClassBase::metaCast(const OSString * toMetaStr) const
1c79356b 245{
b0d623f7
A
246 const OSSymbol * tempSymb = OSSymbol::withString(toMetaStr);
247 OSMetaClassBase * ret = 0;
1c79356b
A
248 if (tempSymb) {
249 ret = metaCast(tempSymb);
250 tempSymb->release();
251 }
252 return ret;
253}
254
b0d623f7
A
255/*********************************************************************
256*********************************************************************/
257OSMetaClassBase *
258OSMetaClassBase::metaCast(const char * toMetaCStr) const
1c79356b 259{
b0d623f7
A
260 const OSSymbol * tempSymb = OSSymbol::withCString(toMetaCStr);
261 OSMetaClassBase * ret = 0;
1c79356b
A
262 if (tempSymb) {
263 ret = metaCast(tempSymb);
264 tempSymb->release();
265 }
266 return ret;
267}
268
b0d623f7
A
269#if PRAGMA_MARK
270#pragma mark OSMetaClassMeta
271#endif /* PRAGMA_MARK */
272/*********************************************************************
273* OSMetaClassMeta - the bootstrap metaclass of OSMetaClass
274*********************************************************************/
1c79356b
A
275class OSMetaClassMeta : public OSMetaClass
276{
277public:
278 OSMetaClassMeta();
b0d623f7 279 OSObject * alloc() const;
1c79356b
A
280};
281OSMetaClassMeta::OSMetaClassMeta()
282 : OSMetaClass("OSMetaClass", 0, sizeof(OSMetaClass))
283 { }
b0d623f7 284OSObject * OSMetaClassMeta::alloc() const { return 0; }
1c79356b
A
285
286static OSMetaClassMeta sOSMetaClassMeta;
287
288const OSMetaClass * const OSMetaClass::metaClass = &sOSMetaClassMeta;
289const OSMetaClass * OSMetaClass::getMetaClass() const
290 { return &sOSMetaClassMeta; }
291
b0d623f7
A
292#if PRAGMA_MARK
293#pragma mark OSMetaClass
294#endif /* PRAGMA_MARK */
295/*********************************************************************
296* OSMetaClass
297*********************************************************************/
1c79356b 298
316670eb 299#if APPLE_KEXT_VTABLE_PADDING
b0d623f7
A
300/*********************************************************************
301* Reserved functions.
302*********************************************************************/
1c79356b 303void OSMetaClass::_RESERVEDOSMetaClass0()
b0d623f7 304 { panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 0); }
1c79356b 305void OSMetaClass::_RESERVEDOSMetaClass1()
b0d623f7 306 { panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 1); }
1c79356b 307void OSMetaClass::_RESERVEDOSMetaClass2()
b0d623f7 308 { panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 2); }
1c79356b 309void OSMetaClass::_RESERVEDOSMetaClass3()
b0d623f7 310 { panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 3); }
1c79356b 311void OSMetaClass::_RESERVEDOSMetaClass4()
b0d623f7 312 { panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 4); }
1c79356b 313void OSMetaClass::_RESERVEDOSMetaClass5()
b0d623f7 314 { panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 5); }
1c79356b 315void OSMetaClass::_RESERVEDOSMetaClass6()
b0d623f7 316 { panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 6); }
1c79356b 317void OSMetaClass::_RESERVEDOSMetaClass7()
b0d623f7 318 { panic("OSMetaClass::_RESERVEDOSMetaClass%d called", 7); }
316670eb 319#endif
b0d623f7
A
320
321/*********************************************************************
322*********************************************************************/
323static void
324OSMetaClassLogErrorForKext(
325 OSReturn error,
326 OSKext * aKext)
1c79356b 327{
b0d623f7 328 const char * message = NULL;
1c79356b 329
b0d623f7
A
330 switch (error) {
331 case kOSReturnSuccess:
332 return;
333 case kOSMetaClassNoInit: // xxx - never returned; logged at fail site
334 message = "OSMetaClass: preModLoad() wasn't called (runtime internal error).";
335 break;
1c79356b 336 case kOSMetaClassNoDicts:
b0d623f7
A
337 message = "OSMetaClass: Allocation failure for OSMetaClass internal dictionaries.";
338 break;
1c79356b 339 case kOSMetaClassNoKModSet:
b0d623f7
A
340 message = "OSMetaClass: Allocation failure for internal kext recording set/set missing.";
341 break;
1c79356b 342 case kOSMetaClassNoInsKModSet:
b0d623f7
A
343 message = "OSMetaClass: Failed to record class in kext.";
344 break;
1c79356b 345 case kOSMetaClassDuplicateClass:
b0d623f7
A
346 message = "OSMetaClass: Duplicate class encountered.";
347 break;
348 case kOSMetaClassNoSuper: // xxx - never returned
349 message = "OSMetaClass: Can't associate a class with its superclass.";
350 break;
351 case kOSMetaClassInstNoSuper: // xxx - never returned
352 message = "OSMetaClass: Instance construction error; unknown superclass.";
353 break;
354 case kOSMetaClassNoKext:
355 message = "OSMetaClass: Kext not found for metaclass.";
356 break;
1c79356b 357 case kOSMetaClassInternal:
b0d623f7
A
358 default:
359 message = "OSMetaClass: Runtime internal error.";
360 break;
361 }
362
363 if (message) {
364 OSKextLog(aKext, kOSMetaClassLogSpec, "%s", message);
1c79356b 365 }
b0d623f7 366 return;
1c79356b
A
367}
368
b0d623f7
A
369void
370OSMetaClass::logError(OSReturn error)
371{
372 OSMetaClassLogErrorForKext(error, NULL);
373}
374
375/*********************************************************************
376* The core constructor for a MetaClass (defined with this name always
377* but within the scope of its represented class).
378*
379* MetaClass constructors are invoked in OSRuntimeInitializeCPP(),
380* in between calls to OSMetaClass::preModLoad(), which sets up for
381* registration, and OSMetaClass::postModLoad(), which actually
382* records all the class/kext relationships of the new MetaClasses.
383*********************************************************************/
384OSMetaClass::OSMetaClass(
385 const char * inClassName,
386 const OSMetaClass * inSuperClass,
387 unsigned int inClassSize)
1c79356b
A
388{
389 instanceCount = 0;
390 classSize = inClassSize;
391 superClassLink = inSuperClass;
392
316670eb
A
393 reserved = IONew(ExpansionData, 1);
394 bzero(reserved, sizeof(ExpansionData));
3e170ce0 395#if IOTRACKING
39037602
A
396 uint32_t numSiteQs = 0;
397 if ((this == &OSSymbol ::gMetaClass)
398 || (this == &OSString ::gMetaClass)
399 || (this == &OSNumber ::gMetaClass)
400 || (this == &OSString ::gMetaClass)
401 || (this == &OSData ::gMetaClass)
402 || (this == &OSDictionary::gMetaClass)
403 || (this == &OSArray ::gMetaClass)
404 || (this == &OSSet ::gMetaClass)) numSiteQs = 27;
405
406 reserved->tracking = IOTrackingQueueAlloc(inClassName, (uintptr_t) this,
407 inClassSize, 0, kIOTrackingQueueTypeAlloc,
408 numSiteQs);
3e170ce0 409#endif
316670eb 410
b0d623f7
A
411 /* Hack alert: We are just casting inClassName and storing it in
412 * an OSString * instance variable. This may be because you can't
413 * create C++ objects in static constructors, but I really don't know!
414 */
415 className = (const OSSymbol *)inClassName;
1c79356b 416
b0d623f7 417 // sStalledClassesLock taken in preModLoad
1c79356b 418 if (!sStalled) {
b0d623f7
A
419 /* There's no way we can look up the kext here, unfortunately.
420 */
421 OSKextLog(/* kext */ NULL, kOSMetaClassLogSpec,
422 "OSMetaClass: preModLoad() wasn't called for class %s "
423 "(runtime internal error).",
424 inClassName);
1c79356b 425 } else if (!sStalled->result) {
b0d623f7
A
426 // Grow stalled array if neccessary
427 if (sStalled->count >= sStalled->capacity) {
428 OSMetaClass **oldStalled = sStalled->classes;
429 int oldSize = sStalled->capacity * sizeof(OSMetaClass *);
430 int newSize = oldSize
431 + kKModCapacityIncrement * sizeof(OSMetaClass *);
432
3e170ce0 433 sStalled->classes = (OSMetaClass **)kalloc_tag(newSize, VM_KERN_MEMORY_OSKEXT);
b0d623f7
A
434 if (!sStalled->classes) {
435 sStalled->classes = oldStalled;
436 sStalled->result = kOSMetaClassNoTempData;
437 return;
438 }
439
440 sStalled->capacity += kKModCapacityIncrement;
441 memmove(sStalled->classes, oldStalled, oldSize);
442 kfree(oldStalled, oldSize);
3e170ce0 443 OSMETA_ACCUMSIZE(((size_t)newSize) - ((size_t)oldSize));
b0d623f7
A
444 }
445
446 sStalled->classes[sStalled->count++] = this;
1c79356b
A
447 }
448}
449
b0d623f7
A
450/*********************************************************************
451*********************************************************************/
1c79356b
A
452OSMetaClass::~OSMetaClass()
453{
316670eb 454 OSKext * myKext = reserved ? reserved->kext : 0; // do not release
b0d623f7
A
455
456 /* Hack alert: 'className' is a C string during early C++ init, and
457 * is converted to a real OSSymbol only when we record the OSKext in
458 * OSMetaClass::postModLoad(). So only do this bit if we have an OSKext.
459 * We can't safely cast or check 'className'.
460 *
461 * Also, release className *after* calling into the kext,
462 * as removeClass() may access className.
463 */
464 IOLockLock(sAllClassesLock);
465 if (sAllClassesDict) {
466 if (myKext) {
467 sAllClassesDict->removeObject(className);
468 } else {
469 sAllClassesDict->removeObject((char *)className);
470 }
471 }
472 IOLockUnlock(sAllClassesLock);
473
474 if (myKext) {
475 if (myKext->removeClass(this) != kOSReturnSuccess) {
476 // xxx - what can we do?
477 }
478 className->release();
479 }
1c79356b 480
b0d623f7 481 // sStalledClassesLock taken in preModLoad
1c79356b 482 if (sStalled) {
b0d623f7
A
483 unsigned int i;
484
485 /* First pass find class in stalled list. If we find it that means
486 * we started C++ init with constructors but now we're tearing down
487 * because of some failure.
488 */
489 for (i = 0; i < sStalled->count; i++) {
490 if (this == sStalled->classes[i]) {
491 break;
492 }
493 }
494
495 /* Remove this metaclass from the stalled list so postModLoad() doesn't
496 * try to register it.
497 */
498 if (i < sStalled->count) {
499 sStalled->count--;
500 if (i < sStalled->count) {
501 memmove(&sStalled->classes[i], &sStalled->classes[i+1],
502 (sStalled->count - i) * sizeof(OSMetaClass *));
503 }
504 }
1c79356b 505 }
3e170ce0
A
506#if IOTRACKING
507 IOTrackingQueueFree(reserved->tracking);
508#endif
509 IODelete(reserved, ExpansionData, 1);
1c79356b
A
510}
511
b0d623f7
A
512/*********************************************************************
513* Empty overrides.
514*********************************************************************/
1c79356b
A
515void OSMetaClass::retain() const { }
516void OSMetaClass::release() const { }
2d21ac55 517void OSMetaClass::release(__unused int when) const { }
b0d623f7
A
518void OSMetaClass::taggedRetain(__unused const void * tag) const { }
519void OSMetaClass::taggedRelease(__unused const void * tag) const { }
520void OSMetaClass::taggedRelease(__unused const void * tag, __unused const int when) const { }
1c79356b
A
521int OSMetaClass::getRetainCount() const { return 0; }
522
b0d623f7
A
523/*********************************************************************
524*********************************************************************/
525const char *
526OSMetaClass::getClassName() const
1c79356b 527{
6d2010ae 528 if (!className) return NULL;
1c79356b
A
529 return className->getCStringNoCopy();
530}
316670eb
A
531/*********************************************************************
532*********************************************************************/
533const OSSymbol *
534OSMetaClass::getClassNameSymbol() const
535{
536 return className;
537}
b0d623f7
A
538/*********************************************************************
539*********************************************************************/
540unsigned int
541OSMetaClass::getClassSize() const
1c79356b
A
542{
543 return classSize;
544}
545
b0d623f7
A
546/*********************************************************************
547*********************************************************************/
548void *
549OSMetaClass::preModLoad(const char * kextIdentifier)
1c79356b 550{
b0d623f7 551 IOLockLock(sStalledClassesLock);
1c79356b 552
b0d623f7 553 assert (sStalled == NULL);
3e170ce0 554 sStalled = (StalledData *)kalloc_tag(sizeof(* sStalled), VM_KERN_MEMORY_OSKEXT);
1c79356b 555 if (sStalled) {
b0d623f7 556 sStalled->classes = (OSMetaClass **)
3e170ce0 557 kalloc_tag(kKModCapacityIncrement * sizeof(OSMetaClass *), VM_KERN_MEMORY_OSKEXT);
b0d623f7
A
558 if (!sStalled->classes) {
559 kfree(sStalled, sizeof(*sStalled));
560 return 0;
561 }
3e170ce0 562 OSMETA_ACCUMSIZE((kKModCapacityIncrement * sizeof(OSMetaClass *)) +
b0d623f7 563 sizeof(*sStalled));
1c79356b
A
564
565 sStalled->result = kOSReturnSuccess;
b0d623f7
A
566 sStalled->capacity = kKModCapacityIncrement;
567 sStalled->count = 0;
568 sStalled->kextIdentifier = kextIdentifier;
569 bzero(sStalled->classes, kKModCapacityIncrement * sizeof(OSMetaClass *));
1c79356b
A
570 }
571
b0d623f7
A
572 // keep sStalledClassesLock locked until postModLoad
573
1c79356b
A
574 return sStalled;
575}
576
b0d623f7
A
577/*********************************************************************
578*********************************************************************/
579bool
580OSMetaClass::checkModLoad(void * loadHandle)
1c79356b 581{
b0d623f7
A
582 return sStalled && loadHandle == sStalled &&
583 sStalled->result == kOSReturnSuccess;
1c79356b
A
584}
585
b0d623f7
A
586/*********************************************************************
587*********************************************************************/
588OSReturn
589OSMetaClass::postModLoad(void * loadHandle)
1c79356b 590{
b0d623f7
A
591 OSReturn result = kOSReturnSuccess;
592 OSSymbol * myKextName = 0; // must release
593 OSKext * myKext = 0; // must release
1c79356b
A
594
595 if (!sStalled || loadHandle != sStalled) {
b0d623f7
A
596 result = kOSMetaClassInternal;
597 goto finish;
1c79356b 598 }
b0d623f7
A
599
600 if (sStalled->result) {
601 result = sStalled->result;
602 } else switch (sBootstrapState) {
603
604 case kNoDictionaries:
605 sBootstrapState = kMakingDictionaries;
606 // No break; fall through
39037602 607 [[clang::fallthrough]];
b0d623f7
A
608
609 case kMakingDictionaries:
610 sAllClassesDict = OSDictionary::withCapacity(kClassCapacityIncrement);
611 if (!sAllClassesDict) {
612 result = kOSMetaClassNoDicts;
613 break;
614 }
316670eb 615 sAllClassesDict->setOptions(OSCollection::kSort, OSCollection::kSort);
1c79356b 616
39037602
A
617 // No break; fall through
618 [[clang::fallthrough]];
1c79356b 619
b0d623f7
A
620 case kCompletedBootstrap:
621 {
622 unsigned int i;
623 myKextName = const_cast<OSSymbol *>(OSSymbol::withCStringNoCopy(
624 sStalled->kextIdentifier));
625
626 if (!sStalled->count) {
627 break; // Nothing to do so just get out
628 }
629
630 myKext = OSKext::lookupKextWithIdentifier(myKextName);
631 if (!myKext) {
632 result = kOSMetaClassNoKext;
633
634 /* Log this error here so we can include the kext name.
635 */
636 OSKextLog(/* kext */ NULL, kOSMetaClassLogSpec,
637 "OSMetaClass: Can't record classes for kext %s - kext not found.",
638 sStalled->kextIdentifier);
639 break;
640 }
641
642 /* First pass checking classes aren't already loaded. If any already
643 * exist, we don't register any, and so we don't technically have
644 * to do any C++ teardown.
645 *
646 * Hack alert: me->className has been a C string until now.
647 * We only release the OSSymbol if we store the kext.
648 */
649 IOLockLock(sAllClassesLock);
650 for (i = 0; i < sStalled->count; i++) {
316670eb 651 const OSMetaClass * me = sStalled->classes[i];
b0d623f7
A
652 OSMetaClass * orig = OSDynamicCast(OSMetaClass,
653 sAllClassesDict->getObject((const char *)me->className));
654
655 if (orig) {
656
657 /* Log this error here so we can include the class name.
658 * xxx - we should look up the other kext that defines the class
659 */
5ba3f43e
A
660#if CONFIG_EMBEDDED
661 panic(
662#else
b0d623f7 663 OSKextLog(myKext, kOSMetaClassLogSpec,
5ba3f43e 664#endif /* CONFIG_EMBEDDED */
b0d623f7
A
665 "OSMetaClass: Kext %s class %s is a duplicate;"
666 "kext %s already has a class by that name.",
667 sStalled->kextIdentifier, (const char *)me->className,
316670eb 668 ((OSKext *)orig->reserved->kext)->getIdentifierCString());
b0d623f7
A
669 result = kOSMetaClassDuplicateClass;
670 break;
671 }
316670eb
A
672 unsigned int depth = 1;
673 while ((me = me->superClassLink)) depth++;
674 if (depth > sDeepestClass) sDeepestClass = depth;
b0d623f7
A
675 }
676 IOLockUnlock(sAllClassesLock);
677
678 /* Bail if we didn't go through the entire list of new classes
679 * (if we hit a duplicate).
680 */
681 if (i != sStalled->count) {
1c79356b
A
682 break;
683 }
1c79356b 684
b0d623f7
A
685 // Second pass symbolling strings and inserting classes in dictionary
686 IOLockLock(sAllClassesLock);
687 for (i = 0; i < sStalled->count; i++) {
688 OSMetaClass * me = sStalled->classes[i];
689
690 /* Hack alert: me->className has been a C string until now.
691 * We only release the OSSymbol in ~OSMetaClass()
692 * if we set the reference to the kext.
693 */
694 me->className =
695 OSSymbol::withCStringNoCopy((const char *)me->className);
696
697 // xxx - I suppose if these fail we're going to panic soon....
698 sAllClassesDict->setObject(me->className, me);
699
700 /* Do not retain the kext object here.
701 */
316670eb 702 me->reserved->kext = myKext;
b0d623f7
A
703 if (myKext) {
704 result = myKext->addClass(me, sStalled->count);
705 if (result != kOSReturnSuccess) {
706 /* OSKext::addClass() logs with kOSMetaClassNoInsKModSet. */
707 break;
708 }
709 }
710 }
711 IOLockUnlock(sAllClassesLock);
712 sBootstrapState = kCompletedBootstrap;
713 break;
714 }
715
716 default:
717 result = kOSMetaClassInternal;
718 break;
1c79356b 719 }
b0d623f7
A
720
721finish:
722 /* Don't call logError() for success or the conditions logged above
723 * or by called function.
724 */
725 if (result != kOSReturnSuccess &&
726 result != kOSMetaClassNoInsKModSet &&
727 result != kOSMetaClassDuplicateClass &&
728 result != kOSMetaClassNoKext) {
1c79356b 729
b0d623f7
A
730 OSMetaClassLogErrorForKext(result, myKext);
731 }
1c79356b 732
39037602
A
733 OSSafeReleaseNULL(myKextName);
734 OSSafeReleaseNULL(myKext);
91447636 735
1c79356b 736 if (sStalled) {
3e170ce0 737 OSMETA_ACCUMSIZE(-(sStalled->capacity * sizeof(OSMetaClass *) +
b0d623f7
A
738 sizeof(*sStalled)));
739 kfree(sStalled->classes, sStalled->capacity * sizeof(OSMetaClass *));
740 kfree(sStalled, sizeof(*sStalled));
741 sStalled = 0;
1c79356b 742 }
b0d623f7
A
743
744 IOLockUnlock(sStalledClassesLock);
1c79356b 745
1c79356b
A
746 return result;
747}
748
749
b0d623f7
A
750/*********************************************************************
751*********************************************************************/
752void
753OSMetaClass::instanceConstructed() const
1c79356b 754{
b0d623f7
A
755 // if ((0 == OSIncrementAtomic(&(((OSMetaClass *) this)->instanceCount))) && superClassLink)
756 if ((0 == OSIncrementAtomic(&instanceCount)) && superClassLink) {
757 superClassLink->instanceConstructed();
1c79356b 758 }
1c79356b
A
759}
760
b0d623f7
A
761/*********************************************************************
762*********************************************************************/
763void
764OSMetaClass::instanceDestructed() const
1c79356b 765{
b0d623f7
A
766 if ((1 == OSDecrementAtomic(&instanceCount)) && superClassLink) {
767 superClassLink->instanceDestructed();
768 }
0c530ab8 769
b0d623f7 770 if (((int)instanceCount) < 0) {
316670eb 771 OSKext * myKext = reserved->kext;
0c530ab8 772
b0d623f7
A
773 OSKextLog(myKext, kOSMetaClassLogSpec,
774 // xxx - this phrasing is rather cryptic
775 "OSMetaClass: Class %s - bad retain (%d)",
776 getClassName(), instanceCount);
0c530ab8 777 }
0c530ab8
A
778}
779
b0d623f7
A
780/*********************************************************************
781*********************************************************************/
782bool
783OSMetaClass::modHasInstance(const char * kextIdentifier)
1c79356b 784{
b0d623f7
A
785 bool result = false;
786 OSKext * theKext = NULL; // must release
787
788 theKext = OSKext::lookupKextWithIdentifier(kextIdentifier);
789 if (!theKext) {
790 goto finish;
0c530ab8 791 }
1c79356b 792
b0d623f7 793 result = theKext->hasOSMetaClassInstances();
1c79356b 794
b0d623f7 795finish:
39037602 796 OSSafeReleaseNULL(theKext);
b0d623f7 797 return result;
1c79356b
A
798}
799
b0d623f7
A
800/*********************************************************************
801*********************************************************************/
802void
803OSMetaClass::reportModInstances(const char * kextIdentifier)
1c79356b 804{
b0d623f7
A
805 OSKext::reportOSMetaClassInstances(kextIdentifier,
806 kOSKextLogExplicitLevel);
807 return;
1c79356b 808}
316670eb
A
809/*********************************************************************
810*********************************************************************/
811
812void
813OSMetaClass::addInstance(const OSObject * instance, bool super) const
814{
815 if (!super) IOLockLock(sInstancesLock);
816
817 if (!reserved->instances) {
818 reserved->instances = OSOrderedSet::withCapacity(16);
819 if (superClassLink) {
820 superClassLink->addInstance(reserved->instances, true);
821 }
822 }
823 reserved->instances->setLastObject(instance);
824
825 if (!super) IOLockUnlock(sInstancesLock);
826}
827
828void
829OSMetaClass::removeInstance(const OSObject * instance, bool super) const
830{
831 if (!super) IOLockLock(sInstancesLock);
832
833 if (reserved->instances) {
834 reserved->instances->removeObject(instance);
835 if (0 == reserved->instances->getCount()) {
836 if (superClassLink) {
837 superClassLink->removeInstance(reserved->instances, true);
838 }
bd504ef0 839 IOLockLock(sAllClassesLock);
316670eb
A
840 reserved->instances->release();
841 reserved->instances = 0;
bd504ef0 842 IOLockUnlock(sAllClassesLock);
316670eb
A
843 }
844 }
845
846 if (!super) IOLockUnlock(sInstancesLock);
847}
848
849void
850OSMetaClass::applyToInstances(OSOrderedSet * set,
851 OSMetaClassInstanceApplierFunction applier,
852 void * context)
853{
854 enum { kLocalDepth = 24 };
855 unsigned int _nextIndex[kLocalDepth];
856 OSOrderedSet * _sets[kLocalDepth];
857 unsigned int * nextIndex = &_nextIndex[0];
858 OSOrderedSet ** sets = &_sets[0];
859 OSObject * obj;
860 OSOrderedSet * childSet;
861 unsigned int maxDepth;
862 unsigned int idx;
863 unsigned int level;
864 bool done;
865
866 maxDepth = sDeepestClass;
867 if (maxDepth > kLocalDepth)
868 {
869 nextIndex = IONew(typeof(nextIndex[0]), maxDepth);
870 sets = IONew(typeof(sets[0]), maxDepth);
871 }
872 done = false;
873 level = 0;
874 idx = 0;
875 do
876 {
877 while (!done && (obj = set->getObject(idx++)))
878 {
879 if ((childSet = OSDynamicCast(OSOrderedSet, obj)))
880 {
881 if (level >= maxDepth) panic(">maxDepth");
882 sets[level] = set;
883 nextIndex[level] = idx;
884 level++;
885 set = childSet;
886 idx = 0;
887 break;
888 }
889 done = (*applier)(obj, context);
890 }
891 if (!obj)
892 {
893 if (!done && level)
894 {
895 level--;
896 set = sets[level];
897 idx = nextIndex[level];
898 } else done = true;
899 }
900 }
901 while (!done);
902 if (maxDepth > kLocalDepth)
903 {
904 IODelete(nextIndex, typeof(nextIndex[0]), maxDepth);
905 IODelete(sets, typeof(sets[0]), maxDepth);
906 }
907}
908
909void
910OSMetaClass::applyToInstances(OSMetaClassInstanceApplierFunction applier,
911 void * context) const
912{
913 IOLockLock(sInstancesLock);
914 if (reserved->instances) applyToInstances(reserved->instances, applier, context);
915 IOLockUnlock(sInstancesLock);
916}
917
918void
919OSMetaClass::applyToInstancesOfClassName(
920 const OSSymbol * name,
921 OSMetaClassInstanceApplierFunction applier,
922 void * context)
923{
924 OSMetaClass * meta;
925 OSOrderedSet * set = 0;
926
927 IOLockLock(sAllClassesLock);
928 if (sAllClassesDict
929 && (meta = (OSMetaClass *) sAllClassesDict->getObject(name))
930 && (set = meta->reserved->instances))
931 {
932 set->retain();
933 }
934 IOLockUnlock(sAllClassesLock);
935
936 if (!set) return;
937
938 IOLockLock(sInstancesLock);
939 applyToInstances(set, applier, context);
940 IOLockUnlock(sInstancesLock);
941 set->release();
942}
1c79356b 943
b0d623f7
A
944/*********************************************************************
945*********************************************************************/
946void
947OSMetaClass::considerUnloads()
1c79356b 948{
b0d623f7
A
949 OSKext::considerUnloads();
950}
1c79356b 951
5ba3f43e
A
952/*********************************************************************
953*********************************************************************/
954bool
955OSMetaClass::removeClasses(OSCollection * metaClasses)
956{
957 OSCollectionIterator * classIterator;
958 OSMetaClass * checkClass;
959 bool result;
960
961 classIterator = OSCollectionIterator::withCollection(metaClasses);
962 if (!classIterator) return (false);
963
964 IOLockLock(sAllClassesLock);
965
966 result = false;
967 do
968 {
969 while ((checkClass = (OSMetaClass *)classIterator->getNextObject())
970 && !checkClass->getInstanceCount()
971 && !checkClass->reserved->retain) {}
972 if (checkClass) break;
973 classIterator->reset();
974 while ((checkClass = (OSMetaClass *)classIterator->getNextObject()))
975 {
976 sAllClassesDict->removeObject(checkClass->className);
977 }
978 result = true;
979 }
980 while (false);
981
982 IOLockUnlock(sAllClassesLock);
983 OSSafeReleaseNULL(classIterator);
984
985 return (result);
986}
987
988
b0d623f7
A
989/*********************************************************************
990*********************************************************************/
991const OSMetaClass *
992OSMetaClass::getMetaClassWithName(const OSSymbol * name)
993{
994 OSMetaClass * retMeta = 0;
1c79356b 995
b0d623f7
A
996 if (!name) {
997 return 0;
998 }
1c79356b 999
b0d623f7
A
1000 IOLockLock(sAllClassesLock);
1001 if (sAllClassesDict) {
1002 retMeta = (OSMetaClass *) sAllClassesDict->getObject(name);
1c79356b 1003 }
b0d623f7 1004 IOLockUnlock(sAllClassesLock);
1c79356b
A
1005
1006 return retMeta;
1007}
1008
5ba3f43e
A
1009/*********************************************************************
1010*********************************************************************/
1011const OSMetaClass *
1012OSMetaClass::copyMetaClassWithName(const OSSymbol * name)
1013{
1014 const OSMetaClass * meta;
1015
1016 if (!name) return (0);
1017
1018 meta = 0;
1019 IOLockLock(sAllClassesLock);
1020 if (sAllClassesDict) {
1021 meta = (OSMetaClass *) sAllClassesDict->getObject(name);
1022 if (meta) OSIncrementAtomic(&meta->reserved->retain);
1023 }
1024 IOLockUnlock(sAllClassesLock);
1025
1026 return (meta);
1027}
1028
1029/*********************************************************************
1030*********************************************************************/
1031void
1032OSMetaClass::releaseMetaClass() const
1033{
1034 OSDecrementAtomic(&reserved->retain);
1035}
1036
b0d623f7
A
1037/*********************************************************************
1038*********************************************************************/
1039OSObject *
1040OSMetaClass::allocClassWithName(const OSSymbol * name)
1c79356b 1041{
5ba3f43e
A
1042 const OSMetaClass * meta;
1043 OSObject * result;
1c79356b 1044
5ba3f43e
A
1045 result = 0;
1046 meta = copyMetaClassWithName(name);
1047 if (meta)
1048 {
b0d623f7 1049 result = meta->alloc();
5ba3f43e 1050 meta->releaseMetaClass();
b0d623f7 1051 }
1c79356b
A
1052
1053 return result;
1054}
1055
b0d623f7
A
1056/*********************************************************************
1057*********************************************************************/
1058OSObject *
1059OSMetaClass::allocClassWithName(const OSString * name)
1c79356b 1060{
b0d623f7
A
1061 const OSSymbol * tmpKey = OSSymbol::withString(name);
1062 OSObject * result = allocClassWithName(tmpKey);
1c79356b
A
1063 tmpKey->release();
1064 return result;
1065}
1066
b0d623f7
A
1067/*********************************************************************
1068*********************************************************************/
1069OSObject *
1070OSMetaClass::allocClassWithName(const char * name)
1c79356b 1071{
b0d623f7
A
1072 const OSSymbol * tmpKey = OSSymbol::withCStringNoCopy(name);
1073 OSObject * result = allocClassWithName(tmpKey);
1c79356b
A
1074 tmpKey->release();
1075 return result;
1076}
1077
1078
b0d623f7
A
1079/*********************************************************************
1080*********************************************************************/
1081OSMetaClassBase *
1082OSMetaClass::checkMetaCastWithName(
1083 const OSSymbol * name,
1084 const OSMetaClassBase * in)
1c79356b 1085{
b0d623f7
A
1086 OSMetaClassBase * result = 0;
1087
1c79356b
A
1088 const OSMetaClass * const meta = getMetaClassWithName(name);
1089
b0d623f7
A
1090 if (meta) {
1091 result = meta->checkMetaCast(in);
1092 }
1c79356b 1093
1c79356b
A
1094 return result;
1095}
1096
b0d623f7
A
1097/*********************************************************************
1098*********************************************************************/
1099OSMetaClassBase * OSMetaClass::
1100checkMetaCastWithName(
1101 const OSString * name,
1102 const OSMetaClassBase * in)
1c79356b 1103{
b0d623f7
A
1104 const OSSymbol * tmpKey = OSSymbol::withString(name);
1105 OSMetaClassBase * result = checkMetaCastWithName(tmpKey, in);
1106
1c79356b
A
1107 tmpKey->release();
1108 return result;
1109}
1110
b0d623f7
A
1111/*********************************************************************
1112*********************************************************************/
1113OSMetaClassBase *
1114OSMetaClass::checkMetaCastWithName(
1115 const char * name,
1116 const OSMetaClassBase * in)
1c79356b 1117{
b0d623f7
A
1118 const OSSymbol * tmpKey = OSSymbol::withCStringNoCopy(name);
1119 OSMetaClassBase * result = checkMetaCastWithName(tmpKey, in);
1120
1c79356b
A
1121 tmpKey->release();
1122 return result;
1123}
1124
b0d623f7
A
1125/*********************************************************************
1126 * OSMetaClass::checkMetaCast()
1127 * Check to see if the 'check' object has this object in its metaclass chain.
1128 * Returns check if it is indeed a kind of the current meta class, 0 otherwise.
1129 *
1130 * Generally this method is not invoked directly but is used to implement
1131 * the OSMetaClassBase::metaCast member function.
1132 *
1133 * See also OSMetaClassBase::metaCast
1134*********************************************************************/
1135OSMetaClassBase * OSMetaClass::checkMetaCast(
1136 const OSMetaClassBase * check) const
1c79356b 1137{
b0d623f7
A
1138 const OSMetaClass * const toMeta = this;
1139 const OSMetaClass * fromMeta;
1c79356b
A
1140
1141 for (fromMeta = check->getMetaClass(); ; fromMeta = fromMeta->superClassLink) {
b0d623f7
A
1142 if (toMeta == fromMeta) {
1143 return const_cast<OSMetaClassBase *>(check); // Discard const
1144 }
1145 if (!fromMeta->superClassLink) {
1146 break;
1147 }
1c79356b
A
1148 }
1149
1150 return 0;
1151}
1152
b0d623f7
A
1153/*********************************************************************
1154*********************************************************************/
1155void
1156OSMetaClass::reservedCalled(int ind) const
1c79356b 1157{
b0d623f7
A
1158 const char * cname = className->getCStringNoCopy();
1159 panic("%s::_RESERVED%s%d called.", cname, cname, ind);
1c79356b
A
1160}
1161
b0d623f7
A
1162/*********************************************************************
1163*********************************************************************/
1164const
1165OSMetaClass *
1166OSMetaClass::getSuperClass() const
1c79356b
A
1167{
1168 return superClassLink;
1169}
1170
b0d623f7
A
1171/*********************************************************************
1172* xxx - I want to rename this :-/
1173*********************************************************************/
1174const OSSymbol *
1175OSMetaClass::getKmodName() const
1176{
316670eb 1177 OSKext * myKext = reserved ? reserved->kext : 0;
b0d623f7
A
1178 if (myKext) {
1179 return myKext->getIdentifier();
1180 }
1181 return OSSymbol::withCStringNoCopy("unknown");
91447636
A
1182}
1183
b0d623f7
A
1184/*********************************************************************
1185*********************************************************************/
1186unsigned int
1187OSMetaClass::getInstanceCount() const
1c79356b
A
1188{
1189 return instanceCount;
1190}
1191
b0d623f7
A
1192/*********************************************************************
1193*********************************************************************/
1194/* static */
1195void
1196OSMetaClass::printInstanceCounts()
1c79356b 1197{
b0d623f7
A
1198 OSCollectionIterator * classes;
1199 OSSymbol * className;
1200 OSMetaClass * meta;
1c79356b 1201
b0d623f7 1202 IOLockLock(sAllClassesLock);
1c79356b 1203 classes = OSCollectionIterator::withCollection(sAllClassesDict);
b0d623f7 1204 assert(classes);
1c79356b
A
1205
1206 while( (className = (OSSymbol *)classes->getNextObject())) {
b0d623f7
A
1207 meta = (OSMetaClass *)sAllClassesDict->getObject(className);
1208 assert(meta);
1209
1210 printf("%24s count: %03d x 0x%03x = 0x%06x\n",
1211 className->getCStringNoCopy(),
1212 meta->getInstanceCount(),
1213 meta->getClassSize(),
1214 meta->getInstanceCount() * meta->getClassSize() );
1c79356b
A
1215 }
1216 printf("\n");
1217 classes->release();
b0d623f7
A
1218 IOLockUnlock(sAllClassesLock);
1219 return;
1c79356b
A
1220}
1221
b0d623f7
A
1222/*********************************************************************
1223*********************************************************************/
1224OSDictionary *
1225OSMetaClass::getClassDictionary()
1c79356b 1226{
b0d623f7 1227 panic("OSMetaClass::getClassDictionary() is obsoleted.\n");
55e303ae 1228 return 0;
1c79356b
A
1229}
1230
b0d623f7
A
1231/*********************************************************************
1232*********************************************************************/
1233bool
1234OSMetaClass::serialize(__unused OSSerialize * s) const
1c79356b 1235{
55e303ae
A
1236 panic("OSMetaClass::serialize(): Obsoleted\n");
1237 return false;
1238}
1239
b0d623f7
A
1240/*********************************************************************
1241*********************************************************************/
1242/* static */
1243void
1244OSMetaClass::serializeClassDictionary(OSDictionary * serializeDictionary)
55e303ae 1245{
b0d623f7
A
1246 OSDictionary * classDict = NULL;
1247
1248 IOLockLock(sAllClassesLock);
55e303ae
A
1249
1250 classDict = OSDictionary::withCapacity(sAllClassesDict->getCount());
b0d623f7
A
1251 if (!classDict) {
1252 goto finish;
1253 }
1c79356b 1254
55e303ae 1255 do {
b0d623f7
A
1256 OSCollectionIterator * classes;
1257 const OSSymbol * className;
1c79356b 1258
55e303ae 1259 classes = OSCollectionIterator::withCollection(sAllClassesDict);
b0d623f7 1260 if (!classes) {
55e303ae 1261 break;
b0d623f7 1262 }
55e303ae 1263
b0d623f7
A
1264 while ((className = (const OSSymbol *)classes->getNextObject())) {
1265 const OSMetaClass * meta;
1266 OSNumber * count;
55e303ae 1267
b0d623f7 1268 meta = (OSMetaClass *)sAllClassesDict->getObject(className);
55e303ae
A
1269 count = OSNumber::withNumber(meta->getInstanceCount(), 32);
1270 if (count) {
1271 classDict->setObject(className, count);
1272 count->release();
1273 }
1274 }
1275 classes->release();
1c79356b 1276
55e303ae
A
1277 serializeDictionary->setObject("Classes", classDict);
1278 } while (0);
1c79356b 1279
b0d623f7 1280finish:
39037602 1281 OSSafeReleaseNULL(classDict);
b0d623f7
A
1282
1283 IOLockUnlock(sAllClassesLock);
1c79356b 1284
b0d623f7 1285 return;
1c79356b 1286}
3e170ce0
A
1287
1288
1289/*********************************************************************
1290*********************************************************************/
1291
1292#if IOTRACKING
1293
1294void *OSMetaClass::trackedNew(size_t size)
1295{
1296 IOTracking * mem;
1297
1298 mem = (typeof(mem)) kalloc_tag_bt(size + sizeof(IOTracking), VM_KERN_MEMORY_LIBKERN);
1299 assert(mem);
1300 if (!mem) return (mem);
1301
1302 memset(mem, 0, size + sizeof(IOTracking));
1303 mem++;
1304
1305 OSIVAR_ACCUMSIZE(size);
1306
1307 return (mem);
1308}
1309
1310void OSMetaClass::trackedDelete(void * instance, size_t size)
1311{
1312 IOTracking * mem = (typeof(mem)) instance; mem--;
1313
1314 kfree(mem, size + sizeof(IOTracking));
1315 OSIVAR_ACCUMSIZE(-size);
1316}
1317
1318void OSMetaClass::trackedInstance(OSObject * instance) const
1319{
1320 IOTracking * mem = (typeof(mem)) instance; mem--;
1321
5ba3f43e 1322 return (IOTrackingAdd(reserved->tracking, mem, classSize, false, VM_KERN_MEMORY_NONE));
3e170ce0
A
1323}
1324
1325void OSMetaClass::trackedFree(OSObject * instance) const
1326{
1327 IOTracking * mem = (typeof(mem)) instance; mem--;
1328
1329 return (IOTrackingRemove(reserved->tracking, mem, classSize));
1330}
1331
1332void OSMetaClass::trackedAccumSize(OSObject * instance, size_t size) const
1333{
1334 IOTracking * mem = (typeof(mem)) instance; mem--;
1335
1336 return (IOTrackingAccumSize(reserved->tracking, mem, size));
1337}
1338
1339IOTrackingQueue * OSMetaClass::getTracking() const
1340{
1341 return (reserved->tracking);
1342}
1343
39037602 1344#endif /* IOTRACKING */