2 * Copyright (c) 1998-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 * Copyright (c) 1998 Apple Computer, Inc. All rights reserved.
30 #include <IOKit/IODeviceTreeSupport.h>
31 #include <IOKit/IOService.h>
32 #include <libkern/c++/OSContainers.h>
33 #include <IOKit/IOCatalogue.h>
34 #include <libkern/c++/OSUnserialize.h>
36 #include <machine/machine_routines.h>
37 #include <mach/kmod.h>
38 #include <mach-o/mach_header.h>
39 #include <kern/host.h>
42 #include <IOKit/IOLib.h>
44 #include <IOKit/assert.h>
48 int IODTGetLoaderInfo( char *key
, void **infoAddr
, int *infoSize
);
49 extern void IODTFreeLoaderInfo( char *key
, void *infoAddr
, int infoSize
);
50 /* operates on 32 bit segments */
51 extern void OSRuntimeUnloadCPPForSegment(struct segment_command
* segment
);
56 * At startup these function pointers are set to use the libsa in-kernel
57 * linker for recording and loading kmods. Once the root filesystem
58 * is available, the kmod_load_function pointer gets switched to point
59 * at the kmod_load_extension() function built into the kernel, and the
60 * others are set to zero. Those two functions must *always* be checked
61 * before being invoked.
64 kern_return_t (*kmod_load_function
)(char *extension_name
) =
66 bool (*record_startup_extensions_function
)(void) = 0;
67 bool (*add_from_mkext_function
)(OSData
* mkext
) = 0;
68 void (*remove_startup_extension_function
)(const char * name
) = 0;
73 * A few parts of IOCatalogue require knowledge of
74 * whether the in-kernel linker is present. This
75 * variable is set by libsa's bootstrap code.
77 int kernelLinkerPresent
= 0;
79 #define kModuleKey "CFBundleIdentifier"
81 #define super OSObject
82 OSDefineMetaClassAndStructors(IOCatalogue
, OSObject
)
86 IOCatalogue
* gIOCatalogue
;
87 const OSSymbol
* gIOClassKey
;
88 const OSSymbol
* gIOProbeScoreKey
;
89 const OSSymbol
* gIOModuleIdentifierKey
;
90 OSSet
* gIOCatalogModuleRequests
;
91 OSSet
* gIOCatalogCacheMisses
;
92 OSSet
* gIOCatalogROMMkexts
;
93 IOLock
* gIOCatalogLock
;
96 /*********************************************************************
97 *********************************************************************/
99 OSArray
* gIOPrelinkedModules
= 0;
101 extern "C" kern_return_t
102 kmod_create_internal(
106 extern "C" kern_return_t
107 kmod_destroy_internal(kmod_t id
);
109 extern "C" kern_return_t
114 mach_msg_type_number_t
*dataCount
);
116 extern "C" kern_return_t
kmod_retain(kmod_t id
);
117 extern "C" kern_return_t
kmod_release(kmod_t id
);
120 kern_return_t
start_prelink_module(UInt32 moduleIndex
)
122 kern_return_t kr
= KERN_SUCCESS
;
124 SInt32 count
, where
, end
;
126 SInt32 next
, lastDep
;
132 prelinkedModules
= gIOPrelinkedModules
;
134 togo
= IONew(UInt32
, prelinkedModules
->getCount());
135 togo
[0] = moduleIndex
;
138 for (next
= 0; next
< count
; next
++)
140 dict
= (OSDictionary
*) prelinkedModules
->getObject(togo
[next
]);
142 data
= OSDynamicCast(OSData
, dict
->getObject("OSBundlePrelink"));
145 // already started or no code
146 if (togo
[next
] == moduleIndex
)
153 prelink
= (UInt32
*) data
->getBytesNoCopy();
154 lastDep
= OSReadBigInt32(prelink
, 12);
155 for (SInt32 idx
= OSReadBigInt32(prelink
, 8); idx
< lastDep
; idx
+= sizeof(UInt32
))
157 UInt32 depIdx
= OSReadBigInt32(prelink
, idx
) - 1;
159 for (where
= next
+ 1;
160 (where
< count
) && (togo
[where
] > depIdx
);
165 if (togo
[where
] == depIdx
)
167 for (end
= count
; end
!= where
; end
--)
168 togo
[end
] = togo
[end
- 1];
171 togo
[where
] = depIdx
;
175 if (KERN_SUCCESS
!= kr
)
178 for (next
= (count
- 1); next
>= 0; next
--)
180 dict
= (OSDictionary
*) prelinkedModules
->getObject(togo
[next
]);
182 data
= OSDynamicCast(OSData
, dict
->getObject("OSBundlePrelink"));
185 prelink
= (UInt32
*) data
->getBytesNoCopy();
188 kmod_info_t
* kmod_info
= (kmod_info_t
*) OSReadBigInt32(prelink
, 0);
190 kr
= kmod_create_internal(kmod_info
, &id
);
191 if (KERN_SUCCESS
!= kr
)
194 lastDep
= OSReadBigInt32(prelink
, 12);
195 for (SInt32 idx
= OSReadBigInt32(prelink
, 8); idx
< lastDep
; idx
+= sizeof(UInt32
))
197 OSDictionary
* depDict
;
198 kmod_info_t
* depInfo
;
200 depDict
= (OSDictionary
*) prelinkedModules
->getObject(OSReadBigInt32(prelink
, idx
) - 1);
201 str
= OSDynamicCast(OSString
, depDict
->getObject(kModuleKey
));
202 depInfo
= kmod_lookupbyname_locked(str
->getCStringNoCopy());
205 kr
= kmod_retain(KMOD_PACK_IDS(id
, depInfo
->id
));
206 kfree(depInfo
, sizeof(kmod_info_t
));
208 IOLog("%s: NO DEP %s\n", kmod_info
->name
, str
->getCStringNoCopy());
210 dict
->removeObject("OSBundlePrelink");
212 if (kmod_info
->start
)
213 kr
= kmod_start_or_stop(kmod_info
->id
, 1, 0, 0);
216 IODelete(togo
, UInt32
, prelinkedModules
->getCount());
221 /*********************************************************************
222 * This is a function that IOCatalogue calls in order to load a kmod.
223 *********************************************************************/
226 kern_return_t
kmod_load_from_cache_sym(const OSSymbol
* kmod_name
)
228 OSArray
* prelinkedModules
= gIOPrelinkedModules
;
229 kern_return_t result
= KERN_FAILURE
;
234 if (!gIOPrelinkedModules
)
238 (dict
= (OSDictionary
*) prelinkedModules
->getObject(idx
));
241 if ((ident
= dict
->getObject(kModuleKey
))
242 && kmod_name
->isEqualTo(ident
))
247 if (kernelLinkerPresent
&& dict
->getObject("OSBundleDefer"))
249 kmod_load_extension((char *) kmod_name
->getCStringNoCopy());
250 result
= kIOReturnOffline
;
253 result
= start_prelink_module(idx
);
259 extern "C" Boolean
kmod_load_request(const char * moduleName
, Boolean make_request
)
261 bool ret
, cacheMiss
= false;
263 const OSSymbol
* sym
= 0;
264 kmod_info_t
* kmod_info
;
269 /* To make sure this operation completes even if a bad extension needs
270 * to be removed, take the kld lock for this whole block, spanning the
271 * kmod_load_function() and remove_startup_extension_function() calls.
273 IOLockLock(gIOKLDLock
);
276 // Is the module already loaded?
277 ret
= (0 != (kmod_info
= kmod_lookupbyname_locked((char *)moduleName
)));
279 kfree(kmod_info
, sizeof(kmod_info_t
));
282 sym
= OSSymbol::withCString(moduleName
);
288 kr
= kmod_load_from_cache_sym(sym
);
289 ret
= (kIOReturnSuccess
== kr
);
291 if (ret
|| !make_request
|| (kr
== kIOReturnOffline
))
294 // If the module hasn't been loaded, then load it.
295 if (!kmod_load_function
) {
296 IOLog("IOCatalogue: %s cannot be loaded "
297 "(kmod load function not set).\n",
303 kr
= kmod_load_function((char *)moduleName
);
305 if (ret
!= kIOReturnSuccess
) {
306 IOLog("IOCatalogue: %s cannot be loaded.\n", moduleName
);
308 /* If the extension couldn't be loaded this time,
309 * make it unavailable so that no more requests are
310 * made in vain. This also enables other matching
311 * extensions to have a chance.
313 if (kernelLinkerPresent
&& remove_startup_extension_function
) {
314 (*remove_startup_extension_function
)(moduleName
);
318 } else if (kernelLinkerPresent
) {
319 // If kern linker is here, the driver is actually loaded,
324 // kern linker isn't here, a request has been queued
325 // but the module isn't necessarily loaded yet, so stall.
331 IOLockUnlock(gIOKLDLock
);
335 IOLockLock(gIOCatalogLock
);
336 gIOCatalogModuleRequests
->setObject(sym
);
338 gIOCatalogCacheMisses
->setObject(sym
);
339 IOLockUnlock(gIOCatalogLock
);
345 extern "C" kern_return_t
kmod_unload_cache(void)
347 OSArray
* prelinkedModules
= gIOPrelinkedModules
;
348 kern_return_t result
= KERN_FAILURE
;
354 if (!gIOPrelinkedModules
)
357 IOLockLock(gIOKLDLock
);
359 (dict
= (OSDictionary
*) prelinkedModules
->getObject(idx
));
362 data
= OSDynamicCast(OSData
, dict
->getObject("OSBundlePrelink"));
365 prelink
= (UInt32
*) data
->getBytesNoCopy();
367 kmod_info_t
* kmod_info
= (kmod_info_t
*) OSReadBigInt32(prelink
, 0);
369 virt
= ml_static_ptovirt(kmod_info
->address
);
371 ml_static_mfree(virt
, kmod_info
->size
);
375 gIOPrelinkedModules
->release();
376 gIOPrelinkedModules
= 0;
378 IOLockUnlock(gIOKLDLock
);
383 extern "C" kern_return_t
kmod_load_from_cache(const char * kmod_name
)
386 const OSSymbol
* sym
= OSSymbol::withCStringNoCopy(kmod_name
);
390 kr
= kmod_load_from_cache_sym(sym
);
394 kr
= kIOReturnNoMemory
;
399 /*********************************************************************
400 *********************************************************************/
402 static void UniqueProperties( OSDictionary
* dict
)
406 data
= OSDynamicCast( OSString
, dict
->getObject( gIOClassKey
));
408 const OSSymbol
*classSymbol
= OSSymbol::withString(data
);
410 dict
->setObject( gIOClassKey
, (OSSymbol
*) classSymbol
);
411 classSymbol
->release();
414 data
= OSDynamicCast( OSString
, dict
->getObject( gIOMatchCategoryKey
));
416 const OSSymbol
*classSymbol
= OSSymbol::withString(data
);
418 dict
->setObject( gIOMatchCategoryKey
, (OSSymbol
*) classSymbol
);
419 classSymbol
->release();
423 void IOCatalogue::initialize( void )
426 OSString
* errorString
;
429 extern const char * gIOKernelConfigTables
;
431 array
= OSDynamicCast(OSArray
, OSUnserialize(gIOKernelConfigTables
, &errorString
));
432 if (!array
&& errorString
) {
433 IOLog("KernelConfigTables syntax error: %s\n",
434 errorString
->getCStringNoCopy());
435 errorString
->release();
438 gIOClassKey
= OSSymbol::withCStringNoCopy( kIOClassKey
);
439 gIOProbeScoreKey
= OSSymbol::withCStringNoCopy( kIOProbeScoreKey
);
440 gIOModuleIdentifierKey
= OSSymbol::withCStringNoCopy( kModuleKey
);
441 gIOCatalogModuleRequests
= OSSet::withCapacity(16);
442 gIOCatalogCacheMisses
= OSSet::withCapacity(16);
443 gIOCatalogROMMkexts
= OSSet::withCapacity(4);
445 assert( array
&& gIOClassKey
&& gIOProbeScoreKey
446 && gIOModuleIdentifierKey
&& gIOCatalogModuleRequests
);
448 gIOCatalogue
= new IOCatalogue
;
449 assert(gIOCatalogue
);
450 rc
= gIOCatalogue
->init(array
);
455 // Initialize the IOCatalog object.
456 bool IOCatalogue::init(OSArray
* initArray
)
460 if ( !super::init() )
467 kernelTables
= OSCollectionIterator::withCollection( array
);
469 gIOCatalogLock
= IOLockAlloc();
470 gIOKLDLock
= IOLockAlloc();
472 lock
= gIOCatalogLock
;
473 kld_lock
= gIOKLDLock
;
475 kernelTables
->reset();
476 while( (dict
= (OSDictionary
*) kernelTables
->getNextObject())) {
477 UniqueProperties(dict
);
478 if( 0 == dict
->getObject( gIOClassKey
))
479 IOLog("Missing or bad \"%s\" key\n",
480 gIOClassKey
->getCStringNoCopy());
484 AbsoluteTime deadline
;
485 clock_interval_to_deadline( 1000, kMillisecondScale
);
486 thread_call_func_delayed( ping
, this, deadline
);
492 // Release all resources used by IOCatalogue and deallocate.
493 // This will probably never be called.
494 void IOCatalogue::free( void )
500 kernelTables
->release();
507 static int hackLimit
;
509 enum { kDriversPerIter
= 4 };
511 void IOCatalogue::ping( thread_call_param_t arg
, thread_call_param_t
)
513 IOCatalogue
* self
= (IOCatalogue
*) arg
;
515 OSDictionary
* table
;
518 set
= OSOrderedSet::withCapacity( 1 );
520 IOLockLock( &self
->lock
);
522 for( newLimit
= 0; newLimit
< kDriversPerIter
; newLimit
++) {
523 table
= (OSDictionary
*) self
->array
->getObject(
524 hackLimit
+ newLimit
);
526 set
->setLastObject( table
);
528 OSSymbol
* sym
= (OSSymbol
*) table
->getObject( gIOClassKey
);
529 kprintf("enabling %s\n", sym
->getCStringNoCopy());
537 IOService::catalogNewDrivers( set
);
539 hackLimit
+= newLimit
;
542 IOLockUnlock( &self
->lock
);
544 if( kDriversPerIter
== newLimit
) {
545 AbsoluteTime deadline
;
546 clock_interval_to_deadline( 500, kMillisecondScale
);
547 thread_call_func_delayed( ping
, this, deadline
);
552 OSOrderedSet
* IOCatalogue::findDrivers( IOService
* service
,
553 SInt32
* generationCount
)
555 OSDictionary
* nextTable
;
559 set
= OSOrderedSet::withCapacity( 1, IOServiceOrdering
,
560 (void *)gIOProbeScoreKey
);
565 kernelTables
->reset();
570 while( (nextTable
= (OSDictionary
*) kernelTables
->getNextObject())) {
572 if( hackIndex
++ > hackLimit
)
575 imports
= OSDynamicCast( OSString
,
576 nextTable
->getObject( gIOProviderClassKey
));
577 if( imports
&& service
->metaCast( imports
))
578 set
->setObject( nextTable
);
581 *generationCount
= getGenerationCount();
583 IOLockUnlock( lock
);
588 // Is personality already in the catalog?
589 OSOrderedSet
* IOCatalogue::findDrivers( OSDictionary
* matching
,
590 SInt32
* generationCount
)
595 UniqueProperties(matching
);
597 set
= OSOrderedSet::withCapacity( 1, IOServiceOrdering
,
598 (void *)gIOProbeScoreKey
);
601 kernelTables
->reset();
602 while ( (dict
= (OSDictionary
*) kernelTables
->getNextObject()) ) {
604 /* This comparison must be done with only the keys in the
605 * "matching" dict to enable general searches.
607 if ( dict
->isEqualTo(matching
, matching
) )
608 set
->setObject(dict
);
610 *generationCount
= getGenerationCount();
611 IOLockUnlock( lock
);
616 // Add a new personality to the set if it has a unique IOResourceMatchKey value.
617 // XXX -- svail: This should be optimized.
618 // esb - There doesn't seem like any reason to do this - it causes problems
619 // esb - when there are more than one loadable driver matching on the same provider class
620 static void AddNewImports( OSOrderedSet
* set
, OSDictionary
* dict
)
622 set
->setObject(dict
);
625 // Add driver config tables to catalog and start matching process.
626 bool IOCatalogue::addDrivers(OSArray
* drivers
,
629 OSCollectionIterator
* iter
;
633 OSString
* moduleName
;
637 persons
= OSDynamicCast(OSArray
, drivers
);
641 iter
= OSCollectionIterator::withCollection( persons
);
645 set
= OSOrderedSet::withCapacity( 10, IOServiceOrdering
,
646 (void *)gIOProbeScoreKey
);
653 while ( (dict
= (OSDictionary
*) iter
->getNextObject()) )
655 if ((moduleName
= OSDynamicCast(OSString
, dict
->getObject("OSBundleModuleDemand"))))
657 IOLockUnlock( lock
);
658 ret
= kmod_load_request(moduleName
->getCStringNoCopy(), false);
666 UniqueProperties( dict
);
668 // Add driver personality to catalogue.
669 count
= array
->getCount();
671 OSDictionary
* driver
;
673 // Be sure not to double up on personalities.
674 driver
= (OSDictionary
*)array
->getObject(count
);
676 /* Unlike in other functions, this comparison must be exact!
677 * The catalogue must be able to contain personalities that
678 * are proper supersets of others.
679 * Do not compare just the properties present in one driver
680 * pesonality or the other.
682 if (dict
->isEqualTo(driver
))
689 ret
= array
->setObject( dict
);
693 AddNewImports( set
, dict
);
696 // Start device matching.
697 if (doNubMatching
&& (set
->getCount() > 0)) {
698 IOService::catalogNewDrivers( set
);
701 IOLockUnlock( lock
);
709 // Remove drivers from the catalog which match the
710 // properties in the matching dictionary.
711 bool IOCatalogue::removeDrivers( OSDictionary
* matching
,
714 OSCollectionIterator
* tables
;
722 set
= OSOrderedSet::withCapacity(10,
724 (void *)gIOProbeScoreKey
);
728 arrayCopy
= OSArray::withCapacity(100);
734 tables
= OSCollectionIterator::withCollection(arrayCopy
);
735 arrayCopy
->release();
741 UniqueProperties( matching
);
744 kernelTables
->reset();
745 arrayCopy
->merge(array
);
746 array
->flushCollection();
748 while ( (dict
= (OSDictionary
*)tables
->getNextObject()) ) {
750 /* This comparison must be done with only the keys in the
751 * "matching" dict to enable general searches.
753 if ( dict
->isEqualTo(matching
, matching
) ) {
754 AddNewImports( set
, dict
);
758 array
->setObject(dict
);
760 // Start device matching.
761 if ( doNubMatching
&& (set
->getCount() > 0) ) {
762 IOService::catalogNewDrivers(set
);
765 IOLockUnlock( lock
);
773 // Return the generation count.
774 SInt32
IOCatalogue::getGenerationCount( void ) const
776 return( generation
);
779 bool IOCatalogue::isModuleLoaded( OSString
* moduleName
) const
781 return isModuleLoaded(moduleName
->getCStringNoCopy());
784 bool IOCatalogue::isModuleLoaded( const char * moduleName
) const
786 return (kmod_load_request(moduleName
, true));
789 // Check to see if module has been loaded already.
790 bool IOCatalogue::isModuleLoaded( OSDictionary
* driver
) const
792 OSString
* moduleName
= NULL
;
797 moduleName
= OSDynamicCast(OSString
, driver
->getObject(gIOModuleIdentifierKey
));
799 return isModuleLoaded(moduleName
);
801 /* If a personality doesn't hold the "CFBundleIdentifier" key
802 * it is assumed to be an "in-kernel" driver.
807 // This function is called after a module has been loaded.
808 void IOCatalogue::moduleHasLoaded( OSString
* moduleName
)
812 dict
= OSDictionary::withCapacity(2);
813 dict
->setObject(gIOModuleIdentifierKey
, moduleName
);
818 void IOCatalogue::moduleHasLoaded( const char * moduleName
)
822 name
= OSString::withCString(moduleName
);
823 moduleHasLoaded(name
);
827 IOReturn
IOCatalogue::unloadModule( OSString
* moduleName
) const
829 kmod_info_t
* k_info
= 0;
833 ret
= kIOReturnBadArgument
;
835 name
= moduleName
->getCStringNoCopy();
836 k_info
= kmod_lookupbyname_locked((char *)name
);
837 if ( k_info
&& (k_info
->reference_count
< 1) ) {
839 !((ret
= k_info
->stop(k_info
, 0)) == kIOReturnSuccess
) ) {
841 kfree(k_info
, sizeof(kmod_info_t
));
845 ret
= kmod_destroy(host_priv_self(), k_info
->id
);
850 kfree(k_info
, sizeof(kmod_info_t
));
856 static IOReturn
_terminateDrivers( OSDictionary
* matching
)
864 return kIOReturnBadArgument
;
866 ret
= kIOReturnSuccess
;
868 iter
= IORegistryIterator::iterateOver(gIOServicePlane
,
869 kIORegistryIterateRecursively
);
871 return kIOReturnNoMemory
;
873 UniqueProperties( matching
);
875 // terminate instances.
878 while( (service
= (IOService
*)iter
->getNextObject()) ) {
879 dict
= service
->getPropertyTable();
883 /* Terminate only for personalities that match the matching dictionary.
884 * This comparison must be done with only the keys in the
885 * "matching" dict to enable general matching.
887 if ( !dict
->isEqualTo(matching
, matching
) )
890 if ( !service
->terminate(kIOServiceRequired
|kIOServiceSynchronous
) ) {
891 ret
= kIOReturnUnsupported
;
895 } while( !service
&& !iter
->isValid());
901 static IOReturn
_removeDrivers( OSArray
* array
, OSDictionary
* matching
)
903 OSCollectionIterator
* tables
;
906 IOReturn ret
= kIOReturnSuccess
;
908 // remove configs from catalog.
910 arrayCopy
= OSArray::withCapacity(100);
912 return kIOReturnNoMemory
;
914 tables
= OSCollectionIterator::withCollection(arrayCopy
);
915 arrayCopy
->release();
917 return kIOReturnNoMemory
;
919 arrayCopy
->merge(array
);
920 array
->flushCollection();
922 while ( (dict
= (OSDictionary
*)tables
->getNextObject()) ) {
924 /* Remove from the catalogue's array any personalities
925 * that match the matching dictionary.
926 * This comparison must be done with only the keys in the
927 * "matching" dict to enable general matching.
929 if ( dict
->isEqualTo(matching
, matching
) )
932 array
->setObject(dict
);
940 IOReturn
IOCatalogue::terminateDrivers( OSDictionary
* matching
)
944 ret
= _terminateDrivers(matching
);
946 if (kIOReturnSuccess
== ret
)
947 ret
= _removeDrivers(array
, matching
);
948 kernelTables
->reset();
949 IOLockUnlock( lock
);
954 IOReturn
IOCatalogue::terminateDriversForModule(
955 OSString
* moduleName
,
961 dict
= OSDictionary::withCapacity(1);
963 return kIOReturnNoMemory
;
965 dict
->setObject(gIOModuleIdentifierKey
, moduleName
);
967 ret
= _terminateDrivers(dict
);
969 if (kIOReturnSuccess
== ret
)
970 ret
= _removeDrivers(array
, dict
);
971 kernelTables
->reset();
973 // Unload the module itself.
974 if ( unload
&& ret
== kIOReturnSuccess
) {
975 // Do kmod stop first.
976 ret
= unloadModule(moduleName
);
979 IOLockUnlock( lock
);
986 IOReturn
IOCatalogue::terminateDriversForModule(
987 const char * moduleName
,
993 name
= OSString::withCString(moduleName
);
995 return kIOReturnNoMemory
;
997 ret
= terminateDriversForModule(name
, unload
);
1003 bool IOCatalogue::startMatching( OSDictionary
* matching
)
1005 OSDictionary
* dict
;
1011 set
= OSOrderedSet::withCapacity(10, IOServiceOrdering
,
1012 (void *)gIOProbeScoreKey
);
1017 kernelTables
->reset();
1019 while ( (dict
= (OSDictionary
*)kernelTables
->getNextObject()) ) {
1021 /* This comparison must be done with only the keys in the
1022 * "matching" dict to enable general matching.
1024 if ( dict
->isEqualTo(matching
, matching
) )
1025 AddNewImports(set
, dict
);
1027 // Start device matching.
1028 if ( set
->getCount() > 0 ) {
1029 IOService::catalogNewDrivers(set
);
1033 IOLockUnlock( lock
);
1040 void IOCatalogue::reset(void)
1042 IOLog("Resetting IOCatalogue.\n");
1045 bool IOCatalogue::serialize(OSSerialize
* s
) const
1050 return super::serialize(s
);
1053 bool IOCatalogue::serializeData(IOOptionBits kind
, OSSerialize
* s
) const
1055 kern_return_t kr
= kIOReturnSuccess
;
1059 case kIOCatalogGetContents
:
1061 kr
= kIOReturnNoMemory
;
1064 case kIOCatalogGetModuleDemandList
:
1066 if (!gIOCatalogModuleRequests
->serialize(s
))
1067 kr
= kIOReturnNoMemory
;
1068 IOLockUnlock( lock
);
1071 case kIOCatalogGetCacheMissList
:
1073 if (!gIOCatalogCacheMisses
->serialize(s
))
1074 kr
= kIOReturnNoMemory
;
1075 IOLockUnlock( lock
);
1078 case kIOCatalogGetROMMkextList
:
1081 if (!gIOCatalogROMMkexts
|| !gIOCatalogROMMkexts
->getCount())
1082 kr
= kIOReturnNoResources
;
1083 else if (!gIOCatalogROMMkexts
->serialize(s
))
1084 kr
= kIOReturnNoMemory
;
1086 if (gIOCatalogROMMkexts
)
1088 gIOCatalogROMMkexts
->release();
1089 gIOCatalogROMMkexts
= 0;
1092 IOLockUnlock( lock
);
1096 kr
= kIOReturnBadArgument
;
1104 bool IOCatalogue::recordStartupExtensions(void) {
1105 bool result
= false;
1107 IOLockLock(kld_lock
);
1108 if (kernelLinkerPresent
&& record_startup_extensions_function
) {
1109 result
= (*record_startup_extensions_function
)();
1111 IOLog("Can't record startup extensions; "
1112 "kernel linker is not present.\n");
1115 IOLockUnlock(kld_lock
);
1121 /*********************************************************************
1122 * This function operates on sections retrieved from the currently running
1123 * 32 bit mach kernel.
1124 *********************************************************************/
1125 bool IOCatalogue::addExtensionsFromArchive(OSData
* mkext
)
1128 bool result
= false;
1131 /* The mkext we've been handed (or the data it references) can go away,
1132 * so we need to make a local copy to keep around as long as it might
1135 copyData
= OSData::withData(mkext
);
1138 struct section
* infosect
;
1140 infosect
= getsectbyname("__PRELINK", "__info");
1141 prelinked
= (infosect
&& infosect
->addr
&& infosect
->size
);
1143 IOLockLock(kld_lock
);
1145 if (gIOCatalogROMMkexts
)
1146 gIOCatalogROMMkexts
->setObject(copyData
);
1150 } else if (kernelLinkerPresent
&& add_from_mkext_function
) {
1151 result
= (*add_from_mkext_function
)(copyData
);
1153 IOLog("Can't add startup extensions from archive; "
1154 "kernel linker is not present.\n");
1158 IOLockUnlock(kld_lock
);
1160 copyData
->release();
1167 /*********************************************************************
1168 * This function clears out all references to the in-kernel linker,
1169 * frees the list of startup extensions in extensionDict, and
1170 * deallocates the kernel's __KLD segment to reclaim that memory.
1172 * The segments it operates on are strictly 32 bit segments.
1173 *********************************************************************/
1174 kern_return_t
IOCatalogue::removeKernelLinker(void) {
1175 kern_return_t result
= KERN_SUCCESS
;
1176 struct segment_command
* segment
;
1177 char * dt_segment_name
;
1178 void * segment_paddress
;
1181 /* This must be the very first thing done by this function.
1183 IOLockLock(kld_lock
);
1186 /* If the kernel linker isn't here, that's automatically
1189 if (!kernelLinkerPresent
) {
1190 result
= KERN_SUCCESS
;
1194 IOLog("Jettisoning kernel linker.\n");
1196 kernelLinkerPresent
= 0;
1198 /* Set the kmod_load_extension function as the means for loading
1199 * a kernel extension.
1201 kmod_load_function
= &kmod_load_extension
;
1203 record_startup_extensions_function
= 0;
1204 add_from_mkext_function
= 0;
1205 remove_startup_extension_function
= 0;
1208 /* Invoke destructors for the __KLD and __LINKEDIT segments.
1209 * Do this for all segments before actually freeing their
1210 * memory so that any cross-dependencies (not that there
1211 * should be any) are handled.
1213 segment
= getsegbyname("__KLD");
1215 IOLog("error removing kernel linker: can't find %s segment\n",
1217 result
= KERN_FAILURE
;
1220 OSRuntimeUnloadCPPForSegment(segment
);
1222 segment
= getsegbyname("__LINKEDIT");
1224 IOLog("error removing kernel linker: can't find %s segment\n",
1226 result
= KERN_FAILURE
;
1229 OSRuntimeUnloadCPPForSegment(segment
);
1232 /* Free the memory that was set up by bootx.
1234 dt_segment_name
= "Kernel-__KLD";
1235 if (0 == IODTGetLoaderInfo(dt_segment_name
, &segment_paddress
, &segment_size
)) {
1236 IODTFreeLoaderInfo(dt_segment_name
, (void *)segment_paddress
,
1240 dt_segment_name
= "Kernel-__LINKEDIT";
1241 if (0 == IODTGetLoaderInfo(dt_segment_name
, &segment_paddress
, &segment_size
)) {
1242 IODTFreeLoaderInfo(dt_segment_name
, (void *)segment_paddress
,
1246 struct section
* sect
;
1247 sect
= getsectbyname("__PRELINK", "__symtab");
1248 if (sect
&& sect
->addr
)
1251 virt
= ml_static_ptovirt(sect
->addr
);
1253 ml_static_mfree(virt
, sect
->size
);
1259 /* This must be the very last thing done before returning.
1261 IOLockUnlock(kld_lock
);
1266 /*********************************************************************
1267 * This function stops the catalogue from making kextd requests during
1269 *********************************************************************/
1270 void IOCatalogue::disableExternalLinker(void) {
1271 IOLockLock(gIOKLDLock
);
1272 /* If kmod_load_extension (the kextd requester function) is in use,
1273 * disable new module requests.
1275 if (kmod_load_function
== &kmod_load_extension
) {
1276 kmod_load_function
= NULL
;
1279 IOLockUnlock(gIOKLDLock
);