2 * Copyright (c) 1998-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_OSREFERENCE_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. The rights granted to you under the
10 * License may not be used to create, or enable the creation or
11 * redistribution of, unlawful or unlicensed copies of an Apple operating
12 * system, or to circumvent, violate, or enable the circumvention or
13 * violation of, any terms of an Apple operating system software license
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
20 * The Original Code and all software distributed under the License are
21 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
22 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
23 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
25 * Please see the License for the specific language governing rights and
26 * limitations under the License.
28 * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
31 * Copyright (c) 1998 Apple Computer, Inc. All rights reserved.
37 #include <IOKit/IODeviceTreeSupport.h>
38 #include <IOKit/IOService.h>
39 #include <libkern/c++/OSContainers.h>
40 #include <IOKit/IOCatalogue.h>
41 #include <libkern/c++/OSUnserialize.h>
43 #include <machine/machine_routines.h>
44 #include <mach/kmod.h>
45 #include <mach-o/mach_header.h>
46 #include <kern/host.h>
49 #include <IOKit/IOLib.h>
51 #include <IOKit/assert.h>
55 int IODTGetLoaderInfo( char *key
, void **infoAddr
, int *infoSize
);
56 extern void IODTFreeLoaderInfo( char *key
, void *infoAddr
, int infoSize
);
57 /* operates on 32 bit segments */
58 extern void OSRuntimeUnloadCPPForSegment(struct segment_command
* segment
);
63 * At startup these function pointers are set to use the libsa in-kernel
64 * linker for recording and loading kmods. Once the root filesystem
65 * is available, the kmod_load_function pointer gets switched to point
66 * at the kmod_load_extension() function built into the kernel, and the
67 * others are set to zero. Those two functions must *always* be checked
68 * before being invoked.
71 kern_return_t (*kmod_load_function
)(char *extension_name
) =
73 bool (*record_startup_extensions_function
)(void) = 0;
74 bool (*add_from_mkext_function
)(OSData
* mkext
) = 0;
75 void (*remove_startup_extension_function
)(const char * name
) = 0;
80 * A few parts of IOCatalogue require knowledge of
81 * whether the in-kernel linker is present. This
82 * variable is set by libsa's bootstrap code.
84 int kernelLinkerPresent
= 0;
86 #define kModuleKey "CFBundleIdentifier"
88 #define super OSObject
89 OSDefineMetaClassAndStructors(IOCatalogue
, OSObject
)
93 IOCatalogue
* gIOCatalogue
;
94 const OSSymbol
* gIOClassKey
;
95 const OSSymbol
* gIOProbeScoreKey
;
96 const OSSymbol
* gIOModuleIdentifierKey
;
97 OSSet
* gIOCatalogModuleRequests
;
98 OSSet
* gIOCatalogCacheMisses
;
99 OSSet
* gIOCatalogROMMkexts
;
100 IOLock
* gIOCatalogLock
;
103 /*********************************************************************
104 *********************************************************************/
106 OSArray
* gIOPrelinkedModules
= 0;
108 extern "C" kern_return_t
109 kmod_create_internal(
113 extern "C" kern_return_t
114 kmod_destroy_internal(kmod_t id
);
116 extern "C" kern_return_t
121 mach_msg_type_number_t
*dataCount
);
123 extern "C" kern_return_t
kmod_retain(kmod_t id
);
124 extern "C" kern_return_t
kmod_release(kmod_t id
);
127 kern_return_t
start_prelink_module(UInt32 moduleIndex
)
129 kern_return_t kr
= KERN_SUCCESS
;
131 SInt32 count
, where
, end
;
133 SInt32 next
, lastDep
;
139 prelinkedModules
= gIOPrelinkedModules
;
141 togo
= IONew(UInt32
, prelinkedModules
->getCount());
142 togo
[0] = moduleIndex
;
145 for (next
= 0; next
< count
; next
++)
147 dict
= (OSDictionary
*) prelinkedModules
->getObject(togo
[next
]);
149 data
= OSDynamicCast(OSData
, dict
->getObject("OSBundlePrelink"));
152 // already started or no code
153 if (togo
[next
] == moduleIndex
)
160 prelink
= (UInt32
*) data
->getBytesNoCopy();
161 lastDep
= OSReadBigInt32(prelink
, 12);
162 for (SInt32 idx
= OSReadBigInt32(prelink
, 8); idx
< lastDep
; idx
+= sizeof(UInt32
))
164 UInt32 depIdx
= OSReadBigInt32(prelink
, idx
) - 1;
166 for (where
= next
+ 1;
167 (where
< count
) && (togo
[where
] > depIdx
);
172 if (togo
[where
] == depIdx
)
174 for (end
= count
; end
!= where
; end
--)
175 togo
[end
] = togo
[end
- 1];
178 togo
[where
] = depIdx
;
182 if (KERN_SUCCESS
!= kr
)
185 for (next
= (count
- 1); next
>= 0; next
--)
187 dict
= (OSDictionary
*) prelinkedModules
->getObject(togo
[next
]);
189 data
= OSDynamicCast(OSData
, dict
->getObject("OSBundlePrelink"));
192 prelink
= (UInt32
*) data
->getBytesNoCopy();
195 kmod_info_t
* kmod_info
= (kmod_info_t
*) OSReadBigInt32(prelink
, 0);
197 kr
= kmod_create_internal(kmod_info
, &id
);
198 if (KERN_SUCCESS
!= kr
)
201 lastDep
= OSReadBigInt32(prelink
, 12);
202 for (SInt32 idx
= OSReadBigInt32(prelink
, 8); idx
< lastDep
; idx
+= sizeof(UInt32
))
204 OSDictionary
* depDict
;
205 kmod_info_t
* depInfo
;
207 depDict
= (OSDictionary
*) prelinkedModules
->getObject(OSReadBigInt32(prelink
, idx
) - 1);
208 str
= OSDynamicCast(OSString
, depDict
->getObject(kModuleKey
));
209 depInfo
= kmod_lookupbyname_locked(str
->getCStringNoCopy());
212 kr
= kmod_retain(KMOD_PACK_IDS(id
, depInfo
->id
));
213 kfree(depInfo
, sizeof(kmod_info_t
));
215 IOLog("%s: NO DEP %s\n", kmod_info
->name
, str
->getCStringNoCopy());
217 dict
->removeObject("OSBundlePrelink");
219 if (kmod_info
->start
)
220 kr
= kmod_start_or_stop(kmod_info
->id
, 1, 0, 0);
223 IODelete(togo
, UInt32
, prelinkedModules
->getCount());
228 /*********************************************************************
229 * This is a function that IOCatalogue calls in order to load a kmod.
230 *********************************************************************/
233 kern_return_t
kmod_load_from_cache_sym(const OSSymbol
* kmod_name
)
235 OSArray
* prelinkedModules
= gIOPrelinkedModules
;
236 kern_return_t result
= KERN_FAILURE
;
241 if (!gIOPrelinkedModules
)
245 (dict
= (OSDictionary
*) prelinkedModules
->getObject(idx
));
248 if ((ident
= dict
->getObject(kModuleKey
))
249 && kmod_name
->isEqualTo(ident
))
254 if (kernelLinkerPresent
&& dict
->getObject("OSBundleDefer"))
256 kmod_load_extension((char *) kmod_name
->getCStringNoCopy());
257 result
= kIOReturnOffline
;
260 result
= start_prelink_module(idx
);
266 extern "C" Boolean
kmod_load_request(const char * moduleName
, Boolean make_request
)
268 bool ret
, cacheMiss
= false;
270 const OSSymbol
* sym
= 0;
271 kmod_info_t
* kmod_info
;
276 /* To make sure this operation completes even if a bad extension needs
277 * to be removed, take the kld lock for this whole block, spanning the
278 * kmod_load_function() and remove_startup_extension_function() calls.
280 IOLockLock(gIOKLDLock
);
283 // Is the module already loaded?
284 ret
= (0 != (kmod_info
= kmod_lookupbyname_locked((char *)moduleName
)));
286 kfree(kmod_info
, sizeof(kmod_info_t
));
289 sym
= OSSymbol::withCString(moduleName
);
295 kr
= kmod_load_from_cache_sym(sym
);
296 ret
= (kIOReturnSuccess
== kr
);
298 if (ret
|| !make_request
|| (kr
== kIOReturnOffline
))
301 // If the module hasn't been loaded, then load it.
302 if (!kmod_load_function
) {
303 IOLog("IOCatalogue: %s cannot be loaded "
304 "(kmod load function not set).\n",
310 kr
= kmod_load_function((char *)moduleName
);
312 if (ret
!= kIOReturnSuccess
) {
313 IOLog("IOCatalogue: %s cannot be loaded.\n", moduleName
);
315 /* If the extension couldn't be loaded this time,
316 * make it unavailable so that no more requests are
317 * made in vain. This also enables other matching
318 * extensions to have a chance.
320 if (kernelLinkerPresent
&& remove_startup_extension_function
) {
321 (*remove_startup_extension_function
)(moduleName
);
325 } else if (kernelLinkerPresent
) {
326 // If kern linker is here, the driver is actually loaded,
331 // kern linker isn't here, a request has been queued
332 // but the module isn't necessarily loaded yet, so stall.
338 IOLockUnlock(gIOKLDLock
);
342 IOLockLock(gIOCatalogLock
);
343 gIOCatalogModuleRequests
->setObject(sym
);
345 gIOCatalogCacheMisses
->setObject(sym
);
346 IOLockUnlock(gIOCatalogLock
);
352 extern "C" kern_return_t
kmod_unload_cache(void)
354 OSArray
* prelinkedModules
= gIOPrelinkedModules
;
355 kern_return_t result
= KERN_FAILURE
;
361 if (!gIOPrelinkedModules
)
364 IOLockLock(gIOKLDLock
);
366 (dict
= (OSDictionary
*) prelinkedModules
->getObject(idx
));
369 data
= OSDynamicCast(OSData
, dict
->getObject("OSBundlePrelink"));
372 prelink
= (UInt32
*) data
->getBytesNoCopy();
374 kmod_info_t
* kmod_info
= (kmod_info_t
*) OSReadBigInt32(prelink
, 0);
376 virt
= ml_static_ptovirt(kmod_info
->address
);
378 ml_static_mfree(virt
, kmod_info
->size
);
382 gIOPrelinkedModules
->release();
383 gIOPrelinkedModules
= 0;
385 IOLockUnlock(gIOKLDLock
);
390 extern "C" kern_return_t
kmod_load_from_cache(const char * kmod_name
)
393 const OSSymbol
* sym
= OSSymbol::withCStringNoCopy(kmod_name
);
397 kr
= kmod_load_from_cache_sym(sym
);
401 kr
= kIOReturnNoMemory
;
406 /*********************************************************************
407 *********************************************************************/
409 static void UniqueProperties( OSDictionary
* dict
)
413 data
= OSDynamicCast( OSString
, dict
->getObject( gIOClassKey
));
415 const OSSymbol
*classSymbol
= OSSymbol::withString(data
);
417 dict
->setObject( gIOClassKey
, (OSSymbol
*) classSymbol
);
418 classSymbol
->release();
421 data
= OSDynamicCast( OSString
, dict
->getObject( gIOMatchCategoryKey
));
423 const OSSymbol
*classSymbol
= OSSymbol::withString(data
);
425 dict
->setObject( gIOMatchCategoryKey
, (OSSymbol
*) classSymbol
);
426 classSymbol
->release();
430 void IOCatalogue::initialize( void )
433 OSString
* errorString
;
436 extern const char * gIOKernelConfigTables
;
438 array
= OSDynamicCast(OSArray
, OSUnserialize(gIOKernelConfigTables
, &errorString
));
439 if (!array
&& errorString
) {
440 IOLog("KernelConfigTables syntax error: %s\n",
441 errorString
->getCStringNoCopy());
442 errorString
->release();
445 gIOClassKey
= OSSymbol::withCStringNoCopy( kIOClassKey
);
446 gIOProbeScoreKey
= OSSymbol::withCStringNoCopy( kIOProbeScoreKey
);
447 gIOModuleIdentifierKey
= OSSymbol::withCStringNoCopy( kModuleKey
);
448 gIOCatalogModuleRequests
= OSSet::withCapacity(16);
449 gIOCatalogCacheMisses
= OSSet::withCapacity(16);
450 gIOCatalogROMMkexts
= OSSet::withCapacity(4);
452 assert( array
&& gIOClassKey
&& gIOProbeScoreKey
453 && gIOModuleIdentifierKey
&& gIOCatalogModuleRequests
);
455 gIOCatalogue
= new IOCatalogue
;
456 assert(gIOCatalogue
);
457 rc
= gIOCatalogue
->init(array
);
462 // Initialize the IOCatalog object.
463 bool IOCatalogue::init(OSArray
* initArray
)
467 if ( !super::init() )
474 kernelTables
= OSCollectionIterator::withCollection( array
);
476 gIOCatalogLock
= IOLockAlloc();
477 gIOKLDLock
= IOLockAlloc();
479 lock
= gIOCatalogLock
;
480 kld_lock
= gIOKLDLock
;
482 kernelTables
->reset();
483 while( (dict
= (OSDictionary
*) kernelTables
->getNextObject())) {
484 UniqueProperties(dict
);
485 if( 0 == dict
->getObject( gIOClassKey
))
486 IOLog("Missing or bad \"%s\" key\n",
487 gIOClassKey
->getCStringNoCopy());
491 AbsoluteTime deadline
;
492 clock_interval_to_deadline( 1000, kMillisecondScale
);
493 thread_call_func_delayed( ping
, this, deadline
);
499 // Release all resources used by IOCatalogue and deallocate.
500 // This will probably never be called.
501 void IOCatalogue::free( void )
507 kernelTables
->release();
514 static int hackLimit
;
516 enum { kDriversPerIter
= 4 };
518 void IOCatalogue::ping( thread_call_param_t arg
, thread_call_param_t
)
520 IOCatalogue
* self
= (IOCatalogue
*) arg
;
522 OSDictionary
* table
;
525 set
= OSOrderedSet::withCapacity( 1 );
527 IOLockLock( &self
->lock
);
529 for( newLimit
= 0; newLimit
< kDriversPerIter
; newLimit
++) {
530 table
= (OSDictionary
*) self
->array
->getObject(
531 hackLimit
+ newLimit
);
533 set
->setLastObject( table
);
535 OSSymbol
* sym
= (OSSymbol
*) table
->getObject( gIOClassKey
);
536 kprintf("enabling %s\n", sym
->getCStringNoCopy());
544 IOService::catalogNewDrivers( set
);
546 hackLimit
+= newLimit
;
549 IOLockUnlock( &self
->lock
);
551 if( kDriversPerIter
== newLimit
) {
552 AbsoluteTime deadline
;
553 clock_interval_to_deadline( 500, kMillisecondScale
);
554 thread_call_func_delayed( ping
, this, deadline
);
559 OSOrderedSet
* IOCatalogue::findDrivers( IOService
* service
,
560 SInt32
* generationCount
)
562 OSDictionary
* nextTable
;
566 set
= OSOrderedSet::withCapacity( 1, IOServiceOrdering
,
567 (void *)gIOProbeScoreKey
);
572 kernelTables
->reset();
577 while( (nextTable
= (OSDictionary
*) kernelTables
->getNextObject())) {
579 if( hackIndex
++ > hackLimit
)
582 imports
= OSDynamicCast( OSString
,
583 nextTable
->getObject( gIOProviderClassKey
));
584 if( imports
&& service
->metaCast( imports
))
585 set
->setObject( nextTable
);
588 *generationCount
= getGenerationCount();
590 IOLockUnlock( lock
);
595 // Is personality already in the catalog?
596 OSOrderedSet
* IOCatalogue::findDrivers( OSDictionary
* matching
,
597 SInt32
* generationCount
)
602 UniqueProperties(matching
);
604 set
= OSOrderedSet::withCapacity( 1, IOServiceOrdering
,
605 (void *)gIOProbeScoreKey
);
608 kernelTables
->reset();
609 while ( (dict
= (OSDictionary
*) kernelTables
->getNextObject()) ) {
611 /* This comparison must be done with only the keys in the
612 * "matching" dict to enable general searches.
614 if ( dict
->isEqualTo(matching
, matching
) )
615 set
->setObject(dict
);
617 *generationCount
= getGenerationCount();
618 IOLockUnlock( lock
);
623 // Add a new personality to the set if it has a unique IOResourceMatchKey value.
624 // XXX -- svail: This should be optimized.
625 // esb - There doesn't seem like any reason to do this - it causes problems
626 // esb - when there are more than one loadable driver matching on the same provider class
627 static void AddNewImports( OSOrderedSet
* set
, OSDictionary
* dict
)
629 set
->setObject(dict
);
632 // Add driver config tables to catalog and start matching process.
633 bool IOCatalogue::addDrivers(OSArray
* drivers
,
636 OSCollectionIterator
* iter
;
640 OSString
* moduleName
;
644 persons
= OSDynamicCast(OSArray
, drivers
);
648 iter
= OSCollectionIterator::withCollection( persons
);
652 set
= OSOrderedSet::withCapacity( 10, IOServiceOrdering
,
653 (void *)gIOProbeScoreKey
);
660 while ( (dict
= (OSDictionary
*) iter
->getNextObject()) )
662 if ((moduleName
= OSDynamicCast(OSString
, dict
->getObject("OSBundleModuleDemand"))))
664 IOLockUnlock( lock
);
665 ret
= kmod_load_request(moduleName
->getCStringNoCopy(), false);
673 UniqueProperties( dict
);
675 // Add driver personality to catalogue.
676 count
= array
->getCount();
678 OSDictionary
* driver
;
680 // Be sure not to double up on personalities.
681 driver
= (OSDictionary
*)array
->getObject(count
);
683 /* Unlike in other functions, this comparison must be exact!
684 * The catalogue must be able to contain personalities that
685 * are proper supersets of others.
686 * Do not compare just the properties present in one driver
687 * pesonality or the other.
689 if (dict
->isEqualTo(driver
))
696 ret
= array
->setObject( dict
);
700 AddNewImports( set
, dict
);
703 // Start device matching.
704 if (doNubMatching
&& (set
->getCount() > 0)) {
705 IOService::catalogNewDrivers( set
);
708 IOLockUnlock( lock
);
716 // Remove drivers from the catalog which match the
717 // properties in the matching dictionary.
718 bool IOCatalogue::removeDrivers( OSDictionary
* matching
,
721 OSCollectionIterator
* tables
;
729 set
= OSOrderedSet::withCapacity(10,
731 (void *)gIOProbeScoreKey
);
735 arrayCopy
= OSArray::withCapacity(100);
741 tables
= OSCollectionIterator::withCollection(arrayCopy
);
742 arrayCopy
->release();
748 UniqueProperties( matching
);
751 kernelTables
->reset();
752 arrayCopy
->merge(array
);
753 array
->flushCollection();
755 while ( (dict
= (OSDictionary
*)tables
->getNextObject()) ) {
757 /* This comparison must be done with only the keys in the
758 * "matching" dict to enable general searches.
760 if ( dict
->isEqualTo(matching
, matching
) ) {
761 AddNewImports( set
, dict
);
765 array
->setObject(dict
);
767 // Start device matching.
768 if ( doNubMatching
&& (set
->getCount() > 0) ) {
769 IOService::catalogNewDrivers(set
);
772 IOLockUnlock( lock
);
780 // Return the generation count.
781 SInt32
IOCatalogue::getGenerationCount( void ) const
783 return( generation
);
786 bool IOCatalogue::isModuleLoaded( OSString
* moduleName
) const
788 return isModuleLoaded(moduleName
->getCStringNoCopy());
791 bool IOCatalogue::isModuleLoaded( const char * moduleName
) const
793 return (kmod_load_request(moduleName
, true));
796 // Check to see if module has been loaded already.
797 bool IOCatalogue::isModuleLoaded( OSDictionary
* driver
) const
799 OSString
* moduleName
= NULL
;
804 moduleName
= OSDynamicCast(OSString
, driver
->getObject(gIOModuleIdentifierKey
));
806 return isModuleLoaded(moduleName
);
808 /* If a personality doesn't hold the "CFBundleIdentifier" key
809 * it is assumed to be an "in-kernel" driver.
814 // This function is called after a module has been loaded.
815 void IOCatalogue::moduleHasLoaded( OSString
* moduleName
)
819 dict
= OSDictionary::withCapacity(2);
820 dict
->setObject(gIOModuleIdentifierKey
, moduleName
);
825 void IOCatalogue::moduleHasLoaded( const char * moduleName
)
829 name
= OSString::withCString(moduleName
);
830 moduleHasLoaded(name
);
834 IOReturn
IOCatalogue::unloadModule( OSString
* moduleName
) const
836 kmod_info_t
* k_info
= 0;
840 ret
= kIOReturnBadArgument
;
842 name
= moduleName
->getCStringNoCopy();
843 k_info
= kmod_lookupbyname_locked((char *)name
);
844 if ( k_info
&& (k_info
->reference_count
< 1) ) {
846 !((ret
= k_info
->stop(k_info
, 0)) == kIOReturnSuccess
) ) {
848 kfree(k_info
, sizeof(kmod_info_t
));
852 ret
= kmod_destroy(host_priv_self(), k_info
->id
);
857 kfree(k_info
, sizeof(kmod_info_t
));
863 static IOReturn
_terminateDrivers( OSDictionary
* matching
)
871 return kIOReturnBadArgument
;
873 ret
= kIOReturnSuccess
;
875 iter
= IORegistryIterator::iterateOver(gIOServicePlane
,
876 kIORegistryIterateRecursively
);
878 return kIOReturnNoMemory
;
880 UniqueProperties( matching
);
882 // terminate instances.
885 while( (service
= (IOService
*)iter
->getNextObject()) ) {
886 dict
= service
->getPropertyTable();
890 /* Terminate only for personalities that match the matching dictionary.
891 * This comparison must be done with only the keys in the
892 * "matching" dict to enable general matching.
894 if ( !dict
->isEqualTo(matching
, matching
) )
897 if ( !service
->terminate(kIOServiceRequired
|kIOServiceSynchronous
) ) {
898 ret
= kIOReturnUnsupported
;
902 } while( !service
&& !iter
->isValid());
908 static IOReturn
_removeDrivers( OSArray
* array
, OSDictionary
* matching
)
910 OSCollectionIterator
* tables
;
913 IOReturn ret
= kIOReturnSuccess
;
915 // remove configs from catalog.
917 arrayCopy
= OSArray::withCapacity(100);
919 return kIOReturnNoMemory
;
921 tables
= OSCollectionIterator::withCollection(arrayCopy
);
922 arrayCopy
->release();
924 return kIOReturnNoMemory
;
926 arrayCopy
->merge(array
);
927 array
->flushCollection();
929 while ( (dict
= (OSDictionary
*)tables
->getNextObject()) ) {
931 /* Remove from the catalogue's array any personalities
932 * that match the matching dictionary.
933 * This comparison must be done with only the keys in the
934 * "matching" dict to enable general matching.
936 if ( dict
->isEqualTo(matching
, matching
) )
939 array
->setObject(dict
);
947 IOReturn
IOCatalogue::terminateDrivers( OSDictionary
* matching
)
951 ret
= _terminateDrivers(matching
);
953 if (kIOReturnSuccess
== ret
)
954 ret
= _removeDrivers(array
, matching
);
955 kernelTables
->reset();
956 IOLockUnlock( lock
);
961 IOReturn
IOCatalogue::terminateDriversForModule(
962 OSString
* moduleName
,
968 dict
= OSDictionary::withCapacity(1);
970 return kIOReturnNoMemory
;
972 dict
->setObject(gIOModuleIdentifierKey
, moduleName
);
974 ret
= _terminateDrivers(dict
);
976 if (kIOReturnSuccess
== ret
)
977 ret
= _removeDrivers(array
, dict
);
978 kernelTables
->reset();
980 // Unload the module itself.
981 if ( unload
&& ret
== kIOReturnSuccess
) {
982 // Do kmod stop first.
983 ret
= unloadModule(moduleName
);
986 IOLockUnlock( lock
);
993 IOReturn
IOCatalogue::terminateDriversForModule(
994 const char * moduleName
,
1000 name
= OSString::withCString(moduleName
);
1002 return kIOReturnNoMemory
;
1004 ret
= terminateDriversForModule(name
, unload
);
1010 bool IOCatalogue::startMatching( OSDictionary
* matching
)
1012 OSDictionary
* dict
;
1018 set
= OSOrderedSet::withCapacity(10, IOServiceOrdering
,
1019 (void *)gIOProbeScoreKey
);
1024 kernelTables
->reset();
1026 while ( (dict
= (OSDictionary
*)kernelTables
->getNextObject()) ) {
1028 /* This comparison must be done with only the keys in the
1029 * "matching" dict to enable general matching.
1031 if ( dict
->isEqualTo(matching
, matching
) )
1032 AddNewImports(set
, dict
);
1034 // Start device matching.
1035 if ( set
->getCount() > 0 ) {
1036 IOService::catalogNewDrivers(set
);
1040 IOLockUnlock( lock
);
1047 void IOCatalogue::reset(void)
1049 IOLog("Resetting IOCatalogue.\n");
1052 bool IOCatalogue::serialize(OSSerialize
* s
) const
1057 return super::serialize(s
);
1060 bool IOCatalogue::serializeData(IOOptionBits kind
, OSSerialize
* s
) const
1062 kern_return_t kr
= kIOReturnSuccess
;
1066 case kIOCatalogGetContents
:
1068 kr
= kIOReturnNoMemory
;
1071 case kIOCatalogGetModuleDemandList
:
1073 if (!gIOCatalogModuleRequests
->serialize(s
))
1074 kr
= kIOReturnNoMemory
;
1075 IOLockUnlock( lock
);
1078 case kIOCatalogGetCacheMissList
:
1080 if (!gIOCatalogCacheMisses
->serialize(s
))
1081 kr
= kIOReturnNoMemory
;
1082 IOLockUnlock( lock
);
1085 case kIOCatalogGetROMMkextList
:
1088 if (!gIOCatalogROMMkexts
|| !gIOCatalogROMMkexts
->getCount())
1089 kr
= kIOReturnNoResources
;
1090 else if (!gIOCatalogROMMkexts
->serialize(s
))
1091 kr
= kIOReturnNoMemory
;
1093 if (gIOCatalogROMMkexts
)
1095 gIOCatalogROMMkexts
->release();
1096 gIOCatalogROMMkexts
= 0;
1099 IOLockUnlock( lock
);
1103 kr
= kIOReturnBadArgument
;
1111 bool IOCatalogue::recordStartupExtensions(void) {
1112 bool result
= false;
1114 IOLockLock(kld_lock
);
1115 if (kernelLinkerPresent
&& record_startup_extensions_function
) {
1116 result
= (*record_startup_extensions_function
)();
1118 IOLog("Can't record startup extensions; "
1119 "kernel linker is not present.\n");
1122 IOLockUnlock(kld_lock
);
1128 /*********************************************************************
1129 * This function operates on sections retrieved from the currently running
1130 * 32 bit mach kernel.
1131 *********************************************************************/
1132 bool IOCatalogue::addExtensionsFromArchive(OSData
* mkext
)
1135 bool result
= false;
1138 /* The mkext we've been handed (or the data it references) can go away,
1139 * so we need to make a local copy to keep around as long as it might
1142 copyData
= OSData::withData(mkext
);
1145 struct section
* infosect
;
1147 infosect
= getsectbyname("__PRELINK", "__info");
1148 prelinked
= (infosect
&& infosect
->addr
&& infosect
->size
);
1150 IOLockLock(kld_lock
);
1152 if (gIOCatalogROMMkexts
)
1153 gIOCatalogROMMkexts
->setObject(copyData
);
1157 } else if (kernelLinkerPresent
&& add_from_mkext_function
) {
1158 result
= (*add_from_mkext_function
)(copyData
);
1160 IOLog("Can't add startup extensions from archive; "
1161 "kernel linker is not present.\n");
1165 IOLockUnlock(kld_lock
);
1167 copyData
->release();
1174 /*********************************************************************
1175 * This function clears out all references to the in-kernel linker,
1176 * frees the list of startup extensions in extensionDict, and
1177 * deallocates the kernel's __KLD segment to reclaim that memory.
1179 * The segments it operates on are strictly 32 bit segments.
1180 *********************************************************************/
1181 kern_return_t
IOCatalogue::removeKernelLinker(void) {
1182 kern_return_t result
= KERN_SUCCESS
;
1183 struct segment_command
* segment
;
1184 char * dt_segment_name
;
1185 void * segment_paddress
;
1188 /* This must be the very first thing done by this function.
1190 IOLockLock(kld_lock
);
1193 /* If the kernel linker isn't here, that's automatically
1196 if (!kernelLinkerPresent
) {
1197 result
= KERN_SUCCESS
;
1201 IOLog("Jettisoning kernel linker.\n");
1203 kernelLinkerPresent
= 0;
1205 /* Set the kmod_load_extension function as the means for loading
1206 * a kernel extension.
1208 kmod_load_function
= &kmod_load_extension
;
1210 record_startup_extensions_function
= 0;
1211 add_from_mkext_function
= 0;
1212 remove_startup_extension_function
= 0;
1215 /* Invoke destructors for the __KLD and __LINKEDIT segments.
1216 * Do this for all segments before actually freeing their
1217 * memory so that any cross-dependencies (not that there
1218 * should be any) are handled.
1220 segment
= getsegbyname("__KLD");
1222 IOLog("error removing kernel linker: can't find %s segment\n",
1224 result
= KERN_FAILURE
;
1227 OSRuntimeUnloadCPPForSegment(segment
);
1229 segment
= getsegbyname("__LINKEDIT");
1231 IOLog("error removing kernel linker: can't find %s segment\n",
1233 result
= KERN_FAILURE
;
1236 OSRuntimeUnloadCPPForSegment(segment
);
1239 /* Free the memory that was set up by bootx.
1241 dt_segment_name
= "Kernel-__KLD";
1242 if (0 == IODTGetLoaderInfo(dt_segment_name
, &segment_paddress
, &segment_size
)) {
1243 IODTFreeLoaderInfo(dt_segment_name
, (void *)segment_paddress
,
1247 dt_segment_name
= "Kernel-__LINKEDIT";
1248 if (0 == IODTGetLoaderInfo(dt_segment_name
, &segment_paddress
, &segment_size
)) {
1249 IODTFreeLoaderInfo(dt_segment_name
, (void *)segment_paddress
,
1253 struct section
* sect
;
1254 sect
= getsectbyname("__PRELINK", "__symtab");
1255 if (sect
&& sect
->addr
)
1258 virt
= ml_static_ptovirt(sect
->addr
);
1260 ml_static_mfree(virt
, sect
->size
);
1266 /* This must be the very last thing done before returning.
1268 IOLockUnlock(kld_lock
);
1273 /*********************************************************************
1274 * This function stops the catalogue from making kextd requests during
1276 *********************************************************************/
1277 void IOCatalogue::disableExternalLinker(void) {
1278 IOLockLock(gIOKLDLock
);
1279 /* If kmod_load_extension (the kextd requester function) is in use,
1280 * disable new module requests.
1282 if (kmod_load_function
== &kmod_load_extension
) {
1283 kmod_load_function
= NULL
;
1286 IOLockUnlock(gIOKLDLock
);