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_dcache64(addr64_t addr
, unsigned cnt
, int phys
);
63 extern void invalidate_icache64(addr64_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 *********************************************************************/
173 Boolean
kextIsADependency(OSString
* name
) {
174 Boolean result
= true;
175 OSDictionary
* extensionsDict
= 0; // don't release
176 OSDictionary
* extDict
= 0; // don't release
177 OSDictionary
* extPlist
= 0; // don't release
178 OSBoolean
* isKernelResourceObj
= 0; // don't release
179 OSData
* driverCode
= 0; // don't release
180 OSData
* compressedCode
= 0; // don't release
182 extensionsDict
= getStartupExtensions();
183 if (!extensionsDict
) {
184 IOLog("kextIsADependency(): No extensions dictionary.\n");
191 extDict
= OSDynamicCast(OSDictionary
,
192 extensionsDict
->getObject(name
));
194 IOLog("kextIsADependency(): "
195 "Extension \"%s\" cannot be found.\n",
196 name
->getCStringNoCopy());
202 extPlist
= OSDynamicCast(OSDictionary
, extDict
->getObject("plist"));
204 IOLog("getDependencyListForKmod(): "
205 "Extension \"%s\" has no property list.\n",
206 name
->getCStringNoCopy());
212 /* A kext that is a kernel component is still a dependency, as there
213 * are fake kmod entries for them.
215 isKernelResourceObj
= OSDynamicCast(OSBoolean
,
216 extPlist
->getObject("OSKernelResource"));
217 if (isKernelResourceObj
&& isKernelResourceObj
->isTrue()) {
222 driverCode
= OSDynamicCast(OSData
, extDict
->getObject("code"));
223 compressedCode
= OSDynamicCast(OSData
,
224 extDict
->getObject("compressedCode"));
226 if (!driverCode
&& !compressedCode
) {
236 /*********************************************************************
237 * This function builds a uniqued, in-order list of modules that need
238 * to be loaded in order for kmod_name to be successfully loaded. This
239 * list ends with kmod_name itself.
240 *********************************************************************/
242 OSArray
* getDependencyListForKmod(const char * kmod_name
) {
246 OSDictionary
* extensionsDict
; // don't release
247 OSDictionary
* extDict
; // don't release
248 OSDictionary
* extPlist
; // don't release
249 OSString
* extName
; // don't release
250 OSArray
* dependencyList
= NULL
; // return value, caller releases
253 /* These are used to remove duplicates from the dependency list.
255 OSArray
* originalList
= NULL
; // must be released
256 OSDictionary
* encounteredNames
= NULL
; // must be release
259 /* Get the dictionary of startup extensions.
260 * This is keyed by module name.
262 extensionsDict
= getStartupExtensions();
263 if (!extensionsDict
) {
264 IOLog("getDependencyListForKmod(): No extensions dictionary.\n");
271 /* Get the requested extension's dictionary entry and its property
272 * list, containing module dependencies.
274 extDict
= OSDynamicCast(OSDictionary
,
275 extensionsDict
->getObject(kmod_name
));
278 IOLog("getDependencyListForKmod(): "
279 "Extension \"%s\" cannot be found.\n",
286 extPlist
= OSDynamicCast(OSDictionary
, extDict
->getObject("plist"));
288 IOLog("getDependencyListForKmod(): "
289 "Extension \"%s\" has no property list.\n",
297 /* Verify that the retrieved entry's "CFBundleIdentifier" property exists.
298 * This will be added to the dependency list.
300 extName
= OSDynamicCast(OSString
,
301 extPlist
->getObject("CFBundleIdentifier"));
303 IOLog("getDependencyListForKmod(): "
304 "Extension \"%s\" has no \"CFBundleIdentifier\" property.\n",
311 dependencyList
= OSArray::withCapacity(10);
312 if (!dependencyList
) {
313 IOLog("getDependencyListForKmod(): "
314 "Couldn't allocate dependency array for extension \"%s\".\n",
322 /* Okay, let's get started.
324 dependencyList
->setObject(extName
);
327 /* Here's a slightly tricky bit. This loop iterates through
328 * the dependency list until it runs off the end. Each time
329 * through, however, any number of dependencies can be added
330 * to the end of the list. Eventually some extensions won't
331 * have any more dependencies, no more names will be added
332 * to the list, and this loop will terminate.
334 for (i
= 0; i
< dependencyList
->getCount(); i
++) {
336 // None of these needs to be released, as they're all from plists.
338 OSDictionary
* curExtDict
;
339 OSDictionary
* curExtDepDict
;
340 OSDictionary
* curExtPlist
;
341 OSString
* curDepName
;
344 /* An arbitrary limit to prevent infinite loops.
347 IOLog("getDependencyListForKmod(): "
348 "max dependency list length exceeded for "
349 "extension \"%s\".\n",
356 curName
= OSDynamicCast(OSString
, dependencyList
->getObject(i
));
358 curExtDict
= OSDynamicCast(OSDictionary
,
359 extensionsDict
->getObject(curName
));
361 IOLog("getDependencyListForKmod(): "
362 "Extension \"%s\", required for extension \"%s\", "
363 "is not available.\n",
364 curName
->getCStringNoCopy(), kmod_name
);
370 curExtPlist
= OSDynamicCast(OSDictionary
,
371 curExtDict
->getObject("plist"));
373 IOLog("getDependencyListForKmod(): "
374 "Extension \"%s\", required for extension \"%s\", "
375 "has no property list.\n",
376 curName
->getCStringNoCopy(), kmod_name
);
382 curExtDepDict
= OSDynamicCast(OSDictionary
,
383 curExtPlist
->getObject("OSBundleLibraries"));
385 OSCollectionIterator
* keyIterator
=
386 OSCollectionIterator::withCollection(curExtDepDict
);
389 IOLog("getDependencyListForKmod(): "
390 "Couldn't allocate iterator for extension "
391 "\"%s\".\n", kmod_name
);
396 while ( (curDepName
=
397 OSDynamicCast(OSString
,
398 keyIterator
->getNextObject())) ) {
400 OSString
* requiredVersion
= OSDynamicCast(OSString
,
401 curExtDepDict
->getObject(curDepName
));
403 if (!verifyCompatibility(curDepName
, requiredVersion
)) {
404 IOLog("getDependencyListForKmod(): "
405 "Dependency %s of %s is not compatible or is unavailable.\n",
406 curDepName
->getCStringNoCopy(),
407 curName
->getCStringNoCopy());
413 dependencyList
->setObject(curDepName
);
416 keyIterator
->release();
422 * The dependency list now exists in the reverse order of required loads,
423 * and may have duplicates. Now we turn the list around and remove
426 originalList
= dependencyList
;
427 dependencyList
= OSArray::withCapacity(originalList
->getCount());
428 if (!dependencyList
) {
429 IOLog("getDependenciesForKmod(): "
430 "Couldn't allocate reversal dependency list for extension "
431 "\"%s\".\n", kmod_name
);
436 encounteredNames
= OSDictionary::withCapacity(originalList
->getCount());
437 if (!encounteredNames
) {
438 IOLog("getDependenciesForKmod(): "
439 "Couldn't allocate list of encountered names for extension "
440 "\"%s\".\n", kmod_name
);
447 /* Go backward through the original list, using the encounteredNames
448 * dictionary to check for duplicates. We put originalList in as the
449 * value because we need some non-NULL value. Here we also drop any
450 * extensions that aren't proper dependencies (that is, any that are
451 * nonkernel kexts without code).
453 i
= originalList
->getCount();
459 OSString
* item
= OSDynamicCast(OSString
,
460 originalList
->getObject(i
));
462 if ( (!encounteredNames
->getObject(item
)) &&
463 kextIsADependency(item
)) {
465 encounteredNames
->setObject(item
, originalList
);
466 dependencyList
->setObject(item
);
475 originalList
->release();
477 if (encounteredNames
) {
478 encounteredNames
->release();
481 if (dependencyList
) {
482 dependencyList
->release();
483 dependencyList
= NULL
;
487 return dependencyList
;
491 /*********************************************************************
492 *********************************************************************/
493 /* Used in address_for_loaded_kmod.
495 static kmod_info_t
* g_current_kmod_info
= NULL
;
496 static const char * g_current_kmod_name
= NULL
;
498 /* Globals to pass link buffer info from
499 * address_for_loaded_kmod() and alloc_for_kmod()
502 * link_load_address is the address used to lay
503 * down the linked code. It gets adjusted by the
504 * pad between the headers size and a full page
505 * multiple. If an error occurs this gets set to
506 * zero so that the kld client code can detect
507 * an address or allocation error even if kld
510 * link_load_size is the size of the image as
511 * created by kld_load_from_memory(). link_buffer_size
512 * is the size of the buffer allocated for the final
513 * laid-down image, and is adjusted by rounding the
514 * load size and header size up to full-page multiples.
516 * link_buffer_address is set only by alloc_for_kmod();
517 * its value is used as a check if kld_load_from_memory()
518 * fails so that the buffer can be deallocated.
520 static unsigned long link_load_address
= 0;
521 static unsigned long link_load_size
= 0;
522 static unsigned long link_buffer_size
= 0;
523 static unsigned long link_header_size
= 0;
524 static unsigned long link_buffer_address
= 0;
527 /*********************************************************************
528 * This function is registered before kmod_load_from_memory() is
529 * invoked to build symbol table entries for an already-loaded
530 * kmod. This function just checks the g_current_kmod_info variable
531 * to gets its load address, and futzes it by the header offset (pad).
532 * See lower comments for more info on load address futzing.
533 *********************************************************************/
535 unsigned long address_for_loaded_kmod(
537 unsigned long headers_size
) {
539 unsigned long round_headers_size
;
540 unsigned long headers_pad
;
542 if (!g_current_kmod_info
) {
543 IOLog("address_for_loaded_kmod(): No current kmod.\n");
545 link_load_address
= 0; // error sentinel for kld client
549 round_headers_size
= round_page_32(headers_size
);
550 headers_pad
= round_headers_size
- headers_size
;
552 link_load_address
= (unsigned long)g_current_kmod_info
->address
+
555 return link_load_address
;
559 /*********************************************************************
560 * This function is registered before kmod_load_from_memory() is
561 * invoked to actually load a new kmod. It rounds up the header and
562 * total sizes and vm_allocates a buffer for the kmod. Now, KLD doesn't
563 * enforce any alignment of headers or segments, and we want to make
564 * sure that the executable code of the kmod lies on a page boundary.
565 * to do so, this function figures the pad between the actual header
566 * size and the page-rounded header size, and returns that offset into
567 * the allocated buffer. After kmod_load_from_memory() returns, its
568 * caller will move the mach_header struct back to the beginning of the
569 * allocated buffer so that the kmod_info_t structure contains the
571 *********************************************************************/
573 unsigned long alloc_for_kmod(
575 unsigned long headers_size
) {
577 vm_address_t buffer
= 0;
578 kern_return_t k_result
;
580 unsigned long round_headers_size
;
581 unsigned long round_segments_size
;
582 unsigned long round_size
;
583 unsigned long headers_pad
;
585 round_headers_size
= round_page_32(headers_size
);
586 round_segments_size
= round_page_32(size
- headers_size
);
587 round_size
= round_headers_size
+ round_segments_size
;
588 headers_pad
= round_headers_size
- headers_size
;
590 k_result
= vm_allocate(kernel_map
, (vm_offset_t
*)&buffer
,
591 round_size
, VM_FLAGS_ANYWHERE
);
592 if (k_result
!= KERN_SUCCESS
) {
593 IOLog("alloc_for_kmod(): Can't allocate memory.\n");
595 link_buffer_address
= 0; // make sure it's clear
596 link_load_address
= 0; // error sentinel for kld client
600 link_load_size
= size
;
602 link_buffer_address
= buffer
;
603 link_buffer_size
= round_size
;
604 link_header_size
= headers_size
; // NOT rounded!
606 link_load_address
= link_buffer_address
+ headers_pad
;
608 return link_load_address
;
611 /*********************************************************************
612 * This function reads the startup extensions dictionary to get the
613 * address and length of the executable data for the requested kmod.
614 *********************************************************************/
616 int map_and_patch(const char * kmod_name
) {
620 // Does the kld system already know about this kmod?
621 address
= (char *) kld_file_getaddr(kmod_name
, NULL
);
625 // None of these needs to be released.
626 OSDictionary
* extensionsDict
;
627 OSDictionary
* kmodDict
;
628 OSData
* compressedCode
= 0;
630 // Driver Code may need to be released
633 /* Get the requested kmod's info dictionary from the global
634 * startup extensions dictionary.
636 extensionsDict
= getStartupExtensions();
637 if (!extensionsDict
) {
638 IOLog("map_and_patch(): No extensions dictionary.\n");
643 kmodDict
= OSDynamicCast(OSDictionary
,
644 extensionsDict
->getObject(kmod_name
));
646 IOLog("map_and_patch(): "
647 "Extension \"%s\" cannot be found.\n", kmod_name
);
654 driverCode
= OSDynamicCast(OSData
, kmodDict
->getObject("code"));
656 ret
= kld_file_map(kmod_name
,
657 (unsigned char *) driverCode
->getBytesNoCopy(),
658 (size_t) driverCode
->getLength(),
661 else { // May be an compressed extension
663 // If we have a compressed segment the uncompressModule
664 // will return a new OSData object that points to the kmem_alloced
665 // memory. Note we don't take a reference to driverCode so later
666 // when we release it we will actually free this driver. Ownership
667 // of the kmem has been handed of to kld_file.
668 compressedCode
= OSDynamicCast(OSData
,
669 kmodDict
->getObject("compressedCode"));
670 if (!compressedCode
) {
671 IOLog("map_and_patch(): "
672 "Extension \"%s\" has no \"code\" property.\n", kmod_name
);
676 if (!uncompressModule(compressedCode
, &driverCode
)) {
677 IOLog("map_and_patch(): "
678 "Extension \"%s\" Couldn't uncompress code.\n", kmod_name
);
683 unsigned char *driver
= (unsigned char *) driverCode
->getBytesNoCopy();
684 size_t driverSize
= driverCode
->getLength();
686 ret
= kld_file_map(kmod_name
, driver
, driverSize
, /* isKmem */ true);
687 driverCode
->release();
689 kmem_free(kernel_map
, (vm_address_t
) driver
, driverSize
);
693 IOLog("map_and_patch(): "
694 "Extension \"%s\" Didn't successfully load.\n", kmod_name
);
700 if (!kld_file_patch_OSObjects(kmod_name
)) {
701 IOLog("map_and_patch(): "
702 "Extension \"%s\" Error binding OSObjects.\n", kmod_name
);
705 // RY: Instead of returning here, set the return value.
706 // We still need to call kld_file_prepare_for_link because
707 // we might have patched files outside of the driver. Don't
708 // worry, it will know to ignore the damaged file
712 // Now repair any damage that the kld patcher may have done to the image
713 kld_file_prepare_for_link();
718 /*********************************************************************
719 *********************************************************************/
720 bool stamp_kmod(const char * kmod_name
, kmod_info_t
* kmod_info
) {
722 OSDictionary
* extensionsDict
= NULL
; // don't release
723 OSDictionary
* kmodDict
= NULL
; // don't release
724 OSDictionary
* plist
= NULL
; // don't release
725 OSString
* versionString
= NULL
; // don't release
726 const char * plist_version
= NULL
; // don't free
728 if (strlen(kmod_name
) + 1 > KMOD_MAX_NAME
) {
729 IOLog("stamp_kmod(): Kext identifier \"%s\" is too long.\n",
736 strcpy(kmod_info
->name
, kmod_name
);
738 /* Get the dictionary of startup extensions.
739 * This is keyed by module name.
741 extensionsDict
= getStartupExtensions();
742 if (!extensionsDict
) {
743 IOLog("stamp_kmod(): No extensions dictionary.\n");
749 kmodDict
= OSDynamicCast(OSDictionary
,
750 extensionsDict
->getObject(kmod_name
));
752 IOLog("stamp_kmod(): Can't find record for kmod \"%s\".\n",
759 plist
= OSDynamicCast(OSDictionary
,
760 kmodDict
->getObject("plist"));
762 IOLog("stamp_kmod(): Kmod \"%s\" has no property list.\n",
770 * Get the kext's version and stuff it into the kmod. This used
771 * to be a check that the kext & kmod had the same version, but
772 * now we just overwrite the kmod's version.
775 versionString
= OSDynamicCast(OSString
,
776 plist
->getObject("CFBundleVersion"));
777 if (!versionString
) {
778 IOLog("stamp_kmod(): Kmod \"%s\" has no \"CFBundleVersion\" "
786 plist_version
= versionString
->getCStringNoCopy();
787 if (!plist_version
) {
788 IOLog("stamp_kmod(): Can't get C string for kext version.\n");
794 if (strlen(plist_version
) + 1 > KMOD_MAX_NAME
) {
795 IOLog("stamp_kmod(): Version \"%s\" of kext \"%s\" is too long.\n",
796 plist_version
, kmod_name
);
802 strcpy(kmod_info
->version
, plist_version
);
812 /*********************************************************************
813 * This function takes a dependency list containing a series of
814 * already-loaded module names, followed by a single name for a module
815 * that hasn't yet been loaded. It invokes kld_load_from_memory() to
816 * build symbol info for the already-loaded modules, and then finally
817 * loads the actually requested module.
818 *********************************************************************/
820 kern_return_t
load_kmod(OSArray
* dependencyList
) {
821 kern_return_t result
= KERN_SUCCESS
;
823 unsigned int num_dependencies
= 0;
824 kmod_info_t
** kmod_dependencies
= NULL
;
826 OSString
* requestedKmodName
; // don't release
827 const char * requested_kmod_name
;
828 OSString
* currentKmodName
; // don't release
830 unsigned long kmod_size
;
831 struct mach_header
* kmod_header
;
832 unsigned long kld_result
;
833 int do_kld_unload
= 0;
834 kmod_info_t
* kmod_info_freeme
= 0;
835 kmod_info_t
* kmod_info
= 0;
839 /* Separate the requested kmod from its dependencies.
841 i
= dependencyList
->getCount();
843 IOLog("load_kmod(): Called with empty list.\n");
845 result
= KERN_FAILURE
;
848 i
--; // make i be the index of the last entry
851 requestedKmodName
= OSDynamicCast(OSString
, dependencyList
->getObject(i
));
852 if (!requestedKmodName
) {
853 IOLog("load_kmod(): Called with invalid list of kmod names.\n");
855 result
= KERN_FAILURE
;
858 requested_kmod_name
= requestedKmodName
->getCStringNoCopy();
859 dependencyList
->removeObject(i
);
861 /* If the requested kmod is already loaded, there's no work to do.
863 kmod_info_freeme
= kmod_lookupbyname_locked(requested_kmod_name
);
864 if (kmod_info_freeme
) {
865 // FIXME: Need to check for version mismatch if already loaded.
866 result
= KERN_SUCCESS
;
871 /* Do the KLD loads for the already-loaded modules in order to get
874 kld_address_func(&address_for_loaded_kmod
);
876 num_dependencies
= dependencyList
->getCount();
877 kmod_dependencies
= (kmod_info_t
**)kalloc(num_dependencies
*
878 sizeof(kmod_info_t
*));
879 if (!kmod_dependencies
) {
880 IOLog("load_kmod(): Failed to allocate memory for dependency array "
881 "during load of kmod \"%s\".\n", requested_kmod_name
);
883 result
= KERN_FAILURE
;
887 bzero(kmod_dependencies
, num_dependencies
*
888 sizeof(kmod_info_t
*));
890 for (i
= 0; i
< num_dependencies
; i
++) {
892 currentKmodName
= OSDynamicCast(OSString
,
893 dependencyList
->getObject(i
));
895 if (!currentKmodName
) {
896 IOLog("load_kmod(): Invalid dependency name at index %d for "
897 "kmod \"%s\".\n", i
, requested_kmod_name
);
899 result
= KERN_FAILURE
;
903 const char * current_kmod_name
= currentKmodName
->getCStringNoCopy();
905 // These globals are needed by the kld_address functions
906 g_current_kmod_info
= kmod_lookupbyname_locked(current_kmod_name
);
907 g_current_kmod_name
= current_kmod_name
;
909 if (!g_current_kmod_info
) {
910 IOLog("load_kmod(): Missing dependency \"%s\".\n",
913 result
= KERN_FAILURE
;
917 /* Record the current kmod as a dependency of the requested
918 * one. This will be used in building references after the
921 kmod_dependencies
[i
] = g_current_kmod_info
;
923 /* If the current kmod's size is zero it means that we have a
924 * fake in-kernel dependency. If so then don't have to arrange
925 * for its symbol table to be reloaded as it is
926 * part of the kernel's symbol table..
928 if (!g_current_kmod_info
->size
)
931 if (!kld_file_merge_OSObjects(current_kmod_name
)) {
932 IOLog("load_kmod(): Can't merge OSObjects \"%s\".\n",
935 result
= KERN_FAILURE
;
939 kmod_address
= (char *)
940 kld_file_getaddr(current_kmod_name
, (long *) &kmod_size
);
943 IOLog("load_kmod() failed for dependency kmod "
944 "\"%s\".\n", current_kmod_name
);
946 result
= KERN_FAILURE
;
950 kld_result
= kld_load_from_memory(&kmod_header
,
951 current_kmod_name
, kmod_address
, kmod_size
);
957 if (!kld_result
|| !link_load_address
) {
958 IOLog("kld_load_from_memory() failed for dependency kmod "
959 "\"%s\".\n", current_kmod_name
);
961 result
= KERN_FAILURE
;
965 kld_forget_symbol("_kmod_info");
969 * Now that we've done all the dependencies, which should have already
970 * been loaded, we do the last requested module, which should not have
971 * already been loaded.
973 kld_address_func(&alloc_for_kmod
);
975 g_current_kmod_name
= requested_kmod_name
;
976 g_current_kmod_info
= 0; // there is no kmod yet
978 if (!map_and_patch(requested_kmod_name
)) {
979 IOLog("load_kmod: map_and_patch() failed for "
980 "kmod \"%s\".\n", requested_kmod_name
);
982 result
= KERN_FAILURE
;
986 kmod_address
= (char *)
987 kld_file_getaddr(requested_kmod_name
, (long *) &kmod_size
);
989 IOLog("load_kmod: kld_file_getaddr() failed internal error "
990 "on \"%s\".\n", requested_kmod_name
);
992 result
= KERN_FAILURE
;
996 kld_result
= kld_load_from_memory(&kmod_header
,
997 requested_kmod_name
, kmod_address
, kmod_size
);
1003 if (!kld_result
|| !link_load_address
) {
1004 IOLog("load_kmod(): kld_load_from_memory() failed for "
1005 "kmod \"%s\".\n", requested_kmod_name
);
1007 result
= KERN_FAILURE
;
1012 /* Copy the linked header and image into the vm_allocated buffer.
1013 * Move each onto the appropriate page-aligned boundary as given
1014 * by the global link_... variables.
1016 bzero((char *)link_buffer_address
, link_buffer_size
);
1017 // bcopy() is (from, to, length)
1018 bcopy((char *)kmod_header
, (char *)link_buffer_address
, link_header_size
);
1019 bcopy((char *)kmod_header
+ link_header_size
,
1020 (char *)link_buffer_address
+ round_page_32(link_header_size
),
1021 link_load_size
- link_header_size
);
1024 /* Get the kmod_info struct for the newly-loaded kmod.
1026 if (!kld_lookup("_kmod_info", (unsigned long *)&kmod_info
)) {
1027 IOLog("kld_lookup() of \"_kmod_info\" failed for "
1028 "kmod \"%s\".\n", requested_kmod_name
);
1030 result
= KERN_FAILURE
;
1035 if (!stamp_kmod(requested_kmod_name
, kmod_info
)) {
1036 // stamp_kmod() logs a meaningful message
1037 result
= KERN_FAILURE
;
1042 /* kld_lookup of _kmod_info yielded the actual linked address,
1043 * so now that we've copied the data into its real place,
1044 * we can set this stuff.
1046 kmod_info
->address
= link_buffer_address
;
1047 kmod_info
->size
= link_buffer_size
;
1048 kmod_info
->hdr_size
= round_page_32(link_header_size
);
1050 /* We've written data and instructions, so *flush* the data cache
1051 * and *invalidate* the instruction cache.
1053 flush_dcache64((addr64_t
)link_buffer_address
, link_buffer_size
, false);
1054 invalidate_icache64((addr64_t
)link_buffer_address
, link_buffer_size
, false);
1057 /* Register the new kmod with the kernel proper.
1059 if (kmod_create_internal(kmod_info
, &kmod_id
) != KERN_SUCCESS
) {
1060 IOLog("load_kmod(): kmod_create() failed for "
1061 "kmod \"%s\".\n", requested_kmod_name
);
1063 result
= KERN_FAILURE
;
1068 IOLog("kmod id %d successfully created at 0x%lx, size %ld.\n",
1069 (unsigned int)kmod_id
, link_buffer_address
, link_buffer_size
);
1073 /* Record dependencies for the newly-loaded kmod.
1075 for (i
= 0; i
< num_dependencies
; i
++) {
1076 kmod_info_t
* cur_dependency_info
;
1078 cur_dependency_info
= kmod_dependencies
[i
];
1079 packed_id
= KMOD_PACK_IDS(kmod_id
, cur_dependency_info
->id
);
1080 if (kmod_retain(packed_id
) != KERN_SUCCESS
) {
1081 IOLog("load_kmod(): kmod_retain() failed for "
1082 "kmod \"%s\".\n", requested_kmod_name
);
1084 kmod_destroy_internal(kmod_id
);
1085 result
= KERN_FAILURE
;
1090 /* Start the kmod (which invokes constructors for I/O Kit
1093 // kmod_start_or_stop(id, start?, user data, datalen)
1094 if (kmod_start_or_stop(kmod_id
, 1, 0, 0) != KERN_SUCCESS
) {
1095 IOLog("load_kmod(): kmod_start_or_stop() failed for "
1096 "kmod \"%s\".\n", requested_kmod_name
);
1098 kmod_destroy_internal(kmod_id
);
1099 result
= KERN_FAILURE
;
1105 if (kmod_info_freeme
) {
1106 kfree((unsigned int)kmod_info_freeme
, sizeof(kmod_info_t
));
1109 /* Only do a kld_unload_all() if at least one load happened.
1111 if (do_kld_unload
) {
1112 kld_unload_all(/* deallocate sets */ 1);
1115 /* If the link failed, blow away the allocated link buffer.
1117 if (result
!= KERN_SUCCESS
&& link_buffer_address
) {
1118 vm_deallocate(kernel_map
, link_buffer_address
, link_buffer_size
);
1121 if (kmod_dependencies
) {
1122 for (i
= 0; i
< num_dependencies
; i
++) {
1123 if (kmod_dependencies
[i
]) {
1124 kfree((unsigned int)kmod_dependencies
[i
], sizeof(kmod_info_t
));
1127 kfree((unsigned int)kmod_dependencies
,
1128 num_dependencies
* sizeof(kmod_info_t
*));
1131 /* Reset these static global variables for the next call.
1133 g_current_kmod_name
= NULL
;
1134 g_current_kmod_info
= NULL
;
1135 link_buffer_address
= 0;
1136 link_load_address
= 0;
1138 link_buffer_size
= 0;
1139 link_header_size
= 0;
1145 /*********************************************************************
1146 * This is the function that IOCatalogue calls in order to load a kmod.
1147 * It first checks whether the kmod is already loaded. If the kmod
1148 * isn't loaded, this function builds a dependency list and calls
1149 * load_kmod() repeatedly to guarantee that each dependency is in fact
1151 *********************************************************************/
1153 kern_return_t
load_kernel_extension(char * kmod_name
) {
1154 kern_return_t result
= KERN_SUCCESS
;
1155 kmod_info_t
* kmod_info
= 0; // must free
1156 OSArray
* dependencyList
= NULL
; // must release
1157 OSArray
* curDependencyList
= NULL
; // must release
1159 /* See if the kmod is already loaded.
1161 kmod_info
= kmod_lookupbyname_locked(kmod_name
);
1162 if (kmod_info
) { // NOT checked
1163 result
= KERN_SUCCESS
;
1167 /* It isn't loaded; build a dependency list and
1172 dependencyList
= getDependencyListForKmod(kmod_name
);
1173 if (!dependencyList
) {
1174 IOLog("load_kernel_extension(): "
1175 "Can't get dependencies for kernel extension \"%s\".\n",
1178 result
= KERN_FAILURE
;
1182 count
= dependencyList
->getCount();
1183 for (i
= 0; i
< count
; i
++) {
1184 kern_return_t load_result
;
1185 OSString
* curKmodName
; // don't release
1186 const char * cur_kmod_name
;
1188 curKmodName
= OSDynamicCast(OSString
,
1189 dependencyList
->getObject(i
));
1190 cur_kmod_name
= curKmodName
->getCStringNoCopy();
1191 curDependencyList
= getDependencyListForKmod(cur_kmod_name
);
1192 if (!curDependencyList
) {
1193 IOLog("load_kernel_extension(): "
1194 "Can't get dependencies for kernel extension \"%s\".\n",
1197 result
= KERN_FAILURE
;
1200 load_result
= load_kmod(curDependencyList
);
1201 if (load_result
!= KERN_SUCCESS
) {
1202 IOLog("load_kernel_extension(): "
1203 "load_kmod() failed for kmod \"%s\".\n",
1206 result
= load_result
;
1209 curDependencyList
->release();
1210 curDependencyList
= NULL
;
1218 kfree((unsigned int)kmod_info
, sizeof(kmod_info_t
));
1221 if (dependencyList
) {
1222 dependencyList
->release();
1223 dependencyList
= NULL
;
1225 if (curDependencyList
) {
1226 curDependencyList
->release();
1227 curDependencyList
= NULL
;