2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 * Copyright (c) 1998 Apple Computer, Inc. All rights reserved.
29 #include <IOKit/IODeviceTreeSupport.h>
30 #include <IOKit/IOService.h>
31 #include <libkern/c++/OSContainers.h>
32 #include <IOKit/IOCatalogue.h>
33 #include <libkern/c++/OSUnserialize.h>
35 #include <machine/machine_routines.h>
36 #include <mach/kmod.h>
37 #include <mach-o/mach_header.h>
38 #include <kern/host.h>
41 #include <IOKit/IOLib.h>
43 #include <IOKit/assert.h>
47 int IODTGetLoaderInfo( char *key
, void **infoAddr
, int *infoSize
);
48 extern void IODTFreeLoaderInfo( char *key
, void *infoAddr
, int infoSize
);
49 extern void OSRuntimeUnloadCPPForSegment(
50 struct segment_command
* segment
);
55 * At startup these function pointers are set to use the libsa in-kernel
56 * linker for recording and loading kmods. Once the root filesystem
57 * is available, the kmod_load_function pointer gets switched to point
58 * at the kmod_load_extension() function built into the kernel, and the
59 * others are set to zero. Those two functions must *always* be checked
60 * before being invoked.
63 kern_return_t (*kmod_load_function
)(char *extension_name
) =
65 bool (*record_startup_extensions_function
)(void) = 0;
66 bool (*add_from_mkext_function
)(OSData
* mkext
) = 0;
67 void (*remove_startup_extension_function
)(const char * name
) = 0;
72 * A few parts of IOCatalogue require knowledge of
73 * whether the in-kernel linker is present. This
74 * variable is set by libsa's bootstrap code.
76 int kernelLinkerPresent
= 0;
78 #define kModuleKey "CFBundleIdentifier"
80 #define super OSObject
81 OSDefineMetaClassAndStructors(IOCatalogue
, OSObject
)
85 IOCatalogue
* gIOCatalogue
;
86 const OSSymbol
* gIOClassKey
;
87 const OSSymbol
* gIOProbeScoreKey
;
88 const OSSymbol
* gIOModuleIdentifierKey
;
89 OSSet
* gIOCatalogModuleRequests
;
90 OSSet
* gIOCatalogCacheMisses
;
91 OSSet
* gIOCatalogROMMkexts
;
92 IOLock
* gIOCatalogLock
;
95 /*********************************************************************
96 *********************************************************************/
98 OSArray
* gIOPrelinkedModules
= 0;
100 extern "C" kern_return_t
101 kmod_create_internal(
105 extern "C" kern_return_t
106 kmod_destroy_internal(kmod_t id
);
108 extern "C" kern_return_t
113 mach_msg_type_number_t
*dataCount
);
115 extern "C" kern_return_t
kmod_retain(kmod_t id
);
116 extern "C" kern_return_t
kmod_release(kmod_t id
);
119 kern_return_t
start_prelink_module(UInt32 moduleIndex
)
121 kern_return_t kr
= KERN_SUCCESS
;
123 SInt32 count
, where
, end
;
125 SInt32 next
, lastDep
;
131 prelinkedModules
= gIOPrelinkedModules
;
133 togo
= IONew(UInt32
, prelinkedModules
->getCount());
134 togo
[0] = moduleIndex
;
137 for (next
= 0; next
< count
; next
++)
139 dict
= (OSDictionary
*) prelinkedModules
->getObject(togo
[next
]);
141 data
= OSDynamicCast(OSData
, dict
->getObject("OSBundlePrelink"));
144 // already started or no code
145 if (togo
[next
] == moduleIndex
)
152 prelink
= (UInt32
*) data
->getBytesNoCopy();
153 lastDep
= OSReadBigInt32(prelink
, 12);
154 for (SInt32 idx
= OSReadBigInt32(prelink
, 8); idx
< lastDep
; idx
+= sizeof(UInt32
))
156 UInt32 depIdx
= OSReadBigInt32(prelink
, idx
) - 1;
158 for (where
= next
+ 1;
159 (where
< count
) && (togo
[where
] > depIdx
);
164 if (togo
[where
] == depIdx
)
166 for (end
= count
; end
!= where
; end
--)
167 togo
[end
] = togo
[end
- 1];
170 togo
[where
] = depIdx
;
174 if (KERN_SUCCESS
!= kr
)
177 for (next
= (count
- 1); next
>= 0; next
--)
179 dict
= (OSDictionary
*) prelinkedModules
->getObject(togo
[next
]);
181 data
= OSDynamicCast(OSData
, dict
->getObject("OSBundlePrelink"));
184 prelink
= (UInt32
*) data
->getBytesNoCopy();
187 kmod_info_t
* kmod_info
= (kmod_info_t
*) OSReadBigInt32(prelink
, 0);
189 kr
= kmod_create_internal(kmod_info
, &id
);
190 if (KERN_SUCCESS
!= kr
)
193 lastDep
= OSReadBigInt32(prelink
, 12);
194 for (SInt32 idx
= OSReadBigInt32(prelink
, 8); idx
< lastDep
; idx
+= sizeof(UInt32
))
196 OSDictionary
* depDict
;
197 kmod_info_t
* depInfo
;
199 depDict
= (OSDictionary
*) prelinkedModules
->getObject(OSReadBigInt32(prelink
, idx
) - 1);
200 str
= OSDynamicCast(OSString
, depDict
->getObject(kModuleKey
));
201 depInfo
= kmod_lookupbyname_locked(str
->getCStringNoCopy());
204 kr
= kmod_retain(KMOD_PACK_IDS(id
, depInfo
->id
));
205 kfree((vm_offset_t
) depInfo
, sizeof(kmod_info_t
));
207 IOLog("%s: NO DEP %s\n", kmod_info
->name
, str
->getCStringNoCopy());
209 dict
->removeObject("OSBundlePrelink");
211 if (kmod_info
->start
)
212 kr
= kmod_start_or_stop(kmod_info
->id
, 1, 0, 0);
215 IODelete(togo
, UInt32
, prelinkedModules
->getCount());
220 /*********************************************************************
221 * This is a function that IOCatalogue calls in order to load a kmod.
222 *********************************************************************/
225 kern_return_t
kmod_load_from_cache_sym(const OSSymbol
* kmod_name
)
227 OSArray
* prelinkedModules
= gIOPrelinkedModules
;
228 kern_return_t result
= KERN_FAILURE
;
233 if (!gIOPrelinkedModules
)
237 (dict
= (OSDictionary
*) prelinkedModules
->getObject(idx
));
240 if ((ident
= dict
->getObject(kModuleKey
))
241 && kmod_name
->isEqualTo(ident
))
246 if (kernelLinkerPresent
&& dict
->getObject("OSBundleDefer"))
248 kmod_load_extension((char *) kmod_name
->getCStringNoCopy());
249 result
= kIOReturnOffline
;
252 result
= start_prelink_module(idx
);
258 extern "C" Boolean
kmod_load_request(const char * moduleName
, Boolean make_request
)
260 bool ret
, cacheMiss
= false;
262 const OSSymbol
* sym
= 0;
263 kmod_info_t
* kmod_info
;
268 /* To make sure this operation completes even if a bad extension needs
269 * to be removed, take the kld lock for this whole block, spanning the
270 * kmod_load_function() and remove_startup_extension_function() calls.
272 IOLockLock(gIOKLDLock
);
275 // Is the module already loaded?
276 ret
= (0 != (kmod_info
= kmod_lookupbyname_locked((char *)moduleName
)));
278 kfree((vm_offset_t
) kmod_info
, sizeof(kmod_info_t
));
281 sym
= OSSymbol::withCString(moduleName
);
287 kr
= kmod_load_from_cache_sym(sym
);
288 ret
= (kIOReturnSuccess
== kr
);
290 if (ret
|| !make_request
|| (kr
== kIOReturnOffline
))
293 // If the module hasn't been loaded, then load it.
294 if (!kmod_load_function
) {
295 IOLog("IOCatalogue: %s cannot be loaded "
296 "(kmod load function not set).\n",
301 kr
= kmod_load_function((char *)moduleName
);
303 if (ret
!= kIOReturnSuccess
) {
304 IOLog("IOCatalogue: %s cannot be loaded.\n", moduleName
);
306 /* If the extension couldn't be loaded this time,
307 * make it unavailable so that no more requests are
308 * made in vain. This also enables other matching
309 * extensions to have a chance.
311 if (kernelLinkerPresent
&& remove_startup_extension_function
) {
312 (*remove_startup_extension_function
)(moduleName
);
316 } else if (kernelLinkerPresent
) {
317 // If kern linker is here, the driver is actually loaded,
322 // kern linker isn't here, a request has been queued
323 // but the module isn't necessarily loaded yet, so stall.
329 IOLockUnlock(gIOKLDLock
);
333 IOLockLock(gIOCatalogLock
);
334 gIOCatalogModuleRequests
->setObject(sym
);
336 gIOCatalogCacheMisses
->setObject(sym
);
337 IOLockUnlock(gIOCatalogLock
);
343 extern "C" kern_return_t
kmod_unload_cache(void)
345 OSArray
* prelinkedModules
= gIOPrelinkedModules
;
346 kern_return_t result
= KERN_FAILURE
;
352 if (!gIOPrelinkedModules
)
355 IOLockLock(gIOKLDLock
);
357 (dict
= (OSDictionary
*) prelinkedModules
->getObject(idx
));
360 data
= OSDynamicCast(OSData
, dict
->getObject("OSBundlePrelink"));
363 prelink
= (UInt32
*) data
->getBytesNoCopy();
365 kmod_info_t
* kmod_info
= (kmod_info_t
*) OSReadBigInt32(prelink
, 0);
367 virt
= ml_static_ptovirt(kmod_info
->address
);
369 ml_static_mfree(virt
, kmod_info
->size
);
373 gIOPrelinkedModules
->release();
374 gIOPrelinkedModules
= 0;
376 IOLockUnlock(gIOKLDLock
);
381 extern "C" kern_return_t
kmod_load_from_cache(const char * kmod_name
)
384 const OSSymbol
* sym
= OSSymbol::withCStringNoCopy(kmod_name
);
388 kr
= kmod_load_from_cache_sym(sym
);
392 kr
= kIOReturnNoMemory
;
397 /*********************************************************************
398 *********************************************************************/
400 static void UniqueProperties( OSDictionary
* dict
)
404 data
= OSDynamicCast( OSString
, dict
->getObject( gIOClassKey
));
406 const OSSymbol
*classSymbol
= OSSymbol::withString(data
);
408 dict
->setObject( gIOClassKey
, (OSSymbol
*) classSymbol
);
409 classSymbol
->release();
412 data
= OSDynamicCast( OSString
, dict
->getObject( gIOMatchCategoryKey
));
414 const OSSymbol
*classSymbol
= OSSymbol::withString(data
);
416 dict
->setObject( gIOMatchCategoryKey
, (OSSymbol
*) classSymbol
);
417 classSymbol
->release();
421 void IOCatalogue::initialize( void )
424 OSString
* errorString
;
427 extern const char * gIOKernelConfigTables
;
429 array
= OSDynamicCast(OSArray
, OSUnserialize(gIOKernelConfigTables
, &errorString
));
430 if (!array
&& errorString
) {
431 IOLog("KernelConfigTables syntax error: %s\n",
432 errorString
->getCStringNoCopy());
433 errorString
->release();
436 gIOClassKey
= OSSymbol::withCStringNoCopy( kIOClassKey
);
437 gIOProbeScoreKey
= OSSymbol::withCStringNoCopy( kIOProbeScoreKey
);
438 gIOModuleIdentifierKey
= OSSymbol::withCStringNoCopy( kModuleKey
);
439 gIOCatalogModuleRequests
= OSSet::withCapacity(16);
440 gIOCatalogCacheMisses
= OSSet::withCapacity(16);
441 gIOCatalogROMMkexts
= OSSet::withCapacity(4);
443 assert( array
&& gIOClassKey
&& gIOProbeScoreKey
444 && gIOModuleIdentifierKey
&& gIOCatalogModuleRequests
);
446 gIOCatalogue
= new IOCatalogue
;
447 assert(gIOCatalogue
);
448 rc
= gIOCatalogue
->init(array
);
453 // Initialize the IOCatalog object.
454 bool IOCatalogue::init(OSArray
* initArray
)
456 IORegistryEntry
* entry
;
459 if ( !super::init() )
466 kernelTables
= OSCollectionIterator::withCollection( array
);
468 gIOCatalogLock
= IOLockAlloc();
469 gIOKLDLock
= IOLockAlloc();
471 lock
= gIOCatalogLock
;
472 kld_lock
= gIOKLDLock
;
474 kernelTables
->reset();
475 while( (dict
= (OSDictionary
*) kernelTables
->getNextObject())) {
476 UniqueProperties(dict
);
477 if( 0 == dict
->getObject( gIOClassKey
))
478 IOLog("Missing or bad \"%s\" key\n",
479 gIOClassKey
->getCStringNoCopy());
483 AbsoluteTime deadline
;
484 clock_interval_to_deadline( 1000, kMillisecondScale
);
485 thread_call_func_delayed( ping
, this, deadline
);
488 entry
= IORegistryEntry::getRegistryRoot();
490 entry
->setProperty(kIOCatalogueKey
, this);
495 // Release all resources used by IOCatalogue and deallocate.
496 // This will probably never be called.
497 void IOCatalogue::free( void )
503 kernelTables
->release();
510 static int hackLimit
;
512 enum { kDriversPerIter
= 4 };
514 void IOCatalogue::ping( thread_call_param_t arg
, thread_call_param_t
)
516 IOCatalogue
* self
= (IOCatalogue
*) arg
;
518 OSDictionary
* table
;
521 set
= OSOrderedSet::withCapacity( 1 );
523 IOLockLock( &self
->lock
);
525 for( newLimit
= 0; newLimit
< kDriversPerIter
; newLimit
++) {
526 table
= (OSDictionary
*) self
->array
->getObject(
527 hackLimit
+ newLimit
);
529 set
->setLastObject( table
);
531 OSSymbol
* sym
= (OSSymbol
*) table
->getObject( gIOClassKey
);
532 kprintf("enabling %s\n", sym
->getCStringNoCopy());
540 IOService::catalogNewDrivers( set
);
542 hackLimit
+= newLimit
;
545 IOLockUnlock( &self
->lock
);
547 if( kDriversPerIter
== newLimit
) {
548 AbsoluteTime deadline
;
549 clock_interval_to_deadline( 500, kMillisecondScale
);
550 thread_call_func_delayed( ping
, this, deadline
);
555 OSOrderedSet
* IOCatalogue::findDrivers( IOService
* service
,
556 SInt32
* generationCount
)
558 OSDictionary
* nextTable
;
562 set
= OSOrderedSet::withCapacity( 1, IOServiceOrdering
,
563 (void *)gIOProbeScoreKey
);
568 kernelTables
->reset();
573 while( (nextTable
= (OSDictionary
*) kernelTables
->getNextObject())) {
575 if( hackIndex
++ > hackLimit
)
578 imports
= OSDynamicCast( OSString
,
579 nextTable
->getObject( gIOProviderClassKey
));
580 if( imports
&& service
->metaCast( imports
))
581 set
->setObject( nextTable
);
584 *generationCount
= getGenerationCount();
586 IOLockUnlock( lock
);
591 // Is personality already in the catalog?
592 OSOrderedSet
* IOCatalogue::findDrivers( OSDictionary
* matching
,
593 SInt32
* generationCount
)
598 UniqueProperties(matching
);
600 set
= OSOrderedSet::withCapacity( 1, IOServiceOrdering
,
601 (void *)gIOProbeScoreKey
);
604 kernelTables
->reset();
605 while ( (dict
= (OSDictionary
*) kernelTables
->getNextObject()) ) {
607 /* This comparison must be done with only the keys in the
608 * "matching" dict to enable general searches.
610 if ( dict
->isEqualTo(matching
, matching
) )
611 set
->setObject(dict
);
613 *generationCount
= getGenerationCount();
614 IOLockUnlock( lock
);
619 // Add a new personality to the set if it has a unique IOResourceMatchKey value.
620 // XXX -- svail: This should be optimized.
621 // esb - There doesn't seem like any reason to do this - it causes problems
622 // esb - when there are more than one loadable driver matching on the same provider class
623 static void AddNewImports( OSOrderedSet
* set
, OSDictionary
* dict
)
625 set
->setObject(dict
);
628 // Add driver config tables to catalog and start matching process.
629 bool IOCatalogue::addDrivers(OSArray
* drivers
,
632 OSCollectionIterator
* iter
;
636 OSString
* moduleName
;
640 persons
= OSDynamicCast(OSArray
, drivers
);
644 iter
= OSCollectionIterator::withCollection( persons
);
648 set
= OSOrderedSet::withCapacity( 10, IOServiceOrdering
,
649 (void *)gIOProbeScoreKey
);
656 while ( (dict
= (OSDictionary
*) iter
->getNextObject()) )
658 if ((moduleName
= OSDynamicCast(OSString
, dict
->getObject("OSBundleModuleDemand"))))
660 IOLockUnlock( lock
);
661 ret
= kmod_load_request(moduleName
->getCStringNoCopy(), false);
669 UniqueProperties( dict
);
671 // Add driver personality to catalogue.
672 count
= array
->getCount();
674 OSDictionary
* driver
;
676 // Be sure not to double up on personalities.
677 driver
= (OSDictionary
*)array
->getObject(count
);
679 /* Unlike in other functions, this comparison must be exact!
680 * The catalogue must be able to contain personalities that
681 * are proper supersets of others.
682 * Do not compare just the properties present in one driver
683 * pesonality or the other.
685 if (dict
->isEqualTo(driver
))
692 ret
= array
->setObject( dict
);
696 AddNewImports( set
, dict
);
699 // Start device matching.
700 if (doNubMatching
&& (set
->getCount() > 0)) {
701 IOService::catalogNewDrivers( set
);
704 IOLockUnlock( lock
);
712 // Remove drivers from the catalog which match the
713 // properties in the matching dictionary.
714 bool IOCatalogue::removeDrivers( OSDictionary
* matching
,
717 OSCollectionIterator
* tables
;
725 set
= OSOrderedSet::withCapacity(10,
727 (void *)gIOProbeScoreKey
);
731 arrayCopy
= OSArray::withCapacity(100);
737 tables
= OSCollectionIterator::withCollection(arrayCopy
);
738 arrayCopy
->release();
744 UniqueProperties( matching
);
747 kernelTables
->reset();
748 arrayCopy
->merge(array
);
749 array
->flushCollection();
751 while ( (dict
= (OSDictionary
*)tables
->getNextObject()) ) {
753 /* This comparison must be done with only the keys in the
754 * "matching" dict to enable general searches.
756 if ( dict
->isEqualTo(matching
, matching
) ) {
757 AddNewImports( set
, dict
);
761 array
->setObject(dict
);
763 // Start device matching.
764 if ( doNubMatching
&& (set
->getCount() > 0) ) {
765 IOService::catalogNewDrivers(set
);
768 IOLockUnlock( lock
);
776 // Return the generation count.
777 SInt32
IOCatalogue::getGenerationCount( void ) const
779 return( generation
);
782 bool IOCatalogue::isModuleLoaded( OSString
* moduleName
) const
784 return isModuleLoaded(moduleName
->getCStringNoCopy());
787 bool IOCatalogue::isModuleLoaded( const char * moduleName
) const
789 return (kmod_load_request(moduleName
, true));
792 // Check to see if module has been loaded already.
793 bool IOCatalogue::isModuleLoaded( OSDictionary
* driver
) const
795 OSString
* moduleName
= NULL
;
800 moduleName
= OSDynamicCast(OSString
, driver
->getObject(gIOModuleIdentifierKey
));
802 return isModuleLoaded(moduleName
);
804 /* If a personality doesn't hold the "CFBundleIdentifier" key
805 * it is assumed to be an "in-kernel" driver.
810 // This function is called after a module has been loaded.
811 void IOCatalogue::moduleHasLoaded( OSString
* moduleName
)
815 dict
= OSDictionary::withCapacity(2);
816 dict
->setObject(gIOModuleIdentifierKey
, moduleName
);
821 void IOCatalogue::moduleHasLoaded( const char * moduleName
)
825 name
= OSString::withCString(moduleName
);
826 moduleHasLoaded(name
);
830 IOReturn
IOCatalogue::unloadModule( OSString
* moduleName
) const
832 kmod_info_t
* k_info
= 0;
836 ret
= kIOReturnBadArgument
;
838 name
= moduleName
->getCStringNoCopy();
839 k_info
= kmod_lookupbyname_locked((char *)name
);
840 if ( k_info
&& (k_info
->reference_count
< 1) ) {
842 !((ret
= k_info
->stop(k_info
, 0)) == kIOReturnSuccess
) ) {
844 kfree((vm_offset_t
) k_info
, sizeof(kmod_info_t
));
848 ret
= kmod_destroy(host_priv_self(), k_info
->id
);
853 kfree((vm_offset_t
) k_info
, sizeof(kmod_info_t
));
859 static IOReturn
_terminateDrivers( OSArray
* array
, OSDictionary
* matching
)
861 OSCollectionIterator
* tables
;
869 return kIOReturnBadArgument
;
871 ret
= kIOReturnSuccess
;
873 iter
= IORegistryIterator::iterateOver(gIOServicePlane
,
874 kIORegistryIterateRecursively
);
876 return kIOReturnNoMemory
;
878 UniqueProperties( matching
);
880 // terminate instances.
883 while( (service
= (IOService
*)iter
->getNextObject()) ) {
884 dict
= service
->getPropertyTable();
888 /* Terminate only for personalities that match the matching dictionary.
889 * This comparison must be done with only the keys in the
890 * "matching" dict to enable general matching.
892 if ( !dict
->isEqualTo(matching
, matching
) )
895 if ( !service
->terminate(kIOServiceRequired
|kIOServiceSynchronous
) ) {
896 ret
= kIOReturnUnsupported
;
900 } while( !service
&& !iter
->isValid());
903 // remove configs from catalog.
904 if ( ret
!= kIOReturnSuccess
)
907 arrayCopy
= OSArray::withCapacity(100);
909 return kIOReturnNoMemory
;
911 tables
= OSCollectionIterator::withCollection(arrayCopy
);
912 arrayCopy
->release();
914 return kIOReturnNoMemory
;
916 arrayCopy
->merge(array
);
917 array
->flushCollection();
919 while ( (dict
= (OSDictionary
*)tables
->getNextObject()) ) {
921 /* Remove from the catalogue's array any personalities
922 * that match the matching dictionary.
923 * This comparison must be done with only the keys in the
924 * "matching" dict to enable general matching.
926 if ( dict
->isEqualTo(matching
, matching
) )
929 array
->setObject(dict
);
937 IOReturn
IOCatalogue::terminateDrivers( OSDictionary
* matching
)
941 ret
= kIOReturnSuccess
;
943 ret
= _terminateDrivers(array
, matching
);
944 kernelTables
->reset();
945 IOLockUnlock( lock
);
950 IOReturn
IOCatalogue::terminateDriversForModule(
951 OSString
* moduleName
,
957 dict
= OSDictionary::withCapacity(1);
959 return kIOReturnNoMemory
;
961 dict
->setObject(gIOModuleIdentifierKey
, moduleName
);
965 ret
= _terminateDrivers(array
, dict
);
966 kernelTables
->reset();
968 // Unload the module itself.
969 if ( unload
&& ret
== kIOReturnSuccess
) {
970 // Do kmod stop first.
971 ret
= unloadModule(moduleName
);
974 IOLockUnlock( lock
);
981 IOReturn
IOCatalogue::terminateDriversForModule(
982 const char * moduleName
,
988 name
= OSString::withCString(moduleName
);
990 return kIOReturnNoMemory
;
992 ret
= terminateDriversForModule(name
, unload
);
998 bool IOCatalogue::startMatching( OSDictionary
* matching
)
1000 OSDictionary
* dict
;
1006 set
= OSOrderedSet::withCapacity(10, IOServiceOrdering
,
1007 (void *)gIOProbeScoreKey
);
1012 kernelTables
->reset();
1014 while ( (dict
= (OSDictionary
*)kernelTables
->getNextObject()) ) {
1016 /* This comparison must be done with only the keys in the
1017 * "matching" dict to enable general matching.
1019 if ( dict
->isEqualTo(matching
, matching
) )
1020 AddNewImports(set
, dict
);
1022 // Start device matching.
1023 if ( set
->getCount() > 0 ) {
1024 IOService::catalogNewDrivers(set
);
1028 IOLockUnlock( lock
);
1035 void IOCatalogue::reset(void)
1037 IOLog("Resetting IOCatalogue.\n");
1040 bool IOCatalogue::serialize(OSSerialize
* s
) const
1049 ret
= array
->serialize(s
);
1051 IOLockUnlock( lock
);
1056 bool IOCatalogue::serializeData(IOOptionBits kind
, OSSerialize
* s
) const
1058 kern_return_t kr
= kIOReturnSuccess
;
1062 case kIOCatalogGetContents
:
1064 kr
= kIOReturnNoMemory
;
1067 case kIOCatalogGetModuleDemandList
:
1069 if (!gIOCatalogModuleRequests
->serialize(s
))
1070 kr
= kIOReturnNoMemory
;
1071 IOLockUnlock( lock
);
1074 case kIOCatalogGetCacheMissList
:
1076 if (!gIOCatalogCacheMisses
->serialize(s
))
1077 kr
= kIOReturnNoMemory
;
1078 IOLockUnlock( lock
);
1081 case kIOCatalogGetROMMkextList
:
1084 if (!gIOCatalogROMMkexts
|| !gIOCatalogROMMkexts
->getCount())
1085 kr
= kIOReturnNoResources
;
1086 else if (!gIOCatalogROMMkexts
->serialize(s
))
1087 kr
= kIOReturnNoMemory
;
1089 if (gIOCatalogROMMkexts
)
1091 gIOCatalogROMMkexts
->release();
1092 gIOCatalogROMMkexts
= 0;
1095 IOLockUnlock( lock
);
1099 kr
= kIOReturnBadArgument
;
1107 bool IOCatalogue::recordStartupExtensions(void) {
1108 bool result
= false;
1110 IOLockLock(kld_lock
);
1111 if (kernelLinkerPresent
&& record_startup_extensions_function
) {
1112 result
= (*record_startup_extensions_function
)();
1114 IOLog("Can't record startup extensions; "
1115 "kernel linker is not present.\n");
1118 IOLockUnlock(kld_lock
);
1124 /*********************************************************************
1125 *********************************************************************/
1126 bool IOCatalogue::addExtensionsFromArchive(OSData
* mkext
)
1129 bool result
= false;
1132 /* The mkext we've been handed (or the data it references) can go away,
1133 * so we need to make a local copy to keep around as long as it might
1136 copyData
= OSData::withData(mkext
);
1139 struct section
* infosect
;
1141 infosect
= getsectbyname("__PRELINK", "__info");
1142 prelinked
= (infosect
&& infosect
->addr
&& infosect
->size
);
1144 IOLockLock(kld_lock
);
1146 if (gIOCatalogROMMkexts
)
1147 gIOCatalogROMMkexts
->setObject(copyData
);
1151 } else if (kernelLinkerPresent
&& add_from_mkext_function
) {
1152 result
= (*add_from_mkext_function
)(copyData
);
1154 IOLog("Can't add startup extensions from archive; "
1155 "kernel linker is not present.\n");
1159 IOLockUnlock(kld_lock
);
1161 copyData
->release();
1168 /*********************************************************************
1169 * This function clears out all references to the in-kernel linker,
1170 * frees the list of startup extensions in extensionDict, and
1171 * deallocates the kernel's __KLD segment to reclaim that memory.
1172 *********************************************************************/
1173 kern_return_t
IOCatalogue::removeKernelLinker(void) {
1174 kern_return_t result
= KERN_SUCCESS
;
1175 struct segment_command
* segment
;
1176 char * dt_segment_name
;
1177 void * segment_paddress
;
1180 /* This must be the very first thing done by this function.
1182 IOLockLock(kld_lock
);
1185 /* If the kernel linker isn't here, that's automatically
1188 if (!kernelLinkerPresent
) {
1189 result
= KERN_SUCCESS
;
1193 IOLog("Jettisoning kernel linker.\n");
1195 kernelLinkerPresent
= 0;
1197 /* Set the kmod_load_extension function as the means for loading
1198 * a kernel extension.
1200 kmod_load_function
= &kmod_load_extension
;
1202 record_startup_extensions_function
= 0;
1203 add_from_mkext_function
= 0;
1204 remove_startup_extension_function
= 0;
1207 /* Invoke destructors for the __KLD and __LINKEDIT segments.
1208 * Do this for all segments before actually freeing their
1209 * memory so that any cross-dependencies (not that there
1210 * should be any) are handled.
1212 segment
= getsegbyname("__KLD");
1214 IOLog("error removing kernel linker: can't find %s segment\n",
1216 result
= KERN_FAILURE
;
1219 OSRuntimeUnloadCPPForSegment(segment
);
1221 segment
= getsegbyname("__LINKEDIT");
1223 IOLog("error removing kernel linker: can't find %s segment\n",
1225 result
= KERN_FAILURE
;
1228 OSRuntimeUnloadCPPForSegment(segment
);
1231 /* Free the memory that was set up by bootx.
1233 dt_segment_name
= "Kernel-__KLD";
1234 if (0 == IODTGetLoaderInfo(dt_segment_name
, &segment_paddress
, &segment_size
)) {
1235 IODTFreeLoaderInfo(dt_segment_name
, (void *)segment_paddress
,
1239 dt_segment_name
= "Kernel-__LINKEDIT";
1240 if (0 == IODTGetLoaderInfo(dt_segment_name
, &segment_paddress
, &segment_size
)) {
1241 IODTFreeLoaderInfo(dt_segment_name
, (void *)segment_paddress
,
1245 struct section
* sect
;
1246 sect
= getsectbyname("__PRELINK", "__symtab");
1247 if (sect
&& sect
->addr
)
1250 virt
= ml_static_ptovirt(sect
->addr
);
1252 ml_static_mfree(virt
, sect
->size
);
1258 /* This must be the very last thing done before returning.
1260 IOLockUnlock(kld_lock
);