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>
42 extern load_return_t
fatfile_getarch(
43 void * vp
, // normally a (struct vnode *)
45 struct fat_arch
* archret
);
53 kmod_destroy_internal(kmod_t id
);
60 mach_msg_type_number_t
*dataCount
);
62 extern kern_return_t
kmod_retain(kmod_t id
);
63 extern kern_return_t
kmod_release(kmod_t id
);
65 extern void flush_dcache(vm_offset_t addr
, unsigned cnt
, int phys
);
66 extern void invalidate_icache(vm_offset_t addr
, unsigned cnt
, int phys
);
75 #define VTYELLOW "\033[33m"
76 #define VTRESET "\033[0m"
79 /*********************************************************************
80 * This function builds a uniqued, in-order list of modules that need
81 * to be loaded in order for kmod_name to be successfully loaded. This
82 * list ends with kmod_name itself.
83 *********************************************************************/
85 OSArray
* getDependencyListForKmod(char * kmod_name
) {
89 OSDictionary
* extensionsDict
; // don't release
90 OSDictionary
* extDict
; // don't release
91 OSDictionary
* extPlist
; // don't release
92 OSString
* extName
; // don't release
93 OSArray
* dependencyList
= NULL
; // return value, caller releases
96 /* These are used to remove duplicates from the dependency list.
98 OSArray
* originalList
= NULL
; // must be released
99 OSDictionary
* encounteredNames
= NULL
; // must be release
102 /* Get the dictionary of startup extensions.
103 * This is keyed by module name.
105 extensionsDict
= getStartupExtensions();
106 if (!extensionsDict
) {
107 IOLog("getDependencyListForKmod(): No extensions dictionary.\n");
114 /* Get the requested extension's dictionary entry and its property
115 * list, containing module dependencies.
117 extDict
= OSDynamicCast(OSDictionary
,
118 extensionsDict
->getObject(kmod_name
));
121 IOLog("getDependencyListForKmod(): "
122 "Extension \"%s\" cannot be found.\n",
129 extPlist
= OSDynamicCast(OSDictionary
, extDict
->getObject("plist"));
131 IOLog("getDependencyListForKmod(): "
132 "Extension \"%s\" has no property list.\n",
140 /* Verify that the retrieved entry's "CFBundleIdentifier" property exists.
141 * This will be added to the dependency list.
143 extName
= OSDynamicCast(OSString
,
144 extPlist
->getObject("CFBundleIdentifier"));
146 IOLog("getDependencyListForKmod(): "
147 "Extension \"%s\" has no \"CFBundleIdentifier\" property.\n",
154 dependencyList
= OSArray::withCapacity(10);
155 if (!dependencyList
) {
156 IOLog("getDependencyListForKmod(): "
157 "Couldn't allocate dependency array for extension \"%s\".\n",
164 dependencyList
->setObject(extName
);
167 /* Here's a slightly tricky bit. This loop iterates through
168 * the dependency list until it runs off the end. Each time
169 * through, however, any number of dependencies can be added
170 * to the end of the list. Eventually some extensions won't
171 * have any more dependencies, no more names will be added
172 * to the list, and this loop will terminate.
174 for (i
= 0; i
< dependencyList
->getCount(); i
++) {
176 // None of these needs to be released, as they're all from plists.
178 OSDictionary
* curExtDict
;
179 OSDictionary
* curExtDepDict
;
180 OSDictionary
* curExtPlist
;
181 OSString
* curDepName
;
184 /* An arbitrary limit to prevent infinite loops.
187 IOLog("getDependencyListForKmod(): "
188 "max dependency list length exceeded for "
189 "extension \"%s\".\n",
196 curName
= OSDynamicCast(OSString
, dependencyList
->getObject(i
));
198 curExtDict
= OSDynamicCast(OSDictionary
,
199 extensionsDict
->getObject(curName
));
201 IOLog("getDependencyListForKmod(): "
202 "Extension \"%s\", required for extension \"%s\", "
203 "is not available.\n",
204 curName
->getCStringNoCopy(), kmod_name
);
210 curExtPlist
= OSDynamicCast(OSDictionary
,
211 curExtDict
->getObject("plist"));
213 IOLog("getDependencyListForKmod(): "
214 "Extension \"%s\", required for extension \"%s\", "
215 "has no property list.\n",
216 curName
->getCStringNoCopy(), kmod_name
);
222 curExtDepDict
= OSDynamicCast(OSDictionary
,
223 curExtPlist
->getObject("OSBundleLibraries"));
225 OSCollectionIterator
* keyIterator
=
226 OSCollectionIterator::withCollection(curExtDepDict
);
229 IOLog("getDependencyListForKmod(): "
230 "Couldn't allocate iterator for extension "
231 "\"%s\".\n", kmod_name
);
236 while ( (curDepName
=
237 OSDynamicCast(OSString
,
238 keyIterator
->getNextObject())) ) {
240 dependencyList
->setObject(curDepName
);
243 keyIterator
->release();
249 * The dependency list now exists in the reverse order of required loads,
250 * and may have duplicates. Now we turn the list around and remove
253 originalList
= dependencyList
;
254 dependencyList
= OSArray::withCapacity(originalList
->getCount());
255 if (!dependencyList
) {
256 IOLog("getDependenciesForKmod(): "
257 "Couldn't allocate reversal dependency list for extension "
258 "\"%s\".\n", kmod_name
);
263 encounteredNames
= OSDictionary::withCapacity(originalList
->getCount());
264 if (!encounteredNames
) {
265 IOLog("getDependenciesForKmod(): "
266 "Couldn't allocate list of encountered names for extension "
267 "\"%s\".\n", kmod_name
);
274 /* Go backward through the original list, using the encounteredNames
275 * dictionary to check for duplicates. We put originalList in as the
276 * value because we need some non-NULL value.
278 i
= originalList
->getCount();
284 OSString
* item
= OSDynamicCast(OSString
,
285 originalList
->getObject(i
));
287 if ( ! encounteredNames
->getObject(item
) ) {
288 encounteredNames
->setObject(item
, originalList
);
289 dependencyList
->setObject(item
);
299 originalList
->release();
301 if (encounteredNames
) {
302 encounteredNames
->release();
305 if (dependencyList
) {
306 dependencyList
->release();
307 dependencyList
= NULL
;
311 return dependencyList
;
315 /*********************************************************************
316 *********************************************************************/
317 static bool verifyCompatibleVersions(OSArray
* dependencyList
) {
320 OSString
* requestedModuleName
= NULL
;
322 OSDictionary
* extensionsDict
= NULL
;
324 OSString
* curName
= NULL
;
325 OSDictionary
* curExt
= NULL
;
326 OSDictionary
* curExtPlist
= NULL
;
328 OSBoolean
* isKernelResource
= NULL
;
330 OSDictionary
* dependencies
= NULL
;
331 OSCollectionIterator
* dependencyIterator
= NULL
; // must release
332 OSString
* dependencyName
= NULL
;
333 OSString
* curExtDependencyVersion
= NULL
;
334 UInt32 cur_ext_required_dependency_vers
;
336 OSDictionary
* dependency
= NULL
;
337 OSDictionary
* dependencyPlist
= NULL
;
339 OSString
* dependencyVersion
= NULL
;
340 OSString
* dependencyCompatibleVersion
= NULL
;
341 UInt32 dependency_vers
;
342 UInt32 dependency_compat_vers
;
345 /* Get the dictionary of startup extensions.
346 * This is keyed by module name.
348 extensionsDict
= getStartupExtensions();
349 if (!extensionsDict
) {
350 IOLog("verifyCompatibleVersions(): No extensions dictionary.\n");
357 count
= dependencyList
->getCount();
359 IOLog("verifyCompatibleVersions(): "
360 "Invoked with no dependency list.\n");
366 requestedModuleName
= OSDynamicCast(OSString
,
367 dependencyList
->getObject(count
- 1));
369 for (i
= count
- 1; i
>= 0; i
--) {
371 if (dependencyIterator
) {
372 dependencyIterator
->release();
373 dependencyIterator
= NULL
;
376 curName
= OSDynamicCast(OSString
, dependencyList
->getObject(i
));
378 IOLog("verifyCompatibleVersions(): Internal error (1).\n");
384 curExt
= OSDynamicCast(OSDictionary
,
385 extensionsDict
->getObject(curName
));
387 IOLog("verifyCompatibleVersions(): Internal error (2).\n");
393 curExtPlist
= OSDynamicCast(OSDictionary
,
394 curExt
->getObject("plist"));
396 IOLog("verifyCompatibleVersions(): Internal error (3).\n");
403 /* In-kernel extensions don't need to check dependencies.
405 isKernelResource
= OSDynamicCast(OSBoolean
,
406 curExtPlist
->getObject("OSKernelResource"));
407 if (isKernelResource
&& isKernelResource
->isTrue()) {
411 dependencies
= OSDynamicCast(OSDictionary
,
412 curExtPlist
->getObject("OSBundleLibraries"));
413 if (!dependencies
|| dependencies
->getCount() < 1) {
414 IOLog(VTYELLOW
"verifyCompatibleVersions(): Extension \"%s\" "
415 "declares no dependencies.\n" VTRESET
,
416 curName
->getCStringNoCopy());
423 OSCollectionIterator::withCollection(dependencies
);
425 IOLog("verifyCompatibleVersions(): Internal error (4).\n");
431 while ((dependencyName
= OSDynamicCast(OSString
,
432 dependencyIterator
->getNextObject()))) {
434 curExtDependencyVersion
= OSDynamicCast(OSString
,
435 dependencies
->getObject(dependencyName
));
436 if (!curExtDependencyVersion
) {
437 IOLog("verifyCompatibleVersions(): Internal error (5).\n");
443 dependency
= OSDynamicCast(OSDictionary
,
444 extensionsDict
->getObject(dependencyName
));
446 IOLog("verifyCompatibleVersions(): Internal error (6).\n");
452 dependencyPlist
= OSDynamicCast(OSDictionary
,
453 dependency
->getObject("plist"));
454 if (!dependencyPlist
) {
455 IOLog("verifyCompatibleVersions(): Internal error (7).\n");
461 dependencyVersion
= OSDynamicCast(OSString
,
462 dependencyPlist
->getObject("CFBundleVersion"));
463 if (!curExtDependencyVersion
) {
464 IOLog(VTYELLOW
"Dependency extension \"%s\" doesn't declare a "
465 "version.\n" VTRESET
,
466 dependencyName
->getCStringNoCopy());
472 dependencyCompatibleVersion
= OSDynamicCast(OSString
,
473 dependencyPlist
->getObject("OSBundleCompatibleVersion"));
474 if (!dependencyCompatibleVersion
) {
475 IOLog(VTYELLOW
"Dependency extension \"%s\" doesn't declare a "
476 "compatible version.\n" VTRESET
,
477 dependencyName
->getCStringNoCopy());
483 IOLog("\033[33m %s (needs %s, compat-current is %s-%s).\n" VTRESET
,
484 dependencyName
->getCStringNoCopy(),
485 curExtDependencyVersion
->getCStringNoCopy(),
486 dependencyCompatibleVersion
->getCStringNoCopy(),
487 dependencyVersion
->getCStringNoCopy());
490 if (!VERS_parse_string(curExtDependencyVersion
->getCStringNoCopy(),
491 &cur_ext_required_dependency_vers
)) {
493 if (!VERS_parse_string(dependencyVersion
->getCStringNoCopy(),
496 if (!VERS_parse_string(dependencyCompatibleVersion
->getCStringNoCopy(),
497 &dependency_compat_vers
)) {
500 if (cur_ext_required_dependency_vers
> dependency_vers
||
501 cur_ext_required_dependency_vers
< dependency_compat_vers
) {
503 IOLog(VTYELLOW
"Cannot load extension \"%s\": dependencies "
504 "\"%s\" and \"%s\" are not of compatible versions.\n" VTRESET
,
505 requestedModuleName
->getCStringNoCopy(),
506 curName
->getCStringNoCopy(),
507 dependencyName
->getCStringNoCopy());
520 /* Used in address_for_loaded_kmod.
522 static kmod_info_t
* g_current_kmod_info
= NULL
;
523 static const char * g_current_kmod_name
= NULL
;
525 /* Globals to pass link buffer info from
526 * address_for_loaded_kmod() and alloc_for_kmod()
529 * link_load_address is the address used to lay
530 * down the linked code. It gets adjusted by the
531 * pad between the headers size and a full page
532 * multiple. If an error occurs this gets set to
533 * zero so that the kld client code can detect
534 * an address or allocation error even if kld
537 * link_load_size is the size of the image as
538 * created by kld_load_from_memory(). link_buffer_size
539 * is the size of the buffer allocated for the final
540 * laid-down image, and is adjusted by rounding the
541 * load size and header size up to full-page multiples.
543 * link_buffer_address is set only by alloc_for_kmod();
544 * its value is used as a check if kld_load_from_memory()
545 * fails so that the buffer can be deallocated.
547 static unsigned long link_load_address
= 0;
548 static unsigned long link_load_size
= 0;
549 static unsigned long link_buffer_size
= 0;
550 static unsigned long link_header_size
= 0;
551 static unsigned long link_buffer_address
= 0;
554 /*********************************************************************
555 * This function is registered before kmod_load_from_memory() is
556 * invoked to build symbol table entries for an already-loaded
557 * kmod. This function just checks the g_current_kmod_info variable
558 * to gets its load address, and futzes it by the header offset (pad).
559 * See lower comments for more info on load address futzing.
560 *********************************************************************/
562 unsigned long address_for_loaded_kmod(
564 unsigned long headers_size
) {
566 unsigned long round_headers_size
;
567 unsigned long headers_pad
;
569 if (!g_current_kmod_info
) {
570 IOLog("address_for_loaded_kmod(): No current kmod.\n");
572 link_load_address
= 0; // error sentinel for kld client
576 round_headers_size
= round_page(headers_size
);
577 headers_pad
= round_headers_size
- headers_size
;
579 link_load_address
= (unsigned long)g_current_kmod_info
->address
+
582 return link_load_address
;
586 /*********************************************************************
587 * This function is registered before kmod_load_from_memory() is
588 * invoked to actually load a new kmod. It rounds up the header and
589 * total sizes and vm_allocates a buffer for the kmod. Now, KLD doesn't
590 * enforce any alignment of headers or segments, and we want to make
591 * sure that the executable code of the kmod lies on a page boundary.
592 * to do so, this function figures the pad between the actual header
593 * size and the page-rounded header size, and returns that offset into
594 * the allocated buffer. After kmod_load_from_memory() returns, its
595 * caller will move the mach_header struct back to the beginning of the
596 * allocated buffer so that the kmod_info_t structure contains the
598 *********************************************************************/
600 unsigned long alloc_for_kmod(
602 unsigned long headers_size
) {
604 vm_address_t buffer
= 0;
605 kern_return_t k_result
;
607 unsigned long round_headers_size
;
608 unsigned long round_segments_size
;
609 unsigned long round_size
;
610 unsigned long headers_pad
;
612 round_headers_size
= round_page(headers_size
);
613 round_segments_size
= round_page(size
- headers_size
);
614 round_size
= round_headers_size
+ round_segments_size
;
615 headers_pad
= round_headers_size
- headers_size
;
617 k_result
= vm_allocate(kernel_map
, (vm_offset_t
*)&buffer
,
619 if (k_result
!= KERN_SUCCESS
) {
620 IOLog("alloc_for_kmod(): Can't allocate memory.\n");
622 link_buffer_address
= 0; // make sure it's clear
623 link_load_address
= 0; // error sentinel for kld client
627 link_load_size
= size
;
629 link_buffer_address
= buffer
;
630 link_buffer_size
= round_size
;
631 link_header_size
= headers_size
; // NOT rounded!
633 link_load_address
= link_buffer_address
+ headers_pad
;
635 return link_load_address
;
639 /*********************************************************************
640 * This function reads the startup extensions dictionary to get the
641 * address and length of the executable data for the requested kmod.
642 *********************************************************************/
644 int get_text_info_for_kmod(const char * kmod_name
,
645 char ** text_address
,
646 unsigned long * text_size
) {
648 // None of these needs to be released.
649 OSDictionary
* extensionsDict
;
650 OSDictionary
* kmodDict
;
653 vm_offset_t kmod_address
;
655 struct mach_header mach_header
;
656 struct fat_header fat_header
;
657 } kmod_header_composite
;
658 kmod_header_composite
* kmod_headers
;
661 /* Get the requested kmod's info dictionary from the global
662 * startup extensions dictionary.
664 extensionsDict
= getStartupExtensions();
665 if (!extensionsDict
) {
666 IOLog("text_address_for_kmod(): No extensions dictionary.\n");
671 kmodDict
= OSDynamicCast(OSDictionary
,
672 extensionsDict
->getObject(kmod_name
));
674 IOLog("text_address_for_kmod(): "
675 "Extension \"%s\" cannot be found.\n", kmod_name
);
680 driverCode
= OSDynamicCast(OSData
, kmodDict
->getObject("code"));
682 IOLog("text_address_for_kmod(): "
683 "Extension \"%s\" has no \"code\" property.\n",
689 kmod_address
= (vm_offset_t
)driverCode
->getBytesNoCopy();
690 kmod_headers
= (kmod_header_composite
*)kmod_address
;
692 /* Now extract the appropriate code from the executable data.
694 if (kmod_headers
->mach_header
.magic
== MH_MAGIC
) {
696 *text_address
= (char *)kmod_address
;
697 *text_size
= driverCode
->getLength();
700 } else if (kmod_headers
->fat_header
.magic
== FAT_MAGIC
||
701 kmod_headers
->fat_header
.magic
== FAT_CIGAM
) {
702 // CIGAM is byte-swapped MAGIC
704 load_return_t load_return
;
705 struct fat_arch fatinfo
;
707 load_return
= fatfile_getarch(NULL
, kmod_address
, &fatinfo
);
708 if (load_return
!= LOAD_SUCCESS
) {
709 IOLog("text_address_for_kmod(): Extension \"%s\" "
710 "doesn't contain code for this computer.\n", kmod_name
);
715 *text_address
= (char *)(kmod_address
+ fatinfo
.offset
);
716 *text_size
= fatinfo
.size
;
720 IOLog("text_address_for_kmod(): Extension \"%s\" either "
721 "isn't code or doesn't contain code for this computer.\n",
731 /*********************************************************************
732 *********************************************************************/
733 bool verify_kmod(const char * kmod_name
, kmod_info_t
* kmod_info
) {
735 OSDictionary
* extensionsDict
= NULL
; // don't release
736 OSDictionary
* kmodDict
= NULL
; // don't release
737 OSDictionary
* plist
= NULL
; // don't release
738 OSString
* versionString
= NULL
; // don't release
742 if (strncmp(kmod_name
, kmod_info
->name
, sizeof(kmod_info
->name
))) {
743 IOLog("verify_kmod(): kmod loaded as \"%s\" has different "
744 "identifier \"%s\".\n", kmod_name
, kmod_info
->name
);
750 if (!VERS_parse_string(kmod_info
->version
,
753 IOLog(VTYELLOW
"verify_kmod(): kmod \"%s\" has an invalid "
754 "version.\n" VTRESET
, kmod_info
->name
);
761 /* Get the dictionary of startup extensions.
762 * This is keyed by module name.
764 extensionsDict
= getStartupExtensions();
765 if (!extensionsDict
) {
766 IOLog("verify_kmod(): No extensions dictionary.\n");
772 kmodDict
= OSDynamicCast(OSDictionary
,
773 extensionsDict
->getObject(kmod_name
));
775 IOLog("verify_kmod(): Can't find record for kmod \"%s\".\n",
782 plist
= OSDynamicCast(OSDictionary
,
783 extensionsDict
->getObject("plist"));
785 IOLog("verify_kmod(): Kmod \"%s\" has no property list.\n",
792 versionString
= OSDynamicCast(OSString
,
793 extensionsDict
->getObject("CFBundleVersion"));
794 if (!versionString
) {
795 IOLog(VTYELLOW
"verify_kmod(): Kmod \"%s\" has no \"CFBundleVersion\" "
796 "property.\n" VTRESET
,
803 if (!VERS_parse_string(versionString
->getCStringNoCopy(),
806 IOLog(VTYELLOW
"verify_kmod(): Property list for kmod \"%s\" has "
807 "an invalid version.\n" VTRESET
, kmod_info
->name
);
813 if (kmod_vers
!= plist_vers
) {
814 IOLog(VTYELLOW
"verify_kmod(): Kmod \"%s\" and its property list "
815 "claim different versions (%s & %s).\n" VTRESET
,
818 versionString
->getCStringNoCopy());
827 // FIXME: make this really return the result after conversion
834 /*********************************************************************
835 * This function takes a dependency list containing a series of
836 * already-loaded module names, followed by a single name for a module
837 * that hasn't yet been loaded. It invokes kld_load_from_memory() to
838 * build symbol info for the already-loaded modules, and then finally
839 * loads the actually requested module.
840 *********************************************************************/
842 kern_return_t
load_kmod(OSArray
* dependencyList
) {
843 kern_return_t result
= KERN_SUCCESS
;
845 unsigned int num_dependencies
= 0;
846 kmod_info_t
** kmod_dependencies
= NULL
;
848 OSString
* requestedKmodName
; // don't release
849 const char * requested_kmod_name
;
850 OSString
* currentKmodName
; // don't release
852 unsigned long kmod_size
;
853 struct mach_header
* kmod_header
;
854 unsigned long kld_result
;
855 int do_kld_unload
= 0;
856 kmod_info_t
* kmod_info
;
860 /* Separate the requested kmod from its dependencies.
862 i
= dependencyList
->getCount();
864 IOLog("load_kmod(): Called with empty list.\n");
866 result
= KERN_FAILURE
;
869 i
--; // make i be the index of the last entry
872 requestedKmodName
= OSDynamicCast(OSString
, dependencyList
->getObject(i
));
873 if (!requestedKmodName
) {
874 IOLog("load_kmod(): Called with invalid list of kmod names.\n");
876 result
= KERN_FAILURE
;
879 requested_kmod_name
= requestedKmodName
->getCStringNoCopy();
880 dependencyList
->removeObject(i
);
882 /* If the requested kmod is already loaded, there's no work to do.
884 kmod_info
= kmod_lookupbyname(requested_kmod_name
);
886 // FIXME: Need to check for version mismatch if already loaded.
887 result
= KERN_SUCCESS
;
892 /* Do the KLD loads for the already-loaded modules in order to get
895 kld_address_func(&address_for_loaded_kmod
);
897 num_dependencies
= dependencyList
->getCount();
898 kmod_dependencies
= (kmod_info_t
**)kalloc(num_dependencies
*
899 sizeof(kmod_info_t
*));
900 if (!kmod_dependencies
) {
901 IOLog("load_kmod(): Failed to allocate memory for dependency array "
902 "during load of kmod \"%s\".\n", requested_kmod_name
);
904 result
= KERN_FAILURE
;
908 for (i
= 0; i
< num_dependencies
; i
++) {
910 currentKmodName
= OSDynamicCast(OSString
,
911 dependencyList
->getObject(i
));
913 if (!currentKmodName
) {
914 IOLog("load_kmod(): Invalid dependency name at index %d for "
915 "kmod \"%s\".\n", i
, requested_kmod_name
);
917 result
= KERN_FAILURE
;
921 const char * current_kmod_name
= currentKmodName
->getCStringNoCopy();
923 // These globals are needed by the kld_address functions
924 g_current_kmod_info
= kmod_lookupbyname(current_kmod_name
);
925 g_current_kmod_name
= current_kmod_name
;
927 if (!g_current_kmod_info
) {
928 IOLog("load_kmod(): Missing dependency \"%s\".\n",
931 result
= KERN_FAILURE
;
935 /* Record the current kmod as a dependency of the requested
936 * one. This will be used in building references after the
939 kmod_dependencies
[i
] = g_current_kmod_info
;
941 /* If the current kmod's size is zero it means that we have a
942 * fake in-kernel dependency. If so then don't have to arrange
943 * for its symbol table to be reloaded as it is
944 * part of the kernel's symbol table..
946 if (!g_current_kmod_info
->size
)
949 if (!get_text_info_for_kmod(current_kmod_name
,
950 &kmod_address
, &kmod_size
)) {
952 IOLog("get_text_info_for_kmod() failed for dependency kmod "
953 "\"%s\".\n", current_kmod_name
);
955 result
= KERN_FAILURE
;
959 kld_result
= kld_load_from_memory(&kmod_header
,
961 (char *)kmod_address
,
968 if (!kld_result
|| !link_load_address
) {
969 IOLog("kld_load_from_memory() failed for dependency kmod "
970 "\"%s\".\n", current_kmod_name
);
972 result
= KERN_FAILURE
;
976 kld_forget_symbol("_kmod_info");
980 * Now that we've done all the dependencies, which should have already
981 * been loaded, we do the last requested module, which should not have
982 * already been loaded.
984 kld_address_func(&alloc_for_kmod
);
986 g_current_kmod_name
= requested_kmod_name
;
987 g_current_kmod_info
= 0; // there is no kmod yet
989 if (!get_text_info_for_kmod(requested_kmod_name
,
990 &kmod_address
, &kmod_size
)) {
991 IOLog("load_kmod: get_text_info_for_kmod() failed for "
992 "kmod \"%s\".\n", requested_kmod_name
);
994 result
= KERN_FAILURE
;
998 kld_result
= kld_load_from_memory(&kmod_header
,
1000 (char *)kmod_address
,
1007 if (!kld_result
|| !link_load_address
) {
1008 IOLog("load_kmod(): kld_load_from_memory() failed for "
1009 "kmod \"%s\".\n", requested_kmod_name
);
1011 result
= KERN_FAILURE
;
1016 /* Copy the linked header and image into the vm_allocated buffer.
1017 * Move each onto the appropriate page-aligned boundary as given
1018 * by the global link_... variables.
1020 bzero((char *)link_buffer_address
, link_buffer_size
);
1021 // bcopy() is (from, to, length)
1022 bcopy((char *)kmod_header
, (char *)link_buffer_address
, link_header_size
);
1023 bcopy((char *)kmod_header
+ link_header_size
,
1024 (char *)link_buffer_address
+ round_page(link_header_size
),
1025 link_load_size
- link_header_size
);
1028 /* Get the kmod_info struct for the newly-loaded kmod.
1030 if (!kld_lookup("_kmod_info", (unsigned long *)&kmod_info
)) {
1031 IOLog("kld_lookup() of \"_kmod_info\" failed for "
1032 "kmod \"%s\".\n", requested_kmod_name
);
1034 result
= KERN_FAILURE
;
1039 if (!verify_kmod(requested_kmod_name
, kmod_info
)) {
1040 // verify_kmod() logs a meaningful message
1041 result
= KERN_FAILURE
;
1046 /* kld_lookup of _kmod_info yielded the actual linked address,
1047 * so now that we've copied the data into its real place,
1048 * we can set this stuff.
1050 kmod_info
->address
= link_buffer_address
;
1051 kmod_info
->size
= link_buffer_size
;
1052 kmod_info
->hdr_size
= round_page(link_header_size
);
1054 /* We've written data and instructions, so *flush* the data cache
1055 * and *invalidate* the instruction cache.
1057 flush_dcache(link_buffer_address
, link_buffer_size
, false);
1058 invalidate_icache(link_buffer_address
, link_buffer_size
, false);
1061 /* Register the new kmod with the kernel proper.
1063 if (kmod_create_internal(kmod_info
, &kmod_id
) != KERN_SUCCESS
) {
1064 IOLog("load_kmod(): kmod_create() failed for "
1065 "kmod \"%s\".\n", requested_kmod_name
);
1067 result
= KERN_FAILURE
;
1071 IOLog("kmod id %d successfully created at 0x%lx, size %ld.\n",
1072 (unsigned int)kmod_id
, link_buffer_address
, link_buffer_size
);
1075 /* Record dependencies for the newly-loaded kmod.
1077 for (i
= 0; i
< num_dependencies
; i
++) {
1078 kmod_info_t
* cur_dependency_info
;
1080 cur_dependency_info
= kmod_dependencies
[i
];
1081 packed_id
= KMOD_PACK_IDS(kmod_id
, cur_dependency_info
->id
);
1082 if (kmod_retain(packed_id
) != KERN_SUCCESS
) {
1083 IOLog("load_kmod(): kmod_retain() failed for "
1084 "kmod \"%s\".\n", requested_kmod_name
);
1086 kmod_destroy_internal(kmod_id
);
1087 result
= KERN_FAILURE
;
1092 /* Start the kmod (which invokes constructors for I/O Kit
1095 // kmod_start_or_stop(id, start?, user data, datalen)
1096 if (kmod_start_or_stop(kmod_id
, 1, 0, 0) != KERN_SUCCESS
) {
1097 IOLog("load_kmod(): kmod_start_or_stop() failed for "
1098 "kmod \"%s\".\n", requested_kmod_name
);
1100 kmod_destroy_internal(kmod_id
);
1101 result
= KERN_FAILURE
;
1107 /* Only do a kld_unload_all() if at least one load happened.
1109 if (do_kld_unload
) {
1110 kld_unload_all(/* deallocate sets */ 1);
1114 /* If the link failed, blow away the allocated link buffer.
1116 if (result
!= KERN_SUCCESS
&& link_buffer_address
) {
1117 vm_deallocate(kernel_map
, link_buffer_address
, link_buffer_size
);
1120 if (kmod_dependencies
) {
1121 kfree((unsigned int)kmod_dependencies
,
1122 num_dependencies
* sizeof(kmod_info_t
*));
1125 /* Reset these static global variables for the next call.
1127 g_current_kmod_name
= NULL
;
1128 g_current_kmod_info
= NULL
;
1129 link_buffer_address
= 0;
1130 link_load_address
= 0;
1132 link_buffer_size
= 0;
1133 link_header_size
= 0;
1139 /*********************************************************************
1140 * This is the function that IOCatalogue calls in order to load a kmod.
1141 * It first checks whether the kmod is already loaded. If the kmod
1142 * isn't loaded, this function builds a dependency list and calls
1143 * load_kmod() repeatedly to guarantee that each dependency is in fact
1145 *********************************************************************/
1147 kern_return_t
load_kernel_extension(char * kmod_name
) {
1148 kern_return_t result
= KERN_SUCCESS
;
1149 kmod_info_t
* kmod_info
;
1150 OSArray
* dependencyList
= NULL
; // must release
1151 OSArray
* curDependencyList
= NULL
; // must release
1154 /* This must be the very first thing done by this function.
1156 IOLockLock(kld_lock
);
1159 /* See if the kmod is already loaded.
1161 kmod_info
= kmod_lookupbyname(kmod_name
);
1162 if (kmod_info
) { // NOT checked
1163 result
= KERN_SUCCESS
;
1167 // FIXME: Need to check whether kmod is built into the kernel!
1169 /* It isn't loaded; build a dependency list and
1174 dependencyList
= getDependencyListForKmod(kmod_name
);
1175 if (!dependencyList
) {
1176 IOLog("load_kernel_extension(): "
1177 "Can't get dependencies for kernel extension \"%s\".\n",
1180 result
= KERN_FAILURE
;
1184 if (!verifyCompatibleVersions(dependencyList
)) {
1185 IOLog(VTYELLOW
"load_kernel_extension(): "
1186 "Version mismatch for kernel extension \"%s\".\n" VTRESET
,
1190 // FIXME: This is currently a warning only; when kexts are updated
1191 // this will become an error.
1192 result
= KERN_FAILURE
;
1195 IOLog(VTYELLOW
"Loading anyway.\n" VTRESET
);
1199 count
= dependencyList
->getCount();
1200 for (i
= 0; i
< count
; i
++) {
1201 kern_return_t load_result
;
1202 OSString
* curKmodName
; // don't release
1203 const char * cur_kmod_name
;
1205 curKmodName
= OSDynamicCast(OSString
,
1206 dependencyList
->getObject(i
));
1207 cur_kmod_name
= curKmodName
->getCStringNoCopy();
1208 curDependencyList
= getDependencyListForKmod(cur_kmod_name
);
1210 load_result
= load_kmod(curDependencyList
);
1211 if (load_result
!= KERN_SUCCESS
) {
1212 IOLog("load_kernel_extension(): "
1213 "load_kmod() failed for kmod \"%s\".\n",
1216 result
= load_result
;
1219 curDependencyList
->release();
1220 curDependencyList
= NULL
;
1226 if (dependencyList
) {
1227 dependencyList
->release();
1228 dependencyList
= NULL
;
1230 if (curDependencyList
) {
1231 curDependencyList
->release();
1232 curDependencyList
= NULL
;
1235 /* This must be the very last thing done before returning.
1237 IOLockUnlock(kld_lock
);