2 * Copyright (c) 1998-2006 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 * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce
36 * support for mandatory and extensible security protections. This notice
37 * is included in support of clause 2.2 (b) of the Apple Public License,
41 #include <IOKit/IODeviceTreeSupport.h>
42 #include <IOKit/IOService.h>
43 #include <libkern/c++/OSContainers.h>
44 #include <IOKit/IOCatalogue.h>
45 #include <libkern/c++/OSUnserialize.h>
47 #include <machine/machine_routines.h>
48 #include <mach/kmod.h>
49 #include <mach-o/mach_header.h>
50 #include <kern/host.h>
51 #include <security/mac_data.h>
54 #include <IOKit/IOLib.h>
56 #include <IOKit/assert.h>
60 int IODTGetLoaderInfo( char *key
, void **infoAddr
, int *infoSize
);
61 extern void IODTFreeLoaderInfo( char *key
, void *infoAddr
, int infoSize
);
62 /* operates on 32 bit segments */
63 extern void OSRuntimeUnloadCPPForSegment(struct segment_command
* segment
);
68 * At startup these function pointers are set to use the libsa in-kernel
69 * linker for recording and loading kmods. Once the root filesystem
70 * is available, the kmod_load_function pointer gets switched to point
71 * at the kmod_load_extension() function built into the kernel, and the
72 * others are set to zero. Those two functions must *always* be checked
73 * before being invoked.
76 kern_return_t (*kmod_load_function
)(char *extension_name
) =
78 bool (*record_startup_extensions_function
)(void) = 0;
79 bool (*add_from_mkext_function
)(OSData
* mkext
) = 0;
80 void (*remove_startup_extension_function
)(const char * name
) = 0;
85 * A few parts of IOCatalogue require knowledge of
86 * whether the in-kernel linker is present. This
87 * variable is set by libsa's bootstrap code.
89 int kernelLinkerPresent
= 0;
91 #define kModuleKey "CFBundleIdentifier"
93 #define super OSObject
94 OSDefineMetaClassAndStructors(IOCatalogue
, OSObject
)
98 IOCatalogue
* gIOCatalogue
;
99 const OSSymbol
* gIOClassKey
;
100 const OSSymbol
* gIOProbeScoreKey
;
101 const OSSymbol
* gIOModuleIdentifierKey
;
102 OSSet
* gIOCatalogModuleRequests
;
103 OSSet
* gIOCatalogCacheMisses
;
104 OSSet
* gIOCatalogROMMkexts
;
105 IOLock
* gIOCatalogLock
;
108 /*********************************************************************
109 *********************************************************************/
111 OSArray
* gIOPrelinkedModules
= 0;
113 extern "C" kern_return_t
114 kmod_create_internal(
118 extern "C" kern_return_t
119 kmod_destroy_internal(kmod_t id
);
121 extern "C" kern_return_t
126 mach_msg_type_number_t
*dataCount
);
128 extern "C" kern_return_t
kmod_retain(kmod_t id
);
129 extern "C" kern_return_t
kmod_release(kmod_t id
);
132 /* MAC Framework support */
135 * define IOC_DEBUG to display run-time debugging information
136 * #define IOC_DEBUG 1
140 #define DPRINTF(x) printf x
147 primitive_type(OSObject
*obj
)
149 const OSMetaClass
*typeID
;
151 typeID
= OSTypeIDInst(obj
);
152 if (typeID
== OSTypeID(OSString
) || typeID
== OSTypeID(OSNumber
) ||
153 typeID
== OSTypeID(OSBoolean
) || typeID
== OSTypeID(OSData
))
160 primitive_type_length(OSObject
*obj
)
162 const OSMetaClass
*typeID
;
165 typeID
= OSTypeIDInst(obj
);
166 if (typeID
== OSTypeID(OSString
)) {
167 OSString
* stringObj
= OSDynamicCast(OSString
, obj
);
168 len
= stringObj
->getLength() + 1;
170 else if (typeID
== OSTypeID(OSNumber
)) {
171 len
= sizeof("4294967295"); /* UINT32_MAX */
173 else if (typeID
== OSTypeID(OSBoolean
)) {
174 OSBoolean
* boolObj
= OSDynamicCast(OSBoolean
, obj
);
175 len
= boolObj
->isTrue() ? sizeof("true") : sizeof("false");
177 else if (typeID
== OSTypeID(OSData
)) {
178 OSData
* dataObj
= OSDynamicCast(OSData
, obj
);
179 len
= dataObj
->getLength();
188 primitive_type_collect(struct mac_module_data_element
*element
, OSObject
*value
)
190 const OSMetaClass
*typeID
;
192 typeID
= OSTypeIDInst(value
);
193 if (typeID
== OSTypeID(OSString
)) {
194 OSString
*stringObj
= OSDynamicCast(OSString
, value
);
195 element
->value_type
= MAC_DATA_TYPE_PRIMITIVE
;
196 element
->value_size
= stringObj
->getLength() + 1;
197 DPRINTF(("osdict: string %s size %d\n",
198 stringObj
->getCStringNoCopy(), element
->value_size
));
199 memcpy(element
->value
, stringObj
->getCStringNoCopy(),
200 element
->value_size
);
201 } else if (typeID
== OSTypeID(OSNumber
)) {
202 OSNumber
*numberObj
= OSDynamicCast(OSNumber
, value
);
203 element
->value_type
= MAC_DATA_TYPE_PRIMITIVE
;
204 element
->value_size
= sprintf(element
->value
, "%u",
205 numberObj
->unsigned32BitValue()) + 1;
206 } else if (typeID
== OSTypeID(OSBoolean
)) {
207 OSBoolean
*boolObj
= OSDynamicCast(OSBoolean
, value
);
208 element
->value_type
= MAC_DATA_TYPE_PRIMITIVE
;
209 if (boolObj
->isTrue()) {
210 strcpy(element
->value
, "true");
211 element
->value_size
= 5;
213 strcpy(element
->value
, "false");
214 element
->value_size
= 6;
216 } else if (typeID
== OSTypeID(OSData
)) {
217 OSData
*dataObj
= OSDynamicCast(OSData
, value
);
218 element
->value_type
= MAC_DATA_TYPE_PRIMITIVE
;
219 element
->value_size
= dataObj
->getLength();
220 DPRINTF(("osdict: data size %d\n", dataObj
->getLength()));
221 memcpy(element
->value
, dataObj
->getBytesNoCopy(),
222 element
->value_size
);
226 /*********************************************************************
227 * This function takes an OSDictionary and returns a struct mac_module_data
229 *********************************************************************/
230 struct mac_module_data
*
231 osdict_encode(OSDictionary
*dict
)
233 const OSMetaClass
* typeID
; // don't release
234 OSString
* key
= NULL
; // don't release
235 OSCollectionIterator
* keyIterator
= 0; // must release
236 struct mac_module_data
* module_data
= 0;
237 struct mac_module_data_element
* element
;
238 unsigned int strtabsize
= 0;
239 unsigned int listtabsize
= 0;
240 unsigned int dicttabsize
= 0;
241 unsigned int nkeys
= 0;
242 unsigned int datalen
;
244 char *listtab
= NULL
;
245 char *dicttab
= NULL
;
246 vm_offset_t data_addr
;
248 keyIterator
= OSCollectionIterator::withCollection(dict
);
252 /* Iterate over OSModuleData to figure out total size */
253 while ( (key
= OSDynamicCast(OSString
, keyIterator
->getNextObject())) ) {
255 // Get the key's value and determine its type
256 OSObject
* value
= dict
->getObject(key
);
260 typeID
= OSTypeIDInst(value
);
261 if (primitive_type(value
)) {
262 strtabsize
+= primitive_type_length(value
);
264 else if (typeID
== OSTypeID(OSArray
)) {
265 unsigned int k
, cnt
, nents
;
266 OSArray
*arrayObj
= OSDynamicCast(OSArray
, value
);
269 cnt
= arrayObj
->getCount();
270 for (k
= 0; k
< cnt
; k
++) {
271 value
= arrayObj
->getObject(k
);
272 typeID
= OSTypeIDInst(value
);
273 if (primitive_type(value
)) {
274 listtabsize
+= primitive_type_length(value
);
277 else if (typeID
== OSTypeID(OSDictionary
)) {
279 OSDictionary
*dictObj
;
281 OSCollectionIterator
*dictIterator
;
284 dictObj
= OSDynamicCast(OSDictionary
, value
);
285 dictIterator
= OSCollectionIterator::withCollection(dictObj
);
288 while ((dictkey
= OSDynamicCast(OSString
,
289 dictIterator
->getNextObject()))) {
292 dictvalue
= dictObj
->getObject(dictkey
);
295 if (primitive_type(dictvalue
)) {
296 strtabsize
+= primitive_type_length(dictvalue
);
299 continue; /* Only handle primitive types here. */
302 * Allow for the "arraynnn/" prefix in the key length.
304 strtabsize
+= dictkey
->getLength() + 1;
307 dictIterator
->release();
309 dicttabsize
+= sizeof(struct mac_module_data_list
) +
310 dents
* sizeof(struct mac_module_data_element
);
315 continue; /* Skip everything else. */
320 listtabsize
+= sizeof(struct mac_module_data_list
) +
321 (nents
- 1) * sizeof(struct mac_module_data_element
);
324 continue; /* skip anything else */
326 strtabsize
+= key
->getLength() + 1;
333 * Allocate and fill in the module data structures.
335 datalen
= sizeof(struct mac_module_data
) +
336 sizeof(mac_module_data_element
) * (nkeys
- 1) +
337 strtabsize
+ listtabsize
+ dicttabsize
;
338 DPRINTF(("osdict: datalen %d strtabsize %d listtabsize %d dicttabsize %d\n",
339 datalen
, strtabsize
, listtabsize
, dicttabsize
));
340 if (kmem_alloc(kernel_map
, &data_addr
, datalen
) != KERN_SUCCESS
)
342 module_data
= (mac_module_data
*)data_addr
;
343 module_data
->base_addr
= data_addr
;
344 module_data
->size
= datalen
;
345 module_data
->count
= nkeys
;
346 strtab
= (char *)&module_data
->data
[nkeys
];
347 listtab
= strtab
+ strtabsize
;
348 dicttab
= listtab
+ listtabsize
;
349 DPRINTF(("osdict: data_addr %p strtab %p listtab %p dicttab %p end %p\n",
350 data_addr
, strtab
, listtab
, dicttab
, data_addr
+ datalen
));
352 keyIterator
->reset();
354 element
= &module_data
->data
[0];
355 DPRINTF(("osdict: element %p\n", element
));
356 while ( (key
= OSDynamicCast(OSString
, keyIterator
->getNextObject())) ) {
358 // Get the key's value and determine its type
359 OSObject
* value
= dict
->getObject(key
);
364 DPRINTF(("osdict: element @%p\n", element
));
365 element
->key
= strtab
;
366 element
->key_size
= key
->getLength() + 1;
367 DPRINTF(("osdict: key %s size %d @%p\n", key
->getCStringNoCopy(), element
->key_size
, strtab
));
368 memcpy(element
->key
, key
->getCStringNoCopy(), element
->key_size
);
370 typeID
= OSTypeIDInst(value
);
371 if (primitive_type(value
)) {
373 element
->value
= element
->key
+ element
->key_size
;
374 DPRINTF(("osdict: primitive element value %p\n", element
->value
));
375 primitive_type_collect(element
, value
);
376 strtab
+= element
->key_size
+ element
->value_size
;
377 DPRINTF(("osdict: new strtab %p\n", strtab
));
379 else if (typeID
== OSTypeID(OSArray
)) {
380 unsigned int k
, cnt
, nents
;
382 struct mac_module_data_list
*arrayhd
;
383 struct mac_module_data_element
*ele
;
384 OSArray
*arrayObj
= OSDynamicCast(OSArray
, value
);
386 element
->value
= listtab
;
387 DPRINTF(("osdict: array element value %p\n", element
->value
));
388 element
->value_type
= MAC_DATA_TYPE_ARRAY
;
389 arrayhd
= (struct mac_module_data_list
*)element
->value
;
391 DPRINTF(("osdict: arrayhd %p\n", arrayhd
));
393 astrtab
= strtab
+ element
->key_size
;
394 ele
= &(arrayhd
->list
[0]);
395 cnt
= arrayObj
->getCount();
396 for (k
= 0; k
< cnt
; k
++) {
397 value
= arrayObj
->getObject(k
);
398 DPRINTF(("osdict: array ele %d @%p\n", nents
, ele
));
401 typeID
= OSTypeIDInst(value
);
402 if (primitive_type(value
)) {
403 if (arrayhd
->type
!= 0 &&
404 arrayhd
->type
!= MAC_DATA_TYPE_PRIMITIVE
)
406 arrayhd
->type
= MAC_DATA_TYPE_PRIMITIVE
;
407 ele
->value
= astrtab
;
408 primitive_type_collect(ele
, value
);
409 astrtab
+= ele
->value_size
;
410 DPRINTF(("osdict: array new astrtab %p\n", astrtab
));
412 else if (typeID
== OSTypeID(OSDictionary
)) {
415 OSDictionary
*dictObj
;
417 OSCollectionIterator
*dictIterator
;
418 struct mac_module_data_list
*dicthd
;
419 struct mac_module_data_element
*dele
;
421 if (arrayhd
->type
!= 0 &&
422 arrayhd
->type
!= MAC_DATA_TYPE_DICT
)
424 dictObj
= OSDynamicCast(OSDictionary
, value
);
425 dictIterator
= OSCollectionIterator::withCollection(dictObj
);
428 DPRINTF(("osdict: dict\n"));
429 ele
->value
= dicttab
;
430 ele
->value_type
= MAC_DATA_TYPE_DICT
;
431 dicthd
= (struct mac_module_data_list
*)ele
->value
;
432 DPRINTF(("osdict: dicthd %p\n", dicthd
));
435 while ((dictkey
= OSDynamicCast(OSString
,
436 dictIterator
->getNextObject()))) {
439 dictvalue
= dictObj
->getObject(dictkey
);
442 dele
= &(dicthd
->list
[dents
]);
443 DPRINTF(("osdict: dict ele %d @%p\n", dents
, dele
));
444 if (primitive_type(dictvalue
)) {
446 dele
->key_size
= dictkey
->getLength() + 1;
447 DPRINTF(("osdict: dictkey %s size %d @%p\n",
448 dictkey
->getCStringNoCopy(), dictkey
->getLength(), dstrtab
));
449 memcpy(dele
->key
, dictkey
->getCStringNoCopy(),
451 dele
->value
= dele
->key
+ dele
->key_size
;
452 primitive_type_collect(dele
, dictvalue
);
453 dstrtab
+= dele
->key_size
+ dele
->value_size
;
454 DPRINTF(("osdict: dict new dstrtab %p\n", dstrtab
));
457 continue; /* Only handle primitive types here. */
461 dictIterator
->release();
464 arrayhd
->type
= MAC_DATA_TYPE_DICT
;
465 ele
->value_size
= sizeof(struct mac_module_data_list
) +
466 (dents
- 1) * sizeof(struct mac_module_data_element
);
467 DPRINTF(("osdict: dict ele size %d ents %d\n", ele
->value_size
, dents
));
468 dicttab
+= ele
->value_size
;
469 DPRINTF(("osdict: new dicttab %p\n", dicttab
));
470 dicthd
->count
= dents
;
474 continue; /* Skip everything else. */
481 element
->value_size
= sizeof(struct mac_module_data_list
) +
482 (nents
- 1) * sizeof(struct mac_module_data_element
);
483 listtab
+= element
->value_size
;
484 DPRINTF(("osdict: new listtab %p\n", listtab
));
485 arrayhd
->count
= nents
;
487 DPRINTF(("osdict: new strtab %p\n", strtab
));
490 continue; /* skip anything else */
494 DPRINTF(("module_data list @%p, key %p value %p\n",
495 module_data
, module_data
->data
[0].key
, module_data
->data
[0].value
));
498 keyIterator
->release();
502 /*********************************************************************
503 * This function takes a plist and looks for an OSModuleData dictionary.
504 * If it is found, an encoded copy is returned.
505 *********************************************************************/
507 get_module_data(OSDictionary
* kextPlist
, mach_msg_type_number_t
* datalen
)
510 OSDictionary
* kextModuleData
= 0; // don't release
511 struct mac_module_data
* module_data
= 0;
512 vm_map_copy_t copy
= 0;
514 kextModuleData
= OSDynamicCast(OSDictionary
,
515 kextPlist
->getObject("OSModuleData"));
519 module_data
= osdict_encode(kextModuleData
);
522 *datalen
= module_data
->size
;
524 * Make a CoW copy of data and free the original. The copy is
525 * consumed by a call to vm_map_copyout() in kmod_start_or_stop().
527 vm_map_copyin(kernel_map
, (vm_offset_t
)module_data
, *datalen
, FALSE
, ©
);
528 kmem_free(kernel_map
, (vm_offset_t
)module_data
, *datalen
);
529 DPRINTF(("get_module_data: copy @ %p\n", copy
));
531 return (kmod_args_t
)copy
;
536 kern_return_t
start_prelink_module(UInt32 moduleIndex
)
538 kern_return_t kr
= KERN_SUCCESS
;
540 SInt32 count
, where
, end
;
542 SInt32 next
, lastDep
;
548 prelinkedModules
= gIOPrelinkedModules
;
550 togo
= IONew(UInt32
, prelinkedModules
->getCount());
551 togo
[0] = moduleIndex
;
554 for (next
= 0; next
< count
; next
++)
556 dict
= (OSDictionary
*) prelinkedModules
->getObject(togo
[next
]);
558 data
= OSDynamicCast(OSData
, dict
->getObject("OSBundlePrelink"));
561 // already started or no code
562 if (togo
[next
] == moduleIndex
)
569 prelink
= (UInt32
*) data
->getBytesNoCopy();
570 lastDep
= OSReadBigInt32(prelink
, 12);
571 for (SInt32 idx
= OSReadBigInt32(prelink
, 8); idx
< lastDep
; idx
+= sizeof(UInt32
))
573 UInt32 depIdx
= OSReadBigInt32(prelink
, idx
) - 1;
575 for (where
= next
+ 1;
576 (where
< count
) && (togo
[where
] > depIdx
);
581 if (togo
[where
] == depIdx
)
583 for (end
= count
; end
!= where
; end
--)
584 togo
[end
] = togo
[end
- 1];
587 togo
[where
] = depIdx
;
591 if (KERN_SUCCESS
!= kr
)
594 for (next
= (count
- 1); next
>= 0; next
--)
596 dict
= (OSDictionary
*) prelinkedModules
->getObject(togo
[next
]);
598 data
= OSDynamicCast(OSData
, dict
->getObject("OSBundlePrelink"));
601 prelink
= (UInt32
*) data
->getBytesNoCopy();
604 kmod_info_t
* kmod_info
= (kmod_info_t
*) OSReadBigInt32(prelink
, 0);
606 kr
= kmod_create_internal(kmod_info
, &id
);
607 if (KERN_SUCCESS
!= kr
)
610 lastDep
= OSReadBigInt32(prelink
, 12);
611 for (SInt32 idx
= OSReadBigInt32(prelink
, 8); idx
< lastDep
; idx
+= sizeof(UInt32
))
613 OSDictionary
* depDict
;
614 kmod_info_t
* depInfo
;
616 depDict
= (OSDictionary
*) prelinkedModules
->getObject(OSReadBigInt32(prelink
, idx
) - 1);
617 str
= OSDynamicCast(OSString
, depDict
->getObject(kModuleKey
));
618 depInfo
= kmod_lookupbyname_locked(str
->getCStringNoCopy());
621 kr
= kmod_retain(KMOD_PACK_IDS(id
, depInfo
->id
));
622 kfree(depInfo
, sizeof(kmod_info_t
));
624 IOLog("%s: NO DEP %s\n", kmod_info
->name
, str
->getCStringNoCopy());
626 dict
->removeObject("OSBundlePrelink");
628 if (kmod_info
->start
)
629 kr
= kmod_start_or_stop(kmod_info
->id
, 1, 0, 0);
632 IODelete(togo
, UInt32
, prelinkedModules
->getCount());
637 /*********************************************************************
638 * This is a function that IOCatalogue calls in order to load a kmod.
639 *********************************************************************/
642 kern_return_t
kmod_load_from_cache_sym(const OSSymbol
* kmod_name
)
644 OSArray
* prelinkedModules
= gIOPrelinkedModules
;
645 kern_return_t result
= KERN_FAILURE
;
650 if (!gIOPrelinkedModules
)
654 (dict
= (OSDictionary
*) prelinkedModules
->getObject(idx
));
657 if ((ident
= dict
->getObject(kModuleKey
))
658 && kmod_name
->isEqualTo(ident
))
663 if (kernelLinkerPresent
&& dict
->getObject("OSBundleDefer"))
665 kmod_load_extension((char *) kmod_name
->getCStringNoCopy());
666 result
= kIOReturnOffline
;
669 result
= start_prelink_module(idx
);
675 extern "C" Boolean
kmod_load_request(const char * moduleName
, Boolean make_request
)
677 bool ret
, cacheMiss
= false;
679 const OSSymbol
* sym
= 0;
680 kmod_info_t
* kmod_info
;
685 /* To make sure this operation completes even if a bad extension needs
686 * to be removed, take the kld lock for this whole block, spanning the
687 * kmod_load_function() and remove_startup_extension_function() calls.
689 IOLockLock(gIOKLDLock
);
692 // Is the module already loaded?
693 ret
= (0 != (kmod_info
= kmod_lookupbyname_locked((char *)moduleName
)));
695 kfree(kmod_info
, sizeof(kmod_info_t
));
698 sym
= OSSymbol::withCString(moduleName
);
704 kr
= kmod_load_from_cache_sym(sym
);
705 ret
= (kIOReturnSuccess
== kr
);
707 if (ret
|| !make_request
|| (kr
== kIOReturnOffline
))
710 // If the module hasn't been loaded, then load it.
711 if (!kmod_load_function
) {
712 IOLog("IOCatalogue: %s cannot be loaded "
713 "(kmod load function not set).\n",
719 kr
= kmod_load_function((char *)moduleName
);
721 if (ret
!= kIOReturnSuccess
) {
722 IOLog("IOCatalogue: %s cannot be loaded.\n", moduleName
);
724 /* If the extension couldn't be loaded this time,
725 * make it unavailable so that no more requests are
726 * made in vain. This also enables other matching
727 * extensions to have a chance.
729 if (kernelLinkerPresent
&& remove_startup_extension_function
) {
730 (*remove_startup_extension_function
)(moduleName
);
734 } else if (kernelLinkerPresent
) {
735 // If kern linker is here, the driver is actually loaded,
740 // kern linker isn't here, a request has been queued
741 // but the module isn't necessarily loaded yet, so stall.
747 IOLockUnlock(gIOKLDLock
);
751 IOLockLock(gIOCatalogLock
);
752 gIOCatalogModuleRequests
->setObject(sym
);
754 gIOCatalogCacheMisses
->setObject(sym
);
755 IOLockUnlock(gIOCatalogLock
);
761 extern "C" kern_return_t
kmod_unload_cache(void)
763 OSArray
* prelinkedModules
= gIOPrelinkedModules
;
764 kern_return_t result
= KERN_FAILURE
;
770 if (!gIOPrelinkedModules
)
773 IOLockLock(gIOKLDLock
);
775 (dict
= (OSDictionary
*) prelinkedModules
->getObject(idx
));
778 data
= OSDynamicCast(OSData
, dict
->getObject("OSBundlePrelink"));
781 prelink
= (UInt32
*) data
->getBytesNoCopy();
783 kmod_info_t
* kmod_info
= (kmod_info_t
*) OSReadBigInt32(prelink
, 0);
785 virt
= ml_static_ptovirt(kmod_info
->address
);
787 ml_static_mfree(virt
, kmod_info
->size
);
791 gIOPrelinkedModules
->release();
792 gIOPrelinkedModules
= 0;
794 IOLockUnlock(gIOKLDLock
);
799 extern "C" kern_return_t
kmod_load_from_cache(const char * kmod_name
)
802 const OSSymbol
* sym
= OSSymbol::withCStringNoCopy(kmod_name
);
806 kr
= kmod_load_from_cache_sym(sym
);
810 kr
= kIOReturnNoMemory
;
815 /*********************************************************************
816 *********************************************************************/
818 static void UniqueProperties( OSDictionary
* dict
)
822 data
= OSDynamicCast( OSString
, dict
->getObject( gIOClassKey
));
824 const OSSymbol
*classSymbol
= OSSymbol::withString(data
);
826 dict
->setObject( gIOClassKey
, (OSSymbol
*) classSymbol
);
827 classSymbol
->release();
830 data
= OSDynamicCast( OSString
, dict
->getObject( gIOMatchCategoryKey
));
832 const OSSymbol
*classSymbol
= OSSymbol::withString(data
);
834 dict
->setObject( gIOMatchCategoryKey
, (OSSymbol
*) classSymbol
);
835 classSymbol
->release();
839 void IOCatalogue::initialize( void )
842 OSString
* errorString
;
845 extern const char * gIOKernelConfigTables
;
847 array
= OSDynamicCast(OSArray
, OSUnserialize(gIOKernelConfigTables
, &errorString
));
848 if (!array
&& errorString
) {
849 IOLog("KernelConfigTables syntax error: %s\n",
850 errorString
->getCStringNoCopy());
851 errorString
->release();
854 gIOClassKey
= OSSymbol::withCStringNoCopy( kIOClassKey
);
855 gIOProbeScoreKey
= OSSymbol::withCStringNoCopy( kIOProbeScoreKey
);
856 gIOModuleIdentifierKey
= OSSymbol::withCStringNoCopy( kModuleKey
);
857 gIOCatalogModuleRequests
= OSSet::withCapacity(16);
858 gIOCatalogCacheMisses
= OSSet::withCapacity(16);
859 gIOCatalogROMMkexts
= OSSet::withCapacity(4);
861 assert( array
&& gIOClassKey
&& gIOProbeScoreKey
862 && gIOModuleIdentifierKey
&& gIOCatalogModuleRequests
);
864 gIOCatalogue
= new IOCatalogue
;
865 assert(gIOCatalogue
);
866 rc
= gIOCatalogue
->init(array
);
871 // Initialize the IOCatalog object.
872 bool IOCatalogue::init(OSArray
* initArray
)
876 if ( !super::init() )
883 kernelTables
= OSCollectionIterator::withCollection( array
);
885 gIOCatalogLock
= IOLockAlloc();
886 gIOKLDLock
= IOLockAlloc();
888 lock
= gIOCatalogLock
;
889 kld_lock
= gIOKLDLock
;
891 kernelTables
->reset();
892 while( (dict
= (OSDictionary
*) kernelTables
->getNextObject())) {
893 UniqueProperties(dict
);
894 if( 0 == dict
->getObject( gIOClassKey
))
895 IOLog("Missing or bad \"%s\" key\n",
896 gIOClassKey
->getCStringNoCopy());
900 AbsoluteTime deadline
;
901 clock_interval_to_deadline( 1000, kMillisecondScale
);
902 thread_call_func_delayed( ping
, this, deadline
);
908 // Release all resources used by IOCatalogue and deallocate.
909 // This will probably never be called.
910 void IOCatalogue::free( void )
916 kernelTables
->release();
923 static int hackLimit
;
925 enum { kDriversPerIter
= 4 };
927 void IOCatalogue::ping( thread_call_param_t arg
, thread_call_param_t
)
929 IOCatalogue
* self
= (IOCatalogue
*) arg
;
931 OSDictionary
* table
;
934 set
= OSOrderedSet::withCapacity( 1 );
936 IOLockLock( &self
->lock
);
938 for( newLimit
= 0; newLimit
< kDriversPerIter
; newLimit
++) {
939 table
= (OSDictionary
*) self
->array
->getObject(
940 hackLimit
+ newLimit
);
942 set
->setLastObject( table
);
944 OSSymbol
* sym
= (OSSymbol
*) table
->getObject( gIOClassKey
);
945 kprintf("enabling %s\n", sym
->getCStringNoCopy());
953 IOService::catalogNewDrivers( set
);
955 hackLimit
+= newLimit
;
958 IOLockUnlock( &self
->lock
);
960 if( kDriversPerIter
== newLimit
) {
961 AbsoluteTime deadline
;
962 clock_interval_to_deadline( 500, kMillisecondScale
);
963 thread_call_func_delayed( ping
, this, deadline
);
968 OSOrderedSet
* IOCatalogue::findDrivers( IOService
* service
,
969 SInt32
* generationCount
)
971 OSDictionary
* nextTable
;
975 set
= OSOrderedSet::withCapacity( 1, IOServiceOrdering
,
976 (void *)gIOProbeScoreKey
);
981 kernelTables
->reset();
986 while( (nextTable
= (OSDictionary
*) kernelTables
->getNextObject())) {
988 if( hackIndex
++ > hackLimit
)
991 imports
= OSDynamicCast( OSString
,
992 nextTable
->getObject( gIOProviderClassKey
));
993 if( imports
&& service
->metaCast( imports
))
994 set
->setObject( nextTable
);
997 *generationCount
= getGenerationCount();
999 IOLockUnlock( lock
);
1004 // Is personality already in the catalog?
1005 OSOrderedSet
* IOCatalogue::findDrivers( OSDictionary
* matching
,
1006 SInt32
* generationCount
)
1008 OSDictionary
* dict
;
1011 UniqueProperties(matching
);
1013 set
= OSOrderedSet::withCapacity( 1, IOServiceOrdering
,
1014 (void *)gIOProbeScoreKey
);
1017 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 searches.
1023 if ( dict
->isEqualTo(matching
, matching
) )
1024 set
->setObject(dict
);
1026 *generationCount
= getGenerationCount();
1027 IOLockUnlock( lock
);
1032 // Add a new personality to the set if it has a unique IOResourceMatchKey value.
1033 // XXX -- svail: This should be optimized.
1034 // esb - There doesn't seem like any reason to do this - it causes problems
1035 // esb - when there are more than one loadable driver matching on the same provider class
1036 static void AddNewImports( OSOrderedSet
* set
, OSDictionary
* dict
)
1038 set
->setObject(dict
);
1041 // Add driver config tables to catalog and start matching process.
1042 bool IOCatalogue::addDrivers(OSArray
* drivers
,
1043 bool doNubMatching
)
1045 OSCollectionIterator
* iter
;
1046 OSDictionary
* dict
;
1049 OSString
* moduleName
;
1053 persons
= OSDynamicCast(OSArray
, drivers
);
1057 iter
= OSCollectionIterator::withCollection( persons
);
1061 set
= OSOrderedSet::withCapacity( 10, IOServiceOrdering
,
1062 (void *)gIOProbeScoreKey
);
1069 while ( (dict
= (OSDictionary
*) iter
->getNextObject()) )
1071 if ((moduleName
= OSDynamicCast(OSString
, dict
->getObject("OSBundleModuleDemand"))))
1073 IOLockUnlock( lock
);
1074 ret
= kmod_load_request(moduleName
->getCStringNoCopy(), false);
1082 UniqueProperties( dict
);
1084 // Add driver personality to catalogue.
1085 count
= array
->getCount();
1087 OSDictionary
* driver
;
1089 // Be sure not to double up on personalities.
1090 driver
= (OSDictionary
*)array
->getObject(count
);
1092 /* Unlike in other functions, this comparison must be exact!
1093 * The catalogue must be able to contain personalities that
1094 * are proper supersets of others.
1095 * Do not compare just the properties present in one driver
1096 * pesonality or the other.
1098 if (dict
->isEqualTo(driver
))
1105 ret
= array
->setObject( dict
);
1109 AddNewImports( set
, dict
);
1112 // Start device matching.
1113 if (doNubMatching
&& (set
->getCount() > 0)) {
1114 IOService::catalogNewDrivers( set
);
1117 IOLockUnlock( lock
);
1125 // Remove drivers from the catalog which match the
1126 // properties in the matching dictionary.
1127 bool IOCatalogue::removeDrivers( OSDictionary
* matching
,
1130 OSCollectionIterator
* tables
;
1131 OSDictionary
* dict
;
1133 OSArray
* arrayCopy
;
1138 set
= OSOrderedSet::withCapacity(10,
1140 (void *)gIOProbeScoreKey
);
1144 arrayCopy
= OSArray::withCapacity(100);
1150 tables
= OSCollectionIterator::withCollection(arrayCopy
);
1151 arrayCopy
->release();
1157 UniqueProperties( matching
);
1160 kernelTables
->reset();
1161 arrayCopy
->merge(array
);
1162 array
->flushCollection();
1164 while ( (dict
= (OSDictionary
*)tables
->getNextObject()) ) {
1166 /* This comparison must be done with only the keys in the
1167 * "matching" dict to enable general searches.
1169 if ( dict
->isEqualTo(matching
, matching
) ) {
1170 AddNewImports( set
, dict
);
1174 array
->setObject(dict
);
1176 // Start device matching.
1177 if ( doNubMatching
&& (set
->getCount() > 0) ) {
1178 IOService::catalogNewDrivers(set
);
1181 IOLockUnlock( lock
);
1189 // Return the generation count.
1190 SInt32
IOCatalogue::getGenerationCount( void ) const
1192 return( generation
);
1195 bool IOCatalogue::isModuleLoaded( OSString
* moduleName
) const
1197 return isModuleLoaded(moduleName
->getCStringNoCopy());
1200 bool IOCatalogue::isModuleLoaded( const char * moduleName
) const
1202 return (kmod_load_request(moduleName
, true));
1205 // Check to see if module has been loaded already.
1206 bool IOCatalogue::isModuleLoaded( OSDictionary
* driver
) const
1208 OSString
* moduleName
= NULL
;
1213 moduleName
= OSDynamicCast(OSString
, driver
->getObject(gIOModuleIdentifierKey
));
1215 return isModuleLoaded(moduleName
);
1217 /* If a personality doesn't hold the "CFBundleIdentifier" key
1218 * it is assumed to be an "in-kernel" driver.
1223 // This function is called after a module has been loaded.
1224 void IOCatalogue::moduleHasLoaded( OSString
* moduleName
)
1226 OSDictionary
* dict
;
1228 dict
= OSDictionary::withCapacity(2);
1229 dict
->setObject(gIOModuleIdentifierKey
, moduleName
);
1230 startMatching(dict
);
1234 void IOCatalogue::moduleHasLoaded( const char * moduleName
)
1238 name
= OSString::withCString(moduleName
);
1239 moduleHasLoaded(name
);
1243 IOReturn
IOCatalogue::unloadModule( OSString
* moduleName
) const
1245 kmod_info_t
* k_info
= 0;
1249 ret
= kIOReturnBadArgument
;
1251 name
= moduleName
->getCStringNoCopy();
1252 k_info
= kmod_lookupbyname_locked((char *)name
);
1253 if ( k_info
&& (k_info
->reference_count
< 1) ) {
1254 if ( k_info
->stop
&&
1255 !((ret
= k_info
->stop(k_info
, 0)) == kIOReturnSuccess
) ) {
1257 kfree(k_info
, sizeof(kmod_info_t
));
1261 ret
= kmod_destroy(host_priv_self(), k_info
->id
);
1266 kfree(k_info
, sizeof(kmod_info_t
));
1272 static IOReturn
_terminateDrivers( OSDictionary
* matching
)
1274 OSDictionary
* dict
;
1276 IOService
* service
;
1280 return kIOReturnBadArgument
;
1282 ret
= kIOReturnSuccess
;
1284 iter
= IORegistryIterator::iterateOver(gIOServicePlane
,
1285 kIORegistryIterateRecursively
);
1287 return kIOReturnNoMemory
;
1289 UniqueProperties( matching
);
1291 // terminate instances.
1294 while( (service
= (IOService
*)iter
->getNextObject()) ) {
1295 dict
= service
->getPropertyTable();
1299 /* Terminate only for personalities that match the matching dictionary.
1300 * This comparison must be done with only the keys in the
1301 * "matching" dict to enable general matching.
1303 if ( !dict
->isEqualTo(matching
, matching
) )
1306 if ( !service
->terminate(kIOServiceRequired
|kIOServiceSynchronous
) ) {
1307 ret
= kIOReturnUnsupported
;
1311 } while( !service
&& !iter
->isValid());
1317 static IOReturn
_removeDrivers( OSArray
* array
, OSDictionary
* matching
)
1319 OSCollectionIterator
* tables
;
1320 OSDictionary
* dict
;
1321 OSArray
* arrayCopy
;
1322 IOReturn ret
= kIOReturnSuccess
;
1324 // remove configs from catalog.
1326 arrayCopy
= OSArray::withCapacity(100);
1328 return kIOReturnNoMemory
;
1330 tables
= OSCollectionIterator::withCollection(arrayCopy
);
1331 arrayCopy
->release();
1333 return kIOReturnNoMemory
;
1335 arrayCopy
->merge(array
);
1336 array
->flushCollection();
1338 while ( (dict
= (OSDictionary
*)tables
->getNextObject()) ) {
1340 /* Remove from the catalogue's array any personalities
1341 * that match the matching dictionary.
1342 * This comparison must be done with only the keys in the
1343 * "matching" dict to enable general matching.
1345 if ( dict
->isEqualTo(matching
, matching
) )
1348 array
->setObject(dict
);
1356 IOReturn
IOCatalogue::terminateDrivers( OSDictionary
* matching
)
1360 ret
= _terminateDrivers(matching
);
1362 if (kIOReturnSuccess
== ret
)
1363 ret
= _removeDrivers(array
, matching
);
1364 kernelTables
->reset();
1365 IOLockUnlock( lock
);
1370 IOReturn
IOCatalogue::terminateDriversForModule(
1371 OSString
* moduleName
,
1375 OSDictionary
* dict
;
1377 dict
= OSDictionary::withCapacity(1);
1379 return kIOReturnNoMemory
;
1381 dict
->setObject(gIOModuleIdentifierKey
, moduleName
);
1383 ret
= _terminateDrivers(dict
);
1385 if (kIOReturnSuccess
== ret
)
1386 ret
= _removeDrivers(array
, dict
);
1387 kernelTables
->reset();
1389 // Unload the module itself.
1390 if ( unload
&& ret
== kIOReturnSuccess
) {
1391 // Do kmod stop first.
1392 ret
= unloadModule(moduleName
);
1395 IOLockUnlock( lock
);
1402 IOReturn
IOCatalogue::terminateDriversForModule(
1403 const char * moduleName
,
1409 name
= OSString::withCString(moduleName
);
1411 return kIOReturnNoMemory
;
1413 ret
= terminateDriversForModule(name
, unload
);
1419 bool IOCatalogue::startMatching( OSDictionary
* matching
)
1421 OSDictionary
* dict
;
1427 set
= OSOrderedSet::withCapacity(10, IOServiceOrdering
,
1428 (void *)gIOProbeScoreKey
);
1433 kernelTables
->reset();
1435 while ( (dict
= (OSDictionary
*)kernelTables
->getNextObject()) ) {
1437 /* This comparison must be done with only the keys in the
1438 * "matching" dict to enable general matching.
1440 if ( dict
->isEqualTo(matching
, matching
) )
1441 AddNewImports(set
, dict
);
1443 // Start device matching.
1444 if ( set
->getCount() > 0 ) {
1445 IOService::catalogNewDrivers(set
);
1449 IOLockUnlock( lock
);
1456 void IOCatalogue::reset(void)
1458 IOLog("Resetting IOCatalogue.\n");
1461 bool IOCatalogue::serialize(OSSerialize
* s
) const
1466 return super::serialize(s
);
1469 bool IOCatalogue::serializeData(IOOptionBits kind
, OSSerialize
* s
) const
1471 kern_return_t kr
= kIOReturnSuccess
;
1475 case kIOCatalogGetContents
:
1476 if (!array
->serialize(s
))
1477 kr
= kIOReturnNoMemory
;
1480 case kIOCatalogGetModuleDemandList
:
1482 if (!gIOCatalogModuleRequests
->serialize(s
))
1483 kr
= kIOReturnNoMemory
;
1484 IOLockUnlock( lock
);
1487 case kIOCatalogGetCacheMissList
:
1489 if (!gIOCatalogCacheMisses
->serialize(s
))
1490 kr
= kIOReturnNoMemory
;
1491 IOLockUnlock( lock
);
1494 case kIOCatalogGetROMMkextList
:
1497 if (!gIOCatalogROMMkexts
|| !gIOCatalogROMMkexts
->getCount())
1498 kr
= kIOReturnNoResources
;
1499 else if (!gIOCatalogROMMkexts
->serialize(s
))
1500 kr
= kIOReturnNoMemory
;
1502 if (gIOCatalogROMMkexts
)
1504 gIOCatalogROMMkexts
->release();
1505 gIOCatalogROMMkexts
= 0;
1508 IOLockUnlock( lock
);
1512 kr
= kIOReturnBadArgument
;
1520 bool IOCatalogue::recordStartupExtensions(void) {
1521 bool result
= false;
1523 IOLockLock(kld_lock
);
1524 if (kernelLinkerPresent
&& record_startup_extensions_function
) {
1525 result
= (*record_startup_extensions_function
)();
1527 IOLog("Can't record startup extensions; "
1528 "kernel linker is not present.\n");
1531 IOLockUnlock(kld_lock
);
1537 /*********************************************************************
1538 * This function operates on sections retrieved from the currently running
1539 * 32 bit mach kernel.
1540 *********************************************************************/
1541 bool IOCatalogue::addExtensionsFromArchive(OSData
* mkext
)
1544 bool result
= false;
1547 /* The mkext we've been handed (or the data it references) can go away,
1548 * so we need to make a local copy to keep around as long as it might
1551 copyData
= OSData::withData(mkext
);
1554 struct section
* infosect
;
1556 infosect
= getsectbyname("__PRELINK", "__info");
1557 prelinked
= (infosect
&& infosect
->addr
&& infosect
->size
);
1559 IOLockLock(kld_lock
);
1561 if (gIOCatalogROMMkexts
)
1562 gIOCatalogROMMkexts
->setObject(copyData
);
1566 } else if (kernelLinkerPresent
&& add_from_mkext_function
) {
1567 result
= (*add_from_mkext_function
)(copyData
);
1569 IOLog("Can't add startup extensions from archive; "
1570 "kernel linker is not present.\n");
1574 IOLockUnlock(kld_lock
);
1576 copyData
->release();
1582 /*********************************************************************
1583 * This function clears out all references to the in-kernel linker,
1584 * frees the list of startup extensions in extensionDict, and
1585 * deallocates the kernel's __KLD segment to reclaim that memory.
1587 * The segments it operates on are strictly 32 bit segments.
1588 *********************************************************************/
1589 kern_return_t
IOCatalogue::removeKernelLinker(void) {
1590 kern_return_t result
= KERN_SUCCESS
;
1591 struct segment_command
* segmentLE
, *segmentKLD
;
1592 boolean_t keepsyms
= FALSE
;
1593 #if __ppc__ || __arm__
1594 char * dt_segment_name
;
1595 void * segment_paddress
;
1599 /* This must be the very first thing done by this function.
1601 IOLockLock(kld_lock
);
1604 /* If the kernel linker isn't here, that's automatically
1607 if (!kernelLinkerPresent
) {
1608 result
= KERN_SUCCESS
;
1612 PE_parse_boot_arg("keepsyms", &keepsyms
);
1614 IOLog("Jettisoning kernel linker.\n");
1616 kernelLinkerPresent
= 0;
1618 /* Set the kmod_load_extension function as the means for loading
1619 * a kernel extension.
1621 kmod_load_function
= &kmod_load_extension
;
1623 record_startup_extensions_function
= 0;
1624 add_from_mkext_function
= 0;
1625 remove_startup_extension_function
= 0;
1628 /* Invoke destructors for the __KLD and __LINKEDIT segments.
1629 * Do this for all segments before actually freeing their
1630 * memory so that any cross-dependencies (not that there
1631 * should be any) are handled.
1633 segmentKLD
= getsegbyname("__KLD");
1635 IOLog("error removing kernel linker: can't find __KLD segment\n");
1636 result
= KERN_FAILURE
;
1639 OSRuntimeUnloadCPPForSegment(segmentKLD
);
1641 #if __ppc__ || __arm__
1642 /* Free the memory that was set up by bootx.
1644 dt_segment_name
= "Kernel-__KLD";
1645 if (0 == IODTGetLoaderInfo(dt_segment_name
, &segment_paddress
, &segment_size
)) {
1646 IODTFreeLoaderInfo(dt_segment_name
, (void *)segment_paddress
,
1650 /* On x86, use the mapping data from the segment load command to
1651 * unload KLD directly, unless the keepsyms boot-arg was enabled.
1652 * This may invalidate any assumptions about "avail_start"
1653 * defining the lower bound for valid physical addresses.
1655 if (!keepsyms
&& segmentKLD
->vmaddr
&& segmentKLD
->vmsize
)
1656 ml_static_mfree(segmentKLD
->vmaddr
, segmentKLD
->vmsize
);
1661 struct section
* sect
;
1662 sect
= getsectbyname("__PRELINK", "__symtab");
1663 if (sect
&& sect
->addr
) {
1664 ml_static_mfree(sect
->addr
, sect
->size
);
1669 /* This must be the very last thing done before returning.
1671 IOLockUnlock(kld_lock
);
1676 /*********************************************************************
1677 * This function stops the catalogue from making kextd requests during
1679 *********************************************************************/
1680 void IOCatalogue::disableExternalLinker(void) {
1681 IOLockLock(gIOKLDLock
);
1682 /* If kmod_load_extension (the kextd requester function) is in use,
1683 * disable new module requests.
1685 if (kmod_load_function
== &kmod_load_extension
) {
1686 kmod_load_function
= NULL
;
1689 IOLockUnlock(gIOKLDLock
);
1693 void jettison_kernel_linker(void)
1695 if (gIOCatalogue
!= NULL
)
1696 gIOCatalogue
->removeKernelLinker();