Loading...
libsa/kmod.cpp xnu-792.2.4 xnu-344.2
--- xnu/xnu-792.2.4/libsa/kmod.cpp
+++ xnu/xnu-344.2/libsa/kmod.cpp
@@ -59,8 +59,8 @@
 extern kern_return_t kmod_retain(kmod_t id);
 extern kern_return_t kmod_release(kmod_t id);
 
-extern void flush_dcache64(addr64_t addr, unsigned cnt, int phys);
-extern void invalidate_icache64(addr64_t addr, unsigned cnt, int phys);
+extern void flush_dcache(vm_offset_t addr, unsigned cnt, int phys);
+extern void invalidate_icache(vm_offset_t addr, unsigned cnt, int phys);
 };
 
 
@@ -168,72 +168,6 @@
 }
 
 /*********************************************************************
-*********************************************************************/
-static
-Boolean kextIsADependency(OSString * name) {
-    Boolean result = true;
-    OSDictionary * extensionsDict = 0;    // don't release
-    OSDictionary * extDict = 0;           // don't release
-    OSDictionary * extPlist = 0;          // don't release
-    OSBoolean * isKernelResourceObj = 0;  // don't release
-    OSData * driverCode = 0;              // don't release
-    OSData * compressedCode = 0;          // don't release
-
-    extensionsDict = getStartupExtensions();
-    if (!extensionsDict) {
-        IOLog("kextIsADependency(): No extensions dictionary.\n");
-        LOG_DELAY();
-        result = false;
-        goto finish;
-    }
-    
-
-    extDict = OSDynamicCast(OSDictionary,
-        extensionsDict->getObject(name));
-    if (!extDict) {
-        IOLog("kextIsADependency(): "
-           "Extension \"%s\" cannot be found.\n",
-           name->getCStringNoCopy());
-        LOG_DELAY();
-        result = false;
-        goto finish;
-    }
-
-    extPlist = OSDynamicCast(OSDictionary, extDict->getObject("plist"));
-    if (!extPlist) {
-        IOLog("getDependencyListForKmod(): "
-            "Extension \"%s\" has no property list.\n",
-            name->getCStringNoCopy());
-        LOG_DELAY();
-        result = false;
-        goto finish;
-    }
-
-   /* A kext that is a kernel component is still a dependency, as there
-    * are fake kmod entries for them.
-    */
-    isKernelResourceObj = OSDynamicCast(OSBoolean,
-        extPlist->getObject("OSKernelResource"));
-    if (isKernelResourceObj && isKernelResourceObj->isTrue()) {
-        result = true;
-        goto finish;
-    }
-
-    driverCode = OSDynamicCast(OSData, extDict->getObject("code"));
-    compressedCode = OSDynamicCast(OSData,
-        extDict->getObject("compressedCode"));
-
-    if (!driverCode && !compressedCode) {
-        result = false;
-        goto finish;
-    }
-
-finish:
-
-    return result;
-}
-
-/*********************************************************************
 * This function builds a uniqued, in-order list of modules that need
 * to be loaded in order for kmod_name to be successfully loaded. This
 * list ends with kmod_name itself.
@@ -248,6 +182,9 @@
     OSDictionary * extPlist;       // don't release
     OSString     * extName;        // don't release
     OSArray      * dependencyList = NULL; // return value, caller releases
+    OSBoolean * isKernelResourceObj = 0; // don't release
+    bool isKernelResource = false;
+    bool declaresExecutable = false;
     unsigned int   i;
 
    /* These are used to remove duplicates from the dependency list.
@@ -318,6 +255,27 @@
         goto finish;
     }
 
+   /* A kext that's not a kernel extension and declares no executable has nothing
+    * to load, so just return an empty array.
+    */
+    isKernelResourceObj = OSDynamicCast(OSBoolean,
+        extPlist->getObject("OSKernelResource"));
+    if (isKernelResourceObj && isKernelResourceObj->isTrue()) {
+        isKernelResource = true;
+    } else {
+        isKernelResource = false;
+    }
+
+    if (extPlist->getObject("CFBundleExecutable")) {
+        declaresExecutable = true;
+    } else {
+        declaresExecutable = false;
+    }
+
+    if (!isKernelResource && !declaresExecutable) {
+        error = 0;
+        goto finish;
+    }
 
    /* Okay, let's get started.
     */
@@ -410,6 +368,28 @@
                     goto finish;
                 }
 
