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
;