2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_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. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
23 #include <libsa/kmod.h>
24 #include <libkern/c++/OSContainers.h>
25 #include <IOKit/IOCatalogue.h>
26 #include <IOKit/IOLib.h>
27 #include <libsa/kmod.h>
28 #include <libsa/catalogue.h>
31 #include <mach-o/kld.h>
32 #include <libsa/vers_rsrc.h>
33 #include <libsa/stdlib.h>
34 #include <mach/kmod.h>
35 #include <vm/vm_kern.h>
36 #include <mach/kern_return.h>
37 #include <mach-o/fat.h>
38 #include <mach_loader.h>
41 #include "kld_patch.h"
51 kmod_destroy_internal(kmod_t id
);
58 mach_msg_type_number_t
*dataCount
);
60 extern kern_return_t
kmod_retain(kmod_t id
);
61 extern kern_return_t
kmod_release(kmod_t id
);
63 extern void flush_dcache64(addr64_t addr
, unsigned cnt
, int phys
);
64 extern void invalidate_icache64(addr64_t addr
, unsigned cnt
, int phys
);
70 #define VTYELLOW "\033[33m"
71 #define VTRESET "\033[0m"
76 /*********************************************************************
78 *********************************************************************/
79 bool verifyCompatibility(OSString
* extName
, OSString
* requiredVersion
)
81 OSDictionary
* extensionsDict
; // don't release
82 OSDictionary
* extDict
; // don't release
83 OSDictionary
* extPlist
; // don't release
84 OSString
* extVersion
; // don't release
85 OSString
* extCompatVersion
; // don't release
87 UInt32 ext_compat_version
;
88 UInt32 required_version
;
90 /* Get the dictionary of startup extensions.
91 * This is keyed by module name.
93 extensionsDict
= getStartupExtensions();
94 if (!extensionsDict
) {
95 IOLog("verifyCompatibility(): No extensions dictionary.\n");
99 /* Get the requested extension's dictionary entry and its property
100 * list, containing module dependencies.
102 extDict
= OSDynamicCast(OSDictionary
,
103 extensionsDict
->getObject(extName
));
106 IOLog("verifyCompatibility(): "
107 "Extension \"%s\" cannot be found.\n",
108 extName
->getCStringNoCopy());
112 extPlist
= OSDynamicCast(OSDictionary
, extDict
->getObject("plist"));
114 IOLog("verifyCompatibility(): "
115 "Extension \"%s\" has no property list.\n",
116 extName
->getCStringNoCopy());
121 extVersion
= OSDynamicCast(OSString
,
122 extPlist
->getObject("CFBundleVersion"));
124 IOLog("verifyCompatibility(): "
125 "Extension \"%s\" has no \"CFBundleVersion\" property.\n",
126 extName
->getCStringNoCopy());
130 extCompatVersion
= OSDynamicCast(OSString
,
131 extPlist
->getObject("OSBundleCompatibleVersion"));
132 if (!extCompatVersion
) {
133 IOLog("verifyCompatibility(): "
134 "Extension \"%s\" has no \"OSBundleCompatibleVersion\" property.\n",
135 extName
->getCStringNoCopy());
139 if (!VERS_parse_string(requiredVersion
->getCStringNoCopy(),
140 &required_version
)) {
141 IOLog("verifyCompatibility(): "
142 "Can't parse required version \"%s\" of dependency %s.\n",
143 requiredVersion
->getCStringNoCopy(),
144 extName
->getCStringNoCopy());
147 if (!VERS_parse_string(extVersion
->getCStringNoCopy(),
149 IOLog("verifyCompatibility(): "
150 "Can't parse version \"%s\" of dependency %s.\n",
151 extVersion
->getCStringNoCopy(),
152 extName
->getCStringNoCopy());
155 if (!VERS_parse_string(extCompatVersion
->getCStringNoCopy(),
156 &ext_compat_version
)) {
157 IOLog("verifyCompatibility(): "
158 "Can't parse compatible version \"%s\" of dependency %s.\n",
159 extCompatVersion
->getCStringNoCopy(),
160 extName
->getCStringNoCopy());
164 if (required_version
> ext_version
|| required_version
< ext_compat_version
) {
171 /*********************************************************************
172 *********************************************************************/
174 Boolean
kextIsADependency(OSString
* name
) {
175 Boolean result
= true;
176 OSDictionary
* extensionsDict
= 0; // don't release
177 OSDictionary
* extDict
= 0; // don't release
178 OSDictionary
* extPlist
= 0; // don't release
179 OSBoolean
* isKernelResourceObj
= 0; // don't release
180 OSData
* driverCode
= 0; // don't release
181 OSData
* compressedCode
= 0; // don't release
183 extensionsDict
= getStartupExtensions();
184 if (!extensionsDict
) {
185 IOLog("kextIsADependency(): No extensions dictionary.\n");
192 extDict
= OSDynamicCast(OSDictionary
,
193 extensionsDict
->getObject(name
));
195 IOLog("kextIsADependency(): "
196 "Extension \"%s\" cannot be found.\n",
197 name
->getCStringNoCopy());
203 extPlist
= OSDynamicCast(OSDictionary
, extDict
->getObject("plist"));
205 IOLog("getDependencyListForKmod(): "
206 "Extension \"%s\" has no property list.\n",
207 name
->getCStringNoCopy());
213 /* A kext that is a kernel component is still a dependency, as there
214 * are fake kmod entries for them.
216 isKernelResourceObj
= OSDynamicCast(OSBoolean
,
217 extPlist
->getObject("OSKernelResource"));
218 if (isKernelResourceObj
&& isKernelResourceObj
->isTrue()) {
223 driverCode
= OSDynamicCast(OSData
, extDict
->getObject("code"));
224 compressedCode
= OSDynamicCast(OSData
,
225 extDict
->getObject("compressedCode"));
227 if (!driverCode
&& !compressedCode
) {
237 /*********************************************************************
238 * This function builds a uniqued, in-order list of modules that need
239 * to be loaded in order for kmod_name to be successfully loaded. This
240 * list ends with kmod_name itself.
241 *********************************************************************/
243 OSArray
* getDependencyListForKmod(const char * kmod_name
) {
247 OSDictionary
* extensionsDict
; // don't release
248 OSDictionary
* extDict
; // don't release
249 OSDictionary
* extPlist
; // don't release
250 OSString
* extName
; // don't release
251 OSArray
* dependencyList
= NULL
; // return value, caller releases
254 /* These are used to remove duplicates from the dependency list.
256 OSArray
* originalList
= NULL
; // must be released
257 OSDictionary
* encounteredNames
= NULL
; // must be release
260 /* Get the dictionary of startup extensions.
261 * This is keyed by module name.
263 extensionsDict
= getStartupExtensions();
264 if (!extensionsDict
) {
265 IOLog("getDependencyListForKmod(): No extensions dictionary.\n");
272 /* Get the requested extension's dictionary entry and its property
273 * list, containing module dependencies.
275 extDict
= OSDynamicCast(OSDictionary
,
276 extensionsDict
->getObject(kmod_name
));
279 IOLog("getDependencyListForKmod(): "
280 "Extension \"%s\" cannot be found.\n",
287 extPlist
= OSDynamicCast(OSDictionary
, extDict
->getObject("plist"));
289 IOLog("getDependencyListForKmod(): "
290 "Extension \"%s\" has no property list.\n",
298 /* Verify that the retrieved entry's "CFBundleIdentifier" property exists.
299 * This will be added to the dependency list.
301 extName
= OSDynamicCast(OSString
,
302 extPlist
->getObject("CFBundleIdentifier"));
304 IOLog("getDependencyListForKmod(): "
305 "Extension \"%s\" has no \"CFBundleIdentifier\" property.\n",
312 dependencyList
= OSArray::withCapacity(10);
313 if (!dependencyList
) {
314 IOLog("getDependencyListForKmod(): "
315 "Couldn't allocate dependency array for extension \"%s\".\n",
323 /* Okay, let's get started.
325 dependencyList
->setObject(extName
);
328 /* Here's a slightly tricky bit. This loop iterates through
329 * the dependency list until it runs off the end. Each time
330 * through, however, any number of dependencies can be added
331 * to the end of the list. Eventually some extensions won't
332 * have any more dependencies, no more names will be added
333 * to the list, and this loop will terminate.
335 for (i
= 0; i
< dependencyList
->getCount(); i
++) {
337 // None of these needs to be released, as they're all from plists.
339 OSDictionary
* curExtDict
;
340 OSDictionary
* curExtDepDict
;
341 OSDictionary
* curExtPlist
;
342 OSString
* curDepName
;
345 /* An arbitrary limit to prevent infinite loops.
348 IOLog("getDependencyListForKmod(): "
349 "max dependency list length exceeded for "
350 "extension \"%s\".\n",
357 curName
= OSDynamicCast(OSString
, dependencyList
->getObject(i
));
359 curExtDict
= OSDynamicCast(OSDictionary
,
360 extensionsDict
->getObject(curName
));
362 IOLog("getDependencyListForKmod(): "
363 "Extension \"%s\", required for extension \"%s\", "
364 "is not available.\n",
365 curName
->getCStringNoCopy(), kmod_name
);
371 curExtPlist
= OSDynamicCast(OSDictionary
,
372 curExtDict
->getObject("plist"));
374 IOLog("getDependencyListForKmod(): "
375 "Extension \"%s\", required for extension \"%s\", "
376 "has no property list.\n",
377 curName
->getCStringNoCopy(), kmod_name
);
383 curExtDepDict
= OSDynamicCast(OSDictionary
,
384 curExtPlist
->getObject("OSBundleLibraries"));
386 OSCollectionIterator
* keyIterator
=
387 OSCollectionIterator::withCollection(curExtDepDict
);
390 IOLog("getDependencyListForKmod(): "
391 "Couldn't allocate iterator for extension "
392 "\"%s\".\n", kmod_name
);
397 while ( (curDepName
=
398 OSDynamicCast(OSString
,
399 keyIterator
->getNextObject())) ) {
401 OSString
* requiredVersion
= OSDynamicCast(OSString
,
402 curExtDepDict
->getObject(curDepName
));
404 if (!verifyCompatibility(curDepName
, requiredVersion
)) {
405 IOLog("getDependencyListForKmod(): "
406 "Dependency %s of %s is not compatible or is unavailable.\n",
407 curDepName
->getCStringNoCopy(),
408 curName
->getCStringNoCopy());
414 dependencyList
->setObject(curDepName
);
417 keyIterator
->release();
423 * The dependency list now exists in the reverse order of required loads,
424 * and may have duplicates. Now we turn the list around and remove
427 originalList
= dependencyList
;
428 dependencyList
= OSArray::withCapacity(originalList
->getCount());
429 if (!dependencyList
) {
430 IOLog("getDependenciesForKmod(): "
431 "Couldn't allocate reversal dependency list for extension "
432 "\"%s\".\n", kmod_name
);
437 encounteredNames
= OSDictionary::withCapacity(originalList
->getCount());
438 if (!encounteredNames
) {
439 IOLog("getDependenciesForKmod(): "
440 "Couldn't allocate list of encountered names for extension "
441 "\"%s\".\n", kmod_name
);
448 /* Go backward through the original list, using the encounteredNames
449 * dictionary to check for duplicates. We put originalList in as the
450 * value because we need some non-NULL value. Here we also drop any
451 * extensions that aren't proper dependencies (that is, any that are
452 * nonkernel kexts without code).
454 i
= originalList
->getCount();
460 OSString
* item
= OSDynamicCast(OSString
,
461 originalList
->getObject(i
));
463 if ( (!encounteredNames
->getObject(item
)) &&
464 kextIsADependency(item
)) {
466 encounteredNames
->setObject(item
, originalList
);
467 dependencyList
->setObject(item
);
476 originalList
->release();
478 if (encounteredNames
) {
479 encounteredNames
->release();
482 if (dependencyList
) {
483 dependencyList
->release();
484 dependencyList
= NULL
;
488 return dependencyList
;
492 /*********************************************************************
493 *********************************************************************/
494 /* Used in address_for_loaded_kmod.
496 static kmod_info_t
* g_current_kmod_info
= NULL
;
497 static const char * g_current_kmod_name
= NULL
;
499 /* Globals to pass link buffer info from
500 * address_for_loaded_kmod() and alloc_for_kmod()
503 * link_load_address is the address used to lay
504 * down the linked code. It gets adjusted by the
505 * pad between the headers size and a full page
506 * multiple. If an error occurs this gets set to
507 * zero so that the kld client code can detect
508 * an address or allocation error even if kld
511 * link_load_size is the size of the image as
512 * created by kld_load_from_memory(). link_buffer_size
513 * is the size of the buffer allocated for the final
514 * laid-down image, and is adjusted by rounding the
515 * load size and header size up to full-page multiples.
517 * link_buffer_address is set only by alloc_for_kmod();
518 * its value is used as a check if kld_load_from_memory()
519 * fails so that the buffer can be deallocated.
521 static unsigned long link_load_address
= 0;
522 static unsigned long link_load_size
= 0;
523 static unsigned long link_buffer_size
= 0;
524 static unsigned long link_header_size
= 0;
525 static unsigned long link_buffer_address
= 0;
528 /*********************************************************************
529 * This function is registered before kmod_load_from_memory() is
530 * invoked to build symbol table entries for an already-loaded
531 * kmod. This function just checks the g_current_kmod_info variable
532 * to gets its load address, and futzes it by the header offset (pad).
533 * See lower comments for more info on load address futzing.
534 *********************************************************************/
536 unsigned long address_for_loaded_kmod(
538 unsigned long headers_size
) {
540 unsigned long round_headers_size
;
541 unsigned long headers_pad
;
543 if (!g_current_kmod_info
) {
544 IOLog("address_for_loaded_kmod(): No current kmod.\n");
546 link_load_address
= 0; // error sentinel for kld client
550 round_headers_size
= round_page_32(headers_size
);
551 headers_pad
= round_headers_size
- headers_size
;
553 link_load_address
= (unsigned long)g_current_kmod_info
->address
+
556 return link_load_address
;
560 /*********************************************************************
561 * This function is registered before kmod_load_from_memory() is
562 * invoked to actually load a new kmod. It rounds up the header and
563 * total sizes and vm_allocates a buffer for the kmod. Now, KLD doesn't
564 * enforce any alignment of headers or segments, and we want to make
565 * sure that the executable code of the kmod lies on a page boundary.
566 * to do so, this function figures the pad between the actual header
567 * size and the page-rounded header size, and returns that offset into
568 * the allocated buffer. After kmod_load_from_memory() returns, its
569 * caller will move the mach_header struct back to the beginning of the
570 * allocated buffer so that the kmod_info_t structure contains the
572 *********************************************************************/
574 unsigned long alloc_for_kmod(
576 unsigned long headers_size
) {
578 vm_address_t buffer
= 0;
579 kern_return_t k_result
;
581 unsigned long round_headers_size
;
582 unsigned long round_segments_size
;
583 unsigned long round_size
;
584 unsigned long headers_pad
;
586 round_headers_size
= round_page_32(headers_size
);
587 round_segments_size
= round_page_32(size
- headers_size
);
588 round_size
= round_headers_size
+ round_segments_size
;
589 headers_pad
= round_headers_size
- headers_size
;
591 k_result
= vm_allocate(kernel_map
, (vm_offset_t
*)&buffer
,
592 round_size
, VM_FLAGS_ANYWHERE
);
593 if (k_result
!= KERN_SUCCESS
) {
594 IOLog("alloc_for_kmod(): Can't allocate memory.\n");
596 link_buffer_address
= 0; // make sure it's clear
597 link_load_address
= 0; // error sentinel for kld client
601 link_load_size
= size
;
603 link_buffer_address
= buffer
;
604 link_buffer_size
= round_size
;
605 link_header_size
= headers_size
; // NOT rounded!
607 link_load_address
= link_buffer_address
+ headers_pad
;
609 return link_load_address
;
612 /*********************************************************************
613 * This function reads the startup extensions dictionary to get the
614 * address and length of the executable data for the requested kmod.
615 *********************************************************************/
617 int map_and_patch(const char * kmod_name
) {
621 // Does the kld system already know about this kmod?
622 address
= (char *) kld_file_getaddr(kmod_name
, NULL
);
626 // None of these needs to be released.
627 OSDictionary
* extensionsDict
;
628 OSDictionary
* kmodDict
;
629 OSData
* compressedCode
= 0;
631 // Driver Code may need to be released
634 /* Get the requested kmod's info dictionary from the global
635 * startup extensions dictionary.
637 extensionsDict
= getStartupExtensions();
638 if (!extensionsDict
) {
639 IOLog("map_and_patch(): No extensions dictionary.\n");
644 kmodDict
= OSDynamicCast(OSDictionary
,
645 extensionsDict
->getObject(kmod_name
));
647 IOLog("map_and_patch(): "
648 "Extension \"%s\" cannot be found.\n", kmod_name
);
655 driverCode
= OSDynamicCast(OSData
, kmodDict
->getObject("code"));
657 ret
= kld_file_map(kmod_name
,
658 (unsigned char *) driverCode
->getBytesNoCopy(),
659 (size_t) driverCode
->getLength(),
662 else { // May be an compressed extension
664 // If we have a compressed segment the uncompressModule
665 // will return a new OSData object that points to the kmem_alloced
666 // memory. Note we don't take a reference to driverCode so later
667 // when we release it we will actually free this driver. Ownership
668 // of the kmem has been handed of to kld_file.
669 compressedCode
= OSDynamicCast(OSData
,
670 kmodDict
->getObject("compressedCode"));
671 if (!compressedCode
) {
672 IOLog("map_and_patch(): "
673 "Extension \"%s\" has no \"code\" property.\n", kmod_name
);
677 if (!uncompressModule(compressedCode
, &driverCode
)) {
678 IOLog("map_and_patch(): "
679 "Extension \"%s\" Couldn't uncompress code.\n", kmod_name
);
684 unsigned char *driver
= (unsigned char *) driverCode
->getBytesNoCopy();
685 size_t driverSize
= driverCode
->getLength();
687 ret
= kld_file_map(kmod_name
, driver
, driverSize
, /* isKmem */ true);
688 driverCode
->release();
690 kmem_free(kernel_map
, (vm_address_t
) driver
, driverSize
);
694 IOLog("map_and_patch(): "
695 "Extension \"%s\" Didn't successfully load.\n", kmod_name
);
701 if (!kld_file_patch_OSObjects(kmod_name
)) {
702 IOLog("map_and_patch(): "
703 "Extension \"%s\" Error binding OSObjects.\n", kmod_name
);
706 // RY: Instead of returning here, set the return value.
707 // We still need to call kld_file_prepare_for_link because
708 // we might have patched files outside of the driver. Don't
709 // worry, it will know to ignore the damaged file
713 // Now repair any damage that the kld patcher may have done to the image
714 kld_file_prepare_for_link();
719 /*********************************************************************
720 *********************************************************************/
721 bool stamp_kmod(const char * kmod_name
, kmod_info_t
* kmod_info
) {
723 OSDictionary
* extensionsDict
= NULL
; // don't release
724 OSDictionary
* kmodDict
= NULL
; // don't release
725 OSDictionary
* plist
= NULL
; // don't release
726 OSString
* versionString
= NULL
; // don't release
727 const char * plist_version
= NULL
; // don't free
729 if (strlen(kmod_name
) + 1 > KMOD_MAX_NAME
) {
730 IOLog("stamp_kmod(): Kext identifier \"%s\" is too long.\n",
737 strcpy(kmod_info
->name
, kmod_name
);
739 /* Get the dictionary of startup extensions.
740 * This is keyed by module name.
742 extensionsDict
= getStartupExtensions();
743 if (!extensionsDict
) {
744 IOLog("stamp_kmod(): No extensions dictionary.\n");
750 kmodDict
= OSDynamicCast(OSDictionary
,
751 extensionsDict
->getObject(kmod_name
));
753 IOLog("stamp_kmod(): Can't find record for kmod \"%s\".\n",
760 plist
= OSDynamicCast(OSDictionary
,
761 kmodDict
->getObject("plist"));
763 IOLog("stamp_kmod(): Kmod \"%s\" has no property list.\n",
771 * Get the kext's version and stuff it into the kmod. This used
772 * to be a check that the kext & kmod had the same version, but
773 * now we just overwrite the kmod's version.
776 versionString
= OSDynamicCast(OSString
,
777 plist
->getObject("CFBundleVersion"));
778 if (!versionString
) {
779 IOLog("stamp_kmod(): Kmod \"%s\" has no \"CFBundleVersion\" "
787 plist_version
= versionString
->getCStringNoCopy();
788 if (!plist_version
) {
789 IOLog("stamp_kmod(): Can't get C string for kext version.\n");
795 if (strlen(plist_version
) + 1 > KMOD_MAX_NAME
) {
796 IOLog("stamp_kmod(): Version \"%s\" of kext \"%s\" is too long.\n",
797 plist_version
, kmod_name
);
803 strcpy(kmod_info
->version
, plist_version
);
813 /*********************************************************************
814 * This function takes a dependency list containing a series of
815 * already-loaded module names, followed by a single name for a module
816 * that hasn't yet been loaded. It invokes kld_load_from_memory() to
817 * build symbol info for the already-loaded modules, and then finally
818 * loads the actually requested module.
819 *********************************************************************/
821 kern_return_t
load_kmod(OSArray
* dependencyList
) {
822 kern_return_t result
= KERN_SUCCESS
;
824 unsigned int num_dependencies
= 0;
825 kmod_info_t
** kmod_dependencies
= NULL
;
827 OSString
* requestedKmodName
; // don't release
828 const char * requested_kmod_name
;
829 OSString
* currentKmodName
; // don't release
831 unsigned long kmod_size
;
832 struct mach_header
* kmod_header
;
833 unsigned long kld_result
;
834 int do_kld_unload
= 0;
835 kmod_info_t
* kmod_info_freeme
= 0;
836 kmod_info_t
* kmod_info
= 0;
840 /* Separate the requested kmod from its dependencies.
842 i
= dependencyList
->getCount();
844 IOLog("load_kmod(): Called with empty list.\n");
846 result
= KERN_FAILURE
;
849 i
--; // make i be the index of the last entry
852 requestedKmodName
= OSDynamicCast(OSString
, dependencyList
->getObject(i
));
853 if (!requestedKmodName
) {
854 IOLog("load_kmod(): Called with invalid list of kmod names.\n");
856 result
= KERN_FAILURE
;
859 requested_kmod_name
= requestedKmodName
->getCStringNoCopy();
860 dependencyList
->removeObject(i
);
862 /* If the requested kmod is already loaded, there's no work to do.
864 kmod_info_freeme
= kmod_lookupbyname_locked(requested_kmod_name
);
865 if (kmod_info_freeme
) {
866 // FIXME: Need to check for version mismatch if already loaded.
867 result
= KERN_SUCCESS
;
872 /* Do the KLD loads for the already-loaded modules in order to get
875 kld_address_func(&address_for_loaded_kmod
);
877 num_dependencies
= dependencyList
->getCount();
878 kmod_dependencies
= (kmod_info_t
**)kalloc(num_dependencies
*
879 sizeof(kmod_info_t
*));
880 if (!kmod_dependencies
) {
881 IOLog("load_kmod(): Failed to allocate memory for dependency array "
882 "during load of kmod \"%s\".\n", requested_kmod_name
);
884 result
= KERN_FAILURE
;
888 bzero(kmod_dependencies
, num_dependencies
*
889 sizeof(kmod_info_t
*));
891 for (i
= 0; i
< num_dependencies
; i
++) {
893 currentKmodName
= OSDynamicCast(OSString
,
894 dependencyList
->getObject(i
));
896 if (!currentKmodName
) {
897 IOLog("load_kmod(): Invalid dependency name at index %d for "
898 "kmod \"%s\".\n", i
, requested_kmod_name
);
900 result
= KERN_FAILURE
;
904 const char * current_kmod_name
= currentKmodName
->getCStringNoCopy();
906 // These globals are needed by the kld_address functions
907 g_current_kmod_info
= kmod_lookupbyname_locked(current_kmod_name
);
908 g_current_kmod_name
= current_kmod_name
;
910 if (!g_current_kmod_info
) {
911 IOLog("load_kmod(): Missing dependency \"%s\".\n",
914 result
= KERN_FAILURE
;
918 /* Record the current kmod as a dependency of the requested
919 * one. This will be used in building references after the
922 kmod_dependencies
[i
] = g_current_kmod_info
;
924 /* If the current kmod's size is zero it means that we have a
925 * fake in-kernel dependency. If so then don't have to arrange
926 * for its symbol table to be reloaded as it is
927 * part of the kernel's symbol table..
929 if (!g_current_kmod_info
->size
)
932 if (!kld_file_merge_OSObjects(current_kmod_name
)) {
933 IOLog("load_kmod(): Can't merge OSObjects \"%s\".\n",
936 result
= KERN_FAILURE
;
940 kmod_address
= (char *)
941 kld_file_getaddr(current_kmod_name
, (long *) &kmod_size
);
944 IOLog("load_kmod() failed for dependency kmod "
945 "\"%s\".\n", current_kmod_name
);
947 result
= KERN_FAILURE
;
951 kld_result
= kld_load_from_memory(&kmod_header
,
952 current_kmod_name
, kmod_address
, kmod_size
);
958 if (!kld_result
|| !link_load_address
) {
959 IOLog("kld_load_from_memory() failed for dependency kmod "
960 "\"%s\".\n", current_kmod_name
);
962 result
= KERN_FAILURE
;
966 kld_forget_symbol("_kmod_info");
970 * Now that we've done all the dependencies, which should have already
971 * been loaded, we do the last requested module, which should not have
972 * already been loaded.
974 kld_address_func(&alloc_for_kmod
);
976 g_current_kmod_name
= requested_kmod_name
;
977 g_current_kmod_info
= 0; // there is no kmod yet
979 if (!map_and_patch(requested_kmod_name
)) {
980 IOLog("load_kmod: map_and_patch() failed for "
981 "kmod \"%s\".\n", requested_kmod_name
);
983 result
= KERN_FAILURE
;
987 kmod_address
= (char *)
988 kld_file_getaddr(requested_kmod_name
, (long *) &kmod_size
);
990 IOLog("load_kmod: kld_file_getaddr() failed internal error "
991 "on \"%s\".\n", requested_kmod_name
);
993 result
= KERN_FAILURE
;
997 kld_result
= kld_load_from_memory(&kmod_header
,
998 requested_kmod_name
, kmod_address
, kmod_size
);
1004 if (!kld_result
|| !link_load_address
) {
1005 IOLog("load_kmod(): kld_load_from_memory() failed for "
1006 "kmod \"%s\".\n", requested_kmod_name
);
1008 result
= KERN_FAILURE
;
1013 /* Copy the linked header and image into the vm_allocated buffer.
1014 * Move each onto the appropriate page-aligned boundary as given
1015 * by the global link_... variables.
1017 bzero((char *)link_buffer_address
, link_buffer_size
);
1018 // bcopy() is (from, to, length)
1019 bcopy((char *)kmod_header
, (char *)link_buffer_address
, link_header_size
);
1020 bcopy((char *)kmod_header
+ link_header_size
,
1021 (char *)link_buffer_address
+ round_page_32(link_header_size
),
1022 link_load_size
- link_header_size
);
1025 /* Get the kmod_info struct for the newly-loaded kmod.
1027 if (!kld_lookup("_kmod_info", (unsigned long *)&kmod_info
)) {
1028 IOLog("kld_lookup() of \"_kmod_info\" failed for "
1029 "kmod \"%s\".\n", requested_kmod_name
);
1031 result
= KERN_FAILURE
;
1036 if (!stamp_kmod(requested_kmod_name
, kmod_info
)) {
1037 // stamp_kmod() logs a meaningful message
1038 result
= KERN_FAILURE
;
1043 /* kld_lookup of _kmod_info yielded the actual linked address,
1044 * so now that we've copied the data into its real place,
1045 * we can set this stuff.
1047 kmod_info
->address
= link_buffer_address
;
1048 kmod_info
->size
= link_buffer_size
;
1049 kmod_info
->hdr_size
= round_page_32(link_header_size
);
1051 /* We've written data and instructions, so *flush* the data cache
1052 * and *invalidate* the instruction cache.
1054 flush_dcache64((addr64_t
)link_buffer_address
, link_buffer_size
, false);
1055 invalidate_icache64((addr64_t
)link_buffer_address
, link_buffer_size
, false);
1058 /* Register the new kmod with the kernel proper.
1060 if (kmod_create_internal(kmod_info
, &kmod_id
) != KERN_SUCCESS
) {
1061 IOLog("load_kmod(): kmod_create() failed for "
1062 "kmod \"%s\".\n", requested_kmod_name
);
1064 result
= KERN_FAILURE
;
1069 IOLog("kmod id %d successfully created at 0x%lx, size %ld.\n",
1070 (unsigned int)kmod_id
, link_buffer_address
, link_buffer_size
);
1074 /* Record dependencies for the newly-loaded kmod.
1076 for (i
= 0; i
< num_dependencies
; i
++) {
1077 kmod_info_t
* cur_dependency_info
;
1079 cur_dependency_info
= kmod_dependencies
[i
];
1080 packed_id
= KMOD_PACK_IDS(kmod_id
, cur_dependency_info
->id
);
1081 if (kmod_retain(packed_id
) != KERN_SUCCESS
) {
1082 IOLog("load_kmod(): kmod_retain() failed for "
1083 "kmod \"%s\".\n", requested_kmod_name
);
1085 kmod_destroy_internal(kmod_id
);
1086 result
= KERN_FAILURE
;
1091 /* Start the kmod (which invokes constructors for I/O Kit
1094 // kmod_start_or_stop(id, start?, user data, datalen)
1095 if (kmod_start_or_stop(kmod_id
, 1, 0, 0) != KERN_SUCCESS
) {
1096 IOLog("load_kmod(): kmod_start_or_stop() failed for "
1097 "kmod \"%s\".\n", requested_kmod_name
);
1099 kmod_destroy_internal(kmod_id
);
1100 result
= KERN_FAILURE
;
1106 if (kmod_info_freeme
) {
1107 kfree((unsigned int)kmod_info_freeme
, sizeof(kmod_info_t
));
1110 /* Only do a kld_unload_all() if at least one load happened.
1112 if (do_kld_unload
) {
1113 kld_unload_all(/* deallocate sets */ 1);
1116 /* If the link failed, blow away the allocated link buffer.
1118 if (result
!= KERN_SUCCESS
&& link_buffer_address
) {
1119 vm_deallocate(kernel_map
, link_buffer_address
, link_buffer_size
);
1122 if (kmod_dependencies
) {
1123 for (i
= 0; i
< num_dependencies
; i
++) {
1124 if (kmod_dependencies
[i
]) {
1125 kfree((unsigned int)kmod_dependencies
[i
], sizeof(kmod_info_t
));
1128 kfree((unsigned int)kmod_dependencies
,
1129 num_dependencies
* sizeof(kmod_info_t
*));
1132 /* Reset these static global variables for the next call.
1134 g_current_kmod_name
= NULL
;
1135 g_current_kmod_info
= NULL
;
1136 link_buffer_address
= 0;
1137 link_load_address
= 0;
1139 link_buffer_size
= 0;
1140 link_header_size
= 0;
1146 /*********************************************************************
1147 * This is the function that IOCatalogue calls in order to load a kmod.
1148 * It first checks whether the kmod is already loaded. If the kmod
1149 * isn't loaded, this function builds a dependency list and calls
1150 * load_kmod() repeatedly to guarantee that each dependency is in fact
1152 *********************************************************************/
1154 kern_return_t
load_kernel_extension(char * kmod_name
) {
1155 kern_return_t result
= KERN_SUCCESS
;
1156 kmod_info_t
* kmod_info
= 0; // must free
1157 OSArray
* dependencyList
= NULL
; // must release
1158 OSArray
* curDependencyList
= NULL
; // must release
1160 /* See if the kmod is already loaded.
1162 kmod_info
= kmod_lookupbyname_locked(kmod_name
);
1163 if (kmod_info
) { // NOT checked
1164 result
= KERN_SUCCESS
;
1168 /* It isn't loaded; build a dependency list and
1173 dependencyList
= getDependencyListForKmod(kmod_name
);
1174 if (!dependencyList
) {
1175 IOLog("load_kernel_extension(): "
1176 "Can't get dependencies for kernel extension \"%s\".\n",
1179 result
= KERN_FAILURE
;
1183 count
= dependencyList
->getCount();
1184 for (i
= 0; i
< count
; i
++) {
1185 kern_return_t load_result
;
1186 OSString
* curKmodName
; // don't release
1187 const char * cur_kmod_name
;
1189 curKmodName
= OSDynamicCast(OSString
,
1190 dependencyList
->getObject(i
));
1191 cur_kmod_name
= curKmodName
->getCStringNoCopy();
1192 curDependencyList
= getDependencyListForKmod(cur_kmod_name
);
1193 if (!curDependencyList
) {
1194 IOLog("load_kernel_extension(): "
1195 "Can't get dependencies for kernel extension \"%s\".\n",
1198 result
= KERN_FAILURE
;
1201 load_result
= load_kmod(curDependencyList
);
1202 if (load_result
!= KERN_SUCCESS
) {
1203 IOLog("load_kernel_extension(): "
1204 "load_kmod() failed for kmod \"%s\".\n",
1207 result
= load_result
;
1210 curDependencyList
->release();
1211 curDependencyList
= NULL
;
1219 kfree((unsigned int)kmod_info
, sizeof(kmod_info_t
));
1222 if (dependencyList
) {
1223 dependencyList
->release();
1224 dependencyList
= NULL
;
1226 if (curDependencyList
) {
1227 curDependencyList
->release();
1228 curDependencyList
= NULL
;