2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_OSREFERENCE_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
10 * License may not be used to create, or enable the creation or
11 * redistribution of, unlawful or unlicensed copies of an Apple operating
12 * system, or to circumvent, violate, or enable the circumvention or
13 * violation of, any terms of an Apple operating system software license
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
20 * The Original Code and all software distributed under the License are
21 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
22 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
23 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
25 * Please see the License for the specific language governing rights and
26 * limitations under the License.
28 * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
30 #include <libsa/kmod.h>
31 #include <libkern/c++/OSContainers.h>
32 #include <IOKit/IOCatalogue.h>
33 #include <IOKit/IOLib.h>
34 #include <libsa/kmod.h>
35 #include <libsa/catalogue.h>
38 #include <mach-o/kld.h>
39 #include <libsa/vers_rsrc.h>
40 #include <libsa/stdlib.h>
41 #include <mach/kmod.h>
42 #include <vm/vm_kern.h>
43 #include <mach/kern_return.h>
44 #include <mach-o/fat.h>
45 #include <mach_loader.h>
48 #include "kld_patch.h"
58 kmod_destroy_internal(kmod_t id
);
65 mach_msg_type_number_t
*dataCount
);
67 extern kern_return_t
kmod_retain(kmod_t id
);
68 extern kern_return_t
kmod_release(kmod_t id
);
70 extern void flush_dcache64(addr64_t addr
, unsigned cnt
, int phys
);
71 extern void invalidate_icache64(addr64_t addr
, unsigned cnt
, int phys
);
77 #define VTYELLOW "\033[33m"
78 #define VTRESET "\033[0m"
83 /*********************************************************************
85 *********************************************************************/
86 bool verifyCompatibility(OSString
* extName
, OSString
* requiredVersion
)
88 OSDictionary
* extensionsDict
; // don't release
89 OSDictionary
* extDict
; // don't release
90 OSDictionary
* extPlist
; // don't release
91 OSString
* extVersion
; // don't release
92 OSString
* extCompatVersion
; // don't release
94 UInt32 ext_compat_version
;
95 UInt32 required_version
;
97 /* Get the dictionary of startup extensions.
98 * This is keyed by module name.
100 extensionsDict
= getStartupExtensions();
101 if (!extensionsDict
) {
102 IOLog("verifyCompatibility(): No extensions dictionary.\n");
106 /* Get the requested extension's dictionary entry and its property
107 * list, containing module dependencies.
109 extDict
= OSDynamicCast(OSDictionary
,
110 extensionsDict
->getObject(extName
));
113 IOLog("verifyCompatibility(): "
114 "Extension \"%s\" cannot be found.\n",
115 extName
->getCStringNoCopy());
119 extPlist
= OSDynamicCast(OSDictionary
, extDict
->getObject("plist"));
121 IOLog("verifyCompatibility(): "
122 "Extension \"%s\" has no property list.\n",
123 extName
->getCStringNoCopy());
128 extVersion
= OSDynamicCast(OSString
,
129 extPlist
->getObject("CFBundleVersion"));
131 IOLog("verifyCompatibility(): "
132 "Extension \"%s\" has no \"CFBundleVersion\" property.\n",
133 extName
->getCStringNoCopy());
137 extCompatVersion
= OSDynamicCast(OSString
,
138 extPlist
->getObject("OSBundleCompatibleVersion"));
139 if (!extCompatVersion
) {
140 IOLog("verifyCompatibility(): "
141 "Extension \"%s\" has no \"OSBundleCompatibleVersion\" property.\n",
142 extName
->getCStringNoCopy());
146 if (!VERS_parse_string(requiredVersion
->getCStringNoCopy(),
147 &required_version
)) {
148 IOLog("verifyCompatibility(): "
149 "Can't parse required version \"%s\" of dependency %s.\n",
150 requiredVersion
->getCStringNoCopy(),
151 extName
->getCStringNoCopy());
154 if (!VERS_parse_string(extVersion
->getCStringNoCopy(),
156 IOLog("verifyCompatibility(): "
157 "Can't parse version \"%s\" of dependency %s.\n",
158 extVersion
->getCStringNoCopy(),
159 extName
->getCStringNoCopy());
162 if (!VERS_parse_string(extCompatVersion
->getCStringNoCopy(),
163 &ext_compat_version
)) {
164 IOLog("verifyCompatibility(): "
165 "Can't parse compatible version \"%s\" of dependency %s.\n",
166 extCompatVersion
->getCStringNoCopy(),
167 extName
->getCStringNoCopy());
171 if (required_version
> ext_version
|| required_version
< ext_compat_version
) {
178 /*********************************************************************
179 *********************************************************************/
181 Boolean
kextIsADependency(OSString
* name
) {
182 Boolean result
= true;
183 OSDictionary
* extensionsDict
= 0; // don't release
184 OSDictionary
* extDict
= 0; // don't release
185 OSDictionary
* extPlist
= 0; // don't release
186 OSBoolean
* isKernelResourceObj
= 0; // don't release
187 OSData
* driverCode
= 0; // don't release
188 OSData
* compressedCode
= 0; // don't release
190 extensionsDict
= getStartupExtensions();
191 if (!extensionsDict
) {
192 IOLog("kextIsADependency(): No extensions dictionary.\n");
199 extDict
= OSDynamicCast(OSDictionary
,
200 extensionsDict
->getObject(name
));
202 IOLog("kextIsADependency(): "
203 "Extension \"%s\" cannot be found.\n",
204 name
->getCStringNoCopy());
210 extPlist
= OSDynamicCast(OSDictionary
, extDict
->getObject("plist"));
212 IOLog("getDependencyListForKmod(): "
213 "Extension \"%s\" has no property list.\n",
214 name
->getCStringNoCopy());
220 /* A kext that is a kernel component is still a dependency, as there
221 * are fake kmod entries for them.
223 isKernelResourceObj
= OSDynamicCast(OSBoolean
,
224 extPlist
->getObject("OSKernelResource"));
225 if (isKernelResourceObj
&& isKernelResourceObj
->isTrue()) {
230 driverCode
= OSDynamicCast(OSData
, extDict
->getObject("code"));
231 compressedCode
= OSDynamicCast(OSData
,
232 extDict
->getObject("compressedCode"));
234 if (!driverCode
&& !compressedCode
) {
244 /*********************************************************************
245 * This function builds a uniqued, in-order list of modules that need
246 * to be loaded in order for kmod_name to be successfully loaded. This
247 * list ends with kmod_name itself.
248 *********************************************************************/
250 OSArray
* getDependencyListForKmod(const char * kmod_name
) {
254 OSDictionary
* extensionsDict
; // don't release
255 OSDictionary
* extDict
; // don't release
256 OSDictionary
* extPlist
; // don't release
257 OSString
* extName
; // don't release
258 OSArray
* dependencyList
= NULL
; // return value, caller releases
261 /* These are used to remove duplicates from the dependency list.
263 OSArray
* originalList
= NULL
; // must be released
264 OSDictionary
* encounteredNames
= NULL
; // must be release
267 /* Get the dictionary of startup extensions.
268 * This is keyed by module name.
270 extensionsDict
= getStartupExtensions();
271 if (!extensionsDict
) {
272 IOLog("getDependencyListForKmod(): No extensions dictionary.\n");
279 /* Get the requested extension's dictionary entry and its property
280 * list, containing module dependencies.
282 extDict
= OSDynamicCast(OSDictionary
,
283 extensionsDict
->getObject(kmod_name
));
286 IOLog("getDependencyListForKmod(): "
287 "Extension \"%s\" cannot be found.\n",
294 extPlist
= OSDynamicCast(OSDictionary
, extDict
->getObject("plist"));
296 IOLog("getDependencyListForKmod(): "
297 "Extension \"%s\" has no property list.\n",
305 /* Verify that the retrieved entry's "CFBundleIdentifier" property exists.
306 * This will be added to the dependency list.
308 extName
= OSDynamicCast(OSString
,
309 extPlist
->getObject("CFBundleIdentifier"));
311 IOLog("getDependencyListForKmod(): "
312 "Extension \"%s\" has no \"CFBundleIdentifier\" property.\n",
319 dependencyList
= OSArray::withCapacity(10);
320 if (!dependencyList
) {
321 IOLog("getDependencyListForKmod(): "
322 "Couldn't allocate dependency array for extension \"%s\".\n",
330 /* Okay, let's get started.
332 dependencyList
->setObject(extName
);
335 /* Here's a slightly tricky bit. This loop iterates through
336 * the dependency list until it runs off the end. Each time
337 * through, however, any number of dependencies can be added
338 * to the end of the list. Eventually some extensions won't
339 * have any more dependencies, no more names will be added
340 * to the list, and this loop will terminate.
342 for (i
= 0; i
< dependencyList
->getCount(); i
++) {
344 // None of these needs to be released, as they're all from plists.
346 OSDictionary
* curExtDict
;
347 OSDictionary
* curExtDepDict
;
348 OSDictionary
* curExtPlist
;
349 OSString
* curDepName
;
352 /* An arbitrary limit to prevent infinite loops.
355 IOLog("getDependencyListForKmod(): "
356 "max dependency list length exceeded for "
357 "extension \"%s\".\n",
364 curName
= OSDynamicCast(OSString
, dependencyList
->getObject(i
));
366 curExtDict
= OSDynamicCast(OSDictionary
,
367 extensionsDict
->getObject(curName
));
369 IOLog("getDependencyListForKmod(): "
370 "Extension \"%s\", required for extension \"%s\", "
371 "is not available.\n",
372 curName
->getCStringNoCopy(), kmod_name
);
378 curExtPlist
= OSDynamicCast(OSDictionary
,
379 curExtDict
->getObject("plist"));
381 IOLog("getDependencyListForKmod(): "
382 "Extension \"%s\", required for extension \"%s\", "
383 "has no property list.\n",
384 curName
->getCStringNoCopy(), kmod_name
);
390 curExtDepDict
= OSDynamicCast(OSDictionary
,
391 curExtPlist
->getObject("OSBundleLibraries"));
393 OSCollectionIterator
* keyIterator
=
394 OSCollectionIterator::withCollection(curExtDepDict
);
397 IOLog("getDependencyListForKmod(): "
398 "Couldn't allocate iterator for extension "
399 "\"%s\".\n", kmod_name
);
404 while ( (curDepName
=
405 OSDynamicCast(OSString
,
406 keyIterator
->getNextObject())) ) {
408 OSString
* requiredVersion
= OSDynamicCast(OSString
,
409 curExtDepDict
->getObject(curDepName
));
411 if (!verifyCompatibility(curDepName
, requiredVersion
)) {
412 IOLog("getDependencyListForKmod(): "
413 "Dependency %s of %s is not compatible or is unavailable.\n",
414 curDepName
->getCStringNoCopy(),
415 curName
->getCStringNoCopy());
421 dependencyList
->setObject(curDepName
);
424 keyIterator
->release();
430 * The dependency list now exists in the reverse order of required loads,
431 * and may have duplicates. Now we turn the list around and remove
434 originalList
= dependencyList
;
435 dependencyList
= OSArray::withCapacity(originalList
->getCount());
436 if (!dependencyList
) {
437 IOLog("getDependenciesForKmod(): "
438 "Couldn't allocate reversal dependency list for extension "
439 "\"%s\".\n", kmod_name
);
444 encounteredNames
= OSDictionary::withCapacity(originalList
->getCount());
445 if (!encounteredNames
) {
446 IOLog("getDependenciesForKmod(): "
447 "Couldn't allocate list of encountered names for extension "
448 "\"%s\".\n", kmod_name
);
455 /* Go backward through the original list, using the encounteredNames
456 * dictionary to check for duplicates. We put originalList in as the
457 * value because we need some non-NULL value. Here we also drop any
458 * extensions that aren't proper dependencies (that is, any that are
459 * nonkernel kexts without code).
461 i
= originalList
->getCount();
467 OSString
* item
= OSDynamicCast(OSString
,
468 originalList
->getObject(i
));
470 if ( (!encounteredNames
->getObject(item
)) &&
471 kextIsADependency(item
)) {
473 encounteredNames
->setObject(item
, originalList
);
474 dependencyList
->setObject(item
);
483 originalList
->release();
485 if (encounteredNames
) {
486 encounteredNames
->release();
489 if (dependencyList
) {
490 dependencyList
->release();
491 dependencyList
= NULL
;
495 return dependencyList
;
499 /*********************************************************************
500 *********************************************************************/
501 /* Used in address_for_loaded_kmod.
503 static kmod_info_t
* g_current_kmod_info
= NULL
;
504 static const char * g_current_kmod_name
= NULL
;
506 /* Globals to pass link buffer info from
507 * address_for_loaded_kmod() and alloc_for_kmod()
510 * link_load_address is the address used to lay
511 * down the linked code. It gets adjusted by the
512 * pad between the headers size and a full page
513 * multiple. If an error occurs this gets set to
514 * zero so that the kld client code can detect
515 * an address or allocation error even if kld
518 * link_load_size is the size of the image as
519 * created by kld_load_from_memory(). link_buffer_size
520 * is the size of the buffer allocated for the final
521 * laid-down image, and is adjusted by rounding the
522 * load size and header size up to full-page multiples.
524 * link_buffer_address is set only by alloc_for_kmod();
525 * its value is used as a check if kld_load_from_memory()
526 * fails so that the buffer can be deallocated.
528 static unsigned long link_load_address
= 0;
529 static unsigned long link_load_size
= 0;
530 static unsigned long link_buffer_size
= 0;
531 static unsigned long link_header_size
= 0;
532 static unsigned long link_buffer_address
= 0;
535 /*********************************************************************
536 * This function is registered before kmod_load_from_memory() is
537 * invoked to build symbol table entries for an already-loaded
538 * kmod. This function just checks the g_current_kmod_info variable
539 * to gets its load address, and futzes it by the header offset (pad).
540 * See lower comments for more info on load address futzing.
541 *********************************************************************/
543 unsigned long address_for_loaded_kmod(
545 unsigned long headers_size
) {
547 unsigned long round_headers_size
;
548 unsigned long headers_pad
;
550 if (!g_current_kmod_info
) {
551 IOLog("address_for_loaded_kmod(): No current kmod.\n");
553 link_load_address
= 0; // error sentinel for kld client
557 round_headers_size
= round_page_32(headers_size
);
558 headers_pad
= round_headers_size
- headers_size
;
560 link_load_address
= (unsigned long)g_current_kmod_info
->address
+
563 return link_load_address
;
567 /*********************************************************************
568 * This function is registered before kmod_load_from_memory() is
569 * invoked to actually load a new kmod. It rounds up the header and
570 * total sizes and vm_allocates a buffer for the kmod. Now, KLD doesn't
571 * enforce any alignment of headers or segments, and we want to make
572 * sure that the executable code of the kmod lies on a page boundary.
573 * to do so, this function figures the pad between the actual header
574 * size and the page-rounded header size, and returns that offset into
575 * the allocated buffer. After kmod_load_from_memory() returns, its
576 * caller will move the mach_header struct back to the beginning of the
577 * allocated buffer so that the kmod_info_t structure contains the
579 *********************************************************************/
581 unsigned long alloc_for_kmod(
583 unsigned long headers_size
) {
585 vm_address_t buffer
= 0;
586 kern_return_t k_result
;
588 unsigned long round_headers_size
;
589 unsigned long round_segments_size
;
590 unsigned long round_size
;
591 unsigned long headers_pad
;
593 round_headers_size
= round_page_32(headers_size
);
594 round_segments_size
= round_page_32(size
- headers_size
);
595 round_size
= round_headers_size
+ round_segments_size
;
596 headers_pad
= round_headers_size
- headers_size
;
598 k_result
= vm_allocate(kernel_map
, (vm_offset_t
*)&buffer
,
599 round_size
, VM_FLAGS_ANYWHERE
);
600 if (k_result
!= KERN_SUCCESS
) {
601 IOLog("alloc_for_kmod(): Can't allocate memory.\n");
603 link_buffer_address
= 0; // make sure it's clear
604 link_load_address
= 0; // error sentinel for kld client
608 link_load_size
= size
;
610 link_buffer_address
= buffer
;
611 link_buffer_size
= round_size
;
612 link_header_size
= headers_size
; // NOT rounded!
614 link_load_address
= link_buffer_address
+ headers_pad
;
616 return link_load_address
;
619 /*********************************************************************
620 * This function reads the startup extensions dictionary to get the
621 * address and length of the executable data for the requested kmod.
622 *********************************************************************/
624 int map_and_patch(const char * kmod_name
) {
628 // Does the kld system already know about this kmod?
629 address
= (char *) kld_file_getaddr(kmod_name
, NULL
);
633 // None of these needs to be released.
634 OSDictionary
* extensionsDict
;
635 OSDictionary
* kmodDict
;
636 OSData
* compressedCode
= 0;
638 // Driver Code may need to be released
641 /* Get the requested kmod's info dictionary from the global
642 * startup extensions dictionary.
644 extensionsDict
= getStartupExtensions();
645 if (!extensionsDict
) {
646 IOLog("map_and_patch(): No extensions dictionary.\n");
651 kmodDict
= OSDynamicCast(OSDictionary
,
652 extensionsDict
->getObject(kmod_name
));
654 IOLog("map_and_patch(): "
655 "Extension \"%s\" cannot be found.\n", kmod_name
);
662 driverCode
= OSDynamicCast(OSData
, kmodDict
->getObject("code"));
664 ret
= kld_file_map(kmod_name
,
665 (unsigned char *) driverCode
->getBytesNoCopy(),
666 (size_t) driverCode
->getLength(),
669 else { // May be an compressed extension
671 // If we have a compressed segment the uncompressModule
672 // will return a new OSData object that points to the kmem_alloced
673 // memory. Note we don't take a reference to driverCode so later
674 // when we release it we will actually free this driver. Ownership
675 // of the kmem has been handed of to kld_file.
676 compressedCode
= OSDynamicCast(OSData
,
677 kmodDict
->getObject("compressedCode"));
678 if (!compressedCode
) {
679 IOLog("map_and_patch(): "
680 "Extension \"%s\" has no \"code\" property.\n", kmod_name
);
684 if (!uncompressModule(compressedCode
, &driverCode
)) {
685 IOLog("map_and_patch(): "
686 "Extension \"%s\" Couldn't uncompress code.\n", kmod_name
);
691 unsigned char *driver
= (unsigned char *) driverCode
->getBytesNoCopy();
692 size_t driverSize
= driverCode
->getLength();
694 ret
= kld_file_map(kmod_name
, driver
, driverSize
, /* isKmem */ true);
695 driverCode
->release();
697 kmem_free(kernel_map
, (vm_address_t
) driver
, driverSize
);
701 IOLog("map_and_patch(): "
702 "Extension \"%s\" Didn't successfully load.\n", kmod_name
);
708 if (!kld_file_patch_OSObjects(kmod_name
)) {
709 IOLog("map_and_patch(): "
710 "Extension \"%s\" Error binding OSObjects.\n", kmod_name
);
713 // RY: Instead of returning here, set the return value.
714 // We still need to call kld_file_prepare_for_link because
715 // we might have patched files outside of the driver. Don't
716 // worry, it will know to ignore the damaged file
720 // Now repair any damage that the kld patcher may have done to the image
721 kld_file_prepare_for_link();
726 /*********************************************************************
727 *********************************************************************/
728 bool stamp_kmod(const char * kmod_name
, kmod_info_t
* kmod_info
) {
730 OSDictionary
* extensionsDict
= NULL
; // don't release
731 OSDictionary
* kmodDict
= NULL
; // don't release
732 OSDictionary
* plist
= NULL
; // don't release
733 OSString
* versionString
= NULL
; // don't release
734 const char * plist_version
= NULL
; // don't free
736 if (strlen(kmod_name
) + 1 > KMOD_MAX_NAME
) {
737 IOLog("stamp_kmod(): Kext identifier \"%s\" is too long.\n",
744 strcpy(kmod_info
->name
, kmod_name
);
746 /* Get the dictionary of startup extensions.
747 * This is keyed by module name.
749 extensionsDict
= getStartupExtensions();
750 if (!extensionsDict
) {
751 IOLog("stamp_kmod(): No extensions dictionary.\n");
757 kmodDict
= OSDynamicCast(OSDictionary
,
758 extensionsDict
->getObject(kmod_name
));
760 IOLog("stamp_kmod(): Can't find record for kmod \"%s\".\n",
767 plist
= OSDynamicCast(OSDictionary
,
768 kmodDict
->getObject("plist"));
770 IOLog("stamp_kmod(): Kmod \"%s\" has no property list.\n",
778 * Get the kext's version and stuff it into the kmod. This used
779 * to be a check that the kext & kmod had the same version, but
780 * now we just overwrite the kmod's version.
783 versionString
= OSDynamicCast(OSString
,
784 plist
->getObject("CFBundleVersion"));
785 if (!versionString
) {
786 IOLog("stamp_kmod(): Kmod \"%s\" has no \"CFBundleVersion\" "
794 plist_version
= versionString
->getCStringNoCopy();
795 if (!plist_version
) {
796 IOLog("stamp_kmod(): Can't get C string for kext version.\n");
802 if (strlen(plist_version
) + 1 > KMOD_MAX_NAME
) {
803 IOLog("stamp_kmod(): Version \"%s\" of kext \"%s\" is too long.\n",
804 plist_version
, kmod_name
);
810 strcpy(kmod_info
->version
, plist_version
);
820 /*********************************************************************
821 * This function takes a dependency list containing a series of
822 * already-loaded module names, followed by a single name for a module
823 * that hasn't yet been loaded. It invokes kld_load_from_memory() to
824 * build symbol info for the already-loaded modules, and then finally
825 * loads the actually requested module.
826 *********************************************************************/
828 kern_return_t
load_kmod(OSArray
* dependencyList
) {
829 kern_return_t result
= KERN_SUCCESS
;
831 unsigned int num_dependencies
= 0;
832 kmod_info_t
** kmod_dependencies
= NULL
;
834 OSString
* requestedKmodName
; // don't release
835 const char * requested_kmod_name
;
836 OSString
* currentKmodName
; // don't release
838 unsigned long kmod_size
;
839 struct mach_header
* kmod_header
;
840 unsigned long kld_result
;
841 int do_kld_unload
= 0;
842 kmod_info_t
* kmod_info_freeme
= 0;
843 kmod_info_t
* kmod_info
= 0;
847 /* Separate the requested kmod from its dependencies.
849 i
= dependencyList
->getCount();
851 IOLog("load_kmod(): Called with empty list.\n");
853 result
= KERN_FAILURE
;
856 i
--; // make i be the index of the last entry
859 requestedKmodName
= OSDynamicCast(OSString
, dependencyList
->getObject(i
));
860 if (!requestedKmodName
) {
861 IOLog("load_kmod(): Called with invalid list of kmod names.\n");
863 result
= KERN_FAILURE
;
866 requested_kmod_name
= requestedKmodName
->getCStringNoCopy();
867 dependencyList
->removeObject(i
);
869 /* If the requested kmod is already loaded, there's no work to do.
871 kmod_info_freeme
= kmod_lookupbyname_locked(requested_kmod_name
);
872 if (kmod_info_freeme
) {
873 // FIXME: Need to check for version mismatch if already loaded.
874 result
= KERN_SUCCESS
;
879 /* Do the KLD loads for the already-loaded modules in order to get
882 kld_address_func(&address_for_loaded_kmod
);
884 num_dependencies
= dependencyList
->getCount();
885 kmod_dependencies
= (kmod_info_t
**)kalloc(num_dependencies
*
886 sizeof(kmod_info_t
*));
887 if (!kmod_dependencies
) {
888 IOLog("load_kmod(): Failed to allocate memory for dependency array "
889 "during load of kmod \"%s\".\n", requested_kmod_name
);
891 result
= KERN_FAILURE
;
895 bzero(kmod_dependencies
, num_dependencies
*
896 sizeof(kmod_info_t
*));
898 for (i
= 0; i
< num_dependencies
; i
++) {
900 currentKmodName
= OSDynamicCast(OSString
,
901 dependencyList
->getObject(i
));
903 if (!currentKmodName
) {
904 IOLog("load_kmod(): Invalid dependency name at index %d for "
905 "kmod \"%s\".\n", i
, requested_kmod_name
);
907 result
= KERN_FAILURE
;
911 const char * current_kmod_name
= currentKmodName
->getCStringNoCopy();
913 // These globals are needed by the kld_address functions
914 g_current_kmod_info
= kmod_lookupbyname_locked(current_kmod_name
);
915 g_current_kmod_name
= current_kmod_name
;
917 if (!g_current_kmod_info
) {
918 IOLog("load_kmod(): Missing dependency \"%s\".\n",
921 result
= KERN_FAILURE
;
925 /* Record the current kmod as a dependency of the requested
926 * one. This will be used in building references after the
929 kmod_dependencies
[i
] = g_current_kmod_info
;
931 /* If the current kmod's size is zero it means that we have a
932 * fake in-kernel dependency. If so then don't have to arrange
933 * for its symbol table to be reloaded as it is
934 * part of the kernel's symbol table..
936 if (!g_current_kmod_info
->size
)
939 if (!kld_file_merge_OSObjects(current_kmod_name
)) {
940 IOLog("load_kmod(): Can't merge OSObjects \"%s\".\n",
943 result
= KERN_FAILURE
;
947 kmod_address
= (char *)
948 kld_file_getaddr(current_kmod_name
, (long *) &kmod_size
);
951 IOLog("load_kmod() failed for dependency kmod "
952 "\"%s\".\n", current_kmod_name
);
954 result
= KERN_FAILURE
;
958 kld_result
= kld_load_from_memory(&kmod_header
,
959 current_kmod_name
, kmod_address
, kmod_size
);
965 if (!kld_result
|| !link_load_address
) {
966 IOLog("kld_load_from_memory() failed for dependency kmod "
967 "\"%s\".\n", current_kmod_name
);
969 result
= KERN_FAILURE
;
973 kld_forget_symbol("_kmod_info");
977 * Now that we've done all the dependencies, which should have already
978 * been loaded, we do the last requested module, which should not have
979 * already been loaded.
981 kld_address_func(&alloc_for_kmod
);
983 g_current_kmod_name
= requested_kmod_name
;
984 g_current_kmod_info
= 0; // there is no kmod yet
986 if (!map_and_patch(requested_kmod_name
)) {
987 IOLog("load_kmod: map_and_patch() failed for "
988 "kmod \"%s\".\n", requested_kmod_name
);
990 result
= KERN_FAILURE
;
994 kmod_address
= (char *)
995 kld_file_getaddr(requested_kmod_name
, (long *) &kmod_size
);
997 IOLog("load_kmod: kld_file_getaddr() failed internal error "
998 "on \"%s\".\n", requested_kmod_name
);
1000 result
= KERN_FAILURE
;
1004 kld_result
= kld_load_from_memory(&kmod_header
,
1005 requested_kmod_name
, kmod_address
, kmod_size
);
1011 if (!kld_result
|| !link_load_address
) {
1012 IOLog("load_kmod(): kld_load_from_memory() failed for "
1013 "kmod \"%s\".\n", requested_kmod_name
);
1015 result
= KERN_FAILURE
;
1020 /* Copy the linked header and image into the vm_allocated buffer.
1021 * Move each onto the appropriate page-aligned boundary as given
1022 * by the global link_... variables.
1024 bzero((char *)link_buffer_address
, link_buffer_size
);
1025 // bcopy() is (from, to, length)
1026 bcopy((char *)kmod_header
, (char *)link_buffer_address
, link_header_size
);
1027 bcopy((char *)kmod_header
+ link_header_size
,
1028 (char *)link_buffer_address
+ round_page_32(link_header_size
),
1029 link_load_size
- link_header_size
);
1032 /* Get the kmod_info struct for the newly-loaded kmod.
1034 if (!kld_lookup("_kmod_info", (unsigned long *)&kmod_info
)) {
1035 IOLog("kld_lookup() of \"_kmod_info\" failed for "
1036 "kmod \"%s\".\n", requested_kmod_name
);
1038 result
= KERN_FAILURE
;
1043 if (!stamp_kmod(requested_kmod_name
, kmod_info
)) {
1044 // stamp_kmod() logs a meaningful message
1045 result
= KERN_FAILURE
;
1050 /* kld_lookup of _kmod_info yielded the actual linked address,
1051 * so now that we've copied the data into its real place,
1052 * we can set this stuff.
1054 kmod_info
->address
= link_buffer_address
;
1055 kmod_info
->size
= link_buffer_size
;
1056 kmod_info
->hdr_size
= round_page_32(link_header_size
);
1058 /* We've written data and instructions, so *flush* the data cache
1059 * and *invalidate* the instruction cache.
1061 flush_dcache64((addr64_t
)link_buffer_address
, link_buffer_size
, false);
1062 invalidate_icache64((addr64_t
)link_buffer_address
, link_buffer_size
, false);
1065 /* Register the new kmod with the kernel proper.
1067 if (kmod_create_internal(kmod_info
, &kmod_id
) != KERN_SUCCESS
) {
1068 IOLog("load_kmod(): kmod_create() failed for "
1069 "kmod \"%s\".\n", requested_kmod_name
);
1071 result
= KERN_FAILURE
;
1076 IOLog("kmod id %d successfully created at 0x%lx, size %ld.\n",
1077 (unsigned int)kmod_id
, link_buffer_address
, link_buffer_size
);
1081 /* Record dependencies for the newly-loaded kmod.
1083 for (i
= 0; i
< num_dependencies
; i
++) {
1084 kmod_info_t
* cur_dependency_info
;
1086 cur_dependency_info
= kmod_dependencies
[i
];
1087 packed_id
= KMOD_PACK_IDS(kmod_id
, cur_dependency_info
->id
);
1088 if (kmod_retain(packed_id
) != KERN_SUCCESS
) {
1089 IOLog("load_kmod(): kmod_retain() failed for "
1090 "kmod \"%s\".\n", requested_kmod_name
);
1092 kmod_destroy_internal(kmod_id
);
1093 result
= KERN_FAILURE
;
1098 /* Start the kmod (which invokes constructors for I/O Kit
1101 // kmod_start_or_stop(id, start?, user data, datalen)
1102 if (kmod_start_or_stop(kmod_id
, 1, 0, 0) != KERN_SUCCESS
) {
1103 IOLog("load_kmod(): kmod_start_or_stop() failed for "
1104 "kmod \"%s\".\n", requested_kmod_name
);
1106 kmod_destroy_internal(kmod_id
);
1107 result
= KERN_FAILURE
;
1113 if (kmod_info_freeme
) {
1114 kfree((unsigned int)kmod_info_freeme
, sizeof(kmod_info_t
));
1117 /* Only do a kld_unload_all() if at least one load happened.
1119 if (do_kld_unload
) {
1120 kld_unload_all(/* deallocate sets */ 1);
1123 /* If the link failed, blow away the allocated link buffer.
1125 if (result
!= KERN_SUCCESS
&& link_buffer_address
) {
1126 vm_deallocate(kernel_map
, link_buffer_address
, link_buffer_size
);
1129 if (kmod_dependencies
) {
1130 for (i
= 0; i
< num_dependencies
; i
++) {
1131 if (kmod_dependencies
[i
]) {
1132 kfree((unsigned int)kmod_dependencies
[i
], sizeof(kmod_info_t
));
1135 kfree((unsigned int)kmod_dependencies
,
1136 num_dependencies
* sizeof(kmod_info_t
*));
1139 /* Reset these static global variables for the next call.
1141 g_current_kmod_name
= NULL
;
1142 g_current_kmod_info
= NULL
;
1143 link_buffer_address
= 0;
1144 link_load_address
= 0;
1146 link_buffer_size
= 0;
1147 link_header_size
= 0;
1153 /*********************************************************************
1154 * This is the function that IOCatalogue calls in order to load a kmod.
1155 * It first checks whether the kmod is already loaded. If the kmod
1156 * isn't loaded, this function builds a dependency list and calls
1157 * load_kmod() repeatedly to guarantee that each dependency is in fact
1159 *********************************************************************/
1161 kern_return_t
load_kernel_extension(char * kmod_name
) {
1162 kern_return_t result
= KERN_SUCCESS
;
1163 kmod_info_t
* kmod_info
= 0; // must free
1164 OSArray
* dependencyList
= NULL
; // must release
1165 OSArray
* curDependencyList
= NULL
; // must release
1167 /* See if the kmod is already loaded.
1169 kmod_info
= kmod_lookupbyname_locked(kmod_name
);
1170 if (kmod_info
) { // NOT checked
1171 result
= KERN_SUCCESS
;
1175 /* It isn't loaded; build a dependency list and
1180 dependencyList
= getDependencyListForKmod(kmod_name
);
1181 if (!dependencyList
) {
1182 IOLog("load_kernel_extension(): "
1183 "Can't get dependencies for kernel extension \"%s\".\n",
1186 result
= KERN_FAILURE
;
1190 count
= dependencyList
->getCount();
1191 for (i
= 0; i
< count
; i
++) {
1192 kern_return_t load_result
;
1193 OSString
* curKmodName
; // don't release
1194 const char * cur_kmod_name
;
1196 curKmodName
= OSDynamicCast(OSString
,
1197 dependencyList
->getObject(i
));
1198 cur_kmod_name
= curKmodName
->getCStringNoCopy();
1199 curDependencyList
= getDependencyListForKmod(cur_kmod_name
);
1200 if (!curDependencyList
) {
1201 IOLog("load_kernel_extension(): "
1202 "Can't get dependencies for kernel extension \"%s\".\n",
1205 result
= KERN_FAILURE
;
1208 load_result
= load_kmod(curDependencyList
);
1209 if (load_result
!= KERN_SUCCESS
) {
1210 IOLog("load_kernel_extension(): "
1211 "load_kmod() failed for kmod \"%s\".\n",
1214 result
= load_result
;
1217 curDependencyList
->release();
1218 curDependencyList
= NULL
;
1226 kfree((unsigned int)kmod_info
, sizeof(kmod_info_t
));
1229 if (dependencyList
) {
1230 dependencyList
->release();
1231 dependencyList
= NULL
;
1233 if (curDependencyList
) {
1234 curDependencyList
->release();
1235 curDependencyList
= NULL
;