2 * Copyright (c) 1998-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 * Copyright (c) 1998 Apple Computer, Inc. All rights reserved.
29 #include <IOKit/IODeviceTreeSupport.h>
30 #include <IOKit/IOService.h>
31 #include <libkern/c++/OSContainers.h>
32 #include <IOKit/IOCatalogue.h>
33 #include <libkern/c++/OSUnserialize.h>
35 #include <machine/machine_routines.h>
36 #include <mach/kmod.h>
37 #include <mach-o/mach_header.h>
38 #include <kern/host.h>
41 #include <IOKit/IOLib.h>
43 #include <IOKit/assert.h>
47 int IODTGetLoaderInfo( char *key
, void **infoAddr
, int *infoSize
);
48 extern void IODTFreeLoaderInfo( char *key
, void *infoAddr
, int infoSize
);
49 /* operates on 32 bit segments */
50 extern void OSRuntimeUnloadCPPForSegment(struct segment_command
* segment
);
55 * At startup these function pointers are set to use the libsa in-kernel
56 * linker for recording and loading kmods. Once the root filesystem
57 * is available, the kmod_load_function pointer gets switched to point
58 * at the kmod_load_extension() function built into the kernel, and the
59 * others are set to zero. Those two functions must *always* be checked
60 * before being invoked.
63 kern_return_t (*kmod_load_function
)(char *extension_name
) =
65 bool (*record_startup_extensions_function
)(void) = 0;
66 bool (*add_from_mkext_function
)(OSData
* mkext
) = 0;
67 void (*remove_startup_extension_function
)(const char * name
) = 0;
72 * A few parts of IOCatalogue require knowledge of
73 * whether the in-kernel linker is present. This
74 * variable is set by libsa's bootstrap code.
76 int kernelLinkerPresent
= 0;
78 #define kModuleKey "CFBundleIdentifier"
80 #define super OSObject
81 OSDefineMetaClassAndStructors(IOCatalogue
, OSObject
)
85 IOCatalogue
* gIOCatalogue
;
86 const OSSymbol
* gIOClassKey
;
87 const OSSymbol
* gIOProbeScoreKey
;
88 const OSSymbol
* gIOModuleIdentifierKey
;
89 OSSet
* gIOCatalogModuleRequests
;
90 OSSet
* gIOCatalogCacheMisses
;
91 OSSet
* gIOCatalogROMMkexts
;
92 IOLock
* gIOCatalogLock
;
95 /*********************************************************************
96 *********************************************************************/
98 OSArray
* gIOPrelinkedModules
= 0;
100 extern "C" kern_return_t
101 kmod_create_internal(
105 extern "C" kern_return_t
106 kmod_destroy_internal(kmod_t id
);
108 extern "C" kern_return_t
113 mach_msg_type_number_t
*dataCount
);
115 extern "C" kern_return_t
kmod_retain(kmod_t id
);
116 extern "C" kern_return_t
kmod_release(kmod_t id
);
119 kern_return_t
start_prelink_module(UInt32 moduleIndex
)
121 kern_return_t kr
= KERN_SUCCESS
;
123 SInt32 count
, where
, end
;
125 SInt32 next
, lastDep
;
131 prelinkedModules
= gIOPrelinkedModules
;
133 togo
= IONew(UInt32
, prelinkedModules
->getCount());
134 togo
[0] = moduleIndex
;
137 for (next
= 0; next
< count
; next
++)
139 dict
= (OSDictionary
*) prelinkedModules
->getObject(togo
[next
]);
141 data
= OSDynamicCast(OSData
, dict
->getObject("OSBundlePrelink"));
144 // already started or no code
145 if (togo
[next
] == moduleIndex
)
152 prelink
= (UInt32
*) data
->getBytesNoCopy();
153 lastDep
= OSReadBigInt32(prelink
, 12);
154 for (SInt32 idx
= OSReadBigInt32(prelink
, 8); idx
< lastDep
; idx
+= sizeof(UInt32
))
156 UInt32 depIdx
= OSReadBigInt32(prelink
, idx
) - 1;
158 for (where
= next
+ 1;
159 (where
< count
) && (togo
[where
] > depIdx
);
164 if (togo
[where
] == depIdx
)
166 for (end
= count
; end
!= where
; end
--)
167 togo
[end
] = togo
[end
- 1];
170 togo
[where
] = depIdx
;
174 if (KERN_SUCCESS
!= kr
)
177 for (next
= (count
- 1); next
>= 0; next
--)
179 dict
= (OSDictionary
*) prelinkedModules
->getObject(togo
[next
]);
181 data
= OSDynamicCast(OSData
, dict
->getObject("OSBundlePrelink"));
184 prelink
= (UInt32
*) data
->getBytesNoCopy();
187 kmod_info_t
* kmod_info
= (kmod_info_t
*) OSReadBigInt32(prelink
, 0);
189 kr
= kmod_create_internal(kmod_info
, &id
);
190 if (KERN_SUCCESS
!= kr
)
193 lastDep
= OSReadBigInt32(prelink
, 12);
194 for (SInt32 idx
= OSReadBigInt32(prelink
, 8); idx
< lastDep
; idx
+= sizeof(UInt32
))
196 OSDictionary
* depDict
;
197 kmod_info_t
* depInfo
;
199 depDict
= (OSDictionary
*) prelinkedModules
->getObject(OSReadBigInt32(prelink
, idx
) - 1);
200 str
= OSDynamicCast(OSString
, depDict
->getObject(kModuleKey
));
201 depInfo
= kmod_lookupbyname_locked(str
->getCStringNoCopy());
204 kr
= kmod_retain(KMOD_PACK_IDS(id
, depInfo
->id
));
205 kfree(depInfo
, sizeof(kmod_info_t
));
207 IOLog("%s: NO DEP %s\n", kmod_info
->name
, str
->getCStringNoCopy());
209 dict
->removeObject("OSBundlePrelink");
211 if (kmod_info
->start
)
212 kr
= kmod_start_or_stop(kmod_info
->id
, 1, 0, 0);
215 IODelete(togo
, UInt32
, prelinkedModules
->getCount());
220 /*********************************************************************
221 * This is a function that IOCatalogue calls in order to load a kmod.
222 *********************************************************************/
225 kern_return_t
kmod_load_from_cache_sym(const OSSymbol
* kmod_name
)
227 OSArray
* prelinkedModules
= gIOPrelinkedModules
;
228 kern_return_t result
= KERN_FAILURE
;
233 if (!gIOPrelinkedModules
)
237 (dict
= (OSDictionary
*) prelinkedModules
->getObject(idx
));
240 if ((ident
= dict
->getObject(kModuleKey
))
241 && kmod_name
->isEqualTo(ident
))
246 if (kernelLinkerPresent
&& dict
->getObject("OSBundleDefer"))
248 kmod_load_extension((char *) kmod_name
->getCStringNoCopy());
249 result
= kIOReturnOffline
;
252 result
= start_prelink_module(idx
);
258 extern "C" Boolean
kmod_load_request(const char * moduleName
, Boolean make_request
)
260 bool ret
, cacheMiss
= false;
262 const OSSymbol
* sym
= 0;
263 kmod_info_t
* kmod_info
;
268 /* To make sure this operation completes even if a bad extension needs
269 * to be removed, take the kld lock for this whole block, spanning the
270 * kmod_load_function() and remove_startup_extension_function() calls.
272 IOLockLock(gIOKLDLock
);
275 // Is the module already loaded?
276 ret
= (0 != (kmod_info
= kmod_lookupbyname_locked((char *)moduleName
)));
278 kfree(kmod_info
, sizeof(kmod_info_t
));
281 sym
= OSSymbol::withCString(moduleName
);
287 kr
= kmod_load_from_cache_sym(sym
);
288 ret
= (kIOReturnSuccess
== kr
);
290 if (ret
|| !make_request
|| (kr
== kIOReturnOffline
))
293 // If the module hasn't been loaded, then load it.
294 if (!kmod_load_function
) {
295 IOLog("IOCatalogue: %s cannot be loaded "
296 "(kmod load function not set).\n",
302 kr
= kmod_load_function((char *)moduleName
);
304 if (ret
!= kIOReturnSuccess
) {
305 IOLog("IOCatalogue: %s cannot be loaded.\n", moduleName
);
307 /* If the extension couldn't be loaded this time,
308 * make it unavailable so that no more requests are
309 * made in vain. This also enables other matching
310 * extensions to have a chance.
312 if (kernelLinkerPresent
&& remove_startup_extension_function
) {
313 (*remove_startup_extension_function
)(moduleName
);
317 } else if (kernelLinkerPresent
) {
318 // If kern linker is here, the driver is actually loaded,
323 // kern linker isn't here, a request has been queued
324 // but the module isn't necessarily loaded yet, so stall.
330 IOLockUnlock(gIOKLDLock
);
334 IOLockLock(gIOCatalogLock
);
335 gIOCatalogModuleRequests
->setObject(sym
);
337 gIOCatalogCacheMisses
->setObject(sym
);
338 IOLockUnlock(gIOCatalogLock
);
344 extern "C" kern_return_t
kmod_unload_cache(void)
346 OSArray
* prelinkedModules
= gIOPrelinkedModules
;
347 kern_return_t result
= KERN_FAILURE
;
353 if (!gIOPrelinkedModules
)
356 IOLockLock(gIOKLDLock
);
358 (dict
= (OSDictionary
*) prelinkedModules
->getObject(idx
));
361 data
= OSDynamicCast(OSData
, dict
->getObject("OSBundlePrelink"));
364 prelink
= (UInt32
*) data
->getBytesNoCopy();
366 kmod_info_t
* kmod_info
= (kmod_info_t
*) OSReadBigInt32(prelink
, 0);
368 virt
= ml_static_ptovirt(kmod_info
->address
);
370 ml_static_mfree(virt
, kmod_info
->size
);
374 gIOPrelinkedModules
->release();
375 gIOPrelinkedModules
= 0;
377 IOLockUnlock(gIOKLDLock
);
382 extern "C" kern_return_t
kmod_load_from_cache(const char * kmod_name
)
385 const OSSymbol
* sym
= OSSymbol::withCStringNoCopy(kmod_name
);
389 kr
= kmod_load_from_cache_sym(sym
);
393 kr
= kIOReturnNoMemory
;
398 /*********************************************************************
399 *********************************************************************/
401 static void UniqueProperties( OSDictionary
* dict
)
405 data
= OSDynamicCast( OSString
, dict
->getObject( gIOClassKey
));
407 const OSSymbol
*classSymbol
= OSSymbol::withString(data
);
409 dict
->setObject( gIOClassKey
, (OSSymbol
*) classSymbol
);
410 classSymbol
->release();
413 data
= OSDynamicCast( OSString
, dict
->getObject( gIOMatchCategoryKey
));
415 const OSSymbol
*classSymbol
= OSSymbol::withString(data
);
417 dict
->setObject( gIOMatchCategoryKey
, (OSSymbol
*) classSymbol
);
418 classSymbol
->release();
422 void IOCatalogue::initialize( void )
425 OSString
* errorString
;
428 extern const char * gIOKernelConfigTables
;
430 array
= OSDynamicCast(OSArray
, OSUnserialize(gIOKernelConfigTables
, &errorString
));
431 if (!array
&& errorString
) {
432 IOLog("KernelConfigTables syntax error: %s\n",
433 errorString
->getCStringNoCopy());
434 errorString
->release();
437 gIOClassKey
= OSSymbol::withCStringNoCopy( kIOClassKey
);
438 gIOProbeScoreKey
= OSSymbol::withCStringNoCopy( kIOProbeScoreKey
);
439 gIOModuleIdentifierKey
= OSSymbol::withCStringNoCopy( kModuleKey
);
440 gIOCatalogModuleRequests
= OSSet::withCapacity(16);
441 gIOCatalogCacheMisses
= OSSet::withCapacity(16);
442 gIOCatalogROMMkexts
= OSSet::withCapacity(4);
444 assert( array
&& gIOClassKey
&& gIOProbeScoreKey
445 && gIOModuleIdentifierKey
&& gIOCatalogModuleRequests
);
447 gIOCatalogue
= new IOCatalogue
;
448 assert(gIOCatalogue
);
449 rc
= gIOCatalogue
->init(array
);
454 // Initialize the IOCatalog object.
455 bool IOCatalogue::init(OSArray
* initArray
)
459 if ( !super::init() )
466 kernelTables
= OSCollectionIterator::withCollection( array
);
468 gIOCatalogLock
= IOLockAlloc();
469 gIOKLDLock
= IOLockAlloc();
471 lock
= gIOCatalogLock
;
472 kld_lock
= gIOKLDLock
;
474 kernelTables
->reset();
475 while( (dict
= (OSDictionary
*) kernelTables
->getNextObject())) {
476 UniqueProperties(dict
);
477 if( 0 == dict
->getObject( gIOClassKey
))
478 IOLog("Missing or bad \"%s\" key\n",
479 gIOClassKey
->getCStringNoCopy());
483 AbsoluteTime deadline
;
484 clock_interval_to_deadline( 1000, kMillisecondScale
);
485 thread_call_func_delayed( ping
, this, deadline
);
491 // Release all resources used by IOCatalogue and deallocate.
492 // This will probably never be called.
493 void IOCatalogue::free( void )
499 kernelTables
->release();
506 static int hackLimit
;
508 enum { kDriversPerIter
= 4 };
510 void IOCatalogue::ping( thread_call_param_t arg
, thread_call_param_t
)
512 IOCatalogue
* self
= (IOCatalogue
*) arg
;
514 OSDictionary
* table
;
517 set
= OSOrderedSet::withCapacity( 1 );
519 IOLockLock( &self
->lock
);
521 for( newLimit
= 0; newLimit
< kDriversPerIter
; newLimit
++) {
522 table
= (OSDictionary
*) self
->array
->getObject(
523 hackLimit
+ newLimit
);
525 set
->setLastObject( table
);
527 OSSymbol
* sym
= (OSSymbol
*) table
->getObject( gIOClassKey
);
528 kprintf("enabling %s\n", sym
->getCStringNoCopy());
536 IOService::catalogNewDrivers( set
);
538 hackLimit
+= newLimit
;
541 IOLockUnlock( &self
->lock
);
543 if( kDriversPerIter
== newLimit
) {
544 AbsoluteTime deadline
;
545 clock_interval_to_deadline( 500, kMillisecondScale
);
546 thread_call_func_delayed( ping
, this, deadline
);
551 OSOrderedSet
* IOCatalogue::findDrivers( IOService
* service
,
552 SInt32
* generationCount
)
554 OSDictionary
* nextTable
;
558 set
= OSOrderedSet::withCapacity( 1, IOServiceOrdering
,
559 (void *)gIOProbeScoreKey
);
564 kernelTables
->reset();
569 while( (nextTable
= (OSDictionary
*) kernelTables
->getNextObject())) {
571 if( hackIndex
++ > hackLimit
)
574 imports
= OSDynamicCast( OSString
,
575 nextTable
->getObject( gIOProviderClassKey
));
576 if( imports
&& service
->metaCast( imports
))
577 set
->setObject( nextTable
);
580 *generationCount
= getGenerationCount();
582 IOLockUnlock( lock
);
587 // Is personality already in the catalog?
588 OSOrderedSet
* IOCatalogue::findDrivers( OSDictionary
* matching
,
589 SInt32
* generationCount
)
594 UniqueProperties(matching
);
596 set
= OSOrderedSet::withCapacity( 1, IOServiceOrdering
,
597 (void *)gIOProbeScoreKey
);
600 kernelTables
->reset();
601 while ( (dict
= (OSDictionary
*) kernelTables
->getNextObject()) ) {
603 /* This comparison must be done with only the keys in the
604 * "matching" dict to enable general searches.
606 if ( dict
->isEqualTo(matching
, matching
) )
607 set
->setObject(dict
);
609 *generationCount
= getGenerationCount();
610 IOLockUnlock( lock
);
615 // Add a new personality to the set if it has a unique IOResourceMatchKey value.
616 // XXX -- svail: This should be optimized.
617 // esb - There doesn't seem like any reason to do this - it causes problems
618 // esb - when there are more than one loadable driver matching on the same provider class
619 static void AddNewImports( OSOrderedSet
* set
, OSDictionary
* dict
)
621 set
->setObject(dict
);
624 // Add driver config tables to catalog and start matching process.
625 bool IOCatalogue::addDrivers(OSArray
* drivers
,
628 OSCollectionIterator
* iter
;
632 OSString
* moduleName
;
636 persons
= OSDynamicCast(OSArray
, drivers
);
640 iter
= OSCollectionIterator::withCollection( persons
);
644 set
= OSOrderedSet::withCapacity( 10, IOServiceOrdering
,
645 (void *)gIOProbeScoreKey
);
652 while ( (dict
= (OSDictionary
*) iter
->getNextObject()) )
654 if ((moduleName
= OSDynamicCast(OSString
, dict
->getObject("OSBundleModuleDemand"))))
656 IOLockUnlock( lock
);
657 ret
= kmod_load_request(moduleName
->getCStringNoCopy(), false);
665 UniqueProperties( dict
);
667 // Add driver personality to catalogue.
668 count
= array
->getCount();
670 OSDictionary
* driver
;
672 // Be sure not to double up on personalities.
673 driver
= (OSDictionary
*)array
->getObject(count
);
675 /* Unlike in other functions, this comparison must be exact!
676 * The catalogue must be able to contain personalities that
677 * are proper supersets of others.
678 * Do not compare just the properties present in one driver
679 * pesonality or the other.
681 if (dict
->isEqualTo(driver
))
688 ret
= array
->setObject( dict
);
692 AddNewImports( set
, dict
);
695 // Start device matching.
696 if (doNubMatching
&& (set
->getCount() > 0)) {
697 IOService::catalogNewDrivers( set
);
700 IOLockUnlock( lock
);
708 // Remove drivers from the catalog which match the
709 // properties in the matching dictionary.
710 bool IOCatalogue::removeDrivers( OSDictionary
* matching
,
713 OSCollectionIterator
* tables
;
721 set
= OSOrderedSet::withCapacity(10,
723 (void *)gIOProbeScoreKey
);
727 arrayCopy
= OSArray::withCapacity(100);
733 tables
= OSCollectionIterator::withCollection(arrayCopy
);
734 arrayCopy
->release();
740 UniqueProperties( matching
);
743 kernelTables
->reset();
744 arrayCopy
->merge(array
);
745 array
->flushCollection();
747 while ( (dict
= (OSDictionary
*)tables
->getNextObject()) ) {
749 /* This comparison must be done with only the keys in the
750 * "matching" dict to enable general searches.
752 if ( dict
->isEqualTo(matching
, matching
) ) {
753 AddNewImports( set
, dict
);
757 array
->setObject(dict
);
759 // Start device matching.
760 if ( doNubMatching
&& (set
->getCount() > 0) ) {
761 IOService::catalogNewDrivers(set
);
764 IOLockUnlock( lock
);
772 // Return the generation count.
773 SInt32
IOCatalogue::getGenerationCount( void ) const
775 return( generation
);
778 bool IOCatalogue::isModuleLoaded( OSString
* moduleName
) const
780 return isModuleLoaded(moduleName
->getCStringNoCopy());
783 bool IOCatalogue::isModuleLoaded( const char * moduleName
) const
785 return (kmod_load_request(moduleName
, true));
788 // Check to see if module has been loaded already.
789 bool IOCatalogue::isModuleLoaded( OSDictionary
* driver
) const
791 OSString
* moduleName
= NULL
;
796 moduleName
= OSDynamicCast(OSString
, driver
->getObject(gIOModuleIdentifierKey
));
798 return isModuleLoaded(moduleName
);
800 /* If a personality doesn't hold the "CFBundleIdentifier" key
801 * it is assumed to be an "in-kernel" driver.
806 // This function is called after a module has been loaded.
807 void IOCatalogue::moduleHasLoaded( OSString
* moduleName
)
811 dict
= OSDictionary::withCapacity(2);
812 dict
->setObject(gIOModuleIdentifierKey
, moduleName
);
817 void IOCatalogue::moduleHasLoaded( const char * moduleName
)
821 name
= OSString::withCString(moduleName
);
822 moduleHasLoaded(name
);
826 IOReturn
IOCatalogue::unloadModule( OSString
* moduleName
) const
828 kmod_info_t
* k_info
= 0;
832 ret
= kIOReturnBadArgument
;
834 name
= moduleName
->getCStringNoCopy();
835 k_info
= kmod_lookupbyname_locked((char *)name
);
836 if ( k_info
&& (k_info
->reference_count
< 1) ) {
838 !((ret
= k_info
->stop(k_info
, 0)) == kIOReturnSuccess
) ) {
840 kfree(k_info
, sizeof(kmod_info_t
));
844 ret
= kmod_destroy(host_priv_self(), k_info
->id
);
849 kfree(k_info
, sizeof(kmod_info_t
));
855 static IOReturn
_terminateDrivers( OSDictionary
* matching
)
863 return kIOReturnBadArgument
;
865 ret
= kIOReturnSuccess
;
867 iter
= IORegistryIterator::iterateOver(gIOServicePlane
,
868 kIORegistryIterateRecursively
);
870 return kIOReturnNoMemory
;
872 UniqueProperties( matching
);
874 // terminate instances.
877 while( (service
= (IOService
*)iter
->getNextObject()) ) {
878 dict
= service
->getPropertyTable();
882 /* Terminate only for personalities that match the matching dictionary.
883 * This comparison must be done with only the keys in the
884 * "matching" dict to enable general matching.
886 if ( !dict
->isEqualTo(matching
, matching
) )
889 if ( !service
->terminate(kIOServiceRequired
|kIOServiceSynchronous
) ) {
890 ret
= kIOReturnUnsupported
;
894 } while( !service
&& !iter
->isValid());
900 static IOReturn
_removeDrivers( OSArray
* array
, OSDictionary
* matching
)
902 OSCollectionIterator
* tables
;
905 IOReturn ret
= kIOReturnSuccess
;
907 // remove configs from catalog.
909 arrayCopy
= OSArray::withCapacity(100);
911 return kIOReturnNoMemory
;
913 tables
= OSCollectionIterator::withCollection(arrayCopy
);
914 arrayCopy
->release();
916 return kIOReturnNoMemory
;
918 arrayCopy
->merge(array
);
919 array
->flushCollection();
921 while ( (dict
= (OSDictionary
*)tables
->getNextObject()) ) {
923 /* Remove from the catalogue's array any personalities
924 * that match the matching dictionary.
925 * This comparison must be done with only the keys in the
926 * "matching" dict to enable general matching.
928 if ( dict
->isEqualTo(matching
, matching
) )
931 array
->setObject(dict
);
939 IOReturn
IOCatalogue::terminateDrivers( OSDictionary
* matching
)
943 ret
= _terminateDrivers(matching
);
945 if (kIOReturnSuccess
== ret
)
946 ret
= _removeDrivers(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
);
966 ret
= _terminateDrivers(dict
);
968 if (kIOReturnSuccess
== ret
)
969 ret
= _removeDrivers(array
, dict
);
970 kernelTables
->reset();
972 // Unload the module itself.
973 if ( unload
&& ret
== kIOReturnSuccess
) {
974 // Do kmod stop first.
975 ret
= unloadModule(moduleName
);
978 IOLockUnlock( lock
);
985 IOReturn
IOCatalogue::terminateDriversForModule(
986 const char * moduleName
,
992 name
= OSString::withCString(moduleName
);
994 return kIOReturnNoMemory
;
996 ret
= terminateDriversForModule(name
, unload
);
1002 bool IOCatalogue::startMatching( OSDictionary
* matching
)
1004 OSDictionary
* dict
;
1010 set
= OSOrderedSet::withCapacity(10, IOServiceOrdering
,
1011 (void *)gIOProbeScoreKey
);
1016 kernelTables
->reset();
1018 while ( (dict
= (OSDictionary
*)kernelTables
->getNextObject()) ) {
1020 /* This comparison must be done with only the keys in the
1021 * "matching" dict to enable general matching.
1023 if ( dict
->isEqualTo(matching
, matching
) )
1024 AddNewImports(set
, dict
);
1026 // Start device matching.
1027 if ( set
->getCount() > 0 ) {
1028 IOService::catalogNewDrivers(set
);
1032 IOLockUnlock( lock
);
1039 void IOCatalogue::reset(void)
1041 IOLog("Resetting IOCatalogue.\n");
1044 bool IOCatalogue::serialize(OSSerialize
* s
) const
1049 return super::serialize(s
);
1052 bool IOCatalogue::serializeData(IOOptionBits kind
, OSSerialize
* s
) const
1054 kern_return_t kr
= kIOReturnSuccess
;
1058 case kIOCatalogGetContents
:
1060 kr
= kIOReturnNoMemory
;
1063 case kIOCatalogGetModuleDemandList
:
1065 if (!gIOCatalogModuleRequests
->serialize(s
))
1066 kr
= kIOReturnNoMemory
;
1067 IOLockUnlock( lock
);
1070 case kIOCatalogGetCacheMissList
:
1072 if (!gIOCatalogCacheMisses
->serialize(s
))
1073 kr
= kIOReturnNoMemory
;
1074 IOLockUnlock( lock
);
1077 case kIOCatalogGetROMMkextList
:
1080 if (!gIOCatalogROMMkexts
|| !gIOCatalogROMMkexts
->getCount())
1081 kr
= kIOReturnNoResources
;
1082 else if (!gIOCatalogROMMkexts
->serialize(s
))
1083 kr
= kIOReturnNoMemory
;
1085 if (gIOCatalogROMMkexts
)
1087 gIOCatalogROMMkexts
->release();
1088 gIOCatalogROMMkexts
= 0;
1091 IOLockUnlock( lock
);
1095 kr
= kIOReturnBadArgument
;
1103 bool IOCatalogue::recordStartupExtensions(void) {
1104 bool result
= false;
1106 IOLockLock(kld_lock
);
1107 if (kernelLinkerPresent
&& record_startup_extensions_function
) {
1108 result
= (*record_startup_extensions_function
)();
1110 IOLog("Can't record startup extensions; "
1111 "kernel linker is not present.\n");
1114 IOLockUnlock(kld_lock
);
1120 /*********************************************************************
1121 * This function operates on sections retrieved from the currently running
1122 * 32 bit mach kernel.
1123 *********************************************************************/
1124 bool IOCatalogue::addExtensionsFromArchive(OSData
* mkext
)
1127 bool result
= false;
1130 /* The mkext we've been handed (or the data it references) can go away,
1131 * so we need to make a local copy to keep around as long as it might
1134 copyData
= OSData::withData(mkext
);
1137 struct section
* infosect
;
1139 infosect
= getsectbyname("__PRELINK", "__info");
1140 prelinked
= (infosect
&& infosect
->addr
&& infosect
->size
);
1142 IOLockLock(kld_lock
);
1144 if (gIOCatalogROMMkexts
)
1145 gIOCatalogROMMkexts
->setObject(copyData
);
1149 } else if (kernelLinkerPresent
&& add_from_mkext_function
) {
1150 result
= (*add_from_mkext_function
)(copyData
);
1152 IOLog("Can't add startup extensions from archive; "
1153 "kernel linker is not present.\n");
1157 IOLockUnlock(kld_lock
);
1159 copyData
->release();
1166 /*********************************************************************
1167 * This function clears out all references to the in-kernel linker,
1168 * frees the list of startup extensions in extensionDict, and
1169 * deallocates the kernel's __KLD segment to reclaim that memory.
1171 * The segments it operates on are strictly 32 bit segments.
1172 *********************************************************************/
1173 kern_return_t
IOCatalogue::removeKernelLinker(void) {
1174 kern_return_t result
= KERN_SUCCESS
;
1175 struct segment_command
* segment
;
1176 char * dt_segment_name
;
1177 void * segment_paddress
;
1180 /* This must be the very first thing done by this function.
1182 IOLockLock(kld_lock
);
1185 /* If the kernel linker isn't here, that's automatically
1188 if (!kernelLinkerPresent
) {
1189 result
= KERN_SUCCESS
;
1193 IOLog("Jettisoning kernel linker.\n");
1195 kernelLinkerPresent
= 0;
1197 /* Set the kmod_load_extension function as the means for loading
1198 * a kernel extension.
1200 kmod_load_function
= &kmod_load_extension
;
1202 record_startup_extensions_function
= 0;
1203 add_from_mkext_function
= 0;
1204 remove_startup_extension_function
= 0;
1207 /* Invoke destructors for the __KLD and __LINKEDIT segments.
1208 * Do this for all segments before actually freeing their
1209 * memory so that any cross-dependencies (not that there
1210 * should be any) are handled.
1212 segment
= getsegbyname("__KLD");
1214 IOLog("error removing kernel linker: can't find %s segment\n",
1216 result
= KERN_FAILURE
;
1219 OSRuntimeUnloadCPPForSegment(segment
);
1221 segment
= getsegbyname("__LINKEDIT");
1223 IOLog("error removing kernel linker: can't find %s segment\n",
1225 result
= KERN_FAILURE
;
1228 OSRuntimeUnloadCPPForSegment(segment
);
1231 /* Free the memory that was set up by bootx.
1233 dt_segment_name
= "Kernel-__KLD";
1234 if (0 == IODTGetLoaderInfo(dt_segment_name
, &segment_paddress
, &segment_size
)) {
1235 IODTFreeLoaderInfo(dt_segment_name
, (void *)segment_paddress
,
1239 dt_segment_name
= "Kernel-__LINKEDIT";
1240 if (0 == IODTGetLoaderInfo(dt_segment_name
, &segment_paddress
, &segment_size
)) {
1241 IODTFreeLoaderInfo(dt_segment_name
, (void *)segment_paddress
,
1245 struct section
* sect
;
1246 sect
= getsectbyname("__PRELINK", "__symtab");
1247 if (sect
&& sect
->addr
)
1250 virt
= ml_static_ptovirt(sect
->addr
);
1252 ml_static_mfree(virt
, sect
->size
);
1258 /* This must be the very last thing done before returning.
1260 IOLockUnlock(kld_lock
);
1265 /*********************************************************************
1266 * This function stops the catalogue from making kextd requests during
1268 *********************************************************************/
1269 void IOCatalogue::disableExternalLinker(void) {
1270 IOLockLock(gIOKLDLock
);
1271 /* If kmod_load_extension (the kextd requester function) is in use,
1272 * disable new module requests.
1274 if (kmod_load_function
== &kmod_load_extension
) {
1275 kmod_load_function
= NULL
;
1278 IOLockUnlock(gIOKLDLock
);