+               /* Don't add any entries that are not kernel resources and that declare no
+                * executable. Such kexts have nothing to load and so don't belong in the
+                * dependency list. Entries that are kernel resource *do* get added,
+                * however, because such kexts get fake kmod entries for reference counting.
+                */
+                isKernelResourceObj = OSDynamicCast(OSBoolean,
+                    curExtPlist->getObject("OSKernelResource"));
+                if (isKernelResourceObj && isKernelResourceObj->isTrue()) {
+                    isKernelResource = true;
+                } else {
+                    isKernelResource = false;
+                }
+                if (curExtPlist->getObject("CFBundleExecutable")) {
+                    declaresExecutable = true;
+                } else {
+                    declaresExecutable = false;
+                }
+
+                if (!isKernelResource && !declaresExecutable) {
+                    continue;
+                }
+
                 dependencyList->setObject(curDepName);
             }
 
@@ -446,9 +426,7 @@
 
    /* Go backward through the original list, using the encounteredNames
     * dictionary to check for duplicates. We put originalList in as the
-    * value because we need some non-NULL value. Here we also drop any
-    * extensions that aren't proper dependencies (that is, any that are
-    * nonkernel kexts without code).
+    * value because we need some non-NULL value.
     */
     i = originalList->getCount();
 
@@ -459,9 +437,7 @@
             OSString * item = OSDynamicCast(OSString,
                 originalList->getObject(i));
 
-            if ( (!encounteredNames->getObject(item)) &&
-                 kextIsADependency(item)) {
-
+            if ( ! encounteredNames->getObject(item) ) {
                 encounteredNames->setObject(item, originalList);
                 dependencyList->setObject(item);
             }
@@ -546,7 +522,7 @@
         return 0;
     }
 
-    round_headers_size = round_page_32(headers_size);
+    round_headers_size = round_page(headers_size);
     headers_pad = round_headers_size - headers_size;
 
     link_load_address = (unsigned long)g_current_kmod_info->address +
@@ -582,13 +558,13 @@
     unsigned long round_size;
     unsigned long headers_pad;
 
-    round_headers_size  = round_page_32(headers_size);
-    round_segments_size = round_page_32(size - headers_size);
+    round_headers_size  = round_page(headers_size);
+    round_segments_size = round_page(size - headers_size);
     round_size  = round_headers_size + round_segments_size;
     headers_pad = round_headers_size - headers_size;
 
     k_result = vm_allocate(kernel_map, (vm_offset_t *)&buffer,
-        round_size, VM_FLAGS_ANYWHERE);
+        round_size, TRUE);
     if (k_result != KERN_SUCCESS) {
         IOLog("alloc_for_kmod(): Can't allocate memory.\n");
         LOG_DELAY();
@@ -1017,7 +993,7 @@
     // bcopy() is (from, to, length)
     bcopy((char *)kmod_header, (char *)link_buffer_address, link_header_size);
     bcopy((char *)kmod_header + link_header_size,
-        (char *)link_buffer_address + round_page_32(link_header_size),
+        (char *)link_buffer_address + round_page(link_header_size),
         link_load_size - link_header_size);
 
 
@@ -1045,13 +1021,13 @@
     */
     kmod_info->address = link_buffer_address;
     kmod_info->size = link_buffer_size;
-    kmod_info->hdr_size = round_page_32(link_header_size);
+    kmod_info->hdr_size = round_page(link_header_size);
 
    /* We've written data and instructions, so *flush* the data cache
     * and *invalidate* the instruction cache.
     */
-    flush_dcache64((addr64_t)link_buffer_address, link_buffer_size, false);
-    invalidate_icache64((addr64_t)link_buffer_address, link_buffer_size, false);
+    flush_dcache(link_buffer_address, link_buffer_size, false);
+    invalidate_icache(link_buffer_address, link_buffer_size, false);
 
 
    /* Register the new kmod with the kernel proper.
@@ -1068,7 +1044,7 @@
     IOLog("kmod id %d successfully created at 0x%lx, size %ld.\n",
         (unsigned int)kmod_id, link_buffer_address, link_buffer_size);
     LOG_DELAY();
-#endif /* DEBUG */
+#endif DEBUG
 
    /* Record dependencies for the newly-loaded kmod.
     */
@@ -1103,7 +1079,7 @@
 finish:
 
     if (kmod_info_freeme) {
-        kfree((unsigned int)kmod_info_freeme, sizeof(kmod_info_t));
+        kfree(kmod_info_freeme, sizeof(kmod_info_t));
     }
 
    /* Only do a kld_unload_all() if at least one load happened.
@@ -1121,7 +1097,7 @@
     if (kmod_dependencies) {
         for (i = 0; i < num_dependencies; i++) {
             if (kmod_dependencies[i]) {
-                kfree((unsigned int)kmod_dependencies[i], sizeof(kmod_info_t));
+                kfree(kmod_dependencies[i], sizeof(kmod_info_t));
             }
         }
         kfree((unsigned int)kmod_dependencies,
@@ -1215,7 +1191,7 @@
 finish:
 
     if (kmod_info) {
-        kfree((unsigned int)kmod_info, sizeof(kmod_info_t));
+        kfree(kmod_info, sizeof(kmod_info_t));
     }
 
     if (dependencyList) {