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 record_kext_unload(k_info
->id
);
1255 if ( k_info
->stop
&&
1256 !((ret
= k_info
->stop(k_info
, 0)) == kIOReturnSuccess
) ) {
1258 kfree(k_info
, sizeof(kmod_info_t
));
1262 ret
= kmod_destroy(host_priv_self(), k_info
->id
);
1267 kfree(k_info
, sizeof(kmod_info_t
));
1273 static IOReturn
_terminateDrivers( OSDictionary
* matching
)
1275 OSDictionary
* dict
;
1277 IOService
* service
;
1281 return kIOReturnBadArgument
;
1283 ret
= kIOReturnSuccess
;
1285 iter
= IORegistryIterator::iterateOver(gIOServicePlane
,
1286 kIORegistryIterateRecursively
);
1288 return kIOReturnNoMemory
;
1290 UniqueProperties( matching
);
1292 // terminate instances.
1295 while( (service
= (IOService
*)iter
->getNextObject()) ) {
1296 dict
= service
->getPropertyTable();
1300 /* Terminate only for personalities that match the matching dictionary.
1301 * This comparison must be done with only the keys in the
1302 * "matching" dict to enable general matching.
1304 if ( !dict
->isEqualTo(matching
, matching
) )
1307 if ( !service
->terminate(kIOServiceRequired
|kIOServiceSynchronous
) ) {
1308 ret
= kIOReturnUnsupported
;
1312 } while( !service
&& !iter
->isValid());
1318 static IOReturn
_removeDrivers( OSArray
* array
, OSDictionary
* matching
)
1320 OSCollectionIterator
* tables
;
1321 OSDictionary
* dict
;
1322 OSArray
* arrayCopy
;
1323 IOReturn ret
= kIOReturnSuccess
;
1325 // remove configs from catalog.
1327 arrayCopy
= OSArray::withCapacity(100);
1329 return kIOReturnNoMemory
;
1331 tables
= OSCollectionIterator::withCollection(arrayCopy
);
1332 arrayCopy
->release();
1334 return kIOReturnNoMemory
;
1336 arrayCopy
->merge(array
);
1337 array
->flushCollection();
1339 while ( (dict
= (OSDictionary
*)tables
->getNextObject()) ) {
1341 /* Remove from the catalogue's array any personalities
1342 * that match the matching dictionary.
1343 * This comparison must be done with only the keys in the
1344 * "matching" dict to enable general matching.
1346 if ( dict
->isEqualTo(matching
, matching
) )
1349 array
->setObject(dict
);
1357 IOReturn
IOCatalogue::terminateDrivers( OSDictionary
* matching
)
1361 ret
= _terminateDrivers(matching
);
1363 if (kIOReturnSuccess
== ret
)
1364 ret
= _removeDrivers(array
, matching
);
1365 kernelTables
->reset();
1366 IOLockUnlock( lock
);
1371 IOReturn
IOCatalogue::terminateDriversForModule(
1372 OSString
* moduleName
,
1376 OSDictionary
* dict
;
1378 dict
= OSDictionary::withCapacity(1);
1380 return kIOReturnNoMemory
;
1382 dict
->setObject(gIOModuleIdentifierKey
, moduleName
);
1384 ret
= _terminateDrivers(dict
);
1386 if (kIOReturnSuccess
== ret
)
1387 ret
= _removeDrivers(array
, dict
);
1388 kernelTables
->reset();
1390 // Unload the module itself.
1391 if ( unload
&& ret
== kIOReturnSuccess
) {
1392 // Do kmod stop first.
1393 ret
= unloadModule(moduleName
);
1396 IOLockUnlock( lock
);
1403 IOReturn
IOCatalogue::terminateDriversForModule(
1404 const char * moduleName
,
1410 name
= OSString::withCString(moduleName
);
1412 return kIOReturnNoMemory
;
1414 ret
= terminateDriversForModule(name
, unload
);
1420 bool IOCatalogue::startMatching( OSDictionary
* matching
)
1422 OSDictionary
* dict
;
1428 set
= OSOrderedSet::withCapacity(10, IOServiceOrdering
,
1429 (void *)gIOProbeScoreKey
);
1434 kernelTables
->reset();
1436 while ( (dict
= (OSDictionary
*)kernelTables
->getNextObject()) ) {
1438 /* This comparison must be done with only the keys in the
1439 * "matching" dict to enable general matching.
1441 if ( dict
->isEqualTo(matching
, matching
) )
1442 AddNewImports(set
, dict
);
1444 // Start device matching.
1445 if ( set
->getCount() > 0 ) {
1446 IOService::catalogNewDrivers(set
);
1450 IOLockUnlock( lock
);
1457 void IOCatalogue::reset(void)
1459 IOLog("Resetting IOCatalogue.\n");
1462 bool IOCatalogue::serialize(OSSerialize
* s
) const
1467 return super::serialize(s
);
1470 bool IOCatalogue::serializeData(IOOptionBits kind
, OSSerialize
* s
) const
1472 kern_return_t kr
= kIOReturnSuccess
;
1476 case kIOCatalogGetContents
:
1477 if (!array
->serialize(s
))
1478 kr
= kIOReturnNoMemory
;
1481 case kIOCatalogGetModuleDemandList
:
1483 if (!gIOCatalogModuleRequests
->serialize(s
))
1484 kr
= kIOReturnNoMemory
;
1485 IOLockUnlock( lock
);
1488 case kIOCatalogGetCacheMissList
:
1490 if (!gIOCatalogCacheMisses
->serialize(s
))
1491 kr
= kIOReturnNoMemory
;
1492 IOLockUnlock( lock
);
1495 case kIOCatalogGetROMMkextList
:
1498 if (!gIOCatalogROMMkexts
|| !gIOCatalogROMMkexts
->getCount())
1499 kr
= kIOReturnNoResources
;
1500 else if (!gIOCatalogROMMkexts
->serialize(s
))
1501 kr
= kIOReturnNoMemory
;
1503 if (gIOCatalogROMMkexts
)
1505 gIOCatalogROMMkexts
->release();
1506 gIOCatalogROMMkexts
= 0;
1509 IOLockUnlock( lock
);
1513 kr
= kIOReturnBadArgument
;
1521 bool IOCatalogue::recordStartupExtensions(void) {
1522 bool result
= false;
1524 IOLockLock(kld_lock
);
1525 if (kernelLinkerPresent
&& record_startup_extensions_function
) {
1526 result
= (*record_startup_extensions_function
)();
1528 IOLog("Can't record startup extensions; "
1529 "kernel linker is not present.\n");
1532 IOLockUnlock(kld_lock
);
1538 /*********************************************************************
1539 * This function operates on sections retrieved from the currently running
1540 * 32 bit mach kernel.
1541 *********************************************************************/
1542 bool IOCatalogue::addExtensionsFromArchive(OSData
* mkext
)
1545 bool result
= false;
1548 /* The mkext we've been handed (or the data it references) can go away,
1549 * so we need to make a local copy to keep around as long as it might
1552 copyData
= OSData::withData(mkext
);
1555 struct section
* infosect
;
1557 infosect
= getsectbyname("__PRELINK", "__info");
1558 prelinked
= (infosect
&& infosect
->addr
&& infosect
->size
);
1560 IOLockLock(kld_lock
);
1562 if (gIOCatalogROMMkexts
)
1563 gIOCatalogROMMkexts
->setObject(copyData
);
1567 } else if (kernelLinkerPresent
&& add_from_mkext_function
) {
1568 result
= (*add_from_mkext_function
)(copyData
);
1570 IOLog("Can't add startup extensions from archive; "
1571 "kernel linker is not present.\n");
1575 IOLockUnlock(kld_lock
);
1577 copyData
->release();
1583 /*********************************************************************
1584 * This function clears out all references to the in-kernel linker,
1585 * frees the list of startup extensions in extensionDict, and
1586 * deallocates the kernel's __KLD segment to reclaim that memory.
1588 * The segments it operates on are strictly 32 bit segments.
1589 *********************************************************************/
1590 kern_return_t
IOCatalogue::removeKernelLinker(void) {
1591 kern_return_t result
= KERN_SUCCESS
;
1592 struct segment_command
* segmentLE
, *segmentKLD
;
1593 boolean_t keepsyms
= FALSE
;
1594 #if __ppc__ || __arm__
1595 char * dt_segment_name
;
1596 void * segment_paddress
;
1600 /* This must be the very first thing done by this function.
1602 IOLockLock(kld_lock
);
1605 /* If the kernel linker isn't here, that's automatically
1608 if (!kernelLinkerPresent
) {
1609 result
= KERN_SUCCESS
;
1613 PE_parse_boot_argn("keepsyms", &keepsyms
, sizeof (keepsyms
));
1615 IOLog("Jettisoning kernel linker.\n");
1617 kernelLinkerPresent
= 0;
1619 /* Set the kmod_load_extension function as the means for loading
1620 * a kernel extension.
1622 kmod_load_function
= &kmod_load_extension
;
1624 record_startup_extensions_function
= 0;
1625 add_from_mkext_function
= 0;
1626 remove_startup_extension_function
= 0;
1629 /* Invoke destructors for the __KLD and __LINKEDIT segments.
1630 * Do this for all segments before actually freeing their
1631 * memory so that any cross-dependencies (not that there
1632 * should be any) are handled.
1634 segmentKLD
= getsegbyname("__KLD");
1636 IOLog("error removing kernel linker: can't find __KLD segment\n");
1637 result
= KERN_FAILURE
;
1640 OSRuntimeUnloadCPPForSegment(segmentKLD
);
1642 #if __ppc__ || __arm__
1643 /* Free the memory that was set up by bootx.
1645 dt_segment_name
= "Kernel-__KLD";
1646 if (0 == IODTGetLoaderInfo(dt_segment_name
, &segment_paddress
, &segment_size
)) {
1647 IODTFreeLoaderInfo(dt_segment_name
, (void *)segment_paddress
,
1651 /* On x86, use the mapping data from the segment load command to
1652 * unload KLD directly, unless the keepsyms boot-arg was enabled.
1653 * This may invalidate any assumptions about "avail_start"
1654 * defining the lower bound for valid physical addresses.
1656 if (!keepsyms
&& segmentKLD
->vmaddr
&& segmentKLD
->vmsize
)
1657 ml_static_mfree(segmentKLD
->vmaddr
, segmentKLD
->vmsize
);
1662 struct section
* sect
;
1663 sect
= getsectbyname("__PRELINK", "__symtab");
1664 if (sect
&& sect
->addr
) {
1665 ml_static_mfree(sect
->addr
, sect
->size
);
1670 /* This must be the very last thing done before returning.
1672 IOLockUnlock(kld_lock
);
1677 /*********************************************************************
1678 * This function stops the catalogue from making kextd requests during
1680 *********************************************************************/
1681 void IOCatalogue::disableExternalLinker(void) {
1682 IOLockLock(gIOKLDLock
);
1683 /* If kmod_load_extension (the kextd requester function) is in use,
1684 * disable new module requests.
1686 if (kmod_load_function
== &kmod_load_extension
) {
1687 kmod_load_function
= NULL
;
1690 IOLockUnlock(gIOKLDLock
);
1694 void jettison_kernel_linker(void)
1696 if (gIOCatalogue
!= NULL
)
1697 gIOCatalogue
->removeKernelLinker();