2 * Copyright (c) 1998-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_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. 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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 * Copyright (c) 1998 Apple Computer, Inc. All rights reserved.
35 #include <IOKit/IODeviceTreeSupport.h>
36 #include <IOKit/IOService.h>
37 #include <libkern/c++/OSContainers.h>
38 #include <IOKit/IOCatalogue.h>
39 #include <libkern/c++/OSUnserialize.h>
41 #include <machine/machine_routines.h>
42 #include <mach/kmod.h>
43 #include <mach-o/mach_header.h>
44 #include <kern/host.h>
47 #include <IOKit/IOLib.h>
49 #include <IOKit/assert.h>
53 int IODTGetLoaderInfo( char *key
, void **infoAddr
, int *infoSize
);
54 extern void IODTFreeLoaderInfo( char *key
, void *infoAddr
, int infoSize
);
55 /* operates on 32 bit segments */
56 extern void OSRuntimeUnloadCPPForSegment(struct segment_command
* segment
);
61 * At startup these function pointers are set to use the libsa in-kernel
62 * linker for recording and loading kmods. Once the root filesystem
63 * is available, the kmod_load_function pointer gets switched to point
64 * at the kmod_load_extension() function built into the kernel, and the
65 * others are set to zero. Those two functions must *always* be checked
66 * before being invoked.
69 kern_return_t (*kmod_load_function
)(char *extension_name
) =
71 bool (*record_startup_extensions_function
)(void) = 0;
72 bool (*add_from_mkext_function
)(OSData
* mkext
) = 0;
73 void (*remove_startup_extension_function
)(const char * name
) = 0;
78 * A few parts of IOCatalogue require knowledge of
79 * whether the in-kernel linker is present. This
80 * variable is set by libsa's bootstrap code.
82 int kernelLinkerPresent
= 0;
84 #define kModuleKey "CFBundleIdentifier"
86 #define super OSObject
87 OSDefineMetaClassAndStructors(IOCatalogue
, OSObject
)
91 IOCatalogue
* gIOCatalogue
;
92 const OSSymbol
* gIOClassKey
;
93 const OSSymbol
* gIOProbeScoreKey
;
94 const OSSymbol
* gIOModuleIdentifierKey
;
95 OSSet
* gIOCatalogModuleRequests
;
96 OSSet
* gIOCatalogCacheMisses
;
97 OSSet
* gIOCatalogROMMkexts
;
98 IOLock
* gIOCatalogLock
;
101 /*********************************************************************
102 *********************************************************************/
104 OSArray
* gIOPrelinkedModules
= 0;
106 extern "C" kern_return_t
107 kmod_create_internal(
111 extern "C" kern_return_t
112 kmod_destroy_internal(kmod_t id
);
114 extern "C" kern_return_t
119 mach_msg_type_number_t
*dataCount
);
121 extern "C" kern_return_t
kmod_retain(kmod_t id
);
122 extern "C" kern_return_t
kmod_release(kmod_t id
);
125 kern_return_t
start_prelink_module(UInt32 moduleIndex
)
127 kern_return_t kr
= KERN_SUCCESS
;
129 SInt32 count
, where
, end
;
131 SInt32 next
, lastDep
;
137 prelinkedModules
= gIOPrelinkedModules
;
139 togo
= IONew(UInt32
, prelinkedModules
->getCount());
140 togo
[0] = moduleIndex
;
143 for (next
= 0; next
< count
; next
++)
145 dict
= (OSDictionary
*) prelinkedModules
->getObject(togo
[next
]);
147 data
= OSDynamicCast(OSData
, dict
->getObject("OSBundlePrelink"));
150 // already started or no code
151 if (togo
[next
] == moduleIndex
)
158 prelink
= (UInt32
*) data
->getBytesNoCopy();
159 lastDep
= OSReadBigInt32(prelink
, 12);
160 for (SInt32 idx
= OSReadBigInt32(prelink
, 8); idx
< lastDep
; idx
+= sizeof(UInt32
))
162 UInt32 depIdx
= OSReadBigInt32(prelink
, idx
) - 1;
164 for (where
= next
+ 1;
165 (where
< count
) && (togo
[where
] > depIdx
);
170 if (togo
[where
] == depIdx
)
172 for (end
= count
; end
!= where
; end
--)
173 togo
[end
] = togo
[end
- 1];
176 togo
[where
] = depIdx
;
180 if (KERN_SUCCESS
!= kr
)
183 for (next
= (count
- 1); next
>= 0; next
--)
185 dict
= (OSDictionary
*) prelinkedModules
->getObject(togo
[next
]);
187 data
= OSDynamicCast(OSData
, dict
->getObject("OSBundlePrelink"));
190 prelink
= (UInt32
*) data
->getBytesNoCopy();
193 kmod_info_t
* kmod_info
= (kmod_info_t
*) OSReadBigInt32(prelink
, 0);
195 kr
= kmod_create_internal(kmod_info
, &id
);
196 if (KERN_SUCCESS
!= kr
)
199 lastDep
= OSReadBigInt32(prelink
, 12);
200 for (SInt32 idx
= OSReadBigInt32(prelink
, 8); idx
< lastDep
; idx
+= sizeof(UInt32
))
202 OSDictionary
* depDict
;
203 kmod_info_t
* depInfo
;
205 depDict
= (OSDictionary
*) prelinkedModules
->getObject(OSReadBigInt32(prelink
, idx
) - 1);
206 str
= OSDynamicCast(OSString
, depDict
->getObject(kModuleKey
));
207 depInfo
= kmod_lookupbyname_locked(str
->getCStringNoCopy());
210 kr
= kmod_retain(KMOD_PACK_IDS(id
, depInfo
->id
));
211 kfree(depInfo
, sizeof(kmod_info_t
));
213 IOLog("%s: NO DEP %s\n", kmod_info
->name
, str
->getCStringNoCopy());
215 dict
->removeObject("OSBundlePrelink");
217 if (kmod_info
->start
)
218 kr
= kmod_start_or_stop(kmod_info
->id
, 1, 0, 0);
221 IODelete(togo
, UInt32
, prelinkedModules
->getCount());
226 /*********************************************************************
227 * This is a function that IOCatalogue calls in order to load a kmod.
228 *********************************************************************/
231 kern_return_t
kmod_load_from_cache_sym(const OSSymbol
* kmod_name
)
233 OSArray
* prelinkedModules
= gIOPrelinkedModules
;
234 kern_return_t result
= KERN_FAILURE
;
239 if (!gIOPrelinkedModules
)
243 (dict
= (OSDictionary
*) prelinkedModules
->getObject(idx
));
246 if ((ident
= dict
->getObject(kModuleKey
))
247 && kmod_name
->isEqualTo(ident
))
252 if (kernelLinkerPresent
&& dict
->getObject("OSBundleDefer"))
254 kmod_load_extension((char *) kmod_name
->getCStringNoCopy());
255 result
= kIOReturnOffline
;
258 result
= start_prelink_module(idx
);
264 extern "C" Boolean
kmod_load_request(const char * moduleName
, Boolean make_request
)
266 bool ret
, cacheMiss
= false;
268 const OSSymbol
* sym
= 0;
269 kmod_info_t
* kmod_info
;
274 /* To make sure this operation completes even if a bad extension needs
275 * to be removed, take the kld lock for this whole block, spanning the
276 * kmod_load_function() and remove_startup_extension_function() calls.
278 IOLockLock(gIOKLDLock
);
281 // Is the module already loaded?
282 ret
= (0 != (kmod_info
= kmod_lookupbyname_locked((char *)moduleName
)));
284 kfree(kmod_info
, sizeof(kmod_info_t
));
287 sym
= OSSymbol::withCString(moduleName
);
293 kr
= kmod_load_from_cache_sym(sym
);
294 ret
= (kIOReturnSuccess
== kr
);
296 if (ret
|| !make_request
|| (kr
== kIOReturnOffline
))
299 // If the module hasn't been loaded, then load it.
300 if (!kmod_load_function
) {
301 IOLog("IOCatalogue: %s cannot be loaded "
302 "(kmod load function not set).\n",
308 kr
= kmod_load_function((char *)moduleName
);
310 if (ret
!= kIOReturnSuccess
) {
311 IOLog("IOCatalogue: %s cannot be loaded.\n", moduleName
);
313 /* If the extension couldn't be loaded this time,
314 * make it unavailable so that no more requests are
315 * made in vain. This also enables other matching
316 * extensions to have a chance.
318 if (kernelLinkerPresent
&& remove_startup_extension_function
) {
319 (*remove_startup_extension_function
)(moduleName
);
323 } else if (kernelLinkerPresent
) {
324 // If kern linker is here, the driver is actually loaded,
329 // kern linker isn't here, a request has been queued
330 // but the module isn't necessarily loaded yet, so stall.
336 IOLockUnlock(gIOKLDLock
);
340 IOLockLock(gIOCatalogLock
);
341 gIOCatalogModuleRequests
->setObject(sym
);
343 gIOCatalogCacheMisses
->setObject(sym
);
344 IOLockUnlock(gIOCatalogLock
);
350 extern "C" kern_return_t
kmod_unload_cache(void)
352 OSArray
* prelinkedModules
= gIOPrelinkedModules
;
353 kern_return_t result
= KERN_FAILURE
;
359 if (!gIOPrelinkedModules
)
362 IOLockLock(gIOKLDLock
);
364 (dict
= (OSDictionary
*) prelinkedModules
->getObject(idx
));
367 data
= OSDynamicCast(OSData
, dict
->getObject("OSBundlePrelink"));
370 prelink
= (UInt32
*) data
->getBytesNoCopy();
372 kmod_info_t
* kmod_info
= (kmod_info_t
*) OSReadBigInt32(prelink
, 0);
374 virt
= ml_static_ptovirt(kmod_info
->address
);
376 ml_static_mfree(virt
, kmod_info
->size
);
380 gIOPrelinkedModules
->release();
381 gIOPrelinkedModules
= 0;
383 IOLockUnlock(gIOKLDLock
);
388 extern "C" kern_return_t
kmod_load_from_cache(const char * kmod_name
)
391 const OSSymbol
* sym
= OSSymbol::withCStringNoCopy(kmod_name
);
395 kr
= kmod_load_from_cache_sym(sym
);
399 kr
= kIOReturnNoMemory
;
404 /*********************************************************************
405 *********************************************************************/
407 static void UniqueProperties( OSDictionary
* dict
)
411 data
= OSDynamicCast( OSString
, dict
->getObject( gIOClassKey
));
413 const OSSymbol
*classSymbol
= OSSymbol::withString(data
);
415 dict
->setObject( gIOClassKey
, (OSSymbol
*) classSymbol
);
416 classSymbol
->release();
419 data
= OSDynamicCast( OSString
, dict
->getObject( gIOMatchCategoryKey
));
421 const OSSymbol
*classSymbol
= OSSymbol::withString(data
);
423 dict
->setObject( gIOMatchCategoryKey
, (OSSymbol
*) classSymbol
);
424 classSymbol
->release();
428 void IOCatalogue::initialize( void )
431 OSString
* errorString
;
434 extern const char * gIOKernelConfigTables
;
436 array
= OSDynamicCast(OSArray
, OSUnserialize(gIOKernelConfigTables
, &errorString
));
437 if (!array
&& errorString
) {
438 IOLog("KernelConfigTables syntax error: %s\n",
439 errorString
->getCStringNoCopy());
440 errorString
->release();
443 gIOClassKey
= OSSymbol::withCStringNoCopy( kIOClassKey
);
444 gIOProbeScoreKey
= OSSymbol::withCStringNoCopy( kIOProbeScoreKey
);
445 gIOModuleIdentifierKey
= OSSymbol::withCStringNoCopy( kModuleKey
);
446 gIOCatalogModuleRequests
= OSSet::withCapacity(16);
447 gIOCatalogCacheMisses
= OSSet::withCapacity(16);
448 gIOCatalogROMMkexts
= OSSet::withCapacity(4);
450 assert( array
&& gIOClassKey
&& gIOProbeScoreKey
451 && gIOModuleIdentifierKey
&& gIOCatalogModuleRequests
);
453 gIOCatalogue
= new IOCatalogue
;
454 assert(gIOCatalogue
);
455 rc
= gIOCatalogue
->init(array
);
460 // Initialize the IOCatalog object.
461 bool IOCatalogue::init(OSArray
* initArray
)
465 if ( !super::init() )
472 kernelTables
= OSCollectionIterator::withCollection( array
);
474 gIOCatalogLock
= IOLockAlloc();
475 gIOKLDLock
= IOLockAlloc();
477 lock
= gIOCatalogLock
;
478 kld_lock
= gIOKLDLock
;
480 kernelTables
->reset();
481 while( (dict
= (OSDictionary
*) kernelTables
->getNextObject())) {
482 UniqueProperties(dict
);
483 if( 0 == dict
->getObject( gIOClassKey
))
484 IOLog("Missing or bad \"%s\" key\n",
485 gIOClassKey
->getCStringNoCopy());
489 AbsoluteTime deadline
;
490 clock_interval_to_deadline( 1000, kMillisecondScale
);
491 thread_call_func_delayed( ping
, this, deadline
);
497 // Release all resources used by IOCatalogue and deallocate.
498 // This will probably never be called.
499 void IOCatalogue::free( void )
505 kernelTables
->release();
512 static int hackLimit
;
514 enum { kDriversPerIter
= 4 };
516 void IOCatalogue::ping( thread_call_param_t arg
, thread_call_param_t
)
518 IOCatalogue
* self
= (IOCatalogue
*) arg
;
520 OSDictionary
* table
;
523 set
= OSOrderedSet::withCapacity( 1 );
525 IOLockLock( &self
->lock
);
527 for( newLimit
= 0; newLimit
< kDriversPerIter
; newLimit
++) {
528 table
= (OSDictionary
*) self
->array
->getObject(
529 hackLimit
+ newLimit
);
531 set
->setLastObject( table
);
533 OSSymbol
* sym
= (OSSymbol
*) table
->getObject( gIOClassKey
);
534 kprintf("enabling %s\n", sym
->getCStringNoCopy());
542 IOService::catalogNewDrivers( set
);
544 hackLimit
+= newLimit
;
547 IOLockUnlock( &self
->lock
);
549 if( kDriversPerIter
== newLimit
) {
550 AbsoluteTime deadline
;
551 clock_interval_to_deadline( 500, kMillisecondScale
);
552 thread_call_func_delayed( ping
, this, deadline
);
557 OSOrderedSet
* IOCatalogue::findDrivers( IOService
* service
,
558 SInt32
* generationCount
)
560 OSDictionary
* nextTable
;
564 set
= OSOrderedSet::withCapacity( 1, IOServiceOrdering
,
565 (void *)gIOProbeScoreKey
);
570 kernelTables
->reset();
575 while( (nextTable
= (OSDictionary
*) kernelTables
->getNextObject())) {
577 if( hackIndex
++ > hackLimit
)
580 imports
= OSDynamicCast( OSString
,
581 nextTable
->getObject( gIOProviderClassKey
));
582 if( imports
&& service
->metaCast( imports
))
583 set
->setObject( nextTable
);
586 *generationCount
= getGenerationCount();
588 IOLockUnlock( lock
);
593 // Is personality already in the catalog?
594 OSOrderedSet
* IOCatalogue::findDrivers( OSDictionary
* matching
,
595 SInt32
* generationCount
)
600 UniqueProperties(matching
);
602 set
= OSOrderedSet::withCapacity( 1, IOServiceOrdering
,
603 (void *)gIOProbeScoreKey
);
606 kernelTables
->reset();
607 while ( (dict
= (OSDictionary
*) kernelTables
->getNextObject()) ) {
609 /* This comparison must be done with only the keys in the
610 * "matching" dict to enable general searches.
612 if ( dict
->isEqualTo(matching
, matching
) )
613 set
->setObject(dict
);
615 *generationCount
= getGenerationCount();
616 IOLockUnlock( lock
);
621 // Add a new personality to the set if it has a unique IOResourceMatchKey value.
622 // XXX -- svail: This should be optimized.
623 // esb - There doesn't seem like any reason to do this - it causes problems
624 // esb - when there are more than one loadable driver matching on the same provider class
625 static void AddNewImports( OSOrderedSet
* set
, OSDictionary
* dict
)
627 set
->setObject(dict
);
630 // Add driver config tables to catalog and start matching process.
631 bool IOCatalogue::addDrivers(OSArray
* drivers
,
634 OSCollectionIterator
* iter
;
638 OSString
* moduleName
;
642 persons
= OSDynamicCast(OSArray
, drivers
);
646 iter
= OSCollectionIterator::withCollection( persons
);
650 set
= OSOrderedSet::withCapacity( 10, IOServiceOrdering
,
651 (void *)gIOProbeScoreKey
);
658 while ( (dict
= (OSDictionary
*) iter
->getNextObject()) )
660 if ((moduleName
= OSDynamicCast(OSString
, dict
->getObject("OSBundleModuleDemand"))))
662 IOLockUnlock( lock
);
663 ret
= kmod_load_request(moduleName
->getCStringNoCopy(), false);
671 UniqueProperties( dict
);
673 // Add driver personality to catalogue.
674 count
= array
->getCount();
676 OSDictionary
* driver
;
678 // Be sure not to double up on personalities.
679 driver
= (OSDictionary
*)array
->getObject(count
);
681 /* Unlike in other functions, this comparison must be exact!
682 * The catalogue must be able to contain personalities that
683 * are proper supersets of others.
684 * Do not compare just the properties present in one driver
685 * pesonality or the other.
687 if (dict
->isEqualTo(driver
))
694 ret
= array
->setObject( dict
);
698 AddNewImports( set
, dict
);
701 // Start device matching.
702 if (doNubMatching
&& (set
->getCount() > 0)) {
703 IOService::catalogNewDrivers( set
);
706 IOLockUnlock( lock
);
714 // Remove drivers from the catalog which match the
715 // properties in the matching dictionary.
716 bool IOCatalogue::removeDrivers( OSDictionary
* matching
,
719 OSCollectionIterator
* tables
;
727 set
= OSOrderedSet::withCapacity(10,
729 (void *)gIOProbeScoreKey
);
733 arrayCopy
= OSArray::withCapacity(100);
739 tables
= OSCollectionIterator::withCollection(arrayCopy
);
740 arrayCopy
->release();
746 UniqueProperties( matching
);
749 kernelTables
->reset();
750 arrayCopy
->merge(array
);
751 array
->flushCollection();
753 while ( (dict
= (OSDictionary
*)tables
->getNextObject()) ) {
755 /* This comparison must be done with only the keys in the
756 * "matching" dict to enable general searches.
758 if ( dict
->isEqualTo(matching
, matching
) ) {
759 AddNewImports( set
, dict
);
763 array
->setObject(dict
);
765 // Start device matching.
766 if ( doNubMatching
&& (set
->getCount() > 0) ) {
767 IOService::catalogNewDrivers(set
);
770 IOLockUnlock( lock
);
778 // Return the generation count.
779 SInt32
IOCatalogue::getGenerationCount( void ) const
781 return( generation
);
784 bool IOCatalogue::isModuleLoaded( OSString
* moduleName
) const
786 return isModuleLoaded(moduleName
->getCStringNoCopy());
789 bool IOCatalogue::isModuleLoaded( const char * moduleName
) const
791 return (kmod_load_request(moduleName
, true));
794 // Check to see if module has been loaded already.
795 bool IOCatalogue::isModuleLoaded( OSDictionary
* driver
) const
797 OSString
* moduleName
= NULL
;
802 moduleName
= OSDynamicCast(OSString
, driver
->getObject(gIOModuleIdentifierKey
));
804 return isModuleLoaded(moduleName
);
806 /* If a personality doesn't hold the "CFBundleIdentifier" key
807 * it is assumed to be an "in-kernel" driver.
812 // This function is called after a module has been loaded.
813 void IOCatalogue::moduleHasLoaded( OSString
* moduleName
)
817 dict
= OSDictionary::withCapacity(2);
818 dict
->setObject(gIOModuleIdentifierKey
, moduleName
);
823 void IOCatalogue::moduleHasLoaded( const char * moduleName
)
827 name
= OSString::withCString(moduleName
);
828 moduleHasLoaded(name
);
832 IOReturn
IOCatalogue::unloadModule( OSString
* moduleName
) const
834 kmod_info_t
* k_info
= 0;
838 ret
= kIOReturnBadArgument
;
840 name
= moduleName
->getCStringNoCopy();
841 k_info
= kmod_lookupbyname_locked((char *)name
);
842 if ( k_info
&& (k_info
->reference_count
< 1) ) {
844 !((ret
= k_info
->stop(k_info
, 0)) == kIOReturnSuccess
) ) {
846 kfree(k_info
, sizeof(kmod_info_t
));
850 ret
= kmod_destroy(host_priv_self(), k_info
->id
);
855 kfree(k_info
, sizeof(kmod_info_t
));
861 static IOReturn
_terminateDrivers( OSDictionary
* matching
)
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());
906 static IOReturn
_removeDrivers( OSArray
* array
, OSDictionary
* matching
)
908 OSCollectionIterator
* tables
;
911 IOReturn ret
= kIOReturnSuccess
;
913 // remove configs from catalog.
915 arrayCopy
= OSArray::withCapacity(100);
917 return kIOReturnNoMemory
;
919 tables
= OSCollectionIterator::withCollection(arrayCopy
);
920 arrayCopy
->release();
922 return kIOReturnNoMemory
;
924 arrayCopy
->merge(array
);
925 array
->flushCollection();
927 while ( (dict
= (OSDictionary
*)tables
->getNextObject()) ) {
929 /* Remove from the catalogue's array any personalities
930 * that match the matching dictionary.
931 * This comparison must be done with only the keys in the
932 * "matching" dict to enable general matching.
934 if ( dict
->isEqualTo(matching
, matching
) )
937 array
->setObject(dict
);
945 IOReturn
IOCatalogue::terminateDrivers( OSDictionary
* matching
)
949 ret
= _terminateDrivers(matching
);
951 if (kIOReturnSuccess
== ret
)
952 ret
= _removeDrivers(array
, matching
);
953 kernelTables
->reset();
954 IOLockUnlock( lock
);
959 IOReturn
IOCatalogue::terminateDriversForModule(
960 OSString
* moduleName
,
966 dict
= OSDictionary::withCapacity(1);
968 return kIOReturnNoMemory
;
970 dict
->setObject(gIOModuleIdentifierKey
, moduleName
);
972 ret
= _terminateDrivers(dict
);
974 if (kIOReturnSuccess
== ret
)
975 ret
= _removeDrivers(array
, dict
);
976 kernelTables
->reset();
978 // Unload the module itself.
979 if ( unload
&& ret
== kIOReturnSuccess
) {
980 // Do kmod stop first.
981 ret
= unloadModule(moduleName
);
984 IOLockUnlock( lock
);
991 IOReturn
IOCatalogue::terminateDriversForModule(
992 const char * moduleName
,
998 name
= OSString::withCString(moduleName
);
1000 return kIOReturnNoMemory
;
1002 ret
= terminateDriversForModule(name
, unload
);
1008 bool IOCatalogue::startMatching( OSDictionary
* matching
)
1010 OSDictionary
* dict
;
1016 set
= OSOrderedSet::withCapacity(10, IOServiceOrdering
,
1017 (void *)gIOProbeScoreKey
);
1022 kernelTables
->reset();
1024 while ( (dict
= (OSDictionary
*)kernelTables
->getNextObject()) ) {
1026 /* This comparison must be done with only the keys in the
1027 * "matching" dict to enable general matching.
1029 if ( dict
->isEqualTo(matching
, matching
) )
1030 AddNewImports(set
, dict
);
1032 // Start device matching.
1033 if ( set
->getCount() > 0 ) {
1034 IOService::catalogNewDrivers(set
);
1038 IOLockUnlock( lock
);
1045 void IOCatalogue::reset(void)
1047 IOLog("Resetting IOCatalogue.\n");
1050 bool IOCatalogue::serialize(OSSerialize
* s
) const
1055 return super::serialize(s
);
1058 bool IOCatalogue::serializeData(IOOptionBits kind
, OSSerialize
* s
) const
1060 kern_return_t kr
= kIOReturnSuccess
;
1064 case kIOCatalogGetContents
:
1066 kr
= kIOReturnNoMemory
;
1069 case kIOCatalogGetModuleDemandList
:
1071 if (!gIOCatalogModuleRequests
->serialize(s
))
1072 kr
= kIOReturnNoMemory
;
1073 IOLockUnlock( lock
);
1076 case kIOCatalogGetCacheMissList
:
1078 if (!gIOCatalogCacheMisses
->serialize(s
))
1079 kr
= kIOReturnNoMemory
;
1080 IOLockUnlock( lock
);
1083 case kIOCatalogGetROMMkextList
:
1086 if (!gIOCatalogROMMkexts
|| !gIOCatalogROMMkexts
->getCount())
1087 kr
= kIOReturnNoResources
;
1088 else if (!gIOCatalogROMMkexts
->serialize(s
))
1089 kr
= kIOReturnNoMemory
;
1091 if (gIOCatalogROMMkexts
)
1093 gIOCatalogROMMkexts
->release();
1094 gIOCatalogROMMkexts
= 0;
1097 IOLockUnlock( lock
);
1101 kr
= kIOReturnBadArgument
;
1109 bool IOCatalogue::recordStartupExtensions(void) {
1110 bool result
= false;
1112 IOLockLock(kld_lock
);
1113 if (kernelLinkerPresent
&& record_startup_extensions_function
) {
1114 result
= (*record_startup_extensions_function
)();
1116 IOLog("Can't record startup extensions; "
1117 "kernel linker is not present.\n");
1120 IOLockUnlock(kld_lock
);
1126 /*********************************************************************
1127 * This function operates on sections retrieved from the currently running
1128 * 32 bit mach kernel.
1129 *********************************************************************/
1130 bool IOCatalogue::addExtensionsFromArchive(OSData
* mkext
)
1133 bool result
= false;
1136 /* The mkext we've been handed (or the data it references) can go away,
1137 * so we need to make a local copy to keep around as long as it might
1140 copyData
= OSData::withData(mkext
);
1143 struct section
* infosect
;
1145 infosect
= getsectbyname("__PRELINK", "__info");
1146 prelinked
= (infosect
&& infosect
->addr
&& infosect
->size
);
1148 IOLockLock(kld_lock
);
1150 if (gIOCatalogROMMkexts
)
1151 gIOCatalogROMMkexts
->setObject(copyData
);
1155 } else if (kernelLinkerPresent
&& add_from_mkext_function
) {
1156 result
= (*add_from_mkext_function
)(copyData
);
1158 IOLog("Can't add startup extensions from archive; "
1159 "kernel linker is not present.\n");
1163 IOLockUnlock(kld_lock
);
1165 copyData
->release();
1171 /*********************************************************************
1172 * This function clears out all references to the in-kernel linker,
1173 * frees the list of startup extensions in extensionDict, and
1174 * deallocates the kernel's __KLD segment to reclaim that memory.
1176 * The segments it operates on are strictly 32 bit segments.
1177 *********************************************************************/
1178 kern_return_t
IOCatalogue::removeKernelLinker(void) {
1179 kern_return_t result
= KERN_SUCCESS
;
1180 struct segment_command
* segmentLE
, *segmentKLD
;
1181 boolean_t keepsyms
= FALSE
;
1183 char * dt_segment_name
;
1184 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 PE_parse_boot_arg("keepsyms", &keepsyms
);
1203 IOLog("Jettisoning kernel linker.\n");
1205 kernelLinkerPresent
= 0;
1207 /* Set the kmod_load_extension function as the means for loading
1208 * a kernel extension.
1210 kmod_load_function
= &kmod_load_extension
;
1212 record_startup_extensions_function
= 0;
1213 add_from_mkext_function
= 0;
1214 remove_startup_extension_function
= 0;
1217 /* Invoke destructors for the __KLD and __LINKEDIT segments.
1218 * Do this for all segments before actually freeing their
1219 * memory so that any cross-dependencies (not that there
1220 * should be any) are handled.
1222 segmentKLD
= getsegbyname("__KLD");
1224 IOLog("error removing kernel linker: can't find %s segment\n",
1226 result
= KERN_FAILURE
;
1229 OSRuntimeUnloadCPPForSegment(segmentKLD
);
1231 segmentLE
= getsegbyname("__LINKEDIT");
1233 IOLog("error removing kernel linker: can't find %s segment\n",
1235 result
= KERN_FAILURE
;
1238 OSRuntimeUnloadCPPForSegment(segmentLE
);
1240 /* Free the memory that was set up by bootx.
1242 dt_segment_name
= "Kernel-__KLD";
1243 if (0 == IODTGetLoaderInfo(dt_segment_name
, &segment_paddress
, &segment_size
)) {
1244 IODTFreeLoaderInfo(dt_segment_name
, (void *)segment_paddress
,
1248 /* On x86, use the mapping data from the segment load command to
1249 * unload KLD and LINKEDIT directly, unless the keepsyms boot-arg
1250 * was enabled. This may invalidate any assumptions about
1251 * "avail_start" defining the lower bound for valid physical addresses.
1253 if (!keepsyms
&& segmentKLD
->vmaddr
&& segmentKLD
->vmsize
)
1254 ml_static_mfree(segmentKLD
->vmaddr
, segmentKLD
->vmsize
);
1259 dt_segment_name
= "Kernel-__LINKEDIT";
1260 if (0 == IODTGetLoaderInfo(dt_segment_name
, &segment_paddress
, &segment_size
)) {
1261 IODTFreeLoaderInfo(dt_segment_name
, (void *)segment_paddress
,
1265 if (!keepsyms
&& segmentLE
->vmaddr
&& segmentLE
->vmsize
)
1266 ml_static_mfree(segmentLE
->vmaddr
, segmentLE
->vmsize
);
1271 struct section
* sect
;
1272 sect
= getsectbyname("__PRELINK", "__symtab");
1273 if (sect
&& sect
->addr
)
1276 virt
= ml_static_ptovirt(sect
->addr
);
1278 ml_static_mfree(virt
, sect
->size
);
1284 /* This must be the very last thing done before returning.
1286 IOLockUnlock(kld_lock
);
1291 /*********************************************************************
1292 * This function stops the catalogue from making kextd requests during
1294 *********************************************************************/
1295 void IOCatalogue::disableExternalLinker(void) {
1296 IOLockLock(gIOKLDLock
);
1297 /* If kmod_load_extension (the kextd requester function) is in use,
1298 * disable new module requests.
1300 if (kmod_load_function
== &kmod_load_extension
) {
1301 kmod_load_function
= NULL
;
1304 IOLockUnlock(gIOKLDLock
);