2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
26 * Copyright (c) 1998 Apple Computer, Inc. All rights reserved.
32 #include <IOKit/IODeviceTreeSupport.h>
33 #include <IOKit/IOService.h>
34 #include <libkern/c++/OSContainers.h>
35 #include <IOKit/IOCatalogue.h>
36 #include <libkern/c++/OSUnserialize.h>
38 #include <machine/machine_routines.h>
39 #include <mach/kmod.h>
40 #include <mach-o/mach_header.h>
41 #include <kern/host.h>
44 #include <IOKit/IOLib.h>
46 #include <IOKit/assert.h>
50 int IODTGetLoaderInfo( char *key
, void **infoAddr
, int *infoSize
);
51 extern void IODTFreeLoaderInfo( char *key
, void *infoAddr
, int infoSize
);
52 extern void OSRuntimeUnloadCPPForSegment(
53 struct segment_command
* segment
);
58 * At startup these function pointers are set to use the libsa in-kernel
59 * linker for recording and loading kmods. Once the root filesystem
60 * is available, the kmod_load_function pointer gets switched to point
61 * at the kmod_load_extension() function built into the kernel, and the
62 * others are set to zero. Those two functions must *always* be checked
63 * before being invoked.
66 kern_return_t (*kmod_load_function
)(char *extension_name
) =
68 bool (*record_startup_extensions_function
)(void) = 0;
69 bool (*add_from_mkext_function
)(OSData
* mkext
) = 0;
70 void (*remove_startup_extension_function
)(const char * name
) = 0;
75 * A few parts of IOCatalogue require knowledge of
76 * whether the in-kernel linker is present. This
77 * variable is set by libsa's bootstrap code.
79 int kernelLinkerPresent
= 0;
81 #define kModuleKey "CFBundleIdentifier"
83 #define super OSObject
84 OSDefineMetaClassAndStructors(IOCatalogue
, OSObject
)
88 IOCatalogue
* gIOCatalogue
;
89 const OSSymbol
* gIOClassKey
;
90 const OSSymbol
* gIOProbeScoreKey
;
91 const OSSymbol
* gIOModuleIdentifierKey
;
92 OSSet
* gIOCatalogModuleRequests
;
93 OSSet
* gIOCatalogCacheMisses
;
94 OSSet
* gIOCatalogROMMkexts
;
95 IOLock
* gIOCatalogLock
;
98 /*********************************************************************
99 *********************************************************************/
101 OSArray
* gIOPrelinkedModules
= 0;
103 extern "C" kern_return_t
104 kmod_create_internal(
108 extern "C" kern_return_t
109 kmod_destroy_internal(kmod_t id
);
111 extern "C" kern_return_t
116 mach_msg_type_number_t
*dataCount
);
118 extern "C" kern_return_t
kmod_retain(kmod_t id
);
119 extern "C" kern_return_t
kmod_release(kmod_t id
);
122 kern_return_t
start_prelink_module(UInt32 moduleIndex
)
124 kern_return_t kr
= KERN_SUCCESS
;
126 SInt32 count
, where
, end
;
128 SInt32 next
, lastDep
;
134 prelinkedModules
= gIOPrelinkedModules
;
136 togo
= IONew(UInt32
, prelinkedModules
->getCount());
137 togo
[0] = moduleIndex
;
140 for (next
= 0; next
< count
; next
++)
142 dict
= (OSDictionary
*) prelinkedModules
->getObject(togo
[next
]);
144 data
= OSDynamicCast(OSData
, dict
->getObject("OSBundlePrelink"));
147 // already started or no code
148 if (togo
[next
] == moduleIndex
)
155 prelink
= (UInt32
*) data
->getBytesNoCopy();
156 lastDep
= OSReadBigInt32(prelink
, 12);
157 for (SInt32 idx
= OSReadBigInt32(prelink
, 8); idx
< lastDep
; idx
+= sizeof(UInt32
))
159 UInt32 depIdx
= OSReadBigInt32(prelink
, idx
) - 1;
161 for (where
= next
+ 1;
162 (where
< count
) && (togo
[where
] > depIdx
);
167 if (togo
[where
] == depIdx
)
169 for (end
= count
; end
!= where
; end
--)
170 togo
[end
] = togo
[end
- 1];
173 togo
[where
] = depIdx
;
177 if (KERN_SUCCESS
!= kr
)
180 for (next
= (count
- 1); next
>= 0; next
--)
182 dict
= (OSDictionary
*) prelinkedModules
->getObject(togo
[next
]);
184 data
= OSDynamicCast(OSData
, dict
->getObject("OSBundlePrelink"));
187 prelink
= (UInt32
*) data
->getBytesNoCopy();
190 kmod_info_t
* kmod_info
= (kmod_info_t
*) OSReadBigInt32(prelink
, 0);
192 kr
= kmod_create_internal(kmod_info
, &id
);
193 if (KERN_SUCCESS
!= kr
)
196 lastDep
= OSReadBigInt32(prelink
, 12);
197 for (SInt32 idx
= OSReadBigInt32(prelink
, 8); idx
< lastDep
; idx
+= sizeof(UInt32
))
199 OSDictionary
* depDict
;
200 kmod_info_t
* depInfo
;
202 depDict
= (OSDictionary
*) prelinkedModules
->getObject(OSReadBigInt32(prelink
, idx
) - 1);
203 str
= OSDynamicCast(OSString
, depDict
->getObject(kModuleKey
));
204 depInfo
= kmod_lookupbyname_locked(str
->getCStringNoCopy());
207 kr
= kmod_retain(KMOD_PACK_IDS(id
, depInfo
->id
));
208 kfree((vm_offset_t
) depInfo
, sizeof(kmod_info_t
));
210 IOLog("%s: NO DEP %s\n", kmod_info
->name
, str
->getCStringNoCopy());
212 dict
->removeObject("OSBundlePrelink");
214 if (kmod_info
->start
)
215 kr
= kmod_start_or_stop(kmod_info
->id
, 1, 0, 0);
218 IODelete(togo
, UInt32
, prelinkedModules
->getCount());
223 /*********************************************************************
224 * This is a function that IOCatalogue calls in order to load a kmod.
225 *********************************************************************/
228 kern_return_t
kmod_load_from_cache_sym(const OSSymbol
* kmod_name
)
230 OSArray
* prelinkedModules
= gIOPrelinkedModules
;
231 kern_return_t result
= KERN_FAILURE
;
236 if (!gIOPrelinkedModules
)
240 (dict
= (OSDictionary
*) prelinkedModules
->getObject(idx
));
243 if ((ident
= dict
->getObject(kModuleKey
))
244 && kmod_name
->isEqualTo(ident
))
249 if (kernelLinkerPresent
&& dict
->getObject("OSBundleDefer"))
251 kmod_load_extension((char *) kmod_name
->getCStringNoCopy());
252 result
= kIOReturnOffline
;
255 result
= start_prelink_module(idx
);
261 extern "C" Boolean
kmod_load_request(const char * moduleName
, Boolean make_request
)
263 bool ret
, cacheMiss
= false;
265 const OSSymbol
* sym
= 0;
266 kmod_info_t
* kmod_info
;
271 /* To make sure this operation completes even if a bad extension needs
272 * to be removed, take the kld lock for this whole block, spanning the
273 * kmod_load_function() and remove_startup_extension_function() calls.
275 IOLockLock(gIOKLDLock
);
278 // Is the module already loaded?
279 ret
= (0 != (kmod_info
= kmod_lookupbyname_locked((char *)moduleName
)));
281 kfree((vm_offset_t
) kmod_info
, sizeof(kmod_info_t
));
284 sym
= OSSymbol::withCString(moduleName
);
290 kr
= kmod_load_from_cache_sym(sym
);
291 ret
= (kIOReturnSuccess
== kr
);
293 if (ret
|| !make_request
|| (kr
== kIOReturnOffline
))
296 // If the module hasn't been loaded, then load it.
297 if (!kmod_load_function
) {
298 IOLog("IOCatalogue: %s cannot be loaded "
299 "(kmod load function not set).\n",
304 kr
= kmod_load_function((char *)moduleName
);
306 if (ret
!= kIOReturnSuccess
) {
307 IOLog("IOCatalogue: %s cannot be loaded.\n", moduleName
);
309 /* If the extension couldn't be loaded this time,
310 * make it unavailable so that no more requests are
311 * made in vain. This also enables other matching
312 * extensions to have a chance.
314 if (kernelLinkerPresent
&& remove_startup_extension_function
) {
315 (*remove_startup_extension_function
)(moduleName
);
319 } else if (kernelLinkerPresent
) {
320 // If kern linker is here, the driver is actually loaded,
325 // kern linker isn't here, a request has been queued
326 // but the module isn't necessarily loaded yet, so stall.
332 IOLockUnlock(gIOKLDLock
);
336 IOLockLock(gIOCatalogLock
);
337 gIOCatalogModuleRequests
->setObject(sym
);
339 gIOCatalogCacheMisses
->setObject(sym
);
340 IOLockUnlock(gIOCatalogLock
);
346 extern "C" kern_return_t
kmod_unload_cache(void)
348 OSArray
* prelinkedModules
= gIOPrelinkedModules
;
349 kern_return_t result
= KERN_FAILURE
;
355 if (!gIOPrelinkedModules
)
358 IOLockLock(gIOKLDLock
);
360 (dict
= (OSDictionary
*) prelinkedModules
->getObject(idx
));
363 data
= OSDynamicCast(OSData
, dict
->getObject("OSBundlePrelink"));
366 prelink
= (UInt32
*) data
->getBytesNoCopy();
368 kmod_info_t
* kmod_info
= (kmod_info_t
*) OSReadBigInt32(prelink
, 0);
370 virt
= ml_static_ptovirt(kmod_info
->address
);
372 ml_static_mfree(virt
, kmod_info
->size
);
376 gIOPrelinkedModules
->release();
377 gIOPrelinkedModules
= 0;
379 IOLockUnlock(gIOKLDLock
);
384 extern "C" kern_return_t
kmod_load_from_cache(const char * kmod_name
)
387 const OSSymbol
* sym
= OSSymbol::withCStringNoCopy(kmod_name
);
391 kr
= kmod_load_from_cache_sym(sym
);
395 kr
= kIOReturnNoMemory
;
400 /*********************************************************************
401 *********************************************************************/
403 static void UniqueProperties( OSDictionary
* dict
)
407 data
= OSDynamicCast( OSString
, dict
->getObject( gIOClassKey
));
409 const OSSymbol
*classSymbol
= OSSymbol::withString(data
);
411 dict
->setObject( gIOClassKey
, (OSSymbol
*) classSymbol
);
412 classSymbol
->release();
415 data
= OSDynamicCast( OSString
, dict
->getObject( gIOMatchCategoryKey
));
417 const OSSymbol
*classSymbol
= OSSymbol::withString(data
);
419 dict
->setObject( gIOMatchCategoryKey
, (OSSymbol
*) classSymbol
);
420 classSymbol
->release();
424 void IOCatalogue::initialize( void )
427 OSString
* errorString
;
430 extern const char * gIOKernelConfigTables
;
432 array
= OSDynamicCast(OSArray
, OSUnserialize(gIOKernelConfigTables
, &errorString
));
433 if (!array
&& errorString
) {
434 IOLog("KernelConfigTables syntax error: %s\n",
435 errorString
->getCStringNoCopy());
436 errorString
->release();
439 gIOClassKey
= OSSymbol::withCStringNoCopy( kIOClassKey
);
440 gIOProbeScoreKey
= OSSymbol::withCStringNoCopy( kIOProbeScoreKey
);
441 gIOModuleIdentifierKey
= OSSymbol::withCStringNoCopy( kModuleKey
);
442 gIOCatalogModuleRequests
= OSSet::withCapacity(16);
443 gIOCatalogCacheMisses
= OSSet::withCapacity(16);
444 gIOCatalogROMMkexts
= OSSet::withCapacity(4);
446 assert( array
&& gIOClassKey
&& gIOProbeScoreKey
447 && gIOModuleIdentifierKey
&& gIOCatalogModuleRequests
);
449 gIOCatalogue
= new IOCatalogue
;
450 assert(gIOCatalogue
);
451 rc
= gIOCatalogue
->init(array
);
456 // Initialize the IOCatalog object.
457 bool IOCatalogue::init(OSArray
* initArray
)
459 IORegistryEntry
* entry
;
462 if ( !super::init() )
469 kernelTables
= OSCollectionIterator::withCollection( array
);
471 gIOCatalogLock
= IOLockAlloc();
472 gIOKLDLock
= IOLockAlloc();
474 lock
= gIOCatalogLock
;
475 kld_lock
= gIOKLDLock
;
477 kernelTables
->reset();
478 while( (dict
= (OSDictionary
*) kernelTables
->getNextObject())) {
479 UniqueProperties(dict
);
480 if( 0 == dict
->getObject( gIOClassKey
))
481 IOLog("Missing or bad \"%s\" key\n",
482 gIOClassKey
->getCStringNoCopy());
486 AbsoluteTime deadline
;
487 clock_interval_to_deadline( 1000, kMillisecondScale
);
488 thread_call_func_delayed( ping
, this, deadline
);
491 entry
= IORegistryEntry::getRegistryRoot();
493 entry
->setProperty(kIOCatalogueKey
, this);
498 // Release all resources used by IOCatalogue and deallocate.
499 // This will probably never be called.
500 void IOCatalogue::free( void )
506 kernelTables
->release();
513 static int hackLimit
;
515 enum { kDriversPerIter
= 4 };
517 void IOCatalogue::ping( thread_call_param_t arg
, thread_call_param_t
)
519 IOCatalogue
* self
= (IOCatalogue
*) arg
;
521 OSDictionary
* table
;
524 set
= OSOrderedSet::withCapacity( 1 );
526 IOLockLock( &self
->lock
);
528 for( newLimit
= 0; newLimit
< kDriversPerIter
; newLimit
++) {
529 table
= (OSDictionary
*) self
->array
->getObject(
530 hackLimit
+ newLimit
);
532 set
->setLastObject( table
);
534 OSSymbol
* sym
= (OSSymbol
*) table
->getObject( gIOClassKey
);
535 kprintf("enabling %s\n", sym
->getCStringNoCopy());
543 IOService::catalogNewDrivers( set
);
545 hackLimit
+= newLimit
;
548 IOLockUnlock( &self
->lock
);
550 if( kDriversPerIter
== newLimit
) {
551 AbsoluteTime deadline
;
552 clock_interval_to_deadline( 500, kMillisecondScale
);
553 thread_call_func_delayed( ping
, this, deadline
);
558 OSOrderedSet
* IOCatalogue::findDrivers( IOService
* service
,
559 SInt32
* generationCount
)
561 OSDictionary
* nextTable
;
565 set
= OSOrderedSet::withCapacity( 1, IOServiceOrdering
,
566 (void *)gIOProbeScoreKey
);
571 kernelTables
->reset();
576 while( (nextTable
= (OSDictionary
*) kernelTables
->getNextObject())) {
578 if( hackIndex
++ > hackLimit
)
581 imports
= OSDynamicCast( OSString
,
582 nextTable
->getObject( gIOProviderClassKey
));
583 if( imports
&& service
->metaCast( imports
))
584 set
->setObject( nextTable
);
587 *generationCount
= getGenerationCount();
589 IOLockUnlock( lock
);
594 // Is personality already in the catalog?
595 OSOrderedSet
* IOCatalogue::findDrivers( OSDictionary
* matching
,
596 SInt32
* generationCount
)
601 UniqueProperties(matching
);
603 set
= OSOrderedSet::withCapacity( 1, IOServiceOrdering
,
604 (void *)gIOProbeScoreKey
);
607 kernelTables
->reset();
608 while ( (dict
= (OSDictionary
*) kernelTables
->getNextObject()) ) {
610 /* This comparison must be done with only the keys in the
611 * "matching" dict to enable general searches.
613 if ( dict
->isEqualTo(matching
, matching
) )
614 set
->setObject(dict
);
616 *generationCount
= getGenerationCount();
617 IOLockUnlock( lock
);
622 // Add a new personality to the set if it has a unique IOResourceMatchKey value.
623 // XXX -- svail: This should be optimized.
624 // esb - There doesn't seem like any reason to do this - it causes problems
625 // esb - when there are more than one loadable driver matching on the same provider class
626 static void AddNewImports( OSOrderedSet
* set
, OSDictionary
* dict
)
628 set
->setObject(dict
);
631 // Add driver config tables to catalog and start matching process.
632 bool IOCatalogue::addDrivers(OSArray
* drivers
,
635 OSCollectionIterator
* iter
;
639 OSString
* moduleName
;
643 persons
= OSDynamicCast(OSArray
, drivers
);
647 iter
= OSCollectionIterator::withCollection( persons
);
651 set
= OSOrderedSet::withCapacity( 10, IOServiceOrdering
,
652 (void *)gIOProbeScoreKey
);
659 while ( (dict
= (OSDictionary
*) iter
->getNextObject()) )
661 if ((moduleName
= OSDynamicCast(OSString
, dict
->getObject("OSBundleModuleDemand"))))
663 IOLockUnlock( lock
);
664 ret
= kmod_load_request(moduleName
->getCStringNoCopy(), false);
672 UniqueProperties( dict
);
674 // Add driver personality to catalogue.
675 count
= array
->getCount();
677 OSDictionary
* driver
;
679 // Be sure not to double up on personalities.
680 driver
= (OSDictionary
*)array
->getObject(count
);
682 /* Unlike in other functions, this comparison must be exact!
683 * The catalogue must be able to contain personalities that
684 * are proper supersets of others.
685 * Do not compare just the properties present in one driver
686 * pesonality or the other.
688 if (dict
->isEqualTo(driver
))
695 ret
= array
->setObject( dict
);
699 AddNewImports( set
, dict
);
702 // Start device matching.
703 if (doNubMatching
&& (set
->getCount() > 0)) {
704 IOService::catalogNewDrivers( set
);
707 IOLockUnlock( lock
);
715 // Remove drivers from the catalog which match the
716 // properties in the matching dictionary.
717 bool IOCatalogue::removeDrivers( OSDictionary
* matching
,
720 OSCollectionIterator
* tables
;
728 set
= OSOrderedSet::withCapacity(10,
730 (void *)gIOProbeScoreKey
);
734 arrayCopy
= OSArray::withCapacity(100);
740 tables
= OSCollectionIterator::withCollection(arrayCopy
);
741 arrayCopy
->release();
747 UniqueProperties( matching
);
750 kernelTables
->reset();
751 arrayCopy
->merge(array
);
752 array
->flushCollection();
754 while ( (dict
= (OSDictionary
*)tables
->getNextObject()) ) {
756 /* This comparison must be done with only the keys in the
757 * "matching" dict to enable general searches.
759 if ( dict
->isEqualTo(matching
, matching
) ) {
760 AddNewImports( set
, dict
);
764 array
->setObject(dict
);
766 // Start device matching.
767 if ( doNubMatching
&& (set
->getCount() > 0) ) {
768 IOService::catalogNewDrivers(set
);
771 IOLockUnlock( lock
);
779 // Return the generation count.
780 SInt32
IOCatalogue::getGenerationCount( void ) const
782 return( generation
);
785 bool IOCatalogue::isModuleLoaded( OSString
* moduleName
) const
787 return isModuleLoaded(moduleName
->getCStringNoCopy());
790 bool IOCatalogue::isModuleLoaded( const char * moduleName
) const
792 return (kmod_load_request(moduleName
, true));
795 // Check to see if module has been loaded already.
796 bool IOCatalogue::isModuleLoaded( OSDictionary
* driver
) const
798 OSString
* moduleName
= NULL
;
803 moduleName
= OSDynamicCast(OSString
, driver
->getObject(gIOModuleIdentifierKey
));
805 return isModuleLoaded(moduleName
);
807 /* If a personality doesn't hold the "CFBundleIdentifier" key
808 * it is assumed to be an "in-kernel" driver.
813 // This function is called after a module has been loaded.
814 void IOCatalogue::moduleHasLoaded( OSString
* moduleName
)
818 dict
= OSDictionary::withCapacity(2);
819 dict
->setObject(gIOModuleIdentifierKey
, moduleName
);
824 void IOCatalogue::moduleHasLoaded( const char * moduleName
)
828 name
= OSString::withCString(moduleName
);
829 moduleHasLoaded(name
);
833 IOReturn
IOCatalogue::unloadModule( OSString
* moduleName
) const
835 kmod_info_t
* k_info
= 0;
839 ret
= kIOReturnBadArgument
;
841 name
= moduleName
->getCStringNoCopy();
842 k_info
= kmod_lookupbyname_locked((char *)name
);
843 if ( k_info
&& (k_info
->reference_count
< 1) ) {
845 !((ret
= k_info
->stop(k_info
, 0)) == kIOReturnSuccess
) ) {
847 kfree((vm_offset_t
) k_info
, sizeof(kmod_info_t
));
851 ret
= kmod_destroy(host_priv_self(), k_info
->id
);
856 kfree((vm_offset_t
) k_info
, sizeof(kmod_info_t
));
862 static IOReturn
_terminateDrivers( OSArray
* array
, OSDictionary
* matching
)
864 OSCollectionIterator
* tables
;
872 return kIOReturnBadArgument
;
874 ret
= kIOReturnSuccess
;
876 iter
= IORegistryIterator::iterateOver(gIOServicePlane
,
877 kIORegistryIterateRecursively
);
879 return kIOReturnNoMemory
;
881 UniqueProperties( matching
);
883 // terminate instances.
886 while( (service
= (IOService
*)iter
->getNextObject()) ) {
887 dict
= service
->getPropertyTable();
891 /* Terminate only for personalities that match the matching dictionary.
892 * This comparison must be done with only the keys in the
893 * "matching" dict to enable general matching.
895 if ( !dict
->isEqualTo(matching
, matching
) )
898 if ( !service
->terminate(kIOServiceRequired
|kIOServiceSynchronous
) ) {
899 ret
= kIOReturnUnsupported
;
903 } while( !service
&& !iter
->isValid());
906 // remove configs from catalog.
907 if ( ret
!= kIOReturnSuccess
)
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
= kIOReturnSuccess
;
946 ret
= _terminateDrivers(array
, matching
);
947 kernelTables
->reset();
948 IOLockUnlock( lock
);
953 IOReturn
IOCatalogue::terminateDriversForModule(
954 OSString
* moduleName
,
960 dict
= OSDictionary::withCapacity(1);
962 return kIOReturnNoMemory
;
964 dict
->setObject(gIOModuleIdentifierKey
, moduleName
);
968 ret
= _terminateDrivers(array
, dict
);
969 kernelTables
->reset();
971 // Unload the module itself.
972 if ( unload
&& ret
== kIOReturnSuccess
) {
973 // Do kmod stop first.
974 ret
= unloadModule(moduleName
);
977 IOLockUnlock( lock
);
984 IOReturn
IOCatalogue::terminateDriversForModule(
985 const char * moduleName
,
991 name
= OSString::withCString(moduleName
);
993 return kIOReturnNoMemory
;
995 ret
= terminateDriversForModule(name
, unload
);
1001 bool IOCatalogue::startMatching( OSDictionary
* matching
)
1003 OSDictionary
* dict
;
1009 set
= OSOrderedSet::withCapacity(10, IOServiceOrdering
,
1010 (void *)gIOProbeScoreKey
);
1015 kernelTables
->reset();
1017 while ( (dict
= (OSDictionary
*)kernelTables
->getNextObject()) ) {
1019 /* This comparison must be done with only the keys in the
1020 * "matching" dict to enable general matching.
1022 if ( dict
->isEqualTo(matching
, matching
) )
1023 AddNewImports(set
, dict
);
1025 // Start device matching.
1026 if ( set
->getCount() > 0 ) {
1027 IOService::catalogNewDrivers(set
);
1031 IOLockUnlock( lock
);
1038 void IOCatalogue::reset(void)
1040 IOLog("Resetting IOCatalogue.\n");
1043 bool IOCatalogue::serialize(OSSerialize
* s
) const
1052 ret
= array
->serialize(s
);
1054 IOLockUnlock( lock
);
1059 bool IOCatalogue::serializeData(IOOptionBits kind
, OSSerialize
* s
) const
1061 kern_return_t kr
= kIOReturnSuccess
;
1065 case kIOCatalogGetContents
:
1067 kr
= kIOReturnNoMemory
;
1070 case kIOCatalogGetModuleDemandList
:
1072 if (!gIOCatalogModuleRequests
->serialize(s
))
1073 kr
= kIOReturnNoMemory
;
1074 IOLockUnlock( lock
);
1077 case kIOCatalogGetCacheMissList
:
1079 if (!gIOCatalogCacheMisses
->serialize(s
))
1080 kr
= kIOReturnNoMemory
;
1081 IOLockUnlock( lock
);
1084 case kIOCatalogGetROMMkextList
:
1087 if (!gIOCatalogROMMkexts
|| !gIOCatalogROMMkexts
->getCount())
1088 kr
= kIOReturnNoResources
;
1089 else if (!gIOCatalogROMMkexts
->serialize(s
))
1090 kr
= kIOReturnNoMemory
;
1092 if (gIOCatalogROMMkexts
)
1094 gIOCatalogROMMkexts
->release();
1095 gIOCatalogROMMkexts
= 0;
1098 IOLockUnlock( lock
);
1102 kr
= kIOReturnBadArgument
;
1110 bool IOCatalogue::recordStartupExtensions(void) {
1111 bool result
= false;
1113 IOLockLock(kld_lock
);
1114 if (kernelLinkerPresent
&& record_startup_extensions_function
) {
1115 result
= (*record_startup_extensions_function
)();
1117 IOLog("Can't record startup extensions; "
1118 "kernel linker is not present.\n");
1121 IOLockUnlock(kld_lock
);
1127 /*********************************************************************
1128 *********************************************************************/
1129 bool IOCatalogue::addExtensionsFromArchive(OSData
* mkext
)
1132 bool result
= false;
1135 /* The mkext we've been handed (or the data it references) can go away,
1136 * so we need to make a local copy to keep around as long as it might
1139 copyData
= OSData::withData(mkext
);
1142 struct section
* infosect
;
1144 infosect
= getsectbyname("__PRELINK", "__info");
1145 prelinked
= (infosect
&& infosect
->addr
&& infosect
->size
);
1147 IOLockLock(kld_lock
);
1149 if (gIOCatalogROMMkexts
)
1150 gIOCatalogROMMkexts
->setObject(copyData
);
1154 } else if (kernelLinkerPresent
&& add_from_mkext_function
) {
1155 result
= (*add_from_mkext_function
)(copyData
);
1157 IOLog("Can't add startup extensions from archive; "
1158 "kernel linker is not present.\n");
1162 IOLockUnlock(kld_lock
);
1164 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.
1175 *********************************************************************/
1176 kern_return_t
IOCatalogue::removeKernelLinker(void) {
1177 kern_return_t result
= KERN_SUCCESS
;
1178 struct segment_command
* segment
;
1179 char * dt_segment_name
;
1180 void * segment_paddress
;
1183 /* This must be the very first thing done by this function.
1185 IOLockLock(kld_lock
);
1188 /* If the kernel linker isn't here, that's automatically
1191 if (!kernelLinkerPresent
) {
1192 result
= KERN_SUCCESS
;
1196 IOLog("Jettisoning kernel linker.\n");
1198 kernelLinkerPresent
= 0;
1200 /* Set the kmod_load_extension function as the means for loading
1201 * a kernel extension.
1203 kmod_load_function
= &kmod_load_extension
;
1205 record_startup_extensions_function
= 0;
1206 add_from_mkext_function
= 0;
1207 remove_startup_extension_function
= 0;
1210 /* Invoke destructors for the __KLD and __LINKEDIT segments.
1211 * Do this for all segments before actually freeing their
1212 * memory so that any cross-dependencies (not that there
1213 * should be any) are handled.
1215 segment
= getsegbyname("__KLD");
1217 IOLog("error removing kernel linker: can't find %s segment\n",
1219 result
= KERN_FAILURE
;
1222 OSRuntimeUnloadCPPForSegment(segment
);
1224 segment
= getsegbyname("__LINKEDIT");
1226 IOLog("error removing kernel linker: can't find %s segment\n",
1228 result
= KERN_FAILURE
;
1231 OSRuntimeUnloadCPPForSegment(segment
);
1234 /* Free the memory that was set up by bootx.
1236 dt_segment_name
= "Kernel-__KLD";
1237 if (0 == IODTGetLoaderInfo(dt_segment_name
, &segment_paddress
, &segment_size
)) {
1238 IODTFreeLoaderInfo(dt_segment_name
, (void *)segment_paddress
,
1242 dt_segment_name
= "Kernel-__LINKEDIT";
1243 if (0 == IODTGetLoaderInfo(dt_segment_name
, &segment_paddress
, &segment_size
)) {
1244 IODTFreeLoaderInfo(dt_segment_name
, (void *)segment_paddress
,
1248 struct section
* sect
;
1249 sect
= getsectbyname("__PRELINK", "__symtab");
1250 if (sect
&& sect
->addr
)
1253 virt
= ml_static_ptovirt(sect
->addr
);
1255 ml_static_mfree(virt
, sect
->size
);
1261 /* This must be the very last thing done before returning.
1263 IOLockUnlock(kld_lock
);