]> git.saurik.com Git - apple/xnu.git/blob - iokit/Kernel/IOCatalogue.cpp
xnu-792.6.56.tar.gz
[apple/xnu.git] / iokit / Kernel / IOCatalogue.cpp
1 /*
2 * Copyright (c) 1998-2004 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23 /*
24 * Copyright (c) 1998 Apple Computer, Inc. All rights reserved.
25 *
26 * HISTORY
27 *
28 */
29
30 #include <IOKit/IODeviceTreeSupport.h>
31 #include <IOKit/IOService.h>
32 #include <libkern/c++/OSContainers.h>
33 #include <IOKit/IOCatalogue.h>
34 #include <libkern/c++/OSUnserialize.h>
35 extern "C" {
36 #include <machine/machine_routines.h>
37 #include <mach/kmod.h>
38 #include <mach-o/mach_header.h>
39 #include <kern/host.h>
40 };
41
42 #include <IOKit/IOLib.h>
43
44 #include <IOKit/assert.h>
45
46
47 extern "C" {
48 int IODTGetLoaderInfo( char *key, void **infoAddr, int *infoSize );
49 extern void IODTFreeLoaderInfo( char *key, void *infoAddr, int infoSize );
50 /* operates on 32 bit segments */
51 extern void OSRuntimeUnloadCPPForSegment(struct segment_command * segment);
52 };
53
54
55 /*****
56 * At startup these function pointers are set to use the libsa in-kernel
57 * linker for recording and loading kmods. Once the root filesystem
58 * is available, the kmod_load_function pointer gets switched to point
59 * at the kmod_load_extension() function built into the kernel, and the
60 * others are set to zero. Those two functions must *always* be checked
61 * before being invoked.
62 */
63 extern "C" {
64 kern_return_t (*kmod_load_function)(char *extension_name) =
65 &kmod_load_extension;
66 bool (*record_startup_extensions_function)(void) = 0;
67 bool (*add_from_mkext_function)(OSData * mkext) = 0;
68 void (*remove_startup_extension_function)(const char * name) = 0;
69 };
70
71
72 /*****
73 * A few parts of IOCatalogue require knowledge of
74 * whether the in-kernel linker is present. This
75 * variable is set by libsa's bootstrap code.
76 */
77 int kernelLinkerPresent = 0;
78
79 #define kModuleKey "CFBundleIdentifier"
80
81 #define super OSObject
82 OSDefineMetaClassAndStructors(IOCatalogue, OSObject)
83
84 #define CATALOGTEST 0
85
86 IOCatalogue * gIOCatalogue;
87 const OSSymbol * gIOClassKey;
88 const OSSymbol * gIOProbeScoreKey;
89 const OSSymbol * gIOModuleIdentifierKey;
90 OSSet * gIOCatalogModuleRequests;
91 OSSet * gIOCatalogCacheMisses;
92 OSSet * gIOCatalogROMMkexts;
93 IOLock * gIOCatalogLock;
94 IOLock * gIOKLDLock;
95
96 /*********************************************************************
97 *********************************************************************/
98
99 OSArray * gIOPrelinkedModules = 0;
100
101 extern "C" kern_return_t
102 kmod_create_internal(
103 kmod_info_t *info,
104 kmod_t *id);
105
106 extern "C" kern_return_t
107 kmod_destroy_internal(kmod_t id);
108
109 extern "C" kern_return_t
110 kmod_start_or_stop(
111 kmod_t id,
112 int start,
113 kmod_args_t *data,
114 mach_msg_type_number_t *dataCount);
115
116 extern "C" kern_return_t kmod_retain(kmod_t id);
117 extern "C" kern_return_t kmod_release(kmod_t id);
118
119 static
120 kern_return_t start_prelink_module(UInt32 moduleIndex)
121 {
122 kern_return_t kr = KERN_SUCCESS;
123 UInt32 * togo;
124 SInt32 count, where, end;
125 UInt32 * prelink;
126 SInt32 next, lastDep;
127 OSData * data;
128 OSString * str;
129 OSDictionary * dict;
130
131 OSArray *
132 prelinkedModules = gIOPrelinkedModules;
133
134 togo = IONew(UInt32, prelinkedModules->getCount());
135 togo[0] = moduleIndex;
136 count = 1;
137
138 for (next = 0; next < count; next++)
139 {
140 dict = (OSDictionary *) prelinkedModules->getObject(togo[next]);
141
142 data = OSDynamicCast(OSData, dict->getObject("OSBundlePrelink"));
143 if (!data)
144 {
145 // already started or no code
146 if (togo[next] == moduleIndex)
147 {
148 kr = KERN_FAILURE;
149 break;
150 }
151 continue;
152 }
153 prelink = (UInt32 *) data->getBytesNoCopy();
154 lastDep = OSReadBigInt32(prelink, 12);
155 for (SInt32 idx = OSReadBigInt32(prelink, 8); idx < lastDep; idx += sizeof(UInt32))
156 {
157 UInt32 depIdx = OSReadBigInt32(prelink, idx) - 1;
158
159 for (where = next + 1;
160 (where < count) && (togo[where] > depIdx);
161 where++) {}
162
163 if (where != count)
164 {
165 if (togo[where] == depIdx)
166 continue;
167 for (end = count; end != where; end--)
168 togo[end] = togo[end - 1];
169 }
170 count++;
171 togo[where] = depIdx;
172 }
173 }
174
175 if (KERN_SUCCESS != kr)
176 return kr;
177
178 for (next = (count - 1); next >= 0; next--)
179 {
180 dict = (OSDictionary *) prelinkedModules->getObject(togo[next]);
181
182 data = OSDynamicCast(OSData, dict->getObject("OSBundlePrelink"));
183 if (!data)
184 continue;
185 prelink = (UInt32 *) data->getBytesNoCopy();
186
187 kmod_t id;
188 kmod_info_t * kmod_info = (kmod_info_t *) OSReadBigInt32(prelink, 0);
189
190 kr = kmod_create_internal(kmod_info, &id);
191 if (KERN_SUCCESS != kr)
192 break;
193
194 lastDep = OSReadBigInt32(prelink, 12);
195 for (SInt32 idx = OSReadBigInt32(prelink, 8); idx < lastDep; idx += sizeof(UInt32))
196 {
197 OSDictionary * depDict;
198 kmod_info_t * depInfo;
199
200 depDict = (OSDictionary *) prelinkedModules->getObject(OSReadBigInt32(prelink, idx) - 1);
201 str = OSDynamicCast(OSString, depDict->getObject(kModuleKey));
202 depInfo = kmod_lookupbyname_locked(str->getCStringNoCopy());
203 if (depInfo)
204 {
205 kr = kmod_retain(KMOD_PACK_IDS(id, depInfo->id));
206 kfree(depInfo, sizeof(kmod_info_t));
207 } else
208 IOLog("%s: NO DEP %s\n", kmod_info->name, str->getCStringNoCopy());
209 }
210 dict->removeObject("OSBundlePrelink");
211
212 if (kmod_info->start)
213 kr = kmod_start_or_stop(kmod_info->id, 1, 0, 0);
214 }
215
216 IODelete(togo, UInt32, prelinkedModules->getCount());
217
218 return kr;
219 }
220
221 /*********************************************************************
222 * This is a function that IOCatalogue calls in order to load a kmod.
223 *********************************************************************/
224
225 static
226 kern_return_t kmod_load_from_cache_sym(const OSSymbol * kmod_name)
227 {
228 OSArray * prelinkedModules = gIOPrelinkedModules;
229 kern_return_t result = KERN_FAILURE;
230 OSDictionary * dict;
231 OSObject * ident;
232 UInt32 idx;
233
234 if (!gIOPrelinkedModules)
235 return KERN_FAILURE;
236
237 for (idx = 0;
238 (dict = (OSDictionary *) prelinkedModules->getObject(idx));
239 idx++)
240 {
241 if ((ident = dict->getObject(kModuleKey))
242 && kmod_name->isEqualTo(ident))
243 break;
244 }
245 if (dict)
246 {
247 if (kernelLinkerPresent && dict->getObject("OSBundleDefer"))
248 {
249 kmod_load_extension((char *) kmod_name->getCStringNoCopy());
250 result = kIOReturnOffline;
251 }
252 else
253 result = start_prelink_module(idx);
254 }
255
256 return result;
257 }
258
259 extern "C" Boolean kmod_load_request(const char * moduleName, Boolean make_request)
260 {
261 bool ret, cacheMiss = false;
262 kern_return_t kr;
263 const OSSymbol * sym = 0;
264 kmod_info_t * kmod_info;
265
266 if (!moduleName)
267 return false;
268
269 /* To make sure this operation completes even if a bad extension needs
270 * to be removed, take the kld lock for this whole block, spanning the
271 * kmod_load_function() and remove_startup_extension_function() calls.
272 */
273 IOLockLock(gIOKLDLock);
274 do
275 {
276 // Is the module already loaded?
277 ret = (0 != (kmod_info = kmod_lookupbyname_locked((char *)moduleName)));
278 if (ret) {
279 kfree(kmod_info, sizeof(kmod_info_t));
280 break;
281 }
282 sym = OSSymbol::withCString(moduleName);
283 if (!sym) {
284 ret = false;
285 break;
286 }
287
288 kr = kmod_load_from_cache_sym(sym);
289 ret = (kIOReturnSuccess == kr);
290 cacheMiss = !ret;
291 if (ret || !make_request || (kr == kIOReturnOffline))
292 break;
293
294 // If the module hasn't been loaded, then load it.
295 if (!kmod_load_function) {
296 IOLog("IOCatalogue: %s cannot be loaded "
297 "(kmod load function not set).\n",
298 moduleName);
299 ret = true;
300 break;
301 }
302
303 kr = kmod_load_function((char *)moduleName);
304
305 if (ret != kIOReturnSuccess) {
306 IOLog("IOCatalogue: %s cannot be loaded.\n", moduleName);
307
308 /* If the extension couldn't be loaded this time,
309 * make it unavailable so that no more requests are
310 * made in vain. This also enables other matching
311 * extensions to have a chance.
312 */
313 if (kernelLinkerPresent && remove_startup_extension_function) {
314 (*remove_startup_extension_function)(moduleName);
315 }
316 ret = false;
317
318 } else if (kernelLinkerPresent) {
319 // If kern linker is here, the driver is actually loaded,
320 // so return true.
321 ret = true;
322
323 } else {
324 // kern linker isn't here, a request has been queued
325 // but the module isn't necessarily loaded yet, so stall.
326 ret = false;
327 }
328 }
329 while (false);
330
331 IOLockUnlock(gIOKLDLock);
332
333 if (sym)
334 {
335 IOLockLock(gIOCatalogLock);
336 gIOCatalogModuleRequests->setObject(sym);
337 if (cacheMiss)
338 gIOCatalogCacheMisses->setObject(sym);
339 IOLockUnlock(gIOCatalogLock);
340 }
341
342 return ret;
343 }
344
345 extern "C" kern_return_t kmod_unload_cache(void)
346 {
347 OSArray * prelinkedModules = gIOPrelinkedModules;
348 kern_return_t result = KERN_FAILURE;
349 OSDictionary * dict;
350 UInt32 idx;
351 UInt32 * prelink;
352 OSData * data;
353
354 if (!gIOPrelinkedModules)
355 return KERN_SUCCESS;
356
357 IOLockLock(gIOKLDLock);
358 for (idx = 0;
359 (dict = (OSDictionary *) prelinkedModules->getObject(idx));
360 idx++)
361 {
362 data = OSDynamicCast(OSData, dict->getObject("OSBundlePrelink"));
363 if (!data)
364 continue;
365 prelink = (UInt32 *) data->getBytesNoCopy();
366
367 kmod_info_t * kmod_info = (kmod_info_t *) OSReadBigInt32(prelink, 0);
368 vm_offset_t
369 virt = ml_static_ptovirt(kmod_info->address);
370 if( virt) {
371 ml_static_mfree(virt, kmod_info->size);
372 }
373 }
374
375 gIOPrelinkedModules->release();
376 gIOPrelinkedModules = 0;
377
378 IOLockUnlock(gIOKLDLock);
379
380 return result;
381 }
382
383 extern "C" kern_return_t kmod_load_from_cache(const char * kmod_name)
384 {
385 kern_return_t kr;
386 const OSSymbol * sym = OSSymbol::withCStringNoCopy(kmod_name);
387
388 if (sym)
389 {
390 kr = kmod_load_from_cache_sym(sym);
391 sym->release();
392 }
393 else
394 kr = kIOReturnNoMemory;
395
396 return kr;
397 }
398
399 /*********************************************************************
400 *********************************************************************/
401
402 static void UniqueProperties( OSDictionary * dict )
403 {
404 OSString * data;
405
406 data = OSDynamicCast( OSString, dict->getObject( gIOClassKey ));
407 if( data) {
408 const OSSymbol *classSymbol = OSSymbol::withString(data);
409
410 dict->setObject( gIOClassKey, (OSSymbol *) classSymbol);
411 classSymbol->release();
412 }
413
414 data = OSDynamicCast( OSString, dict->getObject( gIOMatchCategoryKey ));
415 if( data) {
416 const OSSymbol *classSymbol = OSSymbol::withString(data);
417
418 dict->setObject( gIOMatchCategoryKey, (OSSymbol *) classSymbol);
419 classSymbol->release();
420 }
421 }
422
423 void IOCatalogue::initialize( void )
424 {
425 OSArray * array;
426 OSString * errorString;
427 bool rc;
428
429 extern const char * gIOKernelConfigTables;
430
431 array = OSDynamicCast(OSArray, OSUnserialize(gIOKernelConfigTables, &errorString));
432 if (!array && errorString) {
433 IOLog("KernelConfigTables syntax error: %s\n",
434 errorString->getCStringNoCopy());
435 errorString->release();
436 }
437
438 gIOClassKey = OSSymbol::withCStringNoCopy( kIOClassKey );
439 gIOProbeScoreKey = OSSymbol::withCStringNoCopy( kIOProbeScoreKey );
440 gIOModuleIdentifierKey = OSSymbol::withCStringNoCopy( kModuleKey );
441 gIOCatalogModuleRequests = OSSet::withCapacity(16);
442 gIOCatalogCacheMisses = OSSet::withCapacity(16);
443 gIOCatalogROMMkexts = OSSet::withCapacity(4);
444
445 assert( array && gIOClassKey && gIOProbeScoreKey
446 && gIOModuleIdentifierKey && gIOCatalogModuleRequests);
447
448 gIOCatalogue = new IOCatalogue;
449 assert(gIOCatalogue);
450 rc = gIOCatalogue->init(array);
451 assert(rc);
452 array->release();
453 }
454
455 // Initialize the IOCatalog object.
456 bool IOCatalogue::init(OSArray * initArray)
457 {
458 OSDictionary * dict;
459
460 if ( !super::init() )
461 return false;
462
463 generation = 1;
464
465 array = initArray;
466 array->retain();
467 kernelTables = OSCollectionIterator::withCollection( array );
468
469 gIOCatalogLock = IOLockAlloc();
470 gIOKLDLock = IOLockAlloc();
471
472 lock = gIOCatalogLock;
473 kld_lock = gIOKLDLock;
474
475 kernelTables->reset();
476 while( (dict = (OSDictionary *) kernelTables->getNextObject())) {
477 UniqueProperties(dict);
478 if( 0 == dict->getObject( gIOClassKey ))
479 IOLog("Missing or bad \"%s\" key\n",
480 gIOClassKey->getCStringNoCopy());
481 }
482
483 #if CATALOGTEST
484 AbsoluteTime deadline;
485 clock_interval_to_deadline( 1000, kMillisecondScale );
486 thread_call_func_delayed( ping, this, deadline );
487 #endif
488
489 return true;
490 }
491
492 // Release all resources used by IOCatalogue and deallocate.
493 // This will probably never be called.
494 void IOCatalogue::free( void )
495 {
496 if ( array )
497 array->release();
498
499 if ( kernelTables )
500 kernelTables->release();
501
502 super::free();
503 }
504
505 #if CATALOGTEST
506
507 static int hackLimit;
508
509 enum { kDriversPerIter = 4 };
510
511 void IOCatalogue::ping( thread_call_param_t arg, thread_call_param_t)
512 {
513 IOCatalogue * self = (IOCatalogue *) arg;
514 OSOrderedSet * set;
515 OSDictionary * table;
516 int newLimit;
517
518 set = OSOrderedSet::withCapacity( 1 );
519
520 IOLockLock( &self->lock );
521
522 for( newLimit = 0; newLimit < kDriversPerIter; newLimit++) {
523 table = (OSDictionary *) self->array->getObject(
524 hackLimit + newLimit );
525 if( table) {
526 set->setLastObject( table );
527
528 OSSymbol * sym = (OSSymbol *) table->getObject( gIOClassKey );
529 kprintf("enabling %s\n", sym->getCStringNoCopy());
530
531 } else {
532 newLimit--;
533 break;
534 }
535 }
536
537 IOService::catalogNewDrivers( set );
538
539 hackLimit += newLimit;
540 self->generation++;
541
542 IOLockUnlock( &self->lock );
543
544 if( kDriversPerIter == newLimit) {
545 AbsoluteTime deadline;
546 clock_interval_to_deadline( 500, kMillisecondScale );
547 thread_call_func_delayed( ping, this, deadline );
548 }
549 }
550 #endif
551
552 OSOrderedSet * IOCatalogue::findDrivers( IOService * service,
553 SInt32 * generationCount )
554 {
555 OSDictionary * nextTable;
556 OSOrderedSet * set;
557 OSString * imports;
558
559 set = OSOrderedSet::withCapacity( 1, IOServiceOrdering,
560 (void *)gIOProbeScoreKey );
561 if( !set )
562 return( 0 );
563
564 IOLockLock( lock );
565 kernelTables->reset();
566
567 #if CATALOGTEST
568 int hackIndex = 0;
569 #endif
570 while( (nextTable = (OSDictionary *) kernelTables->getNextObject())) {
571 #if CATALOGTEST
572 if( hackIndex++ > hackLimit)
573 break;
574 #endif
575 imports = OSDynamicCast( OSString,
576 nextTable->getObject( gIOProviderClassKey ));
577 if( imports && service->metaCast( imports ))
578 set->setObject( nextTable );
579 }
580
581 *generationCount = getGenerationCount();
582
583 IOLockUnlock( lock );
584
585 return( set );
586 }
587
588 // Is personality already in the catalog?
589 OSOrderedSet * IOCatalogue::findDrivers( OSDictionary * matching,
590 SInt32 * generationCount)
591 {
592 OSDictionary * dict;
593 OSOrderedSet * set;
594
595 UniqueProperties(matching);
596
597 set = OSOrderedSet::withCapacity( 1, IOServiceOrdering,
598 (void *)gIOProbeScoreKey );
599
600 IOLockLock( lock );
601 kernelTables->reset();
602 while ( (dict = (OSDictionary *) kernelTables->getNextObject()) ) {
603
604 /* This comparison must be done with only the keys in the
605 * "matching" dict to enable general searches.
606 */
607 if ( dict->isEqualTo(matching, matching) )
608 set->setObject(dict);
609 }
610 *generationCount = getGenerationCount();
611 IOLockUnlock( lock );
612
613 return set;
614 }
615
616 // Add a new personality to the set if it has a unique IOResourceMatchKey value.
617 // XXX -- svail: This should be optimized.
618 // esb - There doesn't seem like any reason to do this - it causes problems
619 // esb - when there are more than one loadable driver matching on the same provider class
620 static void AddNewImports( OSOrderedSet * set, OSDictionary * dict )
621 {
622 set->setObject(dict);
623 }
624
625 // Add driver config tables to catalog and start matching process.
626 bool IOCatalogue::addDrivers(OSArray * drivers,
627 bool doNubMatching )
628 {
629 OSCollectionIterator * iter;
630 OSDictionary * dict;
631 OSOrderedSet * set;
632 OSArray * persons;
633 OSString * moduleName;
634 bool ret;
635
636 ret = true;
637 persons = OSDynamicCast(OSArray, drivers);
638 if ( !persons )
639 return false;
640
641 iter = OSCollectionIterator::withCollection( persons );
642 if (!iter )
643 return false;
644
645 set = OSOrderedSet::withCapacity( 10, IOServiceOrdering,
646 (void *)gIOProbeScoreKey );
647 if ( !set ) {
648 iter->release();
649 return false;
650 }
651
652 IOLockLock( lock );
653 while ( (dict = (OSDictionary *) iter->getNextObject()) )
654 {
655 if ((moduleName = OSDynamicCast(OSString, dict->getObject("OSBundleModuleDemand"))))
656 {
657 IOLockUnlock( lock );
658 ret = kmod_load_request(moduleName->getCStringNoCopy(), false);
659 IOLockLock( lock );
660 ret = true;
661 }
662 else
663 {
664 SInt count;
665
666 UniqueProperties( dict );
667
668 // Add driver personality to catalogue.
669 count = array->getCount();
670 while ( count-- ) {
671 OSDictionary * driver;
672
673 // Be sure not to double up on personalities.
674 driver = (OSDictionary *)array->getObject(count);
675
676 /* Unlike in other functions, this comparison must be exact!
677 * The catalogue must be able to contain personalities that
678 * are proper supersets of others.
679 * Do not compare just the properties present in one driver
680 * pesonality or the other.
681 */
682 if (dict->isEqualTo(driver))
683 break;
684 }
685 if (count >= 0)
686 // its a dup
687 continue;
688
689 ret = array->setObject( dict );
690 if (!ret)
691 break;
692
693 AddNewImports( set, dict );
694 }
695 }
696 // Start device matching.
697 if (doNubMatching && (set->getCount() > 0)) {
698 IOService::catalogNewDrivers( set );
699 generation++;
700 }
701 IOLockUnlock( lock );
702
703 set->release();
704 iter->release();
705
706 return ret;
707 }
708
709 // Remove drivers from the catalog which match the
710 // properties in the matching dictionary.
711 bool IOCatalogue::removeDrivers( OSDictionary * matching,
712 bool doNubMatching)
713 {
714 OSCollectionIterator * tables;
715 OSDictionary * dict;
716 OSOrderedSet * set;
717 OSArray * arrayCopy;
718
719 if ( !matching )
720 return false;
721
722 set = OSOrderedSet::withCapacity(10,
723 IOServiceOrdering,
724 (void *)gIOProbeScoreKey);
725 if ( !set )
726 return false;
727
728 arrayCopy = OSArray::withCapacity(100);
729 if ( !arrayCopy ) {
730 set->release();
731 return false;
732 }
733
734 tables = OSCollectionIterator::withCollection(arrayCopy);
735 arrayCopy->release();
736 if ( !tables ) {
737 set->release();
738 return false;
739 }
740
741 UniqueProperties( matching );
742
743 IOLockLock( lock );
744 kernelTables->reset();
745 arrayCopy->merge(array);
746 array->flushCollection();
747 tables->reset();
748 while ( (dict = (OSDictionary *)tables->getNextObject()) ) {
749
750 /* This comparison must be done with only the keys in the
751 * "matching" dict to enable general searches.
752 */
753 if ( dict->isEqualTo(matching, matching) ) {
754 AddNewImports( set, dict );
755 continue;
756 }
757
758 array->setObject(dict);
759 }
760 // Start device matching.
761 if ( doNubMatching && (set->getCount() > 0) ) {
762 IOService::catalogNewDrivers(set);
763 generation++;
764 }
765 IOLockUnlock( lock );
766
767 set->release();
768 tables->release();
769
770 return true;
771 }
772
773 // Return the generation count.
774 SInt32 IOCatalogue::getGenerationCount( void ) const
775 {
776 return( generation );
777 }
778
779 bool IOCatalogue::isModuleLoaded( OSString * moduleName ) const
780 {
781 return isModuleLoaded(moduleName->getCStringNoCopy());
782 }
783
784 bool IOCatalogue::isModuleLoaded( const char * moduleName ) const
785 {
786 return (kmod_load_request(moduleName, true));
787 }
788
789 // Check to see if module has been loaded already.
790 bool IOCatalogue::isModuleLoaded( OSDictionary * driver ) const
791 {
792 OSString * moduleName = NULL;
793
794 if ( !driver )
795 return false;
796
797 moduleName = OSDynamicCast(OSString, driver->getObject(gIOModuleIdentifierKey));
798 if ( moduleName )
799 return isModuleLoaded(moduleName);
800
801 /* If a personality doesn't hold the "CFBundleIdentifier" key
802 * it is assumed to be an "in-kernel" driver.
803 */
804 return true;
805 }
806
807 // This function is called after a module has been loaded.
808 void IOCatalogue::moduleHasLoaded( OSString * moduleName )
809 {
810 OSDictionary * dict;
811
812 dict = OSDictionary::withCapacity(2);
813 dict->setObject(gIOModuleIdentifierKey, moduleName);
814 startMatching(dict);
815 dict->release();
816 }
817
818 void IOCatalogue::moduleHasLoaded( const char * moduleName )
819 {
820 OSString * name;
821
822 name = OSString::withCString(moduleName);
823 moduleHasLoaded(name);
824 name->release();
825 }
826
827 IOReturn IOCatalogue::unloadModule( OSString * moduleName ) const
828 {
829 kmod_info_t * k_info = 0;
830 kern_return_t ret;
831 const char * name;
832
833 ret = kIOReturnBadArgument;
834 if ( moduleName ) {
835 name = moduleName->getCStringNoCopy();
836 k_info = kmod_lookupbyname_locked((char *)name);
837 if ( k_info && (k_info->reference_count < 1) ) {
838 if ( k_info->stop &&
839 !((ret = k_info->stop(k_info, 0)) == kIOReturnSuccess) ) {
840
841 kfree(k_info, sizeof(kmod_info_t));
842 return ret;
843 }
844
845 ret = kmod_destroy(host_priv_self(), k_info->id);
846 }
847 }
848
849 if (k_info) {
850 kfree(k_info, sizeof(kmod_info_t));
851 }
852
853 return ret;
854 }
855
856 static IOReturn _terminateDrivers( OSDictionary * matching )
857 {
858 OSDictionary * dict;
859 OSIterator * iter;
860 IOService * service;
861 IOReturn ret;
862
863 if ( !matching )
864 return kIOReturnBadArgument;
865
866 ret = kIOReturnSuccess;
867 dict = 0;
868 iter = IORegistryIterator::iterateOver(gIOServicePlane,
869 kIORegistryIterateRecursively);
870 if ( !iter )
871 return kIOReturnNoMemory;
872
873 UniqueProperties( matching );
874
875 // terminate instances.
876 do {
877 iter->reset();
878 while( (service = (IOService *)iter->getNextObject()) ) {
879 dict = service->getPropertyTable();
880 if ( !dict )
881 continue;
882
883 /* Terminate only for personalities that match the matching dictionary.
884 * This comparison must be done with only the keys in the
885 * "matching" dict to enable general matching.
886 */
887 if ( !dict->isEqualTo(matching, matching) )
888 continue;
889
890 if ( !service->terminate(kIOServiceRequired|kIOServiceSynchronous) ) {
891 ret = kIOReturnUnsupported;
892 break;
893 }
894 }
895 } while( !service && !iter->isValid());
896 iter->release();
897
898 return ret;
899 }
900
901 static IOReturn _removeDrivers( OSArray * array, OSDictionary * matching )
902 {
903 OSCollectionIterator * tables;
904 OSDictionary * dict;
905 OSArray * arrayCopy;
906 IOReturn ret = kIOReturnSuccess;
907
908 // remove configs from catalog.
909
910 arrayCopy = OSArray::withCapacity(100);
911 if ( !arrayCopy )
912 return kIOReturnNoMemory;
913
914 tables = OSCollectionIterator::withCollection(arrayCopy);
915 arrayCopy->release();
916 if ( !tables )
917 return kIOReturnNoMemory;
918
919 arrayCopy->merge(array);
920 array->flushCollection();
921 tables->reset();
922 while ( (dict = (OSDictionary *)tables->getNextObject()) ) {
923
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.
928 */
929 if ( dict->isEqualTo(matching, matching) )
930 continue;
931
932 array->setObject(dict);
933 }
934
935 tables->release();
936
937 return ret;
938 }
939
940 IOReturn IOCatalogue::terminateDrivers( OSDictionary * matching )
941 {
942 IOReturn ret;
943
944 ret = _terminateDrivers(matching);
945 IOLockLock( lock );
946 if (kIOReturnSuccess == ret)
947 ret = _removeDrivers(array, matching);
948 kernelTables->reset();
949 IOLockUnlock( lock );
950
951 return ret;
952 }
953
954 IOReturn IOCatalogue::terminateDriversForModule(
955 OSString * moduleName,
956 bool unload )
957 {
958 IOReturn ret;
959 OSDictionary * dict;
960
961 dict = OSDictionary::withCapacity(1);
962 if ( !dict )
963 return kIOReturnNoMemory;
964
965 dict->setObject(gIOModuleIdentifierKey, moduleName);
966
967 ret = _terminateDrivers(dict);
968 IOLockLock( lock );
969 if (kIOReturnSuccess == ret)
970 ret = _removeDrivers(array, dict);
971 kernelTables->reset();
972
973 // Unload the module itself.
974 if ( unload && ret == kIOReturnSuccess ) {
975 // Do kmod stop first.
976 ret = unloadModule(moduleName);
977 }
978
979 IOLockUnlock( lock );
980
981 dict->release();
982
983 return ret;
984 }
985
986 IOReturn IOCatalogue::terminateDriversForModule(
987 const char * moduleName,
988 bool unload )
989 {
990 OSString * name;
991 IOReturn ret;
992
993 name = OSString::withCString(moduleName);
994 if ( !name )
995 return kIOReturnNoMemory;
996
997 ret = terminateDriversForModule(name, unload);
998 name->release();
999
1000 return ret;
1001 }
1002
1003 bool IOCatalogue::startMatching( OSDictionary * matching )
1004 {
1005 OSDictionary * dict;
1006 OSOrderedSet * set;
1007
1008 if ( !matching )
1009 return false;
1010
1011 set = OSOrderedSet::withCapacity(10, IOServiceOrdering,
1012 (void *)gIOProbeScoreKey);
1013 if ( !set )
1014 return false;
1015
1016 IOLockLock( lock );
1017 kernelTables->reset();
1018
1019 while ( (dict = (OSDictionary *)kernelTables->getNextObject()) ) {
1020
1021 /* This comparison must be done with only the keys in the
1022 * "matching" dict to enable general matching.
1023 */
1024 if ( dict->isEqualTo(matching, matching) )
1025 AddNewImports(set, dict);
1026 }
1027 // Start device matching.
1028 if ( set->getCount() > 0 ) {
1029 IOService::catalogNewDrivers(set);
1030 generation++;
1031 }
1032
1033 IOLockUnlock( lock );
1034
1035 set->release();
1036
1037 return true;
1038 }
1039
1040 void IOCatalogue::reset(void)
1041 {
1042 IOLog("Resetting IOCatalogue.\n");
1043 }
1044
1045 bool IOCatalogue::serialize(OSSerialize * s) const
1046 {
1047 if ( !s )
1048 return false;
1049
1050 return super::serialize(s);
1051 }
1052
1053 bool IOCatalogue::serializeData(IOOptionBits kind, OSSerialize * s) const
1054 {
1055 kern_return_t kr = kIOReturnSuccess;
1056
1057 switch ( kind )
1058 {
1059 case kIOCatalogGetContents:
1060 if (!serialize(s))
1061 kr = kIOReturnNoMemory;
1062 break;
1063
1064 case kIOCatalogGetModuleDemandList:
1065 IOLockLock( lock );
1066 if (!gIOCatalogModuleRequests->serialize(s))
1067 kr = kIOReturnNoMemory;
1068 IOLockUnlock( lock );
1069 break;
1070
1071 case kIOCatalogGetCacheMissList:
1072 IOLockLock( lock );
1073 if (!gIOCatalogCacheMisses->serialize(s))
1074 kr = kIOReturnNoMemory;
1075 IOLockUnlock( lock );
1076 break;
1077
1078 case kIOCatalogGetROMMkextList:
1079 IOLockLock( lock );
1080
1081 if (!gIOCatalogROMMkexts || !gIOCatalogROMMkexts->getCount())
1082 kr = kIOReturnNoResources;
1083 else if (!gIOCatalogROMMkexts->serialize(s))
1084 kr = kIOReturnNoMemory;
1085
1086 if (gIOCatalogROMMkexts)
1087 {
1088 gIOCatalogROMMkexts->release();
1089 gIOCatalogROMMkexts = 0;
1090 }
1091
1092 IOLockUnlock( lock );
1093 break;
1094
1095 default:
1096 kr = kIOReturnBadArgument;
1097 break;
1098 }
1099
1100 return kr;
1101 }
1102
1103
1104 bool IOCatalogue::recordStartupExtensions(void) {
1105 bool result = false;
1106
1107 IOLockLock(kld_lock);
1108 if (kernelLinkerPresent && record_startup_extensions_function) {
1109 result = (*record_startup_extensions_function)();
1110 } else {
1111 IOLog("Can't record startup extensions; "
1112 "kernel linker is not present.\n");
1113 result = false;
1114 }
1115 IOLockUnlock(kld_lock);
1116
1117 return result;
1118 }
1119
1120
1121 /*********************************************************************
1122 * This function operates on sections retrieved from the currently running
1123 * 32 bit mach kernel.
1124 *********************************************************************/
1125 bool IOCatalogue::addExtensionsFromArchive(OSData * mkext)
1126 {
1127 OSData * copyData;
1128 bool result = false;
1129 bool prelinked;
1130
1131 /* The mkext we've been handed (or the data it references) can go away,
1132 * so we need to make a local copy to keep around as long as it might
1133 * be needed.
1134 */
1135 copyData = OSData::withData(mkext);
1136 if (copyData)
1137 {
1138 struct section * infosect;
1139
1140 infosect = getsectbyname("__PRELINK", "__info");
1141 prelinked = (infosect && infosect->addr && infosect->size);
1142
1143 IOLockLock(kld_lock);
1144
1145 if (gIOCatalogROMMkexts)
1146 gIOCatalogROMMkexts->setObject(copyData);
1147
1148 if (prelinked) {
1149 result = true;
1150 } else if (kernelLinkerPresent && add_from_mkext_function) {
1151 result = (*add_from_mkext_function)(copyData);
1152 } else {
1153 IOLog("Can't add startup extensions from archive; "
1154 "kernel linker is not present.\n");
1155 result = false;
1156 }
1157
1158 IOLockUnlock(kld_lock);
1159
1160 copyData->release();
1161 }
1162
1163 return result;
1164 }
1165
1166
1167 /*********************************************************************
1168 * This function clears out all references to the in-kernel linker,
1169 * frees the list of startup extensions in extensionDict, and
1170 * deallocates the kernel's __KLD segment to reclaim that memory.
1171 *
1172 * The segments it operates on are strictly 32 bit segments.
1173 *********************************************************************/
1174 kern_return_t IOCatalogue::removeKernelLinker(void) {
1175 kern_return_t result = KERN_SUCCESS;
1176 struct segment_command * segment;
1177 char * dt_segment_name;
1178 void * segment_paddress;
1179 int segment_size;
1180
1181 /* This must be the very first thing done by this function.
1182 */
1183 IOLockLock(kld_lock);
1184
1185
1186 /* If the kernel linker isn't here, that's automatically
1187 * a success.
1188 */
1189 if (!kernelLinkerPresent) {
1190 result = KERN_SUCCESS;
1191 goto finish;
1192 }
1193
1194 IOLog("Jettisoning kernel linker.\n");
1195
1196 kernelLinkerPresent = 0;
1197
1198 /* Set the kmod_load_extension function as the means for loading
1199 * a kernel extension.
1200 */
1201 kmod_load_function = &kmod_load_extension;
1202
1203 record_startup_extensions_function = 0;
1204 add_from_mkext_function = 0;
1205 remove_startup_extension_function = 0;
1206
1207
1208 /* Invoke destructors for the __KLD and __LINKEDIT segments.
1209 * Do this for all segments before actually freeing their
1210 * memory so that any cross-dependencies (not that there
1211 * should be any) are handled.
1212 */
1213 segment = getsegbyname("__KLD");
1214 if (!segment) {
1215 IOLog("error removing kernel linker: can't find %s segment\n",
1216 "__KLD");
1217 result = KERN_FAILURE;
1218 goto finish;
1219 }
1220 OSRuntimeUnloadCPPForSegment(segment);
1221
1222 segment = getsegbyname("__LINKEDIT");
1223 if (!segment) {
1224 IOLog("error removing kernel linker: can't find %s segment\n",
1225 "__LINKEDIT");
1226 result = KERN_FAILURE;
1227 goto finish;
1228 }
1229 OSRuntimeUnloadCPPForSegment(segment);
1230
1231
1232 /* Free the memory that was set up by bootx.
1233 */
1234 dt_segment_name = "Kernel-__KLD";
1235 if (0 == IODTGetLoaderInfo(dt_segment_name, &segment_paddress, &segment_size)) {
1236 IODTFreeLoaderInfo(dt_segment_name, (void *)segment_paddress,
1237 (int)segment_size);
1238 }
1239
1240 dt_segment_name = "Kernel-__LINKEDIT";
1241 if (0 == IODTGetLoaderInfo(dt_segment_name, &segment_paddress, &segment_size)) {
1242 IODTFreeLoaderInfo(dt_segment_name, (void *)segment_paddress,
1243 (int)segment_size);
1244 }
1245
1246 struct section * sect;
1247 sect = getsectbyname("__PRELINK", "__symtab");
1248 if (sect && sect->addr)
1249 {
1250 vm_offset_t
1251 virt = ml_static_ptovirt(sect->addr);
1252 if( virt) {
1253 ml_static_mfree(virt, sect->size);
1254 }
1255 }
1256
1257 finish:
1258
1259 /* This must be the very last thing done before returning.
1260 */
1261 IOLockUnlock(kld_lock);
1262
1263 return result;
1264 }
1265
1266 /*********************************************************************
1267 * This function stops the catalogue from making kextd requests during
1268 * shutdown.
1269 *********************************************************************/
1270 void IOCatalogue::disableExternalLinker(void) {
1271 IOLockLock(gIOKLDLock);
1272 /* If kmod_load_extension (the kextd requester function) is in use,
1273 * disable new module requests.
1274 */
1275 if (kmod_load_function == &kmod_load_extension) {
1276 kmod_load_function = NULL;
1277 }
1278
1279 IOLockUnlock(gIOKLDLock);
1280 }
1281