2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
22 #include <libsa/kmod.h>
23 #include <libkern/c++/OSContainers.h>
24 #include <IOKit/IOCatalogue.h>
25 #include <IOKit/IOLib.h>
26 #include <libsa/kmod.h>
27 #include <libsa/catalogue.h>
30 #include <mach-o/kld.h>
31 #include <libsa/vers_rsrc.h>
32 #include <libsa/stdlib.h>
33 #include <mach/kmod.h>
34 #include <vm/vm_kern.h>
35 #include <mach/kern_return.h>
36 #include <mach-o/fat.h>
37 #include <mach_loader.h>
40 #include "kld_patch.h"
50 kmod_destroy_internal(kmod_t id
);
57 mach_msg_type_number_t
*dataCount
);
59 extern kern_return_t
kmod_retain(kmod_t id
);
60 extern kern_return_t
kmod_release(kmod_t id
);
62 extern void flush_dcache(vm_offset_t addr
, unsigned cnt
, int phys
);
63 extern void invalidate_icache(vm_offset_t addr
, unsigned cnt
, int phys
);
69 #define VTYELLOW "\033[33m"
70 #define VTRESET "\033[0m"
75 /*********************************************************************
77 *********************************************************************/
78 bool verifyCompatibility(OSString
* extName
, OSString
* requiredVersion
)
80 OSDictionary
* extensionsDict
; // don't release
81 OSDictionary
* extDict
; // don't release
82 OSDictionary
* extPlist
; // don't release
83 OSString
* extVersion
; // don't release
84 OSString
* extCompatVersion
; // don't release
86 UInt32 ext_compat_version
;
87 UInt32 required_version
;
89 /* Get the dictionary of startup extensions.
90 * This is keyed by module name.
92 extensionsDict
= getStartupExtensions();
93 if (!extensionsDict
) {
94 IOLog("verifyCompatibility(): No extensions dictionary.\n");
98 /* Get the requested extension's dictionary entry and its property
99 * list, containing module dependencies.
101 extDict
= OSDynamicCast(OSDictionary
,
102 extensionsDict
->getObject(extName
));
105 IOLog("verifyCompatibility(): "
106 "Extension \"%s\" cannot be found.\n",
107 extName
->getCStringNoCopy());
111 extPlist
= OSDynamicCast(OSDictionary
, extDict
->getObject("plist"));
113 IOLog("verifyCompatibility(): "
114 "Extension \"%s\" has no property list.\n",
115 extName
->getCStringNoCopy());
120 extVersion
= OSDynamicCast(OSString
,
121 extPlist
->getObject("CFBundleVersion"));
123 IOLog("verifyCompatibility(): "
124 "Extension \"%s\" has no \"CFBundleVersion\" property.\n",
125 extName
->getCStringNoCopy());
129 extCompatVersion
= OSDynamicCast(OSString
,
130 extPlist
->getObject("OSBundleCompatibleVersion"));
131 if (!extCompatVersion
) {
132 IOLog("verifyCompatibility(): "
133 "Extension \"%s\" has no \"OSBundleCompatibleVersion\" property.\n",
134 extName
->getCStringNoCopy());
138 if (!VERS_parse_string(requiredVersion
->getCStringNoCopy(),
139 &required_version
)) {
140 IOLog("verifyCompatibility(): "
141 "Can't parse required version \"%s\" of dependency %s.\n",
142 requiredVersion
->getCStringNoCopy(),
143 extName
->getCStringNoCopy());
146 if (!VERS_parse_string(extVersion
->getCStringNoCopy(),
148 IOLog("verifyCompatibility(): "
149 "Can't parse version \"%s\" of dependency %s.\n",
150 extVersion
->getCStringNoCopy(),
151 extName
->getCStringNoCopy());
154 if (!VERS_parse_string(extCompatVersion
->getCStringNoCopy(),
155 &ext_compat_version
)) {
156 IOLog("verifyCompatibility(): "
157 "Can't parse compatible version \"%s\" of dependency %s.\n",
158 extCompatVersion
->getCStringNoCopy(),
159 extName
->getCStringNoCopy());
163 if (required_version
> ext_version
|| required_version
< ext_compat_version
) {
170 /*********************************************************************
171 * This function builds a uniqued, in-order list of modules that need
172 * to be loaded in order for kmod_name to be successfully loaded. This
173 * list ends with kmod_name itself.
174 *********************************************************************/
176 OSArray
* getDependencyListForKmod(const char * kmod_name
) {
180 OSDictionary
* extensionsDict
; // don't release
181 OSDictionary
* extDict
; // don't release
182 OSDictionary
* extPlist
; // don't release
183 OSString
* extName
; // don't release
184 OSArray
* dependencyList
= NULL
; // return value, caller releases
185 OSBoolean
* isKernelResourceObj
= 0; // don't release
186 bool isKernelResource
= false;
187 bool declaresExecutable
= false;
190 /* These are used to remove duplicates from the dependency list.
192 OSArray
* originalList
= NULL
; // must be released
193 OSDictionary
* encounteredNames
= NULL
; // must be release
196 /* Get the dictionary of startup extensions.
197 * This is keyed by module name.
199 extensionsDict
= getStartupExtensions();
200 if (!extensionsDict
) {
201 IOLog("getDependencyListForKmod(): No extensions dictionary.\n");
208 /* Get the requested extension's dictionary entry and its property
209 * list, containing module dependencies.
211 extDict
= OSDynamicCast(OSDictionary
,
212 extensionsDict
->getObject(kmod_name
));
215 IOLog("getDependencyListForKmod(): "
216 "Extension \"%s\" cannot be found.\n",
223 extPlist
= OSDynamicCast(OSDictionary
, extDict
->getObject("plist"));
225 IOLog("getDependencyListForKmod(): "
226 "Extension \"%s\" has no property list.\n",
234 /* Verify that the retrieved entry's "CFBundleIdentifier" property exists.
235 * This will be added to the dependency list.
237 extName
= OSDynamicCast(OSString
,
238 extPlist
->getObject("CFBundleIdentifier"));
240 IOLog("getDependencyListForKmod(): "
241 "Extension \"%s\" has no \"CFBundleIdentifier\" property.\n",
248 dependencyList
= OSArray::withCapacity(10);
249 if (!dependencyList
) {
250 IOLog("getDependencyListForKmod(): "
251 "Couldn't allocate dependency array for extension \"%s\".\n",
258 /* A kext that's not a kernel extension and declares no executable has nothing
259 * to load, so just return an empty array.
261 isKernelResourceObj
= OSDynamicCast(OSBoolean
,
262 extPlist
->getObject("OSKernelResource"));
263 if (isKernelResourceObj
&& isKernelResourceObj
->isTrue()) {
264 isKernelResource
= true;
266 isKernelResource
= false;
269 if (extPlist
->getObject("CFBundleExecutable")) {
270 declaresExecutable
= true;
272 declaresExecutable
= false;
275 if (!isKernelResource
&& !declaresExecutable
) {
280 /* Okay, let's get started.
282 dependencyList
->setObject(extName
);
285 /* Here's a slightly tricky bit. This loop iterates through
286 * the dependency list until it runs off the end. Each time
287 * through, however, any number of dependencies can be added
288 * to the end of the list. Eventually some extensions won't
289 * have any more dependencies, no more names will be added
290 * to the list, and this loop will terminate.
292 for (i
= 0; i
< dependencyList
->getCount(); i
++) {
294 // None of these needs to be released, as they're all from plists.
296 OSDictionary
* curExtDict
;
297 OSDictionary
* curExtDepDict
;
298 OSDictionary
* curExtPlist
;
299 OSString
* curDepName
;
302 /* An arbitrary limit to prevent infinite loops.
305 IOLog("getDependencyListForKmod(): "
306 "max dependency list length exceeded for "
307 "extension \"%s\".\n",
314 curName
= OSDynamicCast(OSString
, dependencyList
->getObject(i
));
316 curExtDict
= OSDynamicCast(OSDictionary
,
317 extensionsDict
->getObject(curName
));
319 IOLog("getDependencyListForKmod(): "
320 "Extension \"%s\", required for extension \"%s\", "
321 "is not available.\n",
322 curName
->getCStringNoCopy(), kmod_name
);
328 curExtPlist
= OSDynamicCast(OSDictionary
,
329 curExtDict
->getObject("plist"));
331 IOLog("getDependencyListForKmod(): "
332 "Extension \"%s\", required for extension \"%s\", "
333 "has no property list.\n",
334 curName
->getCStringNoCopy(), kmod_name
);
340 curExtDepDict
= OSDynamicCast(OSDictionary
,
341 curExtPlist
->getObject("OSBundleLibraries"));
343 OSCollectionIterator
* keyIterator
=
344 OSCollectionIterator::withCollection(curExtDepDict
);
347 IOLog("getDependencyListForKmod(): "
348 "Couldn't allocate iterator for extension "
349 "\"%s\".\n", kmod_name
);
354 while ( (curDepName
=
355 OSDynamicCast(OSString
,
356 keyIterator
->getNextObject())) ) {
358 OSString
* requiredVersion
= OSDynamicCast(OSString
,
359 curExtDepDict
->getObject(curDepName
));
361 if (!verifyCompatibility(curDepName
, requiredVersion
)) {
362 IOLog("getDependencyListForKmod(): "
363 "Dependency %s of %s is not compatible or is unavailable.\n",
364 curDepName
->getCStringNoCopy(),
365 curName
->getCStringNoCopy());
371 /* Don't add any entries that are not kernel resources and that declare no
372 * executable. Such kexts have nothing to load and so don't belong in the
373 * dependency list. Entries that are kernel resource *do* get added,
374 * however, because such kexts get fake kmod entries for reference counting.
376 isKernelResourceObj
= OSDynamicCast(OSBoolean
,
377 curExtPlist
->getObject("OSKernelResource"));
378 if (isKernelResourceObj
&& isKernelResourceObj
->isTrue()) {
379 isKernelResource
= true;
381 isKernelResource
= false;
383 if (curExtPlist
->getObject("CFBundleExecutable")) {
384 declaresExecutable
= true;
386 declaresExecutable
= false;
389 if (!isKernelResource
&& !declaresExecutable
) {
393 dependencyList
->setObject(curDepName
);
396 keyIterator
->release();
402 * The dependency list now exists in the reverse order of required loads,
403 * and may have duplicates. Now we turn the list around and remove
406 originalList
= dependencyList
;
407 dependencyList
= OSArray::withCapacity(originalList
->getCount());
408 if (!dependencyList
) {
409 IOLog("getDependenciesForKmod(): "
410 "Couldn't allocate reversal dependency list for extension "
411 "\"%s\".\n", kmod_name
);
416 encounteredNames
= OSDictionary::withCapacity(originalList
->getCount());
417 if (!encounteredNames
) {
418 IOLog("getDependenciesForKmod(): "
419 "Couldn't allocate list of encountered names for extension "
420 "\"%s\".\n", kmod_name
);
427 /* Go backward through the original list, using the encounteredNames
428 * dictionary to check for duplicates. We put originalList in as the
429 * value because we need some non-NULL value.
431 i
= originalList
->getCount();
437 OSString
* item
= OSDynamicCast(OSString
,
438 originalList
->getObject(i
));
440 if ( ! encounteredNames
->getObject(item
) ) {
441 encounteredNames
->setObject(item
, originalList
);
442 dependencyList
->setObject(item
);
451 originalList
->release();
453 if (encounteredNames
) {
454 encounteredNames
->release();
457 if (dependencyList
) {
458 dependencyList
->release();
459 dependencyList
= NULL
;
463 return dependencyList
;
467 /*********************************************************************
468 *********************************************************************/
469 /* Used in address_for_loaded_kmod.
471 static kmod_info_t
* g_current_kmod_info
= NULL
;
472 static const char * g_current_kmod_name
= NULL
;
474 /* Globals to pass link buffer info from
475 * address_for_loaded_kmod() and alloc_for_kmod()
478 * link_load_address is the address used to lay
479 * down the linked code. It gets adjusted by the
480 * pad between the headers size and a full page
481 * multiple. If an error occurs this gets set to
482 * zero so that the kld client code can detect
483 * an address or allocation error even if kld
486 * link_load_size is the size of the image as
487 * created by kld_load_from_memory(). link_buffer_size
488 * is the size of the buffer allocated for the final
489 * laid-down image, and is adjusted by rounding the
490 * load size and header size up to full-page multiples.
492 * link_buffer_address is set only by alloc_for_kmod();
493 * its value is used as a check if kld_load_from_memory()
494 * fails so that the buffer can be deallocated.
496 static unsigned long link_load_address
= 0;
497 static unsigned long link_load_size
= 0;
498 static unsigned long link_buffer_size
= 0;
499 static unsigned long link_header_size
= 0;
500 static unsigned long link_buffer_address
= 0;
503 /*********************************************************************
504 * This function is registered before kmod_load_from_memory() is
505 * invoked to build symbol table entries for an already-loaded
506 * kmod. This function just checks the g_current_kmod_info variable
507 * to gets its load address, and futzes it by the header offset (pad).
508 * See lower comments for more info on load address futzing.
509 *********************************************************************/
511 unsigned long address_for_loaded_kmod(
513 unsigned long headers_size
) {
515 unsigned long round_headers_size
;
516 unsigned long headers_pad
;
518 if (!g_current_kmod_info
) {
519 IOLog("address_for_loaded_kmod(): No current kmod.\n");
521 link_load_address
= 0; // error sentinel for kld client
525 round_headers_size
= round_page(headers_size
);
526 headers_pad
= round_headers_size
- headers_size
;
528 link_load_address
= (unsigned long)g_current_kmod_info
->address
+
531 return link_load_address
;
535 /*********************************************************************
536 * This function is registered before kmod_load_from_memory() is
537 * invoked to actually load a new kmod. It rounds up the header and
538 * total sizes and vm_allocates a buffer for the kmod. Now, KLD doesn't
539 * enforce any alignment of headers or segments, and we want to make
540 * sure that the executable code of the kmod lies on a page boundary.
541 * to do so, this function figures the pad between the actual header
542 * size and the page-rounded header size, and returns that offset into
543 * the allocated buffer. After kmod_load_from_memory() returns, its
544 * caller will move the mach_header struct back to the beginning of the
545 * allocated buffer so that the kmod_info_t structure contains the
547 *********************************************************************/
549 unsigned long alloc_for_kmod(
551 unsigned long headers_size
) {
553 vm_address_t buffer
= 0;
554 kern_return_t k_result
;
556 unsigned long round_headers_size
;
557 unsigned long round_segments_size
;
558 unsigned long round_size
;
559 unsigned long headers_pad
;
561 round_headers_size
= round_page(headers_size
);
562 round_segments_size
= round_page(size
- headers_size
);
563 round_size
= round_headers_size
+ round_segments_size
;
564 headers_pad
= round_headers_size
- headers_size
;
566 k_result
= vm_allocate(kernel_map
, (vm_offset_t
*)&buffer
,
568 if (k_result
!= KERN_SUCCESS
) {
569 IOLog("alloc_for_kmod(): Can't allocate memory.\n");
571 link_buffer_address
= 0; // make sure it's clear
572 link_load_address
= 0; // error sentinel for kld client
576 link_load_size
= size
;
578 link_buffer_address
= buffer
;
579 link_buffer_size
= round_size
;
580 link_header_size
= headers_size
; // NOT rounded!
582 link_load_address
= link_buffer_address
+ headers_pad
;
584 return link_load_address
;
587 /*********************************************************************
588 * This function reads the startup extensions dictionary to get the
589 * address and length of the executable data for the requested kmod.
590 *********************************************************************/
592 int map_and_patch(const char * kmod_name
) {
596 // Does the kld system already know about this kmod?
597 address
= (char *) kld_file_getaddr(kmod_name
, NULL
);
601 // None of these needs to be released.
602 OSDictionary
* extensionsDict
;
603 OSDictionary
* kmodDict
;
604 OSData
* compressedCode
= 0;
606 // Driver Code may need to be released
609 /* Get the requested kmod's info dictionary from the global
610 * startup extensions dictionary.
612 extensionsDict
= getStartupExtensions();
613 if (!extensionsDict
) {
614 IOLog("map_and_patch(): No extensions dictionary.\n");
619 kmodDict
= OSDynamicCast(OSDictionary
,
620 extensionsDict
->getObject(kmod_name
));
622 IOLog("map_and_patch(): "
623 "Extension \"%s\" cannot be found.\n", kmod_name
);
630 driverCode
= OSDynamicCast(OSData
, kmodDict
->getObject("code"));
632 ret
= kld_file_map(kmod_name
,
633 (unsigned char *) driverCode
->getBytesNoCopy(),
634 (size_t) driverCode
->getLength(),
637 else { // May be an compressed extension
639 // If we have a compressed segment the uncompressModule
640 // will return a new OSData object that points to the kmem_alloced
641 // memory. Note we don't take a reference to driverCode so later
642 // when we release it we will actually free this driver. Ownership
643 // of the kmem has been handed of to kld_file.
644 compressedCode
= OSDynamicCast(OSData
,
645 kmodDict
->getObject("compressedCode"));
646 if (!compressedCode
) {
647 IOLog("map_and_patch(): "
648 "Extension \"%s\" has no \"code\" property.\n", kmod_name
);
652 if (!uncompressModule(compressedCode
, &driverCode
)) {
653 IOLog("map_and_patch(): "
654 "Extension \"%s\" Couldn't uncompress code.\n", kmod_name
);
659 unsigned char *driver
= (unsigned char *) driverCode
->getBytesNoCopy();
660 size_t driverSize
= driverCode
->getLength();
662 ret
= kld_file_map(kmod_name
, driver
, driverSize
, /* isKmem */ true);
663 driverCode
->release();
665 kmem_free(kernel_map
, (vm_address_t
) driver
, driverSize
);
669 IOLog("map_and_patch(): "
670 "Extension \"%s\" Didn't successfully load.\n", kmod_name
);
675 if (!kld_file_patch_OSObjects(kmod_name
)) {
676 IOLog("map_and_patch(): "
677 "Extension \"%s\" Error binding OSObjects.\n", kmod_name
);
682 // Now repair any damage that the kld patcher may have done to the image
683 kld_file_prepare_for_link();
688 /*********************************************************************
689 *********************************************************************/
690 bool verify_kmod(const char * kmod_name
, kmod_info_t
* kmod_info
) {
692 OSDictionary
* extensionsDict
= NULL
; // don't release
693 OSDictionary
* kmodDict
= NULL
; // don't release
694 OSDictionary
* plist
= NULL
; // don't release
695 OSString
* versionString
= NULL
; // don't release
699 if (strncmp(kmod_name
, kmod_info
->name
, sizeof(kmod_info
->name
))) {
700 IOLog("verify_kmod(): kmod loaded as \"%s\" has different "
701 "identifier \"%s\".\n", kmod_name
, kmod_info
->name
);
707 if (!VERS_parse_string(kmod_info
->version
,
710 IOLog("verify_kmod(): kmod \"%s\" has an invalid "
711 "version.\n", kmod_info
->name
);
718 /* Get the dictionary of startup extensions.
719 * This is keyed by module name.
721 extensionsDict
= getStartupExtensions();
722 if (!extensionsDict
) {
723 IOLog("verify_kmod(): No extensions dictionary.\n");
729 kmodDict
= OSDynamicCast(OSDictionary
,
730 extensionsDict
->getObject(kmod_name
));
732 IOLog("verify_kmod(): Can't find record for kmod \"%s\".\n",
739 plist
= OSDynamicCast(OSDictionary
,
740 kmodDict
->getObject("plist"));
742 IOLog("verify_kmod(): Kmod \"%s\" has no property list.\n",
749 versionString
= OSDynamicCast(OSString
,
750 plist
->getObject("CFBundleVersion"));
751 if (!versionString
) {
752 IOLog("verify_kmod(): Kmod \"%s\" has no \"CFBundleVersion\" "
760 if (!VERS_parse_string(versionString
->getCStringNoCopy(),
763 IOLog("verify_kmod(): Property list for kmod \"%s\" has "
764 "an invalid version.\n", kmod_info
->name
);
770 if (kmod_vers
!= plist_vers
) {
771 IOLog("verify_kmod(): Kmod \"%s\" and its property list "
772 "claim different versions (%s & %s).\n",
775 versionString
->getCStringNoCopy());
789 /*********************************************************************
790 * This function takes a dependency list containing a series of
791 * already-loaded module names, followed by a single name for a module
792 * that hasn't yet been loaded. It invokes kld_load_from_memory() to
793 * build symbol info for the already-loaded modules, and then finally
794 * loads the actually requested module.
795 *********************************************************************/
797 kern_return_t
load_kmod(OSArray
* dependencyList
) {
798 kern_return_t result
= KERN_SUCCESS
;
800 unsigned int num_dependencies
= 0;
801 kmod_info_t
** kmod_dependencies
= NULL
;
803 OSString
* requestedKmodName
; // don't release
804 const char * requested_kmod_name
;
805 OSString
* currentKmodName
; // don't release
807 unsigned long kmod_size
;
808 struct mach_header
* kmod_header
;
809 unsigned long kld_result
;
810 int do_kld_unload
= 0;
811 kmod_info_t
* kmod_info
;
815 /* Separate the requested kmod from its dependencies.
817 i
= dependencyList
->getCount();
819 IOLog("load_kmod(): Called with empty list.\n");
821 result
= KERN_FAILURE
;
824 i
--; // make i be the index of the last entry
827 requestedKmodName
= OSDynamicCast(OSString
, dependencyList
->getObject(i
));
828 if (!requestedKmodName
) {
829 IOLog("load_kmod(): Called with invalid list of kmod names.\n");
831 result
= KERN_FAILURE
;
834 requested_kmod_name
= requestedKmodName
->getCStringNoCopy();
835 dependencyList
->removeObject(i
);
837 /* If the requested kmod is already loaded, there's no work to do.
839 kmod_info
= kmod_lookupbyname(requested_kmod_name
);
841 // FIXME: Need to check for version mismatch if already loaded.
842 result
= KERN_SUCCESS
;
847 /* Do the KLD loads for the already-loaded modules in order to get
850 kld_address_func(&address_for_loaded_kmod
);
852 num_dependencies
= dependencyList
->getCount();
853 kmod_dependencies
= (kmod_info_t
**)kalloc(num_dependencies
*
854 sizeof(kmod_info_t
*));
855 if (!kmod_dependencies
) {
856 IOLog("load_kmod(): Failed to allocate memory for dependency array "
857 "during load of kmod \"%s\".\n", requested_kmod_name
);
859 result
= KERN_FAILURE
;
863 for (i
= 0; i
< num_dependencies
; i
++) {
865 currentKmodName
= OSDynamicCast(OSString
,
866 dependencyList
->getObject(i
));
868 if (!currentKmodName
) {
869 IOLog("load_kmod(): Invalid dependency name at index %d for "
870 "kmod \"%s\".\n", i
, requested_kmod_name
);
872 result
= KERN_FAILURE
;
876 const char * current_kmod_name
= currentKmodName
->getCStringNoCopy();
878 // These globals are needed by the kld_address functions
879 g_current_kmod_info
= kmod_lookupbyname(current_kmod_name
);
880 g_current_kmod_name
= current_kmod_name
;
882 if (!g_current_kmod_info
) {
883 IOLog("load_kmod(): Missing dependency \"%s\".\n",
886 result
= KERN_FAILURE
;
890 /* Record the current kmod as a dependency of the requested
891 * one. This will be used in building references after the
894 kmod_dependencies
[i
] = g_current_kmod_info
;
896 /* If the current kmod's size is zero it means that we have a
897 * fake in-kernel dependency. If so then don't have to arrange
898 * for its symbol table to be reloaded as it is
899 * part of the kernel's symbol table..
901 if (!g_current_kmod_info
->size
)
904 if (!kld_file_merge_OSObjects(current_kmod_name
)) {
905 IOLog("get_text_info_for_kmod(): Can't merge OSObjects \"%s\".\n",
908 result
= KERN_FAILURE
;
912 kmod_address
= (char *)
913 kld_file_getaddr(current_kmod_name
, (long *) &kmod_size
);
916 IOLog("get_text_info_for_kmod() failed for dependency kmod "
917 "\"%s\".\n", current_kmod_name
);
919 result
= KERN_FAILURE
;
923 kld_result
= kld_load_from_memory(&kmod_header
,
924 current_kmod_name
, kmod_address
, kmod_size
);
930 if (!kld_result
|| !link_load_address
) {
931 IOLog("kld_load_from_memory() failed for dependency kmod "
932 "\"%s\".\n", current_kmod_name
);
934 result
= KERN_FAILURE
;
938 kld_forget_symbol("_kmod_info");
942 * Now that we've done all the dependencies, which should have already
943 * been loaded, we do the last requested module, which should not have
944 * already been loaded.
946 kld_address_func(&alloc_for_kmod
);
948 g_current_kmod_name
= requested_kmod_name
;
949 g_current_kmod_info
= 0; // there is no kmod yet
951 if (!map_and_patch(requested_kmod_name
)) {
952 IOLog("load_kmod: map_and_patch() failed for "
953 "kmod \"%s\".\n", requested_kmod_name
);
955 result
= KERN_FAILURE
;
959 kmod_address
= (char *)
960 kld_file_getaddr(requested_kmod_name
, (long *) &kmod_size
);
962 IOLog("load_kmod: kld_file_getaddr() failed internal error "
963 "on \"%s\".\n", requested_kmod_name
);
965 result
= KERN_FAILURE
;
969 kld_result
= kld_load_from_memory(&kmod_header
,
970 requested_kmod_name
, kmod_address
, kmod_size
);
976 if (!kld_result
|| !link_load_address
) {
977 IOLog("load_kmod(): kld_load_from_memory() failed for "
978 "kmod \"%s\".\n", requested_kmod_name
);
980 result
= KERN_FAILURE
;
985 /* Copy the linked header and image into the vm_allocated buffer.
986 * Move each onto the appropriate page-aligned boundary as given
987 * by the global link_... variables.
989 bzero((char *)link_buffer_address
, link_buffer_size
);
990 // bcopy() is (from, to, length)
991 bcopy((char *)kmod_header
, (char *)link_buffer_address
, link_header_size
);
992 bcopy((char *)kmod_header
+ link_header_size
,
993 (char *)link_buffer_address
+ round_page(link_header_size
),
994 link_load_size
- link_header_size
);
997 /* Get the kmod_info struct for the newly-loaded kmod.
999 if (!kld_lookup("_kmod_info", (unsigned long *)&kmod_info
)) {
1000 IOLog("kld_lookup() of \"_kmod_info\" failed for "
1001 "kmod \"%s\".\n", requested_kmod_name
);
1003 result
= KERN_FAILURE
;
1008 if (!verify_kmod(requested_kmod_name
, kmod_info
)) {
1009 // verify_kmod() logs a meaningful message
1010 result
= KERN_FAILURE
;
1015 /* kld_lookup of _kmod_info yielded the actual linked address,
1016 * so now that we've copied the data into its real place,
1017 * we can set this stuff.
1019 kmod_info
->address
= link_buffer_address
;
1020 kmod_info
->size
= link_buffer_size
;
1021 kmod_info
->hdr_size
= round_page(link_header_size
);
1023 /* We've written data and instructions, so *flush* the data cache
1024 * and *invalidate* the instruction cache.
1026 flush_dcache(link_buffer_address
, link_buffer_size
, false);
1027 invalidate_icache(link_buffer_address
, link_buffer_size
, false);
1030 /* Register the new kmod with the kernel proper.
1032 if (kmod_create_internal(kmod_info
, &kmod_id
) != KERN_SUCCESS
) {
1033 IOLog("load_kmod(): kmod_create() failed for "
1034 "kmod \"%s\".\n", requested_kmod_name
);
1036 result
= KERN_FAILURE
;
1041 IOLog("kmod id %d successfully created at 0x%lx, size %ld.\n",
1042 (unsigned int)kmod_id
, link_buffer_address
, link_buffer_size
);
1046 /* Record dependencies for the newly-loaded kmod.
1048 for (i
= 0; i
< num_dependencies
; i
++) {
1049 kmod_info_t
* cur_dependency_info
;
1051 cur_dependency_info
= kmod_dependencies
[i
];
1052 packed_id
= KMOD_PACK_IDS(kmod_id
, cur_dependency_info
->id
);
1053 if (kmod_retain(packed_id
) != KERN_SUCCESS
) {
1054 IOLog("load_kmod(): kmod_retain() failed for "
1055 "kmod \"%s\".\n", requested_kmod_name
);
1057 kmod_destroy_internal(kmod_id
);
1058 result
= KERN_FAILURE
;
1063 /* Start the kmod (which invokes constructors for I/O Kit
1066 // kmod_start_or_stop(id, start?, user data, datalen)
1067 if (kmod_start_or_stop(kmod_id
, 1, 0, 0) != KERN_SUCCESS
) {
1068 IOLog("load_kmod(): kmod_start_or_stop() failed for "
1069 "kmod \"%s\".\n", requested_kmod_name
);
1071 kmod_destroy_internal(kmod_id
);
1072 result
= KERN_FAILURE
;
1078 /* Only do a kld_unload_all() if at least one load happened.
1080 if (do_kld_unload
) {
1081 kld_unload_all(/* deallocate sets */ 1);
1085 /* If the link failed, blow away the allocated link buffer.
1087 if (result
!= KERN_SUCCESS
&& link_buffer_address
) {
1088 vm_deallocate(kernel_map
, link_buffer_address
, link_buffer_size
);
1091 if (kmod_dependencies
) {
1092 kfree((unsigned int)kmod_dependencies
,
1093 num_dependencies
* sizeof(kmod_info_t
*));
1096 /* Reset these static global variables for the next call.
1098 g_current_kmod_name
= NULL
;
1099 g_current_kmod_info
= NULL
;
1100 link_buffer_address
= 0;
1101 link_load_address
= 0;
1103 link_buffer_size
= 0;
1104 link_header_size
= 0;
1110 /*********************************************************************
1111 * This is the function that IOCatalogue calls in order to load a kmod.
1112 * It first checks whether the kmod is already loaded. If the kmod
1113 * isn't loaded, this function builds a dependency list and calls
1114 * load_kmod() repeatedly to guarantee that each dependency is in fact
1116 *********************************************************************/
1118 kern_return_t
load_kernel_extension(char * kmod_name
) {
1119 kern_return_t result
= KERN_SUCCESS
;
1120 kmod_info_t
* kmod_info
;
1121 OSArray
* dependencyList
= NULL
; // must release
1122 OSArray
* curDependencyList
= NULL
; // must release
1123 bool isKernelResource
= false;
1125 /* See if the kmod is already loaded.
1127 kmod_info
= kmod_lookupbyname(kmod_name
);
1128 if (kmod_info
) { // NOT checked
1129 result
= KERN_SUCCESS
;
1133 /* It isn't loaded; build a dependency list and
1138 dependencyList
= getDependencyListForKmod(kmod_name
);
1139 if (!dependencyList
) {
1140 IOLog("load_kernel_extension(): "
1141 "Can't get dependencies for kernel extension \"%s\".\n",
1144 result
= KERN_FAILURE
;
1148 count
= dependencyList
->getCount();
1149 for (i
= 0; i
< count
; i
++) {
1150 kern_return_t load_result
;
1151 OSString
* curKmodName
; // don't release
1152 const char * cur_kmod_name
;
1154 curKmodName
= OSDynamicCast(OSString
,
1155 dependencyList
->getObject(i
));
1156 cur_kmod_name
= curKmodName
->getCStringNoCopy();
1157 curDependencyList
= getDependencyListForKmod(cur_kmod_name
);
1158 if (!curDependencyList
) {
1159 IOLog("load_kernel_extension(): "
1160 "Can't get dependencies for kernel extension \"%s\".\n",
1163 result
= KERN_FAILURE
;
1166 load_result
= load_kmod(curDependencyList
);
1167 if (load_result
!= KERN_SUCCESS
) {
1168 IOLog("load_kernel_extension(): "
1169 "load_kmod() failed for kmod \"%s\".\n",
1172 result
= load_result
;
1175 curDependencyList
->release();
1176 curDependencyList
= NULL
;
1183 if (dependencyList
) {
1184 dependencyList
->release();
1185 dependencyList
= NULL
;
1187 if (curDependencyList
) {
1188 curDependencyList
->release();
1189 curDependencyList
= NULL
;