2 * Copyright (c) 2000 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@
28 #include <libsa/kmod.h>
29 #include <libkern/c++/OSContainers.h>
30 #include <IOKit/IOCatalogue.h>
31 #include <IOKit/IOLib.h>
32 #include <libsa/kmod.h>
33 #include <libsa/catalogue.h>
36 #include <mach-o/kld.h>
37 #include <libsa/vers_rsrc.h>
38 #include <libsa/stdlib.h>
39 #include <mach/kmod.h>
40 #include <vm/vm_kern.h>
41 #include <mach/kern_return.h>
42 #include <mach-o/fat.h>
43 #include <mach_loader.h>
46 #include "kld_patch.h"
56 kmod_destroy_internal(kmod_t id
);
63 mach_msg_type_number_t
*dataCount
);
65 extern kern_return_t
kmod_retain(kmod_t id
);
66 extern kern_return_t
kmod_release(kmod_t id
);
68 extern void flush_dcache64(addr64_t addr
, unsigned cnt
, int phys
);
69 extern void invalidate_icache64(addr64_t addr
, unsigned cnt
, int phys
);
75 #define VTYELLOW "\033[33m"
76 #define VTRESET "\033[0m"
81 /*********************************************************************
83 *********************************************************************/
84 bool verifyCompatibility(OSString
* extName
, OSString
* requiredVersion
)
86 OSDictionary
* extensionsDict
; // don't release
87 OSDictionary
* extDict
; // don't release
88 OSDictionary
* extPlist
; // don't release
89 OSString
* extVersion
; // don't release
90 OSString
* extCompatVersion
; // don't release
92 UInt32 ext_compat_version
;
93 UInt32 required_version
;
95 /* Get the dictionary of startup extensions.
96 * This is keyed by module name.
98 extensionsDict
= getStartupExtensions();
99 if (!extensionsDict
) {
100 IOLog("verifyCompatibility(): No extensions dictionary.\n");
104 /* Get the requested extension's dictionary entry and its property
105 * list, containing module dependencies.
107 extDict
= OSDynamicCast(OSDictionary
,
108 extensionsDict
->getObject(extName
));
111 IOLog("verifyCompatibility(): "
112 "Extension \"%s\" cannot be found.\n",
113 extName
->getCStringNoCopy());
117 extPlist
= OSDynamicCast(OSDictionary
, extDict
->getObject("plist"));
119 IOLog("verifyCompatibility(): "
120 "Extension \"%s\" has no property list.\n",
121 extName
->getCStringNoCopy());
126 extVersion
= OSDynamicCast(OSString
,
127 extPlist
->getObject("CFBundleVersion"));
129 IOLog("verifyCompatibility(): "
130 "Extension \"%s\" has no \"CFBundleVersion\" property.\n",
131 extName
->getCStringNoCopy());
135 extCompatVersion
= OSDynamicCast(OSString
,
136 extPlist
->getObject("OSBundleCompatibleVersion"));
137 if (!extCompatVersion
) {
138 IOLog("verifyCompatibility(): "
139 "Extension \"%s\" has no \"OSBundleCompatibleVersion\" property.\n",
140 extName
->getCStringNoCopy());
144 if (!VERS_parse_string(requiredVersion
->getCStringNoCopy(),
145 &required_version
)) {
146 IOLog("verifyCompatibility(): "
147 "Can't parse required version \"%s\" of dependency %s.\n",
148 requiredVersion
->getCStringNoCopy(),
149 extName
->getCStringNoCopy());
152 if (!VERS_parse_string(extVersion
->getCStringNoCopy(),
154 IOLog("verifyCompatibility(): "
155 "Can't parse version \"%s\" of dependency %s.\n",
156 extVersion
->getCStringNoCopy(),
157 extName
->getCStringNoCopy());
160 if (!VERS_parse_string(extCompatVersion
->getCStringNoCopy(),
161 &ext_compat_version
)) {
162 IOLog("verifyCompatibility(): "
163 "Can't parse compatible version \"%s\" of dependency %s.\n",
164 extCompatVersion
->getCStringNoCopy(),
165 extName
->getCStringNoCopy());
169 if (required_version
> ext_version
|| required_version
< ext_compat_version
) {
176 /*********************************************************************
177 *********************************************************************/
179 Boolean
kextIsADependency(OSString
* name
) {
180 Boolean result
= true;
181 OSDictionary
* extensionsDict
= 0; // don't release
182 OSDictionary
* extDict
= 0; // don't release
183 OSDictionary
* extPlist
= 0; // don't release
184 OSBoolean
* isKernelResourceObj
= 0; // don't release
185 OSData
* driverCode
= 0; // don't release
186 OSData
* compressedCode
= 0; // don't release
188 extensionsDict
= getStartupExtensions();
189 if (!extensionsDict
) {
190 IOLog("kextIsADependency(): No extensions dictionary.\n");
197 extDict
= OSDynamicCast(OSDictionary
,
198 extensionsDict
->getObject(name
));
200 IOLog("kextIsADependency(): "
201 "Extension \"%s\" cannot be found.\n",
202 name
->getCStringNoCopy());
208 extPlist
= OSDynamicCast(OSDictionary
, extDict
->getObject("plist"));
210 IOLog("getDependencyListForKmod(): "
211 "Extension \"%s\" has no property list.\n",
212 name
->getCStringNoCopy());
218 /* A kext that is a kernel component is still a dependency, as there
219 * are fake kmod entries for them.
221 isKernelResourceObj
= OSDynamicCast(OSBoolean
,
222 extPlist
->getObject("OSKernelResource"));
223 if (isKernelResourceObj
&& isKernelResourceObj
->isTrue()) {
228 driverCode
= OSDynamicCast(OSData
, extDict
->getObject("code"));
229 compressedCode
= OSDynamicCast(OSData
,
230 extDict
->getObject("compressedCode"));
232 if (!driverCode
&& !compressedCode
) {
242 /*********************************************************************
243 * This function builds a uniqued, in-order list of modules that need
244 * to be loaded in order for kmod_name to be successfully loaded. This
245 * list ends with kmod_name itself.
246 *********************************************************************/
248 OSArray
* getDependencyListForKmod(const char * kmod_name
) {
252 OSDictionary
* extensionsDict
; // don't release
253 OSDictionary
* extDict
; // don't release
254 OSDictionary
* extPlist
; // don't release
255 OSString
* extName
; // don't release
256 OSArray
* dependencyList
= NULL
; // return value, caller releases
259 /* These are used to remove duplicates from the dependency list.
261 OSArray
* originalList
= NULL
; // must be released
262 OSDictionary
* encounteredNames
= NULL
; // must be release
265 /* Get the dictionary of startup extensions.
266 * This is keyed by module name.
268 extensionsDict
= getStartupExtensions();
269 if (!extensionsDict
) {
270 IOLog("getDependencyListForKmod(): No extensions dictionary.\n");
277 /* Get the requested extension's dictionary entry and its property
278 * list, containing module dependencies.
280 extDict
= OSDynamicCast(OSDictionary
,
281 extensionsDict
->getObject(kmod_name
));
284 IOLog("getDependencyListForKmod(): "
285 "Extension \"%s\" cannot be found.\n",
292 extPlist
= OSDynamicCast(OSDictionary
, extDict
->getObject("plist"));
294 IOLog("getDependencyListForKmod(): "
295 "Extension \"%s\" has no property list.\n",
303 /* Verify that the retrieved entry's "CFBundleIdentifier" property exists.
304 * This will be added to the dependency list.
306 extName
= OSDynamicCast(OSString
,
307 extPlist
->getObject("CFBundleIdentifier"));
309 IOLog("getDependencyListForKmod(): "
310 "Extension \"%s\" has no \"CFBundleIdentifier\" property.\n",
317 dependencyList
= OSArray::withCapacity(10);
318 if (!dependencyList
) {
319 IOLog("getDependencyListForKmod(): "
320 "Couldn't allocate dependency array for extension \"%s\".\n",
328 /* Okay, let's get started.
330 dependencyList
->setObject(extName
);
333 /* Here's a slightly tricky bit. This loop iterates through
334 * the dependency list until it runs off the end. Each time
335 * through, however, any number of dependencies can be added
336 * to the end of the list. Eventually some extensions won't
337 * have any more dependencies, no more names will be added
338 * to the list, and this loop will terminate.
340 for (i
= 0; i
< dependencyList
->getCount(); i
++) {
342 // None of these needs to be released, as they're all from plists.
344 OSDictionary
* curExtDict
;
345 OSDictionary
* curExtDepDict
;
346 OSDictionary
* curExtPlist
;
347 OSString
* curDepName
;
350 /* An arbitrary limit to prevent infinite loops.
353 IOLog("getDependencyListForKmod(): "
354 "max dependency list length exceeded for "
355 "extension \"%s\".\n",
362 curName
= OSDynamicCast(OSString
, dependencyList
->getObject(i
));
364 curExtDict
= OSDynamicCast(OSDictionary
,
365 extensionsDict
->getObject(curName
));
367 IOLog("getDependencyListForKmod(): "
368 "Extension \"%s\", required for extension \"%s\", "
369 "is not available.\n",
370 curName
->getCStringNoCopy(), kmod_name
);
376 curExtPlist
= OSDynamicCast(OSDictionary
,
377 curExtDict
->getObject("plist"));
379 IOLog("getDependencyListForKmod(): "
380 "Extension \"%s\", required for extension \"%s\", "
381 "has no property list.\n",
382 curName
->getCStringNoCopy(), kmod_name
);
388 curExtDepDict
= OSDynamicCast(OSDictionary
,
389 curExtPlist
->getObject("OSBundleLibraries"));
391 OSCollectionIterator
* keyIterator
=
392 OSCollectionIterator::withCollection(curExtDepDict
);
395 IOLog("getDependencyListForKmod(): "
396 "Couldn't allocate iterator for extension "
397 "\"%s\".\n", kmod_name
);
402 while ( (curDepName
=
403 OSDynamicCast(OSString
,
404 keyIterator
->getNextObject())) ) {
406 OSString
* requiredVersion
= OSDynamicCast(OSString
,
407 curExtDepDict
->getObject(curDepName
));
409 if (!verifyCompatibility(curDepName
, requiredVersion
)) {
410 IOLog("getDependencyListForKmod(): "
411 "Dependency %s of %s is not compatible or is unavailable.\n",
412 curDepName
->getCStringNoCopy(),
413 curName
->getCStringNoCopy());
419 dependencyList
->setObject(curDepName
);
422 keyIterator
->release();
428 * The dependency list now exists in the reverse order of required loads,
429 * and may have duplicates. Now we turn the list around and remove
432 originalList
= dependencyList
;
433 dependencyList
= OSArray::withCapacity(originalList
->getCount());
434 if (!dependencyList
) {
435 IOLog("getDependenciesForKmod(): "
436 "Couldn't allocate reversal dependency list for extension "
437 "\"%s\".\n", kmod_name
);
442 encounteredNames
= OSDictionary::withCapacity(originalList
->getCount());
443 if (!encounteredNames
) {
444 IOLog("getDependenciesForKmod(): "
445 "Couldn't allocate list of encountered names for extension "
446 "\"%s\".\n", kmod_name
);
453 /* Go backward through the original list, using the encounteredNames
454 * dictionary to check for duplicates. We put originalList in as the
455 * value because we need some non-NULL value. Here we also drop any
456 * extensions that aren't proper dependencies (that is, any that are
457 * nonkernel kexts without code).
459 i
= originalList
->getCount();
465 OSString
* item
= OSDynamicCast(OSString
,
466 originalList
->getObject(i
));
468 if ( (!encounteredNames
->getObject(item
)) &&
469 kextIsADependency(item
)) {
471 encounteredNames
->setObject(item
, originalList
);
472 dependencyList
->setObject(item
);
481 originalList
->release();
483 if (encounteredNames
) {
484 encounteredNames
->release();
487 if (dependencyList
) {
488 dependencyList
->release();
489 dependencyList
= NULL
;
493 return dependencyList
;
497 /*********************************************************************
498 *********************************************************************/
499 /* Used in address_for_loaded_kmod.
501 static kmod_info_t
* g_current_kmod_info
= NULL
;
502 static const char * g_current_kmod_name
= NULL
;
504 /* Globals to pass link buffer info from
505 * address_for_loaded_kmod() and alloc_for_kmod()
508 * link_load_address is the address used to lay
509 * down the linked code. It gets adjusted by the
510 * pad between the headers size and a full page
511 * multiple. If an error occurs this gets set to
512 * zero so that the kld client code can detect
513 * an address or allocation error even if kld
516 * link_load_size is the size of the image as
517 * created by kld_load_from_memory(). link_buffer_size
518 * is the size of the buffer allocated for the final
519 * laid-down image, and is adjusted by rounding the
520 * load size and header size up to full-page multiples.
522 * link_buffer_address is set only by alloc_for_kmod();
523 * its value is used as a check if kld_load_from_memory()
524 * fails so that the buffer can be deallocated.
526 static unsigned long link_load_address
= 0;
527 static unsigned long link_load_size
= 0;
528 static unsigned long link_buffer_size
= 0;
529 static unsigned long link_header_size
= 0;
530 static unsigned long link_buffer_address
= 0;
533 /*********************************************************************
534 * This function is registered before kmod_load_from_memory() is
535 * invoked to build symbol table entries for an already-loaded
536 * kmod. This function just checks the g_current_kmod_info variable
537 * to gets its load address, and futzes it by the header offset (pad).
538 * See lower comments for more info on load address futzing.
539 *********************************************************************/
541 unsigned long address_for_loaded_kmod(
543 unsigned long headers_size
) {
545 unsigned long round_headers_size
;
546 unsigned long headers_pad
;
548 if (!g_current_kmod_info
) {
549 IOLog("address_for_loaded_kmod(): No current kmod.\n");
551 link_load_address
= 0; // error sentinel for kld client
555 round_headers_size
= round_page_32(headers_size
);
556 headers_pad
= round_headers_size
- headers_size
;
558 link_load_address
= (unsigned long)g_current_kmod_info
->address
+
561 return link_load_address
;
565 /*********************************************************************
566 * This function is registered before kmod_load_from_memory() is
567 * invoked to actually load a new kmod. It rounds up the header and
568 * total sizes and vm_allocates a buffer for the kmod. Now, KLD doesn't
569 * enforce any alignment of headers or segments, and we want to make
570 * sure that the executable code of the kmod lies on a page boundary.
571 * to do so, this function figures the pad between the actual header
572 * size and the page-rounded header size, and returns that offset into
573 * the allocated buffer. After kmod_load_from_memory() returns, its
574 * caller will move the mach_header struct back to the beginning of the
575 * allocated buffer so that the kmod_info_t structure contains the
577 *********************************************************************/
579 unsigned long alloc_for_kmod(
581 unsigned long headers_size
) {
583 vm_address_t buffer
= 0;
584 kern_return_t k_result
;
586 unsigned long round_headers_size
;
587 unsigned long round_segments_size
;
588 unsigned long round_size
;
589 unsigned long headers_pad
;
591 round_headers_size
= round_page_32(headers_size
);
592 round_segments_size
= round_page_32(size
- headers_size
);
593 round_size
= round_headers_size
+ round_segments_size
;
594 headers_pad
= round_headers_size
- headers_size
;
596 k_result
= vm_allocate(kernel_map
, (vm_offset_t
*)&buffer
,
597 round_size
, VM_FLAGS_ANYWHERE
);
598 if (k_result
!= KERN_SUCCESS
) {
599 IOLog("alloc_for_kmod(): Can't allocate memory.\n");
601 link_buffer_address
= 0; // make sure it's clear
602 link_load_address
= 0; // error sentinel for kld client
606 link_load_size
= size
;
608 link_buffer_address
= buffer
;
609 link_buffer_size
= round_size
;
610 link_header_size
= headers_size
; // NOT rounded!
612 link_load_address
= link_buffer_address
+ headers_pad
;
614 return link_load_address
;
617 /*********************************************************************
618 * This function reads the startup extensions dictionary to get the
619 * address and length of the executable data for the requested kmod.
620 *********************************************************************/
622 int map_and_patch(const char * kmod_name
) {
626 // Does the kld system already know about this kmod?
627 address
= (char *) kld_file_getaddr(kmod_name
, NULL
);
631 // None of these needs to be released.
632 OSDictionary
* extensionsDict
;
633 OSDictionary
* kmodDict
;
634 OSData
* compressedCode
= 0;
636 // Driver Code may need to be released
639 /* Get the requested kmod's info dictionary from the global
640 * startup extensions dictionary.
642 extensionsDict
= getStartupExtensions();
643 if (!extensionsDict
) {
644 IOLog("map_and_patch(): No extensions dictionary.\n");
649 kmodDict
= OSDynamicCast(OSDictionary
,
650 extensionsDict
->getObject(kmod_name
));
652 IOLog("map_and_patch(): "
653 "Extension \"%s\" cannot be found.\n", kmod_name
);
660 driverCode
= OSDynamicCast(OSData
, kmodDict
->getObject("code"));
662 ret
= kld_file_map(kmod_name
,
663 (unsigned char *) driverCode
->getBytesNoCopy(),
664 (size_t) driverCode
->getLength(),
667 else { // May be an compressed extension
669 // If we have a compressed segment the uncompressModule
670 // will return a new OSData object that points to the kmem_alloced
671 // memory. Note we don't take a reference to driverCode so later
672 // when we release it we will actually free this driver. Ownership
673 // of the kmem has been handed of to kld_file.
674 compressedCode
= OSDynamicCast(OSData
,
675 kmodDict
->getObject("compressedCode"));
676 if (!compressedCode
) {
677 IOLog("map_and_patch(): "
678 "Extension \"%s\" has no \"code\" property.\n", kmod_name
);
682 if (!uncompressModule(compressedCode
, &driverCode
)) {
683 IOLog("map_and_patch(): "
684 "Extension \"%s\" Couldn't uncompress code.\n", kmod_name
);
689 unsigned char *driver
= (unsigned char *) driverCode
->getBytesNoCopy();
690 size_t driverSize
= driverCode
->getLength();
692 ret
= kld_file_map(kmod_name
, driver
, driverSize
, /* isKmem */ true);
693 driverCode
->release();
695 kmem_free(kernel_map
, (vm_address_t
) driver
, driverSize
);
699 IOLog("map_and_patch(): "
700 "Extension \"%s\" Didn't successfully load.\n", kmod_name
);
706 if (!kld_file_patch_OSObjects(kmod_name
)) {
707 IOLog("map_and_patch(): "
708 "Extension \"%s\" Error binding OSObjects.\n", kmod_name
);
711 // RY: Instead of returning here, set the return value.
712 // We still need to call kld_file_prepare_for_link because
713 // we might have patched files outside of the driver. Don't
714 // worry, it will know to ignore the damaged file
718 // Now repair any damage that the kld patcher may have done to the image
719 kld_file_prepare_for_link();
724 /*********************************************************************
725 *********************************************************************/
726 bool stamp_kmod(const char * kmod_name
, kmod_info_t
* kmod_info
) {
728 OSDictionary
* extensionsDict
= NULL
; // don't release
729 OSDictionary
* kmodDict
= NULL
; // don't release
730 OSDictionary
* plist
= NULL
; // don't release
731 OSString
* versionString
= NULL
; // don't release
732 const char * plist_version
= NULL
; // don't free
734 if (strlen(kmod_name
) + 1 > KMOD_MAX_NAME
) {
735 IOLog("stamp_kmod(): Kext identifier \"%s\" is too long.\n",
742 strcpy(kmod_info
->name
, kmod_name
);
744 /* Get the dictionary of startup extensions.
745 * This is keyed by module name.
747 extensionsDict
= getStartupExtensions();
748 if (!extensionsDict
) {
749 IOLog("stamp_kmod(): No extensions dictionary.\n");
755 kmodDict
= OSDynamicCast(OSDictionary
,
756 extensionsDict
->getObject(kmod_name
));
758 IOLog("stamp_kmod(): Can't find record for kmod \"%s\".\n",
765 plist
= OSDynamicCast(OSDictionary
,
766 kmodDict
->getObject("plist"));
768 IOLog("stamp_kmod(): Kmod \"%s\" has no property list.\n",
776 * Get the kext's version and stuff it into the kmod. This used
777 * to be a check that the kext & kmod had the same version, but
778 * now we just overwrite the kmod's version.
781 versionString
= OSDynamicCast(OSString
,
782 plist
->getObject("CFBundleVersion"));
783 if (!versionString
) {
784 IOLog("stamp_kmod(): Kmod \"%s\" has no \"CFBundleVersion\" "
792 plist_version
= versionString
->getCStringNoCopy();
793 if (!plist_version
) {
794 IOLog("stamp_kmod(): Can't get C string for kext version.\n");
800 if (strlen(plist_version
) + 1 > KMOD_MAX_NAME
) {
801 IOLog("stamp_kmod(): Version \"%s\" of kext \"%s\" is too long.\n",
802 plist_version
, kmod_name
);
808 strcpy(kmod_info
->version
, plist_version
);
818 /*********************************************************************
819 * This function takes a dependency list containing a series of
820 * already-loaded module names, followed by a single name for a module
821 * that hasn't yet been loaded. It invokes kld_load_from_memory() to
822 * build symbol info for the already-loaded modules, and then finally
823 * loads the actually requested module.
824 *********************************************************************/
826 kern_return_t
load_kmod(OSArray
* dependencyList
) {
827 kern_return_t result
= KERN_SUCCESS
;
829 unsigned int num_dependencies
= 0;
830 kmod_info_t
** kmod_dependencies
= NULL
;
832 OSString
* requestedKmodName
; // don't release
833 const char * requested_kmod_name
;
834 OSString
* currentKmodName
; // don't release
836 unsigned long kmod_size
;
837 struct mach_header
* kmod_header
;
838 unsigned long kld_result
;
839 int do_kld_unload
= 0;
840 kmod_info_t
* kmod_info_freeme
= 0;
841 kmod_info_t
* kmod_info
= 0;
845 /* Separate the requested kmod from its dependencies.
847 i
= dependencyList
->getCount();
849 IOLog("load_kmod(): Called with empty list.\n");
851 result
= KERN_FAILURE
;
854 i
--; // make i be the index of the last entry
857 requestedKmodName
= OSDynamicCast(OSString
, dependencyList
->getObject(i
));
858 if (!requestedKmodName
) {
859 IOLog("load_kmod(): Called with invalid list of kmod names.\n");
861 result
= KERN_FAILURE
;
864 requested_kmod_name
= requestedKmodName
->getCStringNoCopy();
865 dependencyList
->removeObject(i
);
867 /* If the requested kmod is already loaded, there's no work to do.
869 kmod_info_freeme
= kmod_lookupbyname_locked(requested_kmod_name
);
870 if (kmod_info_freeme
) {
871 // FIXME: Need to check for version mismatch if already loaded.
872 result
= KERN_SUCCESS
;
877 /* Do the KLD loads for the already-loaded modules in order to get
880 kld_address_func(&address_for_loaded_kmod
);
882 num_dependencies
= dependencyList
->getCount();
883 kmod_dependencies
= (kmod_info_t
**)kalloc(num_dependencies
*
884 sizeof(kmod_info_t
*));
885 if (!kmod_dependencies
) {
886 IOLog("load_kmod(): Failed to allocate memory for dependency array "
887 "during load of kmod \"%s\".\n", requested_kmod_name
);
889 result
= KERN_FAILURE
;
893 bzero(kmod_dependencies
, num_dependencies
*
894 sizeof(kmod_info_t
*));
896 for (i
= 0; i
< num_dependencies
; i
++) {
898 currentKmodName
= OSDynamicCast(OSString
,
899 dependencyList
->getObject(i
));
901 if (!currentKmodName
) {
902 IOLog("load_kmod(): Invalid dependency name at index %d for "
903 "kmod \"%s\".\n", i
, requested_kmod_name
);
905 result
= KERN_FAILURE
;
909 const char * current_kmod_name
= currentKmodName
->getCStringNoCopy();
911 // These globals are needed by the kld_address functions
912 g_current_kmod_info
= kmod_lookupbyname_locked(current_kmod_name
);
913 g_current_kmod_name
= current_kmod_name
;
915 if (!g_current_kmod_info
) {
916 IOLog("load_kmod(): Missing dependency \"%s\".\n",
919 result
= KERN_FAILURE
;
923 /* Record the current kmod as a dependency of the requested
924 * one. This will be used in building references after the
927 kmod_dependencies
[i
] = g_current_kmod_info
;
929 /* If the current kmod's size is zero it means that we have a
930 * fake in-kernel dependency. If so then don't have to arrange
931 * for its symbol table to be reloaded as it is
932 * part of the kernel's symbol table..
934 if (!g_current_kmod_info
->size
)
937 if (!kld_file_merge_OSObjects(current_kmod_name
)) {
938 IOLog("load_kmod(): Can't merge OSObjects \"%s\".\n",
941 result
= KERN_FAILURE
;
945 kmod_address
= (char *)
946 kld_file_getaddr(current_kmod_name
, (long *) &kmod_size
);
949 IOLog("load_kmod() failed for dependency kmod "
950 "\"%s\".\n", current_kmod_name
);
952 result
= KERN_FAILURE
;
956 kld_result
= kld_load_from_memory(&kmod_header
,
957 current_kmod_name
, kmod_address
, kmod_size
);
963 if (!kld_result
|| !link_load_address
) {
964 IOLog("kld_load_from_memory() failed for dependency kmod "
965 "\"%s\".\n", current_kmod_name
);
967 result
= KERN_FAILURE
;
971 kld_forget_symbol("_kmod_info");
975 * Now that we've done all the dependencies, which should have already
976 * been loaded, we do the last requested module, which should not have
977 * already been loaded.
979 kld_address_func(&alloc_for_kmod
);
981 g_current_kmod_name
= requested_kmod_name
;
982 g_current_kmod_info
= 0; // there is no kmod yet
984 if (!map_and_patch(requested_kmod_name
)) {
985 IOLog("load_kmod: map_and_patch() failed for "
986 "kmod \"%s\".\n", requested_kmod_name
);
988 result
= KERN_FAILURE
;
992 kmod_address
= (char *)
993 kld_file_getaddr(requested_kmod_name
, (long *) &kmod_size
);
995 IOLog("load_kmod: kld_file_getaddr() failed internal error "
996 "on \"%s\".\n", requested_kmod_name
);
998 result
= KERN_FAILURE
;
1002 kld_result
= kld_load_from_memory(&kmod_header
,
1003 requested_kmod_name
, kmod_address
, kmod_size
);
1009 if (!kld_result
|| !link_load_address
) {
1010 IOLog("load_kmod(): kld_load_from_memory() failed for "
1011 "kmod \"%s\".\n", requested_kmod_name
);
1013 result
= KERN_FAILURE
;
1018 /* Copy the linked header and image into the vm_allocated buffer.
1019 * Move each onto the appropriate page-aligned boundary as given
1020 * by the global link_... variables.
1022 bzero((char *)link_buffer_address
, link_buffer_size
);
1023 // bcopy() is (from, to, length)
1024 bcopy((char *)kmod_header
, (char *)link_buffer_address
, link_header_size
);
1025 bcopy((char *)kmod_header
+ link_header_size
,
1026 (char *)link_buffer_address
+ round_page_32(link_header_size
),
1027 link_load_size
- link_header_size
);
1030 /* Get the kmod_info struct for the newly-loaded kmod.
1032 if (!kld_lookup("_kmod_info", (unsigned long *)&kmod_info
)) {
1033 IOLog("kld_lookup() of \"_kmod_info\" failed for "
1034 "kmod \"%s\".\n", requested_kmod_name
);
1036 result
= KERN_FAILURE
;
1041 if (!stamp_kmod(requested_kmod_name
, kmod_info
)) {
1042 // stamp_kmod() logs a meaningful message
1043 result
= KERN_FAILURE
;
1048 /* kld_lookup of _kmod_info yielded the actual linked address,
1049 * so now that we've copied the data into its real place,
1050 * we can set this stuff.
1052 kmod_info
->address
= link_buffer_address
;
1053 kmod_info
->size
= link_buffer_size
;
1054 kmod_info
->hdr_size
= round_page_32(link_header_size
);
1056 /* We've written data and instructions, so *flush* the data cache
1057 * and *invalidate* the instruction cache.
1059 flush_dcache64((addr64_t
)link_buffer_address
, link_buffer_size
, false);
1060 invalidate_icache64((addr64_t
)link_buffer_address
, link_buffer_size
, false);
1063 /* Register the new kmod with the kernel proper.
1065 if (kmod_create_internal(kmod_info
, &kmod_id
) != KERN_SUCCESS
) {
1066 IOLog("load_kmod(): kmod_create() failed for "
1067 "kmod \"%s\".\n", requested_kmod_name
);
1069 result
= KERN_FAILURE
;
1074 IOLog("kmod id %d successfully created at 0x%lx, size %ld.\n",
1075 (unsigned int)kmod_id
, link_buffer_address
, link_buffer_size
);
1079 /* Record dependencies for the newly-loaded kmod.
1081 for (i
= 0; i
< num_dependencies
; i
++) {
1082 kmod_info_t
* cur_dependency_info
;
1084 cur_dependency_info
= kmod_dependencies
[i
];
1085 packed_id
= KMOD_PACK_IDS(kmod_id
, cur_dependency_info
->id
);
1086 if (kmod_retain(packed_id
) != KERN_SUCCESS
) {
1087 IOLog("load_kmod(): kmod_retain() failed for "
1088 "kmod \"%s\".\n", requested_kmod_name
);
1090 kmod_destroy_internal(kmod_id
);
1091 result
= KERN_FAILURE
;
1096 /* Start the kmod (which invokes constructors for I/O Kit
1099 // kmod_start_or_stop(id, start?, user data, datalen)
1100 if (kmod_start_or_stop(kmod_id
, 1, 0, 0) != KERN_SUCCESS
) {
1101 IOLog("load_kmod(): kmod_start_or_stop() failed for "
1102 "kmod \"%s\".\n", requested_kmod_name
);
1104 kmod_destroy_internal(kmod_id
);
1105 result
= KERN_FAILURE
;
1111 if (kmod_info_freeme
) {
1112 kfree((unsigned int)kmod_info_freeme
, sizeof(kmod_info_t
));
1115 /* Only do a kld_unload_all() if at least one load happened.
1117 if (do_kld_unload
) {
1118 kld_unload_all(/* deallocate sets */ 1);
1121 /* If the link failed, blow away the allocated link buffer.
1123 if (result
!= KERN_SUCCESS
&& link_buffer_address
) {
1124 vm_deallocate(kernel_map
, link_buffer_address
, link_buffer_size
);
1127 if (kmod_dependencies
) {
1128 for (i
= 0; i
< num_dependencies
; i
++) {
1129 if (kmod_dependencies
[i
]) {
1130 kfree((unsigned int)kmod_dependencies
[i
], sizeof(kmod_info_t
));
1133 kfree((unsigned int)kmod_dependencies
,
1134 num_dependencies
* sizeof(kmod_info_t
*));
1137 /* Reset these static global variables for the next call.
1139 g_current_kmod_name
= NULL
;
1140 g_current_kmod_info
= NULL
;
1141 link_buffer_address
= 0;
1142 link_load_address
= 0;
1144 link_buffer_size
= 0;
1145 link_header_size
= 0;
1151 /*********************************************************************
1152 * This is the function that IOCatalogue calls in order to load a kmod.
1153 * It first checks whether the kmod is already loaded. If the kmod
1154 * isn't loaded, this function builds a dependency list and calls
1155 * load_kmod() repeatedly to guarantee that each dependency is in fact
1157 *********************************************************************/
1159 kern_return_t
load_kernel_extension(char * kmod_name
) {
1160 kern_return_t result
= KERN_SUCCESS
;
1161 kmod_info_t
* kmod_info
= 0; // must free
1162 OSArray
* dependencyList
= NULL
; // must release
1163 OSArray
* curDependencyList
= NULL
; // must release
1165 /* See if the kmod is already loaded.
1167 kmod_info
= kmod_lookupbyname_locked(kmod_name
);
1168 if (kmod_info
) { // NOT checked
1169 result
= KERN_SUCCESS
;
1173 /* It isn't loaded; build a dependency list and
1178 dependencyList
= getDependencyListForKmod(kmod_name
);
1179 if (!dependencyList
) {
1180 IOLog("load_kernel_extension(): "
1181 "Can't get dependencies for kernel extension \"%s\".\n",
1184 result
= KERN_FAILURE
;
1188 count
= dependencyList
->getCount();
1189 for (i
= 0; i
< count
; i
++) {
1190 kern_return_t load_result
;
1191 OSString
* curKmodName
; // don't release
1192 const char * cur_kmod_name
;
1194 curKmodName
= OSDynamicCast(OSString
,
1195 dependencyList
->getObject(i
));
1196 cur_kmod_name
= curKmodName
->getCStringNoCopy();
1197 curDependencyList
= getDependencyListForKmod(cur_kmod_name
);
1198 if (!curDependencyList
) {
1199 IOLog("load_kernel_extension(): "
1200 "Can't get dependencies for kernel extension \"%s\".\n",
1203 result
= KERN_FAILURE
;
1206 load_result
= load_kmod(curDependencyList
);
1207 if (load_result
!= KERN_SUCCESS
) {
1208 IOLog("load_kernel_extension(): "
1209 "load_kmod() failed for kmod \"%s\".\n",
1212 result
= load_result
;
1215 curDependencyList
->release();
1216 curDependencyList
= NULL
;
1224 kfree((unsigned int)kmod_info
, sizeof(kmod_info_t
));
1227 if (dependencyList
) {
1228 dependencyList
->release();
1229 dependencyList
= NULL
;
1231 if (curDependencyList
) {
1232 curDependencyList
->release();
1233 curDependencyList
= NULL
;