Loading...
libkern/c++/OSKext.cpp xnu-12377.101.15 xnu-3248.30.4
--- xnu/xnu-12377.101.15/libkern/c++/OSKext.cpp
+++ xnu/xnu-3248.30.4/libkern/c++/OSKext.cpp
@@ -1,8 +1,8 @@
 /*
- * Copyright (c) 2008-2021 Apple Inc. All rights reserved.
+ * Copyright (c) 2008-2012 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
+ * 
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
@@ -11,10 +11,10 @@
  * unlawful or unlicensed copies of an Apple operating system, or to
  * circumvent, violate, or enable the circumvention or violation of, any
  * terms of an Apple operating system software license agreement.
- *
+ * 
  * Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
+ * 
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -22,21 +22,15 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- *
+ * 
  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 
-#define IOKIT_ENABLE_SHARED_PTR
-
 extern "C" {
-#include <string.h>
 #include <kern/clock.h>
 #include <kern/host.h>
 #include <kern/kext_alloc.h>
-#include <firehose/tracepoint_private.h>
-#include <firehose/chunk_private.h>
-#include <os/firehose_buffer_private.h>
-#include <vm/vm_map_xnu.h>
+#include <vm/vm_kern.h>
 #include <kextd/kextd_mach.h>
 #include <libkern/kernel_mach_header.h>
 #include <libkern/kext_panic_report.h>
@@ -48,30 +42,18 @@
 #include <mach/host_special_ports.h>
 #include <mach/mach_vm.h>
 #include <mach/mach_time.h>
+#include <sys/sysctl.h>
 #include <uuid/uuid.h>
+// 04/18/11 - gab: <rdar://problem/9236163>
 #include <sys/random.h>
-#include <sys/reboot.h>
-#include <pexpert/pexpert.h>
-#include <pexpert/device_tree.h>
 
 #include <sys/pgo.h>
-
-#if CONFIG_CSR
-#include <sys/csr.h>
-#include <sys/stat.h>
-#include <sys/vnode.h>
-#endif /* CONFIG_CSR */
-};
 
 #if CONFIG_MACF
 #include <sys/kauth.h>
 #include <security/mac_framework.h>
 #endif
-
-#include <vm/vm_kern_xnu.h>
-#include <sys/sysctl.h>
-#include <kern/task.h>
-#include <os/cpp_util.h>
+};
 
 #include <libkern/OSKextLibPrivate.h>
 #include <libkern/c++/OSKext.h>
@@ -81,17 +63,9 @@
 #include <IOKit/IOCatalogue.h>
 #include <IOKit/IORegistryEntry.h>
 #include <IOKit/IOService.h>
-#include <IOKit/IOUserServer.h>
 
 #include <IOKit/IOStatisticsPrivate.h>
 #include <IOKit/IOBSD.h>
-#include <IOKit/IOPlatformExpert.h>
-
-#include <san/kasan.h>
-
-#if CONFIG_SPTM
-#include <arm64/sptm/sptm.h>
-#endif
 
 #if PRAGMA_MARK
 #pragma mark External & Internal Function Protos
@@ -101,69 +75,38 @@
 extern "C" {
 extern int  IODTGetLoaderInfo(const char * key, void ** infoAddr, int * infoSize);
 extern void IODTFreeLoaderInfo(const char * key, void * infoAddr, int infoSize);
+extern void OSRuntimeUnloadCPPForSegment(kernel_segment_command_t * segment);
+extern void OSRuntimeUnloadCPP(kmod_info_t * ki, void * data);
 
 extern ppnum_t pmap_find_phys(pmap_t pmap, addr64_t va); /* osfmk/machine/pmap.h */
-extern int dtrace_keep_kernel_symbols(void);
-
-#if defined(__x86_64__) || defined(__i386__)
-extern kern_return_t i386_slide_individual_kext(kernel_mach_header_t *mh, uintptr_t slide);
-extern kern_return_t i386_slide_kext_collection_mh_addrs(kernel_mach_header_t *mh, uintptr_t slide, bool adjust_mach_headers);
-extern void *ubc_getobject_from_filename(const char *filename, struct vnode **, off_t *file_size);
-static void *allocate_kcfileset_map_entry_list(void);
-static void add_kcfileset_map_entry(void *map_entry_list, vm_map_offset_t start, vm_map_offset_t size);
-static void deallocate_kcfileset_map_entry_list_and_unmap_entries(void *map_entry_list, boolean_t unmap_entries, bool pageable);
-int vnode_put(struct vnode *vp);
-kern_return_t vm_map_kcfileset_segment(vm_map_offset_t *start, vm_map_offset_t size,
-    void *control, vm_object_offset_t fileoffset, vm_prot_t max_prot);
-kern_return_t vm_unmap_kcfileset_segment(vm_map_offset_t *start, vm_map_offset_t size);
-void * ubc_getobject(struct vnode *vp, __unused int flags);
-#endif //(__x86_64__) || defined(__i386__)
-}
-
-extern unsigned long gVirtBase;
-extern unsigned long gPhysBase;
-
-bool pageableKCloaded = false;
-bool auxKCloaded = false;
-bool resetAuxKCSegmentOnUnload = false;
-
-extern boolean_t pageablekc_uuid_valid;
-extern uuid_t pageablekc_uuid;
-extern uuid_string_t pageablekc_uuid_string;
-
-extern boolean_t auxkc_uuid_valid;
-extern uuid_t auxkc_uuid;
-extern uuid_string_t auxkc_uuid_string;
+}
 
 static OSReturn _OSKextCreateRequest(
-	const char    * predicate,
-	OSSharedPtr<OSDictionary> & requestP);
+    const char    * predicate,
+    OSDictionary ** requestP);
 static OSString * _OSKextGetRequestPredicate(OSDictionary * requestDict);
 static OSObject * _OSKextGetRequestArgument(
-	OSDictionary * requestDict,
-	const char   * argName);
+    OSDictionary * requestDict,
+    const char   * argName);
 static bool _OSKextSetRequestArgument(
-	OSDictionary    * requestDict,
-	const char      * argName,
-	OSMetaClassBase * value);
-template <typename T>
-static T * _OSKextExtractPointer(OSValueObject<T *> * wrapper);
-static OSKextRequestResourceCallback _OSKextExtractCallbackPointer(OSValueObject<OSKextRequestResourceCallback> * wrapper);
+    OSDictionary * requestDict,
+    const char   * argName,
+    OSObject     * value);
+static void * _OSKextExtractPointer(OSData * wrapper);
 static OSReturn _OSDictionarySetCStringValue(
-	OSDictionary * dict,
-	const char   * key,
-	const char   * value);
+    OSDictionary * dict,
+    const char   * key,
+    const char   * value);
+static bool _OSKextInPrelinkRebuildWindow(void);
 static bool _OSKextInUnloadedPrelinkedKexts(const OSSymbol * theBundleID);
-#if CONFIG_KXLD
-static bool _OSKextInPrelinkRebuildWindow(void);
-#endif
-
+    
 // We really should add containsObject() & containsCString to OSCollection & subclasses.
 // So few pad slots, though....
 static bool _OSArrayContainsCString(OSArray * array, const char * cString);
-static void OSKextLogKextInfo(OSKext *aKext, uint64_t address, uint64_t size, firehose_tracepoint_code_t code);
-
-static const char *getDextUniqueIDCString(OSData *dextUniqueID, unsigned int *size);
+
+#if CONFIG_KEC_FIPS
+static void * GetAppleTEXTHashForKext(OSKext * theKext, OSDictionary *theInfoDict);
+#endif // CONFIG_KEC_FIPS
 
 /* Prelinked arm kexts do not have VM entries because the method we use to
  * fake an entry (see libsa/bootstrap.cpp:readPrelinkedExtensions()) does
@@ -174,9 +117,6 @@
 #define VM_MAPPED_KEXTS 1
 #define KASLR_KEXT_DEBUG 0
 #define KASLR_IOREG_DEBUG 0
-#elif __arm__ || __arm64__
-#define VM_MAPPED_KEXTS 0
-#define KASLR_KEXT_DEBUG 0
 #else
 #error Unsupported architecture
 #endif
@@ -191,7 +131,6 @@
 /* Use this number to create containers.
  */
 #define kOSKextTypicalLoadCount      (150)
-#define kOSKextTypicalUpgradeCount     (5)
 
 /* Any kext will have at least 1 retain for the internal lookup-by-ID dict.
  * A loaded kext will no dependents or external retains will have 2 retains.
@@ -199,9 +138,6 @@
 #define kOSKextMinRetainCount        (1)
 #define kOSKextMinLoadedRetainCount  (2)
 
-#define kOSKextMaxDextLaunchedCount  (~((uint32_t)0))
-#define KOSBundleDextUniqueIdentifierMaxStringLength (KOSBundleDextUniqueIdentifierMaxLength * 2 +1)
-
 /**********
  * Strings and substrings used in dependency resolution.
  */
@@ -244,35 +180,12 @@
  */
 #define _kOSKextExecutableExternalDataKey    "_OSKextExecutableExternalData"
 
-#define OS_LOG_HDR_VERSION  1
-#define NUM_OS_LOG_SECTIONS 3
-
-#define OS_LOG_SECT_IDX         0
-#define CSTRING_SECT_IDX        1
-#define ASAN_CSTRING_SECT_IDX   2
-
 #if PRAGMA_MARK
 #pragma mark Typedefs
 #endif
 /*********************************************************************
 * Typedefs
 *********************************************************************/
-
-/*********************************************************************
-* osLogDataHeaderRef describes the header information of an OSData
-* object that is returned when querying for kOSBundleLogStringsKey.
-* We currently return information regarding 2 sections - os_log and
-* cstring. In the case that the os_log section doesn't exist, we just
-* return an offset and length of 0 for that section.
-*********************************************************************/
-typedef struct osLogDataHeader {
-	uint32_t version;
-	uint32_t sect_count;
-	struct {
-		uint32_t sect_offset;
-		uint32_t sect_size;
-	} sections[0];
-} osLogDataHeaderRef;
 
 /*********************************************************************
 * MkextEntryRef describes the contents of an OSData object
@@ -284,8 +197,8 @@
 * Snow Leopard.
 *********************************************************************/
 typedef struct MkextEntryRef {
-	mkext_basic_header * mkext; // beginning of whole mkext file
-	void               * fileinfo;// mkext2_file_entry or equiv; see mkext.h
+    mkext_basic_header * mkext;     // beginning of whole mkext file
+    void               * fileinfo;  // mkext2_file_entry or equiv; see mkext.h
 } MkextEntryRef;
 
 #if PRAGMA_MARK
@@ -298,55 +211,47 @@
 static  bool                sPrelinkBoot               = false;
 static  bool                sSafeBoot                  = false;
 static  bool                sKeepSymbols               = false;
-static  bool                sPanicOnKCMismatch         = false;
-static  bool                sOSKextWasResetAfterUserspaceReboot = false;
-
-/*********************************************************************
- * sKextLock is the principal lock for OSKext, and guards all static
- * and global variables not owned by other locks (declared further
- * below). It must be taken by any entry-point method or function,
- * including internal functions called on scheduled threads.
- *
- * sKextLock and sKextInnerLock are recursive due to multiple functions
- * that are called both externally and internally. The other locks are
- * nonrecursive.
- *
- * Which locks are taken depends on what they protect, but if more than
- * one must be taken, they must always be locked in this order
- * (and unlocked in reverse order) to prevent deadlocks:
- *
- *    1. sKextLock
- *    2. sKextInnerLock
- *    3. sKextSummariesLock
- *    4. sKextLoggingLock
- */
+
+/*********************************************************************
+* sKextLock is the principal lock for OSKext, and guards all static
+* and global variables not owned by other locks (declared further
+* below). It must be taken by any entry-point method or function,
+* including internal functions called on scheduled threads.
+*
+* sKextLock and sKextInnerLock are recursive due to multiple functions
+* that are called both externally and internally. The other locks are
+* nonrecursive.
+*
+* Which locks are taken depends on what they protect, but if more than
+* one must be taken, they must always be locked in this order
+* (and unlocked in reverse order) to prevent deadlocks:
+*
+*    1. sKextLock
+*    2. sKextInnerLock
+*    3. sKextSummariesLock
+*    4. sKextLoggingLock
+*/
 static IORecursiveLock    * sKextLock                  = NULL;
 
-static OSSharedPtr<OSDictionary>   sKextsByID;
-static OSSharedPtr<OSDictionary>   sExcludeListByID;
-static OSKextVersion               sExcludeListVersion        = 0;
-static OSSharedPtr<OSArray>        sLoadedKexts;
-static OSSharedPtr<OSDictionary>   sNonLoadableKextsByID;
-static OSSharedPtr<OSArray>        sUnloadedPrelinkedKexts;
-static OSSharedPtr<OSArray>        sLoadedDriverKitKexts;
-static OSSharedPtr<OSDictionary>   sDriverKitToUpgradeByID;
-
-// Requests to the IOKit daemon waiting to be picked up.
-static OSSharedPtr<OSArray>        sKernelRequests;
+static OSDictionary       * sKextsByID                 = NULL;
+static OSDictionary       * sExcludeListByID           = NULL;
+static OSArray            * sLoadedKexts               = NULL;
+static OSArray            * sUnloadedPrelinkedKexts    = NULL;
+
+// Requests to kextd waiting to be picked up.
+static OSArray            * sKernelRequests            = NULL;
 // Identifier of kext load requests in sKernelRequests
-static OSSharedPtr<OSSet>          sPostedKextLoadIdentifiers;
-static OSSharedPtr<OSArray>        sRequestCallbackRecords;
+static OSSet              * sPostedKextLoadIdentifiers = NULL;
+static OSArray            * sRequestCallbackRecords    = NULL;
 
 // Identifiers of all kexts ever requested in kernel; used for prelinked kernel
-static OSSharedPtr<OSSet>          sAllKextLoadIdentifiers;
-#if CONFIG_KXLD
+static OSSet              * sAllKextLoadIdentifiers    = NULL;
 static KXLDContext        * sKxldContext               = NULL;
-#endif
 static uint32_t             sNextLoadTag               = 0;
 static uint32_t             sNextRequestTag            = 0;
 
 static bool                 sUserLoadsActive           = false;
-static bool                 sIOKitDaemonActive         = false;
+static bool                 sKextdActive               = false;
 static bool                 sDeferredLoadSucceeded     = false;
 static bool                 sConsiderUnloadsExecuted   = false;
 
@@ -359,19 +264,9 @@
 static bool                 sUnloadEnabled             = true;
 
 /*********************************************************************
- * Stuff for the OSKext representing the kernel itself.
- **********/
+* Stuff for the OSKext representing the kernel itself.
+**********/
 static OSKext          * sKernelKext             = NULL;
-
-/* Load Tag IDs used by statically loaded binaries (e.g, the kernel itself). */
-enum : uint32_t {
-	kOSKextKernelLoadTag = 0,
-#if CONFIG_SPTM
-	kOSKextSPTMLoadTag   = 1,
-	kOSKextTXMLoadTag    = 2,
-#endif /* CONFIG_SPTM */
-	kOSKextLoadTagCount
-};
 
 /* Set up a fake kmod_info struct for the kernel.
  * It's used in OSRuntime.cpp to call OSRuntimeInitializeCPP()
@@ -386,68 +281,18 @@
  * binary compability.
  */
 kmod_info_t g_kernel_kmod_info = {
-	.next =            NULL,
-	.info_version =    KMOD_INFO_VERSION,
-	.id =              kOSKextKernelLoadTag,   // loadTag: kernel is always 0
-	.name =            kOSKextKernelIdentifier,// bundle identifier
-	.version =         "0",           // filled in in OSKext::initialize()
-	.reference_count = -1,            // never adjusted; kernel never unloads
-	.reference_list =  NULL,
-	.address =         0,
-	.size =            0,             // filled in in OSKext::initialize()
-	.hdr_size =        0,
-	.start =           NULL,
-	.stop =            NULL
-};
-
-#if CONFIG_SPTM
-/* The SPTM and TXM need fake kmod structures just like the kernel. */
-kmod_info_t g_sptm_kmod_info = {
-	.next =            NULL,
-	.info_version =    KMOD_INFO_VERSION,
-	.id =              kOSKextSPTMLoadTag,   // Always one after the kernel
-	.name =            kOSKextSPTMIdentifier,// bundle identifier
-	.version =         "0",           // filled in by OSKext::initialize()
-	.reference_count = -1,            // never adjusted; SPTM never unloads
-	.reference_list =  NULL,
-	.address =         0,
-	.size =            0,             // filled in by OSKext::initialize()
-	.hdr_size =        0,
-	.start =           NULL,
-	.stop =            NULL
-};
-
-kmod_info_t g_txm_kmod_info = {
-	.next =            NULL,
-	.info_version =    KMOD_INFO_VERSION,
-	.id =              kOSKextTXMLoadTag,   // Always one after the SPTM
-	.name =            kOSKextTXMIdentifier,// bundle identifier
-	.version =         "0",           // filled in by OSKext::initialize()
-	.reference_count = -1,            // never adjusted; TXM never unloads
-	.reference_list =  NULL,
-	.address =         0,
-	.size =            0,             // filled in by OSKext::initialize()
-	.hdr_size =        0,
-	.start =           NULL,
-	.stop =            NULL
-};
-#endif /* CONFIG_SPTM */
-
-/* Set up a fake kmod_info struct for statically linked kexts that don't have one. */
-
-kmod_info_t invalid_kmod_info = {
-	.next =            NULL,
-	.info_version =    KMOD_INFO_VERSION,
-	.id =              UINT32_MAX,
-	.name =            "invalid",
-	.version =         "0",
-	.reference_count = -1,
-	.reference_list =  NULL,
-	.address =         0,
-	.size =            0,
-	.hdr_size =        0,
-	.start =           NULL,
-	.stop =            NULL
+    /* next            */ 0,
+    /* info_version    */ KMOD_INFO_VERSION,
+    /* id              */ 0,                 // loadTag: kernel is always 0
+    /* name            */ kOSKextKernelIdentifier,    // bundle identifier
+    /* version         */ "0",               // filled in in OSKext::initialize()
+    /* reference_count */ -1,                // never adjusted; kernel never unloads
+    /* reference_list  */ NULL,
+    /* address         */ NULL,
+    /* size            */ 0,                 // filled in in OSKext::initialize()
+    /* hdr_size        */ 0,
+    /* start           */ 0,
+    /* stop            */ 0
 };
 
 extern "C" {
@@ -462,87 +307,62 @@
 
 static char     * loaded_kext_paniclist         = NULL;
 static uint32_t   loaded_kext_paniclist_size    = 0;
-
+    
 AbsoluteTime      last_loaded_timestamp;
-static char       last_loaded_str_buf[2 * KMOD_MAX_NAME];
+static char       last_loaded_str_buf[2*KMOD_MAX_NAME];
 static u_long     last_loaded_strlen            = 0;
 static void     * last_loaded_address           = NULL;
 static u_long     last_loaded_size              = 0;
 
 AbsoluteTime      last_unloaded_timestamp;
-static char       last_unloaded_str_buf[2 * KMOD_MAX_NAME];
+static char       last_unloaded_str_buf[2*KMOD_MAX_NAME];
 static u_long     last_unloaded_strlen          = 0;
 static void     * last_unloaded_address         = NULL;
 static u_long     last_unloaded_size            = 0;
 
-// Statically linked kmods described by several mach-o sections:
-//
-// kPrelinkInfoSegment:kBuiltinInfoSection
-// Array of pointers to kmod_info_t structs.
-//
-// kPrelinkInfoSegment:kBuiltinInfoSection
-// Array of pointers to an embedded mach-o header.
-//
-// __DATA:kBuiltinInitSection, kBuiltinTermSection
-// Structors for all kmods. Has to be filtered by proc address.
-//
-
-static uint32_t gBuiltinKmodsCount;
-static kernel_section_t * gBuiltinKmodsSectionInfo;
-static kernel_section_t * gBuiltinKmodsSectionStart;
-
-const OSSymbol              * gIOSurfaceIdentifier;
-vm_tag_t                      gIOSurfaceTag;
-
-/*********************************************************************
- * sKextInnerLock protects against cross-calls with IOService and
- * IOCatalogue, and owns the variables declared immediately below.
- *
- * Note that sConsiderUnloadsExecuted above belongs to sKextLock!
- *
- * When both sKextLock and sKextInnerLock need to be taken,
- * always lock sKextLock first and unlock it second. Never take both
- * locks in an entry point to OSKext; if you need to do so, you must
- * spawn an independent thread to avoid potential deadlocks for threads
- * calling into OSKext.
- **********/
+/*********************************************************************
+* sKextInnerLock protects against cross-calls with IOService and
+* IOCatalogue, and owns the variables declared immediately below.
+*
+* Note that sConsiderUnloadsExecuted above belongs to sKextLock!
+*
+* When both sKextLock and sKextInnerLock need to be taken,
+* always lock sKextLock first and unlock it second. Never take both
+* locks in an entry point to OSKext; if you need to do so, you must
+* spawn an independent thread to avoid potential deadlocks for threads
+* calling into OSKext.
+**********/
 static IORecursiveLock *    sKextInnerLock             = NULL;
 
-#if XNU_TARGET_OS_OSX
 static bool                 sAutounloadEnabled         = true;
-#endif
 static bool                 sConsiderUnloadsCalled     = false;
 static bool                 sConsiderUnloadsPending    = false;
 
 static unsigned int         sConsiderUnloadDelay       = 60;     // seconds
-static thread_call_t        sUnloadCallout             = NULL;
-#if CONFIG_KXLD
-static thread_call_t        sDestroyLinkContextThread  = NULL;   // one-shot, one-at-a-time thread
-#endif // CONFIG_KXLD
+static thread_call_t        sUnloadCallout             = 0;
+static thread_call_t        sDestroyLinkContextThread  = 0;      // one-shot, one-at-a-time thread
 static bool                 sSystemSleep               = false;  // true when system going to sleep
-static AbsoluteTime         sLastWakeTime;                       // last time we woke up
-
-/*********************************************************************
- * Backtraces can be printed at various times so we need a tight lock
- * on data used for that. sKextSummariesLock protects the variables
- * declared immediately below.
- *
- * gLoadedKextSummaries is accessed by other modules, but only during
- * a panic so the lock isn't needed then.
- *
- * gLoadedKextSummaries has the "used" attribute in order to ensure
- * that it remains visible even when we are performing extremely
- * aggressive optimizations, as it is needed to allow the debugger
- * to automatically parse the list of loaded kexts.
- **********/
+static AbsoluteTime         sLastWakeTime;                       // last time we woke up   
+
+/*********************************************************************
+* Backtraces can be printed at various times so we need a tight lock
+* on data used for that. sKextSummariesLock protects the variables
+* declared immediately below.
+*
+* gLoadedKextSummaries is accessed by other modules, but only during
+* a panic so the lock isn't needed then.
+*
+* gLoadedKextSummaries has the "used" attribute in order to ensure
+* that it remains visible even when we are performing extremely
+* aggressive optimizations, as it is needed to allow the debugger
+* to automatically parse the list of loaded kexts.
+**********/
 static IOLock                 * sKextSummariesLock                = NULL;
-extern "C" lck_grp_t            vm_page_lck_grp_bucket;
-static lck_grp_t              * sKextAccountsLockGrp = &vm_page_lck_grp_bucket;
-#define sKextAccountsLock       (&vm_allocation_sites_lock)
-
-void(*const sLoadedKextSummariesUpdated)(void) = OSKextLoadedKextSummariesUpdated;
+extern "C" lck_spin_t           vm_allocation_sites_lock;
+static IOSimpleLock           * sKextAccountsLock = &vm_allocation_sites_lock;
+
+void (*sLoadedKextSummariesUpdated)(void) = OSKextLoadedKextSummariesUpdated;
 OSKextLoadedKextSummaryHeader * gLoadedKextSummaries __attribute__((used)) = NULL;
-uint64_t gLoadedKextSummariesTimestamp __attribute__((used)) = 0;
 static size_t sLoadedKextSummariesAllocSize = 0;
 
 static OSKextActiveAccount    * sKextAccounts;
@@ -550,46 +370,36 @@
 };
 
 /*********************************************************************
- * sKextLoggingLock protects the logging variables declared immediately below.
- **********/
-__static_testable IOLock      * sKextLoggingLock           = NULL;
-
-static  const OSKextLogSpec     kDefaultKernelLogFilter    = kOSKextLogBasicLevel |
-    kOSKextLogVerboseFlagsMask;
-static  OSKextLogSpec           sKernelLogFilter           = kDefaultKernelLogFilter;
-static  bool                    sBootArgLogFilterFound     = false;
+* sKextLoggingLock protects the logging variables declared immediately below.
+**********/
+static IOLock             * sKextLoggingLock           = NULL;
+
+static  const OSKextLogSpec kDefaultKernelLogFilter    = kOSKextLogBasicLevel |
+                                                         kOSKextLogVerboseFlagsMask;
+static  OSKextLogSpec       sKernelLogFilter           = kDefaultKernelLogFilter;
+static  bool                sBootArgLogFilterFound     = false;
 SYSCTL_UINT(_debug, OID_AUTO, kextlog, CTLFLAG_RW | CTLFLAG_LOCKED, &sKernelLogFilter,
-    0, "kernel kext logging");
-
-static  OSKextLogSpec           sUserSpaceKextLogFilter    = kOSKextLogSilentFilter;
-static  OSSharedPtr<OSArray>    sUserSpaceLogSpecArray;
-static  OSSharedPtr<OSArray>    sUserSpaceLogMessageArray;
+    sKernelLogFilter, "kernel kext logging");
+
+static  OSKextLogSpec       sUserSpaceKextLogFilter    = kOSKextLogSilentFilter;
+static  OSArray           * sUserSpaceLogSpecArray     = NULL;
+static  OSArray           * sUserSpaceLogMessageArray  = NULL;
 
 /*********
- * End scope for sKextInnerLock-protected variables.
- *********************************************************************/
-
-/*********************************************************************
- * OSValueObject concrete type instantiations
- **********/
-OSDefineValueObjectForDependentType(void*)
-OSDefineValueObjectForDependentType(OSKextRequestResourceCallback)
-
-
-/**********************************************************************/
-
-TUNABLE(uint32_t, kMaxDextCrashesInOneDay, "daily_max_dext_crashes", kMaxDextCrashesInOneDayDefault);
-
-/*********************************************************************
- *  helper function used for collecting PGO data upon unload of a kext
+* End scope for sKextInnerLock-protected variables.
+*********************************************************************/
+
+
+/*********************************************************************
+ helper function used for collecting PGO data upon unload of a kext
  */
 
 static int OSKextGrabPgoDataLocked(OSKext *kext,
-    bool metadata,
-    uuid_t instance_uuid,
-    uint64_t *pSize,
-    char *pBuffer,
-    uint64_t bufferSize);
+                                   bool metadata,
+                                   uuid_t instance_uuid,
+                                   uint64_t *pSize,
+                                   char *pBuffer,
+                                   uint64_t bufferSize);
 
 /**********************************************************************/
 
@@ -602,154 +412,138 @@
 * C functions used for callbacks.
 *********************************************************************/
 extern "C" {
-void
-osdata_kmem_free(void * ptr, unsigned int length)
-{
-	kmem_free(kernel_map, (vm_address_t)ptr, length);
-	return;
-}
-
-void
-osdata_phys_free(void * ptr, unsigned int length)
-{
-	ml_static_mfree((vm_offset_t)ptr, length);
-	return;
-}
-
-void
-osdata_vm_deallocate(void * ptr, unsigned int length)
-{
-	(void)vm_deallocate(kernel_map, (vm_offset_t)ptr, length);
-	return;
-}
-
-void
-osdata_kext_free(void * ptr, unsigned int length)
-{
-	(void)kext_free((vm_offset_t)ptr, length);
-}
+void osdata_kmem_free(void * ptr, unsigned int length) {
+    kmem_free(kernel_map, (vm_address_t)ptr, length);
+    return;
+}
+
+void osdata_phys_free(void * ptr, unsigned int length) {
+    ml_static_mfree((vm_offset_t)ptr, length);
+    return;
+}
+
+void osdata_vm_deallocate(void * ptr, unsigned int length)
+{
+    (void)vm_deallocate(kernel_map, (vm_offset_t)ptr, length);
+    return;
+}
+
+void osdata_kext_free(void * ptr, unsigned int length)
+{
+    (void)kext_free((vm_offset_t)ptr, length);
+}
+
 };
 
 #if PRAGMA_MARK
 #pragma mark KXLD Allocation Callback
 #endif
-#if CONFIG_KXLD
 /*********************************************************************
 * KXLD Allocation Callback
 *********************************************************************/
 kxld_addr_t
 kern_allocate(
-	u_long              size,
-	KXLDAllocateFlags * flags,
-	void              * user_data)
-{
-	vm_address_t  result       = 0; // returned
-	kern_return_t mach_result  = KERN_FAILURE;
-	bool          success      = false;
-	OSKext      * theKext      = (OSKext *)user_data;
-	unsigned int  roundSize    = 0;
-	OSSharedPtr<OSData>      linkBuffer;
-
-	if (round_page(size) > UINT_MAX) {
-		OSKextLog(theKext,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogGeneralFlag,
-		    "%s: Requested memory size is greater than UINT_MAX.",
-		    theKext->getIdentifierCString());
-		goto finish;
-	}
-
-	roundSize = (unsigned int)round_page(size);
-
-	mach_result = kext_alloc(&result, roundSize, /* fixed */ FALSE);
-	if (mach_result != KERN_SUCCESS) {
-		OSKextLog(theKext,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogGeneralFlag,
-		    "Can't allocate kernel memory to link %s.",
-		    theKext->getIdentifierCString());
-		goto finish;
-	}
-
-	/* Create an OSData wrapper for the allocated buffer.
-	 */
-	linkBuffer = OSData::withBytesNoCopy((void *)result, roundSize);
-	if (!linkBuffer) {
-		OSKextLog(theKext,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogGeneralFlag,
-		    "Can't allocate linked executable wrapper for %s.",
-		    theKext->getIdentifierCString());
-		goto finish;
-	}
-	linkBuffer->setDeallocFunction(osdata_kext_free);
-	OSKextLog(theKext,
-	    kOSKextLogProgressLevel |
-	    kOSKextLogLoadFlag | kOSKextLogLinkFlag,
-	    "Allocated link buffer for kext %s at %p (%lu bytes).",
-	    theKext->getIdentifierCString(),
-	    (void *)result, (unsigned long)roundSize);
-
-	theKext->setLinkedExecutable(linkBuffer.get());
-
-	*flags = kKxldAllocateWritable;
-	success = true;
+    u_long              size,
+    KXLDAllocateFlags * flags,
+    void              * user_data)
+{
+    vm_address_t  result       = 0;     // returned
+    kern_return_t mach_result  = KERN_FAILURE;
+    bool          success      = false;
+    OSKext      * theKext      = (OSKext *)user_data;
+    u_long        roundSize    = round_page(size);
+    OSData      * linkBuffer   = NULL;  // must release
+
+    mach_result = kext_alloc(&result, roundSize, /* fixed */ FALSE);
+    if (mach_result != KERN_SUCCESS) {
+        OSKextLog(theKext,
+            kOSKextLogErrorLevel |
+            kOSKextLogGeneralFlag,
+            "Can't allocate kernel memory to link %s.",
+            theKext->getIdentifierCString());
+        goto finish;
+    }
+
+   /* Create an OSData wrapper for the allocated buffer.
+    */
+    linkBuffer = OSData::withBytesNoCopy((void *)result, roundSize);
+    if (!linkBuffer) {
+        OSKextLog(theKext,
+            kOSKextLogErrorLevel |
+            kOSKextLogGeneralFlag,
+            "Can't allocate linked executable wrapper for %s.",
+            theKext->getIdentifierCString());
+        goto finish;
+    }
+    linkBuffer->setDeallocFunction(osdata_kext_free);
+    OSKextLog(theKext,
+        kOSKextLogProgressLevel |
+        kOSKextLogLoadFlag | kOSKextLogLinkFlag,
+        "Allocated link buffer for kext %s at %p (%lu bytes).",
+        theKext->getIdentifierCString(),
+        (void *)result, (unsigned long)roundSize);
+
+    theKext->setLinkedExecutable(linkBuffer);
+
+    *flags = kKxldAllocateWritable;
+    success = true;
 
 finish:
-	if (!success && result) {
-		kext_free(result, roundSize);
-		result = 0;
-	}
-
-	return (kxld_addr_t)result;
+    if (!success && result) {
+        kext_free(result, roundSize);
+        result = 0;
+    }
+
+    OSSafeRelease(linkBuffer);
+
+    return (kxld_addr_t)result;
 }
 
 /*********************************************************************
 *********************************************************************/
 void
 kxld_log_callback(
-	KXLDLogSubsystem    subsystem,
-	KXLDLogLevel        level,
-	const char        * format,
-	va_list             argList,
-	void              * user_data)
-{
-	OSKext *theKext = (OSKext *) user_data;
-	OSKextLogSpec logSpec = 0;
-
-	switch (subsystem) {
-	case kKxldLogLinking:
-		logSpec |= kOSKextLogLinkFlag;
-		break;
-	case kKxldLogPatching:
-		logSpec |= kOSKextLogPatchFlag;
-		break;
-	}
-
-	switch (level) {
-	case kKxldLogExplicit:
-		logSpec |= kOSKextLogExplicitLevel;
-		break;
-	case kKxldLogErr:
-		logSpec |= kOSKextLogErrorLevel;
-		break;
-	case kKxldLogWarn:
-		logSpec |= kOSKextLogWarningLevel;
-		break;
-	case kKxldLogBasic:
-		logSpec |= kOSKextLogProgressLevel;
-		break;
-	case kKxldLogDetail:
-		logSpec |= kOSKextLogDetailLevel;
-		break;
-	case kKxldLogDebug:
-		logSpec |= kOSKextLogDebugLevel;
-		break;
-	}
-
-	OSKextVLog(theKext, logSpec, format, argList);
-}
-#endif // CONFIG_KXLD
+    KXLDLogSubsystem    subsystem,
+    KXLDLogLevel        level,
+    const char        * format,
+    va_list             argList,
+    void              * user_data)
+{
+    OSKext *theKext = (OSKext *) user_data;
+    OSKextLogSpec logSpec = 0;
+
+    switch (subsystem) {
+    case kKxldLogLinking:
+        logSpec |= kOSKextLogLinkFlag;
+        break;
+    case kKxldLogPatching:
+        logSpec |= kOSKextLogPatchFlag;
+        break;
+    }
+
+    switch (level) {
+    case kKxldLogExplicit:
+        logSpec |= kOSKextLogExplicitLevel;
+        break;
+    case kKxldLogErr:
+        logSpec |= kOSKextLogErrorLevel;
+        break;
+    case kKxldLogWarn:
+        logSpec |= kOSKextLogWarningLevel;
+        break;
+    case kKxldLogBasic:
+        logSpec |= kOSKextLogProgressLevel;
+        break;
+    case kKxldLogDetail:
+        logSpec |= kOSKextLogDetailLevel;
+        break;
+    case kKxldLogDebug:
+        logSpec |= kOSKextLogDebugLevel;
+        break;
+    }
+
+    OSKextVLog(theKext, logSpec, format, argList);
+}
 
 #if PRAGMA_MARK
 #pragma mark IOStatistics defines
@@ -795,751 +589,489 @@
 #define super OSObject
 OSDefineMetaClassAndStructors(OSKext, OSObject)
 
-OSDefineMetaClassAndStructors(OSKextSavedMutableSegment, OSObject);
-
-OSDefineMetaClassAndStructors(OSDextStatistics, OSObject);
-
-/*********************************************************************
-*********************************************************************/
-/**
- * Allocate and intialize a fake/representative OSKext object for a statically
- * loaded (by iBoot) binary (e.g., the XNU kernel itself).
- *
- * @param kmod_info Pointer to the kmod_info structure for the binary being
- *                  setup. At least the "name" and "id" fields needs to already
- *                  be set correctly.
- *
- * @return The allocated and initialized OSKext object.
- */
-/* static */
-OSKext *
-OSKext::allocAndInitFakeKext(kmod_info_t *kmod_info)
-{
-	vm_offset_t load_address = 0;
-	const char *bundle_name = NULL;
-	bool macho_is_unslid = false;
-	bool set_custom_path = false;
-	const char *executable_fallback_name = NULL;
-
-	if (kmod_info->id == kOSKextKernelLoadTag) {
-		load_address = (vm_offset_t)&_mh_execute_header;
-		bundle_name = "mach_kernel";
-
-		/* The kernel Mach-O header is fixed up to slide all of its addresses. */
-		macho_is_unslid = false;
-
-		/**
-		 * No path to the binary is set for the kernel in its OSKext object. The
-		 * kernel binary is located in fixed directories depending on the OS.
-		 */
-		set_custom_path = false;
-		executable_fallback_name = NULL;
-#if CONFIG_SPTM
-	} else if (kmod_info->id == kOSKextSPTMLoadTag) {
-		load_address = (vm_offset_t)SPTMArgs->debug_header->image[DEBUG_HEADER_ENTRY_SPTM];
-		bundle_name = "sptm";
-
-		/* The addresses in the SPTM Mach-O header are all unslid. */
-		macho_is_unslid = true;
-
-		set_custom_path = true;
-		executable_fallback_name = "sptm.no.binname.in.macho";
-	} else if (kmod_info->id == kOSKextTXMLoadTag) {
-		load_address = (vm_offset_t)SPTMArgs->debug_header->image[DEBUG_HEADER_ENTRY_TXM];
-		bundle_name = "txm";
-
-		/* The addresses in the TXM Mach-O header are all unslid. */
-		macho_is_unslid = true;
-
-		set_custom_path = true;
-		executable_fallback_name = "txm.no.binname.in.macho";
-#endif /* CONFIG_SPTM */
-	} else {
-		panic("%s: Unsupported kmod_info->id (%d)", __func__, kmod_info->id);
-	}
-
-	/* Set up an OSKext instance to represent the statically loaded binary. */
-	OSKext *fakeKext = new OSKext;
-	assert(fakeKext);
-	assert(load_address != 0);
-
-	/*
-	 * The start address is always a slid address whereas the last VA returned
-	 * by getlastaddr() might be unslid depending on the Mach-O. If the address
-	 * coming from the Mach-O is unslid, then unslide the start address before
-	 * computing the length of the executable.
-	 */
-	size_t binaryLength = getlastaddr((kernel_mach_header_t*)load_address);
-	binaryLength -= (macho_is_unslid) ? ml_static_unslide(load_address) : load_address;
-	assert(binaryLength <= UINT_MAX);
-
-	/**
-	 * The load address is always slid. That value will be unslid before being
-	 * exposed to userspace.
-	 */
-	OSSharedPtr<OSData> executable = OSData::withBytesNoCopy(
-		(void*)load_address, (unsigned int)binaryLength);
-	assert(executable);
-
-	fakeKext->loadTag = sNextLoadTag++;
-	fakeKext->bundleID = OSSymbol::withCString(kmod_info->name);
-
-	fakeKext->version = OSKextParseVersionString(osrelease);
-	fakeKext->compatibleVersion = fakeKext->version;
-	fakeKext->linkedExecutable = os::move(executable);
-	fakeKext->interfaceUUID = fakeKext->copyUUID();
-
-	fakeKext->flags.hasAllDependencies = 1;
-	fakeKext->flags.kernelComponent = 1;
-	fakeKext->flags.prelinked = 0;
-	fakeKext->flags.loaded = 1;
-	fakeKext->flags.started = 1;
-	fakeKext->flags.CPPInitialized = 0;
-	fakeKext->flags.jettisonLinkeditSeg = 0;
-	fakeKext->flags.unslidMachO = macho_is_unslid;
-
-#if CONFIG_SPTM
-	if (set_custom_path) {
-		/* Only SPTM/TXM should have custom paths to their executables set. */
-		assert((kmod_info->id == kOSKextSPTMLoadTag) ||
-		    (kmod_info->id == kOSKextTXMLoadTag));
-
-		/* All SPTM/TXM binaries are placed into the same path on internal systems. */
-		fakeKext->path = OSString::withCStringNoCopy("/usr/appleinternal/standalone/platform");
-
-		/**
-		 * Each SPTM/TXM Mach-O should contain a __TEXT,__binname section which contains
-		 * a character array representing the name of the Mach-O executable.
-		 */
-		kernel_section_t *binname_sect =
-		    getsectbynamefromheader((kernel_mach_header_t*)load_address, "__TEXT", "__binname");
-
-		if (binname_sect != NULL) {
-			const char *binname = (const char *)ml_static_slide(binname_sect->addr);
-			fakeKext->executableRelPath = OSString::withCStringNoCopy(binname);
-		} else {
-			fakeKext->executableRelPath = OSString::withCStringNoCopy(executable_fallback_name);
-		}
-	}
-#endif /* CONFIG_SPTM */
-
-	fakeKext->kmod_info = kmod_info;
-	strlcpy(kmod_info->version, osrelease,
-	    sizeof(kmod_info->version));
-	kmod_info->size = binaryLength;
-	assert(kmod_info->id == fakeKext->loadTag);
-
-	/*
-	 * Con up an info dict, so we don't have to have special-case checking all
-	 * over.
-	 */
-	fakeKext->infoDict = OSDictionary::withCapacity(5);
-	assert(fakeKext->infoDict);
-	bool setResult = fakeKext->infoDict->setObject(kCFBundleIdentifierKey,
-	    fakeKext->bundleID.get());
-	assert(setResult);
-	setResult = fakeKext->infoDict->setObject(kOSKernelResourceKey,
-	    kOSBooleanTrue);
-	assert(setResult);
-
-	{
-		OSSharedPtr<OSString> scratchString(OSString::withCStringNoCopy(osrelease));
-		assert(scratchString);
-		setResult = fakeKext->infoDict->setObject(kCFBundleVersionKey,
-		    scratchString.get());
-		assert(setResult);
-	}
-
-	{
-		OSSharedPtr<OSString> scratchString(OSString::withCStringNoCopy(bundle_name));
-		assert(scratchString);
-		setResult = fakeKext->infoDict->setObject(kCFBundleNameKey,
-		    scratchString.get());
-		assert(setResult);
-	}
-
-	return fakeKext;
-}
-
+/*********************************************************************
+*********************************************************************/
 /* static */
 void
 OSKext::initialize(void)
 {
-	OSSharedPtr<OSData>     kernelExecutable   = NULL;// do not release
-	IORegistryEntry * registryRoot       = NULL;// do not release
-	OSSharedPtr<OSNumber> kernelCPUType;
-	OSSharedPtr<OSNumber> kernelCPUSubtype;
-	OSKextLogSpec     bootLogFilter      = kOSKextLogSilentFilter;
-	bool              setResult          = false;
-	uint64_t        * timestamp          = NULL;
-	__unused char     bootArgBuffer[16];// for PE_parse_boot_argn w/strings
-
-	/* This must be the first thing allocated. Everything else grabs this lock.
-	 */
-	sKextLock = IORecursiveLockAlloc();
-	sKextInnerLock = IORecursiveLockAlloc();
-	sKextSummariesLock = IOLockAlloc();
-	sKextLoggingLock = IOLockAlloc();
-	assert(sKextLock);
-	assert(sKextInnerLock);
-	assert(sKextSummariesLock);
-	assert(sKextLoggingLock);
-
-	sKextsByID = OSDictionary::withCapacity(kOSKextTypicalLoadCount);
-	sLoadedKexts = OSArray::withCapacity(kOSKextTypicalLoadCount);
-	sLoadedDriverKitKexts = OSArray::withCapacity(kOSKextTypicalLoadCount);
-	sUnloadedPrelinkedKexts = OSArray::withCapacity(kOSKextTypicalLoadCount / 10);
-	sKernelRequests = OSArray::withCapacity(0);
-	sPostedKextLoadIdentifiers = OSSet::withCapacity(0);
-	sAllKextLoadIdentifiers = OSSet::withCapacity(kOSKextTypicalLoadCount);
-	sRequestCallbackRecords = OSArray::withCapacity(0);
-	sDriverKitToUpgradeByID = OSDictionary::withCapacity(kOSKextTypicalUpgradeCount);
-
-	assert(sKextsByID && sLoadedKexts && sLoadedDriverKitKexts && sKernelRequests &&
-	    sPostedKextLoadIdentifiers && sAllKextLoadIdentifiers &&
-	    sRequestCallbackRecords && sUnloadedPrelinkedKexts && sDriverKitToUpgradeByID);
-
-	/* Read the log flag boot-args and set the log flags.
-	 */
-	if (PE_parse_boot_argn("kextlog", &bootLogFilter, sizeof(bootLogFilter))) {
-		sBootArgLogFilterFound = true;
-		sKernelLogFilter = bootLogFilter;
-		// log this if any flags are set
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogBasicLevel |
-		    kOSKextLogFlagsMask,
-		    "Kernel kext log filter 0x%x per kextlog boot arg.",
-		    (unsigned)sKernelLogFilter);
-	}
-
-#if !defined(__arm__) && !defined(__arm64__)
-	/*
-	 * On our ARM targets, the kernelcache/boot kernel collection contains
-	 * the set of kexts required to boot, as specified by KCB.  Safeboot is
-	 * either unsupported, or is supported by the bootloader only loading
-	 * the boot kernel collection; as a result OSKext has no role to play
-	 * in safeboot policy on ARM.
-	 */
-	sSafeBoot = PE_parse_boot_argn("-x", bootArgBuffer,
-	    sizeof(bootArgBuffer)) ? true : false;
-#endif /* defined(__arm__) && defined(__arm64__) */
-
-	if (sSafeBoot) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogWarningLevel |
-		    kOSKextLogGeneralFlag,
-		    "SAFE BOOT DETECTED - "
-		    "only valid OSBundleRequired kexts will be loaded.");
-	}
-
-	PE_parse_boot_argn("keepsyms", &sKeepSymbols, sizeof(sKeepSymbols));
-#if CONFIG_DTRACE
-	if (dtrace_keep_kernel_symbols()) {
-		sKeepSymbols = true;
-	}
-#endif /* CONFIG_DTRACE */
-#if KASAN_DYNAMIC_DENYLIST
-	/* needed for function lookup */
-	sKeepSymbols = true;
-#endif /* KASAN_DYNAMIC_DENYLIST */
-
-	/*
-	 * Should we panic when the SystemKC is not linked against the
-	 * BootKC that was loaded by the booter? By default: yes, if the
-	 * "-nokcmismatchpanic" boot-arg is passed, then we _don't_ panic
-	 * on mis-match and instead just print an error and continue.
-	 */
-	sPanicOnKCMismatch = PE_parse_boot_argn("-nokcmismatchpanic", bootArgBuffer,
-	    sizeof(bootArgBuffer)) ? false : true;
-
-	/* Set up an OSKext instance to represent the kernel itself. */
-	sKernelKext = allocAndInitFakeKext(&g_kernel_kmod_info);
-	assert(sKernelKext);
-
-#if CONFIG_SPTM
-	/* Set up OSKext instances to represent the SPTM/TXM. */
-	OSKext *SPTMKext = allocAndInitFakeKext(&g_sptm_kmod_info);
-	OSKext *TXMKext = allocAndInitFakeKext(&g_txm_kmod_info);
+    OSData          * kernelExecutable   = NULL;  // do not release
+    u_char          * kernelStart        = NULL;  // do not free
+    size_t            kernelLength       = 0;
+    OSString        * scratchString      = NULL;  // must release
+    IORegistryEntry * registryRoot       = NULL;  // do not release
+    OSNumber        * kernelCPUType      = NULL;  // must release
+    OSNumber        * kernelCPUSubtype   = NULL;  // must release
+    OSKextLogSpec     bootLogFilter      = kOSKextLogSilentFilter;
+    bool              setResult          = false;
+    uint64_t        * timestamp          = 0;
+    char              bootArgBuffer[16];  // for PE_parse_boot_argn w/strings
+
+   /* This must be the first thing allocated. Everything else grabs this lock.
+    */
+    sKextLock = IORecursiveLockAlloc();
+    sKextInnerLock = IORecursiveLockAlloc();
+    sKextSummariesLock = IOLockAlloc();
+    sKextLoggingLock = IOLockAlloc();
+    assert(sKextLock);
+    assert(sKextInnerLock);
+    assert(sKextSummariesLock);
+    assert(sKextLoggingLock);
+
+    sKextsByID = OSDictionary::withCapacity(kOSKextTypicalLoadCount);
+    sLoadedKexts = OSArray::withCapacity(kOSKextTypicalLoadCount);
+    sUnloadedPrelinkedKexts = OSArray::withCapacity(kOSKextTypicalLoadCount / 10);
+    sKernelRequests = OSArray::withCapacity(0);
+    sPostedKextLoadIdentifiers = OSSet::withCapacity(0);
+    sAllKextLoadIdentifiers = OSSet::withCapacity(kOSKextTypicalLoadCount);
+    sRequestCallbackRecords = OSArray::withCapacity(0);
+    assert(sKextsByID && sLoadedKexts && sKernelRequests &&
+        sPostedKextLoadIdentifiers && sAllKextLoadIdentifiers &&
+        sRequestCallbackRecords && sUnloadedPrelinkedKexts);
+
+   /* Read the log flag boot-args and set the log flags.
+    */
+    if (PE_parse_boot_argn("kextlog", &bootLogFilter, sizeof(bootLogFilter))) {
+        sBootArgLogFilterFound = true;
+        sKernelLogFilter = bootLogFilter;
+        // log this if any flags are set
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogBasicLevel |
+            kOSKextLogFlagsMask,
+            "Kernel kext log filter 0x%x per kextlog boot arg.",
+            (unsigned)sKernelLogFilter);
+    }
+
+    sSafeBoot = PE_parse_boot_argn("-x", bootArgBuffer,
+        sizeof(bootArgBuffer)) ? true : false;
+
+    if (sSafeBoot) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogWarningLevel |
+            kOSKextLogGeneralFlag,
+            "SAFE BOOT DETECTED - "
+            "only valid OSBundleRequired kexts will be loaded.");
+    }
+
+    PE_parse_boot_argn("keepsyms", &sKeepSymbols, sizeof(sKeepSymbols));
+
+   /* Set up an OSKext instance to represent the kernel itself.
+    */
+    sKernelKext = new OSKext;
+    assert(sKernelKext);
+
+    kernelStart = (u_char *)&_mh_execute_header;
+    kernelLength = getlastaddr() - (vm_offset_t)kernelStart;
+    kernelExecutable = OSData::withBytesNoCopy(
+        kernelStart, kernelLength);
+    assert(kernelExecutable);
+
+#if KASLR_KEXT_DEBUG 
+    IOLog("kaslr: kernel start 0x%lx end 0x%lx length %lu \n", 
+          (unsigned long)kernelStart, 
+          (unsigned long)getlastaddr(),
+          kernelLength);
 #endif
 
-	/* Add the kernel kext to the bookkeeping dictionaries. Note that
-	 * the kernel kext doesn't have a kmod_info struct. copyInfo()
-	 * gathers info from other places anyhow.
-	 */
-	setResult = sKextsByID->setObject(sKernelKext->bundleID.get(), sKernelKext);
-	assert(setResult);
-	setResult = sLoadedKexts->setObject(sKernelKext);
-	assert(setResult);
-
-#if CONFIG_SPTM
-	setResult = sKextsByID->setObject(SPTMKext->bundleID.get(), SPTMKext);
-	assert(setResult);
-	setResult = sLoadedKexts->setObject(SPTMKext);
-	assert(setResult);
-
-	setResult = sKextsByID->setObject(TXMKext->bundleID.get(), TXMKext);
-	assert(setResult);
-	setResult = sLoadedKexts->setObject(TXMKext);
-	assert(setResult);
-#endif /* CONFIG_SPTM */
-
-	// XXX: better way with OSSharedPtr?
-	// sKernelKext remains a valid pointer even after the decref
-	sKernelKext->release();
-#if CONFIG_SPTM
-	SPTMKext->release();
-	TXMKext->release();
-#endif /* CONFIG_SPTM */
-
-	registryRoot = IORegistryEntry::getRegistryRoot();
-	kernelCPUType = OSNumber::withNumber(
-		(long long unsigned int)_mh_execute_header.cputype,
-		8 * sizeof(_mh_execute_header.cputype));
-	kernelCPUSubtype = OSNumber::withNumber(
-		(long long unsigned int)_mh_execute_header.cpusubtype,
-		8 * sizeof(_mh_execute_header.cpusubtype));
-	assert(registryRoot && kernelCPUSubtype && kernelCPUType);
-
-	registryRoot->setProperty(kOSKernelCPUTypeKey, kernelCPUType.get());
-	registryRoot->setProperty(kOSKernelCPUSubtypeKey, kernelCPUSubtype.get());
-
-	gBuiltinKmodsSectionInfo = getsectbyname(kPrelinkInfoSegment, kBuiltinInfoSection);
-	if (gBuiltinKmodsSectionInfo) {
-		uint32_t count;
-
-		assert(gBuiltinKmodsSectionInfo->addr);
-		assert(gBuiltinKmodsSectionInfo->size);
-		assert(gBuiltinKmodsSectionInfo->size / sizeof(kmod_info_t *) <= UINT_MAX);
-		gBuiltinKmodsCount = (unsigned int)(gBuiltinKmodsSectionInfo->size / sizeof(kmod_info_t *));
-
-		gBuiltinKmodsSectionStart = getsectbyname(kPrelinkInfoSegment, kBuiltinStartSection);
-		assert(gBuiltinKmodsSectionStart);
-		assert(gBuiltinKmodsSectionStart->addr);
-		assert(gBuiltinKmodsSectionStart->size);
-		assert(gBuiltinKmodsSectionStart->size / sizeof(uintptr_t) <= UINT_MAX);
-		count = (unsigned int)(gBuiltinKmodsSectionStart->size / sizeof(uintptr_t));
-		// one extra pointer for the end of last kmod
-		assert(count == (gBuiltinKmodsCount + 1));
-
-		vm_kernel_builtinkmod_text     = ((uintptr_t *)gBuiltinKmodsSectionStart->addr)[0];
-		vm_kernel_builtinkmod_text_end = ((uintptr_t *)gBuiltinKmodsSectionStart->addr)[count - 1];
-	}
-
-	// Don't track this object -- it's never released
-	gIOSurfaceIdentifier = OSSymbol::withCStringNoCopy("com.apple.iokit.IOSurface").detach();
-
-	timestamp = __OSAbsoluteTimePtr(&last_loaded_timestamp);
-	*timestamp = 0;
-	timestamp = __OSAbsoluteTimePtr(&last_unloaded_timestamp);
-	*timestamp = 0;
-	timestamp = __OSAbsoluteTimePtr(&sLastWakeTime);
-	*timestamp = 0;
-
-	OSKextLog(/* kext */ NULL,
-	    kOSKextLogProgressLevel |
-	    kOSKextLogGeneralFlag,
-	    "Kext system initialized.");
-
-	notifyKextLoadObservers(sKernelKext, sKernelKext->kmod_info);
-#if CONFIG_SPTM
-	notifyKextLoadObservers(SPTMKext, SPTMKext->kmod_info);
-	notifyKextLoadObservers(TXMKext, TXMKext->kmod_info);
-#endif
-
-	return;
-}
-
-/*********************************************************************
-* This is expected to be called exactly once, from exactly one thread
-* context, during kernel bootstrap.
+    sKernelKext->loadTag = sNextLoadTag++;  // the kernel is load tag 0
+    sKernelKext->bundleID = OSSymbol::withCString(kOSKextKernelIdentifier);
+    
+    sKernelKext->version = OSKextParseVersionString(osrelease);
+    sKernelKext->compatibleVersion = sKernelKext->version;
+    sKernelKext->linkedExecutable = kernelExecutable;
+    
+    sKernelKext->flags.hasAllDependencies = 1;
+    sKernelKext->flags.kernelComponent = 1;
+    sKernelKext->flags.prelinked = 0;
+    sKernelKext->flags.loaded = 1;
+    sKernelKext->flags.started = 1;
+    sKernelKext->flags.CPPInitialized = 0;
+    sKernelKext->flags.jettisonLinkeditSeg = 0;
+
+    sKernelKext->kmod_info = &g_kernel_kmod_info;
+    strlcpy(g_kernel_kmod_info.version, osrelease,
+        sizeof(g_kernel_kmod_info.version));
+    g_kernel_kmod_info.size = kernelLength;
+    g_kernel_kmod_info.id = sKernelKext->loadTag;
+
+   /* Cons up an info dict, so we don't have to have special-case
+    * checking all over.
+    */
+    sKernelKext->infoDict = OSDictionary::withCapacity(5);
+    assert(sKernelKext->infoDict);
+    setResult = sKernelKext->infoDict->setObject(kCFBundleIdentifierKey,
+        sKernelKext->bundleID);
+    assert(setResult);
+    setResult = sKernelKext->infoDict->setObject(kOSKernelResourceKey,
+        kOSBooleanTrue);
+    assert(setResult);
+        
+    scratchString = OSString::withCStringNoCopy(osrelease);
+    assert(scratchString);
+    setResult = sKernelKext->infoDict->setObject(kCFBundleVersionKey,
+        scratchString);
+    assert(setResult);
+    OSSafeReleaseNULL(scratchString);
+
+    scratchString = OSString::withCStringNoCopy("mach_kernel");
+    assert(scratchString);
+    setResult = sKernelKext->infoDict->setObject(kCFBundleNameKey,
+        scratchString);
+    assert(setResult);
+    OSSafeReleaseNULL(scratchString);
+
+   /* Add the kernel kext to the bookkeeping dictionaries. Note that
+    * the kernel kext doesn't have a kmod_info struct. copyInfo()
+    * gathers info from other places anyhow.
+    */
+    setResult = sKextsByID->setObject(sKernelKext->bundleID, sKernelKext);
+    assert(setResult);
+    setResult = sLoadedKexts->setObject(sKernelKext);
+    assert(setResult);
+    sKernelKext->release();
+
+    registryRoot = IORegistryEntry::getRegistryRoot();
+    kernelCPUType = OSNumber::withNumber(
+        (long long unsigned int)_mh_execute_header.cputype,
+        8 * sizeof(_mh_execute_header.cputype));
+    kernelCPUSubtype = OSNumber::withNumber(
+        (long long unsigned int)_mh_execute_header.cpusubtype,
+        8 * sizeof(_mh_execute_header.cpusubtype));
+    assert(registryRoot && kernelCPUSubtype && kernelCPUType);
+    
+    registryRoot->setProperty(kOSKernelCPUTypeKey, kernelCPUType);
+    registryRoot->setProperty(kOSKernelCPUSubtypeKey, kernelCPUSubtype);
+
+    OSSafeRelease(kernelCPUType);
+    OSSafeRelease(kernelCPUSubtype);
+
+    timestamp = __OSAbsoluteTimePtr(&last_loaded_timestamp);
+    *timestamp = 0;
+    timestamp = __OSAbsoluteTimePtr(&last_unloaded_timestamp);
+    *timestamp = 0;
+    timestamp = __OSAbsoluteTimePtr(&sLastWakeTime);
+    *timestamp = 0;
+
+    OSKextLog(/* kext */ NULL,
+        kOSKextLogProgressLevel |
+        kOSKextLogGeneralFlag,
+        "Kext system initialized.");
+
+    notifyKextLoadObservers(sKernelKext, sKernelKext->kmod_info);
+
+    return;
+}
+
+/*********************************************************************
+* This could be in OSKextLib.cpp but we need to hold a lock
+* while removing all the segments and sKextLock will do.
 *********************************************************************/
 /* static */
 OSReturn
 OSKext::removeKextBootstrap(void)
 {
-	OSReturn                   result                = kOSReturnError;
-
-	const char               * dt_kernel_header_name = "Kernel-__HEADER";
-	const char               * dt_kernel_symtab_name = "Kernel-__SYMTAB";
-	kernel_mach_header_t     * dt_mach_header        = NULL;
-	int                        dt_mach_header_size   = 0;
-	struct symtab_command    * dt_symtab             = NULL;
-	int                        dt_symtab_size        = 0;
-	int                        dt_result             = 0;
-
-	kernel_segment_command_t * seg_kld               = NULL;
-	kernel_segment_command_t * seg_klddata           = NULL;
-	kernel_segment_command_t * seg_linkedit          = NULL;
-
-	const char __unused      * dt_segment_name       = NULL;
-	void       __unused      * segment_paddress      = NULL;
-	int        __unused        segment_size          = 0;
-
-	OSKextLog(/* kext */ NULL,
-	    kOSKextLogProgressLevel |
-	    kOSKextLogGeneralFlag,
-	    "Jettisoning kext bootstrap segments.");
-
-	/*
-	 * keep the linkedit segment around when booted from a new MH_FILESET
-	 * KC because all the kexts shared a linkedit segment.
-	 */
-	kc_format_t kc_format;
-	if (!PE_get_primary_kc_format(&kc_format)) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogGeneralFlag,
-		    "Unable to determine primary KC format");
-	}
-
-	/*****
-	 * Dispose of unnecessary stuff that the booter didn't need to load.
-	 */
-	dt_result = IODTGetLoaderInfo(dt_kernel_header_name,
-	    (void **)&dt_mach_header, &dt_mach_header_size);
-	if (dt_result == 0 && dt_mach_header) {
-		IODTFreeLoaderInfo(dt_kernel_header_name, (void *)dt_mach_header,
-		    round_page_32(dt_mach_header_size));
-	}
-	dt_result = IODTGetLoaderInfo(dt_kernel_symtab_name,
-	    (void **)&dt_symtab, &dt_symtab_size);
-	if (dt_result == 0 && dt_symtab) {
-		IODTFreeLoaderInfo(dt_kernel_symtab_name, (void *)dt_symtab,
-		    round_page_32(dt_symtab_size));
-	}
-
-	/*****
-	 * KLD & KLDDATA bootstrap segments.
-	 */
-	// xxx - should rename KLD segment
-	seg_kld = getsegbyname("__KLD");
-	seg_klddata = getsegbyname("__KLDDATA");
-	if (seg_klddata) {
-		// __mod_term_func is part of __KLDDATA
-		OSRuntimeUnloadCPPForSegment(seg_klddata);
-	}
-
-#if __arm__ || __arm64__
-	/* Free the memory that was set up by iBoot.
-	 */
-#if !defined(KERNEL_INTEGRITY_KTRR) && !defined(KERNEL_INTEGRITY_CTRR) && !defined(KERNEL_INTEGRITY_PV_CTRR)
-	/* We cannot free the KLD segment with CTRR enabled as it contains text and
-	 * is covered by the contiguous rorgn.
-	 */
-	dt_segment_name = "Kernel-__KLD";
-	if (0 == IODTGetLoaderInfo(dt_segment_name, &segment_paddress, &segment_size)) {
-		IODTFreeLoaderInfo(dt_segment_name, (void *)segment_paddress,
-		    (int)segment_size); // calls ml_static_mfree
-	} else if (seg_kld && seg_kld->vmaddr && seg_kld->vmsize) {
-		/* With fileset KCs, the Kernel KLD segment is not recorded in the DT. */
-#if !CONFIG_SPTM
-		ml_static_mfree(ml_static_ptovirt(seg_kld->vmaddr - gVirtBase + gPhysBase),
-		    seg_kld->vmsize);
-#else
-		ml_static_mfree(seg_kld->vmaddr, seg_kld->vmsize);
-#endif
-	}
-#endif
-	dt_segment_name = "Kernel-__KLDDATA";
-	if (0 == IODTGetLoaderInfo(dt_segment_name, &segment_paddress, &segment_size)) {
-		IODTFreeLoaderInfo(dt_segment_name, (void *)segment_paddress,
-		    (int)segment_size);  // calls ml_static_mfree
-	} else if (seg_klddata && seg_klddata->vmaddr && seg_klddata->vmsize) {
-		/* With fileset KCs, the Kernel KLDDATA segment is not recorded in the DT. */
-#if !CONFIG_SPTM
-		ml_static_mfree(ml_static_ptovirt(seg_klddata->vmaddr - gVirtBase + gPhysBase),
-		    seg_klddata->vmsize);
-#else
-		ml_static_mfree(seg_klddata->vmaddr, seg_klddata->vmsize);
-#endif
-	}
-#elif __i386__ || __x86_64__
-	/* On x86, use the mapping data from the segment load command to
-	 * unload KLD & KLDDATA directly.
-	 * This may invalidate any assumptions about  "avail_start"
-	 * defining the lower bound for valid physical addresses.
-	 */
-	if (seg_kld && seg_kld->vmaddr && seg_kld->vmsize) {
-		bzero((void *)seg_kld->vmaddr, seg_kld->vmsize);
-		ml_static_mfree(seg_kld->vmaddr, seg_kld->vmsize);
-	}
-	if (seg_klddata && seg_klddata->vmaddr && seg_klddata->vmsize) {
-		bzero((void *)seg_klddata->vmaddr, seg_klddata->vmsize);
-		ml_static_mfree(seg_klddata->vmaddr, seg_klddata->vmsize);
-	}
+    OSReturn                   result                = kOSReturnError;
+    
+    static bool                alreadyDone           = false;
+
+    const char               * dt_kernel_header_name = "Kernel-__HEADER";
+    const char               * dt_kernel_symtab_name = "Kernel-__SYMTAB";
+    kernel_mach_header_t     * dt_mach_header        = NULL;
+    int                        dt_mach_header_size   = 0;
+    struct symtab_command    * dt_symtab             = NULL;
+    int                        dt_symtab_size        = 0;
+    int                        dt_result             = 0;
+
+    kernel_segment_command_t * seg_to_remove         = NULL;
+
+
+   /* This must be the very first thing done by this function.
+    */
+    IORecursiveLockLock(sKextLock);
+
+   /* If we already did this, it's a success.
+    */
+    if (alreadyDone) {
+        result = kOSReturnSuccess;
+        goto finish;
+    }
+
+    OSKextLog(/* kext */ NULL,
+        kOSKextLogProgressLevel |
+        kOSKextLogGeneralFlag,
+        "Jettisoning kext bootstrap segments.");
+
+   /*****
+    * Dispose of unnecessary stuff that the booter didn't need to load.
+    */
+    dt_result = IODTGetLoaderInfo(dt_kernel_header_name,
+        (void **)&dt_mach_header, &dt_mach_header_size);
+    if (dt_result == 0 && dt_mach_header) {
+        IODTFreeLoaderInfo(dt_kernel_header_name, (void *)dt_mach_header,
+            round_page_32(dt_mach_header_size));
+    }
+    dt_result = IODTGetLoaderInfo(dt_kernel_symtab_name,
+        (void **)&dt_symtab, &dt_symtab_size);
+    if (dt_result == 0 && dt_symtab) {
+        IODTFreeLoaderInfo(dt_kernel_symtab_name, (void *)dt_symtab,
+            round_page_32(dt_symtab_size));
+    }
+
+   /*****
+    * KLD bootstrap segment.
+    */
+    // xxx - should rename KLD segment
+    seg_to_remove = getsegbyname("__KLD");
+    if (seg_to_remove) {
+        OSRuntimeUnloadCPPForSegment(seg_to_remove);
+    }
+
+#if   __i386__ || __x86_64__
+   /* On x86, use the mapping data from the segment load command to
+    * unload KLD directly.
+    * This may invalidate any assumptions about  "avail_start"
+    * defining the lower bound for valid physical addresses.
+    */
+    if (seg_to_remove && seg_to_remove->vmaddr && seg_to_remove->vmsize) {
+        // 04/18/11 - gab: <rdar://problem/9236163>
+        // overwrite memory occupied by KLD segment with random data before
+        // releasing it.
+        read_frandom((void *) seg_to_remove->vmaddr, seg_to_remove->vmsize);
+        ml_static_mfree(seg_to_remove->vmaddr, seg_to_remove->vmsize);
+    }
 #else
 #error arch
 #endif
 
-	/*****
-	 * Prelinked kernel's symtab (if there is one).
-	 */
-	if (kc_format != KCFormatFileset) {
-		kernel_section_t * sect;
-		sect = getsectbyname("__PRELINK", "__symtab");
-		if (sect && sect->addr && sect->size) {
-			ml_static_mfree(sect->addr, sect->size);
-		}
-	}
-
-	seg_linkedit = (kernel_segment_command_t *)getsegbyname("__LINKEDIT");
-
-	/* kxld always needs the kernel's __LINKEDIT segment, but we can make it
-	 * pageable, unless keepsyms is set.  To do that, we have to copy it from
-	 * its booter-allocated memory, free the booter memory, reallocate proper
-	 * managed memory, then copy the segment back in.
-	 *
-	 * NOTE: This optimization is not valid for fileset KCs because each
-	 * fileset entry (kext or xnu) in an MH_FILESET has a LINKEDIT segment
-	 * that points to one fileset-global LINKEDIT segment. This
-	 * optimization is also only valid for platforms that support vm
-	 * mapped kexts or mapped kext collections (pageable KCs)
-	 */
-#if VM_MAPPED_KEXTS
-	if (!sKeepSymbols && kc_format != KCFormatFileset) {
-		kern_return_t mem_result;
-		void *seg_copy = NULL;
-		void *seg_data = NULL;
-		vm_map_offset_t seg_offset = 0;
-		vm_map_offset_t seg_copy_offset = 0;
-		vm_map_size_t seg_length = 0;
-
-		seg_data = (void *) seg_linkedit->vmaddr;
-		seg_offset = (vm_map_offset_t) seg_linkedit->vmaddr;
-		seg_length = (vm_map_size_t) seg_linkedit->vmsize;
-
-		/* Allocate space for the LINKEDIT copy.
-		 */
-		mem_result = kmem_alloc(kernel_map, (vm_offset_t *) &seg_copy,
-		    seg_length, KMA_ZERO, VM_KERN_MEMORY_KEXT);
-		if (mem_result != KERN_SUCCESS) {
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogGeneralFlag | kOSKextLogArchiveFlag,
-			    "Can't copy __LINKEDIT segment for VM reassign.");
-			return result;
-		}
-		seg_copy_offset = (vm_map_offset_t) seg_copy;
-
-		/* Copy it out.
-		 */
-		memcpy(seg_copy, seg_data, seg_length);
-
-		/* Dump the booter memory.
-		 */
-		ml_static_mfree(seg_offset, seg_length);
-
-		/* Set up the VM region.
-		 */
-		mem_result = mach_vm_map_kernel(
-			kernel_map,
-			&seg_offset,
-			seg_length, /* mask */ 0,
-			VM_MAP_KERNEL_FLAGS_FIXED(.vmf_overwrite = true),
-			(ipc_port_t)NULL,
-			(vm_object_offset_t) 0,
-			/* copy */ FALSE,
-			/* cur_protection */ VM_PROT_READ | VM_PROT_WRITE,
-			/* max_protection */ VM_PROT_ALL,
-			/* inheritance */ VM_INHERIT_DEFAULT);
-		if ((mem_result != KERN_SUCCESS) ||
-		    (seg_offset != (vm_map_offset_t) seg_data)) {
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogGeneralFlag | kOSKextLogArchiveFlag,
-			    "Can't create __LINKEDIT VM entry at %p, length 0x%llx (error 0x%x).",
-			    seg_data, seg_length, mem_result);
-			return result;
-		}
-
-		/* And copy it back.
-		 */
-		memcpy(seg_data, seg_copy, seg_length);
-
-		/* Free the copy.
-		 */
-		kmem_free(kernel_map, seg_copy_offset, seg_length);
-	} else if (!sKeepSymbols && kc_format == KCFormatFileset) {
-		/* Remove the linkedit segment of the Boot KC */
-		kernel_mach_header_t *mh = (kernel_mach_header_t *)PE_get_kc_header(KCKindPrimary);
-		OSKext::jettisonFileSetLinkeditSegment(mh);
-	}
-#else // !VM_MAPPED_KEXTS
-	/*****
-	 * Dump the LINKEDIT segment, unless keepsyms is set.
-	 */
-	if (!sKeepSymbols && kc_format != KCFormatFileset) {
-		dt_segment_name = "Kernel-__LINKEDIT";
-		if (0 == IODTGetLoaderInfo(dt_segment_name,
-		    &segment_paddress, &segment_size)) {
+    seg_to_remove = NULL;
+
+    /*****
+    * Prelinked kernel's symtab (if there is one).
+    */
+    kernel_section_t * sect;
+    sect = getsectbyname("__PRELINK", "__symtab");
+    if (sect && sect->addr && sect->size) {
+        ml_static_mfree(sect->addr, sect->size);
+    }
+
+    seg_to_remove = (kernel_segment_command_t *)getsegbyname("__LINKEDIT");
+
+    /* kxld always needs the kernel's __LINKEDIT segment, but we can make it
+     * pageable, unless keepsyms is set.  To do that, we have to copy it from
+     * its booter-allocated memory, free the booter memory, reallocate proper
+     * managed memory, then copy the segment back in.
+     */
+#if CONFIG_KXLD
+    if (!sKeepSymbols) {
+        kern_return_t mem_result;
+        void *seg_copy = NULL;
+        void *seg_data = NULL;
+        vm_map_offset_t seg_offset = 0;
+        vm_map_offset_t seg_copy_offset = 0;
+        vm_map_size_t seg_length = 0;
+
+        seg_data = (void *) seg_to_remove->vmaddr;
+        seg_offset = (vm_map_offset_t) seg_to_remove->vmaddr;
+        seg_length = (vm_map_size_t) seg_to_remove->vmsize;
+
+       /* Allocate space for the LINKEDIT copy.
+        */
+        mem_result = kmem_alloc(kernel_map, (vm_offset_t *) &seg_copy,
+            seg_length, VM_KERN_MEMORY_KEXT);
+        if (mem_result != KERN_SUCCESS) {
+            OSKextLog(/* kext */ NULL,
+                kOSKextLogErrorLevel |
+                kOSKextLogGeneralFlag | kOSKextLogArchiveFlag,
+                "Can't copy __LINKEDIT segment for VM reassign.");
+            goto finish;
+        }
+        seg_copy_offset = (vm_map_offset_t) seg_copy;
+
+       /* Copy it out.
+        */
+        memcpy(seg_copy, seg_data, seg_length);
+
+       /* Dump the booter memory.
+        */
+        ml_static_mfree(seg_offset, seg_length);
+
+       /* Set up the VM region.
+        */
+        mem_result = vm_map_enter_mem_object(
+            kernel_map,
+            &seg_offset,
+            seg_length, /* mask */ 0, 
+            VM_FLAGS_FIXED | VM_FLAGS_OVERWRITE, 
+            (ipc_port_t)NULL,
+            (vm_object_offset_t) 0,
+            /* copy */ FALSE,
+            /* cur_protection */ VM_PROT_READ | VM_PROT_WRITE,
+            /* max_protection */ VM_PROT_ALL,
+            /* inheritance */ VM_INHERIT_DEFAULT);
+        if ((mem_result != KERN_SUCCESS) || 
+            (seg_offset != (vm_map_offset_t) seg_data))
+        {
+            OSKextLog(/* kext */ NULL,
+                kOSKextLogErrorLevel |
+                kOSKextLogGeneralFlag | kOSKextLogArchiveFlag,
+                "Can't create __LINKEDIT VM entry at %p, length 0x%llx (error 0x%x).",
+                seg_data, seg_length, mem_result);
+            goto finish;
+        }
+
+       /* And copy it back.
+        */
+        memcpy(seg_data, seg_copy, seg_length);
+
+       /* Free the copy.
+        */
+        kmem_free(kernel_map, seg_copy_offset, seg_length);
+    }
+#else /* we are not CONFIG_KXLD */
+#error CONFIG_KXLD is expected for this arch
+
+    /*****
+    * Dump the LINKEDIT segment, unless keepsyms is set.
+    */
+    if (!sKeepSymbols) {
+        const char *dt_segment_name = "Kernel-__LINKEDIT";
+        if (0 == IODTGetLoaderInfo(dt_segment_name,
+            &segment_paddress, &segment_size)) {
 #ifdef SECURE_KERNEL
-			vm_offset_t vmaddr = ml_static_ptovirt((vm_offset_t)segment_paddress);
-			bzero((void*)vmaddr, segment_size);
+            vm_offset_t vmaddr = ml_static_ptovirt((vm_offset_t)segment_paddress);
+            bzero((void*)vmaddr, segment_size);
 #endif
-			IODTFreeLoaderInfo(dt_segment_name, (void *)segment_paddress,
-			    (int)segment_size);
-		}
-	} else if (!sKeepSymbols && kc_format == KCFormatFileset) {
-		/* Remove the linkedit segment of the Boot KC */
-		kernel_mach_header_t *mh = (kernel_mach_header_t *)PE_get_kc_header(KCKindPrimary);
-		OSKext::jettisonFileSetLinkeditSegment(mh);
-	} else {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogBasicLevel |
-		    kOSKextLogGeneralFlag,
-		    "keepsyms boot arg specified; keeping linkedit segment for symbols.");
-	}
-#endif // VM_MAPPED_KEXTS
-
-	result = kOSReturnSuccess;
-
-	return result;
-}
-
-#if CONFIG_KXLD
+            IODTFreeLoaderInfo(dt_segment_name, (void *)segment_paddress,
+                (int)segment_size);
+        }
+    } else {
+        OSKextLog(/* kext */ NULL,
+           kOSKextLogBasicLevel |
+           kOSKextLogGeneralFlag,
+           "keepsyms boot arg specified; keeping linkedit segment for symbols.");
+    }
+#endif /* CONFIG_KXLD */
+
+    seg_to_remove = NULL;
+
+    alreadyDone = true;
+    result = kOSReturnSuccess;
+
+finish:
+
+   /* This must be the very last thing done before returning.
+    */
+    IORecursiveLockUnlock(sKextLock);
+
+    return result;
+}
+
 /*********************************************************************
 *********************************************************************/
 void
 OSKext::flushNonloadedKexts(
-	Boolean flushPrelinkedKexts)
-{
-	OSSharedPtr<OSSet>                keepKexts;
-
-	/* TODO: make this more efficient with MH_FILESET kexts */
-
-	// Do not unload prelinked kexts on arm because the kernelcache is not
-	// structured in a way that allows them to be unmapped
-#if !defined(__x86_64__)
-	flushPrelinkedKexts = false;
-#endif /* defined(__x86_64__) */
-
-	IORecursiveLockLock(sKextLock);
-
-	OSKextLog(/* kext */ NULL,
-	    kOSKextLogProgressLevel |
-	    kOSKextLogKextBookkeepingFlag,
-	    "Flushing nonloaded kexts and other unused data.");
-
-	OSKext::considerDestroyingLinkContext();
-
-	/* If we aren't flushing unused prelinked kexts, we have to put them
-	 * aside while we flush everything else so make a container for them.
-	 */
-	keepKexts = OSSet::withCapacity(16);
-	if (!keepKexts) {
-		goto finish;
-	}
-
-	/* Set aside prelinked kexts (in-use or not) and break
-	 * any lingering inter-kext references for nonloaded kexts
-	 * so they have min. retain counts.
-	 */
-	{
-		sKextsByID->iterateObjects(^bool (const OSSymbol * thisID __unused, OSObject * obj) {
-			OSKext * thisKext = OSDynamicCast(OSKext, obj);
-			if (!thisKext) {
-			        return false;
-			}
-			if (!flushPrelinkedKexts && thisKext->isPrelinked()) {
-			        keepKexts->setObject(thisKext);
-			} else if (!thisKext->declaresExecutable()) {
-			        /*
-			         * Don't unload codeless kexts, because they never appear in the loadedKexts array.
-			         * Requesting one from the IOKit daemon will load it and then immediately remove it by calling
-			         * flushNonloadedKexts().
-			         * And adding one to loadedKexts breaks code assuming they have kmod_info etc.
-			         */
-			        keepKexts->setObject(thisKext);
-			} else if (thisKext->isInFileset()) {
-			        /* keep all kexts in the new MH_FILESET KC */
-			        keepKexts->setObject(thisKext);
-			}
-
-			thisKext->flushDependencies(/* forceIfLoaded */ false);
-			return false;
-		});
-	}
-	/* Dump all the kexts in the ID dictionary; we'll repopulate it shortly.
-	 */
-	sKextsByID->flushCollection();
-
-	/* Now put the loaded kexts back into the ID dictionary.
-	 */
-	sLoadedKexts->iterateObjects(^bool (OSObject * obj) {
-		OSKext * thisKext = OSDynamicCast(OSKext, obj);
-		if (!thisKext) {
-		        return false;
-		}
-		sKextsByID->setObject(thisKext->getIdentifierCString(), thisKext);
-		return false;
-	});
-
-	/* Finally, put back the kept kexts if we saved any.
-	 */
-	keepKexts->iterateObjects(^bool (OSObject * obj) {
-		OSKext * thisKext = OSDynamicCast(OSKext, obj);
-		if (!thisKext) {
-		        return false;
-		}
-		sKextsByID->setObject(thisKext->getIdentifierCString(), thisKext);
-		return false;
-	});
+    Boolean flushPrelinkedKexts)
+{
+    OSSet                * prelinkedKexts  = NULL;  // must release
+    OSCollectionIterator * kextIterator    = NULL;  // must release
+    OSCollectionIterator * prelinkIterator = NULL;  // must release
+    const OSSymbol       * thisID          = NULL;  // do not release
+    OSKext               * thisKext        = NULL;  // do not release
+    uint32_t               count, i;
+
+    IORecursiveLockLock(sKextLock);
+
+    OSKextLog(/* kext */ NULL,
+        kOSKextLogProgressLevel |
+        kOSKextLogKextBookkeepingFlag,
+        "Flushing nonloaded kexts and other unused data.");
+
+    OSKext::considerDestroyingLinkContext();
+
+   /* If we aren't flushing unused prelinked kexts, we have to put them
+    * aside while we flush everything else so make a container for them.
+    */
+    if (!flushPrelinkedKexts) {
+        prelinkedKexts = OSSet::withCapacity(0);
+        if (!prelinkedKexts) {
+            goto finish;
+        }
+    }
+    
+   /* Set aside prelinked kexts (in-use or not) and break
+    * any lingering inter-kext references for nonloaded kexts
+    * so they have min. retain counts.
+    */
+    kextIterator = OSCollectionIterator::withCollection(sKextsByID);
+    if (!kextIterator) {
+        goto finish;
+    }
+
+    while ((thisID = OSDynamicCast(OSSymbol, 
+            kextIterator->getNextObject()))) {
+
+        thisKext = OSDynamicCast(OSKext, sKextsByID->getObject(thisID));
+
+        if (thisKext) {
+            if (prelinkedKexts && thisKext->isPrelinked()) {
+                prelinkedKexts->setObject(thisKext);
+            }
+            thisKext->flushDependencies(/* forceIfLoaded */ false);
+        }
+    }
+
+   /* Dump all the kexts in the ID dictionary; we'll repopulate it shortly.
+    */
+    sKextsByID->flushCollection();
+
+   /* Now put the loaded kexts back into the ID dictionary.
+    */
+    count = sLoadedKexts->getCount();
+    for (i = 0; i < count; i++) {
+        thisKext = OSDynamicCast(OSKext, sLoadedKexts->getObject(i));
+        sKextsByID->setObject(thisKext->getIdentifierCString(), thisKext);
+    }
+
+   /* Finally, put back the prelinked kexts if we saved any.
+    */
+    if (prelinkedKexts) {
+        prelinkIterator = OSCollectionIterator::withCollection(prelinkedKexts);
+        if (!prelinkIterator) {
+            goto finish;
+        }
+
+        while ((thisKext = OSDynamicCast(OSKext,
+            prelinkIterator->getNextObject()))) {
+
+            sKextsByID->setObject(thisKext->getIdentifierCString(),
+                thisKext);
+        }
+    }
 
 finish:
-	IORecursiveLockUnlock(sKextLock);
-	return;
-}
-#else /* !CONFIG_KXLD */
-
-void
-OSKext::flushNonloadedKexts(
-	Boolean flushPrelinkedKexts __unused)
-{
-	IORecursiveLockLock(sKextLock);
-
-	OSKextLog(/* kext */ NULL,
-	    kOSKextLogProgressLevel |
-	    kOSKextLogKextBookkeepingFlag,
-	    "Flushing dependency info for non-loaded kexts.");
-
-	/*
-	 * In a world where we don't dynamically link kexts, they all come
-	 * from a kext collection that's either in wired memory, or
-	 * wire-on-demand. We don't need to mess around with moving kexts in
-	 * and out of the sKextsByID array - they can all just stay there.
-	 * Here we just flush the dependency list for kexts that are not
-	 * loaded.
-	 */
-	sKextsByID->iterateObjects(^bool (const OSSymbol * thisID __unused, OSObject * obj) {
-		OSKext * thisKext = OSDynamicCast(OSKext, obj);
-		if (!thisKext) {
-		        return false;
-		}
-		thisKext->flushDependencies(/* forceIfLoaded */ false);
-		return false;
-	});
-
-	IORecursiveLockUnlock(sKextLock);
-	return;
-}
-
-#endif /* CONFIG_KXLD */
+    IORecursiveLockUnlock(sKextLock);
+
+    OSSafeRelease(prelinkedKexts);
+    OSSafeRelease(kextIterator);
+    OSSafeRelease(prelinkIterator);
+
+    return;
+}
 
 /*********************************************************************
 *********************************************************************/
 /* static */
 void
-OSKext::setIOKitDaemonActive(bool active)
-{
-	IOServiceTrace(IOSERVICE_KEXTD_ALIVE, 0, 0, 0, 0);
-	IORecursiveLockLock(sKextLock);
-	sIOKitDaemonActive = active;
-	if (sKernelRequests->getCount()) {
-		OSKext::pingIOKitDaemon();
-	}
-	IORecursiveLockUnlock(sKextLock);
-
-	return;
+OSKext::setKextdActive(Boolean active)
+{
+    IORecursiveLockLock(sKextLock);
+    sKextdActive = active;
+    if (sKernelRequests->getCount()) {
+        OSKext::pingKextd();
+    }
+    IORecursiveLockUnlock(sKextLock);
+
+    return;
 }
 
 /*********************************************************************
@@ -1552,85 +1084,42 @@
 
 /* static */
 OSReturn
-OSKext::pingIOKitDaemon(void)
-{
-	OSReturn    result     = kOSReturnError;
+OSKext::pingKextd(void)
+{
+    OSReturn    result     = kOSReturnError;
 #if !NO_KEXTD
-	mach_port_t kextd_port = IPC_PORT_NULL;
-
-	if (!sIOKitDaemonActive) {
-		result = kOSKextReturnDisabled; // basically unavailable
-		goto finish;
-	}
-
-	result = host_get_kextd_port(host_priv_self(), &kextd_port);
-	if (result != KERN_SUCCESS || !IPC_PORT_VALID(kextd_port)) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogIPCFlag,
-		    "Can't get " kIOKitDaemonName " port.");
-		goto finish;
-	}
-
-	result = kextd_ping(kextd_port);
-	if (result != KERN_SUCCESS) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogIPCFlag,
-		    kIOKitDaemonName " ping failed (0x%x).", (int)result);
-		goto finish;
-	}
+    mach_port_t kextd_port = IPC_PORT_NULL;
+
+    if (!sKextdActive) {
+        result = kOSKextReturnDisabled;  // basically unavailable
+        goto finish;
+    }
+
+    result = host_get_kextd_port(host_priv_self(), &kextd_port);
+    if (result != KERN_SUCCESS || !IPC_PORT_VALID(kextd_port)) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogErrorLevel |
+            kOSKextLogIPCFlag,
+            "Can't get kextd port.");
+        goto finish;
+    }
+
+    result = kextd_ping(kextd_port);
+    if (result != KERN_SUCCESS) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogErrorLevel |
+            kOSKextLogIPCFlag,
+            "kextd ping failed (0x%x).", (int)result);
+        goto finish;
+    }
 
 finish:
-	if (IPC_PORT_VALID(kextd_port)) {
-		ipc_port_release_send(kextd_port);
-	}
+    if (IPC_PORT_VALID(kextd_port)) {
+        ipc_port_release_send(kextd_port);
+    }
 #endif
 
-	return result;
-}
-
-/*********************************************************************
-*********************************************************************/
-/* static */
-
-bool
-OSKext::driverkitEnabled(void)
-{
-	#if XNU_TARGET_OS_WATCH
-	/*
-	 * Driverkit support is available on watchOS only if the device
-	 * tree has the "supports-driverkit" property in its "/product" node
-	 */
-	DTEntry entry;
-	void const *prop = NULL;
-	unsigned int prop_size;
-
-	if (kSuccess != SecureDTLookupEntry(NULL, "/product", &entry)) {
-		return false;
-	}
-	if (kSuccess != SecureDTGetProperty(entry, "supports-driverkit", &prop, &prop_size)) {
-		return false;
-	}
-	#endif /* XNU_TARGET_OS_WATCH */
-
-	return true;
-}
-
-/*********************************************************************
-*********************************************************************/
-/* static */
-bool
-OSKext::iokitDaemonAvailable(void)
-{
-#if XNU_TARGET_OS_XR || XNU_TARGET_OS_BRIDGE
-	int notused;
-	if (PE_parse_boot_argn("-restore", &notused, sizeof(notused))) {
-		return false;
-	}
-#endif /* XNU_TARGET_OS_XR || XNU_TARGET_OS_BRIDGE */
-
-	return driverkitEnabled();
+    return result;
 }
 
 /*********************************************************************
@@ -1639,11 +1128,11 @@
 void
 OSKext::setDeferredLoadSucceeded(Boolean succeeded)
 {
-	IORecursiveLockLock(sKextLock);
-	sDeferredLoadSucceeded = succeeded;
-	IORecursiveLockUnlock(sKextLock);
-
-	return;
+    IORecursiveLockLock(sKextLock);
+    sDeferredLoadSucceeded = succeeded;
+    IORecursiveLockUnlock(sKextLock);
+
+    return;
 }
 
 /*********************************************************************
@@ -1654,113 +1143,41 @@
 OSKext::willShutdown(void)
 {
 #if !NO_KEXTD
-	OSReturn       checkResult = kOSReturnError;
+    OSReturn       checkResult = kOSReturnError;
 #endif
-	OSSharedPtr<OSDictionary> exitRequest;
-
-	IORecursiveLockLock(sKextLock);
-
-	OSKext::setLoadEnabled(false);
-	OSKext::setUnloadEnabled(false);
-	OSKext::setAutounloadsEnabled(false);
-	OSKext::setKernelRequestsEnabled(false);
-
-#if defined(__x86_64__) || defined(__i386__)
-	if (IOPMRootDomainGetWillShutdown()) {
-		OSKext::freeKCFileSetcontrol();
-	}
-#endif // (__x86_64__) || defined(__i386__)
+    OSDictionary * exitRequest = NULL;  // must release
+
+    IORecursiveLockLock(sKextLock);
+
+    OSKext::setLoadEnabled(false);
+    OSKext::setUnloadEnabled(false);
+    OSKext::setAutounloadsEnabled(false);
+    OSKext::setKernelRequestsEnabled(false);
 
 #if !NO_KEXTD
-	OSKextLog(/* kext */ NULL,
-	    kOSKextLogProgressLevel |
-	    kOSKextLogGeneralFlag,
-	    "System shutdown; requesting immediate " kIOKitDaemonName " exit.");
-
-	checkResult = _OSKextCreateRequest(kKextRequestPredicateRequestDaemonExit,
-	    exitRequest);
-	if (checkResult != kOSReturnSuccess) {
-		goto finish;
-	}
-	if (!sKernelRequests->setObject(exitRequest.get())) {
-		goto finish;
-	}
-
-	OSKext::pingIOKitDaemon();
+    OSKextLog(/* kext */ NULL,
+        kOSKextLogProgressLevel |
+        kOSKextLogGeneralFlag,
+        "System shutdown; requesting immediate kextd exit.");
+
+    checkResult = _OSKextCreateRequest(kKextRequestPredicateRequestKextdExit,
+        &exitRequest);
+    if (checkResult != kOSReturnSuccess) {
+        goto finish;
+    }
+    if (!sKernelRequests->setObject(exitRequest)) {
+        goto finish;
+    }
+
+    OSKext::pingKextd();
 
 finish:
 #endif
 
-	IORecursiveLockUnlock(sKextLock);
-	return;
-}
-
-void
-OSKext::setWillUserspaceReboot(void)
-{
-	OSKext::willShutdown();
-	IOService::setWillUserspaceReboot();
-	gIOCatalogue->terminateDriversForUserspaceReboot();
-}
-
-void
-OSKext::resetAfterUserspaceReboot(void)
-{
-	OSSharedPtr<OSArray> arr = OSArray::withCapacity(1);
-	IOService::updateConsoleUsers(arr.get(), 0, true /* after_userspace_reboot */);
-
-	IORecursiveLockLock(sKextLock);
-	gIOCatalogue->resetAfterUserspaceReboot();
-	IOService::userSpaceDidReboot();
-	OSKext::removeDaemonExitRequests();
-	OSKext::setLoadEnabled(true);
-	OSKext::setUnloadEnabled(true);
-	OSKext::setAutounloadsEnabled(true);
-	OSKext::setKernelRequestsEnabled(true);
-	sOSKextWasResetAfterUserspaceReboot = true;
-	IORecursiveLockUnlock(sKextLock);
-}
-
-extern "C" int
-OSKextIsInUserspaceReboot(void)
-{
-	return IOService::getWillUserspaceReboot();
-}
-
-extern "C" void
-OSKextResetAfterUserspaceReboot(void)
-{
-	OSKext::resetAfterUserspaceReboot();
-}
-
-/*
- * Remove daemon exit requests from sKernelRequests
- *
- * If we sent a daemon exit request during a userspace reboot and launchd
- * killed the IOKit daemon before it was able to dequeue the exit request, the
- * next time the daemon starts up it will immediately exit as it gets the old exit request.
- *
- * This removes exit requests so that this does not happen.
- */
-void
-OSKext::removeDaemonExitRequests(void)
-{
-	OSDictionary * current = NULL;
-	OSString     * predicate = NULL;
-	size_t         index     = 0;
-	OSSharedPtr<const OSSymbol> predicateKey = OSSymbol::withCString(kKextRequestPredicateKey);
-
-	while (index < sKernelRequests->getCount()) {
-		current = OSDynamicCast(OSDictionary, sKernelRequests->getObject(index));
-		if (current) {
-			predicate = OSDynamicCast(OSString, current->getObject(predicateKey.get()));
-			if (predicate && predicate->isEqualTo(kKextRequestPredicateRequestDaemonExit)) {
-				sKernelRequests->removeObject(index);
-				continue;
-			}
-		}
-		index++;
-	}
+    IORecursiveLockUnlock(sKextLock);
+
+    OSSafeRelease(exitRequest);
+    return;
 }
 
 /*********************************************************************
@@ -1769,12 +1186,12 @@
 bool
 OSKext::getLoadEnabled(void)
 {
-	bool result;
-
-	IORecursiveLockLock(sKextLock);
-	result = sLoadEnabled;
-	IORecursiveLockUnlock(sKextLock);
-	return result;
+    bool result;
+
+    IORecursiveLockLock(sKextLock);
+    result = sLoadEnabled;
+    IORecursiveLockUnlock(sKextLock);
+    return result;
 }
 
 /*********************************************************************
@@ -1783,22 +1200,22 @@
 bool
 OSKext::setLoadEnabled(bool flag)
 {
-	bool result;
-
-	IORecursiveLockLock(sKextLock);
-	result = sLoadEnabled;
-	sLoadEnabled = (flag ? true : false);
-
-	if (sLoadEnabled != result) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogBasicLevel |
-		    kOSKextLogLoadFlag,
-		    "Kext loading now %sabled.", sLoadEnabled ? "en" : "dis");
-	}
-
-	IORecursiveLockUnlock(sKextLock);
-
-	return result;
+    bool result;
+
+    IORecursiveLockLock(sKextLock);
+    result = sLoadEnabled;
+    sLoadEnabled = (flag ? true : false);
+    
+    if (sLoadEnabled != result) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogBasicLevel |
+            kOSKextLogLoadFlag,
+            "Kext loading now %sabled.", sLoadEnabled ? "en" : "dis");
+    }
+
+    IORecursiveLockUnlock(sKextLock);
+
+    return result;
 }
 
 /*********************************************************************
@@ -1807,12 +1224,12 @@
 bool
 OSKext::getUnloadEnabled(void)
 {
-	bool result;
-
-	IORecursiveLockLock(sKextLock);
-	result = sUnloadEnabled;
-	IORecursiveLockUnlock(sKextLock);
-	return result;
+    bool result;
+
+    IORecursiveLockLock(sKextLock);
+    result = sUnloadEnabled;
+    IORecursiveLockUnlock(sKextLock);
+    return result;
 }
 
 /*********************************************************************
@@ -1821,21 +1238,21 @@
 bool
 OSKext::setUnloadEnabled(bool flag)
 {
-	bool result;
-
-	IORecursiveLockLock(sKextLock);
-	result = sUnloadEnabled;
-	sUnloadEnabled = (flag ? true : false);
-	IORecursiveLockUnlock(sKextLock);
-
-	if (sUnloadEnabled != result) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogBasicLevel |
-		    kOSKextLogGeneralFlag | kOSKextLogLoadFlag,
-		    "Kext unloading now %sabled.", sUnloadEnabled ? "en" : "dis");
-	}
-
-	return result;
+    bool result;
+
+    IORecursiveLockLock(sKextLock);
+    result = sUnloadEnabled;
+    sUnloadEnabled = (flag ? true : false);
+    IORecursiveLockUnlock(sKextLock);
+    
+    if (sUnloadEnabled != result) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogBasicLevel |
+            kOSKextLogGeneralFlag | kOSKextLogLoadFlag,
+            "Kext unloading now %sabled.", sUnloadEnabled ? "en" : "dis");
+    }
+
+    return result;
 }
 
 /*********************************************************************
@@ -1845,16 +1262,12 @@
 bool
 OSKext::getAutounloadEnabled(void)
 {
-#if XNU_TARGET_OS_OSX
-	bool result;
-
-	IORecursiveLockLock(sKextInnerLock);
-	result = sAutounloadEnabled ? true : false;
-	IORecursiveLockUnlock(sKextInnerLock);
-	return result;
-#else
-	return false;
-#endif /* XNU_TARGET_OS_OSX */
+    bool result;
+
+    IORecursiveLockLock(sKextInnerLock);
+    result = sAutounloadEnabled ? true : false;
+    IORecursiveLockUnlock(sKextInnerLock);
+    return result;
 }
 
 /*********************************************************************
@@ -1864,32 +1277,27 @@
 bool
 OSKext::setAutounloadsEnabled(bool flag)
 {
-#if XNU_TARGET_OS_OSX
-	bool result;
-
-	IORecursiveLockLock(sKextInnerLock);
-
-	result = sAutounloadEnabled;
-	sAutounloadEnabled = (flag ? true : false);
-	if (!sAutounloadEnabled && sUnloadCallout) {
-		thread_call_cancel(sUnloadCallout);
-	}
-
-	if (sAutounloadEnabled != result) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogBasicLevel |
-		    kOSKextLogGeneralFlag | kOSKextLogLoadFlag,
-		    "Kext autounloading now %sabled.",
-		    sAutounloadEnabled ? "en" : "dis");
-	}
-
-	IORecursiveLockUnlock(sKextInnerLock);
-
-	return result;
-#else
-	(void)flag;
-	return false;
-#endif /* XNU_TARGET_OS_OSX */
+    bool result;
+
+    IORecursiveLockLock(sKextInnerLock);
+
+    result = sAutounloadEnabled;
+    sAutounloadEnabled = (flag ? true : false);
+    if (!sAutounloadEnabled && sUnloadCallout) {
+        thread_call_cancel(sUnloadCallout);
+    }
+    
+    if (sAutounloadEnabled != result) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogBasicLevel |
+            kOSKextLogGeneralFlag | kOSKextLogLoadFlag,
+            "Kext autounloading now %sabled.",
+            sAutounloadEnabled ? "en" : "dis");
+    }
+
+    IORecursiveLockUnlock(sKextInnerLock);
+
+    return result;
 }
 
 /*********************************************************************
@@ -1898,18 +1306,18 @@
 bool
 OSKext::setAutounloadEnabled(bool flag)
 {
-	bool result = flags.autounloadEnabled ? true : false;
-	flags.autounloadEnabled = flag ? (0 == flags.unloadUnsupported) : 0;
-
-	if (result != (flag ? true : false)) {
-		OSKextLog(this,
-		    kOSKextLogProgressLevel |
-		    kOSKextLogLoadFlag | kOSKextLogKextBookkeepingFlag,
-		    "Autounloading for kext %s now %sabled.",
-		    getIdentifierCString(),
-		    flags.autounloadEnabled ? "en" : "dis");
-	}
-	return result;
+    bool result = flags.autounloadEnabled ? true : false;
+    flags.autounloadEnabled = flag ? 1 : 0;
+    
+    if (result != (flag ? true : false)) {
+        OSKextLog(this,
+            kOSKextLogProgressLevel |
+            kOSKextLogLoadFlag | kOSKextLogKextBookkeepingFlag,
+            "Autounloading for kext %s now %sabled.",
+            getIdentifierCString(),
+            flags.autounloadEnabled ? "en" : "dis");
+    }
+    return result;
 }
 
 /*********************************************************************
@@ -1918,21 +1326,21 @@
 bool
 OSKext::setKernelRequestsEnabled(bool flag)
 {
-	bool result;
-
-	IORecursiveLockLock(sKextLock);
-	result = sKernelRequestsEnabled;
-	sKernelRequestsEnabled = flag ? true : false;
-
-	if (sKernelRequestsEnabled != result) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogBasicLevel |
-		    kOSKextLogGeneralFlag,
-		    "Kernel requests now %sabled.",
-		    sKernelRequestsEnabled ? "en" : "dis");
-	}
-	IORecursiveLockUnlock(sKextLock);
-	return result;
+    bool result;
+
+    IORecursiveLockLock(sKextLock);
+    result = sKernelRequestsEnabled;
+    sKernelRequestsEnabled = flag ? true : false;
+    
+    if (sKernelRequestsEnabled != result) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogBasicLevel |
+            kOSKextLogGeneralFlag,
+            "Kernel requests now %sabled.",
+            sKernelRequestsEnabled ? "en" : "dis");
+    }
+    IORecursiveLockUnlock(sKextLock);
+    return result;
 }
 
 /*********************************************************************
@@ -1941,30 +1349,12 @@
 bool
 OSKext::getKernelRequestsEnabled(void)
 {
-	bool result;
-
-	IORecursiveLockLock(sKextLock);
-	result = sKernelRequestsEnabled;
-	IORecursiveLockUnlock(sKextLock);
-	return result;
-}
-
-static bool
-segmentIsMutable(kernel_segment_command_t *seg)
-{
-	/* Mutable segments have to have VM_PROT_WRITE */
-	if ((seg->maxprot & VM_PROT_WRITE) == 0) {
-		return false;
-	}
-	/* Exclude the __DATA_CONST segment */
-	if (strncmp(seg->segname, "__DATA_CONST", sizeof(seg->segname)) == 0) {
-		return false;
-	}
-	/* Exclude __LINKEDIT */
-	if (strncmp(seg->segname, "__LINKEDIT", sizeof(seg->segname)) == 0) {
-		return false;
-	}
-	return true;
+    bool result;
+
+    IORecursiveLockLock(sKextLock);
+    result = sKernelRequestsEnabled;
+    IORecursiveLockUnlock(sKextLock);
+    return result;
 }
 
 #if PRAGMA_MARK
@@ -1972,1366 +1362,908 @@
 #endif
 /*********************************************************************
 *********************************************************************/
-OSSharedPtr<OSKext>
+OSKext *
 OSKext::withPrelinkedInfoDict(
-	OSDictionary * anInfoDict,
-	bool doCoalescedSlides,
-	kc_kind_t type)
-{
-	OSSharedPtr<OSKext> newKext(OSMakeShared<OSKext>());
-
-	if (newKext && !newKext->initWithPrelinkedInfoDict(anInfoDict, doCoalescedSlides, type)) {
-		return NULL;
-	}
-
-	return newKext;
-}
-
-OSData *
-OSKext::parseDextUniqueID(
-	OSDictionary * anInfoDict,
-	const char *dextIDCS)
-{
-	OSData *ret = NULL;
-	OSData *data_duid = OSDynamicCast(OSData, anInfoDict->getObject(kOSBundleDextUniqueIdentifierKey));
-	if (data_duid != NULL) {
-		if (data_duid->getLength() > KOSBundleDextUniqueIdentifierMaxLength) {
-			OSKextLog(NULL,
-			    kOSKextLogErrorLevel | kOSKextLogLoadFlag,
-			    "Dext %s DextUniqueIdentifier too long.",
-			    dextIDCS);
-		} else {
-			/*
-			 * If the DextUniqueID exists it should be
-			 * present also into the personalities.
-			 */
-			setDextUniqueIDInPersonalities(anInfoDict, data_duid);
-			ret = data_duid;
-		}
-	} else {
-		OSKextLog(NULL,
-		    kOSKextLogDebugLevel | kOSKextLogLoadFlag,
-		    "Dext %s does not have a DextUniqueIdentifier",
-		    dextIDCS);
-	}
-	return ret;
-}
-
-void
-OSKext::setDextUniqueIDInPersonalities(
-	OSDictionary * anInfoDict,
-	OSData * dextUniqueID)
-{
-	OSDictionary * dextPersonalities = NULL;
-	OSSharedPtr<OSCollectionIterator> personalitiesIterator;
-	OSString * personalityName = NULL;
-
-	dextPersonalities = OSDynamicCast(OSDictionary,
-	    anInfoDict->getObject(kIOKitPersonalitiesKey));
-	if (!dextPersonalities || !dextPersonalities->getCount()) {
-		return;
-	}
-
-	personalitiesIterator =
-	    OSCollectionIterator::withCollection(dextPersonalities);
-	if (!personalitiesIterator) {
-		return;
-	}
-	while ((personalityName = OSDynamicCast(OSString,
-	    personalitiesIterator->getNextObject()))) {
-		OSDictionary * personality = OSDynamicCast(OSDictionary,
-		    dextPersonalities->getObject(personalityName));
-		if (personality) {
-			OSObject *duid = personality->getObject(kOSBundleDextUniqueIdentifierKey);
-			if (duid == NULL) {
-				personality->setObject(kOSBundleDextUniqueIdentifierKey, dextUniqueID);
-			}
-		}
-	}
-}
+    OSDictionary * anInfoDict)
+{
+    OSKext * newKext = new OSKext;
+
+    if (newKext && !newKext->initWithPrelinkedInfoDict(anInfoDict)) {
+        newKext->release();
+        return NULL;
+    }
+
+    return newKext;
+}
+
 /*********************************************************************
 *********************************************************************/
 bool
 OSKext::initWithPrelinkedInfoDict(
-	OSDictionary * anInfoDict,
-	bool doCoalescedSlides,
-	kc_kind_t type)
-{
-	bool            result              = false;
-	OSString      * kextPath            = NULL;                // do not release
-	OSNumber      * addressNum          = NULL;                // reused; do not release
-	OSNumber      * lengthNum           = NULL;                // reused; do not release
-	OSBoolean     * scratchBool         = NULL;                // do not release
-	void          * data                = NULL;                // do not free
-	void          * srcData             = NULL;                // do not free
-	OSSharedPtr<OSData>        prelinkedExecutable;
-	uint32_t        length              = 0;                // reused
-	uintptr_t       kext_slide          = PE_get_kc_slide(type);
-	bool            shouldSaveSegments  = false;
-	kc_format     format                = KCFormatUnknown;
-
-	if (!super::init()) {
-		goto finish;
-	}
-
-	/* Get the path. Don't look for an arch-specific path property.
-	 */
-	kextPath = OSDynamicCast(OSString,
-	    anInfoDict->getObject(kPrelinkBundlePathKey));
-
-	if (!setInfoDictionaryAndPath(anInfoDict, kextPath)) {
-		goto finish;
-	}
-
+    OSDictionary * anInfoDict)
+{
+    bool            result              = false;
+    OSString      * kextPath            = NULL;  // do not release
+    OSNumber      * addressNum          = NULL;  // reused; do not release
+    OSNumber      * lengthNum           = NULL;  // reused; do not release
+    void          * data                = NULL;  // do not free
+    void          * srcData             = NULL;  // do not free
+    OSData        * prelinkedExecutable = NULL;  // must release
+    uint32_t        length              = 0;     // reused
+
+    if (!super::init()) {
+        goto finish;
+    }
+
+   /* Get the path. Don't look for an arch-specific path property.
+    */
+    kextPath = OSDynamicCast(OSString,
+        anInfoDict->getObject(kPrelinkBundlePathKey));
+
+    if (!setInfoDictionaryAndPath(anInfoDict, kextPath)) {
+        goto finish;
+    }
 #if KASLR_KEXT_DEBUG
-	IOLog("kaslr: doCoalescedSlides %d kext %s \n", doCoalescedSlides, getIdentifierCString());
+    IOLog("kaslr: kext %s \n", getIdentifierCString());
 #endif
 
-	/* Also get the executable's bundle-relative path if present.
-	 * Don't look for an arch-specific path property.
-	 */
-	executableRelPath.reset(OSDynamicCast(OSString,
-	    anInfoDict->getObject(kPrelinkExecutableRelativePathKey)), OSRetain);
-	userExecutableRelPath.reset(OSDynamicCast(OSString,
-	    anInfoDict->getObject(kCFBundleDriverKitExecutableKey)), OSRetain);
-
-	/* Don't need the paths to be in the info dictionary any more.
-	 */
-	anInfoDict->removeObject(kPrelinkBundlePathKey);
-	anInfoDict->removeObject(kPrelinkExecutableRelativePathKey);
-
-	scratchBool = OSDynamicCast(OSBoolean,
-	    getPropertyForHostArch(kOSBundleRequireExplicitLoadKey));
-	if (scratchBool == kOSBooleanTrue) {
-		flags.requireExplicitLoad = 1;
-	}
-
-	/* Create an OSData wrapper around the linked executable.
-	 */
-	addressNum = OSDynamicCast(OSNumber,
-	    anInfoDict->getObject(kPrelinkExecutableLoadKey));
-	if (addressNum && addressNum->unsigned64BitValue() != kOSKextCodelessKextLoadAddr) {
-		lengthNum = OSDynamicCast(OSNumber,
-		    anInfoDict->getObject(kPrelinkExecutableSizeKey));
-		if (!lengthNum) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogArchiveFlag,
-			    "Kext %s can't find prelinked kext executable size.",
-			    getIdentifierCString());
-			return result;
-		}
-
-		data = (void *) (((uintptr_t) (addressNum->unsigned64BitValue())) + kext_slide);
-		length = (uint32_t) (lengthNum->unsigned32BitValue());
+   /* Also get the executable's bundle-relative path if present.
+    * Don't look for an arch-specific path property.
+    */
+    executableRelPath = OSDynamicCast(OSString,
+        anInfoDict->getObject(kPrelinkExecutableRelativePathKey));
+    if (executableRelPath) {
+        executableRelPath->retain();
+    }
+
+   /* Don't need the paths to be in the info dictionary any more.
+    */
+    anInfoDict->removeObject(kPrelinkBundlePathKey);
+    anInfoDict->removeObject(kPrelinkExecutableRelativePathKey);
+
+   /* Create an OSData wrapper around the linked executable.
+    */
+    addressNum = OSDynamicCast(OSNumber,
+        anInfoDict->getObject(kPrelinkExecutableLoadKey));
+    if (addressNum) {
+        lengthNum = OSDynamicCast(OSNumber,
+            anInfoDict->getObject(kPrelinkExecutableSizeKey));
+        if (!lengthNum) {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogArchiveFlag,
+                "Kext %s can't find prelinked kext executable size.",
+                getIdentifierCString());
+            goto finish;
+        }
+
+        data = (void *) ((intptr_t) (addressNum->unsigned64BitValue()) + vm_kernel_slide);
+        length = (uint32_t) (lengthNum->unsigned32BitValue());
 
 #if KASLR_KEXT_DEBUG
-		IOLog("kaslr: unslid 0x%lx slid 0x%lx length %u - prelink executable \n",
-		    (unsigned long)ml_static_unslide((vm_offset_t)data),
-		    (unsigned long)data,
-		    length);
+        IOLog("kaslr: unslid 0x%lx slid 0x%lx length %u - prelink executable \n", 
+              (unsigned long)VM_KERNEL_UNSLIDE(data), 
+              (unsigned long)data,
+              length);
 #endif
 
-		anInfoDict->removeObject(kPrelinkExecutableLoadKey);
-		anInfoDict->removeObject(kPrelinkExecutableSizeKey);
-
-		/* If the kext's load address differs from its source address, allocate
-		 * space in the kext map at the load address and copy the kext over.
-		 */
-		addressNum = OSDynamicCast(OSNumber, anInfoDict->getObject(kPrelinkExecutableSourceKey));
-		if (addressNum) {
-			srcData = (void *) (((uintptr_t) (addressNum->unsigned64BitValue())) + kext_slide);
+        anInfoDict->removeObject(kPrelinkExecutableLoadKey);
+        anInfoDict->removeObject(kPrelinkExecutableSizeKey);
+
+       /* If the kext's load address differs from its source address, allocate
+        * space in the kext map at the load address and copy the kext over.
+        */
+        addressNum = OSDynamicCast(OSNumber, anInfoDict->getObject(kPrelinkExecutableSourceKey));
+        if (addressNum) {
+            srcData = (void *) ((intptr_t) (addressNum->unsigned64BitValue()) + vm_kernel_slide);
 
 #if KASLR_KEXT_DEBUG
-			IOLog("kaslr: unslid 0x%lx slid 0x%lx - prelink executable source \n",
-			    (unsigned long)ml_static_unslide((vm_offset_t)srcData),
-			    (unsigned long)srcData);
+            IOLog("kaslr: unslid 0x%lx slid 0x%lx - prelink executable source \n", 
+                  (unsigned long)VM_KERNEL_UNSLIDE(srcData), 
+                  (unsigned long)srcData);
 #endif
 
-			if (data != srcData) {
+            if (data != srcData) {
 #if __LP64__
-				kern_return_t alloc_result;
-
-				alloc_result = kext_alloc((vm_offset_t *)&data, length, /* fixed */ TRUE);
-				if (alloc_result != KERN_SUCCESS) {
-					OSKextLog(this,
-					    kOSKextLogErrorLevel | kOSKextLogGeneralFlag,
-					    "Failed to allocate space for prelinked kext %s.",
-					    getIdentifierCString());
-					goto finish;
-				}
-				memcpy(data, srcData, length);
+                kern_return_t alloc_result;
+
+                alloc_result = kext_alloc((vm_offset_t *)&data, length, /* fixed */ TRUE);
+                if (alloc_result != KERN_SUCCESS) {
+                    OSKextLog(this,
+                        kOSKextLogErrorLevel | kOSKextLogGeneralFlag,
+                        "Failed to allocate space for prelinked kext %s.",
+                        getIdentifierCString());
+                    goto finish;
+                }
+                memcpy(data, srcData, length);
 #else
-				OSKextLog(this,
-				    kOSKextLogErrorLevel | kOSKextLogGeneralFlag,
-				    "Error: prelinked kext %s - source and load addresses "
-				    "differ on ILP32 architecture.",
-				    getIdentifierCString());
-				goto finish;
+                OSKextLog(this,
+                    kOSKextLogErrorLevel | kOSKextLogGeneralFlag,
+                    "Error: prelinked kext %s - source and load addresses "
+                    "differ on ILP32 architecture.",
+                    getIdentifierCString());
+                goto finish;
 #endif /* __LP64__ */
-			}
-
-			anInfoDict->removeObject(kPrelinkExecutableSourceKey);
-		}
-
-		prelinkedExecutable = OSData::withBytesNoCopy(data, length);
-		if (!prelinkedExecutable) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogGeneralFlag | kOSKextLogArchiveFlag,
-			    "Kext %s failed to create executable wrapper.",
-			    getIdentifierCString());
-			goto finish;
-		}
-
-		/*
-		 * Fileset KCs are mapped as a whole by iBoot.
-		 * Individual kext executables should not be unmapped
-		 * by xnu.
-		 * Doing so may result in panics like rdar://85419651
-		 */
-		if (PE_get_kc_format(kc_type, &format) && (format == KCFormatFileset)) {
-			prelinkedExecutable->setDeallocFunction(NULL);
-		} else { // Not from a Fileset KC
+            }
+
+            anInfoDict->removeObject(kPrelinkExecutableSourceKey);
+        }
+
+        prelinkedExecutable = OSData::withBytesNoCopy(data, length);
+        if (!prelinkedExecutable) {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogGeneralFlag | kOSKextLogArchiveFlag,
+                "Kext %s failed to create executable wrapper.",
+                getIdentifierCString());
+            goto finish;
+        }
+
 #if VM_MAPPED_KEXTS
-			prelinkedExecutable->setDeallocFunction(osdata_kext_free);
+        prelinkedExecutable->setDeallocFunction(osdata_kext_free);
 #else
-			prelinkedExecutable->setDeallocFunction(osdata_phys_free);
+        prelinkedExecutable->setDeallocFunction(osdata_phys_free);
 #endif
-		}
-		setLinkedExecutable(prelinkedExecutable.get());
-		addressNum = OSDynamicCast(OSNumber,
-		    anInfoDict->getObject(kPrelinkKmodInfoKey));
-		if (!addressNum) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogArchiveFlag,
-			    "Kext %s can't find prelinked kext kmod_info address.",
-			    getIdentifierCString());
-			goto finish;
-		}
-
-		if (addressNum->unsigned64BitValue() != 0) {
-			kmod_info = (kmod_info_t *) (((uintptr_t) (addressNum->unsigned64BitValue())) + kext_slide);
-			if (kmod_info->address) {
-				kmod_info->address = (((uintptr_t)(kmod_info->address)) + kext_slide);
-			} else {
-				kmod_info->address = (uintptr_t)data;
-				kmod_info->size = length;
-			}
+        setLinkedExecutable(prelinkedExecutable);
+        addressNum = OSDynamicCast(OSNumber,
+            anInfoDict->getObject(kPrelinkKmodInfoKey));
+        if (!addressNum) {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogArchiveFlag, 
+                "Kext %s can't find prelinked kext kmod_info address.",
+                getIdentifierCString());
+            goto finish;
+        }
+
+        if (addressNum->unsigned64BitValue() != 0) {
+            kmod_info = (kmod_info_t *) (intptr_t) (addressNum->unsigned64BitValue() + vm_kernel_slide);
+            kmod_info->address += vm_kernel_slide;
 #if KASLR_KEXT_DEBUG
-			IOLog("kaslr: unslid 0x%lx slid 0x%lx - kmod_info \n",
-			    (unsigned long)((vm_offset_t)kmod_info) - kext_slide,
-			    (unsigned long)kmod_info);
-			IOLog("kaslr: unslid 0x%lx slid 0x%lx - kmod_info->address \n",
-			    (unsigned long)((vm_offset_t)kmod_info->address) - kext_slide,
-			    (unsigned long)kmod_info->address);
+            IOLog("kaslr: unslid 0x%lx slid 0x%lx - kmod_info \n", 
+                  (unsigned long)VM_KERNEL_UNSLIDE(kmod_info), 
+                  (unsigned long)kmod_info);
+            IOLog("kaslr: unslid 0x%lx slid 0x%lx - kmod_info->address \n", 
+                  (unsigned long)VM_KERNEL_UNSLIDE(kmod_info->address), 
+                  (unsigned long)kmod_info->address);
  #endif
-		}
-
-		anInfoDict->removeObject(kPrelinkKmodInfoKey);
-	}
-
-	if ((addressNum = OSDynamicCast(OSNumber, anInfoDict->getObject("ModuleIndex")))) {
-		uintptr_t builtinTextStart;
-		uintptr_t builtinTextEnd;
-
-		flags.builtin = true;
-		builtinKmodIdx = addressNum->unsigned32BitValue();
-		assert(builtinKmodIdx < gBuiltinKmodsCount);
-
-		builtinTextStart = ((uintptr_t *)gBuiltinKmodsSectionStart->addr)[builtinKmodIdx];
-		builtinTextEnd   = ((uintptr_t *)gBuiltinKmodsSectionStart->addr)[builtinKmodIdx + 1];
-
-		kmod_info = ((kmod_info_t **)gBuiltinKmodsSectionInfo->addr)[builtinKmodIdx];
-		kmod_info->address = builtinTextStart;
-		kmod_info->size    = builtinTextEnd - builtinTextStart;
-	}
-
-	/* If the plist has a UUID for an interface, save that off.
-	 */
-	if (isInterface()) {
-		interfaceUUID.reset(OSDynamicCast(OSData,
-		    anInfoDict->getObject(kPrelinkInterfaceUUIDKey)), OSRetain);
-		if (interfaceUUID) {
-			anInfoDict->removeObject(kPrelinkInterfaceUUIDKey);
-		}
-	}
-
-	result = (kOSReturnSuccess == slidePrelinkedExecutable(doCoalescedSlides));
-	if (!result) {
-		goto finish;
-	}
-
-	kc_type = type;
-	/* Exclude builtin and codeless kexts */
-	if (prelinkedExecutable && kmod_info) {
-		switch (kc_type) {
-		case KCKindPrimary:
-			shouldSaveSegments = (
-				getPropertyForHostArch(kOSMutableSegmentCopy) == kOSBooleanTrue ||
-				getPropertyForHostArch(kOSBundleAllowUserLoadKey) == kOSBooleanTrue);
-			if (shouldSaveSegments) {
-				flags.resetSegmentsFromImmutableCopy = 1;
-			} else {
-				flags.unloadUnsupported = 1;
-			}
-			break;
-		case KCKindPageable:
-			flags.resetSegmentsFromVnode = 1;
-			break;
-		case KCKindAuxiliary:
-			if (!pageableKCloaded) {
-				flags.resetSegmentsFromImmutableCopy = 1;
-			} else if (resetAuxKCSegmentOnUnload) {
-				flags.resetSegmentsFromVnode = 1;
-			} else {
-				flags.unloadUnsupported = 1;
-			}
-			break;
-		default:
-			break;
-		}
-	}
-
-	if (flags.resetSegmentsFromImmutableCopy) {
-		/* Save a pristine copy of the mutable segments */
-		kernel_segment_command_t *seg = NULL;
-		kernel_mach_header_t *k_mh = (kernel_mach_header_t *)kmod_info->address;
-
-		savedMutableSegments = OSArray::withCapacity(0);
-
-		for (seg = firstsegfromheader(k_mh); seg; seg = nextsegfromheader(k_mh, seg)) {
-			if (!segmentIsMutable(seg)) {
-				continue;
-			}
-			uint64_t unslid_vmaddr = seg->vmaddr - kext_slide;
-			uint64_t vmsize = seg->vmsize;
-			OSKextLog(this, kOSKextLogDebugLevel | kOSKextLogLoadFlag,
-			    "Saving kext %s mutable segment %.*s %llx->%llx.", getIdentifierCString(), (int)strnlen(seg->segname, sizeof(seg->segname)), seg->segname, unslid_vmaddr, unslid_vmaddr + vmsize - 1);
-			OSSharedPtr<OSKextSavedMutableSegment> savedSegment = OSKextSavedMutableSegment::withSegment(seg);
-			if (!savedSegment) {
-				OSKextLog(this,
-				    kOSKextLogErrorLevel |
-				    kOSKextLogGeneralFlag,
-				    "Kext %s failed to save mutable segment %llx->%llx.", getIdentifierCString(), unslid_vmaddr, unslid_vmaddr + vmsize - 1);
-				result = false;
-				goto finish;
-			}
-			savedMutableSegments->setObject(savedSegment);
-		}
-	}
-
-	if (doCoalescedSlides == false && !flags.resetSegmentsFromVnode) {
-		/*
-		 * set VM protections now, wire pages for the old style Aux KC now,
-		 * wire pages for the rest of the KC types at load time.
-		 */
-		result = (kOSReturnSuccess == setVMAttributes(true, (type == KCKindAuxiliary) ? true : false));
-		if (!result) {
-			goto finish;
-		}
-	}
-
-	flags.prelinked = true;
-
-	if (isDriverKit()) {
-		dextStatistics = OSDextStatistics::create();
-		dextUniqueID.reset(parseDextUniqueID(anInfoDict, getIdentifierCString()), OSRetain);
-		dextLaunchedCount = 0;
-	}
-
-	/* If we created a kext from prelink info,
-	 * we must be booting from a prelinked kernel.
-	 */
-	sPrelinkBoot = true;
-
-	result = (registerIdentifier() == kOSKextInitialized);
+        }
+
+        anInfoDict->removeObject(kPrelinkKmodInfoKey);
+    }
+
+   /* If the plist has a UUID for an interface, save that off.
+    */
+    if (isInterface()) {
+        interfaceUUID = OSDynamicCast(OSData,
+            anInfoDict->getObject(kPrelinkInterfaceUUIDKey));
+        if (interfaceUUID) {
+            interfaceUUID->retain();
+            anInfoDict->removeObject(kPrelinkInterfaceUUIDKey);
+        }
+    }
+
+    result = slidePrelinkedExecutable();
+    if (result != kOSReturnSuccess) {
+        goto finish;
+    }
+
+    /* set VM protections now, wire later at kext load */
+    result = setVMAttributes(true, false);
+    if (result != KERN_SUCCESS) {
+        goto finish;
+    }
+
+    flags.prelinked = true;
+
+   /* If we created a kext from prelink info,
+    * we must be booting from a prelinked kernel.
+    */
+    sPrelinkBoot = true;
+
+    result = registerIdentifier();
+
 finish:
-	return result;
-}
-
-/*********************************************************************
-*********************************************************************/
-/* static */
-OSSharedPtr<OSKext>
-OSKext::withCodelessInfo(OSDictionary * anInfoDict, OSKextInitResult *result)
-{
-	OSSharedPtr<OSKext> newKext = OSMakeShared<OSKext>();
-	if (!newKext) {
-		return NULL;
-	}
-
-	OSKextInitResult ret = newKext->initWithCodelessInfo(anInfoDict);
-	if (result != NULL) {
-		*result = ret;
-	}
-	if (ret != kOSKextInitialized) {
-		return NULL;
-	}
-
-	return newKext;
-}
-
-/*********************************************************************
-*********************************************************************/
-OSKextInitResult
-OSKext::initWithCodelessInfo(OSDictionary * anInfoDict)
-{
-	OSKextInitResult result          = kOSKextInitFailure;
-	OSString  * kextPath             = NULL;        // do not release
-	OSBoolean * scratchBool          = NULL;        // do not release
-
-	if (anInfoDict == NULL || !super::init()) {
-		goto finish;
-	}
-
-	/*
-	 * Get the path. Don't look for an arch-specific path property.
-	 */
-	kextPath = OSDynamicCast(OSString,
-	    anInfoDict->getObject(kKextRequestArgumentCodelessInfoBundlePathKey));
-	if (!kextPath) {
-		OSKextLog(NULL,
-		    kOSKextLogErrorLevel | kOSKextLogLoadFlag,
-		    "Requested codeless kext dictionary does not contain the '%s' key",
-		    kKextRequestArgumentCodelessInfoBundlePathKey);
-		goto finish;
-	}
-
-	uniquePersonalityProperties(anInfoDict);
-
-	if (!setInfoDictionaryAndPath(anInfoDict, kextPath)) {
-		goto finish;
-	}
-
-	/*
-	 * This path is meant to initialize codeless kexts only. Refuse
-	 * anything that looks like it has an executable and/or declares
-	 * itself as a kernel component.
-	 */
-	if (declaresExecutable() || isKernelComponent()) {
-		OSKextLog(NULL,
-		    kOSKextLogErrorLevel | kOSKextLogLoadFlag,
-		    "Refusing to register codeless kext that declares an executable/kernel component: %s",
-		    getIdentifierCString());
-		goto finish;
-	}
-
-	if (strcmp(getIdentifierCString(), kIOExcludeListBundleID) == 0) {
-		boolean_t updated = updateExcludeList(infoDict.get());
-		if (updated) {
-			OSKextLog(this,
-			    kOSKextLogDebugLevel | kOSKextLogLoadFlag,
-			    "KextExcludeList was updated to version: %lld", sExcludeListVersion);
-		}
-	}
-
-	kc_type = KCKindNone;
-
-	scratchBool = OSDynamicCast(OSBoolean,
-	    getPropertyForHostArch(kOSBundleRequireExplicitLoadKey));
-	if (scratchBool == kOSBooleanTrue) {
-		flags.requireExplicitLoad = 1;
-	}
-
-	/* Also get the executable's bundle-relative path if present.
-	 * Don't look for an arch-specific path property.
-	 */
-	userExecutableRelPath.reset(OSDynamicCast(OSString,
-	    anInfoDict->getObject(kCFBundleDriverKitExecutableKey)), OSRetain);
-
-	/* remove unnecessary paths from the info dict */
-	anInfoDict->removeObject(kKextRequestArgumentCodelessInfoBundlePathKey);
-
-	if (isDriverKit()) {
-		dextStatistics = OSDextStatistics::create();
-		dextUniqueID.reset(parseDextUniqueID(anInfoDict, getIdentifierCString()), OSRetain);
-		dextLaunchedCount = 0;
-	}
-
-	result = registerIdentifier();
+    OSSafeRelease(prelinkedExecutable);
+
+    return result;
+}
+/*********************************************************************
+*********************************************************************/
+OSKext *
+OSKext::withBooterData(
+    OSString * deviceTreeName,
+    OSData   * booterData)
+{
+    OSKext * newKext = new OSKext;
+
+    if (newKext && !newKext->initWithBooterData(deviceTreeName, booterData)) {
+        newKext->release();
+        return NULL;
+    }
+    
+    return newKext;
+}
+
+/*********************************************************************
+*********************************************************************/
+typedef struct _BooterKextFileInfo {
+    uint32_t  infoDictPhysAddr;
+    uint32_t  infoDictLength;
+    uint32_t  executablePhysAddr;
+    uint32_t  executableLength;
+    uint32_t  bundlePathPhysAddr;
+    uint32_t  bundlePathLength;
+} _BooterKextFileInfo;
+
+bool
+OSKext::initWithBooterData(
+    OSString * deviceTreeName,
+    OSData   * booterData)
+{
+    bool                  result         = false;
+    _BooterKextFileInfo * kextFileInfo   = NULL;  // do not free
+    char                * infoDictAddr   = NULL;  // do not free
+    void                * executableAddr = NULL;  // do not free
+    char                * bundlePathAddr = NULL;  // do not free
+
+    OSObject            * parsedXML      = NULL;  // must release
+    OSDictionary        * theInfoDict    = NULL;  // do not release
+    OSString            * kextPath       = NULL;  // must release
+    OSString            * errorString    = NULL;  // must release
+    OSData              * executable     = NULL;  // must release
+
+    if (!super::init()) {
+        goto finish;
+    }
+
+    kextFileInfo = (_BooterKextFileInfo *)booterData->getBytesNoCopy();
+    if (!kextFileInfo) {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogGeneralFlag, 
+            "No booter-provided data for kext device tree entry %s.",
+            deviceTreeName->getCStringNoCopy());
+        goto finish;
+    }
+
+   /* The info plist must exist or we can't read the kext.
+    */
+    if (!kextFileInfo->infoDictPhysAddr || !kextFileInfo->infoDictLength) {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogGeneralFlag, 
+            "No kext info dictionary for booter device tree entry %s.",
+            deviceTreeName->getCStringNoCopy());
+        goto finish;
+    }
+    
+    infoDictAddr = (char *)ml_static_ptovirt(kextFileInfo->infoDictPhysAddr);
+    if (!infoDictAddr) {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogGeneralFlag, 
+            "Can't translate physical address 0x%x of kext info dictionary "
+            "for device tree entry %s.",
+            (int)kextFileInfo->infoDictPhysAddr,
+            deviceTreeName->getCStringNoCopy());
+        goto finish;
+    }
+
+    parsedXML = OSUnserializeXML(infoDictAddr, &errorString);
+    if (parsedXML) {
+        theInfoDict = OSDynamicCast(OSDictionary, parsedXML);
+    }
+    if (!theInfoDict) {
+        const char * errorCString = "(unknown error)";
+        
+        if (errorString && errorString->getCStringNoCopy()) {
+            errorCString = errorString->getCStringNoCopy();
+        } else if (parsedXML) {
+            errorCString = "not a dictionary";
+        }
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogGeneralFlag, 
+            "Error unserializing info dictionary for device tree entry %s: %s.",
+            deviceTreeName->getCStringNoCopy(), errorCString);
+        goto finish;
+    }
+
+   /* A bundle path is not mandatory.
+    */
+    if (kextFileInfo->bundlePathPhysAddr && kextFileInfo->bundlePathLength) {
+        bundlePathAddr = (char *)ml_static_ptovirt(kextFileInfo->bundlePathPhysAddr);
+        if (!bundlePathAddr) {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogGeneralFlag, 
+                "Can't translate physical address 0x%x of kext bundle path "
+                "for device tree entry %s.",
+                (int)kextFileInfo->bundlePathPhysAddr,
+                deviceTreeName->getCStringNoCopy());
+            goto finish;
+        }
+        bundlePathAddr[kextFileInfo->bundlePathLength-1] = '\0'; // just in case!
+        
+        kextPath = OSString::withCString(bundlePathAddr);
+        if (!kextPath) {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogGeneralFlag, 
+                "Failed to create wrapper for device tree entry %s kext path %s.",
+                deviceTreeName->getCStringNoCopy(), bundlePathAddr);
+            goto finish;
+        }
+    }
+
+    if (!setInfoDictionaryAndPath(theInfoDict, kextPath)) {
+        goto finish;
+    }
+
+   /* An executable is not mandatory.
+    */
+    if (kextFileInfo->executablePhysAddr && kextFileInfo->executableLength) {
+        executableAddr = (void *)ml_static_ptovirt(kextFileInfo->executablePhysAddr);
+        if (!executableAddr) {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogGeneralFlag, 
+                "Can't translate physical address 0x%x of kext executable "
+                "for device tree entry %s.",
+                (int)kextFileInfo->executablePhysAddr,
+                deviceTreeName->getCStringNoCopy());
+            goto finish;
+        }
+
+        executable = OSData::withBytesNoCopy(executableAddr,
+            kextFileInfo->executableLength);
+        if (!executable) {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogGeneralFlag, 
+                "Failed to create executable wrapper for device tree entry %s.",
+                deviceTreeName->getCStringNoCopy());
+            goto finish;
+        }
+
+       /* A kext with an executable needs to retain the whole booterData
+        * object to keep the executable in memory.
+        */
+        if (!setExecutable(executable, booterData)) {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogGeneralFlag, 
+                "Failed to set kext executable for device tree entry %s.",
+                deviceTreeName->getCStringNoCopy());
+            goto finish;
+        }
+    }
+
+    result = registerIdentifier();
 
 finish:
-	return result;
-}
-
-/*********************************************************************
+    OSSafeRelease(parsedXML);
+    OSSafeRelease(kextPath);
+    OSSafeRelease(errorString);
+    OSSafeRelease(executable);
+
+    return result;
+}
+
+/*********************************************************************
+*********************************************************************/
+bool
+OSKext::registerIdentifier(void)
+{
+    bool            result              = false;
+    OSKext        * existingKext        = NULL;  // do not release
+    bool            existingIsLoaded    = false;
+    bool            existingIsPrelinked = false;
+    OSKextVersion   newVersion          = -1;
+    OSKextVersion   existingVersion     = -1;
+    char            newVersionCString[kOSKextVersionMaxLength];
+    char            existingVersionCString[kOSKextVersionMaxLength];
+    OSData        * newUUID             = NULL;  // must release
+    OSData        * existingUUID        = NULL;  // must release
+
+    IORecursiveLockLock(sKextLock);
+
+   /* Get the new kext's version for checks & log messages.
+    */
+    newVersion = getVersion();
+    OSKextVersionGetString(newVersion, newVersionCString,
+        kOSKextVersionMaxLength);
+
+   /* If we don't have an existing kext with this identifier,
+    * just record the new kext and we're done!
+    */
+    existingKext = OSDynamicCast(OSKext, sKextsByID->getObject(bundleID));
+    if (!existingKext) {
+        sKextsByID->setObject(bundleID, this);
+        result = true;
+        goto finish;
+    }
+
+   /* Get the existing kext's version for checks & log messages.
+    */
+    existingVersion = existingKext->getVersion();
+    OSKextVersionGetString(existingVersion,
+        existingVersionCString, kOSKextVersionMaxLength);
+
+    existingIsLoaded = existingKext->isLoaded();
+    existingIsPrelinked = existingKext->isPrelinked();
+
+   /* If we have a kext with this identifier that's already loaded/prelinked,
+    * we can't use the new one, but let's be really thorough and check how
+    * the two are related for a precise diagnostic log message.
+    *
+    * Note that user space can't find out about nonloaded prelinked kexts,
+    * so in this case we log a message when new & existing are equivalent
+    * at the step rather than warning level, because we are always going
+    * be getting a copy of the kext in the user load request mkext.
+    */
+    if (existingIsLoaded || existingIsPrelinked) {
+        bool sameVersion = (newVersion == existingVersion);
+        bool sameExecutable = true;  // assume true unless we have UUIDs
+
+       /* Only get the UUID if the existing kext is loaded. Doing so
+        * might have to uncompress an mkext executable and we shouldn't
+        * take that hit when neither kext is loaded.
+        */
+        newUUID = copyUUID();
+        existingUUID = existingKext->copyUUID();
+
+       /* I'm entirely too paranoid about checking equivalence of executables,
+        * but I remember nasty problems with it in the past.
+        *
+        * - If we have UUIDs for both kexts, compare them.
+        * - If only one kext has a UUID, they're definitely different.
+        */
+        if (newUUID && existingUUID) {
+            sameExecutable = newUUID->isEqualTo(existingUUID);
+        } else if (newUUID || existingUUID) {
+            sameExecutable = false;
+        }
+        
+        if (!newUUID && !existingUUID) {
+
+           /* If there are no UUIDs, we can't really tell that the executables
+            * are *different* without a lot of work; the loaded kext's
+            * unrelocated executable is no longer around (and we never had it
+            * in-kernel for a prelinked kext). We certainly don't want to do
+            * a whole fake link for the new kext just to compare, either.
+            */
+
+            OSKextVersionGetString(version, newVersionCString,
+                sizeof(newVersionCString));
+            OSKextLog(this,
+                kOSKextLogWarningLevel |
+                kOSKextLogKextBookkeepingFlag,
+                "Notice - new kext %s, v%s matches %s kext "
+                "but can't determine if executables are the same (no UUIDs).",
+                getIdentifierCString(),
+                newVersionCString,
+                (existingIsLoaded ? "loaded" : "prelinked"));
+        }
+
+        if (sameVersion && sameExecutable) {
+            OSKextLog(this,
+                (existingIsLoaded ? kOSKextLogWarningLevel : kOSKextLogStepLevel) |
+                kOSKextLogKextBookkeepingFlag,
+                "Refusing new kext %s, v%s: a %s copy is already present "
+                "(same version and executable).",
+                getIdentifierCString(), newVersionCString,
+                (existingIsLoaded ? "loaded" : "prelinked"));
+        } else {
+            if (!sameVersion) {
+               /* This condition is significant so log it under warnings.
+                */
+                OSKextLog(this,
+                    kOSKextLogWarningLevel |
+                    kOSKextLogKextBookkeepingFlag,
+                    "Refusing new kext %s, v%s: already have %s v%s.",
+                    getIdentifierCString(),
+                    newVersionCString,
+                    (existingIsLoaded ? "loaded" : "prelinked"),
+                    existingVersionCString);
+            } else {
+               /* This condition is significant so log it under warnings.
+                */
+                OSKextLog(this,
+                    kOSKextLogWarningLevel | kOSKextLogKextBookkeepingFlag,
+                    "Refusing new kext %s, v%s: a %s copy with a different "
+                    "executable UUID is already present.",
+                    getIdentifierCString(), newVersionCString,
+                    (existingIsLoaded ? "loaded" : "prelinked"));
+            }
+        }
+        goto finish;
+    } /* if (existingIsLoaded || existingIsPrelinked) */
+
+   /* We have two nonloaded/nonprelinked kexts, so our decision depends on whether
+    * user loads are happening or if we're still in early boot. User agents are
+    * supposed to resolve dependencies topside and include only the exact
+    * kexts needed; so we always accept the new kext (in fact we should never
+    * see an older unloaded copy hanging around).
+    */
+    if (sUserLoadsActive) {
+        sKextsByID->setObject(bundleID, this);
+        result = true;
+
+        OSKextLog(this,
+            kOSKextLogStepLevel |
+            kOSKextLogKextBookkeepingFlag,
+            "Dropping old copy of kext %s (v%s) for newly-added (v%s).",
+            getIdentifierCString(),
+            existingVersionCString,
+            newVersionCString);
+
+        goto finish;
+    }
+    
+   /* During early boot, the kext with the highest version always wins out.
+    * Prelinked kernels will never hit this, but mkexts and booter-read
+    * kexts might have duplicates.
+    */
+    if (newVersion > existingVersion) {
+        sKextsByID->setObject(bundleID, this);
+        result = true;
+
+        OSKextLog(this,
+            kOSKextLogStepLevel |
+            kOSKextLogKextBookkeepingFlag,
+            "Dropping lower version (v%s) of registered kext %s for higher (v%s).",
+            existingVersionCString,
+            getIdentifierCString(),
+            newVersionCString);
+
+    } else {
+        OSKextLog(this,
+            kOSKextLogStepLevel |
+            kOSKextLogKextBookkeepingFlag,
+            "Kext %s is already registered with a higher/same version (v%s); "
+            "dropping newly-added (v%s).",
+            getIdentifierCString(),
+            existingVersionCString,
+            newVersionCString);
+    }
+
+   /* result has been set appropriately by now. */
+
+finish:
+
+    IORecursiveLockUnlock(sKextLock);
+
+    if (result) {
+        OSKextLog(this,
+            kOSKextLogStepLevel |
+            kOSKextLogKextBookkeepingFlag,
+            "Kext %s, v%s registered and available for loading.",
+            getIdentifierCString(), newVersionCString);
+    }
+
+    OSSafeRelease(newUUID);
+    OSSafeRelease(existingUUID);
+
+    return result;
+}
+
+/*********************************************************************
+* Does the bare minimum validation to look up a kext.
+* All other validation is done on the spot as needed.
+**********************************************************************/
+bool
+OSKext::setInfoDictionaryAndPath(
+    OSDictionary * aDictionary,
+    OSString     * aPath)
+{
+    bool           result                   = false;
+    OSString     * bundleIDString           = NULL;  // do not release
+    OSString     * versionString            = NULL;  // do not release
+    OSString     * compatibleVersionString  = NULL;  // do not release
+    const char   * versionCString           = NULL;  // do not free
+    const char   * compatibleVersionCString = NULL;  // do not free
+    OSBoolean    * scratchBool              = NULL;  // do not release
+    OSDictionary * scratchDict              = NULL;  // do not release
+
+    if (infoDict) {
+        panic("Attempt to set info dictionary on a kext "
+            "that already has one (%s).",
+            getIdentifierCString());
+    }
+
+    if (!aDictionary || !OSDynamicCast(OSDictionary, aDictionary)) {
+        goto finish;
+    }
+
+    infoDict = aDictionary;
+    infoDict->retain();
+
+   /* Check right away if the info dictionary has any log flags.
+    */
+    scratchBool = OSDynamicCast(OSBoolean,
+        getPropertyForHostArch(kOSBundleEnableKextLoggingKey));
+    if (scratchBool == kOSBooleanTrue) {
+        flags.loggingEnabled = 1;
+    }
+
+   /* The very next thing to get is the bundle identifier. Unlike
+    * in user space, a kext with no bundle identifier gets axed
+    * immediately.
+    */
+    bundleIDString = OSDynamicCast(OSString,
+        getPropertyForHostArch(kCFBundleIdentifierKey));
+    if (!bundleIDString) {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogValidationFlag,
+            "CFBundleIdentifier missing/invalid type in kext %s.",
+            aPath ? aPath->getCStringNoCopy() : "(unknown)");
+        goto finish;
+    }
+    bundleID = OSSymbol::withString(bundleIDString);
+    if (!bundleID) {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogValidationFlag,
+            "Can't copy bundle identifier as symbol for kext %s.",
+            bundleIDString->getCStringNoCopy());
+        goto finish;
+    }
+
+   /* Save the path if we got one (it should always be available but it's
+    * just something nice to have for bookkeeping).
+    */
+    if (aPath) {
+        path = aPath;
+        path->retain();
+    }
+
+   /*****
+    * Minimal validation to initialize. We'll do other validation on the spot.
+    */
+    if (bundleID->getLength() >= KMOD_MAX_NAME) {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogValidationFlag,
+            "Kext %s error - CFBundleIdentifier over max length %d.",
+            getIdentifierCString(), KMOD_MAX_NAME - 1);
+        goto finish;
+    }
+
+    version = compatibleVersion = -1;
+
+    versionString = OSDynamicCast(OSString,
+        getPropertyForHostArch(kCFBundleVersionKey));
+    if (!versionString) {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogValidationFlag,
+            "Kext %s error - CFBundleVersion missing/invalid type.",
+            getIdentifierCString());
+        goto finish;
+    }
+    versionCString = versionString->getCStringNoCopy();
+    version = OSKextParseVersionString(versionCString);
+    if (version < 0) {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogValidationFlag,
+            "Kext %s error - CFBundleVersion bad value '%s'.",
+            getIdentifierCString(), versionCString);
+        goto finish;
+    }
+
+    compatibleVersion = -1;  // set to illegal value for kexts that don't have
+
+    compatibleVersionString = OSDynamicCast(OSString,
+        getPropertyForHostArch(kOSBundleCompatibleVersionKey));
+    if (compatibleVersionString) {
+        compatibleVersionCString = compatibleVersionString->getCStringNoCopy();
+        compatibleVersion = OSKextParseVersionString(compatibleVersionCString);
+        if (compatibleVersion < 0) {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogValidationFlag,
+                "Kext %s error - OSBundleCompatibleVersion bad value '%s'.",
+                getIdentifierCString(), compatibleVersionCString);
+            goto finish;
+        }
+
+        if (compatibleVersion > version) {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogValidationFlag,
+                "Kext %s error - %s %s > %s %s (must be <=).",
+                getIdentifierCString(),
+                kOSBundleCompatibleVersionKey, compatibleVersionCString,
+                kCFBundleVersionKey,  versionCString);
+            goto finish;
+        }
+    }
+    
+    /* Check to see if this kext is in exclude list */
+    if ( isInExcludeList() ) {
+        OSKextLog(this,
+                  kOSKextLogErrorLevel | kOSKextLogGeneralFlag,
+                  "Kext %s is in exclude list, not loadable",
+                  getIdentifierCString());
+        goto finish;
+    }
+
+   /* Set flags for later use if the infoDict gets flushed. We only
+    * check for true values, not false ones(!)
+    */
+    scratchBool = OSDynamicCast(OSBoolean,
+        getPropertyForHostArch(kOSBundleIsInterfaceKey));
+    if (scratchBool == kOSBooleanTrue) {
+        flags.interface = 1;
+    }
+    
+    scratchBool = OSDynamicCast(OSBoolean,
+        getPropertyForHostArch(kOSKernelResourceKey));
+    if (scratchBool == kOSBooleanTrue) {
+        flags.kernelComponent = 1;
+        flags.interface = 1;  // xxx - hm. the kernel itself isn't an interface...
+        flags.started = 1;
+        
+       /* A kernel component has one implicit dependency on the kernel.
+        */
+        flags.hasAllDependencies = 1;
+    }
+
+   /* Make sure common string values in personalities are uniqued to OSSymbols.
+    */
+    scratchDict = OSDynamicCast(OSDictionary, 
+        getPropertyForHostArch(kIOKitPersonalitiesKey));
+    if (scratchDict) {
+        uniquePersonalityProperties(scratchDict);
+    }
+
+    result = true;
+
+finish:
+
+    return result;
+}
+
+/*********************************************************************
+* Not used for prelinked kernel boot as there is no unrelocated
+* executable.
+*********************************************************************/
+bool
+OSKext::setExecutable(
+    OSData * anExecutable,
+    OSData * externalData,
+    bool     externalDataIsMkext)
+{
+    bool         result        = false;
+    const char * executableKey = NULL;  // do not free
+
+    if (!anExecutable) {
+        infoDict->removeObject(_kOSKextExecutableKey);
+        infoDict->removeObject(_kOSKextMkextExecutableReferenceKey);
+        infoDict->removeObject(_kOSKextExecutableExternalDataKey);
+        result = true;
+        goto finish;
+    }
+    
+    if (infoDict->getObject(_kOSKextExecutableKey) ||
+        infoDict->getObject(_kOSKextMkextExecutableReferenceKey)) {
+
+        panic("Attempt to set an executable on a kext "
+            "that already has one (%s).",
+            getIdentifierCString());
+        goto finish;
+    }
+
+    if (externalDataIsMkext) {
+        executableKey = _kOSKextMkextExecutableReferenceKey;
+    } else {
+        executableKey = _kOSKextExecutableKey;
+    }
+
+    if (anExecutable) {
+        infoDict->setObject(executableKey, anExecutable);
+        if (externalData) {
+            infoDict->setObject(_kOSKextExecutableExternalDataKey, externalData);
+        }
+    }
+
+    result = true;
+
+finish:
+    return result;
+}
+
+/*********************************************************************
+*********************************************************************/
+static void
+uniqueStringPlistProperty(OSDictionary * dict, const char * key)
+{
+    OSString       * stringValue = NULL;  // do not release
+    const OSSymbol * symbolValue = NULL;  // must release
+
+    stringValue = OSDynamicCast(OSString, dict->getObject(key));
+    if (!stringValue) {
+        goto finish;
+    }
+    
+    symbolValue = OSSymbol::withString(stringValue);
+    if (!symbolValue) {
+        goto finish;
+    }
+
+    dict->setObject(key, symbolValue);
+    
+finish:
+    if (symbolValue) symbolValue->release();
+
+    return;
+}
+
+/*********************************************************************
+*********************************************************************/
+static void
+uniqueStringPlistProperty(OSDictionary * dict, const OSString * key)
+{
+    OSString       * stringValue = NULL;  // do not release
+    const OSSymbol * symbolValue = NULL;  // must release
+
+    stringValue = OSDynamicCast(OSString, dict->getObject(key));
+    if (!stringValue) {
+        goto finish;
+    }
+    
+    symbolValue = OSSymbol::withString(stringValue);
+    if (!symbolValue) {
+        goto finish;
+    }
+
+    dict->setObject(key, symbolValue);
+    
+finish:
+    if (symbolValue) symbolValue->release();
+
+    return;
+}
+
+/*********************************************************************
+* Replace common personality property values with uniqued instances
+* to save on wired memory.
 *********************************************************************/
 /* static */
 void
-OSKext::setAllVMAttributes(void)
-{
-	OSSharedPtr<OSCollectionIterator> kextIterator;
-	const OSSymbol * thisID                 = NULL;        // do not release
-
-	IORecursiveLockLock(sKextLock);
-
-	kextIterator = OSCollectionIterator::withCollection(sKextsByID.get());
-	if (!kextIterator) {
-		goto finish;
-	}
-
-	while ((thisID = OSDynamicCast(OSSymbol, kextIterator->getNextObject()))) {
-		OSKext *    thisKext;        // do not release
-
-		thisKext = OSDynamicCast(OSKext, sKextsByID->getObject(thisID));
-		if (!thisKext || thisKext->isInterface() || !thisKext->declaresExecutable()) {
-			continue;
-		}
-
-		if (!thisKext->flags.resetSegmentsFromVnode) {
-			/*
-			 * set VM protections now, wire pages for the old style Aux KC now,
-			 * wire pages for the rest of the KC types at load time.
-			 */
-			thisKext->setVMAttributes(true, (thisKext->kc_type == KCKindAuxiliary) ? true : false);
-		}
-	}
-
-finish:
-	IORecursiveLockUnlock(sKextLock);
-
-	return;
-}
-
-/*********************************************************************
-*********************************************************************/
-OSSharedPtr<OSKext>
-OSKext::withBooterData(
-	OSString * deviceTreeName,
-	OSData   * booterData)
-{
-	OSSharedPtr<OSKext> newKext(OSMakeShared<OSKext>());
-
-	if (newKext && !newKext->initWithBooterData(deviceTreeName, booterData)) {
-		return NULL;
-	}
-
-	return newKext;
-}
-
-/*********************************************************************
-*********************************************************************/
-typedef struct _BooterKextFileInfo {
-	uint32_t  infoDictPhysAddr;
-	uint32_t  infoDictLength;
-	uint32_t  executablePhysAddr;
-	uint32_t  executableLength;
-	uint32_t  bundlePathPhysAddr;
-	uint32_t  bundlePathLength;
-} _BooterKextFileInfo;
-
-bool
-OSKext::initWithBooterData(
-	OSString * deviceTreeName,
-	OSData   * booterData)
-{
-	bool                  result         = false;
-	_BooterKextFileInfo * kextFileInfo   = NULL;        // do not free
-	char                * infoDictAddr   = NULL;        // do not free
-	void                * executableAddr = NULL;        // do not free
-	char                * bundlePathAddr = NULL;        // do not free
-
-	OSDictionary        * theInfoDict    = NULL;        // do not release
-	OSSharedPtr<OSObject> parsedXML;
-	OSSharedPtr<OSString> kextPath;
-
-	OSSharedPtr<OSString> errorString;
-	OSSharedPtr<OSData>   executable;
-
-	if (!super::init()) {
-		goto finish;
-	}
-
-	kextFileInfo = (_BooterKextFileInfo *)booterData->getBytesNoCopy();
-	if (!kextFileInfo) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogGeneralFlag,
-		    "No booter-provided data for kext device tree entry %s.",
-		    deviceTreeName->getCStringNoCopy());
-		goto finish;
-	}
-
-	/* The info plist must exist or we can't read the kext.
-	 */
-	if (!kextFileInfo->infoDictPhysAddr || !kextFileInfo->infoDictLength) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogGeneralFlag,
-		    "No kext info dictionary for booter device tree entry %s.",
-		    deviceTreeName->getCStringNoCopy());
-		goto finish;
-	}
-
-	infoDictAddr = (char *)ml_static_ptovirt(kextFileInfo->infoDictPhysAddr);
-	if (!infoDictAddr) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogGeneralFlag,
-		    "Can't translate physical address 0x%x of kext info dictionary "
-		    "for device tree entry %s.",
-		    (int)kextFileInfo->infoDictPhysAddr,
-		    deviceTreeName->getCStringNoCopy());
-		goto finish;
-	}
-
-	parsedXML = OSUnserializeXML(infoDictAddr, errorString);
-	if (parsedXML) {
-		theInfoDict = OSDynamicCast(OSDictionary, parsedXML.get());
-	}
-	if (!theInfoDict) {
-		const char * errorCString = "(unknown error)";
-
-		if (errorString && errorString->getCStringNoCopy()) {
-			errorCString = errorString->getCStringNoCopy();
-		} else if (parsedXML) {
-			errorCString = "not a dictionary";
-		}
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogGeneralFlag,
-		    "Error unserializing info dictionary for device tree entry %s: %s.",
-		    deviceTreeName->getCStringNoCopy(), errorCString);
-		goto finish;
-	}
-
-	/* A bundle path is not mandatory.
-	 */
-	if (kextFileInfo->bundlePathPhysAddr && kextFileInfo->bundlePathLength) {
-		bundlePathAddr = (char *)ml_static_ptovirt(kextFileInfo->bundlePathPhysAddr);
-		if (!bundlePathAddr) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogGeneralFlag,
-			    "Can't translate physical address 0x%x of kext bundle path "
-			    "for device tree entry %s.",
-			    (int)kextFileInfo->bundlePathPhysAddr,
-			    deviceTreeName->getCStringNoCopy());
-			goto finish;
-		}
-		bundlePathAddr[kextFileInfo->bundlePathLength - 1] = '\0';         // just in case!
-
-		kextPath = OSString::withCString(bundlePathAddr);
-		if (!kextPath) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogGeneralFlag,
-			    "Failed to create wrapper for device tree entry %s kext path %s.",
-			    deviceTreeName->getCStringNoCopy(), bundlePathAddr);
-			goto finish;
-		}
-	}
-
-	if (!setInfoDictionaryAndPath(theInfoDict, kextPath.get())) {
-		goto finish;
-	}
-
-	/* An executable is not mandatory.
-	 */
-	if (kextFileInfo->executablePhysAddr && kextFileInfo->executableLength) {
-		executableAddr = (void *)ml_static_ptovirt(kextFileInfo->executablePhysAddr);
-		if (!executableAddr) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogGeneralFlag,
-			    "Can't translate physical address 0x%x of kext executable "
-			    "for device tree entry %s.",
-			    (int)kextFileInfo->executablePhysAddr,
-			    deviceTreeName->getCStringNoCopy());
-			goto finish;
-		}
-
-		executable = OSData::withBytesNoCopy(executableAddr,
-		    kextFileInfo->executableLength);
-		if (!executable) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogGeneralFlag,
-			    "Failed to create executable wrapper for device tree entry %s.",
-			    deviceTreeName->getCStringNoCopy());
-			goto finish;
-		}
-
-		/* A kext with an executable needs to retain the whole booterData
-		 * object to keep the executable in memory.
-		 */
-		if (!setExecutable(executable.get(), booterData)) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogGeneralFlag,
-			    "Failed to set kext executable for device tree entry %s.",
-			    deviceTreeName->getCStringNoCopy());
-			goto finish;
-		}
-	}
-
-	if (isDriverKit()) {
-		dextStatistics = OSDextStatistics::create();
-		dextUniqueID.reset(parseDextUniqueID(theInfoDict, getIdentifierCString()), OSRetain);
-		dextLaunchedCount = 0;
-	}
-
-	result = (registerIdentifier() == kOSKextInitialized);
-
-finish:
-	return result;
-}
-
-/*********************************************************************
-*********************************************************************/
-OSKextInitResult
-OSKext::registerIdentifier(void)
-{
-	OSKextInitResult  result                  = kOSKextInitFailure;
-	OSKext        * existingKext              = NULL;        // do not release
-	bool            existingIsLoaded          = false;
-	bool            existingIsPrelinked       = false;
-	bool            existingIsCodeless        = false;
-	bool            existingIsDext            = false;
-	OSKextVersion   newVersion                = -1;
-	OSKextVersion   existingVersion           = -1;
-	char            newVersionCString[kOSKextVersionMaxLength];
-	char            existingVersionCString[kOSKextVersionMaxLength];
-	OSSharedPtr<OSData> newUUID;
-	OSSharedPtr<OSData> existingUUID;
-	const char *newDextUniqueIDCString = NULL;
-	const char *existingDextUniqueIDCString = NULL;
-	unsigned int newDextUniqueIDCStringSize = 0;
-	unsigned int existingDextUniqueIDCStringSize = 0;
-
-	IORecursiveLockLock(sKextLock);
-
-	/* Get the new kext's version for checks & log messages.
-	 */
-	newVersion = getVersion();
-	OSKextVersionGetString(newVersion, newVersionCString,
-	    kOSKextVersionMaxLength);
-
-	/* If we don't have an existing kext with this identifier,
-	 * just record the new kext and we're done!
-	 */
-	existingKext = OSDynamicCast(OSKext, sKextsByID->getObject(bundleID.get()));
-	if (!existingKext) {
-		sKextsByID->setObject(bundleID.get(), this);
-		result = kOSKextInitialized;
-		goto finish;
-	}
-
-	/* Get the existing kext's version for checks & log messages.
-	 */
-	existingVersion = existingKext->getVersion();
-	OSKextVersionGetString(existingVersion,
-	    existingVersionCString, kOSKextVersionMaxLength);
-
-	existingIsLoaded = existingKext->isLoaded();
-	existingIsPrelinked = existingKext->isPrelinked();
-	existingIsDext = existingKext->isDriverKit();
-	existingIsCodeless = !existingKext->declaresExecutable() && !existingIsDext;
-
-	/*
-	 * Check if we are trying to upgrade a dext
-	 * with another dext.
-	 */
-	if (isDriverKit() && existingIsDext) {
-		OSData *newDextUID = getDextUniqueID();
-		if (!newDextUID) {
-			OSKextLog(this,
-			    kOSKextLogDebugLevel | kOSKextLogLoadFlag,
-			    "New dext %s, v%s requested does not have a unique dext identifier\n",
-			    getIdentifierCString(), newVersionCString);
-			goto finish;
-		}
-		newDextUniqueIDCString = getDextUniqueIDCString(newDextUID, &newDextUniqueIDCStringSize);
-		assert(newDextUniqueIDCString != NULL);
-
-		OSData *existingDextUID = existingKext->getDextUniqueID();
-		if (!existingDextUID) {
-			OSKextLog(this,
-			    kOSKextLogDebugLevel | kOSKextLogLoadFlag,
-			    "Found a dext %s, v%s: with no unique dext identifier\n",
-			    existingKext->getIdentifierCString(), existingVersionCString);
-			goto finish;
-		}
-		existingDextUniqueIDCString = getDextUniqueIDCString(existingDextUID, &existingDextUniqueIDCStringSize);
-		assert(existingDextUniqueIDCString != NULL);
-
-		/*
-		 * We might get multiple requests to save the same dext.
-		 * Check if we already have saved it or if this is an upgrade
-		 * for a dext with the same BundleID.
-		 * Dexts are uniquely identified by DextUniqueID, if a new DextUniqueID
-		 * is requested for a BundleID we are going to upgrade to the newest
-		 * received irrespective from the dext version.
-		 */
-		if (newDextUID->isEqualTo(existingDextUID) && existingKext->flags.dextToReplace == 0) {
-			OSKextLog(this,
-			    kOSKextLogDebugLevel | kOSKextLogLoadFlag,
-			    "Refusing new dext %s, v%s:"
-			    "a dext v %s with the same unique dext identifier (%s) already exists\n",
-			    getIdentifierCString(), newVersionCString,
-			    existingVersionCString, newDextUniqueIDCString);
-			result = kOSKextAlreadyExist;
-			goto finish;
-		}
-
-		bool upgraded = upgradeDext(existingKext, this);
-		if (upgraded) {
-			/* If the dext was upgraded existingKext might have been deallocated */
-			existingKext = NULL;
-			OSKextLog(this,
-			    kOSKextLogDebugLevel | kOSKextLogLoadFlag,
-			    "Dext %s, v%s , unique dext identifier %s "
-			    "Upgraded to v%s, unique dext identifier %s \n",
-			    getIdentifierCString(), existingVersionCString, existingDextUniqueIDCString,
-			    newVersionCString, newDextUniqueIDCString);
-			result = kOSKextInitialized;
-		} else {
-			OSKextLog(this,
-			    kOSKextLogDebugLevel | kOSKextLogLoadFlag,
-			    "Upgrade delayed for %s v%s, unique dext identifier %s "
-			    "with v%s, unique dext identifier %s.\n",
-			    getIdentifierCString(), existingVersionCString, existingDextUniqueIDCString,
-			    newVersionCString, newDextUniqueIDCString);
-			result = kOSKextAlreadyExist;
-		}
-
-		goto finish;
-	}
-
-	/* If we have a non-codeless kext with this identifier that's already
-	 * loaded/prelinked, we can't use the new one, but let's be really
-	 * thorough and check how the two are related for a precise diagnostic
-	 * log message.
-	 *
-	 * This check is valid for kexts that declare an executable and for
-	 * dexts, but not for codeless kexts - we can just replace those.
-	 */
-	if ((!existingIsCodeless || existingIsDext) &&
-	    (existingIsLoaded || existingIsPrelinked)) {
-		bool sameVersion = (newVersion == existingVersion);
-		bool sameExecutable = true;         // assume true unless we have UUIDs
-
-		/* Only get the UUID if the existing kext is loaded. Doing so
-		 * might have to uncompress an mkext executable and we shouldn't
-		 * take that hit when neither kext is loaded.
-		 *
-		 * Note: there is no decompression that happens when all kexts
-		 * are loaded from kext collecitons.
-		 */
-		newUUID = copyUUID();
-		existingUUID = existingKext->copyUUID();
-
-		if (existingIsDext && !isDriverKit()) {
-			OSKextLog(this,
-			    kOSKextLogWarningLevel |
-			    kOSKextLogKextBookkeepingFlag,
-			    "Notice - new kext %s, v%s matches a %s dext"
-			    "with the same bundle ID, v%s.",
-			    getIdentifierCString(), newVersionCString,
-			    (existingIsLoaded ? "loaded" : "prelinked"),
-			    existingVersionCString);
-			goto finish;
-		}
-
-		/* I'm entirely too paranoid about checking equivalence of executables,
-		 * but I remember nasty problems with it in the past.
-		 *
-		 * - If we have UUIDs for both kexts, compare them.
-		 * - If only one kext has a UUID, they're definitely different.
-		 */
-		if (newUUID && existingUUID) {
-			sameExecutable = newUUID->isEqualTo(existingUUID.get());
-		} else if (newUUID || existingUUID) {
-			sameExecutable = false;
-		}
-
-		if (!newUUID && !existingUUID) {
-			/* If there are no UUIDs, we can't really tell that the executables
-			 * are *different* without a lot of work; the loaded kext's
-			 * unrelocated executable is no longer around (and we never had it
-			 * in-kernel for a prelinked kext). We certainly don't want to do
-			 * a whole fake link for the new kext just to compare, either.
-			 */
-			OSKextLog(this,
-			    kOSKextLogWarningLevel |
-			    kOSKextLogKextBookkeepingFlag,
-			    "Notice - new kext %s, v%s matches %s kext "
-			    "but can't determine if executables are the same (no UUIDs).",
-			    getIdentifierCString(),
-			    newVersionCString,
-			    (existingIsLoaded ? "loaded" : "prelinked"));
-		}
-
-		if (sameVersion && sameExecutable) {
-			OSKextLog(this,
-			    (existingIsLoaded ? kOSKextLogWarningLevel : kOSKextLogStepLevel) |
-			    kOSKextLogKextBookkeepingFlag,
-			    "Refusing new kext %s, v%s: a %s copy is already present "
-			    "(same version and executable).",
-			    getIdentifierCString(), newVersionCString,
-			    (existingIsLoaded ? "loaded" : "prelinked"));
-		} else {
-			if (!sameVersion) {
-				/* This condition is significant so log it under warnings.
-				 */
-				OSKextLog(this,
-				    kOSKextLogWarningLevel |
-				    kOSKextLogKextBookkeepingFlag,
-				    "Refusing new kext %s, v%s: already have %s v%s.",
-				    getIdentifierCString(),
-				    newVersionCString,
-				    (existingIsLoaded ? "loaded" : "prelinked"),
-				    existingVersionCString);
-			} else {
-				/* This condition is significant so log it under warnings.
-				 */
-				OSKextLog(this,
-				    kOSKextLogWarningLevel | kOSKextLogKextBookkeepingFlag,
-				    "Refusing new kext %s, v%s: a %s copy with a different "
-				    "executable UUID is already present.",
-				    getIdentifierCString(), newVersionCString,
-				    (existingIsLoaded ? "loaded" : "prelinked"));
-			}
-		}
-		goto finish;
-	} /* if ((!existingIsCodeless || existingIsDext) && (existingIsLoaded || existingIsPrelinked)) */
-
-	/* Refuse to allow an existing loaded codeless kext be replaced by a
-	 * normal kext with the same bundle ID.
-	 */
-	if (existingIsCodeless && declaresExecutable()) {
-		OSKextLog(this,
-		    kOSKextLogWarningLevel | kOSKextLogKextBookkeepingFlag,
-		    "Refusing new kext %s, v%s: a codeless copy is already %s",
-		    getIdentifierCString(), newVersionCString,
-		    (existingIsLoaded ? "loaded" : "prelinked"));
-		goto finish;
-	}
-
-	/* Dexts packaged in the BootKC will be protected against replacement
-	 * by non-dexts by the logic above which checks if they are prelinked.
-	 * Dexts which are prelinked into the System KC will be registered
-	 * before any other kexts in the AuxKC are registered, and we never
-	 * put dexts in the AuxKC. Therefore, there is no need to check if an
-	 * existing object is a dext and is being replaced by a non-dext.
-	 * The scenario cannot happen by construction.
-	 *
-	 * See: OSKext::loadFileSetKexts()
-	 */
-
-
-	/* We have two nonloaded/nonprelinked kexts, so our decision depends on whether
-	 * user loads are happening or if we're still in early boot. User agents are
-	 * supposed to resolve dependencies topside and include only the exact
-	 * kexts needed; so we always accept the new kext (in fact we should never
-	 * see an older unloaded copy hanging around).
-	 */
-	if (sUserLoadsActive) {
-		sKextsByID->setObject(bundleID.get(), this);
-		result = kOSKextInitialized;
-
-		OSKextLog(this,
-		    kOSKextLogStepLevel |
-		    kOSKextLogKextBookkeepingFlag,
-		    "Dropping old copy of kext %s (v%s) for newly-added (v%s).",
-		    getIdentifierCString(),
-		    existingVersionCString,
-		    newVersionCString);
-
-		goto finish;
-	}
-
-	/* During early boot, the kext with the highest version always wins out.
-	 * Prelinked kernels will never hit this, but mkexts and booter-read
-	 * kexts might have duplicates.
-	 */
-	if (newVersion > existingVersion) {
-		sKextsByID->setObject(bundleID.get(), this);
-		result = kOSKextInitialized;
-
-		OSKextLog(this,
-		    kOSKextLogStepLevel |
-		    kOSKextLogKextBookkeepingFlag,
-		    "Dropping lower version (v%s) of registered kext %s for higher (v%s).",
-		    existingVersionCString,
-		    getIdentifierCString(),
-		    newVersionCString);
-	} else {
-		OSKextLog(this,
-		    kOSKextLogStepLevel |
-		    kOSKextLogKextBookkeepingFlag,
-		    "Kext %s is already registered with a higher/same version (v%s); "
-		    "dropping newly-added (v%s).",
-		    getIdentifierCString(),
-		    existingVersionCString,
-		    newVersionCString);
-	}
-
-	/* result has been set appropriately by now. */
-
-finish:
-
-	IORecursiveLockUnlock(sKextLock);
-
-	if (newDextUniqueIDCString != NULL) {
-		kfree_data(newDextUniqueIDCString, newDextUniqueIDCStringSize);
-	}
-	if (existingDextUniqueIDCString != NULL) {
-		kfree_data(existingDextUniqueIDCString, existingDextUniqueIDCStringSize);
-	}
-
-	if (result == kOSKextInitialized) {
-		OSKextLog(this,
-		    kOSKextLogStepLevel |
-		    kOSKextLogKextBookkeepingFlag,
-		    "Kext %s, v%s registered and available for loading.",
-		    getIdentifierCString(), newVersionCString);
-	}
-
-	return result;
-}
-
-/*********************************************************************
- * Does the bare minimum validation to look up a kext.
- * All other validation is done on the spot as needed.
- **********************************************************************/
-bool
-OSKext::setInfoDictionaryAndPath(
-	OSDictionary * aDictionary,
-	OSString     * aPath)
-{
-	bool           result                   = false;
-	OSString     * bundleIDString           = NULL;        // do not release
-	OSString     * versionString            = NULL;        // do not release
-	OSString     * compatibleVersionString  = NULL;        // do not release
-	const char   * versionCString           = NULL;        // do not free
-	const char   * compatibleVersionCString = NULL;        // do not free
-	OSBoolean    * scratchBool              = NULL;        // do not release
-	OSDictionary * scratchDict              = NULL;        // do not release
-
-	if (infoDict) {
-		panic("Attempt to set info dictionary on a kext "
-		    "that already has one (%s).",
-		    getIdentifierCString());
-	}
-
-	if (!aDictionary || !OSDynamicCast(OSDictionary, aDictionary)) {
-		goto finish;
-	}
-
-	infoDict.reset(aDictionary, OSRetain);
-
-	/* Check right away if the info dictionary has any log flags.
-	 */
-	scratchBool = OSDynamicCast(OSBoolean,
-	    getPropertyForHostArch(kOSBundleEnableKextLoggingKey));
-	if (scratchBool == kOSBooleanTrue) {
-		flags.loggingEnabled = 1;
-	}
-
-	/* The very next thing to get is the bundle identifier. Unlike
-	 * in user space, a kext with no bundle identifier gets axed
-	 * immediately.
-	 */
-	bundleIDString = OSDynamicCast(OSString,
-	    getPropertyForHostArch(kCFBundleIdentifierKey));
-	if (!bundleIDString) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogValidationFlag,
-		    "CFBundleIdentifier missing/invalid type in kext %s.",
-		    aPath ? aPath->getCStringNoCopy() : "(unknown)");
-		goto finish;
-	}
-	bundleID = OSSymbol::withString(bundleIDString);
-	if (!bundleID) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogValidationFlag,
-		    "Can't copy bundle identifier as symbol for kext %s.",
-		    bundleIDString->getCStringNoCopy());
-		goto finish;
-	}
-
-	/* Save the path if we got one (it should always be available but it's
-	 * just something nice to have for bookkeeping).
-	 */
-	if (aPath) {
-		path.reset(aPath, OSRetain);
-	}
-
-	/*****
-	 * Minimal validation to initialize. We'll do other validation on the spot.
-	 */
-	if (bundleID->getLength() >= KMOD_MAX_NAME) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogValidationFlag,
-		    "Kext %s error - CFBundleIdentifier over max length %d.",
-		    getIdentifierCString(), KMOD_MAX_NAME - 1);
-		goto finish;
-	}
-
-	version = compatibleVersion = -1;
-
-	versionString = OSDynamicCast(OSString,
-	    getPropertyForHostArch(kCFBundleVersionKey));
-	if (!versionString) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogValidationFlag,
-		    "Kext %s error - CFBundleVersion missing/invalid type.",
-		    getIdentifierCString());
-		goto finish;
-	}
-	versionCString = versionString->getCStringNoCopy();
-	version = OSKextParseVersionString(versionCString);
-	if (version < 0) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogValidationFlag,
-		    "Kext %s error - CFBundleVersion bad value '%s'.",
-		    getIdentifierCString(), versionCString);
-		goto finish;
-	}
-
-	compatibleVersion = -1;         // set to illegal value for kexts that don't have
-
-	compatibleVersionString = OSDynamicCast(OSString,
-	    getPropertyForHostArch(kOSBundleCompatibleVersionKey));
-	if (compatibleVersionString) {
-		compatibleVersionCString = compatibleVersionString->getCStringNoCopy();
-		compatibleVersion = OSKextParseVersionString(compatibleVersionCString);
-		if (compatibleVersion < 0) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogValidationFlag,
-			    "Kext %s error - OSBundleCompatibleVersion bad value '%s'.",
-			    getIdentifierCString(), compatibleVersionCString);
-			goto finish;
-		}
-
-		if (compatibleVersion > version) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogValidationFlag,
-			    "Kext %s error - %s %s > %s %s (must be <=).",
-			    getIdentifierCString(),
-			    kOSBundleCompatibleVersionKey, compatibleVersionCString,
-			    kCFBundleVersionKey, versionCString);
-			goto finish;
-		}
-	}
-
-	/* Check to see if this kext is in exclude list */
-	if (isInExcludeList()) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel | kOSKextLogGeneralFlag,
-		    "Kext %s is in exclude list, not loadable",
-		    getIdentifierCString());
-		goto finish;
-	}
-
-	/* Set flags for later use if the infoDict gets flushed. We only
-	 * check for true values, not false ones(!)
-	 */
-	scratchBool = OSDynamicCast(OSBoolean,
-	    getPropertyForHostArch(kOSBundleIsInterfaceKey));
-	if (scratchBool == kOSBooleanTrue) {
-		flags.interface = 1;
-	}
-
-	scratchBool = OSDynamicCast(OSBoolean,
-	    getPropertyForHostArch(kOSKernelResourceKey));
-	if (scratchBool == kOSBooleanTrue) {
-		flags.kernelComponent = 1;
-		flags.interface = 1;         // xxx - hm. the kernel itself isn't an interface...
-		flags.started = 1;
-
-		/* A kernel component has one implicit dependency on the kernel.
-		 */
-		flags.hasAllDependencies = 1;
-	}
-
-	/* Make sure common string values in personalities are uniqued to OSSymbols.
-	 */
-	scratchDict = OSDynamicCast(OSDictionary,
-	    getPropertyForHostArch(kIOKitPersonalitiesKey));
-	if (scratchDict) {
-		uniquePersonalityProperties(scratchDict);
-	}
-
-	result = true;
-
-finish:
-
-	return result;
-}
-
-/*********************************************************************
-* Not used for prelinked kernel boot as there is no unrelocated
-* executable.
-*********************************************************************/
-bool
-OSKext::setExecutable(
-	OSData * anExecutable,
-	OSData * externalData,
-	bool     externalDataIsMkext)
-{
-	bool         result        = false;
-	const char * executableKey = NULL;         // do not free
-
-	if (!anExecutable) {
-		infoDict->removeObject(_kOSKextExecutableKey);
-		infoDict->removeObject(_kOSKextMkextExecutableReferenceKey);
-		infoDict->removeObject(_kOSKextExecutableExternalDataKey);
-		result = true;
-		goto finish;
-	}
-
-	if (infoDict->getObject(_kOSKextExecutableKey) ||
-	    infoDict->getObject(_kOSKextMkextExecutableReferenceKey)) {
-		panic("Attempt to set an executable on a kext "
-		    "that already has one (%s).",
-		    getIdentifierCString());
-		goto finish;
-	}
-
-	if (externalDataIsMkext) {
-		executableKey = _kOSKextMkextExecutableReferenceKey;
-	} else {
-		executableKey = _kOSKextExecutableKey;
-	}
-
-	if (anExecutable) {
-		infoDict->setObject(executableKey, anExecutable);
-		if (externalData) {
-			infoDict->setObject(_kOSKextExecutableExternalDataKey, externalData);
-		}
-	}
-
-	result = true;
-
-finish:
-	return result;
-}
-
-/*********************************************************************
-*********************************************************************/
-static void
-uniqueStringPlistProperty(OSDictionary * dict, const char * key)
-{
-	OSObject       * value       = NULL;        // do not release
-	OSString       * stringValue = NULL;        // do not release
-	OSSharedPtr<const OSSymbol> symbolValue;
-
-	value = dict->getObject(key);
-	if (!value) {
-		goto finish;
-	}
-	if (OSDynamicCast(OSSymbol, value)) {
-		/* this is already an OSSymbol: we're good */
-		goto finish;
-	}
-
-	stringValue = OSDynamicCast(OSString, value);
-	if (!stringValue) {
-		goto finish;
-	}
-
-	symbolValue = OSSymbol::withString(stringValue);
-	if (!symbolValue) {
-		goto finish;
-	}
-
-	dict->setObject(key, symbolValue.get());
-
-finish:
-	return;
-}
-
-/*********************************************************************
-*********************************************************************/
-static void
-uniqueStringPlistProperty(OSDictionary * dict, const OSString * key)
-{
-	OSObject       * value       = NULL;        // do not release
-	OSString       * stringValue = NULL;        // do not release
-	OSSharedPtr<const OSSymbol> symbolValue;
-
-	value = dict->getObject(key);
-	if (!value) {
-		goto finish;
-	}
-	if (OSDynamicCast(OSSymbol, value)) {
-		/* this is already an OSSymbol: we're good */
-		goto finish;
-	}
-
-	stringValue = OSDynamicCast(OSString, value);
-	if (!stringValue) {
-		goto finish;
-	}
-
-	symbolValue = OSSymbol::withString(stringValue);
-	if (!symbolValue) {
-		goto finish;
-	}
-
-	dict->setObject(key, symbolValue.get());
-
-finish:
-	return;
-}
-
-void
 OSKext::uniquePersonalityProperties(OSDictionary * personalityDict)
 {
-	OSKext::uniquePersonalityProperties(personalityDict, true);
-}
-
-/*********************************************************************
-* Replace common personality property values with uniqued instances
-* to save on wired memory.
-*********************************************************************/
-/* static */
-void
-OSKext::uniquePersonalityProperties(OSDictionary * personalityDict, bool defaultAddKernelBundleIdentifier)
-{
-	/* Properties every personality has.
-	 */
-	uniqueStringPlistProperty(personalityDict, kCFBundleIdentifierKey);
-	uniqueStringPlistProperty(personalityDict, kIOProviderClassKey);
-	uniqueStringPlistProperty(personalityDict, gIOClassKey.get());
-	if (personalityDict->getObject(kCFBundleIdentifierKernelKey)) {
-		uniqueStringPlistProperty(personalityDict, kCFBundleIdentifierKernelKey);
-	} else if (defaultAddKernelBundleIdentifier) {
-		personalityDict->setObject(kCFBundleIdentifierKernelKey, personalityDict->getObject(kCFBundleIdentifierKey));
-	}
-
-	/* Other commonly used properties.
-	 */
-	uniqueStringPlistProperty(personalityDict, gIOMatchCategoryKey);
-	uniqueStringPlistProperty(personalityDict, gIOResourceMatchKey);
-	uniqueStringPlistProperty(personalityDict, gIOUserClientClassKey);
-
-	uniqueStringPlistProperty(personalityDict, "HIDDefaultBehavior");
-	uniqueStringPlistProperty(personalityDict, "HIDPointerAccelerationType");
-	uniqueStringPlistProperty(personalityDict, "HIDRemoteControlType");
-	uniqueStringPlistProperty(personalityDict, "HIDScrollAccelerationType");
-	uniqueStringPlistProperty(personalityDict, "IOPersonalityPublisher");
-	uniqueStringPlistProperty(personalityDict, "Physical Interconnect");
-	uniqueStringPlistProperty(personalityDict, "Physical Interconnect Location");
-	uniqueStringPlistProperty(personalityDict, "Vendor");
-	uniqueStringPlistProperty(personalityDict, "Vendor Identification");
-	uniqueStringPlistProperty(personalityDict, "Vendor Name");
-	uniqueStringPlistProperty(personalityDict, "bConfigurationValue");
-	uniqueStringPlistProperty(personalityDict, "bInterfaceNumber");
-	uniqueStringPlistProperty(personalityDict, "idProduct");
-
-	return;
+   /* Properties every personality has.
+    */
+    uniqueStringPlistProperty(personalityDict, kCFBundleIdentifierKey);
+    uniqueStringPlistProperty(personalityDict, kIOProviderClassKey);
+    uniqueStringPlistProperty(personalityDict, gIOClassKey);
+    
+   /* Other commonly used properties.
+    */
+    uniqueStringPlistProperty(personalityDict, gIOMatchCategoryKey);
+    uniqueStringPlistProperty(personalityDict, gIOResourceMatchKey);
+    uniqueStringPlistProperty(personalityDict, gIOUserClientClassKey);
+
+    uniqueStringPlistProperty(personalityDict, "HIDDefaultBehavior");
+    uniqueStringPlistProperty(personalityDict, "HIDPointerAccelerationType");
+    uniqueStringPlistProperty(personalityDict, "HIDRemoteControlType");
+    uniqueStringPlistProperty(personalityDict, "HIDScrollAccelerationType");
+    uniqueStringPlistProperty(personalityDict, "IOPersonalityPublisher"); 
+    uniqueStringPlistProperty(personalityDict, "Physical Interconnect");
+    uniqueStringPlistProperty(personalityDict, "Physical Interconnect Location");
+    uniqueStringPlistProperty(personalityDict, "Vendor");
+    uniqueStringPlistProperty(personalityDict, "Vendor Identification");
+    uniqueStringPlistProperty(personalityDict, "Vendor Name");
+    uniqueStringPlistProperty(personalityDict, "bConfigurationValue");
+    uniqueStringPlistProperty(personalityDict, "bInterfaceNumber");
+    uniqueStringPlistProperty(personalityDict, "idProduct");
+
+    return;
 }
 
 /*********************************************************************
@@ -3339,102 +2271,85 @@
 void
 OSKext::free(void)
 {
-	if (isLoaded()) {
-		panic("Attempt to free loaded kext %s.", getIdentifierCString());
-	}
-
-	if (isDriverKit()) {
-		if (dextLaunchedCount > 0) {
-			panic("Freeing dext %s but dextLaunchedCount is %d\n", getIdentifierCString(), dextLaunchedCount);
-		}
-	}
-
-	infoDict.reset();
-	bundleID.reset();
-	path.reset();
-	executableRelPath.reset();
-	userExecutableRelPath.reset();
-	dependencies.reset();
-	linkedExecutable.reset();
-	metaClasses.reset();
-	interfaceUUID.reset();
-	driverKitUUID.reset();
-	dextStatistics.reset();
-	dextUniqueID.reset();
-
-	if (isInterface() && kmod_info) {
-		kfree_type(kmod_info_t, kmod_info);
-	}
-
-	super::free();
-	return;
+    if (isLoaded()) {
+        panic("Attempt to free loaded kext %s.", getIdentifierCString());
+    }
+
+    OSSafeRelease(infoDict);
+    OSSafeRelease(bundleID);
+    OSSafeRelease(path);
+    OSSafeRelease(executableRelPath);
+    OSSafeRelease(dependencies);
+    OSSafeRelease(linkedExecutable);
+    OSSafeRelease(metaClasses);
+    OSSafeRelease(interfaceUUID);
+
+    if (isInterface() && kmod_info) {
+        kfree(kmod_info, sizeof(kmod_info_t));
+    }
+
+    super::free();
+    return;
 }
 
 #if PRAGMA_MARK
 #pragma mark Mkext files
 #endif
-
-#if CONFIG_KXLD
-/*
- * mkext archives are really only relevant on kxld-enabled kernels.
- * Without a dynamic kernel linker, we don't need to support any mkexts.
- */
-
 /*********************************************************************
 *********************************************************************/
 OSReturn
 OSKext::readMkextArchive(OSData * mkextData,
     uint32_t * checksumPtr)
 {
-	OSReturn       result       = kOSKextReturnBadData;
-	uint32_t       mkextLength  = 0;
-	mkext_header * mkextHeader  = NULL;        // do not free
-	uint32_t       mkextVersion = 0;
-
-	/* Note default return of kOSKextReturnBadData above.
-	 */
-	mkextLength = mkextData->getLength();
-	if (mkextLength < sizeof(mkext_basic_header)) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogArchiveFlag,
-		    "Mkext archive too small to be valid.");
-		goto finish;
-	}
-
-	mkextHeader = (mkext_header *)mkextData->getBytesNoCopy();
-
-	if (MKEXT_GET_MAGIC(mkextHeader) != MKEXT_MAGIC ||
-	    MKEXT_GET_SIGNATURE(mkextHeader) != MKEXT_SIGN) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogArchiveFlag,
-		    "Mkext archive has invalid magic or signature.");
-		goto finish;
-	}
-
-	if (MKEXT_GET_LENGTH(mkextHeader) != mkextLength) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogArchiveFlag,
-		    "Mkext archive recorded length doesn't match actual file length.");
-		goto finish;
-	}
-
-	mkextVersion = MKEXT_GET_VERSION(mkextHeader);
-
-	if (mkextVersion == MKEXT_VERS_2) {
-		result = OSKext::readMkext2Archive(mkextData, NULL, checksumPtr);
-	} else {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogArchiveFlag,
-		    "Mkext archive of unsupported mkext version 0x%x.", mkextVersion);
-		result = kOSKextReturnUnsupported;
-	}
+    OSReturn       result       = kOSKextReturnBadData;
+    uint32_t       mkextLength  = 0;
+    mkext_header * mkextHeader  = 0;   // do not free
+    uint32_t       mkextVersion = 0;
+
+   /* Note default return of kOSKextReturnBadData above.
+    */
+    mkextLength = mkextData->getLength();
+    if (mkextLength < sizeof(mkext_basic_header)) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogErrorLevel |
+            kOSKextLogArchiveFlag,
+            "Mkext archive too small to be valid.");
+        goto finish;
+    }
+    
+    mkextHeader = (mkext_header *)mkextData->getBytesNoCopy();
+    
+    if (MKEXT_GET_MAGIC(mkextHeader) != MKEXT_MAGIC ||
+        MKEXT_GET_SIGNATURE(mkextHeader) != MKEXT_SIGN) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogErrorLevel |
+            kOSKextLogArchiveFlag,
+            "Mkext archive has invalid magic or signature.");
+        goto finish;
+    }
+
+    if (MKEXT_GET_LENGTH(mkextHeader) != mkextLength) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogErrorLevel |
+            kOSKextLogArchiveFlag,
+            "Mkext archive recorded length doesn't match actual file length.");
+        goto finish;
+    }
+
+    mkextVersion = MKEXT_GET_VERSION(mkextHeader);
+
+    if (mkextVersion == MKEXT_VERS_2) {
+        result = OSKext::readMkext2Archive(mkextData, NULL, checksumPtr);
+    } else {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogErrorLevel |
+            kOSKextLogArchiveFlag,
+            "Mkext archive of unsupported mkext version 0x%x.", mkextVersion);
+        result = kOSKextReturnUnsupported;
+    }
 
 finish:
-	return result;
+    return result;
 }
 
 /*********************************************************************
@@ -3449,318 +2364,285 @@
 /* static */
 OSReturn
 OSKext::readMkext2Archive(
-	OSData        * mkextData,
-	OSDictionary ** mkextPlistOut,
-	uint32_t      * checksumPtr)
-{
-	OSReturn        result                     = kOSReturnError;
-	uint32_t        mkextLength;
-	mkext2_header * mkextHeader                = NULL;        // do not free
-	void          * mkextEnd                   = NULL;        // do not free
-	uint32_t        mkextVersion;
-	uint8_t       * crc_address                = NULL;
-	size_t          crc_buffer_size            = 0;
-	uint32_t        checksum;
-	uint32_t        mkextPlistOffset;
-	uint32_t        mkextPlistCompressedSize;
-	char          * mkextPlistEnd              = NULL;        // do not free
-	uint32_t        mkextPlistFullSize;
-	OSSharedPtr<OSString>     errorString;
-	OSSharedPtr<OSData>       mkextPlistUncompressedData;
-	const char    * mkextPlistDataBuffer       = NULL;        // do not free
-	OSSharedPtr<OSObject>      parsedXML;
-	OSDictionary  * mkextPlist                 = NULL;        // do not release
-	OSArray       * mkextInfoDictArray         = NULL;        // do not release
-	uint32_t        count, i;
-	kc_format_t kc_format;
-
-	if (!PE_get_primary_kc_format(&kc_format)) {
-		OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogGeneralFlag,
-		    "Unable to determine primary KC format");
-		goto finish;
-	}
-
-	mkextLength = mkextData->getLength();
-	mkextHeader = (mkext2_header *)mkextData->getBytesNoCopy();
-	mkextEnd = (char *)mkextHeader + mkextLength;
-	mkextVersion = MKEXT_GET_VERSION(mkextHeader);
-
-	crc_address = (u_int8_t *)&mkextHeader->version;
-	crc_buffer_size = (uintptr_t)mkextHeader +
-	    MKEXT_GET_LENGTH(mkextHeader) - (uintptr_t)crc_address;
-	if (crc_buffer_size > INT32_MAX) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogArchiveFlag,
-		    "Mkext archive size is too large (%lu > INT32_MAX).",
-		    crc_buffer_size);
-		result = kOSKextReturnBadData;
-		goto finish;
-	}
-	checksum = mkext_adler32(crc_address, (int32_t)crc_buffer_size);
-
-	if (MKEXT_GET_CHECKSUM(mkextHeader) != checksum) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogArchiveFlag,
-		    "Mkext archive has bad checksum.");
-		result = kOSKextReturnBadData;
-		goto finish;
-	}
-
-	if (checksumPtr) {
-		*checksumPtr = checksum;
-	}
-
-	/* Check that the CPU type & subtype match that of the running kernel. */
-	if (MKEXT_GET_CPUTYPE(mkextHeader) == (UInt32)CPU_TYPE_ANY) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogArchiveFlag,
-		    "Mkext archive must have a specific CPU type.");
-		result = kOSKextReturnBadData;
-		goto finish;
-	} else {
-		if ((UInt32)_mh_execute_header.cputype !=
-		    MKEXT_GET_CPUTYPE(mkextHeader)) {
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogArchiveFlag,
-			    "Mkext archive does not match the running kernel's CPU type.");
-			result = kOSKextReturnArchNotFound;
-			goto finish;
-		}
-	}
-
-	mkextPlistOffset = MKEXT2_GET_PLIST(mkextHeader);
-	mkextPlistCompressedSize = MKEXT2_GET_PLIST_COMPSIZE(mkextHeader);
-	mkextPlistEnd = (char *)mkextHeader + mkextPlistOffset +
-	    mkextPlistCompressedSize;
-	if (mkextPlistEnd > mkextEnd) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogArchiveFlag,
-		    "Mkext archive file overrun.");
-		result = kOSKextReturnBadData;
-	}
-
-	mkextPlistFullSize = MKEXT2_GET_PLIST_FULLSIZE(mkextHeader);
-	if (mkextPlistCompressedSize) {
-		mkextPlistUncompressedData = sKernelKext->extractMkext2FileData(
-			(UInt8 *)mkextHeader + mkextPlistOffset,
-			"plist",
-			mkextPlistCompressedSize, mkextPlistFullSize);
-		if (!mkextPlistUncompressedData) {
-			goto finish;
-		}
-		mkextPlistDataBuffer = (const char *)
-		    mkextPlistUncompressedData->getBytesNoCopy();
-	} else {
-		mkextPlistDataBuffer = (const char *)mkextHeader + mkextPlistOffset;
-	}
-
-	/* IOCFSerialize added a nul byte to the end of the string. Very nice of it.
-	 */
-	parsedXML = OSUnserializeXML(mkextPlistDataBuffer, errorString);
-	if (parsedXML) {
-		mkextPlist = OSDynamicCast(OSDictionary, parsedXML.get());
-	}
-	if (!mkextPlist) {
-		const char * errorCString = "(unknown error)";
-
-		if (errorString && errorString->getCStringNoCopy()) {
-			errorCString = errorString->getCStringNoCopy();
-		} else if (parsedXML) {
-			errorCString = "not a dictionary";
-		}
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogArchiveFlag,
-		    "Error unserializing mkext plist: %s.", errorCString);
-		goto finish;
-	}
-
-	mkextInfoDictArray = OSDynamicCast(OSArray,
-	    mkextPlist->getObject(kMKEXTInfoDictionariesKey));
-	if (!mkextInfoDictArray) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogArchiveFlag,
-		    "Mkext archive contains no kext info dictionaries.");
-		goto finish;
-	}
-
-	count = mkextInfoDictArray->getCount();
-	for (i = 0; i < count; i++) {
-		OSDictionary * infoDict;
-
-
-		infoDict = OSDynamicCast(OSDictionary,
-		    mkextInfoDictArray->getObject(i));
-
-		/* Create the kext for the entry, then release it, because the
-		 * kext system keeps them around until explicitly removed.
-		 * Any creation/registration failures are already logged for us.
-		 */
-		if (infoDict) {
-			OSSharedPtr<OSKext> newKext = OSKext::withMkext2Info(infoDict, mkextData);
-
-			/* Fail dynamic loading of a kext when booted from MH_FILESET */
-			if (kc_format == KCFormatFileset &&
-			    newKext &&
-			    !(newKext->isPrelinked()) &&
-			    newKext->declaresExecutable()) {
-				result = kOSReturnError;
-				printf("Kext LOG: Dynamic loading of kext denied for kext %s\n",
-				    newKext->getIdentifier() ? newKext->getIdentifierCString() : "unknown kext");
-
-				OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogArchiveFlag,
-				    "Dynamic loading of kext denied for kext %s\n",
-				    newKext->getIdentifier() ? newKext->getIdentifierCString() : "unknown kext");
-				goto finish;
-			}
-		}
-	}
-
-	/* If the caller needs the plist, hand them back our copy
-	 */
-	if (mkextPlistOut) {
-		*mkextPlistOut = mkextPlist;
-		parsedXML.detach();
-	}
-
-	/* Even if we didn't keep any kexts from the mkext, we may have a load
-	 * request to process, so we are successful (no errors occurred).
-	 */
-	result = kOSReturnSuccess;
+    OSData        * mkextData,
+    OSDictionary ** mkextPlistOut,
+    uint32_t      * checksumPtr)
+{
+    OSReturn        result                     = kOSReturnError;
+    uint32_t        mkextLength;
+    mkext2_header * mkextHeader                = NULL;  // do not free
+    void          * mkextEnd                   = NULL;  // do not free
+    uint32_t        mkextVersion;
+    uint8_t       * crc_address                = NULL;
+    uint32_t        checksum;
+    uint32_t        mkextPlistOffset;
+    uint32_t        mkextPlistCompressedSize;
+    char          * mkextPlistEnd              = NULL;  // do not free
+    uint32_t        mkextPlistFullSize;
+    OSString      * errorString                = NULL;  // must release
+    OSData        * mkextPlistUncompressedData = NULL;  // must release
+    const char    * mkextPlistDataBuffer       = NULL;  // do not free
+    OSObject      * parsedXML                  = NULL;  // must release
+    OSDictionary  * mkextPlist                 = NULL;  // do not release
+    OSArray       * mkextInfoDictArray         = NULL;  // do not release
+    uint32_t        count, i;
+
+    mkextLength = mkextData->getLength();
+    mkextHeader = (mkext2_header *)mkextData->getBytesNoCopy();
+    mkextEnd = (char *)mkextHeader + mkextLength;
+    mkextVersion = MKEXT_GET_VERSION(mkextHeader);
+
+    crc_address = (u_int8_t *)&mkextHeader->version;
+    checksum = mkext_adler32(crc_address,
+        (uintptr_t)mkextHeader +
+        MKEXT_GET_LENGTH(mkextHeader) - (uintptr_t)crc_address);
+
+    if (MKEXT_GET_CHECKSUM(mkextHeader) != checksum) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogErrorLevel |
+            kOSKextLogArchiveFlag,
+            "Mkext archive has bad checksum.");
+        result = kOSKextReturnBadData;
+        goto finish;
+    }
+
+    if (checksumPtr) {
+        *checksumPtr = checksum;
+    }
+
+   /* Check that the CPU type & subtype match that of the running kernel. */
+    if (MKEXT_GET_CPUTYPE(mkextHeader) == (UInt32)CPU_TYPE_ANY) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogErrorLevel |
+            kOSKextLogArchiveFlag,
+            "Mkext archive must have a specific CPU type.");
+        result = kOSKextReturnBadData;
+        goto finish;
+    } else {
+        if ((UInt32)_mh_execute_header.cputype !=
+            MKEXT_GET_CPUTYPE(mkextHeader)) {
+
+            OSKextLog(/* kext */ NULL,
+                kOSKextLogErrorLevel |
+                kOSKextLogArchiveFlag,
+                "Mkext archive does not match the running kernel's CPU type.");
+            result = kOSKextReturnArchNotFound;
+            goto finish;
+        }
+    }
+
+    mkextPlistOffset = MKEXT2_GET_PLIST(mkextHeader);
+    mkextPlistCompressedSize = MKEXT2_GET_PLIST_COMPSIZE(mkextHeader);
+    mkextPlistEnd = (char *)mkextHeader + mkextPlistOffset +
+        mkextPlistCompressedSize;
+    if (mkextPlistEnd > mkextEnd) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogErrorLevel |
+            kOSKextLogArchiveFlag,
+            "Mkext archive file overrun.");
+        result = kOSKextReturnBadData;
+    }
+
+    mkextPlistFullSize = MKEXT2_GET_PLIST_FULLSIZE(mkextHeader);
+    if (mkextPlistCompressedSize) {
+        mkextPlistUncompressedData = sKernelKext->extractMkext2FileData(
+            (UInt8 *)mkextHeader + mkextPlistOffset,
+            "plist",
+            mkextPlistCompressedSize, mkextPlistFullSize);
+        if (!mkextPlistUncompressedData) {
+            goto finish;
+        }
+        mkextPlistDataBuffer = (const char *)
+            mkextPlistUncompressedData->getBytesNoCopy();
+    } else {
+        mkextPlistDataBuffer = (const char *)mkextHeader + mkextPlistOffset;
+    }
+
+   /* IOCFSerialize added a nul byte to the end of the string. Very nice of it.
+    */
+    parsedXML = OSUnserializeXML(mkextPlistDataBuffer, &errorString);
+    if (parsedXML) {
+        mkextPlist = OSDynamicCast(OSDictionary, parsedXML);
+    }
+    if (!mkextPlist) {
+        const char * errorCString = "(unknown error)";
+        
+        if (errorString && errorString->getCStringNoCopy()) {
+            errorCString = errorString->getCStringNoCopy();
+        } else if (parsedXML) {
+            errorCString = "not a dictionary";
+        }
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogErrorLevel |
+            kOSKextLogArchiveFlag,
+            "Error unserializing mkext plist: %s.", errorCString);
+        goto finish;
+    }
+
+   /* If the caller needs the plist, hand it back and retain it.
+    * (This function releases it at the end.)
+    */
+    if (mkextPlistOut) {
+        *mkextPlistOut = mkextPlist;
+        (*mkextPlistOut)->retain();
+    }
+
+    mkextInfoDictArray = OSDynamicCast(OSArray,
+        mkextPlist->getObject(kMKEXTInfoDictionariesKey));
+    if (!mkextInfoDictArray) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogErrorLevel |
+            kOSKextLogArchiveFlag,
+            "Mkext archive contains no kext info dictionaries.");
+        goto finish;
+    }
+
+    count = mkextInfoDictArray->getCount();
+    for (i = 0; i < count; i++) {
+        OSDictionary * infoDict;
+
+
+        infoDict = OSDynamicCast(OSDictionary,
+                                 mkextInfoDictArray->getObject(i));
+        
+       /* Create the kext for the entry, then release it, because the
+        * kext system keeps them around until explicitly removed.
+        * Any creation/registration failures are already logged for us.
+        */
+        if (infoDict) {
+            OSKext * newKext = OSKext::withMkext2Info(infoDict, mkextData);
+            OSSafeRelease(newKext);
+        }
+    }
+
+   /* Even if we didn't keep any kexts from the mkext, we may have a load
+    * request to process, so we are successful (no errors occurred).
+    */
+    result = kOSReturnSuccess;
 
 finish:
-	return result;
-}
-
+
+    OSSafeRelease(parsedXML);
+    OSSafeRelease(mkextPlistUncompressedData);
+    OSSafeRelease(errorString);
+
+    return result;
+}
+
+/*********************************************************************
+*********************************************************************/
 /* static */
-OSReturn
-OSKext::readMkext2Archive(
-	OSData        * mkextData,
-	OSSharedPtr<OSDictionary> &mkextPlistOut,
-	uint32_t      * checksumPtr)
-{
-	OSDictionary * mkextPlist = NULL;
-	OSReturn ret;
-
-	if (kOSReturnSuccess == (ret = readMkext2Archive(mkextData,
-	    &mkextPlist,
-	    checksumPtr))) {
-		mkextPlistOut.reset(mkextPlist, OSNoRetain);
-	}
-	return ret;
-}
-
-/*********************************************************************
-*********************************************************************/
-/* static */
-OSSharedPtr<OSKext>
+OSKext *
 OSKext::withMkext2Info(
-	OSDictionary * anInfoDict,
-	OSData       * mkextData)
-{
-	OSSharedPtr<OSKext> newKext = OSMakeShared<OSKext>();
-
-	if (newKext && !newKext->initWithMkext2Info(anInfoDict, mkextData)) {
-		return NULL;
-	}
-
-	return newKext;
+    OSDictionary * anInfoDict,
+    OSData       * mkextData)
+{
+    OSKext * newKext = new OSKext;
+
+    if (newKext && !newKext->initWithMkext2Info(anInfoDict, mkextData)) {
+        newKext->release();
+        return NULL;
+    }
+
+    return newKext;
 }
 
 /*********************************************************************
 *********************************************************************/
 bool
 OSKext::initWithMkext2Info(
-	OSDictionary * anInfoDict,
-	OSData       * mkextData)
-{
-	bool                   result              = false;
-	OSString             * kextPath            = NULL;        // do not release
-	OSNumber             * executableOffsetNum = NULL;        // do not release
-	OSSharedPtr<OSData>               executable;
-
-	if (anInfoDict == NULL || !super::init()) {
-		goto finish;
-	}
-
-	/* Get the path. Don't look for an arch-specific path property.
-	 */
-	kextPath = OSDynamicCast(OSString,
-	    anInfoDict->getObject(kMKEXTBundlePathKey));
-
-	if (!setInfoDictionaryAndPath(anInfoDict, kextPath)) {
-		goto finish;
-	}
-
-	/* If we have a path to the executable, save it.
-	 */
-	executableRelPath.reset(OSDynamicCast(OSString,
-	    anInfoDict->getObject(kMKEXTExecutableRelativePathKey)), OSRetain);
-
-	/* Don't need the paths to be in the info dictionary any more.
-	 */
-	anInfoDict->removeObject(kMKEXTBundlePathKey);
-	anInfoDict->removeObject(kMKEXTExecutableRelativePathKey);
-
-	executableOffsetNum = OSDynamicCast(OSNumber,
-	    infoDict->getObject(kMKEXTExecutableKey));
-	if (executableOffsetNum) {
-		executable = createMkext2FileEntry(mkextData,
-		    executableOffsetNum, "executable");
-		infoDict->removeObject(kMKEXTExecutableKey);
-		if (!executable) {
-			goto finish;
-		}
-		if (!setExecutable(executable.get(), mkextData, true)) {
-			goto finish;
-		}
-	}
-
-	result = (registerIdentifier() == kOSKextInitialized);
+    OSDictionary * anInfoDict,
+    OSData       * mkextData)
+{
+    bool                   result              = false;
+    OSString             * kextPath            = NULL;  // do not release
+    OSNumber             * executableOffsetNum = NULL;  // do not release
+    OSCollectionIterator * iterator            = NULL;  // must release
+    OSData               * executable          = NULL;  // must release
+
+    if (anInfoDict == NULL || !super::init()) {
+        goto finish;
+    }
+
+   /* Get the path. Don't look for an arch-specific path property.
+    */
+    kextPath = OSDynamicCast(OSString,
+                             anInfoDict->getObject(kMKEXTBundlePathKey));
+
+    if (!setInfoDictionaryAndPath(anInfoDict, kextPath)) {
+        goto finish;
+    }
+
+   /* If we have a path to the executable, save it.
+    */
+    executableRelPath = OSDynamicCast(OSString,
+        anInfoDict->getObject(kMKEXTExecutableRelativePathKey));
+    if (executableRelPath) {
+        executableRelPath->retain();
+    }
+
+   /* Don't need the paths to be in the info dictionary any more.
+    */
+    anInfoDict->removeObject(kMKEXTBundlePathKey);
+    anInfoDict->removeObject(kMKEXTExecutableRelativePathKey);
+
+    executableOffsetNum = OSDynamicCast(OSNumber,
+        infoDict->getObject(kMKEXTExecutableKey));
+    if (executableOffsetNum) {
+        executable = createMkext2FileEntry(mkextData,
+            executableOffsetNum, "executable");
+        infoDict->removeObject(kMKEXTExecutableKey);
+        if (!executable) {
+            goto finish;
+        }
+        if (!setExecutable(executable, mkextData, true)) {
+            goto finish;
+        }
+    }
+
+    result = registerIdentifier();
+
 finish:
-	return result;
-}
-
-/*********************************************************************
-*********************************************************************/
-OSSharedPtr<OSData>
+
+    OSSafeRelease(executable);
+    OSSafeRelease(iterator);
+    return result;
+}
+
+/*********************************************************************
+*********************************************************************/
+OSData *
 OSKext::createMkext2FileEntry(
-	OSData     * mkextData,
-	OSNumber   * offsetNum,
-	const char * name)
-{
-	OSSharedPtr<OSData> result;
-	MkextEntryRef   entryRef;
-	uint8_t       * mkextBuffer = (uint8_t *)mkextData->getBytesNoCopy();
-	uint32_t        entryOffset = offsetNum->unsigned32BitValue();
-
-	result = OSData::withCapacity(sizeof(entryRef));
-	if (!result) {
-		goto finish;
-	}
-
-	entryRef.mkext = (mkext_basic_header *)mkextBuffer;
-	entryRef.fileinfo = mkextBuffer + entryOffset;
-	if (!result->appendValue(entryRef)) {
-		result.reset();
-		goto finish;
-	}
+    OSData     * mkextData,
+    OSNumber   * offsetNum,
+    const char * name)
+{
+    OSData        * result      = NULL;
+    MkextEntryRef   entryRef;
+    uint8_t       * mkextBuffer = (uint8_t *)mkextData->getBytesNoCopy();
+    uint32_t        entryOffset = offsetNum->unsigned32BitValue();
+
+    result = OSData::withCapacity(sizeof(entryRef));
+    if (!result) {
+        goto finish;
+    }
+
+    entryRef.mkext = (mkext_basic_header *)mkextBuffer;
+    entryRef.fileinfo = mkextBuffer + entryOffset;
+    if (!result->appendBytes(&entryRef, sizeof(entryRef))) {
+        OSSafeReleaseNULL(result);
+        goto finish;
+    }
 
 finish:
-	if (!result) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogArchiveFlag,
-		    "Can't create wrapper for mkext file entry '%s' of kext %s.",
-		    name, getIdentifierCString());
-	}
-	return result;
+    if (!result) {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogArchiveFlag,
+            "Can't create wrapper for mkext file entry '%s' of kext %s.",
+            name, getIdentifierCString());
+    }
+    return result;
 }
 
 /*********************************************************************
@@ -3770,8 +2652,8 @@
 static void   z_free(void *, void *ptr);
 
 typedef struct z_mem {
-	uint32_t alloc_size;
-	uint8_t  data[0];
+    uint32_t alloc_size;
+    uint8_t  data[0];
 } z_mem;
 
 /*
@@ -3780,208 +2662,211 @@
 void *
 z_alloc(void * notused __unused, u_int num_items, u_int size)
 {
-	void     * result = NULL;
-	z_mem    * zmem = NULL;
-
-	uint64_t   total = ((uint64_t)num_items) * ((uint64_t)size);
-	//Check for overflow due to multiplication
-	if (total > UINT32_MAX) {
-		panic("z_alloc(%p, %x, %x): overflow caused by %x * %x",
-		    notused, num_items, size, num_items, size);
-	}
-
-	uint64_t   allocSize64 =  total + ((uint64_t)sizeof(zmem));
-	//Check for overflow due to addition
-	if (allocSize64 > UINT32_MAX) {
-		panic("z_alloc(%p, %x, %x): overflow caused by %x + %lx",
-		    notused, num_items, size, (uint32_t)total, sizeof(zmem));
-	}
-	uint32_t allocSize = (uint32_t)allocSize64;
-
-	zmem = (z_mem *)kalloc_data_tag(allocSize, Z_WAITOK,
-	    VM_KERN_MEMORY_OSKEXT);
-	if (!zmem) {
-		goto finish;
-	}
-	zmem->alloc_size = allocSize;
-	result = (void *)&(zmem->data);
+    void     * result = NULL;
+    z_mem    * zmem = NULL;
+
+    uint64_t   total = ((uint64_t)num_items) * ((uint64_t)size);
+    //Check for overflow due to multiplication 
+    if (total > UINT32_MAX){
+        panic("z_alloc(%p, %x, %x): overflow caused by %x * %x\n",
+               notused, num_items, size, num_items, size);
+    }
+    
+    uint64_t   allocSize64 =  total + ((uint64_t)sizeof(zmem));
+    //Check for overflow due to addition
+    if (allocSize64 > UINT32_MAX){
+        panic("z_alloc(%p, %x, %x): overflow caused by %x + %lx\n",
+               notused, num_items, size, (uint32_t)total, sizeof(zmem));
+    }
+    uint32_t allocSize = (uint32_t)allocSize64;
+
+    zmem = (z_mem *)kalloc_tag(allocSize, VM_KERN_MEMORY_OSKEXT);
+    if (!zmem) {
+        goto finish;
+    }
+    zmem->alloc_size = allocSize;
+    result = (void *)&(zmem->data);
 finish:
-	return result;
+    return result;
 }
 
 void
 z_free(void * notused __unused, void * ptr)
 {
-	uint32_t * skipper = (uint32_t *)ptr - 1;
-	z_mem    * zmem = (z_mem *)skipper;
-	kfree_data(zmem, zmem->alloc_size);
+    uint32_t * skipper = (uint32_t *)ptr - 1;
+    z_mem    * zmem = (z_mem *)skipper;
+    kfree((void *)zmem, zmem->alloc_size);
+    return;
 }
 };
 
-OSSharedPtr<OSData>
+OSData *
 OSKext::extractMkext2FileData(
-	UInt8      * data,
-	const char * name,
-	uint32_t     compressedSize,
-	uint32_t     fullSize)
-{
-	OSSharedPtr<OSData>      result;
-	OSSharedPtr<OSData>      uncompressedData;        // release on error
-
-	uint8_t     * uncompressedDataBuffer = NULL;        // do not free
-	unsigned long uncompressedSize;
-	z_stream      zstream;
-	bool          zstream_inited = false;
-	int           zlib_result;
-
-	/* If the file isn't compressed, we want to make a copy
-	 * so that we don't have the tie to the larger mkext file buffer any more.
-	 */
-	if (!compressedSize) {
-		uncompressedData = OSData::withBytes(data, fullSize);
-		// xxx - no check for failure?
-		result = uncompressedData;
-		goto finish;
-	}
-
-	if (KERN_SUCCESS != kmem_alloc(kernel_map,
-	    (vm_offset_t*)&uncompressedDataBuffer, fullSize,
-	    KMA_DATA_SHARED, VM_KERN_MEMORY_OSKEXT)) {
-		/* How's this for cheesy? The kernel is only asked to extract
-		 * kext plists so we tailor the log messages.
-		 */
-		if (isKernel()) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogArchiveFlag,
-			    "Allocation failure extracting %s from mkext.", name);
-		} else {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogArchiveFlag,
-			    "Allocation failure extracting %s from mkext for kext %s.",
-			    name, getIdentifierCString());
-		}
-
-		goto finish;
-	}
-	uncompressedData = OSData::withBytesNoCopy(uncompressedDataBuffer, fullSize);
-	if (!uncompressedData) {
-		if (isKernel()) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogArchiveFlag,
-			    "Allocation failure extracting %s from mkext.", name);
-		} else {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogArchiveFlag,
-			    "Allocation failure extracting %s from mkext for kext %s.",
-			    name, getIdentifierCString());
-		}
-		goto finish;
-	}
-	uncompressedData->setDeallocFunction(&osdata_kmem_free);
-
-	if (isKernel()) {
-		OSKextLog(this,
-		    kOSKextLogDetailLevel |
-		    kOSKextLogArchiveFlag,
-		    "Kernel extracted %s from mkext - compressed size %d, uncompressed size %d.",
-		    name, compressedSize, fullSize);
-	} else {
-		OSKextLog(this,
-		    kOSKextLogDetailLevel |
-		    kOSKextLogArchiveFlag,
-		    "Kext %s extracted %s from mkext - compressed size %d, uncompressed size %d.",
-		    getIdentifierCString(), name, compressedSize, fullSize);
-	}
-
-	bzero(&zstream, sizeof(zstream));
-	zstream.next_in   = (UInt8 *)data;
-	zstream.avail_in  = compressedSize;
-
-	zstream.next_out  = uncompressedDataBuffer;
-	zstream.avail_out = fullSize;
-
-	zstream.zalloc    = z_alloc;
-	zstream.zfree     = z_free;
-
-	zlib_result = inflateInit(&zstream);
-	if (Z_OK != zlib_result) {
-		if (isKernel()) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogArchiveFlag,
-			    "Mkext error; zlib inflateInit failed (%d) for %s.",
-			    zlib_result, name);
-		} else {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogArchiveFlag,
-			    "Kext %s - mkext error; zlib inflateInit failed (%d) for %s .",
-			    getIdentifierCString(), zlib_result, name);
-		}
-		goto finish;
-	} else {
-		zstream_inited = true;
-	}
-
-	zlib_result = inflate(&zstream, Z_FINISH);
-
-	if (zlib_result == Z_STREAM_END || zlib_result == Z_OK) {
-		uncompressedSize = zstream.total_out;
-	} else {
-		if (isKernel()) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogArchiveFlag,
-			    "Mkext error; zlib inflate failed (%d) for %s.",
-			    zlib_result, name);
-		} else {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogArchiveFlag,
-			    "Kext %s - mkext error; zlib inflate failed (%d) for %s .",
-			    getIdentifierCString(), zlib_result, name);
-		}
-		if (zstream.msg) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogArchiveFlag,
-			    "zlib error: %s.", zstream.msg);
-		}
-		goto finish;
-	}
-
-	if (uncompressedSize != fullSize) {
-		if (isKernel()) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogArchiveFlag,
-			    "Mkext error; zlib inflate discrepancy for %s, "
-			    "uncompressed size != original size.", name);
-		} else {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogArchiveFlag,
-			    "Kext %s - mkext error; zlib inflate discrepancy for %s, "
-			    "uncompressed size != original size.",
-			    getIdentifierCString(), name);
-		}
-		goto finish;
-	}
-
-	result = os::move(uncompressedData);
+    UInt8      * data,
+    const char * name,
+    uint32_t     compressedSize,
+    uint32_t     fullSize)
+{
+    OSData      * result = NULL;
+    
+    OSData      * uncompressedData = NULL;   // release on error
+
+    uint8_t     * uncompressedDataBuffer = 0;    // do not free
+    unsigned long uncompressedSize;
+    z_stream      zstream;
+    bool          zstream_inited = false;
+    int           zlib_result;
+
+   /* If the file isn't compressed, we want to make a copy
+    * so that we don't have the tie to the larger mkext file buffer any more.
+    */
+    if (!compressedSize) {
+        uncompressedData = OSData::withBytes(data, fullSize);
+        // xxx - no check for failure?
+        result = uncompressedData;
+        goto finish;
+    }
+
+    if (KERN_SUCCESS != kmem_alloc(kernel_map,
+        (vm_offset_t*)&uncompressedDataBuffer, fullSize, VM_KERN_MEMORY_OSKEXT)) {
+
+       /* How's this for cheesy? The kernel is only asked to extract
+        * kext plists so we tailor the log messages.
+        */
+        if (isKernel()) {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogArchiveFlag,
+                "Allocation failure extracting %s from mkext.", name);
+        } else {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogArchiveFlag,
+                "Allocation failure extracting %s from mkext for kext %s.",
+                name, getIdentifierCString());
+        }
+
+        goto finish;
+    }
+    uncompressedData = OSData::withBytesNoCopy(uncompressedDataBuffer, fullSize);
+    if (!uncompressedData) {
+        if (isKernel()) {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogArchiveFlag,
+                "Allocation failure extracting %s from mkext.", name);
+        } else {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogArchiveFlag,
+                "Allocation failure extracting %s from mkext for kext %s.",
+                name, getIdentifierCString());
+        }
+        goto finish;
+    }
+    uncompressedData->setDeallocFunction(&osdata_kmem_free);
+
+    if (isKernel()) {
+        OSKextLog(this,
+            kOSKextLogDetailLevel |
+            kOSKextLogArchiveFlag,
+            "Kernel extracted %s from mkext - compressed size %d, uncompressed size %d.",
+            name, compressedSize, fullSize);
+    } else {
+        OSKextLog(this,
+            kOSKextLogDetailLevel |
+            kOSKextLogArchiveFlag,
+            "Kext %s extracted %s from mkext - compressed size %d, uncompressed size %d.",
+            getIdentifierCString(), name, compressedSize, fullSize);
+    }
+
+    bzero(&zstream, sizeof(zstream));
+    zstream.next_in   = (UInt8 *)data;
+    zstream.avail_in  = compressedSize;
+
+    zstream.next_out  = uncompressedDataBuffer;
+    zstream.avail_out = fullSize;
+
+    zstream.zalloc    = z_alloc;
+    zstream.zfree     = z_free;
+
+    zlib_result = inflateInit(&zstream);
+    if (Z_OK != zlib_result) {
+        if (isKernel()) {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogArchiveFlag,
+                "Mkext error; zlib inflateInit failed (%d) for %s.",
+                zlib_result, name);
+        } else {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogArchiveFlag,
+                "Kext %s - mkext error; zlib inflateInit failed (%d) for %s .",
+                getIdentifierCString(), zlib_result, name);
+        }
+        goto finish;
+    } else {
+        zstream_inited = true;
+    }
+
+    zlib_result = inflate(&zstream, Z_FINISH);
+
+    if (zlib_result == Z_STREAM_END || zlib_result == Z_OK) {
+        uncompressedSize = zstream.total_out;
+    } else {
+        if (isKernel()) {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogArchiveFlag,
+                "Mkext error; zlib inflate failed (%d) for %s.",
+                zlib_result, name);
+        } else {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogArchiveFlag,
+                "Kext %s - mkext error; zlib inflate failed (%d) for %s .",
+                getIdentifierCString(), zlib_result, name);
+        }
+        if (zstream.msg) {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogArchiveFlag,
+                "zlib error: %s.", zstream.msg);
+        }
+        goto finish;
+    }
+
+    if (uncompressedSize != fullSize) {
+        if (isKernel()) {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogArchiveFlag,
+                "Mkext error; zlib inflate discrepancy for %s, "
+                "uncompressed size != original size.", name);
+        } else {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogArchiveFlag,
+                "Kext %s - mkext error; zlib inflate discrepancy for %s, "
+                "uncompressed size != original size.",
+                getIdentifierCString(), name);
+        }
+        goto finish;
+    }
+
+    result = uncompressedData;
 
 finish:
-	/* Don't bother checking return, nothing we can do on fail.
-	 */
-	if (zstream_inited) {
-		inflateEnd(&zstream);
-	}
-
-	return result;
+   /* Don't bother checking return, nothing we can do on fail.
+    */
+    if (zstream_inited) inflateEnd(&zstream);
+
+    if (!result) {
+        OSSafeRelease(uncompressedData);
+    }
+
+    return result;
 }
 
 /*********************************************************************
@@ -3989,282 +2874,283 @@
 /* static */
 OSReturn
 OSKext::loadFromMkext(
-	OSKextLogSpec   clientLogFilter,
-	char          * mkextBuffer,
-	uint32_t        mkextBufferLength,
-	char         ** logInfoOut,
-	uint32_t      * logInfoLengthOut)
-{
-	OSReturn         result                      = kOSReturnError;
-	OSReturn         tempResult                  = kOSReturnError;
-
-	OSSharedPtr<OSData>        mkextData;
-	OSSharedPtr<OSDictionary>  mkextPlist;
-
-	OSSharedPtr<OSArray>       logInfoArray;
-	OSSharedPtr<OSSerialize>   serializer;
-
-	OSString       * predicate                   = NULL;        // do not release
-	OSDictionary   * requestArgs                 = NULL;        // do not release
-
-	OSString       * kextIdentifier              = NULL;        // do not release
-	OSNumber       * startKextExcludeNum         = NULL;        // do not release
-	OSNumber       * startMatchingExcludeNum     = NULL;        // do not release
-	OSBoolean      * delayAutounloadBool         = NULL;        // do not release
-	OSArray        * personalityNames            = NULL;        // do not release
-
-	/* Default values for these two options: regular autounload behavior,
-	 * load all kexts, send no personalities.
-	 */
-	Boolean            delayAutounload           = false;
-	OSKextExcludeLevel startKextExcludeLevel     = kOSKextExcludeNone;
-	OSKextExcludeLevel startMatchingExcludeLevel = kOSKextExcludeAll;
-
-	IORecursiveLockLock(sKextLock);
-
-	if (logInfoOut) {
-		*logInfoOut = NULL;
-		*logInfoLengthOut = 0;
-	}
-
-	OSKext::setUserSpaceLogFilter(clientLogFilter, logInfoOut ? true : false);
-
-	OSKextLog(/* kext */ NULL,
-	    kOSKextLogDebugLevel |
-	    kOSKextLogIPCFlag,
-	    "Received kext load request from user space.");
-
-	/* Regardless of processing, the fact that we have gotten here means some
-	 * user-space program is up and talking to us, so we'll switch our kext
-	 * registration to reflect that.
-	 */
-	if (!sUserLoadsActive) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogProgressLevel |
-		    kOSKextLogGeneralFlag | kOSKextLogLoadFlag,
-		    "Switching to late startup (user-space) kext loading policy.");
-
-		sUserLoadsActive = true;
-	}
-
-	if (!sLoadEnabled) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag,
-		    "Kext loading is disabled.");
-		result = kOSKextReturnDisabled;
-		goto finish;
-	}
-
-	/* Note that we do not set a dealloc function on this OSData
-	 * object! No references to it can remain after the loadFromMkext()
-	 * call since we are in a MIG function, and will vm_deallocate()
-	 * the buffer.
-	 */
-	mkextData = OSData::withBytesNoCopy(mkextBuffer,
-	    mkextBufferLength);
-	if (!mkextData) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag | kOSKextLogIPCFlag,
-		    "Failed to create wrapper for kext load request.");
-		result = kOSKextReturnNoMemory;
-		goto finish;
-	}
-
-	result = readMkext2Archive(mkextData.get(), mkextPlist, NULL);
-	if (result != kOSReturnSuccess) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag,
-		    "Failed to read kext load request.");
-		goto finish;
-	}
-
-	predicate = _OSKextGetRequestPredicate(mkextPlist.get());
-	if (!predicate || !predicate->isEqualTo(kKextRequestPredicateLoad)) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag,
-		    "Received kext load request with no predicate; skipping.");
-		result = kOSKextReturnInvalidArgument;
-		goto finish;
-	}
-
-	requestArgs = OSDynamicCast(OSDictionary,
-	    mkextPlist->getObject(kKextRequestArgumentsKey));
-	if (!requestArgs || !requestArgs->getCount()) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag,
-		    "Received kext load request with no arguments.");
-		result = kOSKextReturnInvalidArgument;
-		goto finish;
-	}
-
-	kextIdentifier = OSDynamicCast(OSString,
-	    requestArgs->getObject(kKextRequestArgumentBundleIdentifierKey));
-
-	if (!kextIdentifier) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag,
-		    "Received kext load request with no kext identifier.");
-		result = kOSKextReturnInvalidArgument;
-		goto finish;
-	}
-
-	startKextExcludeNum = OSDynamicCast(OSNumber,
-	    requestArgs->getObject(kKextRequestArgumentStartExcludeKey));
-	startMatchingExcludeNum = OSDynamicCast(OSNumber,
-	    requestArgs->getObject(kKextRequestArgumentStartMatchingExcludeKey));
-	delayAutounloadBool = OSDynamicCast(OSBoolean,
-	    requestArgs->getObject(kKextRequestArgumentDelayAutounloadKey));
-	personalityNames = OSDynamicCast(OSArray,
-	    requestArgs->getObject(kKextRequestArgumentPersonalityNamesKey));
-
-	if (delayAutounloadBool) {
-		delayAutounload = delayAutounloadBool->getValue();
-	}
-	if (startKextExcludeNum) {
-		startKextExcludeLevel = startKextExcludeNum->unsigned8BitValue();
-	}
-	if (startMatchingExcludeNum) {
-		startMatchingExcludeLevel = startMatchingExcludeNum->unsigned8BitValue();
-	}
-
-	OSKextLog(/* kext */ NULL,
-	    kOSKextLogProgressLevel |
-	    kOSKextLogIPCFlag,
-	    "Received request from user space to load kext %s.",
-	    kextIdentifier->getCStringNoCopy());
-
-	/* Load the kext, with no deferral, since this is a load from outside
-	 * the kernel.
-	 * xxx - Would like a better way to handle the default values for the
-	 * xxx - start/match opt args.
-	 */
-	result = OSKext::loadKextWithIdentifier(
-		kextIdentifier,
-		/* kextRef */ NULL,
-		/* allowDefer */ false,
-		delayAutounload,
-		startKextExcludeLevel,
-		startMatchingExcludeLevel,
-		personalityNames);
-	if (result != kOSReturnSuccess) {
-		goto finish;
-	}
-	/* If the load came down from the IOKit daemon, it will shortly inform IOCatalogue
-	 * for matching via a separate IOKit calldown.
-	 */
+    OSKextLogSpec   clientLogFilter,
+    char          * mkextBuffer,
+    uint32_t        mkextBufferLength,
+    char         ** logInfoOut,
+    uint32_t      * logInfoLengthOut)
+{
+    OSReturn         result                      = kOSReturnError;
+    OSReturn         tempResult                  = kOSReturnError;
+
+    OSData         * mkextData                   = NULL;  // must release
+    OSDictionary   * mkextPlist                  = NULL;  // must release
+
+    OSArray        * logInfoArray                = NULL;  // must release
+    OSSerialize    * serializer                  = NULL;  // must release
+
+    OSString       * predicate                   = NULL;  // do not release
+    OSDictionary   * requestArgs                 = NULL;  // do not release
+
+    OSString       * kextIdentifier              = NULL;  // do not release
+    OSNumber       * startKextExcludeNum         = NULL;  // do not release
+    OSNumber       * startMatchingExcludeNum     = NULL;  // do not release
+    OSBoolean      * delayAutounloadBool         = NULL;  // do not release
+    OSArray        * personalityNames            = NULL;  // do not release
+
+   /* Default values for these two options: regular autounload behavior,
+    * load all kexts, send no personalities.
+    */
+    Boolean            delayAutounload           = false;
+    OSKextExcludeLevel startKextExcludeLevel     = kOSKextExcludeNone;
+    OSKextExcludeLevel startMatchingExcludeLevel = kOSKextExcludeAll;
+    
+    IORecursiveLockLock(sKextLock);
+
+    if (logInfoOut) {
+        *logInfoOut = NULL;
+        *logInfoLengthOut = 0;
+    }
+
+    OSKext::setUserSpaceLogFilter(clientLogFilter, logInfoOut ? true : false);
+
+    OSKextLog(/* kext */ NULL,
+        kOSKextLogDebugLevel |
+        kOSKextLogIPCFlag,
+        "Received kext load request from user space.");
+    
+   /* Regardless of processing, the fact that we have gotten here means some
+    * user-space program is up and talking to us, so we'll switch our kext
+    * registration to reflect that.
+    */
+    if (!sUserLoadsActive) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogProgressLevel |
+            kOSKextLogGeneralFlag | kOSKextLogLoadFlag,
+            "Switching to late startup (user-space) kext loading policy.");
+
+        sUserLoadsActive = true;
+    }
+  
+    if (!sLoadEnabled) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogErrorLevel |
+            kOSKextLogLoadFlag,
+            "Kext loading is disabled.");
+        result = kOSKextReturnDisabled;
+        goto finish;
+    }
+
+   /* Note that we do not set a dealloc function on this OSData
+    * object! No references to it can remain after the loadFromMkext()
+    * call since we are in a MIG function, and will vm_deallocate()
+    * the buffer.
+    */
+    mkextData = OSData::withBytesNoCopy(mkextBuffer,
+        mkextBufferLength);
+    if (!mkextData) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogErrorLevel |
+            kOSKextLogLoadFlag | kOSKextLogIPCFlag,
+            "Failed to create wrapper for kext load request.");
+        result = kOSKextReturnNoMemory;
+        goto finish;
+    }
+
+    result = readMkext2Archive(mkextData, &mkextPlist, NULL);
+    if (result != kOSReturnSuccess) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogErrorLevel |
+            kOSKextLogLoadFlag,
+            "Failed to read kext load request.");
+        goto finish;
+    }
+
+    predicate = _OSKextGetRequestPredicate(mkextPlist);
+    if (!predicate || !predicate->isEqualTo(kKextRequestPredicateLoad)) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogErrorLevel |
+            kOSKextLogLoadFlag,
+            "Received kext load request with no predicate; skipping.");
+        result = kOSKextReturnInvalidArgument;
+        goto finish;
+    }
+
+    requestArgs = OSDynamicCast(OSDictionary,
+        mkextPlist->getObject(kKextRequestArgumentsKey));
+    if (!requestArgs || !requestArgs->getCount()) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogErrorLevel |
+            kOSKextLogLoadFlag,
+            "Received kext load request with no arguments.");
+        result = kOSKextReturnInvalidArgument;
+        goto finish;
+    }
+
+    kextIdentifier = OSDynamicCast(OSString,
+        requestArgs->getObject(kKextRequestArgumentBundleIdentifierKey));
+    if (!kextIdentifier) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogErrorLevel |
+            kOSKextLogLoadFlag,
+            "Received kext load request with no kext identifier.");
+        result = kOSKextReturnInvalidArgument;
+        goto finish;
+    }
+
+    startKextExcludeNum = OSDynamicCast(OSNumber,
+        requestArgs->getObject(kKextRequestArgumentStartExcludeKey));
+    startMatchingExcludeNum = OSDynamicCast(OSNumber,
+        requestArgs->getObject(kKextRequestArgumentStartMatchingExcludeKey));
+    delayAutounloadBool = OSDynamicCast(OSBoolean,
+        requestArgs->getObject(kKextRequestArgumentDelayAutounloadKey));
+    personalityNames = OSDynamicCast(OSArray,
+        requestArgs->getObject(kKextRequestArgumentPersonalityNamesKey));
+
+    if (delayAutounloadBool) {
+        delayAutounload = delayAutounloadBool->getValue();
+    }
+    if (startKextExcludeNum) {
+        startKextExcludeLevel = startKextExcludeNum->unsigned8BitValue();
+    }
+    if (startMatchingExcludeNum) {
+        startMatchingExcludeLevel = startMatchingExcludeNum->unsigned8BitValue();
+    }
+    
+    OSKextLog(/* kext */ NULL,
+        kOSKextLogProgressLevel |
+        kOSKextLogIPCFlag,
+        "Received request from user space to load kext %s.",
+        kextIdentifier->getCStringNoCopy());
+
+   /* Load the kext, with no deferral, since this is a load from outside
+    * the kernel.
+    * xxx - Would like a better way to handle the default values for the
+    * xxx - start/match opt args.
+    */
+    result = OSKext::loadKextWithIdentifier(
+        kextIdentifier,
+        /* allowDefer */ false,
+        delayAutounload,
+        startKextExcludeLevel,
+        startMatchingExcludeLevel,
+        personalityNames);
+    if (result != kOSReturnSuccess) {
+        goto finish;
+    }
+   /* If the load came down from kextd, it will shortly inform IOCatalogue
+    * for matching via a separate IOKit calldown.
+    */
 
 finish:
 
-	/* Gather up the collected log messages for user space. Any
-	 * error messages past this call will not make it up as log messages
-	 * but will be in the system log.
-	 */
-	logInfoArray = OSKext::clearUserSpaceLogFilter();
-
-	if (logInfoArray && logInfoOut && logInfoLengthOut) {
-		tempResult = OSKext::serializeLogInfo(logInfoArray.get(),
-		    logInfoOut, logInfoLengthOut);
-		if (tempResult != kOSReturnSuccess) {
-			result = tempResult;
-		}
-	}
-
-	OSKext::flushNonloadedKexts(/* flushPrelinkedKexts */ false);
-
-	IORecursiveLockUnlock(sKextLock);
-
-	/* Note: mkextDataObject will have been retained by every kext w/an
-	 * executable in it. That should all have been flushed out at the
-	 * and of the load operation, but you never know....
-	 */
-	if (mkextData && mkextData->getRetainCount() > 1) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag | kOSKextLogIPCFlag,
-		    "Kext load request buffer from user space still retained by a kext; "
-		    "probable memory leak.");
-	}
-
-	return result;
-}
-
-#endif // CONFIG_KXLD
+   /* Gather up the collected log messages for user space. Any
+    * error messages past this call will not make it up as log messages
+    * but will be in the system log.
+    */
+    logInfoArray = OSKext::clearUserSpaceLogFilter();
+
+    if (logInfoArray && logInfoOut && logInfoLengthOut) {
+        tempResult = OSKext::serializeLogInfo(logInfoArray,
+            logInfoOut, logInfoLengthOut);
+        if (tempResult != kOSReturnSuccess) {
+            result = tempResult;
+        }
+    }
+
+    OSKext::flushNonloadedKexts(/* flushPrelinkedKexts */ false);
+
+   /* Note: mkextDataObject will have been retained by every kext w/an
+    * executable in it. That should all have been flushed out at the
+    * and of the load operation, but you never know....
+    */
+    if (mkextData && mkextData->getRetainCount() > 1) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogErrorLevel |
+            kOSKextLogLoadFlag | kOSKextLogIPCFlag,
+            "Kext load request buffer from user space still retained by a kext; "
+            "probable memory leak.");
+    }
+
+    IORecursiveLockUnlock(sKextLock);
+
+    OSSafeRelease(mkextData);
+    OSSafeRelease(mkextPlist);
+    OSSafeRelease(serializer);
+    OSSafeRelease(logInfoArray);
+
+    return result;
+}
 
 /*********************************************************************
 *********************************************************************/
 /* static */
 OSReturn
 OSKext::serializeLogInfo(
-	OSArray   * logInfoArray,
-	char     ** logInfoOut,
-	uint32_t  * logInfoLengthOut)
-{
-	OSReturn        result      = kOSReturnError;
-	char          * buffer      = NULL;
-	kern_return_t   kmem_result = KERN_FAILURE;
-	OSSharedPtr<OSSerialize>  serializer;
-	char         * logInfo            = NULL;        // returned by reference
-	uint32_t       logInfoLength      = 0;
-
-	if (!logInfoArray || !logInfoOut || !logInfoLengthOut) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogIPCFlag,
-		    "Internal error; invalid arguments to OSKext::serializeLogInfo().");
-		/* Bad programmer. */
-		result = kOSKextReturnInvalidArgument;
-		goto finish;
-	}
-
-	serializer = OSSerialize::withCapacity(0);
-	if (!serializer) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogIPCFlag,
-		    "Failed to create serializer on log info for request from user space.");
-		/* Incidental error; we're going to (try to) allow the request
-		 * itself to succeed. */
-	} else {
-		if (!logInfoArray->serialize(serializer.get())) {
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogIPCFlag,
-			    "Failed to serialize log info for request from user space.");
-			/* Incidental error; we're going to (try to) allow the request
-			 * itself to succeed. */
-		} else {
-			logInfo = serializer->text();
-			logInfoLength = serializer->getLength();
-
-			kmem_result = kmem_alloc(kernel_map, (vm_offset_t *)&buffer, round_page(logInfoLength),
-			    KMA_DATA_SHARED, VM_KERN_MEMORY_OSKEXT);
-			if (kmem_result != KERN_SUCCESS) {
-				OSKextLog(/* kext */ NULL,
-				    kOSKextLogErrorLevel |
-				    kOSKextLogIPCFlag,
-				    "Failed to copy log info for request from user space.");
-				/* Incidental error; we're going to (try to) allow the request
-				 * to succeed. */
-			} else {
-				/* 11981737 - clear uninitialized data in last page */
-				bzero((void *)(buffer + logInfoLength),
-				    (round_page(logInfoLength) - logInfoLength));
-				memcpy(buffer, logInfo, logInfoLength);
-				*logInfoOut = buffer;
-				*logInfoLengthOut = logInfoLength;
-			}
-		}
-	}
-
-	result = kOSReturnSuccess;
+    OSArray   * logInfoArray,
+    char     ** logInfoOut,
+    uint32_t  * logInfoLengthOut)
+{
+    OSReturn        result      = kOSReturnError;
+    char          * buffer      = NULL;
+    kern_return_t   kmem_result = KERN_FAILURE;
+    OSSerialize  * serializer   = NULL;  // must release; reused
+    char         * logInfo            = NULL;  // returned by reference
+    uint32_t       logInfoLength      = 0;
+
+    if (!logInfoArray || !logInfoOut || !logInfoLengthOut) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogErrorLevel |
+            kOSKextLogIPCFlag,
+            "Internal error; invalid arguments to OSKext::serializeLogInfo().");
+       /* Bad programmer. */
+        result = kOSKextReturnInvalidArgument;
+        goto finish;
+    }
+
+    serializer = OSSerialize::withCapacity(0);
+    if (!serializer) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogErrorLevel |
+            kOSKextLogIPCFlag,
+            "Failed to create serializer on log info for request from user space.");
+       /* Incidental error; we're going to (try to) allow the request
+        * itself to succeed. */
+    }
+
+    if (!logInfoArray->serialize(serializer)) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogErrorLevel |
+            kOSKextLogIPCFlag,
+            "Failed to serialize log info for request from user space.");
+       /* Incidental error; we're going to (try to) allow the request
+        * itself to succeed. */
+    } else {
+        logInfo = serializer->text();
+        logInfoLength = serializer->getLength();
+
+        kmem_result = kmem_alloc(kernel_map, (vm_offset_t *)&buffer, round_page(logInfoLength), VM_KERN_MEMORY_OSKEXT);
+        if (kmem_result != KERN_SUCCESS) {
+            OSKextLog(/* kext */ NULL,
+                kOSKextLogErrorLevel |
+                kOSKextLogIPCFlag,
+                "Failed to copy log info for request from user space.");
+           /* Incidental error; we're going to (try to) allow the request
+            * to succeed. */
+        } else {
+            /* 11981737 - clear uninitialized data in last page */
+            bzero((void *)(buffer + logInfoLength),
+                  (round_page(logInfoLength) - logInfoLength));
+            memcpy(buffer, logInfo, logInfoLength);
+            *logInfoOut = buffer;
+            *logInfoLengthOut = logInfoLength;
+        }
+    }
+    
+    result = kOSReturnSuccess;
 finish:
-	return result;
+    OSSafeRelease(serializer);
+    return result;
 }
 
 #if PRAGMA_MARK
@@ -4272,252 +3158,130 @@
 #endif
 /*********************************************************************
 *********************************************************************/
-OSSharedPtr<OSKext>
+OSKext *
 OSKext::lookupKextWithIdentifier(const char * kextIdentifier)
 {
-	OSSharedPtr<OSKext> foundKext;
-
-	IORecursiveLockLock(sKextLock);
-	foundKext.reset(OSDynamicCast(OSKext, sKextsByID->getObject(kextIdentifier)), OSRetain);
-	IORecursiveLockUnlock(sKextLock);
-
-	return foundKext;
-}
-
-/*********************************************************************
-*********************************************************************/
-OSSharedPtr<OSKext>
+    OSKext * foundKext = NULL;
+
+    IORecursiveLockLock(sKextLock);
+    foundKext = OSDynamicCast(OSKext, sKextsByID->getObject(kextIdentifier));
+    if (foundKext) {
+        foundKext->retain();
+    }
+    IORecursiveLockUnlock(sKextLock);
+
+    return foundKext;
+}
+
+/*********************************************************************
+*********************************************************************/
+OSKext *
 OSKext::lookupKextWithIdentifier(OSString * kextIdentifier)
 {
-	return OSKext::lookupKextWithIdentifier(kextIdentifier->getCStringNoCopy());
-}
-
-/*********************************************************************
-*********************************************************************/
-OSSharedPtr<OSKext>
-OSKext::lookupDextWithIdentifier(OSString * dextIdentifier, OSData *dextUniqueIdentifier)
-{
-	OSSharedPtr<OSKext> foundDext;
-	foundDext.reset();
-
-	IORecursiveLockLock(sKextLock);
-	OSKext *dext = OSDynamicCast(OSKext, sKextsByID->getObject(dextIdentifier->getCStringNoCopy()));
-	if (dext != NULL && dext->isDriverKit()) {
-		if (dext->dextUniqueID == NULL || dext->dextUniqueID->isEqualTo(dextUniqueIdentifier)) {
-			foundDext.reset(dext, OSRetain);
-		}
-	}
-	IORecursiveLockUnlock(sKextLock);
-
-	return foundDext;
-}
-
-/*********************************************************************
-*********************************************************************/
-OSSharedPtr<OSKext>
+    return OSKext::lookupKextWithIdentifier(kextIdentifier->getCStringNoCopy());
+}
+
+/*********************************************************************
+*********************************************************************/
+OSKext *
 OSKext::lookupKextWithLoadTag(uint32_t aTag)
 {
-	OSSharedPtr<OSKext> foundKext;             // returned
-	uint32_t i, j;
-	OSArray *list[2] = {sLoadedKexts.get(), sLoadedDriverKitKexts.get()};
-	uint32_t count[2] = {sLoadedKexts->getCount(), sLoadedDriverKitKexts->getCount()};
-
-	IORecursiveLockLock(sKextLock);
-
-	for (j = 0; j < (sizeof(list) / sizeof(list[0])); j++) {
-		for (i = 0; i < count[j]; i++) {
-			OSKext * thisKext = OSDynamicCast(OSKext, list[j]->getObject(i));
-			if (thisKext->getLoadTag() == aTag) {
-				foundKext.reset(thisKext, OSRetain);
-				goto finish;
-			}
-		}
-	}
-
+    OSKext * foundKext = NULL;                 // returned
+    uint32_t count, i;
+
+    IORecursiveLockLock(sKextLock);
+    
+    count = sLoadedKexts->getCount();
+    for (i = 0; i < count; i++) {
+        OSKext * thisKext = OSDynamicCast(OSKext, sLoadedKexts->getObject(i));
+        if (thisKext->getLoadTag() == aTag) {
+            foundKext = thisKext;
+            foundKext->retain();
+            goto finish;
+        }
+    }
+    
 finish:
-	IORecursiveLockUnlock(sKextLock);
-
-	return foundKext;
-}
-
-/*********************************************************************
-*********************************************************************/
-OSSharedPtr<OSKext>
+    IORecursiveLockUnlock(sKextLock);
+
+    return foundKext;
+}
+
+/*********************************************************************
+*********************************************************************/
+OSKext *
 OSKext::lookupKextWithAddress(vm_address_t address)
 {
-	OSSharedPtr<OSKext> foundKext;             // returned
-	uint32_t count, i;
-	kmod_info_t *kmod_info;
-	vm_address_t originalAddress;
-#if defined(__arm64__)
-	uint64_t   textExecBase;
-	size_t     textExecSize;
-#endif /* defined(__arm64__) */
-
-	originalAddress = address;
-#if  __has_feature(ptrauth_calls)
-	address = (vm_address_t)VM_KERNEL_STRIP_PTR(address);
-#endif /*  __has_feature(ptrauth_calls) */
-
-	IORecursiveLockLock(sKextLock);
-
-	count = sLoadedKexts->getCount();
-	for (i = 0; i < count; i++) {
-		OSKext * thisKext = OSDynamicCast(OSKext, sLoadedKexts->getObject(i));
-		if (thisKext == sKernelKext) {
-			continue;
-		}
-		if (thisKext->kmod_info && thisKext->kmod_info->address) {
-			kmod_info = thisKext->kmod_info;
-			vm_address_t kext_start = kmod_info->address;
-			vm_address_t kext_end = kext_start + kmod_info->size;
-			if ((kext_start <= address) && (address < kext_end)) {
-				foundKext.reset(thisKext, OSRetain);
-				goto finish;
-			}
-#if defined(__arm64__)
-			textExecBase = (uintptr_t) getsegdatafromheader((kernel_mach_header_t *)kmod_info->address, "__TEXT_EXEC", &textExecSize);
-
-			/**
-			 * If the addresses within the Mach-O are unslid, then manually
-			 * slide any addresses coming from the Mach-O before usage.
-			 */
-			if (thisKext->flags.unslidMachO) {
-				textExecBase = (uintptr_t) ml_static_slide((vm_offset_t) textExecBase);
-			}
-
-			if ((textExecBase <= address) && (address < textExecBase + textExecSize)) {
-				foundKext.reset(thisKext, OSRetain);
-				goto finish;
-			}
-#endif /* defined (__arm64__) */
-		}
-	}
-
-	if (kernel_text_contains(address)) {
-		foundKext.reset(sKernelKext, OSRetain);
-		goto finish;
-	}
-	/*
-	 * DriverKit userspace executables do not have a kernel linkedExecutable,
-	 * so we "fake" their address range with the LoadTag. We cannot use the ptrauth-stripped address
-	 * here, so use the original address passed to this method.
-	 *
-	 * This is supposed to be used for logging reasons only. When logd
-	 * calls this function it ors the address with FIREHOSE_TRACEPOINT_PC_KERNEL_MASK, so we
-	 * remove it here before checking it against the LoadTag.
-	 * Also we need to remove FIREHOSE_TRACEPOINT_PC_DYNAMIC_BIT set when emitting the log line.
-	 */
-
-	address = originalAddress & ~(FIREHOSE_TRACEPOINT_PC_KERNEL_MASK | FIREHOSE_TRACEPOINT_PC_DYNAMIC_BIT);
-	count = sLoadedDriverKitKexts->getCount();
-	for (i = 0; i < count; i++) {
-		OSKext * thisKext = OSDynamicCast(OSKext, sLoadedDriverKitKexts->getObject(i));
-		if (thisKext->getLoadTag() == address) {
-			foundKext.reset(thisKext, OSRetain);
-		}
-	}
-
+    OSKext * foundKext = NULL;                 // returned
+    uint32_t count, i;
+
+    IORecursiveLockLock(sKextLock);
+    
+    count = sLoadedKexts->getCount();
+    for (i = 0; i < count; i++) {
+        OSKext * thisKext = OSDynamicCast(OSKext, sLoadedKexts->getObject(i));
+        if (thisKext->linkedExecutable) {
+            vm_address_t kext_start =
+                (vm_address_t)thisKext->linkedExecutable->getBytesNoCopy();
+            vm_address_t kext_end = kext_start +
+                thisKext->linkedExecutable->getLength();
+            
+            if ((kext_start <= address) && (address < kext_end)) {
+                foundKext = thisKext;
+                foundKext->retain();
+                goto finish;
+            }
+        }
+    }
+    
 finish:
-	IORecursiveLockUnlock(sKextLock);
-
-	return foundKext;
-}
-
-OSSharedPtr<OSData>
-OSKext::copyKextUUIDForAddress(OSNumber *address)
-{
-	OSSharedPtr<OSData>   uuid;
-	OSSharedPtr<OSKext>   kext;
-
-	if (!address) {
-		return NULL;
-	}
-
-#if CONFIG_MACF
-	/* Is the calling process allowed to query kext info? */
-	if (current_task() != kernel_task) {
-		int macCheckResult = 0;
-		kauth_cred_t cred = NULL;
-
-		cred = kauth_cred_get_with_ref();
-		macCheckResult = mac_kext_check_query(cred);
-		kauth_cred_unref(&cred);
-
-		if (macCheckResult != 0) {
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogErrorLevel | kOSKextLogLoadFlag,
-			    "Failed to query kext UUID (MAC policy error 0x%x).",
-			    macCheckResult);
-			return NULL;
-		}
-	}
-#endif
-
-	uintptr_t slidAddress = ml_static_slide((uintptr_t)address->unsigned64BitValue());
-	if (slidAddress != 0) {
-		kext = lookupKextWithAddress(slidAddress);
-		if (kext) {
-			uuid = kext->copyTextUUID();
-		}
-	}
-
-	if (!uuid) {
-		/*
-		 * If we still don't have a UUID, then we failed to match the slid + stripped address with
-		 * a kext. This might have happened because the log message came from a dext.
-		 *
-		 * Try again with the original address.
-		 */
-		kext = lookupKextWithAddress((vm_address_t)address->unsigned64BitValue());
-		if (kext && kext->isDriverKit()) {
-			uuid = kext->copyTextUUID();
-		}
-	}
-
-	return uuid;
-}
-
-/*********************************************************************
-*********************************************************************/
-OSSharedPtr<OSKext>
+    IORecursiveLockUnlock(sKextLock);
+
+    return foundKext;
+}
+
+
+/*********************************************************************
+*********************************************************************/
+OSKext *
 OSKext::lookupKextWithUUID(uuid_t wanted)
 {
-	OSSharedPtr<OSKext> foundKext;             // returned
-	uint32_t j, i;
-	OSArray *list[2] = {sLoadedKexts.get(), sLoadedDriverKitKexts.get()};
-	uint32_t count[2] = {sLoadedKexts->getCount(), sLoadedDriverKitKexts->getCount()};
-
-
-	IORecursiveLockLock(sKextLock);
-
-	for (j = 0; j < (sizeof(list) / sizeof(list[0])); j++) {
-		for (i = 0; i < count[j]; i++) {
-			OSKext   * thisKext     = NULL;
-
-			thisKext = OSDynamicCast(OSKext, list[j]->getObject(i));
-			if (!thisKext) {
-				continue;
-			}
-
-			OSSharedPtr<OSData> uuid_data = thisKext->copyUUID();
-			if (!uuid_data) {
-				continue;
-			}
-
-			uuid_t uuid;
-			memcpy(&uuid, uuid_data->getBytesNoCopy(), sizeof(uuid));
-
-			if (0 == uuid_compare(wanted, uuid)) {
-				foundKext.reset(thisKext, OSRetain);
-				goto finish;
-			}
-		}
-	}
+    OSKext * foundKext = NULL;                 // returned
+    uint32_t count, i;
+
+    IORecursiveLockLock(sKextLock);
+
+    count = sLoadedKexts->getCount();
+
+    for (i = 0; i < count; i++) {
+        OSKext   * thisKext     = NULL;
+
+        thisKext = OSDynamicCast(OSKext, sLoadedKexts->getObject(i));
+        if (!thisKext) {
+            continue;
+        }
+
+        OSData *uuid_data = thisKext->copyUUID();
+        if (!uuid_data) {
+            continue;
+        }
+
+        uuid_t uuid;
+        memcpy(&uuid, uuid_data->getBytesNoCopy(), sizeof(uuid));
+        uuid_data->release();
+
+        if (0 == uuid_compare(wanted, uuid)) {
+            foundKext = thisKext;
+            foundKext->retain();
+            goto finish;
+        }
+
+    }
+
 finish:
-	IORecursiveLockUnlock(sKextLock);
-
-	return foundKext;
+    IORecursiveLockUnlock(sKextLock);
+
+    return foundKext;
 }
 
 
@@ -4526,22 +3290,21 @@
 /*********************************************************************
 *********************************************************************/
 /* static */
-bool
-OSKext::isKextWithIdentifierLoaded(const char * kextIdentifier)
-{
-	bool result = false;
-	OSKext * foundKext = NULL;             // returned
-
-	IORecursiveLockLock(sKextLock);
-
-	foundKext = OSDynamicCast(OSKext, sKextsByID->getObject(kextIdentifier));
-	if (foundKext && foundKext->isLoaded()) {
-		result = true;
-	}
-
-	IORecursiveLockUnlock(sKextLock);
-
-	return result;
+bool OSKext::isKextWithIdentifierLoaded(const char * kextIdentifier)
+{
+    bool result = false;
+    OSKext * foundKext = NULL;                 // returned
+
+    IORecursiveLockLock(sKextLock);
+
+    foundKext = OSDynamicCast(OSKext, sKextsByID->getObject(kextIdentifier));
+    if (foundKext && foundKext->isLoaded()) {
+        result = true;
+    }
+
+    IORecursiveLockUnlock(sKextLock);
+    
+    return result;
 }
 
 /*********************************************************************
@@ -4551,172 +3314,136 @@
 /* static */
 OSReturn
 OSKext::removeKext(
-	OSKext * aKext,
-#if CONFIG_EMBEDDED
-	__unused
+    OSKext * aKext,
+    bool     terminateServicesAndRemovePersonalitiesFlag)
+ {
+    OSReturn result    = kOSKextReturnInUse;
+    OSKext * checkKext = NULL;   // do not release
+#if CONFIG_MACF
+    int macCheckResult = 0;
+    kauth_cred_t cred  = NULL;
 #endif
-	bool     terminateServicesAndRemovePersonalitiesFlag)
-{
-#if CONFIG_EMBEDDED
-	if (!aKext->isDriverKit()) {
-		OSKextLog(aKext,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogKextBookkeepingFlag,
-		    "removeKext() called for %s, only supported on embedded for DriverKit dexts",
-		    aKext->getIdentifier() ? aKext->getIdentifierCString() : "unknown kext");
-
-		return kOSReturnSuccess;
-	}
-#endif /* CONFIG_EMBEDDED */
-	OSReturn result    = kOSKextReturnInUse;
-	OSKext * checkKext = NULL;         // do not release
+
+    IORecursiveLockLock(sKextLock);
+
+   /* If the kext has no identifier, it failed to init
+    * so isn't in sKextsByID and it isn't loaded.
+    */
+    if (!aKext->getIdentifier()) {
+        result = kOSReturnSuccess;
+        goto finish;
+    }
+
+    checkKext = OSDynamicCast(OSKext,
+        sKextsByID->getObject(aKext->getIdentifier()));
+    if (checkKext != aKext) {
+        result = kOSKextReturnNotFound;
+        goto finish;
+    }
+
+    if (aKext->isLoaded()) {
 #if CONFIG_MACF
-	int macCheckResult = 0;
-	kauth_cred_t cred  = NULL;
+        if (current_task() != kernel_task) {
+            cred = kauth_cred_get_with_ref();
+            macCheckResult = mac_kext_check_unload(cred, aKext->getIdentifierCString());
+            kauth_cred_unref(&cred);
+        }
+
+        if (macCheckResult != 0) {
+            result = kOSReturnError;
+            OSKextLog(aKext,
+                kOSKextLogErrorLevel |
+                kOSKextLogKextBookkeepingFlag,
+                "Failed to remove kext %s (MAC policy error 0x%x).",
+                aKext->getIdentifierCString(), macCheckResult);
+            goto finish;
+        }
 #endif
 
-	IORecursiveLockLock(sKextLock);
-
-	/* If the kext has no identifier, it failed to init
-	 * so isn't in sKextsByID and it isn't loaded.
-	 */
-	if (!aKext->getIdentifier()) {
-		result = kOSReturnSuccess;
-		goto finish;
-	}
-
-	checkKext = OSDynamicCast(OSKext,
-	    sKextsByID->getObject(aKext->getIdentifier()));
-	if (checkKext != aKext) {
-		result = kOSKextReturnNotFound;
-		goto finish;
-	}
-
-	if (aKext->isLoaded() || aKext->isDriverKit()) {
-#if CONFIG_MACF
-		if (current_task() != kernel_task) {
-			cred = kauth_cred_get_with_ref();
-			macCheckResult = mac_kext_check_unload(cred, aKext->getIdentifierCString());
-			kauth_cred_unref(&cred);
-		}
-
-		if (macCheckResult != 0) {
-			result = kOSReturnError;
-			OSKextLog(aKext,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogKextBookkeepingFlag,
-			    "Failed to remove kext %s (MAC policy error 0x%x).",
-			    aKext->getIdentifierCString(), macCheckResult);
-			goto finish;
-		}
-#endif
-
-		/* make sure there are no resource requests in flight - 17187548 */
-		if (aKext->declaresExecutable() && aKext->countRequestCallbacks()) {
-			goto finish;
-		}
-		if (aKext->flags.unloadUnsupported) {
-			result = kOSKextReturnInUse;
-			OSKextLog(aKext,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogKextBookkeepingFlag,
-			    "Can't remove kext %s; unsupported by cache.",
-			    aKext->getIdentifierCString());
-			goto finish;
-		}
-
-		/* If we are terminating, send the request to the IOCatalogue
-		 * (which will actually call us right back but that's ok we have
-		 * a recursive lock don't you know) but do not ask the IOCatalogue
-		 * to call back with an unload, we'll do that right here.
-		 */
-		if (terminateServicesAndRemovePersonalitiesFlag) {
-			result = gIOCatalogue->terminateDriversForModule(
-				aKext->getIdentifierCString(), /* unload */ false);
-			if (result != kOSReturnSuccess) {
-				OSKextLog(aKext,
-				    kOSKextLogErrorLevel |
-				    kOSKextLogKextBookkeepingFlag,
-				    "Can't remove kext %s; services failed to terminate - 0x%x.",
-				    aKext->getIdentifierCString(), result);
-				goto finish;
-			}
-		}
-
-		result = aKext->unload();
-		if (result != kOSReturnSuccess) {
-			OSKextLog(aKext,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogKextBookkeepingFlag,
-			    "Can't remove kext %s; kext failed to unload - 0x%x.",
-			    aKext->getIdentifierCString(), result);
-			goto finish;
-		}
-	}
-
-	/* Remove personalities as requested. This is a bit redundant for a loaded
-	 * kext as IOCatalogue::terminateDriversForModule() removes driver
-	 * personalities, but it doesn't restart matching, which we always want
-	 * coming from here, and OSKext::removePersonalitiesFromCatalog() ensures
-	 * that happens.
-	 */
-	if (terminateServicesAndRemovePersonalitiesFlag) {
-		aKext->removePersonalitiesFromCatalog();
-	}
-
-	if (aKext->isInFileset()) {
-		OSKextLog(aKext,
-		    kOSKextLogProgressLevel |
-		    kOSKextLogKextBookkeepingFlag,
-		    "Fileset kext %s unloaded.",
-		    aKext->getIdentifierCString());
-	} else {
-		OSKextLog(aKext,
-		    kOSKextLogProgressLevel |
-		    kOSKextLogKextBookkeepingFlag,
-		    "Removing kext %s.",
-		    aKext->getIdentifierCString());
-
-		sKextsByID->removeObject(aKext->getIdentifier());
-	}
-	result = kOSReturnSuccess;
+        /* make sure there are no resource requests in flight - 17187548 */
+        if (aKext->countRequestCallbacks()) {
+            goto finish;
+        }
+
+       /* If we are terminating, send the request to the IOCatalogue
+        * (which will actually call us right back but that's ok we have
+        * a recursive lock don't you know) but do not ask the IOCatalogue
+        * to call back with an unload, we'll do that right here.
+        */
+        if (terminateServicesAndRemovePersonalitiesFlag) {
+            result = gIOCatalogue->terminateDriversForModule(
+                aKext->getIdentifierCString(), /* unload */ false);
+            if (result != kOSReturnSuccess) {
+                OSKextLog(aKext,
+                    kOSKextLogErrorLevel |
+                    kOSKextLogKextBookkeepingFlag,
+                    "Can't remove kext %s; services failed to terminate - 0x%x.",
+                    aKext->getIdentifierCString(), result);
+                goto finish;
+            }
+        }
+
+        result = aKext->unload();
+        if (result != kOSReturnSuccess) {
+            goto finish;
+        }
+    }
+    
+   /* Remove personalities as requested. This is a bit redundant for a loaded
+    * kext as IOCatalogue::terminateDriversForModule() removes driver
+    * personalities, but it doesn't restart matching, which we always want
+    * coming from here, and OSKext::removePersonalitiesFromCatalog() ensures
+    * that happens.
+    */
+    if (terminateServicesAndRemovePersonalitiesFlag) {
+        aKext->removePersonalitiesFromCatalog();
+    }
+
+    OSKextLog(aKext,
+              kOSKextLogProgressLevel |
+              kOSKextLogKextBookkeepingFlag,
+              "Removing kext %s.",
+              aKext->getIdentifierCString());
+          
+    sKextsByID->removeObject(aKext->getIdentifier());
+    result = kOSReturnSuccess;
 
 finish:
-	IORecursiveLockUnlock(sKextLock);
-	return result;
-}
+    IORecursiveLockUnlock(sKextLock);
+    return result;
+ }
 
 /*********************************************************************
 *********************************************************************/
 /* static */
 OSReturn
 OSKext::removeKextWithIdentifier(
-	const char * kextIdentifier,
-	bool         terminateServicesAndRemovePersonalitiesFlag)
-{
-	OSReturn result = kOSReturnError;
-
-	IORecursiveLockLock(sKextLock);
-
-	OSKext * aKext = OSDynamicCast(OSKext,
-	    sKextsByID->getObject(kextIdentifier));
-	if (!aKext) {
-		result = kOSKextReturnNotFound;
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogKextBookkeepingFlag,
-		    "Can't remove kext %s - not found.",
-		    kextIdentifier);
-		goto finish;
-	}
-
-	result = OSKext::removeKext(aKext,
-	    terminateServicesAndRemovePersonalitiesFlag);
+    const char * kextIdentifier,
+    bool         terminateServicesAndRemovePersonalitiesFlag)
+{
+    OSReturn result = kOSReturnError;
+
+    IORecursiveLockLock(sKextLock);
+    
+    OSKext * aKext = OSDynamicCast(OSKext,
+        sKextsByID->getObject(kextIdentifier));
+    if (!aKext) {
+        result = kOSKextReturnNotFound;
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogErrorLevel |
+            kOSKextLogKextBookkeepingFlag,
+            "Can't remove kext %s - not found.",
+            kextIdentifier);
+        goto finish;
+    }
+
+    result = OSKext::removeKext(aKext,
+        terminateServicesAndRemovePersonalitiesFlag);
 
 finish:
-	IORecursiveLockUnlock(sKextLock);
-
-	return result;
+    IORecursiveLockUnlock(sKextLock);
+    
+    return result;
 }
 
 /*********************************************************************
@@ -4724,256 +3451,231 @@
 /* static */
 OSReturn
 OSKext::removeKextWithLoadTag(
-	OSKextLoadTag loadTag,
-	bool          terminateServicesAndRemovePersonalitiesFlag)
-{
-	OSReturn result    = kOSReturnError;
-	OSKext * foundKext = NULL;
-	uint32_t i, j;
-	OSArray *list[2] = {sLoadedKexts.get(), sLoadedDriverKitKexts.get()};
-	uint32_t count[2] = {sLoadedKexts->getCount(), sLoadedDriverKitKexts->getCount()};
-
-
-	IORecursiveLockLock(sKextLock);
-
-	for (j = 0; j < (sizeof(list) / sizeof(list[0])); j++) {
-		for (i = 0; i < count[j]; i++) {
-			OSKext * thisKext = OSDynamicCast(OSKext, list[j]->getObject(i));
-			if (thisKext->loadTag == loadTag) {
-				foundKext = thisKext;
-				break;
-			}
-		}
-	}
-
-	if (!foundKext) {
-		result = kOSKextReturnNotFound;
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag | kOSKextLogKextBookkeepingFlag,
-		    "Can't remove kext with load tag %d - not found.",
-		    loadTag);
-		goto finish;
-	}
-
-	result = OSKext::removeKext(foundKext,
-	    terminateServicesAndRemovePersonalitiesFlag);
+    OSKextLoadTag loadTag,
+    bool          terminateServicesAndRemovePersonalitiesFlag)
+{
+    OSReturn result    = kOSReturnError;
+    OSKext * foundKext = NULL;
+    uint32_t count, i;
+
+    IORecursiveLockLock(sKextLock);
+
+    count = sLoadedKexts->getCount();
+    for (i = 0; i < count; i++) {
+        OSKext * thisKext = OSDynamicCast(OSKext, sLoadedKexts->getObject(i));
+        if (thisKext->loadTag == loadTag) {
+            foundKext = thisKext;
+            break;
+        }
+    }
+    
+    if (!foundKext) {
+        result = kOSKextReturnNotFound;
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogErrorLevel |
+            kOSKextLogLoadFlag | kOSKextLogKextBookkeepingFlag,
+            "Can't remove kext with load tag %d - not found.",
+            loadTag);
+        goto finish;
+    }
+
+    result = OSKext::removeKext(foundKext,
+        terminateServicesAndRemovePersonalitiesFlag);
 
 finish:
-	IORecursiveLockUnlock(sKextLock);
-
-	return result;
-}
-
-/*********************************************************************
-*********************************************************************/
-OSSharedPtr<OSDictionary>
+    IORecursiveLockUnlock(sKextLock);
+    
+    return result;
+ }
+
+/*********************************************************************
+*********************************************************************/
+OSDictionary *
 OSKext::copyKexts(void)
 {
-	OSSharedPtr<OSDictionary> result;
-
-	IORecursiveLockLock(sKextLock);
-	result = OSDynamicPtrCast<OSDictionary>(sKextsByID->copyCollection());
-	IORecursiveLockUnlock(sKextLock);
-
-	return result;
-}
-
-/*********************************************************************
-*********************************************************************/
+    OSDictionary * result;
+
+    IORecursiveLockLock(sKextLock);
+    result = OSDynamicCast(OSDictionary, sKextsByID->copyCollection());
+    IORecursiveLockUnlock(sKextLock);
+
+    return result;
+}
+
+/*********************************************************************
+ *********************************************************************/
 #define BOOTER_KEXT_PREFIX   "Driver-"
 
 typedef struct _DeviceTreeBuffer {
-	uint32_t paddr;
-	uint32_t length;
+    uint32_t paddr;
+    uint32_t length;
 } _DeviceTreeBuffer;
 
 /*********************************************************************
-* Create a dictionary of excluded kexts from the given booter data.
-*********************************************************************/
+ * Create a dictionary of excluded kexts from the given booter data.
+ *********************************************************************/
 /* static */
 void
 OSKext::createExcludeListFromBooterData(
-	OSDictionary *          theDictionary,
-	OSCollectionIterator *  theIterator )
-{
-	OSString                  * deviceTreeName      = NULL;        // do not release
-	const _DeviceTreeBuffer   * deviceTreeBuffer    = NULL;        // do not release
-	char                      * booterDataPtr       = NULL;        // do not release
-	_BooterKextFileInfo       * kextFileInfo        = NULL;        // do not release
-	char                      * infoDictAddr        = NULL;        // do not release
-	OSSharedPtr<OSObject>       parsedXML;
-	OSDictionary              * theInfoDict         = NULL;        // do not release
-
-	theIterator->reset();
-
-	/* look for AppleKextExcludeList.kext */
-	while ((deviceTreeName =
-	    OSDynamicCast(OSString, theIterator->getNextObject()))) {
-		const char *    devTreeNameCString;
-		OSData *        deviceTreeEntry;        // do not release
-		OSString *      myBundleID;        // do not release
-
-		deviceTreeEntry =
-		    OSDynamicCast(OSData, theDictionary->getObject(deviceTreeName));
-		if (!deviceTreeEntry) {
-			continue;
-		}
-
-		/* Make sure it is a kext */
-		devTreeNameCString = deviceTreeName->getCStringNoCopy();
-		if (strncmp(devTreeNameCString, BOOTER_KEXT_PREFIX,
-		    (sizeof(BOOTER_KEXT_PREFIX) - 1)) != 0) {
-			OSKextLog(NULL,
-			    kOSKextLogErrorLevel | kOSKextLogGeneralFlag,
-			    "\"%s\" not a kext",
-			    devTreeNameCString);
-			continue;
-		}
-
-		deviceTreeBuffer = (const _DeviceTreeBuffer *)
-		    deviceTreeEntry->getBytesNoCopy(0, sizeof(deviceTreeBuffer));
-		if (!deviceTreeBuffer) {
-			continue;
-		}
-
-		booterDataPtr = (char *)ml_static_ptovirt(deviceTreeBuffer->paddr);
-		if (!booterDataPtr) {
-			continue;
-		}
-
-		kextFileInfo = (_BooterKextFileInfo *) booterDataPtr;
-		if (!kextFileInfo->infoDictPhysAddr ||
-		    !kextFileInfo->infoDictLength) {
-			continue;
-		}
-
-		infoDictAddr = (char *)
-		    ml_static_ptovirt(kextFileInfo->infoDictPhysAddr);
-		if (!infoDictAddr) {
-			continue;
-		}
-
-		parsedXML = OSUnserializeXML(infoDictAddr);
-		if (!parsedXML) {
-			continue;
-		}
-
-		theInfoDict = OSDynamicCast(OSDictionary, parsedXML.get());
-		if (!theInfoDict) {
-			continue;
-		}
-
-		myBundleID =
-		    OSDynamicCast(OSString,
-		    theInfoDict->getObject(kCFBundleIdentifierKey));
-		if (myBundleID &&
-		    strcmp( myBundleID->getCStringNoCopy(), kIOExcludeListBundleID ) == 0) {
-			boolean_t updated = updateExcludeList(theInfoDict);
-			if (!updated) {
-				/* 25322874 */
-				panic("Missing OSKextExcludeList dictionary");
-			}
-			break;
-		}
-	}         // while ( (deviceTreeName = ...) )
-
-	return;
-}
-
-/*********************************************************************
-* Create a dictionary of excluded kexts from the given prelink
-* info (kernelcache).
-*********************************************************************/
+                                        OSDictionary *          theDictionary,
+                                        OSCollectionIterator *  theIterator )
+{
+    OSString                  * deviceTreeName      = NULL;  // do not release
+    const _DeviceTreeBuffer   * deviceTreeBuffer    = NULL;  // do not release
+    char                      * booterDataPtr       = NULL;  // do not release
+    _BooterKextFileInfo       * kextFileInfo        = NULL;  // do not release
+    char                      * infoDictAddr        = NULL;  // do not release
+    OSObject                  * parsedXML           = NULL;  // must release
+    OSDictionary              * theInfoDict         = NULL;  // do not release
+    
+    theIterator->reset();
+    
+    /* look for AppleKextExcludeList.kext */
+    while ( (deviceTreeName =
+             OSDynamicCast(OSString, theIterator->getNextObject())) ) {
+        
+        const char *    devTreeNameCString;
+        OSData *        deviceTreeEntry;
+        OSString *      myBundleID;    // do not release
+        
+        OSSafeReleaseNULL(parsedXML);
+        
+        deviceTreeEntry = 
+        OSDynamicCast(OSData, theDictionary->getObject(deviceTreeName));
+        if (!deviceTreeEntry) {
+            continue;
+        }
+        
+        /* Make sure it is a kext */
+        devTreeNameCString = deviceTreeName->getCStringNoCopy();
+        if (strncmp(devTreeNameCString, BOOTER_KEXT_PREFIX,
+                    (sizeof(BOOTER_KEXT_PREFIX) - 1)) != 0) {
+            OSKextLog(NULL,
+                      kOSKextLogErrorLevel | kOSKextLogGeneralFlag, 
+                      "\"%s\" not a kext",
+                      devTreeNameCString);
+            continue;
+        }
+        
+        deviceTreeBuffer = (const _DeviceTreeBuffer *)
+        deviceTreeEntry->getBytesNoCopy(0, sizeof(deviceTreeBuffer));
+        if (!deviceTreeBuffer) {
+            continue;
+        }
+        
+        booterDataPtr = (char *)ml_static_ptovirt(deviceTreeBuffer->paddr);
+        if (!booterDataPtr) {
+            continue;
+        }
+        
+        kextFileInfo = (_BooterKextFileInfo *) booterDataPtr;
+        if (!kextFileInfo->infoDictPhysAddr || 
+            !kextFileInfo->infoDictLength)       {
+            continue;
+        }
+        
+        infoDictAddr = (char *)
+        ml_static_ptovirt(kextFileInfo->infoDictPhysAddr);
+        if (!infoDictAddr) {
+            continue;
+        }
+        
+        parsedXML = OSUnserializeXML(infoDictAddr);
+        if (!parsedXML) {
+            continue;
+        }
+        
+        theInfoDict = OSDynamicCast(OSDictionary, parsedXML);
+        if (!theInfoDict) {
+            continue;
+        }
+        
+        myBundleID = 
+        OSDynamicCast(OSString, 
+                      theInfoDict->getObject(kCFBundleIdentifierKey));
+        if ( myBundleID && 
+            strcmp( myBundleID->getCStringNoCopy(), "com.apple.driver.KextExcludeList" ) == 0 ) {
+            
+            /* get copy of exclusion list dictionary */
+            OSDictionary *      myTempDict;     // do not free
+            
+            myTempDict = OSDynamicCast(
+                                       OSDictionary,
+                                       theInfoDict->getObject("OSKextExcludeList"));
+            if ( myTempDict ) {
+                IORecursiveLockLock(sKextLock);
+                
+                /* get rid of old exclusion list */
+                if (sExcludeListByID) {
+                    sExcludeListByID->flushCollection();
+                    OSSafeRelease(sExcludeListByID);
+                }
+                sExcludeListByID = OSDictionary::withDictionary(myTempDict, 0);
+                IORecursiveLockUnlock(sKextLock);
+            }
+            break;
+        }
+        
+    } // while ( (deviceTreeName = ...) )
+    
+    OSSafeReleaseNULL(parsedXML);
+    return;
+}
+
+/*********************************************************************
+ * Create a dictionary of excluded kexts from the given prelink 
+ * info (kernelcache).
+ *********************************************************************/
 /* static */
 void
 OSKext::createExcludeListFromPrelinkInfo( OSArray * theInfoArray )
 {
-	OSDictionary *  myInfoDict = NULL;        // do not release
-	OSString *      myBundleID;        // do not release
-	u_int           i;
-
-	/* Find the Apple Kext Exclude List. */
-	for (i = 0; i < theInfoArray->getCount(); i++) {
-		myInfoDict = OSDynamicCast(OSDictionary, theInfoArray->getObject(i));
-		if (!myInfoDict) {
-			continue;
-		}
-		myBundleID =
-		    OSDynamicCast(OSString,
-		    myInfoDict->getObject(kCFBundleIdentifierKey));
-		if (myBundleID &&
-		    strcmp( myBundleID->getCStringNoCopy(), kIOExcludeListBundleID ) == 0) {
-			boolean_t updated = updateExcludeList(myInfoDict);
-			if (!updated) {
-				/* 25322874 */
-				panic("Missing OSKextExcludeList dictionary");
-			}
-			break;
-		}
-	}         // for (i = 0; i < theInfoArray->getCount()...
-
-	return;
-}
-
-/* static */
-boolean_t
-OSKext::updateExcludeList(OSDictionary *infoDict)
-{
-	OSDictionary *myTempDict = NULL;         // do not free
-	OSString     *myTempString = NULL;        // do not free
-	OSKextVersion newVersion = 0;
-	boolean_t updated = false;
-
-	if (!infoDict) {
-		return false;
-	}
-
-	myTempDict = OSDynamicCast(OSDictionary, infoDict->getObject("OSKextExcludeList"));
-	if (!myTempDict) {
-		return false;
-	}
-
-	myTempString = OSDynamicCast(OSString, infoDict->getObject(kCFBundleVersionKey));
-	if (!myTempString) {
-		return false;
-	}
-
-	newVersion = OSKextParseVersionString(myTempString->getCStringNoCopy());
-	if (newVersion == 0) {
-		return false;
-	}
-
-	IORecursiveLockLock(sKextLock);
-
-	if (newVersion > sExcludeListVersion) {
-		sExcludeListByID = OSDictionary::withDictionary(myTempDict, 0);
-		sExcludeListVersion = newVersion;
-		updated = true;
-	}
-
-	IORecursiveLockUnlock(sKextLock);
-	return updated;
+    OSDictionary *  myInfoDict = NULL;  // do not release
+    OSString *      myBundleID;         // do not release
+    u_int           i;
+    
+    /* Find com.apple.driver.KextExcludeList. */
+    for (i = 0; i < theInfoArray->getCount(); i++) {
+        myInfoDict = OSDynamicCast(OSDictionary, theInfoArray->getObject(i));
+        if (!myInfoDict) {
+            continue;
+        }
+        myBundleID = 
+        OSDynamicCast(OSString, 
+                      myInfoDict->getObject(kCFBundleIdentifierKey));
+        if ( myBundleID && 
+            strcmp( myBundleID->getCStringNoCopy(), "com.apple.driver.KextExcludeList" ) == 0 ) {
+            // get copy of exclude list dictionary
+            OSDictionary *      myTempDict;     // do not free
+            myTempDict = OSDynamicCast(OSDictionary,
+                                       myInfoDict->getObject("OSKextExcludeList"));
+            if ( myTempDict ) {
+                IORecursiveLockLock(sKextLock);
+                // get rid of old exclude list
+                if (sExcludeListByID) {
+                    sExcludeListByID->flushCollection();
+                    OSSafeRelease(sExcludeListByID);
+                }
+                
+                sExcludeListByID = OSDictionary::withDictionary(myTempDict, 0);
+                IORecursiveLockUnlock(sKextLock);
+            }
+            break;
+        }
+    } // for (i = 0; i < theInfoArray->getCount()...
+    
+    return;
 }
 
 #if PRAGMA_MARK
 #pragma mark Accessors
 #endif
-
-/*********************************************************************
-*********************************************************************/
-const OSObject *
-OSKext::getBundleExecutable(void)
-{
-	return infoDict->getObject(kCFBundleExecutableKey);
-}
-
 /*********************************************************************
 *********************************************************************/
 const OSSymbol *
 OSKext::getIdentifier(void)
 {
-	return bundleID.get();
+    return bundleID;
 }
 
 /*********************************************************************
@@ -4983,7 +3685,7 @@
 const char *
 OSKext::getIdentifierCString(void)
 {
-	return bundleID->getCStringNoCopy();
+    return bundleID->getCStringNoCopy();
 }
 
 /*********************************************************************
@@ -4991,7 +3693,7 @@
 OSKextVersion
 OSKext::getVersion(void)
 {
-	return version;
+    return version;
 }
 
 /*********************************************************************
@@ -4999,7 +3701,7 @@
 OSKextVersion
 OSKext::getCompatibleVersion(void)
 {
-	return compatibleVersion;
+    return compatibleVersion;
 }
 
 /*********************************************************************
@@ -5007,7 +3709,7 @@
 bool
 OSKext::isLibrary(void)
 {
-	return getCompatibleVersion() > 0;
+    return (getCompatibleVersion() > 0);
 }
 
 /*********************************************************************
@@ -5015,11 +3717,11 @@
 bool
 OSKext::isCompatibleWithVersion(OSKextVersion aVersion)
 {
-	if ((compatibleVersion > -1 && version > -1) &&
-	    (compatibleVersion <= version && aVersion <= version)) {
-		return true;
-	}
-	return false;
+    if ((compatibleVersion > -1 && version > -1) &&
+        (compatibleVersion <= version && aVersion <= version)) {
+        return true;
+    }
+    return false;
 }
 
 /*********************************************************************
@@ -5027,10 +3729,7 @@
 bool
 OSKext::declaresExecutable(void)
 {
-	if (isDriverKit()) {
-		return false;
-	}
-	return getPropertyForHostArch(kCFBundleExecutableKey) != NULL;
+    return (getPropertyForHostArch(kCFBundleExecutableKey) != NULL);
 }
 
 /*********************************************************************
@@ -5038,62 +3737,60 @@
 OSData *
 OSKext::getExecutable(void)
 {
-	OSData * result              = NULL;
-	OSSharedPtr<OSData> extractedExecutable;
-
-	if (flags.builtin) {
-		return sKernelKext->linkedExecutable.get();
-	}
-
-	result = OSDynamicCast(OSData, infoDict->getObject(_kOSKextExecutableKey));
-	if (result) {
-		return result;
-	}
-
-#if CONFIG_KXLD
-	OSData * mkextExecutableRef  = NULL;        // do not release
-	mkextExecutableRef = OSDynamicCast(OSData,
-	    getPropertyForHostArch(_kOSKextMkextExecutableReferenceKey));
-
-	if (mkextExecutableRef) {
-		MkextEntryRef * mkextEntryRef = (MkextEntryRef *)
-		    mkextExecutableRef->getBytesNoCopy();
-		uint32_t mkextVersion = MKEXT_GET_VERSION(mkextEntryRef->mkext);
-		if (mkextVersion == MKEXT_VERS_2) {
-			mkext2_file_entry * fileinfo =
-			    (mkext2_file_entry *)mkextEntryRef->fileinfo;
-			uint32_t compressedSize = MKEXT2_GET_ENTRY_COMPSIZE(fileinfo);
-			uint32_t fullSize = MKEXT2_GET_ENTRY_FULLSIZE(fileinfo);
-			extractedExecutable = extractMkext2FileData(
-				MKEXT2_GET_ENTRY_DATA(fileinfo), "executable",
-				compressedSize, fullSize);
-		} else {
-			OSKextLog(this, kOSKextLogErrorLevel |
-			    kOSKextLogArchiveFlag,
-			    "Kext %s - unknown mkext version 0x%x for executable.",
-			    getIdentifierCString(), mkextVersion);
-		}
-
-		/* Regardless of success, remove the mkext executable,
-		 * and drop one reference on the mkext.  (setExecutable() does not
-		 * replace, it removes, or panics if asked to replace.)
-		 */
-		infoDict->removeObject(_kOSKextMkextExecutableReferenceKey);
-		infoDict->removeObject(_kOSKextExecutableExternalDataKey);
-
-		if (extractedExecutable && extractedExecutable->getLength()) {
-			if (!setExecutable(extractedExecutable.get())) {
-				goto finish;
-			}
-			result = extractedExecutable.get();
-		} else {
-			goto finish;
-		}
-	}
+    OSData * result              = NULL;
+    OSData * extractedExecutable = NULL;  // must release
+    OSData * mkextExecutableRef  = NULL;  // do not release
+
+    result = OSDynamicCast(OSData, infoDict->getObject(_kOSKextExecutableKey));
+    if (result) {
+        goto finish;
+    }
+
+    mkextExecutableRef = OSDynamicCast(OSData,
+        getPropertyForHostArch(_kOSKextMkextExecutableReferenceKey));
+
+    if (mkextExecutableRef) {
+
+        MkextEntryRef * mkextEntryRef = (MkextEntryRef *)
+            mkextExecutableRef->getBytesNoCopy();
+        uint32_t mkextVersion = MKEXT_GET_VERSION(mkextEntryRef->mkext);
+        if (mkextVersion == MKEXT_VERS_2) {
+            mkext2_file_entry * fileinfo =
+                (mkext2_file_entry *)mkextEntryRef->fileinfo;
+            uint32_t compressedSize = MKEXT2_GET_ENTRY_COMPSIZE(fileinfo);
+            uint32_t fullSize = MKEXT2_GET_ENTRY_FULLSIZE(fileinfo);
+            extractedExecutable = extractMkext2FileData(
+                MKEXT2_GET_ENTRY_DATA(fileinfo), "executable",
+                compressedSize, fullSize);
+        } else {
+            OSKextLog(this, kOSKextLogErrorLevel |
+            kOSKextLogArchiveFlag,
+                "Kext %s - unknown mkext version 0x%x for executable.",
+                getIdentifierCString(), mkextVersion);
+        }
+
+       /* Regardless of success, remove the mkext executable,
+        * and drop one reference on the mkext.  (setExecutable() does not
+        * replace, it removes, or panics if asked to replace.)
+        */        
+        infoDict->removeObject(_kOSKextMkextExecutableReferenceKey);
+        infoDict->removeObject(_kOSKextExecutableExternalDataKey);
+
+        if (extractedExecutable && extractedExecutable->getLength()) {
+            if (!setExecutable(extractedExecutable)) {
+                goto finish;
+            }
+            result = extractedExecutable;
+        } else {
+            goto finish;
+        }
+    }
 
 finish:
-#endif // CONFIG_KXLD
-	return result;
+
+    OSSafeRelease(extractedExecutable);
+
+    return result;
 }
 
 /*********************************************************************
@@ -5101,7 +3798,7 @@
 bool
 OSKext::isInterface(void)
 {
-	return flags.interface;
+    return flags.interface;
 }
 
 /*********************************************************************
@@ -5109,7 +3806,7 @@
 bool
 OSKext::isKernel(void)
 {
-	return this == sKernelKext;
+    return (this == sKernelKext);
 }
 
 /*********************************************************************
@@ -5117,7 +3814,7 @@
 bool
 OSKext::isKernelComponent(void)
 {
-	return flags.kernelComponent ? true : false;
+    return flags.kernelComponent ? true : false;
 }
 
 /*********************************************************************
@@ -5125,21 +3822,7 @@
 bool
 OSKext::isExecutable(void)
 {
-	return !isKernel() && !isInterface() && declaresExecutable();
-}
-
-/*********************************************************************
-*********************************************************************/
-bool
-OSKext::isSpecialKernelBinary(void)
-{
-#if CONFIG_SPTM
-	return (this->kmod_info) &&
-	       ((this->kmod_info->id == kOSKextSPTMLoadTag) ||
-	       (this->kmod_info->id == kOSKextTXMLoadTag));
-#else
-	return false;
-#endif
+    return (!isKernel() && !isInterface() && declaresExecutable());
 }
 
 /*********************************************************************
@@ -5157,34 +3840,30 @@
 bool
 OSKext::isLoadableInSafeBoot(void)
 {
-	bool       result   = false;
-	OSString * required = NULL;         // do not release
-
-	if (isKernel()) {
-		result = true;
-		goto finish;
-	}
-
-	if (isDriverKit()) {
-		result = true;
-		goto finish;
-	}
-
-	required = OSDynamicCast(OSString,
-	    getPropertyForHostArch(kOSBundleRequiredKey));
-	if (!required) {
-		goto finish;
-	}
-	if (required->isEqualTo(kOSBundleRequiredRoot) ||
-	    required->isEqualTo(kOSBundleRequiredLocalRoot) ||
-	    required->isEqualTo(kOSBundleRequiredNetworkRoot) ||
-	    required->isEqualTo(kOSBundleRequiredSafeBoot) ||
-	    required->isEqualTo(kOSBundleRequiredConsole)) {
-		result = true;
-	}
-
+    bool       result   = false;
+    OSString * required = NULL;  // do not release
+    
+    if (isKernel()) {
+        result = true;
+        goto finish;
+    }
+    
+    required = OSDynamicCast(OSString,
+        getPropertyForHostArch(kOSBundleRequiredKey));
+    if (!required) {
+        goto finish;
+    }
+    if (required->isEqualTo(kOSBundleRequiredRoot)        ||
+        required->isEqualTo(kOSBundleRequiredLocalRoot)   ||
+        required->isEqualTo(kOSBundleRequiredNetworkRoot) ||
+        required->isEqualTo(kOSBundleRequiredSafeBoot)    ||
+        required->isEqualTo(kOSBundleRequiredConsole)) {
+        
+        result = true;
+    }
+    
 finish:
-	return result;
+    return result;
 }
 
 /*********************************************************************
@@ -5192,15 +3871,14 @@
 bool
 OSKext::isPrelinked(void)
 {
-	return flags.prelinked ? true : false;
-}
-
-/*********************************************************************
-*********************************************************************/
-bool
-OSKext::isLoaded(void)
-{
-	return flags.loaded ? true : false;
+    return flags.prelinked ? true : false;
+}
+
+/*********************************************************************
+*********************************************************************/
+bool OSKext::isLoaded(void)
+{
+    return flags.loaded ? true : false;
 }
 
 /*********************************************************************
@@ -5208,7 +3886,7 @@
 bool
 OSKext::isStarted(void)
 {
-	return flags.started ? true : false;
+    return flags.started ? true : false;
 }
 
 /*********************************************************************
@@ -5216,7 +3894,7 @@
 bool
 OSKext::isCPPInitialized(void)
 {
-	return flags.CPPInitialized;
+    return flags.CPPInitialized;
 }
 
 /*********************************************************************
@@ -5224,7 +3902,7 @@
 void
 OSKext::setCPPInitialized(bool initialized)
 {
-	flags.CPPInitialized = initialized;
+    flags.CPPInitialized = initialized;
 }
 
 /*********************************************************************
@@ -5232,601 +3910,120 @@
 uint32_t
 OSKext::getLoadTag(void)
 {
-	return loadTag;
-}
-
-/*********************************************************************
-*********************************************************************/
-void
-OSKext::getSizeInfo(uint32_t *loadSize, uint32_t *wiredSize)
-{
-	if (linkedExecutable) {
-		*loadSize = linkedExecutable->getLength();
-
-		/* If we have a kmod_info struct, calculated the wired size
-		 * from that. Otherwise it's the full load size.
-		 */
-		if (kmod_info) {
-			*wiredSize = *loadSize - (uint32_t)kmod_info->hdr_size;
-		} else {
-			*wiredSize = *loadSize;
-		}
-	} else {
-		*wiredSize = 0;
-		*loadSize = 0;
-	}
-}
-
-/*********************************************************************
-*********************************************************************/
-OSSharedPtr<OSData>
+    return loadTag;
+}
+
+/*********************************************************************
+ *********************************************************************/
+void OSKext::getSizeInfo(uint32_t *loadSize, uint32_t *wiredSize)
+{
+    if (linkedExecutable) {
+        *loadSize = linkedExecutable->getLength();
+           
+        /* If we have a kmod_info struct, calculated the wired size
+         * from that. Otherwise it's the full load size.
+         */
+        if (kmod_info) {
+            *wiredSize = *loadSize - kmod_info->hdr_size;
+        } else {
+            *wiredSize = *loadSize;
+        }
+    }
+    else {
+        *wiredSize = 0;
+        *loadSize = 0;
+    }
+}
+
+/*********************************************************************
+*********************************************************************/
+OSData *
 OSKext::copyUUID(void)
 {
-	OSSharedPtr<OSData>          result;
-	OSData                     * theExecutable = NULL;        // do not release
-	const kernel_mach_header_t * header;
-
-	/* An interface kext doesn't have a linked executable with an LC_UUID,
-	 * we create one when it's linked.
-	 */
-	if (interfaceUUID) {
-		result = interfaceUUID;
-		goto finish;
-	}
-
-	if (flags.builtin || isInterface()) {
-		return sKernelKext->copyUUID();
-	}
-
-	if (isDriverKit() && infoDict) {
-		return driverKitUUID;
-	}
-
-	/* For real kexts, try to get the UUID from the linked executable,
-	 * or if is hasn't been linked yet, the unrelocated executable.
-	 */
-	theExecutable = linkedExecutable.get();
-	if (!theExecutable) {
-		theExecutable = getExecutable();
-	}
-
-	if (!theExecutable) {
-		goto finish;
-	}
-
-	header = (const kernel_mach_header_t *)theExecutable->getBytesNoCopy();
-	result = copyMachoUUID(header);
+    OSData                     * result        = NULL;
+    OSData                     * theExecutable = NULL;  // do not release
+    const kernel_mach_header_t * header        = NULL;
+    const struct load_command  * load_cmd      = NULL;
+    const struct uuid_command  * uuid_cmd      = NULL;
+    uint32_t                     i;
+
+   /* An interface kext doesn't have a linked executable with an LC_UUID,
+    * we create one when it's linked.
+    */
+    if (interfaceUUID) {
+        result = interfaceUUID;
+        result->retain();
+        goto finish;
+    }
+
+   /* For real kexts, try to get the UUID from the linked executable,
+    * or if is hasn't been linked yet, the unrelocated executable.
+    */
+    theExecutable = linkedExecutable;
+    if (!theExecutable) {
+        theExecutable = getExecutable();
+    }
+    if (!theExecutable) {
+        goto finish;
+    }
+
+    header = (const kernel_mach_header_t *)theExecutable->getBytesNoCopy();
+    load_cmd = (const struct load_command *)&header[1];
+        
+    if (header->magic != MH_MAGIC_KERNEL) {
+        OSKextLog(NULL,
+                  kOSKextLogErrorLevel | kOSKextLogGeneralFlag,
+                  "%s: bad header %p",
+                  __func__,
+                  header);
+        goto finish;
+    }
+    
+    for (i = 0; i < header->ncmds; i++) {
+        if (load_cmd->cmd == LC_UUID) {
+            uuid_cmd = (struct uuid_command *)load_cmd;
+            result = OSData::withBytes(uuid_cmd->uuid, sizeof(uuid_cmd->uuid));
+            goto finish;
+        }
+        load_cmd = (struct load_command *)((caddr_t)load_cmd + load_cmd->cmdsize);
+    }
 
 finish:
-	return result;
-}
-
-/*********************************************************************
-*********************************************************************/
-OSSharedPtr<OSData>
-OSKext::copyTextUUID(void)
-{
-	if (flags.builtin) {
-		return copyMachoUUID((const kernel_mach_header_t *)kmod_info->address);
-	}
-	return copyUUID();
-}
-
-/*********************************************************************
-*********************************************************************/
-OSSharedPtr<OSData>
-OSKext::copyMachoUUID(const kernel_mach_header_t * header)
-{
-	OSSharedPtr<OSData>                     result;
-	const struct load_command  * load_cmd      = NULL;
-	const struct uuid_command  * uuid_cmd      = NULL;
-	uint32_t                     i;
-
-	load_cmd = (const struct load_command *)&header[1];
-
-	if (header->magic != MH_MAGIC_KERNEL) {
-		OSKextLog(NULL,
-		    kOSKextLogErrorLevel | kOSKextLogGeneralFlag,
-		    "%s: bad header %p",
-		    __func__,
-		    header);
-		goto finish;
-	}
-
-	for (i = 0; i < header->ncmds; i++) {
-		if (load_cmd->cmd == LC_UUID) {
-			uuid_cmd = (struct uuid_command *)load_cmd;
-			result = OSData::withValue(uuid_cmd->uuid);
-			goto finish;
-		}
-		load_cmd = (struct load_command *)((caddr_t)load_cmd + load_cmd->cmdsize);
-	}
-
-finish:
-	return result;
-}
-
-void
-OSKext::setDriverKitUUID(OSData *uuid)
-{
-	if (!OSCompareAndSwapPtr(nullptr, uuid, &driverKitUUID)) {
-		OSSafeReleaseNULL(uuid);
-	}
-}
-
-OSData *
-OSKext::getDextUniqueID(void)
-{
-	if (isDriverKit() && dextUniqueID != NULL) {
-		return dextUniqueID.get();
-	}
-
-	return NULL;
-}
-
-/*
- * In case a DextUniqueID exists this function returns
- * an allocated char* with the hexadecimal represantition of
- * DextUniqueID.
- * The returned pinter needs to be freed with kfree_data, the
- * size of the allocated buffer is returned in size.
- */
-static const char *
-getDextUniqueIDCString(OSData *dextUniqueID, unsigned int *size)
-{
-	if (dextUniqueID != NULL) {
-		char *s_buffer = NULL;
-		unsigned int d_length = dextUniqueID->getLength();
-		/*
-		 * We are converting in hex, so for every byte we will have
-		 * 2 hex chars and one last \0.
-		 */
-		unsigned int s_length = d_length * 2 + 1;
-		s_buffer = (char *) kalloc_data(s_length, Z_WAITOK_ZERO);
-
-		char *uid = (char*) dextUniqueID->getBytesNoCopy();
-		int cpos = 0;
-		for (unsigned int i = 0; i < d_length && cpos < (s_length - 1); i++) {
-			int ret = snprintf(s_buffer + cpos, s_length - cpos - 1, "%02X", uid[i]);
-			if (ret <= 0) {
-				break;
-			}
-			cpos += ret;
-		}
-		*size = s_length;
-
-		return s_buffer;
-	}
-
-	return NULL;
-}
-
-/*
- * Atomically swaps the olddext with newdext.
- * olddext will be unloaded, so it might be freed
- * after this call unless it was previously retained.
- *
- * If newdext is NULL, this unloads olddext and does not perform an upgrade
- */
-void
-OSKext::replaceDextInternal(OSKext *olddext, OSKext *newdext)
-{
-	OSReturn result;
-	const OSSymbol * dextID = olddext->getIdentifier();
-	OSData * oldDextUniqueIdentifier = olddext->getDextUniqueID();
-	OSSharedPtr<OSArray> new_personalities;
-	OSSharedPtr<OSString> kextIdentifier;
-	__assert_only bool lock_held = IORecursiveLockHaveLock(sKextLock);
-	assert(lock_held);
-
-	// The old dext will be unloaded and release dextID, so we need to retain dextID here
-	dextID->retain();
-
-	if (newdext != NULL) {
-		__assert_only bool eq = dextID->isEqualTo(newdext->getIdentifier());
-		assert(eq);
-	}
-
-	if (newdext != NULL) {
-		/*
-		 * Swap the catalog personalities.
-		 */
-		new_personalities = newdext->copyPersonalitiesArray();
-		olddext->updatePersonalitiesInCatalog(new_personalities.get());
-	}
-
-	if (NULL != oldDextUniqueIdentifier) {
-		oldDextUniqueIdentifier->retain();
-	}
-
-	/*
-	 * Unload the dext.
-	 */
-	result = olddext->unload();
-	if (result != kOSReturnSuccess) {
-		OSKextLog(NULL,
-		    kOSKextLogErrorLevel | kOSKextLogLoadFlag,
-		    "Cannot unload dext for upgrade %s: %d\n",
-		    dextID->getCStringNoCopy(), result);
-	}
-
-	if (newdext != NULL) {
-		/*
-		 * Swap the dexts on the OSKext dictionary.
-		 * This might free the dext.
-		 */
-		sKextsByID->setObject(dextID, newdext);
-	} else {
-		/*
-		 * Remove the old dext
-		 */
-		removeKext(olddext, true);
-	}
-
-	/*
-	 * Inform userspace.
-	 */
-	if (newdext != NULL) {
-		result = notifyDextUpgrade(OSDynamicCast(OSString, dextID), newdext->getDextUniqueID());
-		if (result != kOSReturnSuccess) {
-			OSKextLog(NULL,
-			    kOSKextLogErrorLevel | kOSKextLogLoadFlag,
-			    "Cannot send upgrade notification for %s\n",
-			    dextID->getCStringNoCopy());
-		}
-	} else {
-		// notify dext removal
-		queueKextNotification(kKextRequestPredicateUnloadNotification,
-		    OSDynamicCast(OSString, dextID), oldDextUniqueIdentifier);
-	}
-
-	OSSafeReleaseNULL(dextID);
-	OSSafeReleaseNULL(oldDextUniqueIdentifier);
-}
-
-/*
- * To be called with sKextLock held.
- * NOTE: this could unload the olddext.
- */
-bool
-OSKext::upgradeDext(OSKext *olddext, OSKext *newdext)
-{
-	const char * dextIDCS = newdext->getIdentifierCString();
-	__assert_only bool old_isDext = olddext->isDriverKit();
-	__assert_only bool new_isDext = newdext->isDriverKit();
-	__assert_only bool lock_held = IORecursiveLockHaveLock(sKextLock);
-
-	assert(old_isDext && new_isDext);
-	assert(lock_held);
-
-	/*
-	 * New dext and old dext have the same ID.
-	 * We use this ID as key on the OSKext
-	 * dictionarys/arrays.
-	 */
-	const OSSymbol * dextID = newdext->getIdentifier();
-	__assert_only bool eq = dextID->isEqualTo(olddext->getIdentifier());
-	assert(eq);
-
-	/*
-	 * Set this OSKect as to update.
-	 * Note that this flags will never be removed once set.
-	 * When a OSKext is marked, it will be substitued by a new
-	 * OSKext, and every subsystem having a reference on this
-	 * OSKext need to know they have check if they can use
-	 * this OSKext or look for a new one.
-	 */
-	olddext->flags.dextToReplace = 1;
-
-	/*
-	 * Check if the current OSKext has any
-	 * userspace processes launched.
-	 * In this case we cannot upgrade and we have to
-	 * delay the upgrade until all processes
-	 * are done.
-	 */
-	if (olddext->dextLaunchedCount == 0) {
-		/*
-		 * Be sure that if there are no launched dexts, no
-		 * pending upgrades exist.
-		 * This is an error if it happens, as the decrement
-		 * should have removed the dext from sDriverKitToUpgradeByID
-		 * in case it reached 0.
-		 */
-		OSObject *pending_upgdare = sDriverKitToUpgradeByID->getObject(dextID);
-		if (pending_upgdare != NULL) {
-			OSKextLog(NULL,
-			    kOSKextLogErrorLevel | kOSKextLogLoadFlag,
-			    "Pending upgrade found for %s but dextLaunchedCount is 0!\n",
-			    dextIDCS);
-			goto out;
-		}
-
-		replaceDextInternal(olddext, newdext);
-		return true;
-	}
-
-out:
-
-	/*
-	 * Delay the upgrade.
-	 * Make the new dext available in sDriverKitToUpgradeByID.
-	 * In case there was already a pending upgrade, this will
-	 * overwrite it.
-	 */
-	sDriverKitToUpgradeByID->setObject(dextID, newdext);
-	return false;
-}
-
-/*
- * To be called with sKextLock held.
- * NOTE: this could unload the dext.
- */
-bool
-OSKext::removeDext(OSKext *dext)
-{
-	__assert_only bool dext_isDext = dext->isDriverKit();
-	__assert_only bool lock_held = IORecursiveLockHaveLock(sKextLock);
-	IOReturn result;
-
-	assert(dext_isDext);
-	assert(lock_held);
-
-	/*
-	 * Set this OSKext to be unloaded when all running instances exit.
-	 */
-	dext->flags.dextToReplace = 1;
-
-	result = gIOCatalogue->terminateDriversForModule(
-		dext->getIdentifierCString(), /* unload */ false, /* asynchronous */ true);
-	if (result != kOSReturnSuccess) {
-		OSKextLog(dext,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogKextBookkeepingFlag,
-		    "%s services failed to terminate - 0x%x.",
-		    dext->getIdentifierCString(), result);
-	}
-
-	dext->removePersonalitiesFromCatalog();
-	sDriverKitToUpgradeByID->removeObject(dext->getIdentifier());
-
-	/*
-	 * Check if the current OSKext has any
-	 * userspace processes launched.
-	 * In this case we cannot unload and we have to
-	 * delay the unload until all processes
-	 * are done.
-	 */
-	if (dext->dextLaunchedCount == 0) {
-		replaceDextInternal(dext, NULL);
-		return true;
-	}
-
-	return false;
-}
-
-bool
-OSKext::incrementDextLaunchCount(OSKext *dext, OSData *dextUniqueIDToMatch)
-{
-	bool ret = false;
-	__assert_only bool isDext = dext->isDriverKit();
-	assert(isDext);
-
-	const char * dextIDCS = dext->getIdentifierCString();
-	OSData *myDextUniqueID = dext->getDextUniqueID();
-
-	if (!myDextUniqueID || !dextUniqueIDToMatch) {
-		OSKextLog(dext,
-		    kOSKextLogErrorLevel | kOSKextLogLoadFlag,
-		    "Cannot find dext UniqueID for %s, cannot increment dext launches\n",
-		    dextIDCS);
-		return ret;
-	}
-
-	unsigned int dextUniqueIDCStringSize = 0, dextUniqueIDToMatchCStringSize = 0;
-	const char *dextUniqueIDCString = getDextUniqueIDCString(myDextUniqueID, &dextUniqueIDCStringSize);
-	const char *dextUniqueIDToMatchCString = getDextUniqueIDCString(dextUniqueIDToMatch, &dextUniqueIDToMatchCStringSize);
-	assert(dextUniqueIDCString != NULL);
-	assert(dextUniqueIDToMatchCString != NULL);
-
-	IORecursiveLockLock(sKextLock);
-
-	/*
-	 * Check that the dext we are referencing is the same
-	 * looked for the match.
-	 */
-	if (myDextUniqueID->isEqualTo(dextUniqueIDToMatch)) {
-		if (dext->flags.dextToReplace == 0 || dext->dextLaunchedCount > 0) {
-			if (dext->dextLaunchedCount == kOSKextMaxDextLaunchedCount) {
-				OSKextLog(dext,
-				    kOSKextLogErrorLevel | kOSKextLogLoadFlag,
-				    "Too many dexts launched for %s UniqueID %s\n",
-				    dextIDCS, dextUniqueIDCString);
-			} else {
-				dext->dextLaunchedCount++;
-				ret = true;
-
-				OSKextLog(dext,
-				    kOSKextLogProgressLevel | kOSKextLogLoadFlag,
-				    "New dext launched for  %s UniqueID %s",
-				    dextIDCS, dextUniqueIDCString);
-			}
-		} else {
-			OSKextLog(dext,
-			    kOSKextLogProgressLevel | kOSKextLogLoadFlag,
-			    "Dext %s UniqueID %s requires update, cannot launch a new dext\n",
-			    dextIDCS, dextUniqueIDCString);
-		}
-	} else {
-		OSKextLog(dext,
-		    kOSKextLogProgressLevel | kOSKextLogLoadFlag,
-		    "Dext %s: UniqueID %s does not match UniqueID looked for %s, cannot launch a new dext\n",
-		    dextIDCS, dextUniqueIDCString, dextUniqueIDToMatchCString);
-	}
-
-	IORecursiveLockUnlock(sKextLock);
-
-	if (dextUniqueIDCString != NULL) {
-		kfree_data(dextUniqueIDCString, dextUniqueIDCStringSize);
-	}
-	if (dextUniqueIDToMatchCString != NULL) {
-		kfree_data(dextUniqueIDToMatchCString, dextUniqueIDToMatchCStringSize);
-	}
-	return ret;
-}
-
-bool
-OSKext::decrementDextLaunchCount(OSString *bundleID)
-{
-	bool ret = false;
-	const char * dextIDCS;
-	OSData *myDextUniqueID;
-	unsigned int dextUniqueIDCStringSize = 0;
-	const char * dextUniqueIDCString = NULL;
-	OSKext* dext = NULL;
-
-	if (!bundleID) {
-		return ret;
-	}
-	dextIDCS = bundleID->getCStringNoCopy();
-
-	IORecursiveLockLock(sKextLock);
-
-	/*
-	 * Look for the dext with the bundle it. This
-	 * call is triggered only if a previous increment was
-	 * performed. It means that the dext could have not
-	 * been upgraded as its dextLaunchedCount was at least 1.
-	 * Because of this it still needs to be available
-	 * in sKextsByID.
-	 */
-	dext = OSDynamicCast(OSKext, sKextsByID->getObject(dextIDCS));
-	if (!dext || !dext->isDriverKit()) {
-		OSKextLog(NULL,
-		    kOSKextLogErrorLevel | kOSKextLogLoadFlag,
-		    "Cannot find dext for %s, cannot decrement dext launches\n",
-		    dextIDCS);
-
-		goto out_locked;
-	}
-
-	myDextUniqueID = dext->getDextUniqueID();
-	if (!myDextUniqueID) {
-		OSKextLog(dext,
-		    kOSKextLogErrorLevel | kOSKextLogLoadFlag,
-		    "Cannot find dext UniqueID for %s, cannot decrement dext launches\n",
-		    dextIDCS);
-
-		goto out_locked;
-	}
-	dextUniqueIDCString = getDextUniqueIDCString(myDextUniqueID, &dextUniqueIDCStringSize);
-	assert(dextUniqueIDCString != NULL);
-
-	if (dext->dextLaunchedCount == 0) {
-		OSKextLog(dext,
-		    kOSKextLogErrorLevel | kOSKextLogLoadFlag,
-		    "Over decrementing dext launch for %s UniqueID %s\n",
-		    dextIDCS, dextUniqueIDCString);
-
-		goto out_locked;
-	}
-
-	dext->dextLaunchedCount--;
-
-	OSKextLog(dext,
-	    kOSKextLogProgressLevel | kOSKextLogLoadFlag,
-	    "Dext terminated for %s UniqueID %s",
-	    dextIDCS, dextUniqueIDCString);
-
-	if (dext->dextLaunchedCount == 0 && dext->flags.dextToReplace == 1) {
-		/*
-		 * Find the upgraded dext.
-		 */
-		OSKext *newdext = OSDynamicCast(OSKext, sDriverKitToUpgradeByID->getObject(dextIDCS));
-		if (newdext) {
-			OSKextLog(dext,
-			    kOSKextLogProgressLevel | kOSKextLogLoadFlag,
-			    "Dext upgrade for %s UniqueID %s",
-			    dextIDCS, dextUniqueIDCString);
-			replaceDextInternal(dext, newdext);
-			/* NOTE dext could have been freed past this point */
-
-			sDriverKitToUpgradeByID->removeObject(dextIDCS);
-		} else {
-			OSKextLog(dext,
-			    kOSKextLogProgressLevel | kOSKextLogLoadFlag,
-			    "Dext unload for %s UniqueID %s",
-			    dextIDCS, dextUniqueIDCString);
-			replaceDextInternal(dext, NULL);
-		}
-
-		ret = true;
-	}
-out_locked:
-	IORecursiveLockUnlock(sKextLock);
-
-	if (dextUniqueIDCString != NULL) {
-		kfree_data(dextUniqueIDCString, dextUniqueIDCStringSize);
-	}
-
-	return ret;
-}
-
-/*********************************************************************
-*********************************************************************/
-#if defined (__arm__)
-#include <arm/arch.h>
-#endif
+    return result;
+}
+
+/*********************************************************************
+*********************************************************************/
 
 #if   defined (__x86_64__)
 #define ARCHNAME "x86_64"
-#elif defined (__arm64__)
-#define ARCHNAME "arm64"
-#elif defined (__arm__)
-
-#if defined (__ARM_ARCH_7S__)
-#define ARCHNAME "armv7s"
-#elif defined (__ARM_ARCH_7F__)
-#define ARCHNAME "armv7f"
-#elif defined (__ARM_ARCH_7K__)
-#define ARCHNAME "armv7k"
-#elif defined (_ARM_ARCH_7) /* umbrella for all remaining */
-#define ARCHNAME "armv7"
-#elif defined (_ARM_ARCH_6) /* umbrella for all armv6 */
-#define ARCHNAME "armv6"
-#endif
-
-#elif defined (__arm64__)
-#define ARCHNAME "arm64"
 #else
 #error architecture not supported
 #endif
 
 #define ARCH_SEPARATOR_CHAR  '_'
 
-static char *
-makeHostArchKey(const char * key, size_t * keySizeOut)
-{
-	char     * result = NULL;
-	size_t     keyLength = strlen(key);
-	size_t     keySize;
-
-	/* Add 1 for the ARCH_SEPARATOR_CHAR, and 1 for the '\0'.
-	 */
-	keySize = 1 + 1 + keyLength + strlen(ARCHNAME);
-	result = (char *)kalloc_data_tag(keySize, Z_WAITOK, VM_KERN_MEMORY_OSKEXT);
-
-	if (!result) {
-		goto finish;
-	}
-	strlcpy(result, key, keySize);
-	result[keyLength++] = ARCH_SEPARATOR_CHAR;
-	result[keyLength] = '\0';
-	strlcat(result, ARCHNAME, keySize);
-	*keySizeOut = keySize;
+static char * makeHostArchKey(const char * key, uint32_t * keySizeOut)
+{
+    char     * result = NULL;
+    uint32_t   keyLength = strlen(key);
+    uint32_t   keySize;
+
+   /* Add 1 for the ARCH_SEPARATOR_CHAR, and 1 for the '\0'.
+    */
+    keySize = 1 + 1 + strlen(key) + strlen(ARCHNAME);
+    result = (char *)kalloc_tag(keySize, VM_KERN_MEMORY_OSKEXT);
+    if (!result) {
+        goto finish;
+    }
+    strlcpy(result, key, keySize);
+    result[keyLength++] = ARCH_SEPARATOR_CHAR;
+    result[keyLength] = '\0';
+    strlcat(result, ARCHNAME, keySize);
+    *keySizeOut = keySize;
 
 finish:
-	return result;
+    return result;
 }
 
 /*********************************************************************
@@ -5834,598 +4031,302 @@
 OSObject *
 OSKext::getPropertyForHostArch(const char * key)
 {
-	OSObject * result           = NULL;// do not release
-	size_t     hostArchKeySize  = 0;
-	char     * hostArchKey      = NULL;// must kfree
-
-	if (!key || !infoDict) {
-		goto finish;
-	}
-
-	/* Some properties are not allowed to be arch-variant:
-	 * - Any CFBundle... property.
-	 * - OSBundleIsInterface.
-	 * - OSKernelResource.
-	 */
-	if (STRING_HAS_PREFIX(key, "OS") ||
-	    STRING_HAS_PREFIX(key, "IO")) {
-		hostArchKey = makeHostArchKey(key, &hostArchKeySize);
-		if (!hostArchKey) {
-			OSKextLog(/* kext (this isn't about a kext) */ NULL,
-			    kOSKextLogErrorLevel | kOSKextLogGeneralFlag,
-			    "Allocation failure.");
-			goto finish;
-		}
-		result = infoDict->getObject(hostArchKey);
-	}
-
-	if (!result) {
-		result = infoDict->getObject(key);
-	}
+    OSObject * result           = NULL;  // do not release
+    uint32_t   hostArchKeySize  = 0;
+    char     * hostArchKey      = NULL;  // must kfree
+    
+    if (!key || !infoDict) {
+        goto finish;
+    }
+    
+   /* Some properties are not allowed to be arch-variant:
+    * - Any CFBundle... property.
+    * - OSBundleIsInterface.
+    * - OSKernelResource.
+    */
+    if (STRING_HAS_PREFIX(key, "OS") ||
+        STRING_HAS_PREFIX(key, "IO")) {
+
+        hostArchKey = makeHostArchKey(key, &hostArchKeySize);
+        if (!hostArchKey) {
+            OSKextLog(/* kext (this isn't about a kext) */ NULL,
+                kOSKextLogErrorLevel | kOSKextLogGeneralFlag,
+                "Allocation failure.");
+            goto finish;
+        }
+        result = infoDict->getObject(hostArchKey);
+    }
+    
+    if (!result) {
+        result = infoDict->getObject(key);
+    }
 
 finish:
-	if (hostArchKey) {
-		kfree_data(hostArchKey, hostArchKeySize);
-	}
-	return result;
+    if (hostArchKey) kfree(hostArchKey, hostArchKeySize);
+    return result;
 }
 
 #if PRAGMA_MARK
 #pragma mark Load/Start/Stop/Unload
 #endif
 
-#define isWhiteSpace(c) ((c) == ' ' || (c) == '\t' || (c) == '\r' || (c) == ',' || (c) == '\n')
-
-/*********************************************************************
-* sExcludeListByID is a dictionary with keys / values of:
-*  key = bundleID string of kext we will not allow to load
-*  value = version string(s) of the kext that is to be denied loading.
-*      The version strings can be comma delimited.  For example if kext
-*      com.foocompany.fookext has two versions that we want to deny
-*      loading then the version strings might look like:
-*      1.0.0, 1.0.1
-*      If the current fookext has a version of 1.0.0 OR 1.0.1 we will
-*      not load the kext.
-*
-*      Value may also be in the form of "LE 2.0.0" (version numbers
-*      less than or equal to 2.0.0 will not load) or "LT 2.0.0" (version
-*      number less than 2.0.0 will not load)
-*
-*      NOTE - we cannot use the characters "<=" or "<" because we have code
-*      that serializes plists and treats '<' as a special character.
-*********************************************************************/
-bool
+#define isWhiteSpace(c)	((c) == ' ' || (c) == '\t' || (c) == '\r' || (c) == ',' || (c) == '\n')
+
+/*********************************************************************
+ * sExcludeListByID is a dictionary with keys / values of:
+ *  key = bundleID string of kext we will not allow to load
+ *  value = version string(s) of the kext that is to be denied loading.
+ *      The version strings can be comma delimited.  For example if kext
+ *      com.foocompany.fookext has two versions that we want to deny
+ *      loading then the version strings might look like:
+ *      1.0.0, 1.0.1
+ *      If the current fookext has a version of 1.0.0 OR 1.0.1 we will
+ *      not load the kext.
+ *
+ *      Value may also be in the form of "LE 2.0.0" (version numbers
+ *      less than or equal to 2.0.0 will not load) or "LT 2.0.0" (version 
+ *      number less than 2.0.0 will not load)
+ *
+ *      NOTE - we cannot use the characters "<=" or "<" because we have code 
+ *      that serializes plists and treats '<' as a special character.
+ *********************************************************************/
+bool 
 OSKext::isInExcludeList(void)
 {
-	OSString *      versionString           = NULL;        // do not release
-	char *          versionCString          = NULL;        // do not free
-	size_t          i;
-	boolean_t       wantLessThan = false;
-	boolean_t       wantLessThanEqualTo = false;
-	boolean_t       isInExcludeList = true;
-	char            myBuffer[32];
-
-	IORecursiveLockLock(sKextLock);
-
-	if (!sExcludeListByID) {
-		isInExcludeList = false;
-	} else {
-		/* look up by bundleID in our exclude list and if found get version
-		 * string (or strings) that we will not allow to load
-		 */
-		versionString = OSDynamicCast(OSString, sExcludeListByID->getObject(bundleID.get()));
-		if (versionString == NULL || versionString->getLength() > (sizeof(myBuffer) - 1)) {
-			isInExcludeList = false;
-		}
-	}
-
-	IORecursiveLockUnlock(sKextLock);
-
-	if (!isInExcludeList) {
-		return false;
-	}
-
-	/* parse version strings */
-	versionCString = (char *) versionString->getCStringNoCopy();
-
-	/* look for "LT" or "LE" form of version string, must be in first two
-	 * positions.
-	 */
-	if (*versionCString == 'L' && *(versionCString + 1) == 'T') {
-		wantLessThan = true;
-		versionCString += 2;
-	} else if (*versionCString == 'L' && *(versionCString + 1) == 'E') {
-		wantLessThanEqualTo = true;
-		versionCString += 2;
-	}
-
-	for (i = 0; *versionCString != 0x00; versionCString++) {
-		/* skip whitespace */
-		if (isWhiteSpace(*versionCString)) {
-			continue;
-		}
-
-		/* peek ahead for version string separator or null terminator */
-		if (*(versionCString + 1) == ',' || *(versionCString + 1) == 0x00) {
-			/* OK, we have a version string */
-			myBuffer[i++] = *versionCString;
-			myBuffer[i] = 0x00;
-
-			OSKextVersion excludeVers;
-			excludeVers = OSKextParseVersionString(myBuffer);
-
-			if (wantLessThanEqualTo) {
-				if (version <= excludeVers) {
-					return true;
-				}
-			} else if (wantLessThan) {
-				if (version < excludeVers) {
-					return true;
-				}
-			} else if (version == excludeVers) {
-				return true;
-			}
-
-			/* reset for the next (if any) version string */
-			i = 0;
-			wantLessThan = false;
-			wantLessThanEqualTo = false;
-		} else {
-			/* save valid version character */
-			myBuffer[i++] = *versionCString;
-
-			/* make sure bogus version string doesn't overrun local buffer */
-			if (i >= sizeof(myBuffer)) {
-				break;
-			}
-		}
-	}
-
-	return false;
-}
-
-/*********************************************************************
-* sNonLoadableKextsByID is a dictionary with keys / values of:
-*  key = bundleID string of kext we will not allow to load
-*  value = boolean (true == loadable, false == not loadable)
-*
-*  Only kexts which are in the AuxKC will be marked as "not loadble,"
-*  i.e., the value for the kext's bundleID will be false. All kexts in
-*  the primary and system KCs will always be marked as "loadable."
-*
-*  This list ultimately comes from kexts which have been uninstalled
-*  in user space by deleting the kext from disk, but which have not
-*  yet been removed from the AuxKC. Because the user could choose to
-*  re-install the exact same version of the kext, we need to keep
-*  a dictionary of boolean values so that user space only needs to
-*  keep a simple list of "uninstalled" or "missing" bundles. When
-*  a bundle is re-installed, the iokit daemon can use the
-*  AucKCBundleAvailable  predicate to set the individual kext's
-*  availability to true.
-*********************************************************************/
-bool
-OSKext::isLoadable(void)
-{
-	bool isLoadable = true;
-
-	if (kc_type != KCKindAuxiliary) {
-		/* this filtering only applies to kexts in the auxkc */
-		return true;
-	}
-
-	IORecursiveLockLock(sKextLock);
-
-	if (sNonLoadableKextsByID) {
-		/* look up by bundleID in our exclude list and if found get version
-		 * string (or strings) that we will not allow to load
-		 */
-		OSBoolean *loadableVal;
-		loadableVal = OSDynamicCast(OSBoolean, sNonLoadableKextsByID->getObject(bundleID.get()));
-		if (loadableVal && !loadableVal->getValue()) {
-			isLoadable = false;
-		}
-	}
-	IORecursiveLockUnlock(sKextLock);
-
-	return isLoadable;
-}
+    OSString *      versionString           = NULL;  // do not release
+    char *          versionCString          = NULL;  // do not free
+    size_t          i;
+    boolean_t       wantLessThan = false;
+    boolean_t       wantLessThanEqualTo = false;
+    char            myBuffer[32];
+    
+    if (!sExcludeListByID) {
+        return(false);
+    }
+    /* look up by bundleID in our exclude list and if found get version
+     * string (or strings) that we will not allow to load
+     */
+    versionString = OSDynamicCast(OSString, sExcludeListByID->getObject(bundleID));
+    if (versionString == NULL || versionString->getLength() > (sizeof(myBuffer) - 1)) {
+        return(false);
+    }
+    
+    /* parse version strings */
+    versionCString = (char *) versionString->getCStringNoCopy();
+    
+    /* look for "LT" or "LE" form of version string, must be in first two
+     * positions.
+     */
+    if (*versionCString == 'L' && *(versionCString + 1) == 'T') {
+        wantLessThan = true;
+        versionCString +=2; 
+    }
+    else if (*versionCString == 'L' && *(versionCString + 1) == 'E') {
+        wantLessThanEqualTo = true;
+        versionCString +=2;
+    }
+
+    for (i = 0; *versionCString != 0x00; versionCString++) {
+        /* skip whitespace */
+        if (isWhiteSpace(*versionCString)) {
+            continue;
+        }
+        
+        /* peek ahead for version string separator or null terminator */
+        if (*(versionCString + 1) == ',' || *(versionCString + 1) == 0x00) {
+            
+            /* OK, we have a version string */
+            myBuffer[i++] = *versionCString;
+            myBuffer[i] = 0x00;
+
+            OSKextVersion excludeVers;
+            excludeVers = OSKextParseVersionString(myBuffer);
+                
+            if (wantLessThanEqualTo) {
+                if (version <= excludeVers) {
+                    return(true);
+                }
+            }
+            else if (wantLessThan) {
+                if (version < excludeVers) {
+                    return(true);
+                }
+            }
+            else if ( version == excludeVers )  {
+                return(true);
+            }
+            
+            /* reset for the next (if any) version string */
+            i = 0;
+            wantLessThan = false;
+            wantLessThanEqualTo = false;
+        }
+        else {
+            /* save valid version character */
+            myBuffer[i++] = *versionCString;
+            
+            /* make sure bogus version string doesn't overrun local buffer */
+            if ( i >= sizeof(myBuffer) ) {
+                break;
+            }
+        }
+    }
+    
+    return(false);
+} 
 
 /*********************************************************************
 *********************************************************************/
 /* static */
 OSReturn
 OSKext::loadKextWithIdentifier(
-	const char       * kextIdentifierCString,
-	Boolean            allowDeferFlag,
-	Boolean            delayAutounloadFlag,
-	OSKextExcludeLevel startOpt,
-	OSKextExcludeLevel startMatchingOpt,
-	OSArray          * personalityNames)
-{
-	OSReturn   result         = kOSReturnError;
-	OSSharedPtr<OSString> kextIdentifier;
-
-	kextIdentifier = OSString::withCString(kextIdentifierCString);
-	if (!kextIdentifier) {
-		result = kOSKextReturnNoMemory;
-		goto finish;
-	}
-	result = OSKext::loadKextWithIdentifier(kextIdentifier.get(),
-	    NULL /* kextRef */,
-	    allowDeferFlag, delayAutounloadFlag,
-	    startOpt, startMatchingOpt, personalityNames);
-
+    const char       * kextIdentifierCString,
+    Boolean            allowDeferFlag,
+    Boolean            delayAutounloadFlag,
+    OSKextExcludeLevel startOpt,
+    OSKextExcludeLevel startMatchingOpt,
+    OSArray          * personalityNames)
+{
+    OSReturn   result         = kOSReturnError;
+    OSString * kextIdentifier = NULL;  // must release
+
+    kextIdentifier = OSString::withCString(kextIdentifierCString);
+    if (!kextIdentifier) {
+        result = kOSKextReturnNoMemory;
+        goto finish;
+    }
+    result = OSKext::loadKextWithIdentifier(kextIdentifier,
+        allowDeferFlag, delayAutounloadFlag,
+        startOpt, startMatchingOpt, personalityNames);
+        
 finish:
-	return result;
-}
-
+    OSSafeRelease(kextIdentifier);
+    return result;
+}
+
+/*********************************************************************
+*********************************************************************/
 OSReturn
 OSKext::loadKextWithIdentifier(
-	OSString          * kextIdentifier,
-	OSSharedPtr<OSObject>         &kextRef,
-	Boolean             allowDeferFlag,
-	Boolean             delayAutounloadFlag,
-	OSKextExcludeLevel  startOpt,
-	OSKextExcludeLevel  startMatchingOpt,
-	OSArray           * personalityNames)
-{
-	OSObject * kextRefRaw = NULL;
-	OSReturn result;
-
-	result = loadKextWithIdentifier(kextIdentifier,
-	    &kextRefRaw,
-	    allowDeferFlag,
-	    delayAutounloadFlag,
-	    startOpt,
-	    startMatchingOpt,
-	    personalityNames);
-	if ((kOSReturnSuccess == result) && kextRefRaw) {
-		kextRef.reset(kextRefRaw, OSNoRetain);
-	}
-	return result;
-}
-
-/*********************************************************************
-*********************************************************************/
-OSReturn
-OSKext::loadKextWithIdentifier(
-	OSString          * kextIdentifier,
-	OSObject         ** kextRef,
-	Boolean             allowDeferFlag,
-	Boolean             delayAutounloadFlag,
-	OSKextExcludeLevel  startOpt,
-	OSKextExcludeLevel  startMatchingOpt,
-	OSArray           * personalityNames)
-{
-	OSReturn          result               = kOSReturnError;
-	OSReturn          pingResult           = kOSReturnError;
-	OSKext          * theKext              = NULL;        // do not release
-	OSSharedPtr<OSDictionary>   loadRequest;
-	OSSharedPtr<const OSSymbol> kextIdentifierSymbol;
-
-	if (kextRef) {
-		*kextRef = NULL;
-	}
-
-	IORecursiveLockLock(sKextLock);
-
-	if (!kextIdentifier) {
-		result = kOSKextReturnInvalidArgument;
-		goto finish;
-	}
-
-	OSKext::recordIdentifierRequest(kextIdentifier);
-
-	theKext = OSDynamicCast(OSKext, sKextsByID->getObject(kextIdentifier));
-	if (!theKext) {
-		if (!allowDeferFlag) {
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogLoadFlag,
-			    "Can't load kext %s - not found.",
-			    kextIdentifier->getCStringNoCopy());
-			goto finish;
-		}
-
-		if (!sKernelRequestsEnabled) {
-			OSKextLog(theKext,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogLoadFlag,
-			    "Can't load kext %s - requests to user space are disabled.",
-			    kextIdentifier->getCStringNoCopy());
-			result = kOSKextReturnDisabled;
-			goto finish;
-		}
-
-		/* Create a new request unless one is already sitting
-		 * in sKernelRequests for this bundle identifier
-		 */
-		kextIdentifierSymbol = OSSymbol::withString(kextIdentifier);
-		if (!sPostedKextLoadIdentifiers->containsObject(kextIdentifierSymbol.get())) {
-			result = _OSKextCreateRequest(kKextRequestPredicateRequestLoad,
-			    loadRequest);
-			if (result != kOSReturnSuccess) {
-				goto finish;
-			}
-			if (!_OSKextSetRequestArgument(loadRequest.get(),
-			    kKextRequestArgumentBundleIdentifierKey, kextIdentifier)) {
-				result = kOSKextReturnNoMemory;
-				goto finish;
-			}
-			if (!sKernelRequests->setObject(loadRequest.get())) {
-				result = kOSKextReturnNoMemory;
-				goto finish;
-			}
-
-			if (!sPostedKextLoadIdentifiers->setObject(kextIdentifierSymbol.get())) {
-				result = kOSKextReturnNoMemory;
-				goto finish;
-			}
-
-			OSKextLog(theKext,
-			    kOSKextLogDebugLevel |
-			    kOSKextLogLoadFlag,
-			    "Kext %s not found; queued load request to user space.",
-			    kextIdentifier->getCStringNoCopy());
-		}
-
-		pingResult = OSKext::pingIOKitDaemon();
-		if (pingResult == kOSKextReturnDisabled) {
-			OSKextLog(/* kext */ NULL,
-			    ((sPrelinkBoot) ? kOSKextLogDebugLevel : kOSKextLogErrorLevel) |
-			    kOSKextLogLoadFlag,
-			    "Kext %s might not load - " kIOKitDaemonName " is currently unavailable.",
-			    kextIdentifier->getCStringNoCopy());
-		}
-
-		result = kOSKextReturnDeferred;
-		goto finish;
-	}
-
-	result = theKext->load(startOpt, startMatchingOpt, personalityNames);
-
-	if (result != kOSReturnSuccess) {
-		OSKextLog(theKext,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag,
-		    "Failed to load kext %s (error 0x%x).",
-		    kextIdentifier->getCStringNoCopy(), (int)result);
-
-		if (theKext->kc_type == KCKindUnknown) {
-			OSKext::removeKext(theKext,
-			    /* terminateService/removePersonalities */ true);
-		}
-		goto finish;
-	}
-
-	if (delayAutounloadFlag) {
-		OSKextLog(theKext,
-		    kOSKextLogProgressLevel |
-		    kOSKextLogLoadFlag | kOSKextLogKextBookkeepingFlag,
-		    "Setting delayed autounload for %s.",
-		    kextIdentifier->getCStringNoCopy());
-		theKext->flags.delayAutounload = 1;
-	}
+    OSString          * kextIdentifier,
+    Boolean             allowDeferFlag,
+    Boolean             delayAutounloadFlag,
+    OSKextExcludeLevel  startOpt,
+    OSKextExcludeLevel  startMatchingOpt,
+    OSArray           * personalityNames)
+{
+    OSReturn          result               = kOSReturnError;
+    OSReturn          pingResult           = kOSReturnError;
+    OSKext          * theKext              = NULL;  // do not release
+    OSDictionary    * loadRequest          = NULL;  // must release
+    const OSSymbol  * kextIdentifierSymbol = NULL;  // must release
+
+    IORecursiveLockLock(sKextLock);
+
+    if (!kextIdentifier) {
+        result = kOSKextReturnInvalidArgument;
+        goto finish;
+    }
+
+    OSKext::recordIdentifierRequest(kextIdentifier);
+
+    theKext = OSDynamicCast(OSKext, sKextsByID->getObject(kextIdentifier));
+    if (!theKext) {
+        if (!allowDeferFlag) {
+            OSKextLog(/* kext */ NULL,
+                kOSKextLogErrorLevel |
+                kOSKextLogLoadFlag,
+                "Can't load kext %s - not found.",
+                kextIdentifier->getCStringNoCopy());
+             goto finish;
+        }
+        
+        if (!sKernelRequestsEnabled) {
+            OSKextLog(theKext,
+                kOSKextLogErrorLevel |
+                kOSKextLogLoadFlag,
+                "Can't load kext %s - requests to user space are disabled.",
+                kextIdentifier->getCStringNoCopy());
+            result = kOSKextReturnDisabled;
+            goto finish;
+        }
+
+       /* Create a new request unless one is already sitting
+        * in sKernelRequests for this bundle identifier
+        */
+        kextIdentifierSymbol = OSSymbol::withString(kextIdentifier);
+        if (!sPostedKextLoadIdentifiers->containsObject(kextIdentifierSymbol)) {
+            result = _OSKextCreateRequest(kKextRequestPredicateRequestLoad,
+                &loadRequest);
+            if (result != kOSReturnSuccess) {
+                goto finish;
+            }
+            if (!_OSKextSetRequestArgument(loadRequest,
+                kKextRequestArgumentBundleIdentifierKey, kextIdentifier)) {
+                
+                result = kOSKextReturnNoMemory;
+                goto finish;
+            }
+            if (!sKernelRequests->setObject(loadRequest)) {
+                result = kOSKextReturnNoMemory;
+                goto finish;
+            }
+            
+            if (!sPostedKextLoadIdentifiers->setObject(kextIdentifierSymbol)) {
+                result = kOSKextReturnNoMemory;
+                goto finish;
+            }
+
+            OSKextLog(theKext,
+                kOSKextLogDebugLevel |
+                kOSKextLogLoadFlag,
+                "Kext %s not found; queued load request to user space.",
+                kextIdentifier->getCStringNoCopy());
+        }
+
+        pingResult = OSKext::pingKextd();
+        if (pingResult == kOSKextReturnDisabled) {
+            OSKextLog(/* kext */ NULL,
+                ((sPrelinkBoot) ? kOSKextLogDebugLevel : kOSKextLogErrorLevel) |
+                kOSKextLogLoadFlag,
+                "Kext %s might not load - kextd is currently unavailable.",
+                kextIdentifier->getCStringNoCopy());
+        }
+
+        result = kOSKextReturnDeferred;
+        goto finish;
+    }
+
+    result = theKext->load(startOpt, startMatchingOpt, personalityNames);
+
+    if (result != kOSReturnSuccess) {
+        OSKextLog(theKext,
+            kOSKextLogErrorLevel |
+            kOSKextLogLoadFlag,
+            "Failed to load kext %s (error 0x%x).",
+            kextIdentifier->getCStringNoCopy(), (int)result);
+
+        OSKext::removeKext(theKext,
+            /* terminateService/removePersonalities */ true);
+        goto finish;
+    }
+
+    if (delayAutounloadFlag) {
+        OSKextLog(theKext,
+            kOSKextLogProgressLevel |
+            kOSKextLogLoadFlag | kOSKextLogKextBookkeepingFlag,
+            "Setting delayed autounload for %s.",
+            kextIdentifier->getCStringNoCopy());
+        theKext->flags.delayAutounload = 1;
+    }
 
 finish:
-	if ((kOSReturnSuccess == result) && kextRef) {
-		*kextRef = theKext;
-		theKext->matchingRefCount++;
-		theKext->retain();
-	}
-
-	IORecursiveLockUnlock(sKextLock);
-
-	return result;
-}
-
-/*********************************************************************
-*********************************************************************/
-/* static */
-OSReturn
-OSKext::loadKextFromKC(OSKext *theKext, OSDictionary *requestDict)
-{
-	OSReturn  result = kOSReturnError;
-
-	OSBoolean *delayAutounloadBool     = NULL; // do not release
-	OSNumber  *startKextExcludeNum     = NULL; // do not release
-	OSNumber  *startMatchingExcludeNum = NULL; // do not release
-	OSArray   *personalityNames        = NULL; // do not release
-
-	/*
-	 * Default values for these options:
-	 *      regular autounload behavior
-	 *      start the kext
-	 *      send all personalities to the catalog
-	 */
-	Boolean            delayAutounload           = false;
-	OSKextExcludeLevel startKextExcludeLevel     = kOSKextExcludeNone;
-	OSKextExcludeLevel startMatchingExcludeLevel = kOSKextExcludeNone;
-
-	IORecursiveLockLock(sKextLock);
-
-	OSKextLog(/* kext */ NULL,
-	    kOSKextLogDebugLevel |
-	    kOSKextLogIPCFlag,
-	    "Received kext KC load request from user space.");
-
-	/* Regardless of processing, the fact that we have gotten here means some
-	 * user-space program is up and talking to us, so we'll switch our kext
-	 * registration to reflect that.
-	 */
-	if (!sUserLoadsActive) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogProgressLevel |
-		    kOSKextLogGeneralFlag | kOSKextLogLoadFlag,
-		    "Switching to late startup (user-space) kext loading policy.");
-		sUserLoadsActive = true;
-	}
-
-	delayAutounloadBool = OSDynamicCast(OSBoolean,
-	    _OSKextGetRequestArgument(requestDict,
-	    kKextRequestArgumentDelayAutounloadKey));
-	startKextExcludeNum = OSDynamicCast(OSNumber,
-	    _OSKextGetRequestArgument(requestDict,
-	    kKextRequestArgumentStartExcludeKey));
-	startMatchingExcludeNum = OSDynamicCast(OSNumber,
-	    _OSKextGetRequestArgument(requestDict,
-	    kKextRequestArgumentStartMatchingExcludeKey));
-	personalityNames = OSDynamicCast(OSArray,
-	    _OSKextGetRequestArgument(requestDict,
-	    kKextRequestArgumentPersonalityNamesKey));
-
-	if (delayAutounloadBool) {
-		delayAutounload = delayAutounloadBool->getValue();
-	}
-	if (startKextExcludeNum) {
-		startKextExcludeLevel = startKextExcludeNum->unsigned8BitValue();
-	}
-	if (startMatchingExcludeNum) {
-		startMatchingExcludeLevel = startMatchingExcludeNum->unsigned8BitValue();
-	}
-
-	OSKextLog(/* kext */ NULL,
-	    kOSKextLogProgressLevel |
-	    kOSKextLogIPCFlag,
-	    "Received request from user space to load KC kext %s.",
-	    theKext->getIdentifierCString());
-
-	/* this could be in the Auxiliary KC, so record the load request */
-	OSKext::recordIdentifierRequest(OSDynamicCast(OSString, theKext->getIdentifier()));
-
-	/*
-	 * Load the kext
-	 */
-	result = theKext->load(startKextExcludeLevel,
-	    startMatchingExcludeLevel, personalityNames);
-
-	if (result != kOSReturnSuccess) {
-		OSKextLog(theKext,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag,
-		    "Failed to load kext %s (error 0x%x).",
-		    theKext->getIdentifierCString(), (int)result);
-
-		OSKext::removeKext(theKext,
-		    /* terminateService/removePersonalities */ true);
-		goto finish;
-	} else {
-		OSKextLog(theKext,
-		    kOSKextLogProgressLevel |
-		    kOSKextLogLoadFlag,
-		    "Kext %s Loaded successfully from %s KC",
-		    theKext->getIdentifierCString(), theKext->getKCTypeString());
-	}
-
-	if (delayAutounload) {
-		OSKextLog(theKext,
-		    kOSKextLogProgressLevel |
-		    kOSKextLogLoadFlag | kOSKextLogKextBookkeepingFlag,
-		    "Setting delayed autounload for %s.",
-		    theKext->getIdentifierCString());
-		theKext->flags.delayAutounload = 1;
-	}
-
-finish:
-	IORecursiveLockUnlock(sKextLock);
-
-	return result;
-}
-
-/*********************************************************************
-*********************************************************************/
-/* static */
-OSReturn
-OSKext::loadCodelessKext(OSString *kextIdentifier, OSDictionary *requestDict)
-{
-	OSReturn  result = kOSReturnError;
-	OSDictionary *anInfoDict = NULL; // do not release
-
-	anInfoDict = OSDynamicCast(OSDictionary,
-	    _OSKextGetRequestArgument(requestDict,
-	    kKextRequestArgumentCodelessInfoKey));
-	if (anInfoDict == NULL) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogGeneralFlag | kOSKextLogLoadFlag,
-		    "Missing 'Codeless Kext Info' dictionary in codeless kext load request of %s.",
-		    kextIdentifier->getCStringNoCopy());
-		return kOSKextReturnInvalidArgument;
-	}
-
-	IORecursiveLockLock(sKextLock);
-
-	OSKextLog(/* kext */ NULL,
-	    kOSKextLogProgressLevel |
-	    kOSKextLogIPCFlag,
-	    "Received request from user space to load codeless kext %s.",
-	    kextIdentifier->getCStringNoCopy());
-
-	{
-		// instantiate a new kext, and don't hold a reference
-		// (the kext subsystem will hold one implicitly)
-		OSKextInitResult ret;
-		OSSharedPtr<OSKext> newKext = OSKext::withCodelessInfo(anInfoDict, &ret);
-		if (!newKext) {
-			/*
-			 * We might have failed to create a new OSKext
-			 * because the old one should still be used.
-			 * Check if that is the case.
-			 */
-			if (ret != kOSKextInitFailure) {
-				result = kOSReturnSuccess;
-				goto finish;
-			}
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogGeneralFlag | kOSKextLogLoadFlag,
-			    "Could not instantiate codeless kext.");
-			result = kOSKextReturnNotLoadable;
-			goto finish;
-		}
-		if (!kextIdentifier->isEqualTo(newKext->getIdentifierCString())) {
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogGeneralFlag | kOSKextLogLoadFlag,
-			    "Codeless kext identifiers don't match '%s' != '%s'",
-			    kextIdentifier->getCStringNoCopy(), newKext->getIdentifierCString());
-
-			OSKext::removeKext(newKext.get(), false);
-			result = kOSKextReturnInvalidArgument;
-			goto finish;
-		}
-
-		/* Record the request for the codeless kext */
-		OSKext::recordIdentifierRequest(OSDynamicCast(OSString, newKext->getIdentifier()));
-
-		result = kOSReturnSuccess;
-		/* Send the kext's personalities to the IOCatalog. This is an explicit load. */
-		result = newKext->sendPersonalitiesToCatalog(true, NULL);
-	}
-
-finish:
-	IORecursiveLockUnlock(sKextLock);
-
-	return result;
-}
-
-/*********************************************************************
-*********************************************************************/
-/* static */
-void
-OSKext::dropMatchingReferences(
-	OSSet * kexts)
-{
-	IORecursiveLockLock(sKextLock);
-	kexts->iterateObjects(^bool (OSObject * obj) {
-		OSKext * thisKext = OSDynamicCast(OSKext, obj);
-		if (!thisKext) {
-		        return false;
-		}
-		thisKext->matchingRefCount--;
-		return false;
-	});
-	IORecursiveLockUnlock(sKextLock);
+    OSSafeRelease(loadRequest);
+    OSSafeRelease(kextIdentifierSymbol);
+    
+    IORecursiveLockUnlock(sKextLock);
+
+    return result;
 }
 
 /*********************************************************************
@@ -6433,491 +4334,425 @@
 /* static */
 void
 OSKext::recordIdentifierRequest(
-	OSString * kextIdentifier)
-{
-	OSSharedPtr<const OSSymbol> kextIdentifierSymbol;
-	bool             fail                 = false;
-
-	if (!sAllKextLoadIdentifiers || !kextIdentifier) {
-		goto finish;
-	}
-
-	kextIdentifierSymbol = OSSymbol::withString(kextIdentifier);
-	if (!kextIdentifierSymbol) {
-		// xxx - this is really a basic alloc failure
-		fail = true;
-		goto finish;
-	}
-
-	IORecursiveLockLock(sKextLock);
-	if (!sAllKextLoadIdentifiers->containsObject(kextIdentifierSymbol.get())) {
-		if (!sAllKextLoadIdentifiers->setObject(kextIdentifierSymbol.get())) {
-			fail = true;
-		} else {
-			// xxx - need to find a way to associate this whole func w/the kext
-			OSKextLog(/* kext */ NULL,
-			    // xxx - check level
-			    kOSKextLogStepLevel |
-			    kOSKextLogArchiveFlag,
-			    "Recorded kext %s as a candidate for inclusion in prelinked kernel.",
-			    kextIdentifier->getCStringNoCopy());
-		}
-	}
-	IORecursiveLockUnlock(sKextLock);
-
+    OSString * kextIdentifier)
+{
+    const OSSymbol * kextIdentifierSymbol = NULL;  // must release
+    bool             fail                 = false;
+
+    if (!sAllKextLoadIdentifiers || !kextIdentifier) {
+        goto finish;
+    }
+
+    kextIdentifierSymbol = OSSymbol::withString(kextIdentifier);
+    if (!kextIdentifierSymbol) {
+        // xxx - this is really a basic alloc failure
+        fail = true;
+        goto finish;
+    }
+
+    if (!sAllKextLoadIdentifiers->containsObject(kextIdentifierSymbol)) {
+        if (!sAllKextLoadIdentifiers->setObject(kextIdentifierSymbol)) {
+            fail = true;
+        } else {
+            // xxx - need to find a way to associate this whole func w/the kext
+            OSKextLog(/* kext */ NULL,
+                // xxx - check level
+                kOSKextLogStepLevel |
+                kOSKextLogArchiveFlag,
+                "Recorded kext %s as a candidate for inclusion in prelinked kernel.",
+                kextIdentifier->getCStringNoCopy());
+        }
+    }
 finish:
 
-	if (fail) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogArchiveFlag,
-		    "Failed to record kext %s as a candidate for inclusion in prelinked kernel.",
-		    kextIdentifier->getCStringNoCopy());
-	}
-	return;
+    if (fail) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogErrorLevel |
+            kOSKextLogArchiveFlag,
+            "Failed to record kext %s as a candidate for inclusion in prelinked kernel.",
+            kextIdentifier->getCStringNoCopy());
+    }
+    OSSafeRelease(kextIdentifierSymbol);
+    return;
 }
 
 /*********************************************************************
 *********************************************************************/
 OSReturn
 OSKext::load(
-	OSKextExcludeLevel   startOpt,
-	OSKextExcludeLevel   startMatchingOpt,
-	OSArray            * personalityNames)
-{
-	OSReturn             result                       = kOSReturnError;
-	OSKextExcludeLevel   dependenciesStartOpt         = startOpt;
-	OSKextExcludeLevel   dependenciesStartMatchingOpt = startMatchingOpt;
-	unsigned int         i, count;
-	Boolean              alreadyLoaded                = false;
-	OSKext             * lastLoadedKext               = NULL;        // do not release
-
-	if (isInExcludeList()) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel | kOSKextLogGeneralFlag |
-		    kOSKextLogLoadFlag,
-		    "Kext %s is in exclude list, not loadable",
-		    getIdentifierCString());
-
-		result = kOSKextReturnNotLoadable;
-		goto finish;
-	}
-	if (!isLoadable()) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel | kOSKextLogGeneralFlag |
-		    kOSKextLogLoadFlag,
-		    "Kext %s is not loadable",
-		    getIdentifierCString());
-
-		result = kOSKextReturnNotLoadable;
-		goto finish;
-	}
-
-	if (isLoaded()) {
-		alreadyLoaded = true;
-		result = kOSReturnSuccess;
-
-		OSKextLog(this,
-		    kOSKextLogDebugLevel |
-		    kOSKextLogLoadFlag | kOSKextLogKextBookkeepingFlag,
-		    "Kext %s is already loaded.",
-		    getIdentifierCString());
-		goto loaded;
-	}
-
+    OSKextExcludeLevel   startOpt,
+    OSKextExcludeLevel   startMatchingOpt,
+    OSArray            * personalityNames)
+{
+    OSReturn             result                       = kOSReturnError;
+    kern_return_t        kxldResult;
+    OSKextExcludeLevel   dependenciesStartOpt         = startOpt;
+    OSKextExcludeLevel   dependenciesStartMatchingOpt = startMatchingOpt;
+    unsigned int         i, count;
+    Boolean              alreadyLoaded                = false;
+    OSKext             * lastLoadedKext               = NULL;
+
+    if (isInExcludeList()) {
+        OSKextLog(this,
+                  kOSKextLogErrorLevel | kOSKextLogGeneralFlag |
+                  kOSKextLogLoadFlag,
+                  "Kext %s is in exclude list, not loadable",
+                  getIdentifierCString());
+        
+        result = kOSKextReturnNotLoadable;
+        goto finish;
+    }
+
+    if (isLoaded()) {
+        alreadyLoaded = true;
+        result = kOSReturnSuccess;
+
+        OSKextLog(this,
+            kOSKextLogDebugLevel |
+            kOSKextLogLoadFlag | kOSKextLogKextBookkeepingFlag,
+            "Kext %s is already loaded.",
+            getIdentifierCString());
+        goto loaded;
+    }
+    
 #if CONFIG_MACF
-	/*
-	 * On kxld and on embedded, only call into the MAC hook when on a
-	 * user thread, for access control over userspace kextloads.
-	 *
-	 * On non-kxld systems, additionally check the MAC hook for kexts in
-	 * the Pageable and Aux KCs, regardless of whether we are on a user
-	 * thread or not. This means on Apple silicon devices that the MAC
-	 * hook will only be useful to block 3rd party kexts loaded via
-	 * matching, and any kexts loaded from userspace kextloads.
-	 *
-	 * Note that this should _not_ be called on kexts loaded from the
-	 * kernel bootstrap thread as the kernel proc's cred struct is not
-	 * yet initialized! This won't happen on macOS because all the kexts
-	 * in the BootKC are self-contained and their kc_type = KCKindPrimary.
-	 */
-	if (current_task() != kernel_task
-#if XNU_TARGET_OS_OSX && !CONFIG_KXLD
-	    || (kc_type != KCKindPrimary && kc_type != KCKindUnknown)
+    if (current_task() != kernel_task) {
+        int                 macCheckResult      = 0;
+        kauth_cred_t        cred                = NULL;
+
+        cred = kauth_cred_get_with_ref();
+        macCheckResult = mac_kext_check_load(cred, getIdentifierCString());
+        kauth_cred_unref(&cred);
+        
+        if (macCheckResult != 0) {
+            result = kOSReturnError;
+            OSKextLog(this,
+                      kOSKextLogErrorLevel | kOSKextLogLoadFlag,
+                      "Failed to load kext %s (MAC policy error 0x%x).",
+                      getIdentifierCString(), macCheckResult);
+            goto finish;
+        }
+   }
 #endif
-	    ) {
-		int                 macCheckResult      = 0;
-		kauth_cred_t        cred                = NULL;
-
-		cred = kauth_cred_get_with_ref();
-		macCheckResult = mac_kext_check_load(cred, getIdentifierCString());
-		kauth_cred_unref(&cred);
-
-		if (macCheckResult != 0) {
-			result = kOSReturnError;
-			OSKextLog(this,
-			    kOSKextLogErrorLevel | kOSKextLogLoadFlag,
-			    "Failed to load kext %s (MAC policy error 0x%x).",
-			    getIdentifierCString(), macCheckResult);
-			goto finish;
-		}
-	}
-#endif /* CONFIG_MACF */
-
-	if (!sLoadEnabled) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag,
-		    "Kext loading is disabled (attempt to load kext %s).",
-		    getIdentifierCString());
-		result = kOSKextReturnDisabled;
-		goto finish;
-	}
-
-	/* If we've pushed the next available load tag to the invalid value,
-	 * we can't load any more kexts.
-	 */
-	if (sNextLoadTag == kOSKextInvalidLoadTag) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag,
-		    "Can't load kext %s - no more load tags to assign.",
-		    getIdentifierCString());
-		result = kOSKextReturnNoResources;
-		goto finish;
-	}
-
-	/* This is a bit of a hack, because we shouldn't be handling
-	 * personalities within the load function.
-	 */
-	if (!declaresExecutable()) {
-		/* There is a special case where a non-executable kext can be loaded: the
-		 * AppleKextExcludeList.  Detect that special kext by bundle identifier and
-		 * load its metadata into the global data structures, if appropriate
-		 */
-		if (strcmp(getIdentifierCString(), kIOExcludeListBundleID) == 0) {
-			boolean_t updated = updateExcludeList(infoDict.get());
-			if (updated) {
-				OSKextLog(this,
-				    kOSKextLogDebugLevel | kOSKextLogLoadFlag,
-				    "KextExcludeList was updated to version: %lld", sExcludeListVersion);
-			}
-		}
-
-		if (isDriverKit()) {
-			if (loadTag == 0) {
-				sLoadedDriverKitKexts->setObject(this);
-				loadTag = sNextLoadTag++;
-			}
-		}
-		result = kOSReturnSuccess;
-		goto loaded;
-	}
-
-	/* Are we in safe boot?
-	 */
-	if (sSafeBoot && !isLoadableInSafeBoot()) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag,
-		    "Can't load kext %s - not loadable during safe boot.",
-		    getIdentifierCString());
-		result = kOSKextReturnBootLevel;
-		goto finish;
-	}
-
-	OSKextLog(this,
-	    kOSKextLogProgressLevel | kOSKextLogLoadFlag,
-	    "Loading kext %s.",
-	    getIdentifierCString());
+
+    if (!sLoadEnabled) {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogLoadFlag,
+            "Kext loading is disabled (attempt to load kext %s).",
+            getIdentifierCString());
+        result = kOSKextReturnDisabled;
+        goto finish;
+    }
+
+   /* If we've pushed the next available load tag to the invalid value,
+    * we can't load any more kexts.
+    */
+    if (sNextLoadTag == kOSKextInvalidLoadTag) {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogLoadFlag,
+            "Can't load kext %s - no more load tags to assign.",
+            getIdentifierCString());
+        result = kOSKextReturnNoResources;
+        goto finish;
+    }
+
+   /* This is a bit of a hack, because we shouldn't be handling 
+    * personalities within the load function.
+    */
+    if (!declaresExecutable()) {
+        result = kOSReturnSuccess;
+        goto loaded;
+    }
+
+   /* Are we in safe boot?
+    */
+    if (sSafeBoot && !isLoadableInSafeBoot()) {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogLoadFlag,
+            "Can't load kext %s - not loadable during safe boot.",
+            getIdentifierCString());
+        result = kOSKextReturnBootLevel;
+        goto finish;
+    }
+
+    OSKextLog(this,
+        kOSKextLogProgressLevel | kOSKextLogLoadFlag,
+        "Loading kext %s.",
+        getIdentifierCString());
+    
+    if (!sKxldContext) {
+        kxldResult = kxld_create_context(&sKxldContext, &kern_allocate, 
+            &kxld_log_callback, /* Flags */ (KXLDFlags) 0, 
+            /* cputype */ 0, /* cpusubtype */ 0, /* page size */ 0);
+        if (kxldResult) {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogLoadFlag | kOSKextLogLinkFlag,
+                "Can't load kext %s - failed to create link context.",
+                getIdentifierCString());
+            result = kOSKextReturnNoMemory;
+            goto finish;
+        }
+    }
+    
+    /* We only need to resolve dependencies once for the whole graph, but
+     * resolveDependencies will just return if there's no work to do, so it's
+     * safe to call it more than once.
+     */
+    if (!resolveDependencies()) {
+        // xxx - check resolveDependencies() for log msg
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogLoadFlag | kOSKextLogDependenciesFlag,
+            "Can't load kext %s - failed to resolve library dependencies.",
+            getIdentifierCString());
+        result = kOSKextReturnDependencies;
+        goto finish;
+    }
+
+   /* If we are excluding just the kext being loaded now (and not its
+    * dependencies), drop the exclusion level to none so dependencies
+    * start and/or add their personalities.
+    */
+    if (dependenciesStartOpt == kOSKextExcludeKext) {
+        dependenciesStartOpt = kOSKextExcludeNone;
+    }
+
+    if (dependenciesStartMatchingOpt == kOSKextExcludeKext) {
+        dependenciesStartMatchingOpt = kOSKextExcludeNone;
+    }
+
+   /* Load the dependencies, recursively.
+    */
+    count = getNumDependencies();
+    for (i = 0; i < count; i++) {
+        OSKext * dependency = OSDynamicCast(OSKext,
+            dependencies->getObject(i));
+        if (dependency == NULL) {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogLoadFlag | kOSKextLogDependenciesFlag,
+                "Internal error loading kext %s; dependency disappeared.",
+                getIdentifierCString());
+            result = kOSKextReturnInternalError;
+            goto finish;
+        }
+        
+       /* Dependencies must be started accorting to the opt,
+        * but not given the personality names of the main kext.
+        */
+        result = dependency->load(dependenciesStartOpt,
+            dependenciesStartMatchingOpt,
+            /* personalityNames */ NULL);
+        if (result != KERN_SUCCESS) {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogLoadFlag | kOSKextLogDependenciesFlag,
+                "Dependency %s of kext %s failed to load.",
+                dependency->getIdentifierCString(),
+                getIdentifierCString());
+
+            OSKext::removeKext(dependency,
+                /* terminateService/removePersonalities */ true);
+            result = kOSKextReturnDependencyLoadError;
+
+            goto finish;
+        }
+    }
+
+    result = loadExecutable();
+    if (result != KERN_SUCCESS) {
+        goto finish;
+    }
+
+    pendingPgoHead.next = &pendingPgoHead;
+    pendingPgoHead.prev = &pendingPgoHead;
+
+    uuid_generate(instance_uuid);
+    account = IONew(OSKextAccount, 1);
+    if (!account) {
+    	result = KERN_MEMORY_ERROR;
+	goto finish;
+    }
+    bzero(account, sizeof(*account));
+    account->loadTag = kmod_info->id;
+    account->site.flags = VM_TAG_KMOD;
+
+    flags.loaded = true;
+
+   /* Add the kext to the list of loaded kexts and update the kmod_info
+    * struct to point to that of the last loaded kext (which is the way
+    * it's always been done, though I'd rather do them in order now).
+    */
+    lastLoadedKext = OSDynamicCast(OSKext, sLoadedKexts->getLastObject());
+    sLoadedKexts->setObject(this);
+
+   /* Keep the kernel itself out of the kmod list.
+    */
+    if (lastLoadedKext->isKernel()) {
+        lastLoadedKext = NULL;
+    }
+
+    if (lastLoadedKext) {
+        kmod_info->next = lastLoadedKext->kmod_info;
+    }
+
+    notifyKextLoadObservers(this, kmod_info);
+
+   /* Make the global kmod list point at the just-loaded kext. Note that the
+    * __kernel__ kext isn't in this list, as it wasn't before SnowLeopard,
+    * although we do report it in kextstat these days by using the newer
+    * OSArray of loaded kexts, which does contain it.
+    *
+    * (The OSKext object representing the kernel doesn't even have a kmod_info
+    * struct, though I suppose we could stick a pointer to it from the
+    * static struct in OSRuntime.cpp.)
+    */
+    kmod = kmod_info;
+
+   /* Save the list of loaded kexts in case we panic.
+    */
+    OSKext::saveLoadedKextPanicList();
+
+    if (isExecutable()) {
+        OSKext::updateLoadedKextSummaries();
+        savePanicString(/* isLoading */ true);
+
+#if CONFIG_DTRACE
+        registerWithDTrace();
+#else
+        jettisonLinkeditSegment();
+#endif /* CONFIG_DTRACE */
 
 #if !VM_MAPPED_KEXTS
-	if (isPrelinked() == false) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag,
-		    "Can't load kext %s - not in a kext collection.",
-		    getIdentifierCString());
-		result = kOSKextReturnDisabled;
-		goto finish;
-	}
-#endif /* defined(__x86_64__) */
-
-#if CONFIG_KXLD
-	if (!sKxldContext) {
-		kern_return_t kxldResult;
-		kxldResult = kxld_create_context(&sKxldContext, &kern_allocate,
-		    &kxld_log_callback, /* Flags */ (KXLDFlags) 0,
-		    /* cputype */ 0, /* cpusubtype */ 0, /* page size */ 0);
-		if (kxldResult) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogLoadFlag | kOSKextLogLinkFlag,
-			    "Can't load kext %s - failed to create link context.",
-			    getIdentifierCString());
-			result = kOSKextReturnNoMemory;
-			goto finish;
-		}
-	}
-#endif // CONFIG_KXLD
-
-	/* We only need to resolve dependencies once for the whole graph, but
-	 * resolveDependencies will just return if there's no work to do, so it's
-	 * safe to call it more than once.
-	 */
-	if (!resolveDependencies()) {
-		// xxx - check resolveDependencies() for log msg
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag | kOSKextLogDependenciesFlag,
-		    "Can't load kext %s - failed to resolve library dependencies.",
-		    getIdentifierCString());
-		result = kOSKextReturnDependencies;
-		goto finish;
-	}
-
-	/* If we are excluding just the kext being loaded now (and not its
-	 * dependencies), drop the exclusion level to none so dependencies
-	 * start and/or add their personalities.
-	 */
-	if (dependenciesStartOpt == kOSKextExcludeKext) {
-		dependenciesStartOpt = kOSKextExcludeNone;
-	}
-
-	if (dependenciesStartMatchingOpt == kOSKextExcludeKext) {
-		dependenciesStartMatchingOpt = kOSKextExcludeNone;
-	}
-
-	/* Load the dependencies, recursively.
-	 */
-	count = getNumDependencies();
-	for (i = 0; i < count; i++) {
-		OSKext * dependency = OSDynamicCast(OSKext,
-		    dependencies->getObject(i));
-		if (dependency == NULL) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogLoadFlag | kOSKextLogDependenciesFlag,
-			    "Internal error loading kext %s; dependency disappeared.",
-			    getIdentifierCString());
-			result = kOSKextReturnInternalError;
-			goto finish;
-		}
-
-		/* Dependencies must be started accorting to the opt,
-		 * but not given the personality names of the main kext.
-		 */
-		result = dependency->load(dependenciesStartOpt,
-		    dependenciesStartMatchingOpt,
-		    /* personalityNames */ NULL);
-		if (result != KERN_SUCCESS) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogLoadFlag | kOSKextLogDependenciesFlag,
-			    "Dependency %s of kext %s failed to load.",
-			    dependency->getIdentifierCString(),
-			    getIdentifierCString());
-
-			OSKext::removeKext(dependency,
-			    /* terminateService/removePersonalities */ true);
-			result = kOSKextReturnDependencyLoadError;
-
-			goto finish;
-		}
-	}
-
-	result = loadExecutable();
-	if (result != KERN_SUCCESS) {
-		goto finish;
-	}
-
-	pendingPgoHead.next = &pendingPgoHead;
-	pendingPgoHead.prev = &pendingPgoHead;
-
-	// The kernel PRNG is not initialized when the first kext is
-	// loaded, so use early random
-	uuid_generate_early_random(instance_uuid);
-	account = IOMallocType(OSKextAccount);
-
-	account->loadTag = kmod_info->id;
-	account->site.refcount = 0;
-	account->site.flags = VM_TAG_KMOD;
-
-#if DEVELOPMENT || DEBUG
-	/* Setup the task reference group. */
-	(void)snprintf(account->task_refgrp_name, sizeof(account->task_refgrp_name),
-	    "task_%s", getIdentifierCString());
-	account->task_refgrp.grp_name = account->task_refgrp_name;
-	account->task_refgrp.grp_parent = &task_external_refgrp;
-	account->task_refgrp.grp_flags = OS_REFGRP_F_ALWAYS_ENABLED;
-	os_ref_log_init(&account->task_refgrp);
-#endif /* DEVELOPMENT || DEBUG */
-
-	account->kext = this;
-	if (gIOSurfaceIdentifier == bundleID) {
-		vm_tag_alloc(&account->site);
-		gIOSurfaceTag = account->site.tag;
-	}
-
-	flags.loaded = true;
-
-	/* Add the kext to the list of loaded kexts and update the kmod_info
-	 * struct to point to that of the last loaded kext (which is the way
-	 * it's always been done, though I'd rather do them in order now).
-	 */
-	lastLoadedKext = OSDynamicCast(OSKext, sLoadedKexts->getLastObject());
-	sLoadedKexts->setObject(this);
-
-	/* Keep the kernel itself out of the kmod list.
-	 */
-	if (lastLoadedKext->isKernel()) {
-		lastLoadedKext = NULL;
-	}
-
-	if (lastLoadedKext) {
-		kmod_info->next = lastLoadedKext->kmod_info;
-	}
-
-	notifyKextLoadObservers(this, kmod_info);
-
-	/* Make the global kmod list point at the just-loaded kext. Note that the
-	 * __kernel__ kext isn't in this list, as it wasn't before SnowLeopard,
-	 * although we do report it in kextstat these days by using the newer
-	 * OSArray of loaded kexts, which does contain it.
-	 *
-	 * (The OSKext object representing the kernel doesn't even have a kmod_info
-	 * struct, though I suppose we could stick a pointer to it from the
-	 * static struct in OSRuntime.cpp.)
-	 */
-	kmod = kmod_info;
-
-	/* Save the list of loaded kexts in case we panic.
-	 */
-	OSKext::saveLoadedKextPanicList();
-
-	if (isExecutable()) {
-		OSKext::updateLoadedKextSummaries();
-		savePanicString(/* isLoading */ true);
-
-#if CONFIG_DTRACE
-		registerWithDTrace();
-#else
-		jettisonLinkeditSegment();
-#endif /* CONFIG_DTRACE */
-
-#if !VM_MAPPED_KEXTS
-		/* If there is a page (or more) worth of padding after the end
-		 * of the last data section but before the end of the data segment
-		 * then free it in the same manner the LinkeditSegment is freed
-		 */
-		jettisonDATASegmentPadding();
+        /* If there is a page (or more) worth of padding after the end
+         * of the last data section but before the end of the data segment
+         * then free it in the same manner the LinkeditSegment is freed
+         */
+        jettisonDATASegmentPadding();
 #endif
-	}
+    }
 
 loaded:
-	if (isExecutable() && !flags.started) {
-		if (startOpt == kOSKextExcludeNone) {
-			result = start();
-			if (result != kOSReturnSuccess) {
-				OSKextLog(this,
-				    kOSKextLogErrorLevel | kOSKextLogLoadFlag,
-				    "Kext %s start failed (result 0x%x).",
-				    getIdentifierCString(), result);
-				result = kOSKextReturnStartStopError;
-			}
-		}
-	}
-
-	/* If not excluding matching, send the personalities to the kernel.
-	 * This never affects the result of the load operation.
-	 * This is a bit of a hack, because we shouldn't be handling
-	 * personalities within the load function.
-	 */
-	if (result == kOSReturnSuccess && startMatchingOpt == kOSKextExcludeNone) {
-		result = sendPersonalitiesToCatalog(true, personalityNames);
-	}
+    if (isExecutable() && !flags.started) {
+        if (startOpt == kOSKextExcludeNone) {
+            result = start();
+            if (result != kOSReturnSuccess) {
+                OSKextLog(this,
+                    kOSKextLogErrorLevel | kOSKextLogLoadFlag,
+                    "Kext %s start failed (result 0x%x).",
+                    getIdentifierCString(), result);
+                result = kOSKextReturnStartStopError;
+            }
+        }
+    }
+    
+   /* If not excluding matching, send the personalities to the kernel.
+    * This never affects the result of the load operation.
+    * This is a bit of a hack, because we shouldn't be handling 
+    * personalities within the load function.
+    */
+    if (result == kOSReturnSuccess && startMatchingOpt == kOSKextExcludeNone) {
+        result = sendPersonalitiesToCatalog(true, personalityNames);
+    }
 
 finish:
 
-	if (result != kOSReturnSuccess) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag,
-		    "Kext %s failed to load (0x%x).",
-		    getIdentifierCString(), (int)result);
-	} else if (!alreadyLoaded) {
-		OSKextLog(this,
-		    kOSKextLogProgressLevel |
-		    kOSKextLogLoadFlag,
-		    "Kext %s loaded.",
-		    getIdentifierCString());
-
-		queueKextNotification(kKextRequestPredicateLoadNotification,
-		    OSDynamicCast(OSString, bundleID.get()), getDextUniqueID());
-	}
-	return result;
-}
-
-#if CONFIG_KXLD
-/*********************************************************************
-*
-*********************************************************************/
-static char *
-strdup(const char * string)
-{
-	char * result = NULL;
-	size_t size;
-
-	if (!string) {
-		goto finish;
-	}
-
-	size = 1 + strlen(string);
-	result = (char *)kalloc_data_tag(size, Z_WAITOK, VM_KERN_MEMORY_OSKEXT);
-	if (!result) {
-		goto finish;
-	}
-
-	memcpy(result, string, size);
+   /* More hack! If the kext doesn't declare an executable, even if we
+    * "loaded" it, we have to remove any personalities naming it, or we'll
+    * never see the registry go quiet. Errors here do not count for the
+    * load operation itself.
+    *
+    * Note that in every other regard it's perfectly ok for a kext to
+    * not declare an executable and serve only as a package for personalities
+    * naming another kext, so we do have to allow such kexts to be "loaded"
+    * so that those other personalities get added & matched.
+    */
+    if (!declaresExecutable()) {
+        OSKextLog(this,
+            kOSKextLogStepLevel | kOSKextLogLoadFlag,
+            "Kext %s has no executable; removing any personalities naming it.",
+            getIdentifierCString());
+        removePersonalitiesFromCatalog();
+    }
+
+    if (result != kOSReturnSuccess) {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogLoadFlag,
+            "Kext %s failed to load (0x%x).",
+            getIdentifierCString(), (int)result);
+    } else if (!alreadyLoaded) {
+        OSKextLog(this,
+            kOSKextLogProgressLevel |
+            kOSKextLogLoadFlag,
+            "Kext %s loaded.",
+            getIdentifierCString());
+
+        queueKextNotification(kKextRequestPredicateLoadNotification,
+            OSDynamicCast(OSString, bundleID));
+    }
+    return result;
+}
+
+/*********************************************************************
+* 
+*********************************************************************/
+static char * strdup(const char * string)
+{
+    char * result = NULL;
+    size_t size;
+    
+    if (!string) {
+        goto finish;
+    }
+    
+    size = 1 + strlen(string);
+    result = (char *)kalloc_tag(size, VM_KERN_MEMORY_OSKEXT);
+    if (!result) {
+        goto finish;
+    }
+    
+    memcpy(result, string, size);
 
 finish:
-	return result;
-}
-#endif // CONFIG_KXLD
-
-/*********************************************************************
-*
+    return result;
+}
+
+/*********************************************************************
+* 
 *********************************************************************/
 
 kernel_section_t *
 OSKext::lookupSection(const char *segname, const char *secname)
 {
-	kernel_section_t         * found_section = NULL;
-	kernel_mach_header_t     * mh            = NULL;
-	kernel_segment_command_t * seg           = NULL;
-	kernel_section_t         * sec           = NULL;
-
-	if (!linkedExecutable) {
-		return NULL;
-	}
-
-	mh = (kernel_mach_header_t *)linkedExecutable->getBytesNoCopy();
-
-	for (seg = firstsegfromheader(mh); seg != NULL; seg = nextsegfromheader(mh, seg)) {
-		if (0 != strncmp(seg->segname, segname, sizeof(seg->segname))) {
-			continue;
-		}
-
-		for (sec = firstsect(seg); sec != NULL; sec = nextsect(seg, sec)) {
-			if (0 == strncmp(sec->sectname, secname, sizeof(sec->sectname))) {
-				found_section = sec;
-				goto out;
-			}
-		}
-	}
-
-out:
-	return found_section;
+    kernel_section_t         * found_section = NULL;
+    kernel_mach_header_t     * mh            = NULL;
+    kernel_segment_command_t * seg           = NULL;
+    kernel_section_t         * sec           = NULL;
+
+    mh = (kernel_mach_header_t *)linkedExecutable->getBytesNoCopy();
+
+    for (seg = firstsegfromheader(mh); seg != NULL; seg = nextsegfromheader(mh, seg)) {
+
+        if (0 != strcmp(seg->segname, segname)) {
+            continue;
+        }
+
+        for (sec = firstsect(seg); sec != NULL; sec = nextsect(seg, sec)) {
+
+            if (0 == strcmp(sec->sectname, secname)) {
+                found_section = sec;
+                goto out;
+            }
+        }
+    }
+
+ out:
+    return found_section;
 }
 
 /*********************************************************************
@@ -6925,250 +4760,221 @@
 *********************************************************************/
 
 OSReturn
-OSKext::slidePrelinkedExecutable(bool doCoalescedSlides)
-{
-	OSReturn                       result           = kOSKextReturnBadData;
-	kernel_mach_header_t         * mh               = NULL;
-	kernel_segment_command_t     * seg              = NULL;
-	kernel_segment_command_t     * linkeditSeg      = NULL;
-	kernel_section_t             * sec              = NULL;
-	char                         * linkeditBase     = NULL;
-	bool                           haveLinkeditBase = false;
-	char                         * relocBase        = NULL;
-	bool                           haveRelocBase    = false;
-	struct dysymtab_command      * dysymtab         = NULL;
-	struct linkedit_data_command * segmentSplitInfo = NULL;
-	struct symtab_command        * symtab           = NULL;
-	kernel_nlist_t               * sym              = NULL;
-	struct relocation_info       * reloc            = NULL;
-	uint32_t                       i                = 0;
-	int                            reloc_size;
-	vm_offset_t                    new_kextsize;
-	kc_format                    format             = KCFormatUnknown;
-
-	if (linkedExecutable == NULL || flags.builtin) {
-		result = kOSReturnSuccess;
-		goto finish;
-	}
-
-	mh = (kernel_mach_header_t *)linkedExecutable->getBytesNoCopy();
-	if (kernel_mach_header_is_in_fileset(mh)) {
-		// kexts in filesets are slid as part of collection sliding
-		result = kOSReturnSuccess;
-		goto finish;
-	}
-
-	segmentSplitInfo = (struct linkedit_data_command *) getcommandfromheader(mh, LC_SEGMENT_SPLIT_INFO);
-
-	for (seg = firstsegfromheader(mh); seg != NULL; seg = nextsegfromheader(mh, seg)) {
-		if (!seg->vmaddr) {
-			continue;
-		}
-
-		seg->vmaddr = ml_static_slide(seg->vmaddr);
-
+OSKext::slidePrelinkedExecutable()
+{
+    OSReturn                   result           = kOSKextReturnBadData;
+    kernel_mach_header_t     * mh               = NULL;
+    kernel_segment_command_t * seg              = NULL;
+    kernel_segment_command_t * linkeditSeg      = NULL;
+    kernel_section_t         * sec              = NULL;
+    char                     * linkeditBase     = NULL;
+    bool                       haveLinkeditBase = false;
+    char                     * relocBase        = NULL;
+    bool                       haveRelocBase    = false;
+    struct dysymtab_command  * dysymtab         = NULL;
+    struct symtab_command    * symtab           = NULL;
+    kernel_nlist_t           * sym              = NULL;
+    struct relocation_info   * reloc            = NULL;
+    uint32_t                   i                = 0; 
+    int                        reloc_size;
+    vm_offset_t                new_kextsize;
+
+    if (linkedExecutable == NULL || vm_kernel_slide == 0) {
+        result = kOSReturnSuccess;
+        goto finish;
+    }
+
+    mh = (kernel_mach_header_t *)linkedExecutable->getBytesNoCopy();
+
+    for (seg = firstsegfromheader(mh); seg != NULL; seg = nextsegfromheader(mh, seg)) {
+        if (!seg->vmaddr) {
+            continue;
+        }
+        seg->vmaddr += vm_kernel_slide;
+                
 #if KASLR_KEXT_DEBUG
-		IOLog("kaslr: segname %s unslid 0x%lx slid 0x%lx \n",
-		    seg->segname,
-		    (unsigned long)ml_static_unslide(seg->vmaddr),
-		    (unsigned long)seg->vmaddr);
+        IOLog("kaslr: segname %s unslid 0x%lx slid 0x%lx \n", 
+              seg->segname,
+              (unsigned long)VM_KERNEL_UNSLIDE(seg->vmaddr), 
+              (unsigned long)seg->vmaddr);
 #endif
-
-		if (!haveRelocBase) {
-			relocBase = (char *) seg->vmaddr;
-			haveRelocBase = true;
-		}
-		if (!strcmp(seg->segname, "__LINKEDIT")) {
-			linkeditBase = (char *) seg->vmaddr - seg->fileoff;
-			haveLinkeditBase = true;
-			linkeditSeg = seg;
-		}
-		for (sec = firstsect(seg); sec != NULL; sec = nextsect(seg, sec)) {
-			sec->addr = ml_static_slide(sec->addr);
+       
+        if (!haveRelocBase) {
+            relocBase = (char *) seg->vmaddr;
+            haveRelocBase = true;
+        }
+        if (!strcmp(seg->segname, "__LINKEDIT")) {
+            linkeditBase = (char *) seg->vmaddr - seg->fileoff;
+            haveLinkeditBase = true;
+            linkeditSeg = seg;
+        }
+        for (sec = firstsect(seg); sec != NULL; sec = nextsect(seg, sec)) {
+            sec->addr += vm_kernel_slide;
 
 #if KASLR_KEXT_DEBUG
-			IOLog("kaslr: sectname %s unslid 0x%lx slid 0x%lx \n",
-			    sec->sectname,
-			    (unsigned long)ml_static_unslide(sec->addr),
-			    (unsigned long)sec->addr);
+            IOLog("kaslr: sectname %s unslid 0x%lx slid 0x%lx \n", 
+                  sec->sectname,
+                  (unsigned long)VM_KERNEL_UNSLIDE(sec->addr), 
+                  (unsigned long)sec->addr);
 #endif
-		}
-	}
-
-	dysymtab = (struct dysymtab_command *) getcommandfromheader(mh, LC_DYSYMTAB);
-
-	symtab = (struct symtab_command *) getcommandfromheader(mh, LC_SYMTAB);
-
-	if (symtab != NULL && doCoalescedSlides == false) {
-		/* Some pseudo-kexts have symbol tables without segments.
-		 * Ignore them. */
-		if (symtab->nsyms > 0 && haveLinkeditBase) {
-			sym = (kernel_nlist_t *) (linkeditBase + symtab->symoff);
-			for (i = 0; i < symtab->nsyms; i++) {
-				if (sym[i].n_type & N_STAB) {
-					continue;
-				}
-				sym[i].n_value = ml_static_slide(sym[i].n_value);
-
+        }
+    }
+
+    dysymtab = (struct dysymtab_command *) getcommandfromheader(mh, LC_DYSYMTAB);
+
+    symtab = (struct symtab_command *) getcommandfromheader(mh, LC_SYMTAB);
+
+    if (symtab != NULL) {
+      /* Some pseudo-kexts have symbol tables without segments.
+       * Ignore them. */
+        if (symtab->nsyms > 0 && haveLinkeditBase) {
+            sym = (kernel_nlist_t *) (linkeditBase + symtab->symoff);
+            for (i = 0; i < symtab->nsyms; i++) {
+                if (sym[i].n_type & N_STAB) {
+                    continue;
+                }
+                sym[i].n_value += vm_kernel_slide;
+                
 #if KASLR_KEXT_DEBUG
 #define MAX_SYMS_TO_LOG 5
-				if (i < MAX_SYMS_TO_LOG) {
-					IOLog("kaslr: LC_SYMTAB unslid 0x%lx slid 0x%lx \n",
-					    (unsigned long)ml_static_unslide(sym[i].n_value),
-					    (unsigned long)sym[i].n_value);
-				}
+                if ( i < MAX_SYMS_TO_LOG ) {
+                    IOLog("kaslr: LC_SYMTAB unslid 0x%lx slid 0x%lx \n", 
+                          (unsigned long)VM_KERNEL_UNSLIDE(sym[i].n_value), 
+                          (unsigned long)sym[i].n_value);
+                }
 #endif
-			}
-		}
-	}
-
-	if (dysymtab != NULL && doCoalescedSlides == false) {
-		if (dysymtab->nextrel > 0) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel | kOSKextLogLoadFlag |
-			    kOSKextLogLinkFlag,
-			    "Sliding kext %s: External relocations found.",
-			    getIdentifierCString());
-			goto finish;
-		}
-
-		if (dysymtab->nlocrel > 0) {
-			if (!haveLinkeditBase) {
-				OSKextLog(this,
-				    kOSKextLogErrorLevel | kOSKextLogLoadFlag |
-				    kOSKextLogLinkFlag,
-				    "Sliding kext %s: No linkedit segment.",
-				    getIdentifierCString());
-				goto finish;
-			}
-
-			if (!haveRelocBase) {
-				OSKextLog(this,
-				    kOSKextLogErrorLevel | kOSKextLogLoadFlag |
-				    kOSKextLogLinkFlag,
+            }
+        }
+    }
+
+    if (dysymtab != NULL) {
+        if (dysymtab->nextrel > 0) {
+            OSKextLog(this,
+                kOSKextLogErrorLevel | kOSKextLogLoadFlag |
+                kOSKextLogLinkFlag,
+                "Sliding kext %s: External relocations found.",
+                getIdentifierCString());
+            goto finish;
+        }
+
+        if (dysymtab->nlocrel > 0) {
+            if (!haveLinkeditBase) {
+                OSKextLog(this,
+                    kOSKextLogErrorLevel | kOSKextLogLoadFlag |
+                    kOSKextLogLinkFlag,
+                    "Sliding kext %s: No linkedit segment.",
+                    getIdentifierCString());
+                goto finish;
+            }
+
+            if (!haveRelocBase) {
+                OSKextLog(this,
+                    kOSKextLogErrorLevel | kOSKextLogLoadFlag |
+                    kOSKextLogLinkFlag,
 #if __x86_64__
-				    "Sliding kext %s: No writable segments.",
+                    "Sliding kext %s: No writable segments.",
 #else
-				    "Sliding kext %s: No segments.",
+                    "Sliding kext %s: No segments.",
 #endif
-				    getIdentifierCString());
-				goto finish;
-			}
-
-			reloc = (struct relocation_info *) (linkeditBase + dysymtab->locreloff);
-			reloc_size = dysymtab->nlocrel * sizeof(struct relocation_info);
-
-			for (i = 0; i < dysymtab->nlocrel; i++) {
-				if (reloc[i].r_extern != 0
-				    || reloc[i].r_type != 0
-				    || reloc[i].r_length != (sizeof(void *) == 8 ? 3 : 2)
-				    ) {
-					OSKextLog(this,
-					    kOSKextLogErrorLevel | kOSKextLogLoadFlag |
-					    kOSKextLogLinkFlag,
-					    "Sliding kext %s: Unexpected relocation found.",
-					    getIdentifierCString());
-					goto finish;
-				}
-				if (reloc[i].r_pcrel != 0) {
-					continue;
-				}
-				uintptr_t *relocAddr = (uintptr_t*)(relocBase + reloc[i].r_address);
-				*relocAddr = ml_static_slide(*relocAddr);
+                    getIdentifierCString());
+                goto finish;
+            }
+
+            reloc = (struct relocation_info *) (linkeditBase + dysymtab->locreloff);
+            reloc_size = dysymtab->nlocrel * sizeof(struct relocation_info);
+            
+            for (i = 0; i < dysymtab->nlocrel; i++) {
+                if (   reloc[i].r_extern != 0
+                    || reloc[i].r_type != 0
+                    || reloc[i].r_length != (sizeof(void *) == 8 ? 3 : 2)
+                    ) {
+                    OSKextLog(this,
+                        kOSKextLogErrorLevel | kOSKextLogLoadFlag |
+                        kOSKextLogLinkFlag,
+                        "Sliding kext %s: Unexpected relocation found.",
+                        getIdentifierCString());
+                    goto finish;
+                }
+                if (reloc[i].r_pcrel != 0) {
+                    continue;
+                }
+                *((uintptr_t *)(relocBase + reloc[i].r_address)) += vm_kernel_slide;
 
 #if KASLR_KEXT_DEBUG
 #define MAX_DYSYMS_TO_LOG 5
-				if (i < MAX_DYSYMS_TO_LOG) {
-					IOLog("kaslr: LC_DYSYMTAB unslid 0x%lx slid 0x%lx \n",
-					    (unsigned long)ml_static_unslide(*((uintptr_t *)(relocAddr))),
-					    (unsigned long)*((uintptr_t *)(relocBase + reloc[i].r_address)));
-				}
+                if ( i < MAX_DYSYMS_TO_LOG ) {
+                    IOLog("kaslr: LC_DYSYMTAB unslid 0x%lx slid 0x%lx \n", 
+                          (unsigned long)VM_KERNEL_UNSLIDE(*((uintptr_t *)(relocBase + reloc[i].r_address))), 
+                          (unsigned long)*((uintptr_t *)(relocBase + reloc[i].r_address)));
+                }
 #endif
-			}
-
-			/* We should free these relocations, not just delete the reference to them.
-			 * <rdar://problem/10535549> Free relocations from PIE kexts.
-			 *
-			 * For now, we do not free LINKEDIT for kexts with split segments.
-			 */
-			new_kextsize = round_page(kmod_info->size - reloc_size);
-			if (new_kextsize > UINT_MAX) {
-				OSKextLog(this,
-				    kOSKextLogErrorLevel | kOSKextLogLoadFlag |
-				    kOSKextLogLinkFlag,
-				    "Kext %s: new kext size is too large.",
-				    getIdentifierCString());
-				goto finish;
-			}
-			if (((kmod_info->size - new_kextsize) > PAGE_SIZE) && (!segmentSplitInfo)) {
-				vm_offset_t     endofkext = kmod_info->address + kmod_info->size;
-				vm_offset_t     new_endofkext = kmod_info->address + new_kextsize;
-				vm_offset_t     endofrelocInfo = (vm_offset_t) (((uint8_t *)reloc) + reloc_size);
-				size_t          bytes_remaining = endofkext - endofrelocInfo;
-				OSSharedPtr<OSData>        new_osdata;
-
-				/* fix up symbol offsets if they are after the dsymtab local relocs */
-				if (symtab) {
-					if (dysymtab->locreloff < symtab->symoff) {
-						symtab->symoff -= reloc_size;
-					}
-					if (dysymtab->locreloff < symtab->stroff) {
-						symtab->stroff -= reloc_size;
-					}
-				}
-				if (dysymtab->locreloff < dysymtab->extreloff) {
-					dysymtab->extreloff -= reloc_size;
-				}
-
-				/* move data behind reloc info down to new offset */
-				if (endofrelocInfo < endofkext) {
-					memcpy(reloc, (void *)endofrelocInfo, bytes_remaining);
-				}
-
-				/* Create a new OSData for the smaller kext object and reflect
-				 * new linkedit segment size.
-				 */
-				linkeditSeg->vmsize = round_page(linkeditSeg->vmsize - reloc_size);
-				linkeditSeg->filesize = linkeditSeg->vmsize;
-
-				new_osdata = OSData::withBytesNoCopy((void *)kmod_info->address, (unsigned int)new_kextsize);
-				if (new_osdata) {
-					/* Fix up kmod info and linkedExecutable.
-					 */
-					kmod_info->size = new_kextsize;
-					/*
-					 * Fileset KCs are mapped as a whole by iBoot.
-					 * Individual kext executables should not be unmapped
-					 * by xnu.
-					 * Doing so may result in panics like rdar://85419651
-					 */
-					if (PE_get_kc_format(kc_type, &format) && (format == KCFormatFileset)) {
-						new_osdata->setDeallocFunction(NULL);
-					} else { // Not from a Fileset KC
+            }
+
+            /* We should free these relocations, not just delete the reference to them.
+             * <rdar://problem/10535549> Free relocations from PIE kexts.
+             */
+            new_kextsize = round_page(kmod_info->size - reloc_size);
+            
+            if ((kmod_info->size - new_kextsize) > PAGE_SIZE) {
+                vm_offset_t     endofkext = kmod_info->address + kmod_info->size;
+                vm_offset_t     new_endofkext = kmod_info->address + new_kextsize;
+                vm_offset_t     endofrelocInfo = (vm_offset_t) (((uint8_t *)reloc) + reloc_size);
+                int             bytes_remaining = endofkext - endofrelocInfo;
+                OSData *        new_osdata = NULL;
+
+                /* fix up symbol offsets if they are after the dsymtab local relocs */
+                if (symtab) {
+                    if (dysymtab->locreloff < symtab->symoff){
+                        symtab->symoff -= reloc_size;
+                    }
+                    if (dysymtab->locreloff < symtab->stroff) {
+                        symtab->stroff -= reloc_size;
+                    }
+                }
+                if (dysymtab->locreloff < dysymtab->extreloff) {
+                    dysymtab->extreloff -= reloc_size;
+                }
+                
+                /* move data behind reloc info down to new offset */
+                if (endofrelocInfo < endofkext) {
+                   memcpy(reloc, (void *)endofrelocInfo, bytes_remaining);
+                }
+                               
+                /* Create a new OSData for the smaller kext object and reflect 
+                 * new linkedit segment size.
+                 */
+                linkeditSeg->vmsize = round_page(linkeditSeg->vmsize - reloc_size);
+                linkeditSeg->filesize = linkeditSeg->vmsize;
+                
+                new_osdata = OSData::withBytesNoCopy((void *)kmod_info->address, new_kextsize);
+                if (new_osdata) {
+                    /* Fix up kmod info and linkedExecutable.
+                     */
+                    kmod_info->size = new_kextsize;
 #if VM_MAPPED_KEXTS
-						new_osdata->setDeallocFunction(osdata_kext_free);
+                    new_osdata->setDeallocFunction(osdata_kext_free);
 #else
-						new_osdata->setDeallocFunction(osdata_phys_free);
+                    new_osdata->setDeallocFunction(osdata_phys_free);
 #endif
-					}
-					linkedExecutable->setDeallocFunction(NULL);
-					linkedExecutable = os::move(new_osdata);
-
+                    linkedExecutable->setDeallocFunction(NULL);
+                    linkedExecutable->release();
+                    linkedExecutable = new_osdata;
+                    
 #if VM_MAPPED_KEXTS
-					kext_free(new_endofkext, (endofkext - new_endofkext));
+                    kext_free(new_endofkext, (endofkext - new_endofkext));
 #else
-					ml_static_mfree(new_endofkext, (endofkext - new_endofkext));
+                    ml_static_mfree(new_endofkext, (endofkext - new_endofkext));
 #endif
-				}
-			}
-			dysymtab->nlocrel = 0;
-			dysymtab->locreloff = 0;
-		}
-	}
-
-	result = kOSReturnSuccess;
+                }
+            }
+            dysymtab->nlocrel = 0;
+            dysymtab->locreloff = 0;
+        }
+    }
+                
+    result = kOSReturnSuccess;
 finish:
-	return result;
+    return result;
 }
 
 /*********************************************************************
@@ -7177,466 +4983,350 @@
 OSReturn
 OSKext::loadExecutable()
 {
-	OSReturn              result             = kOSReturnError;
-	OSSharedPtr<OSArray>  linkDependencies;
-	uint32_t              num_kmod_refs      = 0;
-	OSData              * theExecutable      = NULL;        // do not release
-	OSString            * versString         = NULL;        // do not release
-	const char          * versCString        = NULL;        // do not free
-	const char          * string             = NULL;        // do not free
-
-#if CONFIG_KXLD
-	unsigned int          i;
-	uint32_t              numDirectDependencies   = 0;
-	kern_return_t         kxldResult;
-	KXLDDependency     *  kxlddeps           = NULL;        // must kfree
-	uint32_t              num_kxlddeps       = 0;
-	struct mach_header ** kxldHeaderPtr      = NULL;        // do not free
-	struct mach_header  * kxld_header        = NULL;        // xxx - need to free here?
-#endif // CONFIG_KXLD
-
-	/* We need the version string for a variety of bits below.
-	 */
-	versString = OSDynamicCast(OSString,
-	    getPropertyForHostArch(kCFBundleVersionKey));
-	if (!versString) {
-		goto finish;
-	}
-	versCString = versString->getCStringNoCopy();
-
-	if (isKernelComponent()) {
-		if (STRING_HAS_PREFIX(versCString, KERNEL_LIB_PREFIX)) {
-			if (strncmp(versCString, KERNEL6_VERSION, strlen(KERNEL6_VERSION))) {
-				OSKextLog(this,
-				    kOSKextLogErrorLevel |
-				    kOSKextLogLoadFlag,
-				    "Kernel component %s has incorrect version %s; "
-				    "expected %s.",
-				    getIdentifierCString(),
-				    versCString, KERNEL6_VERSION);
-				result = kOSKextReturnInternalError;
-				goto finish;
-			} else if (strcmp(versCString, osrelease)) {
-				OSKextLog(this,
-				    kOSKextLogErrorLevel |
-				    kOSKextLogLoadFlag,
-				    "Kernel component %s has incorrect version %s; "
-				    "expected %s.",
-				    getIdentifierCString(),
-				    versCString, osrelease);
-				result = kOSKextReturnInternalError;
-				goto finish;
-			}
-		}
-	}
-
-#if defined(__x86_64__) || defined(__i386__)
-	if (flags.resetSegmentsFromVnode) {
-		/* Fixup the chains and slide the mach headers */
-		kernel_mach_header_t *mh = (kernel_mach_header_t *)kmod_info->address;
-
-		if (i386_slide_individual_kext(mh, PE_get_kc_slide(kc_type)) != KERN_SUCCESS) {
-			result = kOSKextReturnValidation;
-			goto finish;
-		}
-	}
-#endif //(__x86_64__) || defined(__i386__)
-
-	if (isPrelinked()) {
-		goto register_kmod;
-	}
-
-	/* <rdar://problem/21444003> all callers must be entitled */
-	if (FALSE == IOCurrentTaskHasEntitlement(kOSKextCollectionManagementEntitlement)) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel | kOSKextLogLoadFlag,
-		    "Not entitled to link kext '%s'",
-		    getIdentifierCString());
-		result = kOSKextReturnNotPrivileged;
-		goto finish;
-	}
-
-	theExecutable = getExecutable();
-	if (!theExecutable) {
-		if (declaresExecutable()) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogLoadFlag,
-			    "Can't load kext %s - executable is missing.",
-			    getIdentifierCString());
-			result = kOSKextReturnValidation;
-			goto finish;
-		}
-		goto register_kmod;
-	}
-
-	if (isInterface()) {
-		OSSharedPtr<OSData> executableCopy = OSData::withData(theExecutable);
-		if (executableCopy) {
-			setLinkedExecutable(executableCopy.get());
-		}
-		goto register_kmod;
-	}
-
-#if CONFIG_KXLD
-	numDirectDependencies = getNumDependencies();
-
-	if (flags.hasBleedthrough) {
-		linkDependencies = dependencies;
-	} else {
-		linkDependencies = OSArray::withArray(dependencies.get());
-		if (!linkDependencies) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogLoadFlag | kOSKextLogLinkFlag,
-			    "Can't allocate link dependencies to load kext %s.",
-			    getIdentifierCString());
-			goto finish;
-		}
-
-		for (i = 0; i < numDirectDependencies; ++i) {
-			OSKext * dependencyKext = OSDynamicCast(OSKext,
-			    dependencies->getObject(i));
-			dependencyKext->addBleedthroughDependencies(linkDependencies.get());
-		}
-	}
-
-	num_kxlddeps = linkDependencies->getCount();
-	if (!num_kxlddeps) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag | kOSKextLogDependenciesFlag,
-		    "Can't load kext %s - it has no library dependencies.",
-		    getIdentifierCString());
-		goto finish;
-	}
-
-	kxlddeps = kalloc_type_tag(KXLDDependency, num_kxlddeps, Z_WAITOK, VM_KERN_MEMORY_OSKEXT);
-	if (!kxlddeps) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag | kOSKextLogLinkFlag,
-		    "Can't allocate link context to load kext %s.",
-		    getIdentifierCString());
-		goto finish;
-	}
-	bzero(kxlddeps, num_kxlddeps * sizeof(*kxlddeps));
-
-	for (i = 0; i < num_kxlddeps; ++i) {
-		OSKext * dependency = OSDynamicCast(OSKext, linkDependencies->getObject(i));
-
-		if (dependency->isInterface()) {
-			OSKext *interfaceTargetKext = NULL;        //do not release
-			OSData * interfaceTarget = NULL;        //do not release
-
-			if (dependency->isKernelComponent()) {
-				interfaceTargetKext = sKernelKext;
-				interfaceTarget = sKernelKext->linkedExecutable.get();
-			} else {
-				interfaceTargetKext = OSDynamicCast(OSKext,
-				    dependency->dependencies->getObject(0));
-
-				interfaceTarget = interfaceTargetKext->linkedExecutable.get();
-			}
-
-			if (!interfaceTarget) {
-				// panic?
-				goto finish;
-			}
-
-			/* The names set here aren't actually logged yet <rdar://problem/7941514>,
-			 * it will be useful to have them in the debugger.
-			 * strdup() failing isn't critical right here so we don't check that.
-			 */
-			kxlddeps[i].kext = (u_char *) interfaceTarget->getBytesNoCopy();
-			kxlddeps[i].kext_size = interfaceTarget->getLength();
-			kxlddeps[i].kext_name = strdup(interfaceTargetKext->getIdentifierCString());
-
-			if (dependency->linkedExecutable != NULL) {
-				kxlddeps[i].interface = (u_char *) dependency->linkedExecutable->getBytesNoCopy();
-				kxlddeps[i].interface_size = dependency->linkedExecutable->getLength();
-			} else {
-				kxlddeps[i].interface = (u_char *) NULL;
-				kxlddeps[i].interface_size = 0;
-			}
-			kxlddeps[i].interface_name = strdup(dependency->getIdentifierCString());
-		} else {
-			kxlddeps[i].kext = (u_char *) dependency->linkedExecutable->getBytesNoCopy();
-			kxlddeps[i].kext_size = dependency->linkedExecutable->getLength();
-			kxlddeps[i].kext_name = strdup(dependency->getIdentifierCString());
-		}
-
-		kxlddeps[i].is_direct_dependency = (i < numDirectDependencies);
-	}
-
-	kxldHeaderPtr = &kxld_header;
+    OSReturn              result             = kOSReturnError;
+    kern_return_t         kxldResult;
+    KXLDDependency     *  kxlddeps           = NULL;  // must kfree
+    uint32_t              num_kxlddeps       = 0;
+    OSArray            *  linkDependencies   = NULL;  // must release
+    uint32_t              numDirectDependencies   = 0;
+    uint32_t              num_kmod_refs      = 0;
+    struct mach_header ** kxldHeaderPtr      = NULL;  // do not free
+    struct mach_header  * kxld_header        = NULL;  // xxx - need to free here?
+    OSData              * theExecutable      = NULL;  // do not release
+    OSString            * versString         = NULL;  // do not release
+    const char          * versCString        = NULL;  // do not free
+    const char          * string             = NULL;  // do not free
+    unsigned int          i;
+
+   /* We need the version string for a variety of bits below.
+    */
+    versString = OSDynamicCast(OSString,
+        getPropertyForHostArch(kCFBundleVersionKey));
+    if (!versString) {
+        goto finish;
+    }
+    versCString = versString->getCStringNoCopy();
+
+    if (isKernelComponent()) {
+       if (STRING_HAS_PREFIX(versCString, KERNEL_LIB_PREFIX)) {
+
+           if (strncmp(versCString, KERNEL6_VERSION, strlen(KERNEL6_VERSION))) {
+                OSKextLog(this,
+                    kOSKextLogErrorLevel |
+                    kOSKextLogLoadFlag,
+                    "Kernel component %s has incorrect version %s; "
+                    "expected %s.",
+                    getIdentifierCString(),
+                    versCString, KERNEL6_VERSION);
+               result = kOSKextReturnInternalError;
+               goto finish;
+           } else if (strcmp(versCString, osrelease)) {
+                OSKextLog(this,
+                    kOSKextLogErrorLevel |
+                    kOSKextLogLoadFlag,
+                    "Kernel component %s has incorrect version %s; "
+                    "expected %s.",
+                    getIdentifierCString(),
+                    versCString, osrelease);
+               result = kOSKextReturnInternalError;
+               goto finish;
+           }
+       }
+    }
+
+    if (isPrelinked()) {
+        goto register_kmod;
+    }
+
+    /* <rdar://problem/21444003> all callers must be entitled */
+    if (FALSE == IOTaskHasEntitlement(current_task(), "com.apple.rootless.kext-management")) {
+        OSKextLog(this,
+                  kOSKextLogErrorLevel | kOSKextLogLoadFlag,
+                  "Not entitled to link kext '%s'",
+                  getIdentifierCString());
+        result = kOSKextReturnNotPrivileged;
+        goto finish;
+    }
+    
+    theExecutable = getExecutable();
+    if (!theExecutable) {
+        if (declaresExecutable()) {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogLoadFlag,
+                "Can't load kext %s - executable is missing.",
+                getIdentifierCString());
+            result = kOSKextReturnValidation;
+            goto finish;
+        }
+        goto register_kmod;
+    }
+
+    if (isInterface()) {
+        OSData *executableCopy = OSData::withData(theExecutable);
+        setLinkedExecutable(executableCopy);
+        executableCopy->release();
+        goto register_kmod;
+    }
+
+    numDirectDependencies = getNumDependencies();
+
+    if (flags.hasBleedthrough) {
+        linkDependencies = dependencies;
+        linkDependencies->retain();
+    } else {
+        linkDependencies = OSArray::withArray(dependencies);
+        if (!linkDependencies) {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogLoadFlag | kOSKextLogLinkFlag,
+                "Can't allocate link dependencies to load kext %s.",
+                getIdentifierCString());
+            goto finish;
+        }
+
+        for (i = 0; i < numDirectDependencies; ++i) {
+            OSKext * dependencyKext = OSDynamicCast(OSKext,
+                dependencies->getObject(i));
+            dependencyKext->addBleedthroughDependencies(linkDependencies);
+        }
+    } 
+
+    num_kxlddeps = linkDependencies->getCount();
+    if (!num_kxlddeps) {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogLoadFlag | kOSKextLogDependenciesFlag,
+            "Can't load kext %s - it has no library dependencies.",
+            getIdentifierCString());
+        goto finish;
+    }
+
+    kxlddeps = (KXLDDependency *)kalloc_tag(num_kxlddeps * sizeof(*kxlddeps), VM_KERN_MEMORY_OSKEXT);
+    if (!kxlddeps) {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogLoadFlag | kOSKextLogLinkFlag,
+            "Can't allocate link context to load kext %s.",
+            getIdentifierCString());
+        goto finish;
+    }
+    bzero(kxlddeps, num_kxlddeps * sizeof(*kxlddeps));
+
+    for (i = 0; i < num_kxlddeps; ++i ) {
+        OSKext * dependency = OSDynamicCast(OSKext, linkDependencies->getObject(i));
+
+        if (dependency->isInterface()) {
+            OSKext *interfaceTargetKext = NULL;
+            OSData * interfaceTarget = NULL;
+
+            if (dependency->isKernelComponent()) {
+                interfaceTargetKext = sKernelKext;
+                interfaceTarget = sKernelKext->linkedExecutable;
+            } else {
+                interfaceTargetKext = OSDynamicCast(OSKext, 
+                    dependency->dependencies->getObject(0));
+
+                interfaceTarget = interfaceTargetKext->linkedExecutable;
+            }
+
+            if (!interfaceTarget) {
+                // panic?
+                goto finish;
+            }
+
+           /* The names set here aren't actually logged yet <rdar://problem/7941514>,
+            * it will be useful to have them in the debugger.
+            * strdup() failing isn't critical right here so we don't check that.
+            */
+            kxlddeps[i].kext = (u_char *) interfaceTarget->getBytesNoCopy();
+            kxlddeps[i].kext_size = interfaceTarget->getLength();
+            kxlddeps[i].kext_name = strdup(interfaceTargetKext->getIdentifierCString());
+
+            kxlddeps[i].interface = (u_char *) dependency->linkedExecutable->getBytesNoCopy();
+            kxlddeps[i].interface_size = dependency->linkedExecutable->getLength();
+            kxlddeps[i].interface_name = strdup(dependency->getIdentifierCString());
+        } else {
+            kxlddeps[i].kext = (u_char *) dependency->linkedExecutable->getBytesNoCopy();
+            kxlddeps[i].kext_size = dependency->linkedExecutable->getLength();
+            kxlddeps[i].kext_name = strdup(dependency->getIdentifierCString());
+        }
+
+        kxlddeps[i].is_direct_dependency = (i < numDirectDependencies);
+    }
+
+    kxldHeaderPtr = &kxld_header;
 
 #if DEBUG
-	OSKextLog(this,
-	    kOSKextLogExplicitLevel |
-	    kOSKextLogLoadFlag | kOSKextLogLinkFlag,
-	    "Kext %s - calling kxld_link_file:\n"
-	    "    kxld_context: %p\n"
-	    "    executable: %p    executable_length: %d\n"
-	    "    user_data: %p\n"
-	    "    kxld_dependencies: %p    num_dependencies: %d\n"
-	    "    kxld_header_ptr: %p    kmod_info_ptr: %p\n",
-	    getIdentifierCString(), sKxldContext,
-	    theExecutable->getBytesNoCopy(), theExecutable->getLength(),
-	    this, kxlddeps, num_kxlddeps,
-	    kxldHeaderPtr, &kmod_info);
+    OSKextLog(this,
+        kOSKextLogExplicitLevel |
+        kOSKextLogLoadFlag | kOSKextLogLinkFlag,
+        "Kext %s - calling kxld_link_file:\n"
+        "    kxld_context: %p\n"
+        "    executable: %p    executable_length: %d\n"
+        "    user_data: %p\n"
+        "    kxld_dependencies: %p    num_dependencies: %d\n"
+        "    kxld_header_ptr: %p    kmod_info_ptr: %p\n",
+        getIdentifierCString(), sKxldContext,
+        theExecutable->getBytesNoCopy(), theExecutable->getLength(),
+        this, kxlddeps, num_kxlddeps,
+        kxldHeaderPtr, &kmod_info);
 #endif
 
-	/* After this call, the linkedExecutable instance variable
-	 * should exist.
-	 */
-	kxldResult = kxld_link_file(sKxldContext,
-	    (u_char *)theExecutable->getBytesNoCopy(),
-	    theExecutable->getLength(),
-	    getIdentifierCString(), this, kxlddeps, num_kxlddeps,
-	    (u_char **)kxldHeaderPtr, (kxld_addr_t *)&kmod_info);
-
-	if (kxldResult != KERN_SUCCESS) {
-		// xxx - add kxldResult here?
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag,
-		    "Can't load kext %s - link failed.",
-		    getIdentifierCString());
-		result = kOSKextReturnLinkError;
-		goto finish;
-	}
-
-	/* We've written data & instructions into kernel memory, so flush the data
-	 * cache and invalidate the instruction cache.
-	 * I/D caches are coherent on x86
-	 */
+   /* After this call, the linkedExecutable instance variable
+    * should exist.
+    */
+    kxldResult = kxld_link_file(sKxldContext,
+        (u_char *)theExecutable->getBytesNoCopy(),
+        theExecutable->getLength(),
+        getIdentifierCString(), this, kxlddeps, num_kxlddeps,
+        (u_char **)kxldHeaderPtr, (kxld_addr_t *)&kmod_info);
+
+    if (kxldResult != KERN_SUCCESS) {
+        // xxx - add kxldResult here?
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogLoadFlag,
+            "Can't load kext %s - link failed.",
+            getIdentifierCString());
+        result = kOSKextReturnLinkError;
+        goto finish;
+    }
+    
+   /* We've written data & instructions into kernel memory, so flush the data
+    * cache and invalidate the instruction cache.
+    * I/D caches are coherent on x86
+    */
 #if !defined(__i386__) && !defined(__x86_64__)
-	flush_dcache(kmod_info->address, kmod_info->size, false);
-	invalidate_icache(kmod_info->address, kmod_info->size, false);
+    flush_dcache(kmod_info->address, kmod_info->size, false);
+    invalidate_icache(kmod_info->address, kmod_info->size, false);
 #endif
-
-#else // !CONFIG_KXLD
-	OSKextLog(this, kOSKextLogErrorLevel | kOSKextLogLoadFlag,
-	    "Refusing to link non-prelinked kext: %s (no kxld support)", getIdentifierCString());
-	result = kOSKextReturnLinkError;
-	goto finish;
-#endif // CONFIG_KXLD
-
 register_kmod:
 
-	if (isInterface()) {
-		/* Whip up a fake kmod_info entry for the interface kext.
-		 */
-		kmod_info = kalloc_type(kmod_info_t, (zalloc_flags_t)(Z_WAITOK | Z_ZERO));
-		if (!kmod_info) {
-			result = KERN_MEMORY_ERROR;
-			goto finish;
-		}
-
-		/* A pseudokext has almost nothing in its kmod_info struct.
-		 */
-		kmod_info->info_version = KMOD_INFO_VERSION;
-
-		/* An interface kext doesn't have a linkedExecutable, so save a
-		 * copy of the UUID out of the original executable via copyUUID()
-		 * while we still have the original executable.
-		 */
-		interfaceUUID = copyUUID();
-	}
-
-	kmod_info->id = loadTag = sNextLoadTag++;
-	kmod_info->reference_count = 0;         // KMOD_DECL... sets it to -1 (invalid).
-
-	/* Stamp the bundle ID and version from the OSKext over anything
-	 * resident inside the kmod_info.
-	 */
-	string = getIdentifierCString();
-	strlcpy(kmod_info->name, string, sizeof(kmod_info->name));
-
-	string = versCString;
-	strlcpy(kmod_info->version, string, sizeof(kmod_info->version));
-
-	/* Add the dependencies' kmod_info structs as kmod_references.
-	 */
-	num_kmod_refs = getNumDependencies();
-	if (num_kmod_refs) {
-		kmod_info->reference_list = kalloc_type_tag(kmod_reference_t,
-		    num_kmod_refs, Z_WAITOK_ZERO, VM_KERN_MEMORY_OSKEXT);
-		if (!kmod_info->reference_list) {
-			result = KERN_MEMORY_ERROR;
-			goto finish;
-		}
-		for (uint32_t refIndex = 0; refIndex < num_kmod_refs; refIndex++) {
-			kmod_reference_t * ref = &(kmod_info->reference_list[refIndex]);
-			OSKext * refKext = OSDynamicCast(OSKext, dependencies->getObject(refIndex));
-			ref->info = refKext->kmod_info;
-			ref->info->reference_count++;
-
-			if (refIndex + 1 < num_kmod_refs) {
-				ref->next = kmod_info->reference_list + refIndex + 1;
-			}
-		}
-	}
-
-	if (kmod_info->hdr_size > UINT32_MAX) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag,
-#if __LP64__
-		    "Kext %s header size is too large (%lu > UINT32_MAX).",
-#else
-		    "Kext %s header size is too large (%u > UINT32_MAX).",
-#endif
-		    kmod_info->name,
-		    kmod_info->hdr_size);
-		result = KERN_FAILURE;
-		goto finish;
-	}
-
-	if (kmod_info->size > UINT32_MAX) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag,
-#if __LP64__
-		    "Kext %s size is too large (%lu > UINT32_MAX).",
-#else
-		    "Kext %s size is too large (%u > UINT32_MAX).",
-#endif
-		    kmod_info->name,
-		    kmod_info->size);
-		result = KERN_FAILURE;
-		goto finish;
-	}
-
-	if (!isInterface() && linkedExecutable) {
-		OSKextLog(this,
-		    kOSKextLogProgressLevel |
-		    kOSKextLogLoadFlag,
-		    "Kext %s executable loaded; %u pages at 0x%lx (load tag %u).",
-		    kmod_info->name,
-		    (unsigned)kmod_info->size / PAGE_SIZE,
-		    (unsigned long)ml_static_unslide(kmod_info->address),
-		    (unsigned)kmod_info->id);
-	}
-
-	/* VM protections and wiring for the Aux KC are done at collection loading time */
-	if (kc_type != KCKindAuxiliary || flags.resetSegmentsFromVnode) {
-		/* if prelinked and primary KC, VM protections are already set */
-		result = setVMAttributes(!isPrelinked() || flags.resetSegmentsFromVnode, true);
-		if (result != KERN_SUCCESS) {
-			goto finish;
-		}
-	}
-
-#if KASAN
-	if (linkedExecutable) {
-		kasan_load_kext((vm_offset_t)linkedExecutable->getBytesNoCopy(),
-		    linkedExecutable->getLength(), getIdentifierCString());
-	}
-#else
-	if (lookupSection(KASAN_GLOBAL_SEGNAME, KASAN_GLOBAL_SECTNAME)) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel | kOSKextLogLoadFlag,
-		    "KASAN: cannot load KASAN-ified kext %s on a non-KASAN kernel\n",
-		    getIdentifierCString()
-		    );
-		result = KERN_FAILURE;
-		goto finish;
-	}
-#endif
-
-	result = kOSReturnSuccess;
+    if (isInterface()) {
+
+       /* Whip up a fake kmod_info entry for the interface kext.
+        */
+        kmod_info = (kmod_info_t *)kalloc_tag(sizeof(kmod_info_t), VM_KERN_MEMORY_OSKEXT);
+        if (!kmod_info) {
+            result = KERN_MEMORY_ERROR;
+            goto finish;
+        }
+
+       /* A pseudokext has almost nothing in its kmod_info struct.
+        */
+        bzero(kmod_info, sizeof(kmod_info_t));
+
+        kmod_info->info_version = KMOD_INFO_VERSION;
+
+       /* An interface kext doesn't have a linkedExecutable, so save a
+        * copy of the UUID out of the original executable via copyUUID()
+        * while we still have the original executable.
+        */
+        interfaceUUID = copyUUID();
+    }
+
+    kmod_info->id = loadTag = sNextLoadTag++;
+    kmod_info->reference_count = 0;  // KMOD_DECL... sets it to -1 (invalid).
+
+   /* Stamp the bundle ID and version from the OSKext over anything
+    * resident inside the kmod_info.
+    */
+    string = getIdentifierCString();
+    strlcpy(kmod_info->name, string, sizeof(kmod_info->name));
+
+    string = versCString;
+    strlcpy(kmod_info->version, string, sizeof(kmod_info->version));
+
+   /* Add the dependencies' kmod_info structs as kmod_references.
+    */
+    num_kmod_refs = getNumDependencies();
+    if (num_kmod_refs) {
+        kmod_info->reference_list = (kmod_reference_t *)kalloc_tag(
+            num_kmod_refs * sizeof(kmod_reference_t), VM_KERN_MEMORY_OSKEXT);
+        if (!kmod_info->reference_list) {
+            result = KERN_MEMORY_ERROR;
+            goto finish;
+        }
+        bzero(kmod_info->reference_list,
+            num_kmod_refs * sizeof(kmod_reference_t));
+        for (uint32_t refIndex = 0; refIndex < num_kmod_refs; refIndex++) {
+            kmod_reference_t * ref = &(kmod_info->reference_list[refIndex]);
+            OSKext * refKext = OSDynamicCast(OSKext, dependencies->getObject(refIndex));
+            ref->info = refKext->kmod_info;
+            ref->info->reference_count++;
+
+            if (refIndex + 1 < num_kmod_refs) {
+                ref->next = kmod_info->reference_list + refIndex + 1;
+            }
+        }
+    }
+
+    if (!isInterface() && linkedExecutable) {
+        OSKextLog(this,
+            kOSKextLogProgressLevel |
+            kOSKextLogLoadFlag,
+            "Kext %s executable loaded; %u pages at 0x%lx (load tag %u).", 
+            kmod_info->name,
+            (unsigned)kmod_info->size / PAGE_SIZE,
+            (unsigned long)VM_KERNEL_UNSLIDE(kmod_info->address),
+            (unsigned)kmod_info->id);
+    }
+
+    /* if prelinked, VM protections are already set */
+    result = setVMAttributes(!isPrelinked(), true);
+    if (result != KERN_SUCCESS) {
+        goto finish;
+    }
+
+    result = kOSReturnSuccess;
 
 finish:
-
-#if CONFIG_KXLD
-	/* Clear up locally allocated dependency info.
-	 */
-	for (i = 0; i < num_kxlddeps; ++i) {
-		size_t size;
-
-		if (kxlddeps[i].kext_name) {
-			size = 1 + strlen(kxlddeps[i].kext_name);
-			kfree_data(kxlddeps[i].kext_name, size);
-		}
-		if (kxlddeps[i].interface_name) {
-			size = 1 + strlen(kxlddeps[i].interface_name);
-			kfree_data(kxlddeps[i].interface_name, size);
-		}
-	}
-	if (kxlddeps) {
-		kfree_type(KXLDDependency, num_kxlddeps, kxlddeps);
-	}
-#endif // CONFIG_KXLD
-
-	/* We no longer need the unrelocated executable (which the linker
-	 * has altered anyhow).
-	 */
-	setExecutable(NULL);
-
-	if (result != kOSReturnSuccess) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag,
-		    "Failed to load executable for kext %s.",
-		    getIdentifierCString());
-
-		if (kmod_info && kmod_info->reference_list) {
-			kfree_type(kmod_reference_t, num_kmod_refs,
-			    kmod_info->reference_list);
-		}
-		if (isInterface()) {
-			kfree_type(kmod_info_t, kmod_info);
-			kmod_info = NULL;
-		}
-		if (kc_type == KCKindUnknown) {
-			kmod_info = NULL;
-			if (linkedExecutable) {
-				linkedExecutable.reset();
-			}
-		}
-	}
-
-	return result;
-}
-
-/* static */
-void
-OSKext::jettisonFileSetLinkeditSegment(kernel_mach_header_t *mh)
-{
-	kernel_segment_command_t *linkeditseg = NULL;
-
-	linkeditseg = getsegbynamefromheader(mh, SEG_LINKEDIT);
-	if (linkeditseg == NULL) {
-		panic("FileSet booted with no Linkedit segment");
-	}
-
-#if VM_MAPPED_KEXTS
-	/* BootKC on x86_64 is not vm mapped */
-	ml_static_mfree(linkeditseg->vmaddr, linkeditseg->vmsize);
-
-	OSKextLog(/* kext */ NULL,
-	    kOSKextLogProgressLevel |
-	    kOSKextLogGeneralFlag,
-	    "Jettisoning fileset Linkedit segments from vmaddr %llx with size %llu",
-	    linkeditseg->vmaddr, linkeditseg->vmsize);
-#else
-	/* BootKC on arm64 is not vm mapped, but is slid */
-#if !CONFIG_SPTM
-	vm_offset_t linkedit_vmaddr = ml_static_ptovirt((vm_offset_t)(linkeditseg->vmaddr - gVirtBase + gPhysBase));
-#else
-	vm_offset_t linkedit_vmaddr = linkeditseg->vmaddr;
-#endif
-
-	ml_static_mfree(linkedit_vmaddr, (vm_size_t)linkeditseg->vmsize);
-
-	OSKextLog(/* kext */ NULL,
-	    kOSKextLogProgressLevel |
-	    kOSKextLogGeneralFlag,
-	    "Jettisoning fileset Linkedit segments from vmaddr %llx with size %llu",
-	    (unsigned long long)linkedit_vmaddr, (unsigned long long)linkeditseg->vmsize);
-#endif /* VM_MAPPED_KEXTS */
+    OSSafeRelease(linkDependencies);
+
+   /* Clear up locally allocated dependency info.
+    */
+    for (i = 0; i < num_kxlddeps; ++i ) {
+        size_t size;
+
+        if (kxlddeps[i].kext_name) {
+            size = 1 + strlen(kxlddeps[i].kext_name);
+            kfree(kxlddeps[i].kext_name, size);
+        }
+        if (kxlddeps[i].interface_name) {
+            size = 1 + strlen(kxlddeps[i].interface_name);
+            kfree(kxlddeps[i].interface_name, size);
+        }
+    }
+    if (kxlddeps) kfree(kxlddeps, (num_kxlddeps * sizeof(*kxlddeps)));
+
+   /* We no longer need the unrelocated executable (which the linker
+    * has altered anyhow).
+    */
+    setExecutable(NULL);
+
+    if (result != kOSReturnSuccess) {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogLoadFlag,
+            "Failed to load executable for kext %s.",
+            getIdentifierCString());
+
+        if (kmod_info && kmod_info->reference_list) {
+            kfree(kmod_info->reference_list,
+                num_kmod_refs * sizeof(kmod_reference_t));
+        }
+        if (isInterface()) {
+            kfree(kmod_info, sizeof(kmod_info_t));
+        }
+        kmod_info = NULL;
+        if (linkedExecutable) {
+            linkedExecutable->release();
+            linkedExecutable = NULL;
+        }
+    }
+
+    return result;
 }
 
 /*********************************************************************
@@ -7648,88 +5338,73 @@
 void
 OSKext::jettisonLinkeditSegment(void)
 {
-	kernel_mach_header_t     * machhdr = (kernel_mach_header_t *)kmod_info->address;
-	kernel_segment_command_t * linkedit = NULL;
-	vm_offset_t                start;
-	vm_size_t                  linkeditsize, kextsize;
-	OSSharedPtr<OSData>        data;
-	kc_format                format    = KCFormatUnknown;
-
-	if (isInFileset()) {
-		return;
-	}
+    kernel_mach_header_t     * machhdr = (kernel_mach_header_t *)kmod_info->address;
+    kernel_segment_command_t * linkedit = NULL;
+    vm_offset_t                start;
+    vm_size_t                  linkeditsize, kextsize;
+    OSData                   * data = NULL;
 
 #if NO_KEXTD
-	/* We can free symbol tables for all embedded kexts because we don't
-	 * support runtime kext linking.
-	 */
-	if (sKeepSymbols || !isExecutable() || !linkedExecutable || flags.jettisonLinkeditSeg) {
+    /* We can free symbol tables for all embedded kexts because we don't
+     * support runtime kext linking.
+     */
+    if (sKeepSymbols || !isExecutable() || !linkedExecutable || flags.jettisonLinkeditSeg) {
 #else
-	if (sKeepSymbols || isLibrary() || !isExecutable() || !linkedExecutable || flags.jettisonLinkeditSeg) {
+    if (sKeepSymbols || isLibrary() || !isExecutable() || !linkedExecutable || flags.jettisonLinkeditSeg) {
 #endif
-		goto finish;
-	}
-
-	/* Find the linkedit segment.  If it's not the last segment, then freeing
-	 * it will fragment the kext into multiple VM regions, which OSKext is not
-	 * designed to handle, so we'll have to skip it.
-	 */
-	linkedit = getsegbynamefromheader(machhdr, SEG_LINKEDIT);
-	if (!linkedit) {
-		goto finish;
-	}
-
-	if (round_page(kmod_info->address + kmod_info->size) !=
-	    round_page(linkedit->vmaddr + linkedit->vmsize)) {
-		goto finish;
-	}
-
-	/* Create a new OSData for the smaller kext object.
-	 */
-	linkeditsize = round_page(linkedit->vmsize);
-	kextsize = kmod_info->size - linkeditsize;
-	start = linkedit->vmaddr;
-
-	if (kextsize > UINT_MAX) {
-		goto finish;
-	}
-	data = OSData::withBytesNoCopy((void *)kmod_info->address, (unsigned int)kextsize);
-	if (!data) {
-		goto finish;
-	}
-
-	/* Fix the kmod info and linkedExecutable.
-	 */
-	kmod_info->size = kextsize;
-
-	/*
-	 * Fileset KCs are mapped as a whole by iBoot.
-	 * Individual kext executables should not be unmapped by xnu
-	 * Doing so may result in panics like rdar://85419651
-	 */
-	if (PE_get_kc_format(kc_type, &format) && (format == KCFormatFileset)) {
-		data->setDeallocFunction(NULL);
-	} else { // Not from a Fileset KC
+        goto finish;
+    }
+
+   /* Find the linkedit segment.  If it's not the last segment, then freeing
+    * it will fragment the kext into multiple VM regions, which OSKext is not
+    * designed to handle, so we'll have to skip it.
+    */
+    linkedit = getsegbynamefromheader(machhdr, SEG_LINKEDIT);
+    if (!linkedit) {
+        goto finish;
+    }
+
+    if (round_page(kmod_info->address + kmod_info->size) !=
+        round_page(linkedit->vmaddr + linkedit->vmsize))
+    {
+        goto finish;
+    }
+
+   /* Create a new OSData for the smaller kext object.
+    */
+    linkeditsize = round_page(linkedit->vmsize);
+    kextsize = kmod_info->size - linkeditsize;
+    start = linkedit->vmaddr;
+
+    data = OSData::withBytesNoCopy((void *)kmod_info->address, kextsize);
+    if (!data) {
+        goto finish;
+    }
+
+   /* Fix the kmod info and linkedExecutable.
+    */
+    kmod_info->size = kextsize;
+        
 #if VM_MAPPED_KEXTS
-		data->setDeallocFunction(osdata_kext_free);
+    data->setDeallocFunction(osdata_kext_free);
 #else
-		data->setDeallocFunction(osdata_phys_free);
+    data->setDeallocFunction(osdata_phys_free);
 #endif
-	}
-	linkedExecutable->setDeallocFunction(NULL);
-	linkedExecutable = os::move(data);
-	flags.jettisonLinkeditSeg = 1;
-
-	/* Free the linkedit segment.
-	 */
+    linkedExecutable->setDeallocFunction(NULL);
+    linkedExecutable->release();
+    linkedExecutable = data;
+    flags.jettisonLinkeditSeg = 1;
+        
+   /* Free the linkedit segment.
+    */
 #if VM_MAPPED_KEXTS
-	kext_free(start, linkeditsize);
+    kext_free(start, linkeditsize);
 #else
-	ml_static_mfree(start, linkeditsize);
+    ml_static_mfree(start, linkeditsize);
 #endif
 
 finish:
-	return;
+    return;
 }
 
 /*********************************************************************
@@ -7740,58 +5415,51 @@
 void
 OSKext::jettisonDATASegmentPadding(void)
 {
-	kernel_mach_header_t * mh;
-	kernel_segment_command_t * dataSeg;
-	kernel_section_t * sec, * lastSec;
-	vm_offset_t dataSegEnd, lastSecEnd;
-	vm_size_t padSize;
-
-	if (flags.builtin) {
-		return;
-	}
-	mh = (kernel_mach_header_t *)kmod_info->address;
-
-	if (isInFileset()) {
-		return;
-	}
-
-	dataSeg = getsegbynamefromheader(mh, SEG_DATA);
-	if (dataSeg == NULL) {
-		return;
-	}
-
-	lastSec = NULL;
-	sec = firstsect(dataSeg);
-	while (sec != NULL) {
-		lastSec = sec;
-		sec = nextsect(dataSeg, sec);
-	}
-
-	if (lastSec == NULL) {
-		return;
-	}
-
-	if ((dataSeg->vmaddr != round_page(dataSeg->vmaddr)) ||
-	    (dataSeg->vmsize != round_page(dataSeg->vmsize))) {
-		return;
-	}
-
-	dataSegEnd = dataSeg->vmaddr + dataSeg->vmsize;
-	lastSecEnd = round_page(lastSec->addr + lastSec->size);
-
-	if (dataSegEnd <= lastSecEnd) {
-		return;
-	}
-
-	padSize = dataSegEnd - lastSecEnd;
-
-	if (padSize >= PAGE_SIZE) {
+    kernel_mach_header_t * mh;
+    kernel_segment_command_t * dataSeg;
+    kernel_section_t * sec, * lastSec;
+    vm_offset_t dataSegEnd, lastSecEnd;
+    vm_size_t padSize;
+
+    mh = (kernel_mach_header_t *)kmod_info->address;
+
+    dataSeg = getsegbynamefromheader(mh, SEG_DATA);
+    if (dataSeg == NULL) {
+        return;
+    }
+
+    lastSec = NULL;
+    sec = firstsect(dataSeg);
+    while (sec != NULL) {
+        lastSec = sec;
+        sec = nextsect(dataSeg, sec);
+    } 
+
+    if (lastSec == NULL) {
+        return;
+    }
+
+    if ((dataSeg->vmaddr != round_page(dataSeg->vmaddr)) ||
+        (dataSeg->vmsize != round_page(dataSeg->vmsize))) {
+        return;
+    }
+
+    dataSegEnd = dataSeg->vmaddr + dataSeg->vmsize;
+    lastSecEnd = round_page(lastSec->addr + lastSec->size);
+
+    if (dataSegEnd <= lastSecEnd) {
+        return;
+    }
+
+    padSize = dataSegEnd - lastSecEnd;
+
+    if (padSize >= PAGE_SIZE) {
 #if VM_MAPPED_KEXTS
-		kext_free(lastSecEnd, padSize);
+        kext_free(lastSecEnd, padSize);
 #else
-		ml_static_mfree(lastSecEnd, padSize);
+        ml_static_mfree(lastSecEnd, padSize);
 #endif
-	}
+    }
 }
 
 /*********************************************************************
@@ -7799,13 +5467,14 @@
 void
 OSKext::setLinkedExecutable(OSData * anExecutable)
 {
-	if (linkedExecutable) {
-		panic("Attempt to set linked executable on kext "
-		    "that already has one (%s).\n",
-		    getIdentifierCString());
-	}
-	linkedExecutable.reset(anExecutable, OSRetain);
-	return;
+    if (linkedExecutable) {
+        panic("Attempt to set linked executable on kext "
+            "that already has one (%s).\n",
+            getIdentifierCString());
+    }
+    linkedExecutable = anExecutable;
+    linkedExecutable->retain();
+    return;
 }
 
 #if CONFIG_DTRACE
@@ -7817,30 +5486,30 @@
 void
 OSKext::registerKextsWithDTrace(void)
 {
-	uint32_t count = sLoadedKexts->getCount();
-	uint32_t i;
-
-	IORecursiveLockLock(sKextLock);
-
-	for (i = 0; i < count; i++) {
-		OSKext   * thisKext     = NULL;        // do not release
-
-		thisKext = OSDynamicCast(OSKext, sLoadedKexts->getObject(i));
-		if (!thisKext || !thisKext->isExecutable()) {
-			continue;
-		}
-
-		thisKext->registerWithDTrace();
-	}
-
-	IORecursiveLockUnlock(sKextLock);
-
-	return;
+    uint32_t count = sLoadedKexts->getCount();
+    uint32_t i;
+
+    IORecursiveLockLock(sKextLock);
+
+    for (i = 0; i < count; i++) {
+        OSKext   * thisKext     = NULL;  // do not release
+
+        thisKext = OSDynamicCast(OSKext, sLoadedKexts->getObject(i));
+        if (!thisKext || !thisKext->isExecutable()) {
+            continue;
+        }
+
+        thisKext->registerWithDTrace();
+    }
+
+    IORecursiveLockUnlock(sKextLock);
+
+    return;
 }
 
 extern "C" {
-extern int (*dtrace_modload)(struct kmod_info *, uint32_t);
-extern int (*dtrace_modunload)(struct kmod_info *);
+    extern int (*dtrace_modload)(struct kmod_info *, uint32_t);
+    extern int (*dtrace_modunload)(struct kmod_info *);
 };
 
 /*********************************************************************
@@ -7848,52 +5517,35 @@
 void
 OSKext::registerWithDTrace(void)
 {
-	/* Register kext with dtrace. A dtrace_modload failure should not
-	 * prevent a kext from loading, so we ignore the return code.
-	 */
-	if (!flags.dtraceInitialized && (dtrace_modload != NULL)) {
-		uint32_t modflag = 0;
-		OSObject * forceInit = getPropertyForHostArch("OSBundleForceDTraceInit");
-
-		if (!sKeepSymbols && kc_type == KCKindPrimary) {
-			if (forceInit == kOSBooleanTrue) {
-				OSKextLog(this,
-				    kOSKextLogBasicLevel |
-				    kOSKextLogGeneralFlag,
-				    "Ignoring OSBundleForceDTraceInit for Boot KC Kext %s",
-				    getIdentifierCString());
-				forceInit = kOSBooleanFalse;
-			}
-			/* Linkedit segment of the Boot KC is gone, make sure fbt_provide_module don't use kernel symbols */
-			modflag |= KMOD_DTRACE_NO_KERNEL_SYMS;
-		}
-
-		if (forceInit == kOSBooleanTrue) {
-			modflag |= KMOD_DTRACE_FORCE_INIT;
-		}
-		if (flags.builtin) {
-			modflag |= KMOD_DTRACE_STATIC_KEXT;
-		}
-
-		(void)(*dtrace_modload)(kmod_info, modflag);
-		flags.dtraceInitialized = true;
-		jettisonLinkeditSegment();
-	}
-	return;
+   /* Register kext with dtrace. A dtrace_modload failure should not
+    * prevent a kext from loading, so we ignore the return code.
+    */
+    if (!flags.dtraceInitialized && (dtrace_modload != NULL)) {
+        uint32_t modflag = 0;
+        OSObject * forceInit = getPropertyForHostArch("OSBundleForceDTraceInit");
+        if (forceInit == kOSBooleanTrue) {
+            modflag |= KMOD_DTRACE_FORCE_INIT;
+        }
+
+        (void)(*dtrace_modload)(kmod_info, modflag);
+        flags.dtraceInitialized = true;
+        jettisonLinkeditSegment();
+    }
+    return;
 }
 /*********************************************************************
 *********************************************************************/
 void
 OSKext::unregisterWithDTrace(void)
 {
-	/* Unregister kext with dtrace. A dtrace_modunload failure should not
-	 * prevent a kext from loading, so we ignore the return code.
-	 */
-	if (flags.dtraceInitialized && (dtrace_modunload != NULL)) {
-		(void)(*dtrace_modunload)(kmod_info);
-		flags.dtraceInitialized = false;
-	}
-	return;
+   /* Unregister kext with dtrace. A dtrace_modunload failure should not
+    * prevent a kext from loading, so we ignore the return code.
+    */
+    if (flags.dtraceInitialized && (dtrace_modunload != NULL)) {
+        (void)(*dtrace_modunload)(kmod_info);
+        flags.dtraceInitialized = false;
+    }
+    return;
 }
 #endif /* CONFIG_DTRACE */
 
@@ -7902,228 +5554,115 @@
 * called only by loadExecutable()
 *********************************************************************/
 #if !VM_MAPPED_KEXTS
-#if defined(__arm__) || defined(__arm64__)
-static inline kern_return_t
-OSKext_protect(
-	kernel_mach_header_t *kext_mh,
-	vm_map_t   map,
-	vm_map_offset_t    start,
-	vm_map_size_t      size,
-	vm_prot_t  new_prot,
-	boolean_t  set_max,
-	kc_kind_t  kc_type)
-{
-	vm_map_offset_t    end = start + size;
-
-#pragma unused(kext_mh,map,kc_type)
-	assert(map == kernel_map);         // we can handle KEXTs arising from the PRELINK segment and no others
-	assert(start <= end);
-	if (start >= end) {
-		return KERN_SUCCESS;         // Punt segments of length zero (e.g., headers) or less (i.e., blunders)
-	} else if (set_max) {
-		return KERN_SUCCESS;         // Punt set_max, as there's no mechanism to record that state
-	} else {
-		return ml_static_protect(start, size, new_prot);
-	}
-}
-
-static inline kern_return_t
-OSKext_wire(
-	kernel_mach_header_t *kext_mh,
-	vm_map_t   map,
-	vm_map_offset_t    start,
-	vm_map_offset_t    end,
-	vm_prot_t  access_type,
-	boolean_t       user_wire,
-	kc_kind_t       kc_type)
-{
-#pragma unused(kext_mh,map,start,end,access_type,user_wire,kc_type)
-	return KERN_SUCCESS;         // No-op as PRELINK kexts are cemented into physical memory at boot
-}
-#else
-#error Unrecognized architecture
-#endif
+#error Unrecognized architecture 
 #else
 static inline kern_return_t
 OSKext_protect(
-	kernel_mach_header_t *kext_mh,
-	vm_map_t   map,
-	vm_map_offset_t    start,
-	vm_map_size_t      size,
-	vm_prot_t  new_prot,
-	boolean_t  set_max,
-	kc_kind_t  kc_type)
-{
-	vm_map_offset_t    end = start + size;
-
-	if (start == end) {         // 10538581
-		return KERN_SUCCESS;
-	}
-	if (kernel_mach_header_is_in_fileset(kext_mh) && kc_type == KCKindPrimary) {
-		/*
-		 * XXX: This will probably need to be different for AuxKC and
-		 * pageableKC!
-		 */
-		return ml_static_protect(start, size, new_prot);
-	}
-	return mach_vm_protect(map, start, size, set_max, new_prot);
+    vm_map_t   map,
+    vm_map_offset_t    start,
+    vm_map_offset_t    end,
+    vm_prot_t  new_prot,
+    boolean_t  set_max)
+{
+    if (start == end) { // 10538581
+        return(KERN_SUCCESS);
+    }
+    return vm_map_protect(map, start, end, new_prot, set_max);
 }
 
 static inline kern_return_t
 OSKext_wire(
-	kernel_mach_header_t *kext_mh,
-	vm_map_t   map,
-	vm_map_offset_t    start,
-	vm_map_offset_t    end,
-	vm_prot_t  access_type,
-	boolean_t       user_wire,
-	kc_kind_t       kc_type)
-{
-	if (kernel_mach_header_is_in_fileset(kext_mh) && kc_type == KCKindPrimary) {
-		/* TODO: we may need to hook this for the pageableKC */
-		return KERN_SUCCESS;
-	}
-	return vm_map_wire_kernel(map, start, end, access_type, VM_KERN_MEMORY_KEXT, user_wire);
+    vm_map_t   map,
+    vm_map_offset_t    start,
+    vm_map_offset_t    end,
+    vm_prot_t  access_type,
+    boolean_t       user_wire)
+{
+	return vm_map_wire(map, start, end, access_type | VM_PROT_MEMORY_TAG_MAKE(VM_KERN_MEMORY_KEXT), user_wire);
 }
 #endif
 
 OSReturn
 OSKext::setVMAttributes(bool protect, bool wire)
 {
-	vm_map_t                    kext_map        = NULL;
-	kernel_segment_command_t  * seg             = NULL;
-	vm_map_offset_t             start_protect   = 0;
-	vm_map_offset_t             start_wire      = 0;
-	vm_map_offset_t             end_protect     = 0;
-	vm_map_size_t               size_protect    = 0;
-	vm_map_offset_t             end_wire        = 0;
-	OSReturn                    result          = kOSReturnError;
-
-	if (isInterface() || !declaresExecutable() || flags.builtin) {
-		result = kOSReturnSuccess;
-		goto finish;
-	}
-
-	/* Get the kext's vm map */
-	kext_map = kext_get_vm_map(kmod_info);
-	if (!kext_map) {
-		result = KERN_MEMORY_ERROR;
-		goto finish;
-	}
-
-#if !VM_MAPPED_KEXTS
-	if (getcommandfromheader((kernel_mach_header_t *)kmod_info->address, LC_SEGMENT_SPLIT_INFO)) {
-		/* This is a split kext in a prelinked kernelcache; we'll let the
-		 * platform code take care of protecting it.  It is already wired.
-		 */
-		/* TODO: Should this still allow protections for the first segment
-		 * to go through, in the event that we have a mix of split and
-		 * unsplit kexts?
-		 */
-		result = KERN_SUCCESS;
-		goto finish;
-	}
-
-	if (isInFileset() && kc_type != KCKindPageable) {
-		// kexts in filesets have protections setup as part of collection loading
-		result = KERN_SUCCESS;
-		goto finish;
-	}
-#endif
-
-	/* Protect the headers as read-only; they do not need to be wired */
-	result = (protect) ? OSKext_protect((kernel_mach_header_t *)kmod_info->address,
-	    kext_map, kmod_info->address,
-	    kmod_info->hdr_size, VM_PROT_READ, TRUE, kc_type)
-	    : KERN_SUCCESS;
-	if (result != KERN_SUCCESS) {
-		goto finish;
-	}
-
-	/* Set the VM protections and wire down each of the segments */
-	seg = firstsegfromheader((kernel_mach_header_t *)kmod_info->address);
-	while (seg) {
-#if __arm__
-		/* We build all ARM kexts, so we can ensure they are aligned */
-		assert((seg->vmaddr & PAGE_MASK) == 0);
-		assert((seg->vmsize & PAGE_MASK) == 0);
-#endif
-
-		/*
-		 * For the non page aligned segments, the range calculation for protection
-		 * and wiring differ as follows:
-		 *
-		 * Protection: The non page aligned data at the start or at the end of the
-		 * segment is excluded from the protection. This exclusion is needed to make
-		 * sure OSKext_protect is not called twice on same page, if the page is shared
-		 * between two segments.
-		 *
-		 * Wiring: The non page aligned data at the start or at the end of the
-		 * segment is included in the wiring range, this inclusion is needed to make sure
-		 * all the data of the segment is wired.
-		 */
-		start_protect = round_page(seg->vmaddr);
-		end_protect = trunc_page(seg->vmaddr + seg->vmsize);
-		size_protect = end_protect - start_protect;
-
-		start_wire = trunc_page(seg->vmaddr);
-		end_wire = round_page(seg->vmaddr + seg->vmsize);
-
-		/*
-		 * Linkedit and Linkinfo for the Pageable KC and the Aux KC are shared
-		 * across kexts and data from kexts is not page aligned
-		 */
-		if (protect && (end_protect > start_protect) &&
-		    ((strncmp(seg->segname, SEG_LINKEDIT, sizeof(seg->segname)) != 0 &&
-		    strncmp(seg->segname, SEG_LINKINFO, sizeof(seg->segname)) != 0) ||
-		    (kc_type != KCKindPageable && kc_type != KCKindAuxiliary))) {
-			result = OSKext_protect((kernel_mach_header_t *)kmod_info->address,
-			    kext_map, start_protect, size_protect, seg->maxprot, TRUE, kc_type);
-			if (result != KERN_SUCCESS) {
-				OSKextLog(this,
-				    kOSKextLogErrorLevel |
-				    kOSKextLogLoadFlag,
-				    "Kext %s failed to set maximum VM protections "
-				    "for segment %s - 0x%x.",
-				    getIdentifierCString(), seg->segname, (int)result);
-				goto finish;
-			}
-
-			result = OSKext_protect((kernel_mach_header_t *)kmod_info->address,
-			    kext_map, start_protect, size_protect, seg->initprot, FALSE, kc_type);
-			if (result != KERN_SUCCESS) {
-				OSKextLog(this,
-				    kOSKextLogErrorLevel |
-				    kOSKextLogLoadFlag,
-				    "Kext %s failed to set initial VM protections "
-				    "for segment %s - 0x%x.",
-				    getIdentifierCString(), seg->segname, (int)result);
-				goto finish;
-			}
-		}
-
-		if (segmentShouldBeWired(seg) && wire) {
-			result = OSKext_wire((kernel_mach_header_t *)kmod_info->address,
-			    kext_map, start_wire, end_wire, seg->initprot, FALSE, kc_type);
-			if (result != KERN_SUCCESS) {
-				goto finish;
-			}
-		}
-
-		seg = nextsegfromheader((kernel_mach_header_t *) kmod_info->address, seg);
-	}
+    vm_map_t                    kext_map        = NULL;
+    kernel_segment_command_t  * seg             = NULL;
+    vm_map_offset_t             start           = 0;
+    vm_map_offset_t             end             = 0;
+    OSReturn                    result          = kOSReturnError;
+
+    if (isInterface() || !declaresExecutable()) {
+        result = kOSReturnSuccess;
+        goto finish;
+    }
+
+    /* Get the kext's vm map */
+    kext_map = kext_get_vm_map(kmod_info);
+    if (!kext_map) {
+        result = KERN_MEMORY_ERROR;
+        goto finish;
+    }
+
+    /* Protect the headers as read-only; they do not need to be wired */
+    result = (protect) ? OSKext_protect(kext_map, kmod_info->address, 
+        kmod_info->address + kmod_info->hdr_size, VM_PROT_READ, TRUE)
+            : KERN_SUCCESS;
+    if (result != KERN_SUCCESS) {
+        goto finish;
+    }
+
+    /* Set the VM protections and wire down each of the segments */
+    seg = firstsegfromheader((kernel_mach_header_t *)kmod_info->address);
+    while (seg) {
+
+
+        start = round_page(seg->vmaddr);
+        end = trunc_page(seg->vmaddr + seg->vmsize);
+
+        if (protect) {
+            result = OSKext_protect(kext_map, start, end, seg->maxprot, TRUE);
+            if (result != KERN_SUCCESS) {
+                OSKextLog(this,
+                    kOSKextLogErrorLevel |
+                    kOSKextLogLoadFlag,
+                    "Kext %s failed to set maximum VM protections "
+                    "for segment %s - 0x%x.",
+                    getIdentifierCString(), seg->segname, (int)result);
+                goto finish;
+            }
+
+            result = OSKext_protect(kext_map, start, end, seg->initprot, FALSE);
+            if (result != KERN_SUCCESS) {
+                OSKextLog(this,
+                    kOSKextLogErrorLevel |
+                    kOSKextLogLoadFlag,
+                    "Kext %s failed to set initial VM protections "
+                    "for segment %s - 0x%x.",
+                    getIdentifierCString(), seg->segname, (int)result);
+                goto finish;
+            }
+        }
+
+        if (segmentShouldBeWired(seg) && wire) {
+            result = OSKext_wire(kext_map, start, end, seg->initprot, FALSE);
+            if (result != KERN_SUCCESS) {
+                goto finish;
+            }
+        }
+
+        seg = nextsegfromheader((kernel_mach_header_t *) kmod_info->address, seg);
+    }
 
 finish:
-	return result;
-}
-
-/*********************************************************************
-*********************************************************************/
-boolean_t
+    return result;
+}
+
+/*********************************************************************
+*********************************************************************/
+boolean_t 
 OSKext::segmentShouldBeWired(kernel_segment_command_t *seg)
 {
-	return sKeepSymbols || (strncmp(seg->segname, SEG_LINKEDIT, sizeof(seg->segname)) &&
-	       strncmp(seg->segname, SEG_LINKINFO, sizeof(seg->segname)));
+    return (sKeepSymbols || strncmp(seg->segname, SEG_LINKEDIT, sizeof(seg->segname)));
 }
 
 /*********************************************************************
@@ -8131,188 +5670,125 @@
 OSReturn
 OSKext::validateKextMapping(bool startFlag)
 {
-	OSReturn                              result      = kOSReturnError;
-	const char                          * whichOp = startFlag ? "start" : "stop";
-	kern_return_t                         kern_result = 0;
-	vm_map_t                              kext_map    = NULL;
-	kernel_segment_command_t            * seg         = NULL;
-	mach_vm_address_t                     address     = 0;
-	mach_vm_size_t                        size        = 0;
-	uint32_t                              depth       = 0;
-	uint64_t                              kext_segbase = 0;
-	uint64_t                              kext_segsize = 0;
-	mach_msg_type_number_t                count;
-	vm_region_submap_short_info_data_64_t info;
-	uintptr_t                             kext_slide = PE_get_kc_slide(kc_type);
-
-	if (flags.builtin) {
-		return kOSReturnSuccess;
-	}
-
-	count = VM_REGION_SUBMAP_SHORT_INFO_COUNT_64;
-	bzero(&info, sizeof(info));
-
-	// xxx - do we need a distinct OSReturn value for these or is "bad data"
-	// xxx - sufficient?
-
-	/* Verify that the kmod_info and start/stop pointers are non-NULL.
-	 */
-	if (!kmod_info) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag,
-		    "Kext %s - NULL kmod_info pointer.",
-		    getIdentifierCString());
-		result = kOSKextReturnBadData;
-		goto finish;
-	}
-
-	if (startFlag) {
-		address = (mach_vm_address_t)kmod_info->start;
-	} else {
-		address = (mach_vm_address_t)kmod_info->stop;
-	}
-
-	if (!address) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag,
-		    "Kext %s - NULL module %s pointer.",
-		    getIdentifierCString(), whichOp);
-		result = kOSKextReturnBadData;
-		goto finish;
-	}
-
-	kext_map = kext_get_vm_map(kmod_info);
-	depth = (kernel_map == kext_map) ? 1 : 2;
-	if (isInFileset()) {
-#if defined(HAS_APPLE_PAC)
-		address = (mach_vm_address_t)ptrauth_auth_data((void*)address, ptrauth_key_function_pointer, 0);
-#endif /* defined(HAS_APPLE_PAC) */
-	}
-
-	/* Verify that the start/stop function lies within the kext's address range.
-	 */
-	if (getcommandfromheader((kernel_mach_header_t *)kmod_info->address, LC_SEGMENT_SPLIT_INFO) ||
-	    isInFileset()) {
-		/* This will likely be how we deal with split kexts; walk the segments to
-		 * check that the function lies inside one of the segments of this kext.
-		 */
-		for (seg = firstsegfromheader((kernel_mach_header_t *)kmod_info->address);
-		    seg != NULL;
-		    seg = nextsegfromheader((kernel_mach_header_t *)kmod_info->address, seg)) {
-			if ((address >= seg->vmaddr) && address < (seg->vmaddr + seg->vmsize)) {
-				kext_segbase = seg->vmaddr;
-				kext_segsize = seg->vmsize;
-				break;
-			}
-		}
-
-		if (!seg) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogLoadFlag,
-			    "Kext %s module %s pointer is outside of kext range "
-			    "(%s %p - kext starts at %p).",
-			    getIdentifierCString(),
-			    whichOp,
-			    whichOp,
-			    (void *)(((uintptr_t)address) - kext_slide),
-			    (void *)(((uintptr_t)kmod_info->address) - kext_slide));
-			result = kOSKextReturnBadData;
-			goto finish;
-		}
-
-		seg = NULL;
-	} else {
-		if (address < kmod_info->address + kmod_info->hdr_size ||
-		    kmod_info->address + kmod_info->size <= address) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogLoadFlag,
-			    "Kext %s module %s pointer is outside of kext range "
-			    "(%s %p - kext at %p-%p).",
-			    getIdentifierCString(),
-			    whichOp,
-			    whichOp,
-			    (void *)(((uintptr_t)address) - kext_slide),
-			    (void *)(((uintptr_t)kmod_info->address) - kext_slide),
-			    (void *)((((uintptr_t)kmod_info->address) - kext_slide) + kmod_info->size));
-			result = kOSKextReturnBadData;
-			goto finish;
-		}
-	}
-
-	/* Only do these checks before calling the start function;
-	 * If anything goes wrong with the mapping while the kext is running,
-	 * we'll likely have panicked well before any attempt to stop the kext.
-	 */
-	if (startFlag) {
-		if (!isInFileset() || kc_type != KCKindPrimary) {
-			/*
-			 * Verify that the start/stop function is executable.
-			 */
-			kern_result = mach_vm_region_recurse(kernel_map, &address, &size, &depth,
-			    (vm_region_recurse_info_t)&info, &count);
-			if (kern_result != KERN_SUCCESS) {
-				OSKextLog(this,
-				    kOSKextLogErrorLevel |
-				    kOSKextLogLoadFlag,
-				    "Kext %s - bad %s pointer %p.",
-				    getIdentifierCString(),
-				    whichOp, (void *)ml_static_unslide(address));
-				result = kOSKextReturnBadData;
-				goto finish;
-			}
-		} else {
-			/*
-			 * Since kexts loaded from the primary KC are held in memory
-			 * allocated by efiboot, we cannot use mach_vm_region_recurse() to
-			 * discover that memory's protection flags.  Instead, we need to
-			 * get that information from the kernel pmap itself.  Above, we
-			 * (potentially) saved the size of the segment in which the address
-			 * in question was located.  If we have a non-zero size, verify
-			 * that all pages in the (address, address + kext_segsize) range
-			 * are marked executable.  If we somehow did not record the size
-			 * (or the base) just verify the single page that includes the address.
-			 */
-			if (kext_segbase == 0 || kext_segsize == 0) {
-				kext_segbase = address & ~(uint64_t)PAGE_MASK;
-				kext_segsize = PAGE_SIZE;
-			}
-		}
+    OSReturn                              result      = kOSReturnError;
+    const char                          * whichOp = startFlag ? "start" : "stop";
+    kern_return_t                         kern_result = 0;
+    vm_map_t                              kext_map    = NULL;
+    kernel_segment_command_t            * seg         = NULL;
+    mach_vm_address_t                     address     = 0;
+    mach_vm_size_t                        size        = 0;
+    uint32_t                              depth       = 0;
+    mach_msg_type_number_t                count;
+    vm_region_submap_short_info_data_64_t info;
+
+    count = VM_REGION_SUBMAP_SHORT_INFO_COUNT_64;
+    bzero(&info, sizeof(info));
+
+   // xxx - do we need a distinct OSReturn value for these or is "bad data"
+   // xxx - sufficient?
+
+   /* Verify that the kmod_info and start/stop pointers are non-NULL.
+    */
+    if (!kmod_info) {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogLoadFlag,
+            "Kext %s - NULL kmod_info pointer.",
+            getIdentifierCString());
+        result = kOSKextReturnBadData;
+        goto finish;
+    }
+
+    if (startFlag) {
+        address = (mach_vm_address_t)kmod_info->start;
+    } else {
+        address = (mach_vm_address_t)kmod_info->stop;
+    }
+
+    if (!address) {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogLoadFlag,
+            "Kext %s - NULL module %s pointer.",
+            getIdentifierCString(), whichOp);
+        result = kOSKextReturnBadData;
+        goto finish;
+    }
+
+    kext_map = kext_get_vm_map(kmod_info);
+    depth = (kernel_map == kext_map) ? 1 : 2;
+
+   /* Verify that the start/stop function lies within the kext's address range.
+    */
+    if (address < kmod_info->address + kmod_info->hdr_size ||
+        kmod_info->address + kmod_info->size <= address)
+    {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogLoadFlag,
+            "Kext %s module %s pointer is outside of kext range "
+            "(%s %p - kext at %p-%p)..",
+            getIdentifierCString(),
+            whichOp,
+            whichOp,
+            (void *)VM_KERNEL_UNSLIDE(address),
+            (void *)VM_KERNEL_UNSLIDE(kmod_info->address),
+            (void *)(VM_KERNEL_UNSLIDE(kmod_info->address) + kmod_info->size));
+        result = kOSKextReturnBadData;
+        goto finish;
+    }
+
+   /* Only do these checks before calling the start function;
+    * If anything goes wrong with the mapping while the kext is running,
+    * we'll likely have panicked well before any attempt to stop the kext.
+    */
+    if (startFlag) {
+
+       /* Verify that the start/stop function is executable.
+        */
+        kern_result = mach_vm_region_recurse(kernel_map, &address, &size, &depth,
+            (vm_region_recurse_info_t)&info, &count);
+        if (kern_result != KERN_SUCCESS) {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogLoadFlag,
+                "Kext %s - bad %s pointer %p.",
+                getIdentifierCString(),
+                whichOp, (void *)VM_KERNEL_UNSLIDE(address)); 
+            result = kOSKextReturnBadData;
+            goto finish;
+        }
 
 #if VM_MAPPED_KEXTS
-		if (((!isInFileset() || kc_type != KCKindPrimary) && !(info.protection & VM_PROT_EXECUTE)) ||
-		    ((isInFileset() && kc_type == KCKindPrimary) &&
-		    ml_static_verify_page_protections(kext_segbase, kext_segsize, VM_PROT_EXECUTE) != KERN_SUCCESS)) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogLoadFlag,
-			    "Kext %s - memory region containing module %s function "
-			    "is not executable.",
-			    getIdentifierCString(), whichOp);
-			result = kOSKextReturnBadData;
-			goto finish;
-		}
+        if (!(info.protection & VM_PROT_EXECUTE)) {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogLoadFlag,
+                "Kext %s - memory region containing module %s function "
+                "is not executable.",
+                getIdentifierCString(), whichOp);
+            result = kOSKextReturnBadData;
+            goto finish;
+        }
 #endif
 
-		/* Verify that the kext's segments are backed by physical memory.
-		 */
-		seg = firstsegfromheader((kernel_mach_header_t *)kmod_info->address);
-		while (seg) {
-			if (!verifySegmentMapping(seg)) {
-				result = kOSKextReturnBadData;
-				goto finish;
-			}
-
-			seg = nextsegfromheader((kernel_mach_header_t *) kmod_info->address, seg);
-		}
-	}
-
-	result = kOSReturnSuccess;
+       /* Verify that the kext's segments are backed by physical memory.
+        */
+        seg = firstsegfromheader((kernel_mach_header_t *)kmod_info->address);
+        while (seg) {
+            if (!verifySegmentMapping(seg)) {
+                result = kOSKextReturnBadData;
+                goto finish;
+            }
+
+            seg = nextsegfromheader((kernel_mach_header_t *) kmod_info->address, seg);
+        }
+
+    }
+
+    result = kOSReturnSuccess;
 finish:
-	return result;
+    return result;
 }
 
 /*********************************************************************
@@ -8320,67 +5796,26 @@
 boolean_t
 OSKext::verifySegmentMapping(kernel_segment_command_t *seg)
 {
-	mach_vm_address_t address = 0;
-
-	if (seg->vmsize > UINT32_MAX) {
-		return false;
-	}
-
-	if (!segmentShouldBeWired(seg)) {
-		return true;
-	}
-
-	for (address = seg->vmaddr;
-	    address < round_page(seg->vmaddr + seg->vmsize);
-	    address += PAGE_SIZE) {
-		if (!pmap_find_phys(kernel_pmap, (vm_offset_t)address)) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogLoadFlag,
-			    "Kext %s - page %p is not backed by physical memory.",
-			    getIdentifierCString(),
-			    (void *)address);
-			return false;
-		}
-	}
-
-	return true;
-}
-
-/*********************************************************************
-*********************************************************************/
-static void
-OSKextLogKextInfo(OSKext *aKext, uint64_t address, uint64_t size, firehose_tracepoint_code_t code)
-{
-	uint64_t                            stamp = 0;
-	firehose_tracepoint_id_u            trace_id;
-	struct firehose_trace_uuid_info_s   uuid_info_s;
-	firehose_trace_uuid_info_t          uuid_info = &uuid_info_s;
-	size_t                              uuid_info_len = sizeof(struct firehose_trace_uuid_info_s);
-	OSSharedPtr<OSData>                 uuid_data;
-
-	stamp = firehose_tracepoint_time(firehose_activity_flags_default);
-	trace_id.ftid_value = FIREHOSE_TRACE_ID_MAKE(firehose_tracepoint_namespace_metadata, _firehose_tracepoint_type_metadata_kext, (firehose_tracepoint_flags_t)0, code);
-
-	uuid_data = aKext->copyTextUUID();
-	if (uuid_data) {
-		memcpy(uuid_info->ftui_uuid, uuid_data->getBytesNoCopy(), sizeof(uuid_info->ftui_uuid));
-	}
-
-	uuid_info->ftui_size    = size;
-	if (aKext->isDriverKit()) {
-		uuid_info->ftui_address = address;
-	} else {
-		uuid_info->ftui_address = ml_static_unslide(address);
-	}
-	os_log_encoded_metadata(trace_id, stamp, uuid_info, uuid_info_len);
-	return;
-}
-
-void
-OSKext::OSKextLogDriverKitInfoLoad(OSKext *kext)
-{
-	OSKextLogKextInfo(kext, kext->getLoadTag(), 1, firehose_tracepoint_code_load);
+    mach_vm_address_t address = 0;
+
+    if (!segmentShouldBeWired(seg)) return true;
+
+    for (address = seg->vmaddr;
+         address < round_page(seg->vmaddr + seg->vmsize);
+         address += PAGE_SIZE)
+    {
+        if (!pmap_find_phys(kernel_pmap, (vm_offset_t)address)) {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogLoadFlag,
+                "Kext %s - page %p is not backed by physical memory.",
+                getIdentifierCString(), 
+                (void *)address);
+            return false;
+        }
+    }
+
+    return true;
 }
 
 /*********************************************************************
@@ -8388,158 +5823,178 @@
 OSReturn
 OSKext::start(bool startDependenciesFlag)
 {
-	OSReturn                            result = kOSReturnError;
-	kern_return_t                       (* startfunc)(kmod_info_t *, void *);
-	unsigned int                        i, count;
-	void                              * kmodStartData = NULL;
-
-	if (isStarted() || isInterface() || isKernelComponent()) {
-		result = kOSReturnSuccess;
-		goto finish;
-	}
-
-	if (!isLoaded()) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag,
-		    "Attempt to start nonloaded kext %s.",
-		    getIdentifierCString());
-		result = kOSKextReturnInvalidArgument;
-		goto finish;
-	}
-
-	if (!sLoadEnabled) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag,
-		    "Kext loading is disabled (attempt to start kext %s).",
-		    getIdentifierCString());
-		result = kOSKextReturnDisabled;
-		goto finish;
-	}
-
-	result = validateKextMapping(/* start? */ true);
-	if (result != kOSReturnSuccess) {
-		goto finish;
-	}
-
-	startfunc = kmod_info->start;
-
-	count = getNumDependencies();
-	for (i = 0; i < count; i++) {
-		OSKext * dependency = OSDynamicCast(OSKext, dependencies->getObject(i));
-		if (dependency == NULL) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogLoadFlag,
-			    "Kext %s start - internal error, dependency disappeared.",
-			    getIdentifierCString());
-			goto finish;
-		}
-		if (!dependency->isStarted()) {
-			if (startDependenciesFlag) {
-				OSReturn dependencyResult =
-				    dependency->start(startDependenciesFlag);
-				if (dependencyResult != KERN_SUCCESS) {
-					OSKextLog(this,
-					    kOSKextLogErrorLevel |
-					    kOSKextLogLoadFlag,
-					    "Kext %s start - dependency %s failed to start (error 0x%x).",
-					    getIdentifierCString(),
-					    dependency->getIdentifierCString(),
-					    dependencyResult);
-					goto finish;
-				}
-			} else {
-				OSKextLog(this,
-				    kOSKextLogErrorLevel |
-				    kOSKextLogLoadFlag,
-				    "Not starting %s - dependency %s not started yet.",
-				    getIdentifierCString(),
-				    dependency->getIdentifierCString());
-				result = kOSKextReturnStartStopError;         // xxx - make new return?
-				goto finish;
-			}
-		}
-	}
-
-	OSKextLog(this,
-	    kOSKextLogDetailLevel |
-	    kOSKextLogLoadFlag,
-	    "Kext %s calling module start function.",
-	    getIdentifierCString());
-
-	flags.starting = 1;
-
-	// Drop a log message so logd can grab the needed information to decode this kext
-	OSKextLogKextInfo(this, kmod_info->address, kmod_info->size, firehose_tracepoint_code_load);
-	result = OSRuntimeInitializeCPP(this);
-	if (result == KERN_SUCCESS) {
-		result = startfunc(kmod_info, kmodStartData);
-	}
-
-	flags.starting = 0;
-
-	/* On success overlap the setting of started/starting. On failure just
-	 * clear starting.
-	 */
-	if (result == KERN_SUCCESS) {
-		flags.started = 1;
-
-		// xxx - log start error from kernel?
-		OSKextLog(this,
-		    kOSKextLogProgressLevel |
-		    kOSKextLogLoadFlag,
-		    "Kext %s is now started.",
-		    getIdentifierCString());
-	} else {
-		invokeOrCancelRequestCallbacks(
-			/* result not actually used */ kOSKextReturnStartStopError,
-			/* invokeFlag */ false);
-		OSKextLog(this,
-		    kOSKextLogWarningLevel |
-		    kOSKextLogLoadFlag,
-		    "Kext %s did not start (return code 0x%x).",
-		    getIdentifierCString(), result);
-	}
+    OSReturn                            result = kOSReturnError;
+    kern_return_t                       (* startfunc)(kmod_info_t *, void *);
+    unsigned int                        i, count;
+    void                              * kmodStartData = NULL; 
+
+    if (isStarted() || isInterface() || isKernelComponent()) {
+        result = kOSReturnSuccess;
+        goto finish;
+    }
+
+    if (!isLoaded()) {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogLoadFlag,
+            "Attempt to start nonloaded kext %s.",
+            getIdentifierCString()); 
+        result = kOSKextReturnInvalidArgument;
+        goto finish;
+    }
+
+    if (!sLoadEnabled) {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogLoadFlag,
+            "Kext loading is disabled (attempt to start kext %s).",
+            getIdentifierCString());
+        result = kOSKextReturnDisabled;
+        goto finish;
+    }
+
+    result = validateKextMapping(/* start? */ true);
+    if (result != kOSReturnSuccess) {
+        goto finish;
+    }
+
+    startfunc = kmod_info->start;
+
+    count = getNumDependencies();
+    for (i = 0; i < count; i++) {
+        OSKext * dependency = OSDynamicCast(OSKext, dependencies->getObject(i));
+        if (dependency == NULL) {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogLoadFlag,
+                "Kext %s start - internal error, dependency disappeared.",
+                getIdentifierCString());
+            goto finish;
+        }
+        if (!dependency->isStarted()) {
+            if (startDependenciesFlag) {
+                OSReturn dependencyResult =
+                    dependency->start(startDependenciesFlag);
+                if (dependencyResult != KERN_SUCCESS) {
+                    OSKextLog(this,
+                        kOSKextLogErrorLevel |
+                        kOSKextLogLoadFlag,
+                        "Kext %s start - dependency %s failed to start (error 0x%x).",
+                        getIdentifierCString(),
+                        dependency->getIdentifierCString(),
+                        dependencyResult);
+                    goto finish;
+                }
+            } else {
+                OSKextLog(this,
+                    kOSKextLogErrorLevel |
+                    kOSKextLogLoadFlag,
+                    "Not starting %s - dependency %s not started yet.",
+                    getIdentifierCString(),
+                    dependency->getIdentifierCString());
+                result = kOSKextReturnStartStopError;  // xxx - make new return?
+                goto finish;
+            }
+        }
+    }
+
+    OSKextLog(this,
+        kOSKextLogDetailLevel |
+        kOSKextLogLoadFlag,
+        "Kext %s calling module start function.",
+        getIdentifierCString()); 
+
+    flags.starting = 1;
+
+#if !CONFIG_STATIC_CPPINIT
+    result = OSRuntimeInitializeCPP(kmod_info, NULL);
+    if (result == KERN_SUCCESS) {
+#endif
+
+#if CONFIG_KEC_FIPS
+        kmodStartData = GetAppleTEXTHashForKext(this, this->infoDict);
+        
+#if 0
+        if (kmodStartData) {
+            OSKextLog(this,
+                      kOSKextLogErrorLevel |
+                      kOSKextLogGeneralFlag,
+                      "Kext %s calling module start function. kmodStartData %p. arch %s",
+                      getIdentifierCString(), kmodStartData, ARCHNAME); 
+        }
+#endif
+#endif // CONFIG_KEC_FIPS 
+
+        result = startfunc(kmod_info, kmodStartData);
+
+#if !CONFIG_STATIC_CPPINIT
+        if (result != KERN_SUCCESS) {
+            (void) OSRuntimeFinalizeCPP(kmod_info, NULL);
+        }
+    }
+#endif
+
+    flags.starting = 0;
+
+   /* On success overlap the setting of started/starting. On failure just
+    * clear starting.
+    */
+    if (result == KERN_SUCCESS) {
+        flags.started = 1;
+
+        // xxx - log start error from kernel?
+        OSKextLog(this,
+            kOSKextLogProgressLevel |
+            kOSKextLogLoadFlag,
+            "Kext %s is now started.",
+            getIdentifierCString()); 
+    } else {
+        invokeOrCancelRequestCallbacks(
+            /* result not actually used */ kOSKextReturnStartStopError,
+            /* invokeFlag */ false);
+        OSKextLog(this,
+            kOSKextLogProgressLevel |
+            kOSKextLogLoadFlag,
+            "Kext %s did not start (return code 0x%x).",
+            getIdentifierCString(), result); 
+    }
 
 finish:
-	return result;
+    return result;
 }
 
 /*********************************************************************
 *********************************************************************/
 /* static */
-bool
-OSKext::canUnloadKextWithIdentifier(
-	OSString * kextIdentifier,
-	bool       checkClassesFlag)
-{
-	bool     result = false;
-	OSKext * aKext  = NULL;        // do not release
-
-	IORecursiveLockLock(sKextLock);
-
-	aKext = OSDynamicCast(OSKext, sKextsByID->getObject(kextIdentifier));
-
-	if (!aKext) {
-		goto finish;         // can't unload what's not loaded
-	}
-
-	if (aKext->isLoaded()) {
-		if (aKext->getRetainCount() > kOSKextMinLoadedRetainCount) {
-			goto finish;
-		}
-		if (checkClassesFlag && aKext->hasOSMetaClassInstances()) {
-			goto finish;
-		}
-	}
-
-	result = true;
+bool OSKext::canUnloadKextWithIdentifier(
+    OSString * kextIdentifier,
+    bool       checkClassesFlag)
+{
+    bool     result = false;
+    OSKext * aKext  = NULL;  // do not release
+
+    IORecursiveLockLock(sKextLock);
+
+    aKext = OSDynamicCast(OSKext, sKextsByID->getObject(kextIdentifier));
+
+    if (!aKext) {
+        goto finish;  // can't unload what's not loaded
+    }
+
+    if (aKext->isLoaded()) {
+        if (aKext->getRetainCount() > kOSKextMinLoadedRetainCount) {
+            goto finish;
+        }
+        if (checkClassesFlag && aKext->hasOSMetaClassInstances()) {
+            goto finish;
+        }
+    }
+
+    result = true;
 
 finish:
-	IORecursiveLockUnlock(sKextLock);
-	return result;
+    IORecursiveLockUnlock(sKextLock);
+    return result;
 }
 
 /*********************************************************************
@@ -8547,96 +6002,97 @@
 OSReturn
 OSKext::stop(void)
 {
-	OSReturn result = kOSReturnError;
-	kern_return_t (*stopfunc)(kmod_info_t *, void *);
-
-	if (!isStarted() || isInterface()) {
-		result = kOSReturnSuccess;
-		goto finish;
-	}
-
-	if (!isLoaded()) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag,
-		    "Attempt to stop nonloaded kext %s.",
-		    getIdentifierCString());
-		result = kOSKextReturnInvalidArgument;
-		goto finish;
-	}
-
-	/* Refuse to stop if we have clients or instances. It is up to
-	 * the caller to make sure those aren't true.
-	 */
-	if (getRetainCount() > kOSKextMinLoadedRetainCount) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag,
-		    "Kext %s - C++ instances; can't stop.",
-		    getIdentifierCString());
-		result = kOSKextReturnInUse;
-		goto finish;
-	}
-
-	if (getRetainCount() > kOSKextMinLoadedRetainCount) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag,
-		    "Kext %s - has references (linkage or tracking object); "
-		    "can't stop.",
-		    getIdentifierCString());
-		result = kOSKextReturnInUse;
-		goto finish;
-	}
-
-	/* Note: If validateKextMapping fails on the stop & unload path,
-	 * we are in serious trouble and a kernel panic is likely whether
-	 * we stop & unload the kext or not.
-	 */
-	result = validateKextMapping(/* start? */ false);
-	if (result != kOSReturnSuccess) {
-		goto finish;
-	}
-
-	stopfunc = kmod_info->stop;
-	if (stopfunc) {
-		OSKextLog(this,
-		    kOSKextLogDetailLevel |
-		    kOSKextLogLoadFlag,
-		    "Kext %s calling module stop function.",
-		    getIdentifierCString());
-
-		flags.stopping = 1;
-
-		result = stopfunc(kmod_info, /* userData */ NULL);
-		if (result == KERN_SUCCESS) {
-			result = OSRuntimeFinalizeCPP(this);
-		}
-
-		flags.stopping = 0;
-
-		if (result == KERN_SUCCESS) {
-			flags.started = 0;
-
-			OSKextLog(this,
-			    kOSKextLogDetailLevel |
-			    kOSKextLogLoadFlag,
-			    "Kext %s is now stopped and ready to unload.",
-			    getIdentifierCString());
-		} else {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogLoadFlag,
-			    "Kext %s did not stop (return code 0x%x).",
-			    getIdentifierCString(), result);
-			result = kOSKextReturnStartStopError;
-		}
-	}
+    OSReturn result = kOSReturnError;
+    kern_return_t (*stopfunc)(kmod_info_t *, void *);
+    
+    if (!isStarted() || isInterface()) {
+        result = kOSReturnSuccess;
+        goto finish;
+    }
+
+    if (!isLoaded()) {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogLoadFlag,
+            "Attempt to stop nonloaded kext %s.",
+            getIdentifierCString());
+        result = kOSKextReturnInvalidArgument;
+        goto finish;
+    }
+
+   /* Refuse to stop if we have clients or instances. It is up to
+    * the caller to make sure those aren't true.
+    */
+    if (getRetainCount() > kOSKextMinLoadedRetainCount) {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogLoadFlag,
+            "Kext %s - C++ instances; can't stop.",
+            getIdentifierCString());
+        result = kOSKextReturnInUse;
+        goto finish;
+    }
+
+    if (getRetainCount() > kOSKextMinLoadedRetainCount) {
+
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogLoadFlag,
+            "Kext %s - has references (linkage or tracking object); "
+            "can't stop.",
+            getIdentifierCString());
+        result = kOSKextReturnInUse;
+        goto finish;
+    }
+
+   /* Note: If validateKextMapping fails on the stop & unload path,
+    * we are in serious trouble and a kernel panic is likely whether
+    * we stop & unload the kext or not.
+    */
+    result = validateKextMapping(/* start? */ false);
+    if (result != kOSReturnSuccess) {
+        goto finish;
+    }
+
+    stopfunc = kmod_info->stop;
+    if (stopfunc) {
+        OSKextLog(this,
+            kOSKextLogDetailLevel |
+            kOSKextLogLoadFlag,
+            "Kext %s calling module stop function.",
+            getIdentifierCString()); 
+
+        flags.stopping = 1;
+
+        result = stopfunc(kmod_info, /* userData */ NULL);
+#if !CONFIG_STATIC_CPPINIT
+        if (result == KERN_SUCCESS) {
+            result = OSRuntimeFinalizeCPP(kmod_info, NULL);
+        }
+#endif
+
+        flags.stopping = 0;
+
+        if (result == KERN_SUCCESS) {
+            flags.started = 0;
+
+            OSKextLog(this,
+                kOSKextLogDetailLevel |
+                kOSKextLogLoadFlag,
+                "Kext %s is now stopped and ready to unload.",
+                getIdentifierCString()); 
+        } else {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogLoadFlag,
+                "Kext %s did not stop (return code 0x%x).",
+                getIdentifierCString(), result); 
+            result = kOSKextReturnStartStopError;
+        }
+    }
 
 finish:
-	// Drop a log message so logd can update this kext's metadata
-	OSKextLogKextInfo(this, kmod_info->address, kmod_info->size, firehose_tracepoint_code_unload);
-	return result;
+    return result;
 }
 
 /*********************************************************************
@@ -8644,317 +6100,261 @@
 OSReturn
 OSKext::unload(void)
 {
-	OSReturn        result = kOSReturnError;
-	unsigned int    index;
-	uint32_t        num_kmod_refs = 0;
-	OSKextAccount * freeAccount;
-	bool            in_fileset = false;
-
-	if (!sUnloadEnabled) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag,
-		    "Kext unloading is disabled (%s).",
-		    this->getIdentifierCString());
-
-		result = kOSKextReturnDisabled;
-		goto finish;
-	}
-
-	// cache this result so we don't need to access the kmod_info after
-	// it's been potentially free'd
-	in_fileset = isInFileset();
-
-	/* Refuse to unload if we have clients or instances. It is up to
-	 * the caller to make sure those aren't true.
-	 */
-	if (getRetainCount() > kOSKextMinLoadedRetainCount) {
-		// xxx - Don't log under errors? this is more of an info thing
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogKextBookkeepingFlag,
-		    "Can't unload kext %s; outstanding references %d (linkage or tracking object).",
-		    getIdentifierCString(), getRetainCount());
-		result = kOSKextReturnInUse;
-		goto finish;
-	}
-
-	if (isDriverKit()) {
-		index = sLoadedDriverKitKexts->getNextIndexOfObject(this, 0);
-		if (index != (unsigned int)-1) {
-			sLoadedDriverKitKexts->removeObject(index);
-			OSKextLogKextInfo(this, loadTag, 1, firehose_tracepoint_code_unload);
-			loadTag = 0;
-		}
-	}
-
-	if (!isLoaded()) {
-		result = kOSReturnSuccess;
-		goto finish;
-	}
-
-	if (isKernelComponent()) {
-		result = kOSKextReturnInvalidArgument;
-		goto finish;
-	}
-
-	if (metaClasses && !OSMetaClass::removeClasses(metaClasses.get())) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag | kOSKextLogKextBookkeepingFlag,
-		    "Can't unload kext %s; classes have instances:",
-		    getIdentifierCString());
-		reportOSMetaClassInstances(kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag | kOSKextLogKextBookkeepingFlag);
-		result = kOSKextReturnInUse;
-		goto finish;
-	}
-
-	/* Note that the kext is unloading before running any code that
-	 * might be in the kext (request callbacks, module stop function).
-	 * We will deny certain requests made against a kext in the process
-	 * of unloading.
-	 */
-	flags.unloading = 1;
-
-	/* Update the string describing the last kext to unload in case we panic.
-	 */
-	savePanicString(/* isLoading */ false);
-
-	if (isStarted()) {
-		result = stop();
-		if (result != KERN_SUCCESS) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogLoadFlag,
-			    "Kext %s can't unload - module stop returned 0x%x.",
-			    getIdentifierCString(), (unsigned)result);
-			result = kOSKextReturnStartStopError;
-			goto finish;
-		}
-	}
-
-	OSKextLog(this,
-	    kOSKextLogProgressLevel |
-	    kOSKextLogLoadFlag,
-	    "Kext %s unloading.",
-	    getIdentifierCString());
-
-	{
-		struct list_head *p;
-		struct list_head *prev;
-		struct list_head *next;
-		for (p = pendingPgoHead.next; p != &pendingPgoHead; p = next) {
-			OSKextGrabPgoStruct *s = container_of(p, OSKextGrabPgoStruct, list_head);
-			s->err = OSKextGrabPgoDataLocked(this, s->metadata, instance_uuid, s->pSize, s->pBuffer, s->bufferSize);
-			prev = p->prev;
-			next = p->next;
-			prev->next = next;
-			next->prev = prev;
-			p->prev = p;
-			p->next = p;
-			IORecursiveLockWakeup(sKextLock, s, false);
-		}
-	}
-
-
-	/* Even if we don't call the stop function, we want to be sure we
-	 * have no OSMetaClass references before unloading the kext executable
-	 * from memory. OSMetaClasses may have pointers into the kext executable
-	 * and that would cause a panic on OSKext::free() when metaClasses is freed.
-	 */
-	if (metaClasses) {
-		metaClasses->flushCollection();
-	}
-	(void) OSRuntimeFinalizeCPP(this);
-
-	/* Remove the kext from the list of loaded kexts, patch the gap
-	 * in the kmod_info_t linked list, and reset "kmod" to point to the
-	 * last loaded kext that isn't the fake kernel kext (sKernelKext).
-	 */
-	index = sLoadedKexts->getNextIndexOfObject(this, 0);
-	if (index != (unsigned int)-1) {
-		sLoadedKexts->removeObject(index);
-
-		OSKext * nextKext = OSDynamicCast(OSKext,
-		    sLoadedKexts->getObject(index));
-
-		if (nextKext) {
-			if (index > 0) {
-				OSKext * gapKext = OSDynamicCast(OSKext,
-				    sLoadedKexts->getObject(index - 1));
-
-				nextKext->kmod_info->next = gapKext->kmod_info;
-			} else {         /* index == 0 */
-				nextKext->kmod_info->next = NULL;
-			}
-		}
-
-		OSKext * lastKext = OSDynamicCast(OSKext, sLoadedKexts->getLastObject());
-		if (lastKext && !lastKext->isKernel()) {
-			kmod = lastKext->kmod_info;
-		} else {
-			kmod = NULL;         // clear the global kmod variable
-		}
-	}
-
-	/* Clear out the kmod references that we're keeping for compatibility
-	 * with current panic backtrace code & kgmacros.
-	 * xxx - will want to update those bits sometime and remove this.
-	 */
-	num_kmod_refs = getNumDependencies();
-	if (num_kmod_refs && kmod_info && kmod_info->reference_list) {
-		for (uint32_t refIndex = 0; refIndex < num_kmod_refs; refIndex++) {
-			kmod_reference_t * ref = &(kmod_info->reference_list[refIndex]);
-			ref->info->reference_count--;
-		}
-		kfree_type(kmod_reference_t, num_kmod_refs,
-		    kmod_info->reference_list);
-	}
+    OSReturn        result = kOSReturnError;
+    unsigned int    index;
+    uint32_t        num_kmod_refs = 0;
+    OSKextAccount * freeAccount;
+
+    if (!sUnloadEnabled) {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogLoadFlag,
+            "Kext unloading is disabled (%s).",
+            this->getIdentifierCString());
+
+        result = kOSKextReturnDisabled;
+        goto finish;
+    }
+
+   /* Refuse to unload if we have clients or instances. It is up to
+    * the caller to make sure those aren't true.
+    */
+    if (getRetainCount() > kOSKextMinLoadedRetainCount) {
+        // xxx - Don't log under errors? this is more of an info thing
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogKextBookkeepingFlag,
+            "Can't unload kext %s; outstanding references (linkage or tracking object).",
+            getIdentifierCString());
+        result = kOSKextReturnInUse;
+        goto finish;
+    }
+
+    if (hasOSMetaClassInstances()) {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogLoadFlag | kOSKextLogKextBookkeepingFlag,
+            "Can't unload kext %s; classes have instances:",
+            getIdentifierCString());
+        reportOSMetaClassInstances(kOSKextLogErrorLevel |
+            kOSKextLogLoadFlag | kOSKextLogKextBookkeepingFlag);
+        result = kOSKextReturnInUse;
+        goto finish;
+    }
+
+    if (!isLoaded()) {
+        result = kOSReturnSuccess;
+        goto finish;
+    }
+
+    if (isKernelComponent()) {
+        result = kOSKextReturnInvalidArgument;
+        goto finish;
+    }
+    
+   /* Note that the kext is unloading before running any code that
+    * might be in the kext (request callbacks, module stop function).
+    * We will deny certain requests made against a kext in the process
+    * of unloading.
+    */
+    flags.unloading = 1;
+
+   /* Update the string describing the last kext to unload in case we panic.
+    */
+    savePanicString(/* isLoading */ false);
+    
+    if (isStarted()) {
+        result = stop();
+        if (result != KERN_SUCCESS) {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogLoadFlag,
+                "Kext %s can't unload - module stop returned 0x%x.",
+                getIdentifierCString(), (unsigned)result);
+            result = kOSKextReturnStartStopError;
+            goto finish;
+        }
+    }
+
+    OSKextLog(this,
+        kOSKextLogProgressLevel |
+        kOSKextLogLoadFlag,
+        "Kext %s unloading.",
+        getIdentifierCString());
+
+    {
+        struct list_head *p;
+        struct list_head *prev;
+        struct list_head *next;
+        for (p = pendingPgoHead.next; p != &pendingPgoHead; p = next) {
+            OSKextGrabPgoStruct *s = container_of(p, OSKextGrabPgoStruct, list_head);
+            s->err = OSKextGrabPgoDataLocked(this, s->metadata, instance_uuid, s->pSize, s->pBuffer, s->bufferSize);
+            prev = p->prev;
+            next = p->next;
+            prev->next = next;
+            next->prev = prev;
+            p->prev = p;
+            p->next = p;
+            IORecursiveLockWakeup(sKextLock, s, false);
+        }
+    }
+
+
+   /* Even if we don't call the stop function, we want to be sure we
+    * have no OSMetaClass references before unloading the kext executable
+    * from memory. OSMetaClasses may have pointers into the kext executable
+    * and that would cause a panic on OSKext::free() when metaClasses is freed.
+    */
+    if (metaClasses) {
+        metaClasses->flushCollection();
+    }
+
+   /* Remove the kext from the list of loaded kexts, patch the gap
+    * in the kmod_info_t linked list, and reset "kmod" to point to the
+    * last loaded kext that isn't the fake kernel kext (sKernelKext).
+    */
+    index = sLoadedKexts->getNextIndexOfObject(this, 0);
+    if (index != (unsigned int)-1) {
+
+        sLoadedKexts->removeObject(index);
+
+        OSKext * nextKext = OSDynamicCast(OSKext,
+            sLoadedKexts->getObject(index));
+
+        if (nextKext) {
+            if (index > 0) {
+                OSKext * gapKext = OSDynamicCast(OSKext,
+                    sLoadedKexts->getObject(index - 1));
+                
+                nextKext->kmod_info->next = gapKext->kmod_info;
+
+            } else /* index == 0 */ {
+                nextKext->kmod_info->next = NULL;
+            }
+        }
+
+        OSKext * lastKext = OSDynamicCast(OSKext, sLoadedKexts->getLastObject());
+        if (lastKext && !lastKext->isKernel()) {
+            kmod = lastKext->kmod_info;
+        } else {
+            kmod = NULL;  // clear the global kmod variable
+        }
+    }
+
+   /* Clear out the kmod references that we're keeping for compatibility
+    * with current panic backtrace code & kgmacros.
+    * xxx - will want to update those bits sometime and remove this.
+    */
+    num_kmod_refs = getNumDependencies();
+    if (num_kmod_refs && kmod_info && kmod_info->reference_list) {
+        for (uint32_t refIndex = 0; refIndex < num_kmod_refs; refIndex++) {
+            kmod_reference_t * ref = &(kmod_info->reference_list[refIndex]);
+            ref->info->reference_count--;
+        }
+        kfree(kmod_info->reference_list,
+            num_kmod_refs * sizeof(kmod_reference_t));
+    }
 
 #if CONFIG_DTRACE
-	unregisterWithDTrace();
+    unregisterWithDTrace();
 #endif /* CONFIG_DTRACE */
 
-	notifyKextUnloadObservers(this);
-
-	freeAccount = NULL;
-	lck_ticket_lock(sKextAccountsLock, sKextAccountsLockGrp);
-	account->kext = NULL;
-	if (account->site.tag) {
-		account->site.flags |= VM_TAG_UNLOAD;
-	} else {
-		freeAccount = account;
-	}
-
-#if DEVELOPMENT || DEBUG
-	assertf(account->task_refgrp.grp_count == 0,
-	    "unloading a kext with active task references");
-#endif /* DEVELOPMENT || DEBUG */
-
-	lck_ticket_unlock(sKextAccountsLock);
-	if (freeAccount) {
-		IOFreeType(freeAccount, OSKextAccount);
-	}
-
-	/* Unwire and free the linked executable.
-	 */
-	if (linkedExecutable) {
-#if KASAN
-		kasan_unload_kext((vm_offset_t)linkedExecutable->getBytesNoCopy(), linkedExecutable->getLength());
+    notifyKextUnloadObservers(this);
+
+    freeAccount = NULL;
+    IOSimpleLockLock(sKextAccountsLock);
+    if (account->site.tag) account->site.flags |= VM_TAG_UNLOAD;
+    else                   freeAccount = account;
+    IOSimpleLockUnlock(sKextAccountsLock);
+    if (freeAccount) IODelete(freeAccount, OSKextAccount, 1);
+
+    /* Unwire and free the linked executable.
+     */
+    if (linkedExecutable) {
+#if VM_MAPPED_KEXTS
+        if (!isInterface()) {
+            kernel_segment_command_t *seg = NULL;
+            vm_map_t kext_map = kext_get_vm_map(kmod_info);
+
+            if (!kext_map) {
+                OSKextLog(this,
+                    kOSKextLogErrorLevel |
+                    kOSKextLogLoadFlag,
+                    "Failed to free kext %s; couldn't find the kext map.",
+                    getIdentifierCString());
+                result = kOSKextReturnInternalError;
+                goto finish;
+            }
+
+            OSKextLog(this,
+                kOSKextLogProgressLevel |
+                kOSKextLogLoadFlag,
+                "Kext %s unwiring and unmapping linked executable.",
+                getIdentifierCString());
+
+            seg = firstsegfromheader((kernel_mach_header_t *)kmod_info->address);
+            while (seg) {
+                if (segmentShouldBeWired(seg)) {
+                    result = vm_map_unwire(kext_map, seg->vmaddr, 
+                        seg->vmaddr + seg->vmsize, FALSE);
+                    if (result != KERN_SUCCESS) {
+                        OSKextLog(this,
+                            kOSKextLogErrorLevel |
+                            kOSKextLogLoadFlag,
+                            "Failed to unwire kext %s.",
+                            getIdentifierCString());
+                        result = kOSKextReturnInternalError;
+                        goto finish;
+                    }
+                }
+
+                seg = nextsegfromheader((kernel_mach_header_t *) kmod_info->address, seg);
+            }
+        }
 #endif
-
-#if VM_MAPPED_KEXTS
-		if (!isInterface() && (!in_fileset || flags.resetSegmentsFromVnode)) {
-			kernel_segment_command_t *seg = NULL;
-			vm_map_t kext_map = kext_get_vm_map(kmod_info);
-
-			if (!kext_map) {
-				OSKextLog(this,
-				    kOSKextLogErrorLevel |
-				    kOSKextLogLoadFlag,
-				    "Failed to free kext %s; couldn't find the kext map.",
-				    getIdentifierCString());
-				result = kOSKextReturnInternalError;
-				goto finish;
-			}
-
-			OSKextLog(this,
-			    kOSKextLogProgressLevel |
-			    kOSKextLogLoadFlag,
-			    "Kext %s unwiring and unmapping linked executable.",
-			    getIdentifierCString());
-
-			seg = firstsegfromheader((kernel_mach_header_t *)kmod_info->address);
-			while (seg) {
-				if (segmentShouldBeWired(seg)) {
-					vm_map_offset_t start_wire = trunc_page(seg->vmaddr);
-					vm_map_offset_t end_wire = round_page(seg->vmaddr + seg->vmsize);
-
-					result = vm_map_unwire(kext_map, start_wire,
-					    end_wire, FALSE);
-					if (result != KERN_SUCCESS) {
-						OSKextLog(this,
-						    kOSKextLogErrorLevel |
-						    kOSKextLogLoadFlag,
-						    "Failed to unwire kext %s.",
-						    getIdentifierCString());
-						result = kOSKextReturnInternalError;
-						goto finish;
-					}
-				}
-
-				seg = nextsegfromheader((kernel_mach_header_t *) kmod_info->address, seg);
-			}
-#if defined(__x86_64__) || defined(__i386__)
-			if (in_fileset && flags.resetSegmentsFromVnode) {
-				IORecursiveLockLock(sKextLock);
-				resetKCFileSetSegments();
-				IORecursiveLockUnlock(sKextLock);
-			}
-#endif // (__x86_64__) || defined(__i386__)
-		}
-#endif /* VM_MAPPED_KEXTS */
-		if (flags.resetSegmentsFromImmutableCopy) {
-			result = resetMutableSegments();
-			if (result != kOSReturnSuccess) {
-				OSKextLog(this,
-				    kOSKextLogErrorLevel |
-				    kOSKextLogLoadFlag,
-				    "Failed to reset kext %s.",
-				    getIdentifierCString());
-				result = kOSKextReturnInternalError;
-				goto finish;
-			}
-		}
-		if (kc_type == KCKindUnknown) {
-			linkedExecutable.reset();
-		}
-	}
-
-	/* An interface kext has a fake kmod_info that was allocated,
-	 * so we have to free it.
-	 */
-	if (isInterface()) {
-		kfree_type(kmod_info_t, kmod_info);
-		kmod_info = NULL;
-	}
-
-	if (!in_fileset) {
-		kmod_info = NULL;
-	}
-
-	flags.loaded = false;
-	flushDependencies();
-
-	/* save a copy of the bundle ID for us to check when deciding to
-	 * rebuild the kernel cache file.  If a kext was already in the kernel
-	 * cache and unloaded then later loaded we do not need to rebuild the
-	 * kernel cache.  9055303
-	 */
-	if (isPrelinked()) {
-		if (!_OSKextInUnloadedPrelinkedKexts(bundleID.get())) {
-			IORecursiveLockLock(sKextLock);
-			if (sUnloadedPrelinkedKexts) {
-				sUnloadedPrelinkedKexts->setObject(bundleID.get());
-			}
-			IORecursiveLockUnlock(sKextLock);
-		}
-	}
-
-	OSKextLog(this,
-	    kOSKextLogProgressLevel | kOSKextLogLoadFlag,
-	    "Kext %s unloaded.", getIdentifierCString());
-
-	queueKextNotification(kKextRequestPredicateUnloadNotification,
-	    OSDynamicCast(OSString, bundleID.get()), getDextUniqueID());
+        OSSafeReleaseNULL(linkedExecutable);
+    }
+
+   /* An interface kext has a fake kmod_info that was allocated,
+    * so we have to free it.
+    */
+    if (isInterface()) {
+        kfree(kmod_info, sizeof(kmod_info_t));
+    }
+
+    kmod_info = NULL;
+
+    flags.loaded = false;
+    flushDependencies();
+
+    /* save a copy of the bundle ID for us to check when deciding to 
+     * rebuild the kernel cache file.  If a kext was already in the kernel 
+     * cache and unloaded then later loaded we do not need to rebuild the 
+     * kernel cache.  9055303
+     */
+    if (isPrelinked()) {
+        if (!_OSKextInUnloadedPrelinkedKexts(bundleID)) {
+            IORecursiveLockLock(sKextLock);
+            if (sUnloadedPrelinkedKexts) {
+                sUnloadedPrelinkedKexts->setObject(bundleID);
+            }
+            IORecursiveLockUnlock(sKextLock);
+        }
+    }
+
+    OSKextLog(this,
+        kOSKextLogProgressLevel | kOSKextLogLoadFlag,
+        "Kext %s unloaded.", getIdentifierCString());
+
+    queueKextNotification(kKextRequestPredicateUnloadNotification,
+        OSDynamicCast(OSString, bundleID));
 
 finish:
-	OSKext::saveLoadedKextPanicList();
-	OSKext::updateLoadedKextSummaries();
-
-	flags.unloading = 0;
-	return result;
+    OSKext::saveLoadedKextPanicList();
+    OSKext::updateLoadedKextSummaries();
+
+    flags.unloading = 0;
+    return result;
 }
 
 /*********************************************************************
@@ -8963,95 +6363,88 @@
 /* static */
 OSReturn
 OSKext::queueKextNotification(
-	const char * notificationName,
-	OSString   * kextIdentifier,
-	OSData     * dextUniqueIdentifier)
-{
-	OSReturn          result               = kOSReturnError;
-	OSSharedPtr<OSDictionary>    loadRequest;
-
-	if (!kextIdentifier) {
-		result = kOSKextReturnInvalidArgument;
-		goto finish;
-	}
-
-	/* Create a new request unless one is already sitting
-	 * in sKernelRequests for this bundle identifier
-	 */
-	result = _OSKextCreateRequest(notificationName, loadRequest);
-	if (result != kOSReturnSuccess) {
-		goto finish;
-	}
-	if (!_OSKextSetRequestArgument(loadRequest.get(),
-	    kKextRequestArgumentBundleIdentifierKey, kextIdentifier)) {
-		result = kOSKextReturnNoMemory;
-		goto finish;
-	}
-	if (NULL != dextUniqueIdentifier) {
-		if (!_OSKextSetRequestArgument(loadRequest.get(),
-		    kKextRequestArgumentDriverUniqueIdentifier, dextUniqueIdentifier)) {
-			result = kOSKextReturnNoMemory;
-			goto finish;
-		}
-	}
-	if (!sKernelRequests->setObject(loadRequest.get())) {
-		result = kOSKextReturnNoMemory;
-		goto finish;
-	}
-
-	/* We might want to only queue the notification if the IOKit daemon is active,
-	 * but that wouldn't work for embedded. Note that we don't care if
-	 * the ping immediately succeeds here so don't do anything with the
-	 * result of this call.
-	 */
-	OSKext::pingIOKitDaemon();
-
-	result = kOSReturnSuccess;
+    const char * notificationName,
+    OSString   * kextIdentifier)
+{
+    OSReturn          result               = kOSReturnError;
+    OSDictionary    * loadRequest          = NULL;  // must release
+
+    if (!kextIdentifier) {
+        result = kOSKextReturnInvalidArgument;
+        goto finish;
+    }
+
+   /* Create a new request unless one is already sitting
+    * in sKernelRequests for this bundle identifier
+    */
+    result = _OSKextCreateRequest(notificationName, &loadRequest);
+    if (result != kOSReturnSuccess) {
+        goto finish;
+    }
+    if (!_OSKextSetRequestArgument(loadRequest,
+        kKextRequestArgumentBundleIdentifierKey, kextIdentifier)) {
+        
+        result = kOSKextReturnNoMemory;
+        goto finish;
+    }
+    if (!sKernelRequests->setObject(loadRequest)) {
+        result = kOSKextReturnNoMemory;
+        goto finish;
+    }
+
+   /* We might want to only queue the notification if kextd is active,
+    * but that wouldn't work for embedded. Note that we don't care if
+    * the ping immediately succeeds here so don't do anything with the
+    * result of this call.
+    */
+    OSKext::pingKextd();
+
+    result = kOSReturnSuccess;
 
 finish:
-	return result;
-}
-
-
-#if CONFIG_KXLD
+    OSSafeRelease(loadRequest);
+
+    return result;
+}
+
 /*********************************************************************
 *********************************************************************/
 static void
 _OSKextConsiderDestroyingLinkContext(
-	__unused thread_call_param_t p0,
-	__unused thread_call_param_t p1)
-{
-	/* Take multiple locks in the correct order.
-	 */
-	IORecursiveLockLock(sKextLock);
-	IORecursiveLockLock(sKextInnerLock);
-
-	/* The first time we destroy the kxldContext is in the first
-	 * OSKext::considerUnloads() call, which sets sConsiderUnloadsCalled
-	 * before calling this function. Thereafter any call to this function
-	 * will actually destroy the context.
-	 */
-	if (sConsiderUnloadsCalled && sKxldContext) {
-		kxld_destroy_context(sKxldContext);
-		sKxldContext = NULL;
-	}
-
-	/* Free the thread_call that was allocated to execute this function.
-	 */
-	if (sDestroyLinkContextThread) {
-		if (!thread_call_free(sDestroyLinkContextThread)) {
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogGeneralFlag,
-			    "thread_call_free() failed for kext link context.");
-		}
-		sDestroyLinkContextThread = NULL;
-	}
-
-	IORecursiveLockUnlock(sKextInnerLock);
-	IORecursiveLockUnlock(sKextLock);
-
-	return;
+    __unused thread_call_param_t p0,
+    __unused thread_call_param_t p1)
+{
+   /* Take multiple locks in the correct order.
+    */
+    IORecursiveLockLock(sKextLock);
+    IORecursiveLockLock(sKextInnerLock);
+
+   /* The first time we destroy the kxldContext is in the first 
+    * OSKext::considerUnloads() call, which sets sConsiderUnloadsCalled
+    * before calling this function. Thereafter any call to this function
+    * will actually destroy the context.
+    */
+    if (sConsiderUnloadsCalled && sKxldContext) {
+        kxld_destroy_context(sKxldContext);
+        sKxldContext = NULL;
+    }
+
+   /* Free the thread_call that was allocated to execute this function.
+    */
+    if (sDestroyLinkContextThread) {
+        if (!thread_call_free(sDestroyLinkContextThread)) {
+            OSKextLog(/* kext */ NULL,
+                kOSKextLogErrorLevel |
+                kOSKextLogGeneralFlag,
+                "thread_call_free() failed for kext link context.");
+        }
+        sDestroyLinkContextThread = 0;
+    }
+
+    IORecursiveLockUnlock(sKextInnerLock);
+    IORecursiveLockUnlock(sKextLock);
+
+    return;
 }
 
 /*********************************************************************
@@ -9067,44 +6460,33 @@
 void
 OSKext::considerDestroyingLinkContext(void)
 {
-	IORecursiveLockLock(sKextInnerLock);
-
-	/* If we have already queued a thread to destroy the link context,
-	 * don't bother resetting; that thread will take care of it.
-	 */
-	if (sDestroyLinkContextThread) {
-		goto finish;
-	}
-
-	/* The function to be invoked in the thread will deallocate
-	 * this thread_call, so don't share it around.
-	 */
-	sDestroyLinkContextThread = thread_call_allocate(
-		&_OSKextConsiderDestroyingLinkContext, NULL);
-	if (!sDestroyLinkContextThread) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel | kOSKextLogGeneralFlag | kOSKextLogLinkFlag,
-		    "Can't create thread to destroy kext link context.");
-		goto finish;
-	}
-
-	thread_call_enter(sDestroyLinkContextThread);
+    IORecursiveLockLock(sKextInnerLock);
+
+   /* If we have already queued a thread to destroy the link context,
+    * don't bother resetting; that thread will take care of it.
+    */
+    if (sDestroyLinkContextThread) {
+        goto finish;
+    }
+
+   /* The function to be invoked in the thread will deallocate
+    * this thread_call, so don't share it around.
+    */
+    sDestroyLinkContextThread = thread_call_allocate(
+        &_OSKextConsiderDestroyingLinkContext, 0);
+    if (!sDestroyLinkContextThread) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogErrorLevel | kOSKextLogGeneralFlag | kOSKextLogLinkFlag,
+            "Can't create thread to destroy kext link context.");
+        goto finish;
+    }
+
+    thread_call_enter(sDestroyLinkContextThread);
 
 finish:
-	IORecursiveLockUnlock(sKextInnerLock);
-	return;
-}
-
-#else // !CONFIG_KXLD
-
-/* static */
-void
-OSKext::considerDestroyingLinkContext(void)
-{
-	return;
-}
-
-#endif // CONFIG_KXLD
+    IORecursiveLockUnlock(sKextInnerLock);
+    return;
+}
 
 #if PRAGMA_MARK
 #pragma mark Autounload
@@ -9117,235 +6499,216 @@
 OSReturn
 OSKext::autounloadKext(OSKext * aKext)
 {
-	OSReturn result = kOSKextReturnInUse;
-
-#if NO_KEXTD
-	/*
-	 * Do not unload prelinked kexts on platforms that do not have an
-	 * IOKit daemon as there is no way to reload the kext or restart
-	 * matching.
-	 */
-	if (aKext->isPrelinked()) {
-		goto finish;
-	}
-#endif /* defined(__x86_64__) */
-
-	/* Check for external references to this kext (usu. dependents),
-	 * instances of defined classes (or classes derived from them),
-	 * outstanding requests.
-	 */
-	if ((aKext->getRetainCount() > kOSKextMinLoadedRetainCount) ||
-	    !aKext->flags.autounloadEnabled ||
-	    aKext->isKernelComponent()) {
-		goto finish;
-	}
-
-	/* Skip a delay-autounload kext, once.
-	 */
-	if (aKext->flags.delayAutounload) {
-		OSKextLog(aKext,
-		    kOSKextLogProgressLevel |
-		    kOSKextLogLoadFlag | kOSKextLogKextBookkeepingFlag,
-		    "Kext %s has delayed autounload set; skipping and clearing flag.",
-		    aKext->getIdentifierCString());
-		aKext->flags.delayAutounload = 0;
-		goto finish;
-	}
-
-	if (aKext->hasOSMetaClassInstances() ||
-	    aKext->countRequestCallbacks()) {
-		goto finish;
-	}
-
-	result = OSKext::removeKext(aKext);
+    OSReturn result = kOSKextReturnInUse;
+
+   /* Check for external references to this kext (usu. dependents),
+    * instances of defined classes (or classes derived from them),
+    * outstanding requests.
+    */
+    if ((aKext->getRetainCount() > kOSKextMinLoadedRetainCount) ||
+        !aKext->flags.autounloadEnabled ||
+        aKext->isKernelComponent()) {
+
+        goto finish;
+    }
+
+   /* Skip a delay-autounload kext, once.
+    */
+    if (aKext->flags.delayAutounload) {
+        OSKextLog(aKext,
+            kOSKextLogProgressLevel |
+            kOSKextLogLoadFlag | kOSKextLogKextBookkeepingFlag,
+            "Kext %s has delayed autounload set; skipping and clearing flag.",
+            aKext->getIdentifierCString());
+        aKext->flags.delayAutounload = 0;
+        goto finish;
+    }
+
+    if (aKext->hasOSMetaClassInstances() ||
+        aKext->countRequestCallbacks()) {
+        goto finish;
+    }
+
+    result = OSKext::removeKext(aKext);
 
 finish:
-	return result;
-}
-
+    return result;
+}
+    
 /*********************************************************************
 *********************************************************************/
 void
 _OSKextConsiderUnloads(
-	__unused thread_call_param_t p0,
-	__unused thread_call_param_t p1)
-{
-	bool         didUnload = false;
-	unsigned int count, i;
-
-	/* Take multiple locks in the correct order
-	 * (note also sKextSummaries lock further down).
-	 */
-	IORecursiveLockLock(sKextLock);
-	IORecursiveLockLock(sKextInnerLock);
-
-	OSKext::flushNonloadedKexts(/* flushPrelinkedKexts */ true);
-
-	/* If the system is powering down, don't try to unload anything.
-	 */
-	if (sSystemSleep) {
-		goto finish;
-	}
-
-	OSKextLog(/* kext */ NULL,
-	    kOSKextLogProgressLevel | kOSKextLogLoadFlag,
-	    "Checking for unused kexts to autounload.");
-
-	/*****
-	 * Remove any request callbacks marked as stale,
-	 * and mark as stale any currently in flight.
-	 */
-	count = sRequestCallbackRecords->getCount();
-	if (count) {
-		i = count - 1;
-		do {
-			OSDictionary * callbackRecord = OSDynamicCast(OSDictionary,
-			    sRequestCallbackRecords->getObject(i));
-			if (callbackRecord) {
-				OSBoolean * stale = OSDynamicCast(OSBoolean,
-				    callbackRecord->getObject(kKextRequestStaleKey));
-
-				if (stale == kOSBooleanTrue) {
-					OSKext::invokeRequestCallback(callbackRecord,
-					    kOSKextReturnTimeout);
-				} else {
-					callbackRecord->setObject(kKextRequestStaleKey,
-					    kOSBooleanTrue);
-				}
-			}
-		} while (i--);
-	}
-
-	/*****
-	 * Make multiple passes through the array of loaded kexts until
-	 * we don't unload any. This handles unwinding of dependency
-	 * chains. We have to go *backwards* through the array because
-	 * kexts are removed from it when unloaded, and we cannot make
-	 * a copy or we'll mess up the retain counts we rely on to
-	 * check whether a kext will unload. If only we could have
-	 * nonretaining collections like CF has....
-	 */
-	do {
-		didUnload = false;
-
-		count = sLoadedKexts->getCount();
-		if (count) {
-			i = count - 1;
-			do {
-				OSKext * thisKext = OSDynamicCast(OSKext,
-				    sLoadedKexts->getObject(i));
-				didUnload |= (kOSReturnSuccess == OSKext::autounloadKext(thisKext));
-			} while (i--);
-		}
-	} while (didUnload);
+    __unused thread_call_param_t p0,
+    __unused thread_call_param_t p1)
+{
+    bool         didUnload = false;
+    unsigned int count, i;
+
+   /* Take multiple locks in the correct order
+    * (note also sKextSummaries lock further down).
+    */
+    IORecursiveLockLock(sKextLock);
+    IORecursiveLockLock(sKextInnerLock);
+
+    OSKext::flushNonloadedKexts(/* flushPrelinkedKexts */ true);
+    
+   /* If the system is powering down, don't try to unload anything.
+    */
+    if (sSystemSleep) {
+        goto finish;
+    }
+
+    OSKextLog(/* kext */ NULL,
+              kOSKextLogProgressLevel | kOSKextLogLoadFlag,
+              "Checking for unused kexts to autounload.");
+
+   /*****
+    * Remove any request callbacks marked as stale,
+    * and mark as stale any currently in flight.
+    */
+    count = sRequestCallbackRecords->getCount();
+    if (count) {
+        i = count - 1;
+        do {
+            OSDictionary * callbackRecord = OSDynamicCast(OSDictionary,
+                sRequestCallbackRecords->getObject(i));
+            OSBoolean * stale = OSDynamicCast(OSBoolean,
+                callbackRecord->getObject(kKextRequestStaleKey));
+            
+            if (stale == kOSBooleanTrue) {
+                OSKext::invokeRequestCallback(callbackRecord,
+                    kOSKextReturnTimeout);
+            } else {
+                callbackRecord->setObject(kKextRequestStaleKey,
+                    kOSBooleanTrue);
+            }
+        } while (i--);
+    }
+
+   /*****
+    * Make multiple passes through the array of loaded kexts until
+    * we don't unload any. This handles unwinding of dependency
+    * chains. We have to go *backwards* through the array because
+    * kexts are removed from it when unloaded, and we cannot make
+    * a copy or we'll mess up the retain counts we rely on to
+    * check whether a kext will unload. If only we could have
+    * nonretaining collections like CF has....
+    */
+    do {
+        didUnload = false;
+        
+        count = sLoadedKexts->getCount();
+        if (count) {
+            i = count - 1;
+            do {
+                OSKext * thisKext = OSDynamicCast(OSKext,
+                                                  sLoadedKexts->getObject(i));
+                didUnload |= (kOSReturnSuccess == OSKext::autounloadKext(thisKext));
+            } while (i--);
+        }
+    } while (didUnload);
 
 finish:
-	sConsiderUnloadsPending = false;
-	sConsiderUnloadsExecuted = true;
-
-	(void) OSKext::considerRebuildOfPrelinkedKernel();
-
-	IORecursiveLockUnlock(sKextInnerLock);
-	IORecursiveLockUnlock(sKextLock);
-
-	return;
+    sConsiderUnloadsPending = false;
+    sConsiderUnloadsExecuted = true;
+
+    (void) OSKext::considerRebuildOfPrelinkedKernel();
+    
+    IORecursiveLockUnlock(sKextInnerLock);
+    IORecursiveLockUnlock(sKextLock);
+
+    return;
 }
 
 /*********************************************************************
 * Do not call any function that takes sKextLock here!
 *********************************************************************/
-void
-OSKext::considerUnloads(Boolean rescheduleOnlyFlag)
-{
-	AbsoluteTime when;
-
-	IORecursiveLockLock(sKextInnerLock);
-
-	if (!sUnloadCallout) {
-		sUnloadCallout = thread_call_allocate(&_OSKextConsiderUnloads, NULL);
-	}
-
-	/* we only reset delay value for unloading if we already have something
-	 * pending.  rescheduleOnlyFlag should not start the count down.
-	 */
-	if (rescheduleOnlyFlag && !sConsiderUnloadsPending) {
-		goto finish;
-	}
-
-	thread_call_cancel(sUnloadCallout);
-	if (OSKext::getAutounloadEnabled() && !sSystemSleep
-#if !NO_KEXTD
-	    && sIOKitDaemonActive
-#endif
-	    ) {
-		clock_interval_to_deadline(sConsiderUnloadDelay,
-		    1000 * 1000 * 1000, &when);
-
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogProgressLevel |
-		    kOSKextLogLoadFlag,
-		    "%scheduling %sscan for unused kexts in %lu seconds.",
-		    sConsiderUnloadsPending ? "Res" : "S",
-		    sConsiderUnloadsCalled ? "" : "initial ",
-		    (unsigned long)sConsiderUnloadDelay);
-
-		sConsiderUnloadsPending = true;
-		thread_call_enter_delayed(sUnloadCallout, when);
-	}
+void OSKext::considerUnloads(Boolean rescheduleOnlyFlag)
+{
+    AbsoluteTime when;
+
+    IORecursiveLockLock(sKextInnerLock);
+
+    if (!sUnloadCallout) {
+        sUnloadCallout = thread_call_allocate(&_OSKextConsiderUnloads, 0);
+    }
+
+    /* we only reset delay value for unloading if we already have something
+     * pending.  rescheduleOnlyFlag should not start the count down.
+     */
+    if (rescheduleOnlyFlag && !sConsiderUnloadsPending) {
+        goto finish;
+    }
+
+    thread_call_cancel(sUnloadCallout);
+    if (OSKext::getAutounloadEnabled() && !sSystemSleep) {
+        clock_interval_to_deadline(sConsiderUnloadDelay,
+            1000 * 1000 * 1000, &when);
+
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogProgressLevel |
+            kOSKextLogLoadFlag,
+            "%scheduling %sscan for unused kexts in %lu seconds.",
+            sConsiderUnloadsPending ? "Res" : "S",
+            sConsiderUnloadsCalled ? "" : "initial ",
+            (unsigned long)sConsiderUnloadDelay);
+
+        sConsiderUnloadsPending = true;
+        thread_call_enter_delayed(sUnloadCallout, when);
+    }
 
 finish:
-	/* The kxld context should be reused throughout boot.  We mark the end of
-	 * period as the first time considerUnloads() is called, and we destroy
-	 * the first kxld context in that function.  Afterwards, it will be
-	 * destroyed in flushNonloadedKexts.
-	 */
-	if (!sConsiderUnloadsCalled) {
-		sConsiderUnloadsCalled = true;
-		OSKext::considerDestroyingLinkContext();
-	}
-
-	IORecursiveLockUnlock(sKextInnerLock);
-	return;
+   /* The kxld context should be reused throughout boot.  We mark the end of
+    * period as the first time considerUnloads() is called, and we destroy
+    * the first kxld context in that function.  Afterwards, it will be
+    * destroyed in flushNonloadedKexts.
+    */
+    if (!sConsiderUnloadsCalled) {
+        sConsiderUnloadsCalled = true;
+        OSKext::considerDestroyingLinkContext();
+    }
+
+    IORecursiveLockUnlock(sKextInnerLock);
+    return;
 }
 
 /*********************************************************************
 * Do not call any function that takes sKextLock here!
 *********************************************************************/
 extern "C" {
-IOReturn OSKextSystemSleepOrWake(UInt32 messageType);
-IOReturn
-OSKextSystemSleepOrWake(UInt32 messageType)
-{
-	IORecursiveLockLock(sKextInnerLock);
-
-	/* If the system is going to sleep, cancel the reaper thread timer,
-	 * and note that we're in a sleep state in case it just fired but hasn't
-	 * taken the lock yet. If we are coming back from sleep, just
-	 * clear the sleep flag; IOService's normal operation will cause
-	 * unloads to be considered soon enough.
-	 */
-	if (messageType == kIOMessageSystemWillSleep) {
-		if (sUnloadCallout) {
-			thread_call_cancel(sUnloadCallout);
-		}
-		sSystemSleep = true;
-		AbsoluteTime_to_scalar(&sLastWakeTime) = 0;
-	} else if (messageType == kIOMessageSystemHasPoweredOn) {
-		sSystemSleep = false;
-		clock_get_uptime(&sLastWakeTime);
-	}
-	IORecursiveLockUnlock(sKextInnerLock);
-
-	return kIOReturnSuccess;
-}
+
+IOReturn OSKextSystemSleepOrWake(UInt32 messageType)
+{
+    IORecursiveLockLock(sKextInnerLock);
+
+   /* If the system is going to sleep, cancel the reaper thread timer,
+    * and note that we're in a sleep state in case it just fired but hasn't
+    * taken the lock yet. If we are coming back from sleep, just
+    * clear the sleep flag; IOService's normal operation will cause
+    * unloads to be considered soon enough.
+    */
+    if (messageType == kIOMessageSystemWillSleep) {
+        if (sUnloadCallout) {
+            thread_call_cancel(sUnloadCallout);
+        }
+        sSystemSleep = true;
+        AbsoluteTime_to_scalar(&sLastWakeTime) = 0;
+    } else if (messageType == kIOMessageSystemHasPoweredOn) {
+        sSystemSleep = false;
+        clock_get_uptime(&sLastWakeTime);
+   }
+    IORecursiveLockUnlock(sKextInnerLock);
+
+    return kIOReturnSuccess;
+}
+
 };
 
 
 #if PRAGMA_MARK
 #pragma mark Prelinked Kernel
 #endif
-
-#ifdef CONFIG_KXLD
 /*********************************************************************
 * Do not access sConsiderUnloads... variables other than
 * sConsiderUnloadsExecuted in this function. They are guarded by a
@@ -9355,128 +6718,119 @@
 void
 OSKext::considerRebuildOfPrelinkedKernel(void)
 {
-	static bool     requestedPrelink        = false;
-	OSReturn        checkResult             = kOSReturnError;
-	OSSharedPtr<OSDictionary>         prelinkRequest;
-	OSSharedPtr<OSCollectionIterator> kextIterator;
-	const OSSymbol * thisID                 = NULL;        // do not release
-	bool            doRebuild               = false;
-	AbsoluteTime    my_abstime;
-	UInt64          my_ns;
-	SInt32          delta_secs;
-
-	/* Only one auto rebuild per boot and only on boot from prelinked kernel */
-	if (requestedPrelink || !sPrelinkBoot) {
-		return;
-	}
-
-	/* no direct return from this point */
-	IORecursiveLockLock(sKextLock);
-
-	/* We need to wait for the IOKit daemon to get up and running with unloads already done
-	 * and any new startup kexts loaded.
-	 */
-	if (!sConsiderUnloadsExecuted ||
-	    !sDeferredLoadSucceeded) {
-		goto finish;
-	}
-
-	/* we really only care about boot / system start up related kexts so bail
-	 * if we're here after REBUILD_MAX_TIME.
-	 */
-	if (!_OSKextInPrelinkRebuildWindow()) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogArchiveFlag,
-		    "%s prebuild rebuild has expired",
-		    __FUNCTION__);
-		requestedPrelink = true;
-		goto finish;
-	}
-
-	/* we do not want to trigger a rebuild if we get here too close to waking
-	 * up.  (see radar 10233768)
-	 */
-	IORecursiveLockLock(sKextInnerLock);
-
-	clock_get_uptime(&my_abstime);
-	delta_secs = MINIMUM_WAKEUP_SECONDS + 1;
-	if (AbsoluteTime_to_scalar(&sLastWakeTime) != 0) {
-		SUB_ABSOLUTETIME(&my_abstime, &sLastWakeTime);
-		absolutetime_to_nanoseconds(my_abstime, &my_ns);
-		delta_secs = (SInt32)(my_ns / NSEC_PER_SEC);
-	}
-	IORecursiveLockUnlock(sKextInnerLock);
-
-	if (delta_secs < MINIMUM_WAKEUP_SECONDS) {
-		/* too close to time of last wake from sleep */
-		goto finish;
-	}
-	requestedPrelink = true;
-
-	/* Now it's time to see if we have a reason to rebuild.  We may have done
-	 * some loads and unloads but the kernel cache didn't actually change.
-	 * We will rebuild if any kext is not marked prelinked AND is not in our
-	 * list of prelinked kexts that got unloaded.  (see radar 9055303)
-	 */
-	kextIterator = OSCollectionIterator::withCollection(sKextsByID.get());
-	if (!kextIterator) {
-		goto finish;
-	}
-
-	while ((thisID = OSDynamicCast(OSSymbol, kextIterator->getNextObject()))) {
-		OSKext *    thisKext;        // do not release
-
-		thisKext = OSDynamicCast(OSKext, sKextsByID->getObject(thisID));
-		if (!thisKext || thisKext->isPrelinked() || thisKext->isKernel()) {
-			continue;
-		}
-
-		if (_OSKextInUnloadedPrelinkedKexts(thisKext->bundleID.get())) {
-			continue;
-		}
-		/* kext is loaded and was not in current kernel cache so let's rebuild
-		 */
-		doRebuild = true;
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogArchiveFlag,
-		    "considerRebuildOfPrelinkedKernel %s triggered rebuild",
-		    thisKext->bundleID->getCStringNoCopy());
-		break;
-	}
-	sUnloadedPrelinkedKexts->flushCollection();
-
-	if (!doRebuild) {
-		goto finish;
-	}
-
-	checkResult = _OSKextCreateRequest(kKextRequestPredicateRequestPrelink,
-	    prelinkRequest);
-	if (checkResult != kOSReturnSuccess) {
-		goto finish;
-	}
-
-	if (!sKernelRequests->setObject(prelinkRequest.get())) {
-		goto finish;
-	}
-
-	OSKext::pingIOKitDaemon();
-
+    static bool     requestedPrelink        = false;
+    OSReturn        checkResult             = kOSReturnError;
+    OSDictionary *  prelinkRequest          = NULL;  // must release
+    OSCollectionIterator * kextIterator     = NULL;  // must release
+    const OSSymbol * thisID                 = NULL;  // do not release
+    bool            doRebuild               = false;
+    AbsoluteTime    my_abstime;
+    UInt64          my_ns;
+    SInt32          delta_secs;
+    
+    /* Only one auto rebuild per boot and only on boot from prelinked kernel */
+    if (requestedPrelink || !sPrelinkBoot) {
+        return;
+    }
+    
+    /* no direct return from this point */
+    IORecursiveLockLock(sKextLock);
+    
+    /* We need to wait for kextd to get up and running with unloads already done
+     * and any new startup kexts loaded.   
+     */
+    if (!sConsiderUnloadsExecuted ||
+        !sDeferredLoadSucceeded) {
+        goto finish;
+    }
+    
+    /* we really only care about boot / system start up related kexts so bail 
+     * if we're here after REBUILD_MAX_TIME.
+     */
+    if (!_OSKextInPrelinkRebuildWindow()) {
+        OSKextLog(/* kext */ NULL,
+                  kOSKextLogArchiveFlag,
+                  "%s prebuild rebuild has expired",
+                  __FUNCTION__);
+        requestedPrelink = true;
+        goto finish;
+    }
+    
+    /* we do not want to trigger a rebuild if we get here too close to waking
+     * up.  (see radar 10233768)
+     */
+    IORecursiveLockLock(sKextInnerLock);
+    
+    clock_get_uptime(&my_abstime);
+    delta_secs = MINIMUM_WAKEUP_SECONDS + 1;
+    if (AbsoluteTime_to_scalar(&sLastWakeTime) != 0) {
+        SUB_ABSOLUTETIME(&my_abstime, &sLastWakeTime);
+        absolutetime_to_nanoseconds(my_abstime, &my_ns);
+        delta_secs = (SInt32)(my_ns / NSEC_PER_SEC);
+    }
+    IORecursiveLockUnlock(sKextInnerLock);
+    
+    if (delta_secs < MINIMUM_WAKEUP_SECONDS) {
+        /* too close to time of last wake from sleep */
+        goto finish;
+    }
+    requestedPrelink = true;
+    
+    /* Now it's time to see if we have a reason to rebuild.  We may have done 
+     * some loads and unloads but the kernel cache didn't actually change.
+     * We will rebuild if any kext is not marked prelinked AND is not in our
+     * list of prelinked kexts that got unloaded.  (see radar 9055303)
+     */
+    kextIterator = OSCollectionIterator::withCollection(sKextsByID);
+    if (!kextIterator) {
+        goto finish;
+    }
+    
+    while ((thisID = OSDynamicCast(OSSymbol, kextIterator->getNextObject()))) {
+        OSKext *    thisKext;  // do not release
+        
+        thisKext = OSDynamicCast(OSKext, sKextsByID->getObject(thisID));
+        if (!thisKext || thisKext->isPrelinked() || thisKext->isKernel()) {
+            continue;
+        }
+        
+        if (_OSKextInUnloadedPrelinkedKexts(thisKext->bundleID)) {
+            continue;
+        }
+        /* kext is loaded and was not in current kernel cache so let's rebuild
+         */
+        doRebuild = true;
+        OSKextLog(/* kext */ NULL,
+                  kOSKextLogArchiveFlag,
+                  "considerRebuildOfPrelinkedKernel %s triggered rebuild",
+                  thisKext->bundleID->getCStringNoCopy());
+        break;
+    }
+    sUnloadedPrelinkedKexts->flushCollection();
+    
+    if (!doRebuild) {
+        goto finish;
+    }
+    
+    checkResult = _OSKextCreateRequest(kKextRequestPredicateRequestPrelink,
+                                       &prelinkRequest);
+    if (checkResult != kOSReturnSuccess) {
+        goto finish;
+    }
+    
+    if (!sKernelRequests->setObject(prelinkRequest)) {
+        goto finish;
+    }
+    
+    OSKext::pingKextd();
+    
 finish:
-	IORecursiveLockUnlock(sKextLock);
-
-	return;
-}
-
-#else /* !CONFIG_KXLD */
-
-void
-OSKext::considerRebuildOfPrelinkedKernel(void)
-{
-	/* in a non-dynamic kext loading world, there is never a reason to rebuild */
-	return;
-}
-
-#endif /* CONFIG_KXLD */
+    IORecursiveLockUnlock(sKextLock);
+    OSSafeRelease(prelinkRequest);
+    OSSafeRelease(kextIterator);
+    
+    return;
+}
 
 #if PRAGMA_MARK
 #pragma mark Dependencies
@@ -9485,400 +6839,398 @@
 *********************************************************************/
 bool
 OSKext::resolveDependencies(
-	OSArray * loopStack)
-{
-	bool                   result                   = false;
-	OSSharedPtr<OSArray>   localLoopStack;
-	bool                   addedToLoopStack         = false;
-	OSDictionary         * libraries                = NULL;        // do not release
-	OSSharedPtr<OSCollectionIterator> libraryIterator;
-	OSString             * libraryID                = NULL;        // do not release
-	OSKext               * libraryKext              = NULL;        // do not release
-	bool                   hasRawKernelDependency   = false;
-	bool                   hasKernelDependency      = false;
-	bool                   hasKPIDependency         = false;
-	bool                   hasPrivateKPIDependency  = false;
-	unsigned int           count;
-
-#if CONFIG_KXLD
-	OSString             * infoString               = NULL;        // do not release
-	OSString             * readableString           = NULL;        // do not release
-#endif // CONFIG_KXLD
-
-	/* A kernel component will automatically have this flag set,
-	 * and a loaded kext should also have it set (as should all its
-	 * loaded dependencies).
-	 */
-	if (flags.hasAllDependencies) {
-		result = true;
-		goto finish;
-	}
-
-	/* Check for loops in the dependency graph.
-	 */
-	if (loopStack) {
-		if (loopStack->getNextIndexOfObject(this, 0) != (unsigned int)-1) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogDependenciesFlag,
-			    "Kext %s has a dependency loop; can't resolve dependencies.",
-			    getIdentifierCString());
-			goto finish;
-		}
-	} else {
-		OSKextLog(this,
-		    kOSKextLogStepLevel |
-		    kOSKextLogDependenciesFlag,
-		    "Kext %s resolving dependencies.",
-		    getIdentifierCString());
-
-		localLoopStack = OSArray::withCapacity(6);         // any small capacity will do
-		if (!localLoopStack) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogDependenciesFlag,
-			    "Kext %s can't create bookkeeping stack to resolve dependencies.",
-			    getIdentifierCString());
-			goto finish;
-		}
-		loopStack = localLoopStack.get();
-	}
-	if (!loopStack->setObject(this)) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogDependenciesFlag,
-		    "Kext %s - internal error resolving dependencies.",
-		    getIdentifierCString());
-		goto finish;
-	}
-	addedToLoopStack = true;
-
-	/* Purge any existing kexts in the dependency list and start over.
-	 */
-	flushDependencies();
-	if (dependencies) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogDependenciesFlag,
-		    "Kext %s - internal error resolving dependencies.",
-		    getIdentifierCString());
-	}
-
-	libraries = OSDynamicCast(OSDictionary,
-	    getPropertyForHostArch(kOSBundleLibrariesKey));
-	if (libraries == NULL || libraries->getCount() == 0) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogValidationFlag | kOSKextLogDependenciesFlag,
-		    "Kext %s - can't resolve dependencies; %s missing/invalid type.",
-		    getIdentifierCString(), kOSBundleLibrariesKey);
-		goto finish;
-	}
-
-	/* Make a new array to hold the dependencies (flush freed the old one).
-	 */
-	dependencies = OSArray::withCapacity(libraries->getCount());
-	if (!dependencies) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogDependenciesFlag,
-		    "Kext %s - can't allocate dependencies array.",
-		    getIdentifierCString());
-		goto finish;
-	}
-
-	// xxx - compat: We used to add an implicit dependency on kernel 6.0
-	// xxx - compat: if none were declared.
-
-	libraryIterator = OSCollectionIterator::withCollection(libraries);
-	if (!libraryIterator) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogDependenciesFlag,
-		    "Kext %s - can't allocate dependencies iterator.",
-		    getIdentifierCString());
-		goto finish;
-	}
-
-	while ((libraryID = OSDynamicCast(OSString,
-	    libraryIterator->getNextObject()))) {
-		const char * library_id = libraryID->getCStringNoCopy();
-
-		OSString * libraryVersion = OSDynamicCast(OSString,
-		    libraries->getObject(libraryID));
-		if (libraryVersion == NULL) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogValidationFlag | kOSKextLogDependenciesFlag,
-			    "Kext %s - illegal type in OSBundleLibraries.",
-			    getIdentifierCString());
-			goto finish;
-		}
-
-		OSKextVersion libraryVers =
-		    OSKextParseVersionString(libraryVersion->getCStringNoCopy());
-		if (libraryVers == -1) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogValidationFlag | kOSKextLogDependenciesFlag,
-			    "Kext %s - invalid library version %s.",
-			    getIdentifierCString(),
-			    libraryVersion->getCStringNoCopy());
-			goto finish;
-		}
-
-		libraryKext = OSDynamicCast(OSKext, sKextsByID->getObject(libraryID));
-		if (libraryKext == NULL) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogDependenciesFlag,
-			    "Kext %s - library kext %s not found.",
-			    getIdentifierCString(), library_id);
-			goto finish;
-		}
-
-		if (!libraryKext->isCompatibleWithVersion(libraryVers)) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogDependenciesFlag,
-			    "Kext %s - library kext %s not compatible "
-			    "with requested version %s.",
-			    getIdentifierCString(), library_id,
-			    libraryVersion->getCStringNoCopy());
-			goto finish;
-		}
-
-		/* If a nonprelinked library somehow got into the mix for a
-		 * prelinked kext, at any point in the chain, we must fail
-		 * because the prelinked relocs for the library will be all wrong.
-		 */
-		if (this->isPrelinked() &&
-		    libraryKext->declaresExecutable() &&
-		    !libraryKext->isPrelinked()) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogDependenciesFlag,
-			    "Kext %s (prelinked) - library kext %s (v%s) not prelinked.",
-			    getIdentifierCString(), library_id,
-			    libraryVersion->getCStringNoCopy());
-			goto finish;
-		}
-
-		if (!libraryKext->resolveDependencies(loopStack)) {
-			goto finish;
-		}
-
-		/* Add the library directly only if it has an executable to link.
-		 * Otherwise it's just used to collect other dependencies, so put
-		 * *its* dependencies on the list for this kext.
-		 */
-		// xxx - We are losing info here; would like to make fake entries or
-		// xxx - keep these in the dependency graph for loaded kexts.
-		// xxx - I really want to make kernel components not a special case!
-		if (libraryKext->declaresExecutable() ||
-		    libraryKext->isInterface()) {
-			if (dependencies->getNextIndexOfObject(libraryKext, 0) == (unsigned)-1) {
-				dependencies->setObject(libraryKext);
-
-				OSKextLog(this,
-				    kOSKextLogDetailLevel |
-				    kOSKextLogDependenciesFlag,
-				    "Kext %s added dependency %s.",
-				    getIdentifierCString(),
-				    libraryKext->getIdentifierCString());
-			}
-		} else {
-			int       numLibDependencies  = libraryKext->getNumDependencies();
-			OSArray * libraryDependencies = libraryKext->getDependencies();
-			int       index;
-
-			if (numLibDependencies) {
-				// xxx - this msg level should be 1 lower than the per-kext one
-				OSKextLog(this,
-				    kOSKextLogDetailLevel |
-				    kOSKextLogDependenciesFlag,
-				    "Kext %s pulling %d dependencies from codeless library %s.",
-				    getIdentifierCString(),
-				    numLibDependencies,
-				    libraryKext->getIdentifierCString());
-			}
-			for (index = 0; index < numLibDependencies; index++) {
-				OSKext * thisLibDependency = OSDynamicCast(OSKext,
-				    libraryDependencies->getObject(index));
-				if (dependencies->getNextIndexOfObject(thisLibDependency, 0) == (unsigned)-1) {
-					dependencies->setObject(thisLibDependency);
-					OSKextLog(this,
-					    kOSKextLogDetailLevel |
-					    kOSKextLogDependenciesFlag,
-					    "Kext %s added dependency %s from codeless library %s.",
-					    getIdentifierCString(),
-					    thisLibDependency->getIdentifierCString(),
-					    libraryKext->getIdentifierCString());
-				}
-			}
-		}
-
-		if ((strlen(library_id) == strlen(KERNEL_LIB)) &&
-		    0 == strncmp(library_id, KERNEL_LIB, sizeof(KERNEL_LIB) - 1)) {
-			hasRawKernelDependency = true;
-		} else if (STRING_HAS_PREFIX(library_id, KERNEL_LIB_PREFIX)) {
-			hasKernelDependency = true;
-		} else if (STRING_HAS_PREFIX(library_id, KPI_LIB_PREFIX)) {
-			hasKPIDependency = true;
-			if (!strncmp(library_id, PRIVATE_KPI, sizeof(PRIVATE_KPI) - 1)) {
-				hasPrivateKPIDependency = true;
-			}
-		}
-	}
-
-	if (hasRawKernelDependency) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogValidationFlag | kOSKextLogDependenciesFlag,
-		    "Error - kext %s declares a dependency on %s, which is not permitted.",
-		    getIdentifierCString(), KERNEL_LIB);
-		goto finish;
-	}
+    OSArray * loopStack)
+{
+    bool                   result                   = false;
+    OSArray              * localLoopStack           = NULL;   // must release
+    bool                   addedToLoopStack         = false;
+    OSDictionary         * libraries                = NULL;   // do not release
+    OSCollectionIterator * libraryIterator          = NULL;   // must release
+    OSString             * libraryID                = NULL;   // do not release
+    OSString             * infoString               = NULL;   // do not release
+    OSString             * readableString           = NULL;   // do not release
+    OSKext               * libraryKext              = NULL;   // do not release
+    bool                   hasRawKernelDependency   = false;
+    bool                   hasKernelDependency      = false;
+    bool                   hasKPIDependency         = false;
+    bool                   hasPrivateKPIDependency  = false;
+    unsigned int           count;
+
+   /* A kernel component will automatically have this flag set,
+    * and a loaded kext should also have it set (as should all its
+    * loaded dependencies).
+    */
+    if (flags.hasAllDependencies) {
+        result = true;
+        goto finish;
+    }
+
+   /* Check for loops in the dependency graph.
+    */
+    if (loopStack) {
+        if (loopStack->getNextIndexOfObject(this, 0) != (unsigned int)-1) {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogDependenciesFlag,
+                "Kext %s has a dependency loop; can't resolve dependencies.",
+                getIdentifierCString());
+            goto finish;
+        }
+    } else {
+        OSKextLog(this,
+            kOSKextLogStepLevel |
+            kOSKextLogDependenciesFlag,
+            "Kext %s resolving dependencies.",
+            getIdentifierCString());
+
+        loopStack = OSArray::withCapacity(6);  // any small capacity will do
+        if (!loopStack) {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogDependenciesFlag,
+                "Kext %s can't create bookkeeping stack to resolve dependencies.",
+                getIdentifierCString());
+            goto finish;
+        }
+        localLoopStack = loopStack;
+    }
+    if (!loopStack->setObject(this)) {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogDependenciesFlag,
+            "Kext %s - internal error resolving dependencies.",
+            getIdentifierCString());
+        goto finish;
+    }
+    addedToLoopStack = true;
+
+   /* Purge any existing kexts in the dependency list and start over.
+    */
+    flushDependencies();
+    if (dependencies) {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogDependenciesFlag,
+            "Kext %s - internal error resolving dependencies.",
+            getIdentifierCString());
+    }
+
+    libraries = OSDynamicCast(OSDictionary,
+        getPropertyForHostArch(kOSBundleLibrariesKey));
+    if (libraries == NULL || libraries->getCount() == 0) {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogValidationFlag | kOSKextLogDependenciesFlag,
+            "Kext %s - can't resolve dependencies; %s missing/invalid type.",
+            getIdentifierCString(), kOSBundleLibrariesKey);
+        goto finish;
+    }
+
+   /* Make a new array to hold the dependencies (flush freed the old one).
+    */
+    dependencies = OSArray::withCapacity(libraries->getCount());
+    if (!dependencies) {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogDependenciesFlag,
+            "Kext %s - can't allocate dependencies array.",
+            getIdentifierCString());
+        goto finish;
+    }
+
+    // xxx - compat: We used to add an implicit dependency on kernel 6.0
+    // xxx - compat: if none were declared.
+
+    libraryIterator = OSCollectionIterator::withCollection(libraries);
+    if (!libraryIterator) {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogDependenciesFlag,
+            "Kext %s - can't allocate dependencies iterator.",
+            getIdentifierCString());
+        goto finish;
+    }
+    
+    while ((libraryID = OSDynamicCast(OSString,
+           libraryIterator->getNextObject()))) {
+           
+       const char * library_id = libraryID->getCStringNoCopy();
+
+        OSString * libraryVersion = OSDynamicCast(OSString,
+            libraries->getObject(libraryID));
+        if (libraryVersion == NULL) {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogValidationFlag | kOSKextLogDependenciesFlag,
+                "Kext %s - illegal type in OSBundleLibraries.",
+                getIdentifierCString());
+            goto finish;
+        }
+        
+        OSKextVersion libraryVers =
+            OSKextParseVersionString(libraryVersion->getCStringNoCopy());
+        if (libraryVers == -1) {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogValidationFlag | kOSKextLogDependenciesFlag,
+                "Kext %s - invalid library version %s.",
+                getIdentifierCString(),
+                libraryVersion->getCStringNoCopy());
+            goto finish;
+        }
+
+        libraryKext = OSDynamicCast(OSKext, sKextsByID->getObject(libraryID));
+        if (libraryKext == NULL) {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogDependenciesFlag,
+                "Kext %s - library kext %s not found.",
+                getIdentifierCString(), library_id);
+            goto finish;
+        }
+        
+        if (!libraryKext->isCompatibleWithVersion(libraryVers)) {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogDependenciesFlag,
+                "Kext %s - library kext %s not compatible "
+                "with requested version %s.",
+                getIdentifierCString(), library_id,
+                libraryVersion->getCStringNoCopy());
+            goto finish;
+        }
+
+       /* If a nonprelinked library somehow got into the mix for a
+        * prelinked kext, at any point in the chain, we must fail
+        * because the prelinked relocs for the library will be all wrong.
+        */
+        if (this->isPrelinked() &&
+            libraryKext->declaresExecutable() &&
+            !libraryKext->isPrelinked()) {
+
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogDependenciesFlag,
+                "Kext %s (prelinked) - library kext %s (v%s) not prelinked.",
+                getIdentifierCString(), library_id,
+                libraryVersion->getCStringNoCopy());
+            goto finish;
+        }
+
+        if (!libraryKext->resolveDependencies(loopStack)) {
+            goto finish;
+        }
+
+       /* Add the library directly only if it has an executable to link.
+        * Otherwise it's just used to collect other dependencies, so put
+        * *its* dependencies on the list for this kext.
+        */
+        // xxx - We are losing info here; would like to make fake entries or
+        // xxx - keep these in the dependency graph for loaded kexts.
+        // xxx - I really want to make kernel components not a special case!
+        if (libraryKext->declaresExecutable() ||
+            libraryKext->isInterface()) {
+
+            if (dependencies->getNextIndexOfObject(libraryKext, 0) == (unsigned)-1) {
+                dependencies->setObject(libraryKext);
+
+                OSKextLog(this,
+                    kOSKextLogDetailLevel |
+                    kOSKextLogDependenciesFlag,
+                    "Kext %s added dependency %s.",
+                    getIdentifierCString(),
+                    libraryKext->getIdentifierCString());
+            }
+        } else {
+            int       numLibDependencies  = libraryKext->getNumDependencies();
+            OSArray * libraryDependencies = libraryKext->getDependencies();
+            int       index;
+
+            if (numLibDependencies) {
+                // xxx - this msg level should be 1 lower than the per-kext one
+                OSKextLog(this,
+                    kOSKextLogDetailLevel |
+                    kOSKextLogDependenciesFlag,
+                    "Kext %s pulling %d dependencies from codeless library %s.",
+                    getIdentifierCString(),
+                    numLibDependencies,
+                    libraryKext->getIdentifierCString());
+            }
+            for (index = 0; index < numLibDependencies; index++) {
+                OSKext * thisLibDependency = OSDynamicCast(OSKext,
+                    libraryDependencies->getObject(index));
+                if (dependencies->getNextIndexOfObject(thisLibDependency, 0) == (unsigned)-1) {
+                    dependencies->setObject(thisLibDependency);
+                    OSKextLog(this,
+                        kOSKextLogDetailLevel |
+                        kOSKextLogDependenciesFlag,
+                        "Kext %s added dependency %s from codeless library %s.",
+                        getIdentifierCString(),
+                        thisLibDependency->getIdentifierCString(),
+                        libraryKext->getIdentifierCString());
+                }
+            }
+        }
+
+        if ((strlen(library_id) == strlen(KERNEL_LIB)) &&
+            0 == strncmp(library_id, KERNEL_LIB, sizeof(KERNEL_LIB)-1)) {
+
+            hasRawKernelDependency = true;
+        } else if (STRING_HAS_PREFIX(library_id, KERNEL_LIB_PREFIX)) {
+            hasKernelDependency = true;
+        } else if (STRING_HAS_PREFIX(library_id, KPI_LIB_PREFIX)) {
+            hasKPIDependency = true;
+            if (!strncmp(library_id, PRIVATE_KPI, sizeof(PRIVATE_KPI)-1)) {
+                hasPrivateKPIDependency = true;
+            }
+        }
+    }
+    
+    if (hasRawKernelDependency) {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogValidationFlag | kOSKextLogDependenciesFlag,
+            "Error - kext %s declares a dependency on %s, which is not permitted.",
+            getIdentifierCString(), KERNEL_LIB);
+        goto finish;
+    }
 #if __LP64__
-	if (hasKernelDependency) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogValidationFlag | kOSKextLogDependenciesFlag,
-		    "Error - kext %s declares %s dependencies. "
-		    "Only %s* dependencies are supported for 64-bit kexts.",
-		    getIdentifierCString(), KERNEL_LIB, KPI_LIB_PREFIX);
-		goto finish;
-	}
-	if (!hasKPIDependency) {
-		OSKextLog(this,
-		    kOSKextLogWarningLevel |
-		    kOSKextLogDependenciesFlag,
-		    "Warning - kext %s declares no %s* dependencies. "
-		    "If it uses any KPIs, the link may fail with undefined symbols.",
-		    getIdentifierCString(), KPI_LIB_PREFIX);
-	}
+    if (hasKernelDependency) {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogValidationFlag | kOSKextLogDependenciesFlag,
+            "Error - kext %s declares %s dependencies. "
+            "Only %s* dependencies are supported for 64-bit kexts.",
+            getIdentifierCString(), KERNEL_LIB, KPI_LIB_PREFIX);
+        goto finish;
+    }
+    if (!hasKPIDependency) {
+        OSKextLog(this,
+            kOSKextLogWarningLevel |
+            kOSKextLogDependenciesFlag,
+            "Warning - kext %s declares no %s* dependencies. "
+            "If it uses any KPIs, the link may fail with undefined symbols.",
+            getIdentifierCString(), KPI_LIB_PREFIX);
+    }
 #else /* __LP64__ */
-	// xxx - will change to flatly disallow "kernel" dependencies at some point
-	// xxx - is it invalid to do both "com.apple.kernel" and any
-	// xxx - "com.apple.kernel.*"?
-
-	if (hasKernelDependency && hasKPIDependency) {
-		OSKextLog(this,
-		    kOSKextLogWarningLevel |
-		    kOSKextLogDependenciesFlag,
-		    "Warning - kext %s has immediate dependencies on both "
-		    "%s* and %s* components; use only one style.",
-		    getIdentifierCString(), KERNEL_LIB, KPI_LIB_PREFIX);
-	}
-
-	if (!hasKernelDependency && !hasKPIDependency) {
-		// xxx - do we want to use validation flag for these too?
-		OSKextLog(this,
-		    kOSKextLogWarningLevel |
-		    kOSKextLogDependenciesFlag,
-		    "Warning - %s declares no kernel dependencies; using %s.",
-		    getIdentifierCString(), KERNEL6_LIB);
-		OSKext * kernelKext = OSDynamicCast(OSKext,
-		    sKextsByID->getObject(KERNEL6_LIB));
-		if (kernelKext) {
-			dependencies->setObject(kernelKext);
-		} else {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogDependenciesFlag,
-			    "Error - Library %s not found for %s.",
-			    KERNEL6_LIB, getIdentifierCString());
-		}
-	}
-
-	/* If the kext doesn't have a raw kernel or KPI dependency, then add all of
-	 * its indirect dependencies to simulate old-style linking.  XXX - Should
-	 * check for duplicates.
-	 */
-	if (!hasKPIDependency) {
-		unsigned int i;
-
-		flags.hasBleedthrough = true;
-
-		count = getNumDependencies();
-
-		/* We add to the dependencies array in this loop, but do not iterate
-		 * past its original count.
-		 */
-		for (i = 0; i < count; i++) {
-			OSKext * dependencyKext = OSDynamicCast(OSKext,
-			    dependencies->getObject(i));
-			dependencyKext->addBleedthroughDependencies(dependencies.get());
-		}
-	}
+    // xxx - will change to flatly disallow "kernel" dependencies at some point
+    // xxx - is it invalid to do both "com.apple.kernel" and any
+    // xxx - "com.apple.kernel.*"?
+
+    if (hasKernelDependency && hasKPIDependency) {
+        OSKextLog(this,
+            kOSKextLogWarningLevel |
+            kOSKextLogDependenciesFlag,
+            "Warning - kext %s has immediate dependencies on both "
+            "%s* and %s* components; use only one style.",
+            getIdentifierCString(), KERNEL_LIB, KPI_LIB_PREFIX);
+    }
+
+    if (!hasKernelDependency && !hasKPIDependency) {
+        // xxx - do we want to use validation flag for these too?
+        OSKextLog(this,
+            kOSKextLogWarningLevel |
+            kOSKextLogDependenciesFlag,
+            "Warning - %s declares no kernel dependencies; using %s.",
+            getIdentifierCString(), KERNEL6_LIB);
+        OSKext * kernelKext = OSDynamicCast(OSKext,
+            sKextsByID->getObject(KERNEL6_LIB));
+        if (kernelKext) {
+            dependencies->setObject(kernelKext);
+        } else {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogDependenciesFlag,
+                "Error - Library %s not found for %s.",
+                KERNEL6_LIB, getIdentifierCString());
+        }
+    }
+
+   /* If the kext doesn't have a raw kernel or KPI dependency, then add all of
+    * its indirect dependencies to simulate old-style linking.  XXX - Should
+    * check for duplicates.
+    */
+    if (!hasKPIDependency) {
+        unsigned int i;
+
+        flags.hasBleedthrough = true;
+
+        count = getNumDependencies();
+        
+       /* We add to the dependencies array in this loop, but do not iterate
+        * past its original count.
+        */
+        for (i = 0; i < count; i++) {
+            OSKext * dependencyKext = OSDynamicCast(OSKext,
+                dependencies->getObject(i));
+            dependencyKext->addBleedthroughDependencies(dependencies);
+        }
+    }
 #endif /* __LP64__ */
 
-#if CONFIG_KXLD
-	/*
-	 * If we're not dynamically linking kexts, then we don't need to check
-	 * copyright strings. The linker in user space has already done this.
-	 */
-	if (hasPrivateKPIDependency) {
-		bool hasApplePrefix = false;
-		bool infoCopyrightIsValid = false;
-		bool readableCopyrightIsValid = false;
-
-		hasApplePrefix = STRING_HAS_PREFIX(getIdentifierCString(),
-		    APPLE_KEXT_PREFIX);
-
-		infoString = OSDynamicCast(OSString,
-		    getPropertyForHostArch("CFBundleGetInfoString"));
-		if (infoString) {
-			infoCopyrightIsValid =
-			    kxld_validate_copyright_string(infoString->getCStringNoCopy());
-		}
-
-		readableString = OSDynamicCast(OSString,
-		    getPropertyForHostArch("NSHumanReadableCopyright"));
-		if (readableString) {
-			readableCopyrightIsValid =
-			    kxld_validate_copyright_string(readableString->getCStringNoCopy());
-		}
-
-		if (!hasApplePrefix || (!infoCopyrightIsValid && !readableCopyrightIsValid)) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogDependenciesFlag,
-			    "Error - kext %s declares a dependency on %s. "
-			    "Only Apple kexts may declare a dependency on %s.",
-			    getIdentifierCString(), PRIVATE_KPI, PRIVATE_KPI);
-			goto finish;
-		}
-	}
-#endif // CONFIG_KXLD
-
-	result = true;
-	flags.hasAllDependencies = 1;
+    if (hasPrivateKPIDependency) {
+        bool hasApplePrefix = false;
+        bool infoCopyrightIsValid = false;
+        bool readableCopyrightIsValid = false;
+        
+        hasApplePrefix = STRING_HAS_PREFIX(getIdentifierCString(), 
+            APPLE_KEXT_PREFIX);
+
+        infoString = OSDynamicCast(OSString,  
+            getPropertyForHostArch("CFBundleGetInfoString"));
+        if (infoString) {
+            infoCopyrightIsValid = 
+                kxld_validate_copyright_string(infoString->getCStringNoCopy());
+        }
+
+        readableString = OSDynamicCast(OSString,
+            getPropertyForHostArch("NSHumanReadableCopyright"));
+        if (readableString) {
+            readableCopyrightIsValid = 
+                kxld_validate_copyright_string(readableString->getCStringNoCopy());
+        }
+
+        if (!hasApplePrefix || (!infoCopyrightIsValid && !readableCopyrightIsValid)) {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogDependenciesFlag,
+                "Error - kext %s declares a dependency on %s. "
+                  "Only Apple kexts may declare a dependency on %s.",
+                  getIdentifierCString(), PRIVATE_KPI, PRIVATE_KPI);
+            goto finish;
+        }
+    }
+
+    result = true;
+    flags.hasAllDependencies = 1;
 
 finish:
 
-	if (addedToLoopStack) {
-		count = loopStack->getCount();
-		if (count > 0 && (this == loopStack->getObject(count - 1))) {
-			loopStack->removeObject(count - 1);
-		} else {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogDependenciesFlag,
-			    "Kext %s - internal error resolving dependencies.",
-			    getIdentifierCString());
-		}
-	}
-
-	if (result && localLoopStack) {
-		OSKextLog(this,
-		    kOSKextLogStepLevel |
-		    kOSKextLogDependenciesFlag,
-		    "Kext %s successfully resolved dependencies.",
-		    getIdentifierCString());
-	}
-
-	return result;
+    if (addedToLoopStack) {
+        count = loopStack->getCount();
+        if (count > 0 && (this == loopStack->getObject(count - 1))) {
+            loopStack->removeObject(count - 1);            
+        } else {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogDependenciesFlag,
+                "Kext %s - internal error resolving dependencies.",
+                getIdentifierCString());
+        }
+    }
+    
+    if (result && localLoopStack) {
+        OSKextLog(this,
+            kOSKextLogStepLevel |
+            kOSKextLogDependenciesFlag,
+            "Kext %s successfully resolved dependencies.",
+            getIdentifierCString());
+    }
+
+    OSSafeRelease(localLoopStack);
+    OSSafeRelease(libraryIterator);
+
+    return result;
 }
 
 /*********************************************************************
@@ -9886,34 +7238,35 @@
 bool
 OSKext::addBleedthroughDependencies(OSArray * anArray)
 {
-	bool result = false;
-	unsigned int dependencyIndex, dependencyCount;
-
-	dependencyCount = getNumDependencies();
-
-	for (dependencyIndex = 0;
-	    dependencyIndex < dependencyCount;
-	    dependencyIndex++) {
-		OSKext * dependency = OSDynamicCast(OSKext,
-		    dependencies->getObject(dependencyIndex));
-		if (!dependency) {
-			OSKextLog(this,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogDependenciesFlag,
-			    "Kext %s - internal error propagating compatibility dependencies.",
-			    getIdentifierCString());
-			goto finish;
-		}
-		if (anArray->getNextIndexOfObject(dependency, 0) == (unsigned int)-1) {
-			anArray->setObject(dependency);
-		}
-		dependency->addBleedthroughDependencies(anArray);
-	}
-
-	result = true;
+    bool result = false;
+    unsigned int dependencyIndex, dependencyCount;
+    
+    dependencyCount = getNumDependencies();
+
+    for (dependencyIndex = 0;
+         dependencyIndex < dependencyCount;
+         dependencyIndex++) {
+
+        OSKext * dependency = OSDynamicCast(OSKext,
+            dependencies->getObject(dependencyIndex));
+        if (!dependency) {
+            OSKextLog(this,
+                kOSKextLogErrorLevel |
+                kOSKextLogDependenciesFlag,
+                "Kext %s - internal error propagating compatibility dependencies.",
+                getIdentifierCString());
+            goto finish;
+        }
+        if (anArray->getNextIndexOfObject(dependency, 0) == (unsigned int)-1) {
+            anArray->setObject(dependency);
+        }
+        dependency->addBleedthroughDependencies(anArray);
+    }
+
+    result = true;
 
 finish:
-	return result;
+    return result;
 }
 
 /*********************************************************************
@@ -9921,28 +7274,29 @@
 bool
 OSKext::flushDependencies(bool forceFlag)
 {
-	bool result = false;
-
-	/* Only clear the dependencies if the kext isn't loaded;
-	 * we need the info for loaded kexts to track references.
-	 */
-	if (!isLoaded() || forceFlag) {
-		if (dependencies) {
-			// xxx - check level
-			OSKextLog(this,
-			    kOSKextLogProgressLevel |
-			    kOSKextLogDependenciesFlag,
-			    "Kext %s flushing dependencies.",
-			    getIdentifierCString());
-			dependencies.reset();
-		}
-		if (!isKernelComponent()) {
-			flags.hasAllDependencies = 0;
-		}
-		result = true;
-	}
-
-	return result;
+    bool result = false;
+
+   /* Only clear the dependencies if the kext isn't loaded;
+    * we need the info for loaded kexts to track references.
+    */
+    if (!isLoaded() || forceFlag) {
+        if (dependencies) {
+            // xxx - check level
+            OSKextLog(this,
+                kOSKextLogProgressLevel |
+                kOSKextLogDependenciesFlag,
+                "Kext %s flushing dependencies.",
+                getIdentifierCString());
+            OSSafeReleaseNULL(dependencies);
+
+        }
+        if (!isKernelComponent()) {
+            flags.hasAllDependencies = 0;
+        }
+        result = true;
+    }
+
+    return result;
 }
 
 /*********************************************************************
@@ -9950,10 +7304,10 @@
 uint32_t
 OSKext::getNumDependencies(void)
 {
-	if (!dependencies) {
-		return 0;
-	}
-	return dependencies->getCount();
+    if (!dependencies) {
+        return 0;
+    }
+    return dependencies->getCount();
 }
 
 /*********************************************************************
@@ -9961,31 +7315,7 @@
 OSArray *
 OSKext::getDependencies(void)
 {
-	return dependencies.get();
-}
-
-bool
-OSKext::hasDependency(const OSSymbol * depID)
-{
-	bool result __block;
-
-	if (depID == getIdentifier()) {
-		return true;
-	}
-	if (!dependencies) {
-		return false;
-	}
-	result = false;
-	dependencies->iterateObjects(^bool (OSObject * obj) {
-		OSKext * kext;
-		kext = OSDynamicCast(OSKext, obj);
-		if (!kext) {
-		        return false;
-		}
-		result = (depID == kext->getIdentifier());
-		return result;
-	});
-	return result;
+    return dependencies;
 }
 
 #if PRAGMA_MARK
@@ -9995,121 +7325,122 @@
 *********************************************************************/
 OSReturn
 OSKext::addClass(
-	OSMetaClass * aClass,
-	uint32_t      numClasses)
-{
-	OSReturn result = kOSMetaClassNoInsKModSet;
-
-	if (!metaClasses) {
-		metaClasses = OSSet::withCapacity(numClasses);
-		if (!metaClasses) {
-			goto finish;
-		}
-	}
-
-	if (metaClasses->containsObject(aClass)) {
-		OSKextLog(this,
-		    kOSKextLogWarningLevel |
-		    kOSKextLogLoadFlag,
-		    "Notice - kext %s has already registered class %s.",
-		    getIdentifierCString(),
-		    aClass->getClassName());
-		result = kOSReturnSuccess;
-		goto finish;
-	}
-
-	if (!metaClasses->setObject(aClass)) {
-		goto finish;
-	} else {
-		OSKextLog(this,
-		    kOSKextLogDetailLevel |
-		    kOSKextLogLoadFlag,
-		    "Kext %s registered class %s.",
-		    getIdentifierCString(),
-		    aClass->getClassName());
-	}
-
-	if (!flags.autounloadEnabled) {
-		const OSMetaClass * metaScan  = NULL;        // do not release
-
-		for (metaScan = aClass; metaScan; metaScan = metaScan->getSuperClass()) {
-			if (metaScan == OSTypeID(IOService)) {
-				OSKextLog(this,
-				    kOSKextLogProgressLevel |
-				    kOSKextLogLoadFlag,
-				    "Kext %s has IOService subclass %s; enabling autounload.",
-				    getIdentifierCString(),
-				    aClass->getClassName());
-
-				flags.autounloadEnabled = (0 == flags.unloadUnsupported);
-				break;
-			}
-		}
-	}
-
-	notifyAddClassObservers(this, aClass, flags);
-
-	result = kOSReturnSuccess;
+    OSMetaClass * aClass,
+    uint32_t      numClasses)
+{
+    OSReturn result = kOSMetaClassNoInsKModSet;
+
+    if (!metaClasses) {
+        metaClasses = OSSet::withCapacity(numClasses);
+        if (!metaClasses) {
+            goto finish;
+        }
+    }
+
+    if (metaClasses->containsObject(aClass)) {
+        OSKextLog(this,
+            kOSKextLogWarningLevel |
+            kOSKextLogLoadFlag,
+            "Notice - kext %s has already registered class %s.",
+            getIdentifierCString(),
+            aClass->getClassName());
+        result = kOSReturnSuccess;
+        goto finish;
+    }
+
+    if (!metaClasses->setObject(aClass)) {
+        goto finish;
+    } else {
+        OSKextLog(this,
+            kOSKextLogDetailLevel |
+            kOSKextLogLoadFlag,
+            "Kext %s registered class %s.",
+            getIdentifierCString(),
+            aClass->getClassName());
+    }
+
+    if (!flags.autounloadEnabled) {
+        const OSMetaClass * metaScan  = NULL;  // do not release
+
+        for (metaScan = aClass; metaScan; metaScan = metaScan->getSuperClass()) {
+            if (metaScan == OSTypeID(IOService)) {
+
+                OSKextLog(this,
+                    kOSKextLogProgressLevel |
+                    kOSKextLogLoadFlag,
+                    "Kext %s has IOService subclass %s; enabling autounload.",
+                    getIdentifierCString(),
+                    aClass->getClassName());
+
+                flags.autounloadEnabled = 1;
+                break;
+            }
+        }
+    }
+
+    notifyAddClassObservers(this, aClass, flags);
+
+    result = kOSReturnSuccess;
 
 finish:
-	if (result != kOSReturnSuccess) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag,
-		    "Kext %s failed to register class %s.",
-		    getIdentifierCString(),
-		    aClass->getClassName());
-	}
-
-	return result;
+    if (result != kOSReturnSuccess) {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogLoadFlag,
+            "Kext %s failed to register class %s.",
+            getIdentifierCString(),
+            aClass->getClassName());
+    }
+
+    return result;
 }
 
 /*********************************************************************
 *********************************************************************/
 OSReturn
 OSKext::removeClass(
-	OSMetaClass * aClass)
-{
-	OSReturn result = kOSMetaClassNoKModSet;
-
-	if (!metaClasses) {
-		goto finish;
-	}
-
-	if (!metaClasses->containsObject(aClass)) {
-		OSKextLog(this,
-		    kOSKextLogWarningLevel |
-		    kOSKextLogLoadFlag,
-		    "Notice - kext %s asked to unregister unknown class %s.",
-		    getIdentifierCString(),
-		    aClass->getClassName());
-		result = kOSReturnSuccess;
-		goto finish;
-	}
-
-	OSKextLog(this,
-	    kOSKextLogDetailLevel |
-	    kOSKextLogLoadFlag,
-	    "Kext %s unregistering class %s.",
-	    getIdentifierCString(),
-	    aClass->getClassName());
-
-	metaClasses->removeObject(aClass);
-
-	notifyRemoveClassObservers(this, aClass, flags);
-
-	result = kOSReturnSuccess;
+    OSMetaClass * aClass)
+{
+    OSReturn result = kOSMetaClassNoKModSet;
+
+    if (!metaClasses) {
+        goto finish;
+    }
+
+    if (!metaClasses->containsObject(aClass)) {
+        OSKextLog(this,
+            kOSKextLogWarningLevel |
+            kOSKextLogLoadFlag,
+            "Notice - kext %s asked to unregister unknown class %s.",
+            getIdentifierCString(),
+            aClass->getClassName());
+        result = kOSReturnSuccess;
+        goto finish;
+    }
+
+    OSKextLog(this,
+        kOSKextLogDetailLevel |
+        kOSKextLogLoadFlag,
+        "Kext %s unregistering class %s.",
+        getIdentifierCString(),
+        aClass->getClassName());
+
+    metaClasses->removeObject(aClass);
+    
+    notifyRemoveClassObservers(this, aClass, flags);
+
+    result = kOSReturnSuccess;
 
 finish:
-	if (result != kOSReturnSuccess) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag,
-		    "Failed to unregister kext %s class %s.",
-		    getIdentifierCString(),
-		    aClass->getClassName());
-	}
-	return result;
+    if (result != kOSReturnSuccess) {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogLoadFlag,
+            "Failed to unregister kext %s class %s.",
+            getIdentifierCString(),
+            aClass->getClassName());
+    }
+    return result;
 }
 
 /*********************************************************************
@@ -10117,7 +7448,7 @@
 OSSet *
 OSKext::getMetaClasses(void)
 {
-	return metaClasses.get();
+    return metaClasses;
 }
 
 /*********************************************************************
@@ -10125,28 +7456,30 @@
 bool
 OSKext::hasOSMetaClassInstances(void)
 {
-	bool                   result        = false;
-	OSSharedPtr<OSCollectionIterator> classIterator;
-	OSMetaClass          * checkClass    = NULL;        // do not release
-
-	if (!metaClasses) {
-		goto finish;
-	}
-
-	classIterator = OSCollectionIterator::withCollection(metaClasses.get());
-	if (!classIterator) {
-		// xxx - log alloc failure?
-		goto finish;
-	}
-	while ((checkClass = (OSMetaClass *)classIterator->getNextObject())) {
-		if (checkClass->getInstanceCount()) {
-			result = true;
-			goto finish;
-		}
-	}
+    bool                   result        = false;
+    OSCollectionIterator * classIterator = NULL;  // must release
+    OSMetaClass          * checkClass    = NULL;  // do not release
+
+    if (!metaClasses) {
+        goto finish;
+    }
+
+    classIterator = OSCollectionIterator::withCollection(metaClasses);
+    if (!classIterator) {
+        // xxx - log alloc failure?
+        goto finish;
+    }
+    while ((checkClass = (OSMetaClass *)classIterator->getNextObject())) {
+        if (checkClass->getInstanceCount()) {
+            result = true;
+            goto finish;
+        }
+    }
 
 finish:
-	return result;
+    
+    OSSafeRelease(classIterator);
+    return result;
 }
 
 /*********************************************************************
@@ -10154,19 +7487,20 @@
 /* static */
 void
 OSKext::reportOSMetaClassInstances(
-	const char     * kextIdentifier,
-	OSKextLogSpec    msgLogSpec)
-{
-	OSSharedPtr<OSKext> theKext;
-
-	theKext = OSKext::lookupKextWithIdentifier(kextIdentifier);
-	if (!theKext) {
-		goto finish;
-	}
-
-	theKext->reportOSMetaClassInstances(msgLogSpec);
+    const char     * kextIdentifier,
+    OSKextLogSpec    msgLogSpec)
+{
+    OSKext * theKext = NULL; // must release
+    
+    theKext = OSKext::lookupKextWithIdentifier(kextIdentifier);
+    if (!theKext) {
+        goto finish;
+    }
+    
+    theKext->reportOSMetaClassInstances(msgLogSpec);
 finish:
-	return;
+    OSSafeRelease(theKext);
+    return;
 }
 
 /*********************************************************************
@@ -10174,1856 +7508,800 @@
 void
 OSKext::reportOSMetaClassInstances(OSKextLogSpec msgLogSpec)
 {
-	OSSharedPtr<OSCollectionIterator> classIterator;
-	OSMetaClass          * checkClass    = NULL;        // do not release
-
-	if (!metaClasses) {
-		goto finish;
-	}
-
-	classIterator = OSCollectionIterator::withCollection(metaClasses.get());
-	if (!classIterator) {
-		goto finish;
-	}
-	while ((checkClass = (OSMetaClass *)classIterator->getNextObject())) {
-		if (checkClass->getInstanceCount()) {
-			OSKextLog(this,
-			    msgLogSpec,
-			    "    Kext %s class %s has %d instance%s.",
-			    getIdentifierCString(),
-			    checkClass->getClassName(),
-			    checkClass->getInstanceCount(),
-			    checkClass->getInstanceCount() == 1 ? "" : "s");
-		}
-	}
+    OSCollectionIterator * classIterator = NULL;  // must release
+    OSMetaClass          * checkClass    = NULL;  // do not release
+
+    if (!metaClasses) {
+        goto finish;
+    }
+
+    classIterator = OSCollectionIterator::withCollection(metaClasses);
+    if (!classIterator) {
+        goto finish;
+    }
+    while ((checkClass = (OSMetaClass *)classIterator->getNextObject())) {
+        if (checkClass->getInstanceCount()) {
+            OSKextLog(this,
+                msgLogSpec,
+                "    Kext %s class %s has %d instance%s.",
+                getIdentifierCString(),
+                checkClass->getClassName(),
+                checkClass->getInstanceCount(),
+                checkClass->getInstanceCount() == 1 ? "" : "s");
+        }
+    }
 
 finish:
-	return;
+    OSSafeRelease(classIterator);
+    return;
 }
 
 #if PRAGMA_MARK
 #pragma mark User-Space Requests
 #endif
-
-static kern_return_t
-patchDextLaunchRequests(task_t calling_task, OSArray *requests)
-{
-	OSReturn result = kOSReturnSuccess;
-	for (uint32_t requestIndex = 0; requestIndex < requests->getCount(); requestIndex++) {
-		OSDictionary * request = NULL;         //do not release
-		IOUserServerCheckInToken * token = NULL;         //do not release
-		OSString * requestPredicate = NULL;         //do not release
-		OSSharedPtr<OSNumber> portNameNumber;
-		mach_port_name_t portName = 0;
-		request = OSDynamicCast(OSDictionary, requests->getObject(requestIndex));
-		if (!request) {
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogGeneralFlag | kOSKextLogErrorLevel,
-			    "Elements of request should be of type OSDictionary");
-			result = kOSKextReturnInternalError;
-			goto finish;
-		}
-		requestPredicate = _OSKextGetRequestPredicate(request);
-		if (!requestPredicate) {
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogGeneralFlag | kOSKextLogErrorLevel,
-			    "Failed to get request predicate");
-			result = kOSKextReturnInternalError;
-			goto finish;
-		}
-		// is this a dext launch?
-		if (requestPredicate->isEqualTo(kKextRequestPredicateRequestDaemonLaunch)) {
-			token = OSDynamicCast(IOUserServerCheckInToken, _OSKextGetRequestArgument(request, kKextRequestArgumentCheckInToken));
-			if (!token) {
-				OSKextLog(/* kext */ NULL,
-				    kOSKextLogGeneralFlag | kOSKextLogErrorLevel,
-				    "Could not find a IOUserServerCheckInToken in daemon launch request.");
-				result = kOSKextReturnInternalError;
-				goto finish;
-			}
-			portName = iokit_make_send_right(calling_task, token, IKOT_IOKIT_IDENT);
-			if (portName == 0 || portName == MACH_PORT_DEAD) {
-				OSKextLog(/* kext */ NULL,
-				    kOSKextLogGeneralFlag | kOSKextLogErrorLevel,
-				    "Could not create send right for object.");
-				result = kOSKextReturnInternalError;
-				goto finish;
-			}
-			// Store the mach port name as a OSNumber
-			portNameNumber = OSNumber::withNumber(portName, CHAR_BIT * sizeof(portName));
-			if (!portNameNumber) {
-				OSKextLog(/* kext */ NULL,
-				    kOSKextLogGeneralFlag | kOSKextLogErrorLevel,
-				    "Could not create OSNumber object.");
-				result = kOSKextReturnNoMemory;
-				goto finish;
-			}
-			if (!_OSKextSetRequestArgument(request, kKextRequestArgumentCheckInToken, portNameNumber.get())) {
-				OSKextLog(/* kext */ NULL,
-				    kOSKextLogGeneralFlag | kOSKextLogErrorLevel,
-				    "Could not set OSNumber object as request " kKextRequestArgumentCheckInToken);
-				result = kOSKextReturnNoMemory;
-				goto finish;
-			}
-		}
-finish:
-		if (result != kOSReturnSuccess) {
-			break;
-		}
-	}
-	return result;
-}
-
-bool
-OSKext::iokitDaemonActive()
-{
-	bool result;
-	IORecursiveLockLock(sKextLock);
-	result = sIOKitDaemonActive && !sOSKextWasResetAfterUserspaceReboot;
-	IORecursiveLockUnlock(sKextLock);
-	return result;
-}
-
 /*********************************************************************
 * XXX - this function is a big ugly mess
 *********************************************************************/
 /* static */
 OSReturn
 OSKext::handleRequest(
-	host_priv_t     hostPriv,
-	OSKextLogSpec   clientLogFilter,
-	char          * requestBuffer,
-	uint32_t        requestLength,
-	char         ** responseOut,
-	uint32_t      * responseLengthOut,
-	char         ** logInfoOut,
-	uint32_t      * logInfoLengthOut)
-{
-	OSReturn       result             = kOSReturnError;
-	kern_return_t  kmem_result        = KERN_FAILURE;
-
-	char         * response           = NULL;        // returned by reference
-	uint32_t       responseLength     = 0;
-
-	bool           taskCanManageAllKCs   = false;
-	bool           taskOnlyManagesBootKC = false;
-
-	OSSharedPtr<OSObject>     parsedXML;
-	OSDictionary            * requestDict    = NULL;        // do not release
-	OSSharedPtr<OSString>     errorString;
-
-	OSSharedPtr<OSObject>     responseObject;
-
-	OSSharedPtr<OSSerialize>  serializer;
-
-	OSSharedPtr<OSArray>      logInfoArray;
-
-	OSString     * predicate          = NULL;        // do not release
-	OSString     * kextIdentifier     = NULL;        // do not release
-	OSArray      * kextIdentifiers    = NULL;        // do not release
-	OSKext       * theKext            = NULL;        // do not release
-	OSBoolean    * boolArg            = NULL;        // do not release
-
-
-	IORecursiveLockLock(sKextLock);
-
-	if (responseOut) {
-		*responseOut = NULL;
-		*responseLengthOut = 0;
-	}
-	if (logInfoOut) {
-		*logInfoOut = NULL;
-		*logInfoLengthOut = 0;
-	}
-
-	OSKext::setUserSpaceLogFilter(clientLogFilter, logInfoOut ? true : false);
-
-	/* XML must be nul-terminated.
-	 */
-	if (requestBuffer[requestLength - 1] != '\0') {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogIPCFlag,
-		    "Invalid request from user space (not nul-terminated).");
-		result = kOSKextReturnBadData;
-		goto finish;
-	}
-	parsedXML = OSUnserializeXML((const char *)requestBuffer, errorString);
-	if (parsedXML) {
-		requestDict = OSDynamicCast(OSDictionary, parsedXML.get());
-	}
-	if (!requestDict) {
-		const char * errorCString = "(unknown error)";
-
-		if (errorString && errorString->getCStringNoCopy()) {
-			errorCString = errorString->getCStringNoCopy();
-		} else if (parsedXML) {
-			errorCString = "not a dictionary";
-		}
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogIPCFlag,
-		    "Error unserializing request from user space: %s.",
-		    errorCString);
-		result = kOSKextReturnSerialization;
-		goto finish;
-	}
-
-	predicate = _OSKextGetRequestPredicate(requestDict);
-	if (!predicate) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogIPCFlag,
-		    "Recieved kext request from user space with no predicate.");
-		result = kOSKextReturnInvalidArgument;
-		goto finish;
-	}
-	OSKextLog(/* kext */ NULL,
-	    kOSKextLogDebugLevel |
-	    kOSKextLogIPCFlag,
-	    "Received '%s' request from user space.",
-	    predicate->getCStringNoCopy());
-
-	/*
-	 * All management of file sets requires an entitlement
-	 */
-	result = kOSKextReturnNotPrivileged;
-	if (predicate->isEqualTo(kKextRequestPredicateUnload) ||
-	    predicate->isEqualTo(kKextRequestPredicateStart) ||
-	    predicate->isEqualTo(kKextRequestPredicateStop) ||
-	    predicate->isEqualTo(kKextRequestPredicateGetKernelRequests) ||
-	    predicate->isEqualTo(kKextRequestPredicateSendResource) ||
-	    predicate->isEqualTo(kKextRequestPredicateLoadFileSetKC) ||
-	    predicate->isEqualTo(kKextRequestPredicateLoadCodeless) ||
-	    predicate->isEqualTo(kKextRequestPredicateLoadFromKC) ||
-	    predicate->isEqualTo(kKextRequestPredicateMissingAuxKCBundles) ||
-	    predicate->isEqualTo(kKextRequestPredicateAuxKCBundleAvailable) ||
-	    predicate->isEqualTo(kKextRequestPredicateDaemonReady)) {
-		if (!iokitDaemonAvailable()) {
-			panic("Received unexpected request in environment where " kIOKitDaemonName " is unavailable");
-		}
-		if (hostPriv == HOST_PRIV_NULL) {
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogIPCFlag,
-			    "Access Failure - must be root user.");
-			goto finish;
-		}
-		taskCanManageAllKCs = IOCurrentTaskHasEntitlement(kOSKextCollectionManagementEntitlement) == TRUE;
-		taskOnlyManagesBootKC = IOCurrentTaskHasEntitlement(kOSKextOnlyBootKCManagementEntitlement) == TRUE;
-
-		if (!taskCanManageAllKCs && !taskOnlyManagesBootKC) {
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogIPCFlag,
-			    "Access Failure - client not entitled to manage file sets.");
-			goto finish;
-		}
-
-		/*
-		 * The OnlyBootKC entitlement restricts the
-		 * collection-management entitlement to only managing kexts in
-		 * the BootKC. All other predicates that alter global state or
-		 * add new KCs are disallowed.
-		 */
-		if (taskOnlyManagesBootKC &&
-		    (predicate->isEqualTo(kKextRequestPredicateGetKernelRequests) ||
-		    predicate->isEqualTo(kKextRequestPredicateSendResource) ||
-		    predicate->isEqualTo(kKextRequestPredicateLoadFileSetKC) ||
-		    predicate->isEqualTo(kKextRequestPredicateLoadCodeless) ||
-		    predicate->isEqualTo(kKextRequestPredicateMissingAuxKCBundles) ||
-		    predicate->isEqualTo(kKextRequestPredicateAuxKCBundleAvailable) ||
-		    predicate->isEqualTo(kKextRequestPredicateDaemonReady))) {
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogIPCFlag,
-			    "Access Failure - client not entitled to manage non-primary KCs");
-			goto finish;
-		}
-
-		/*
-		 * If we get here, then the process either has the full KC
-		 * management entitlement, or it has the BootKC-only
-		 * entitlement and the request is about the BootKC.
-		 */
-	}
-
-	/* Get common args in anticipation of use.
-	 */
-	kextIdentifier = OSDynamicCast(OSString, _OSKextGetRequestArgument(
-		    requestDict, kKextRequestArgumentBundleIdentifierKey));
-	kextIdentifiers = OSDynamicCast(OSArray, _OSKextGetRequestArgument(
-		    requestDict, kKextRequestArgumentBundleIdentifierKey));
-	if (kextIdentifier) {
-		theKext = OSDynamicCast(OSKext, sKextsByID->getObject(kextIdentifier));
-	}
-	boolArg = OSDynamicCast(OSBoolean, _OSKextGetRequestArgument(
-		    requestDict, kKextRequestArgumentValueKey));
-
-	if (taskOnlyManagesBootKC &&
-	    theKext &&
-	    theKext->isInFileset() &&
-	    theKext->kc_type != KCKindPrimary) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogIPCFlag,
-		    "Access Failure - client not entitled to manage kext in non-primary KC");
-		result = kOSKextReturnNotPrivileged;
-		goto finish;
-	}
-	result = kOSKextReturnInvalidArgument;
-
-	if (predicate->isEqualTo(kKextRequestPredicateStart)) {
-		if (!kextIdentifier) {
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogIPCFlag,
-			    "Invalid arguments to kext start request.");
-		} else if (!theKext) {
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogIPCFlag,
-			    "Kext %s not found for start request.",
-			    kextIdentifier->getCStringNoCopy());
-			result = kOSKextReturnNotFound;
-		} else {
-			result = theKext->start();
-		}
-	} else if (predicate->isEqualTo(kKextRequestPredicateStop)) {
-		if (!kextIdentifier) {
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogIPCFlag,
-			    "Invalid arguments to kext stop request.");
-		} else if (!theKext) {
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogIPCFlag,
-			    "Kext %s not found for stop request.",
-			    kextIdentifier->getCStringNoCopy());
-			result = kOSKextReturnNotFound;
-		} else {
-			result = theKext->stop();
-		}
-	} else if (predicate->isEqualTo(kKextRequestPredicateMissingAuxKCBundles)) {
-		result = OSKext::setMissingAuxKCBundles(requestDict);
-	} else if (predicate->isEqualTo(kKextRequestPredicateAuxKCBundleAvailable)) {
-		if (!kextIdentifier) {
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogIPCFlag,
-			    "Invalid arguments to AuxKC Bundle Available request.");
-		} else {
-			result = OSKext::setAuxKCBundleAvailable(kextIdentifier, requestDict);
-		}
-	} else if (predicate->isEqualTo(kKextRequestPredicateLoadFromKC)) {
-		if (!kextIdentifier) {
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogIPCFlag,
-			    "Invalid arguments to kext load from KC request.");
-		} else if (!theKext) {
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogIPCFlag,
-			    "Kext %s not found for load from KC request.",
-			    kextIdentifier->getCStringNoCopy());
-			result = kOSKextReturnNotFound;
-		} else if (!theKext->isInFileset()) {
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogIPCFlag,
-			    "Kext %s does not exist in a KC: refusing to load.",
-			    kextIdentifier->getCStringNoCopy());
-			result = kOSKextReturnNotLoadable;
-		} else {
-			result = OSKext::loadKextFromKC(theKext, requestDict);
-		}
-	} else if (predicate->isEqualTo(kKextRequestPredicateLoadCodeless)) {
-		if (!kextIdentifier) {
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogIPCFlag,
-			    "Invalid arguments to codeless kext load interface (missing identifier).");
-		} else {
-			result = OSKext::loadCodelessKext(kextIdentifier, requestDict);
-		}
-	} else if (predicate->isEqualTo(kKextRequestPredicateUnload)) {
-		if (!kextIdentifier) {
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogIPCFlag,
-			    "Invalid arguments to kext unload request.");
-		} else if (!theKext) {
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogIPCFlag,
-			    "Kext %s not found for unload request.",
-			    kextIdentifier->getCStringNoCopy());
-			result = kOSKextReturnNotFound;
-		} else {
-			if (theKext->isDriverKit()) {
-				result = OSKext::removeDext(theKext);
-			} else {
-				OSBoolean * terminateFlag = OSDynamicCast(OSBoolean,
-				    _OSKextGetRequestArgument(requestDict,
-				    kKextRequestArgumentTerminateIOServicesKey));
-				result = OSKext::removeKext(theKext, terminateFlag == kOSBooleanTrue);
-			}
-		}
-	} else if (predicate->isEqualTo(kKextRequestPredicateSendResource)) {
-		result = OSKext::dispatchResource(requestDict);
-	} else if (predicate->isEqualTo(kKextRequestPredicateGetUUIDByAddress)) {
-		OSNumber     *lookupNum   = NULL;
-		lookupNum = OSDynamicCast(OSNumber,
-		    _OSKextGetRequestArgument(requestDict,
-		    kKextRequestArgumentLookupAddressKey));
-
-		responseObject = OSKext::copyKextUUIDForAddress(lookupNum);
-		if (responseObject) {
-			result = kOSReturnSuccess;
-		} else {
-			goto finish;
-		}
-	} else if (predicate->isEqualTo(kKextRequestPredicateGetLoaded) ||
-	    predicate->isEqualTo(kKextRequestPredicateGetLoadedByUUID) ||
-	    predicate->isEqualTo(kKextRequestPredicateGetKextsInCollection) ||
-	    predicate->isEqualTo(kKextRequestPredicateGetDexts)) {
-		OSBoolean    * delayAutounloadBool = NULL;
-		OSObject     * infoKeysRaw         = NULL;
-		OSArray      * infoKeys            = NULL;
-		uint32_t       infoKeysCount       = 0;
-
-		delayAutounloadBool = OSDynamicCast(OSBoolean,
-		    _OSKextGetRequestArgument(requestDict,
-		    kKextRequestArgumentDelayAutounloadKey));
-
-		/* If asked to delay autounload, reset the timer if it's currently set.
-		 * (That is, don't schedule an unload if one isn't already pending.
-		 */
-		if (delayAutounloadBool == kOSBooleanTrue) {
-			OSKext::considerUnloads(/* rescheduleOnly? */ true);
-		}
-
-		infoKeysRaw = _OSKextGetRequestArgument(requestDict,
-		    kKextRequestArgumentInfoKeysKey);
-		infoKeys = OSDynamicCast(OSArray, infoKeysRaw);
-		if (infoKeysRaw && !infoKeys) {
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogIPCFlag,
-			    "Invalid arguments to kext info request.");
-			goto finish;
-		}
-
-		if (infoKeys) {
-			infoKeysCount = infoKeys->getCount();
-			for (uint32_t i = 0; i < infoKeysCount; i++) {
-				if (!OSDynamicCast(OSString, infoKeys->getObject(i))) {
-					OSKextLog(/* kext */ NULL,
-					    kOSKextLogErrorLevel |
-					    kOSKextLogIPCFlag,
-					    "Invalid arguments to kext info request.");
-					goto finish;
-				}
-			}
-		}
-
-		if (predicate->isEqualTo(kKextRequestPredicateGetLoaded)) {
-			responseObject = OSKext::copyLoadedKextInfo(kextIdentifiers, infoKeys);
-		} else if (predicate->isEqualTo(kKextRequestPredicateGetLoadedByUUID)) {
-			responseObject = OSKext::copyLoadedKextInfoByUUID(kextIdentifiers, infoKeys);
-		} else if (predicate->isEqualTo(kKextRequestPredicateGetKextsInCollection)) {
-			responseObject = OSKext::copyKextCollectionInfo(requestDict, infoKeys);
-		} else if (predicate->isEqualTo(kKextRequestPredicateGetDexts)) {
-			responseObject = OSKext::copyDextsInfo(kextIdentifiers, infoKeys);
-		}
-
-		if (!responseObject) {
-			result = kOSKextReturnInternalError;
-		} else {
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogDebugLevel |
-			    kOSKextLogIPCFlag,
-			    "Returning loaded kext info.");
-			result = kOSReturnSuccess;
-		}
-	} else if (predicate->isEqualTo(kKextRequestPredicateGetKernelRequests)) {
-		/* Hand the current sKernelRequests array to the caller
-		 * (who must release it), and make a new one.
-		 */
-		responseObject = os::move(sKernelRequests);
-		sKernelRequests = OSArray::withCapacity(0);
-		sPostedKextLoadIdentifiers->flushCollection();
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogDebugLevel |
-		    kOSKextLogIPCFlag,
-		    "Returning kernel requests.");
-		result = kOSReturnSuccess;
-	} else if (predicate->isEqualTo(kKextRequestPredicateGetAllLoadRequests)) {
-		/* Return the set of all requested bundle identifiers */
-		responseObject = sAllKextLoadIdentifiers;
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogDebugLevel |
-		    kOSKextLogIPCFlag,
-		    "Returning load requests.");
-		result = kOSReturnSuccess;
-	} else if (predicate->isEqualTo(kKextRequestPredicateLoadFileSetKC)) {
-		printf("KextLog: Loading FileSet KC(s)\n");
-		result = OSKext::loadFileSetKexts(requestDict);
-	} else if (predicate->isEqualTo(kKextRequestPredicateDaemonReady)) {
-		bool active = iokitDaemonActive();
-		printf("KextLog: " kIOKitDaemonName " is %s\n", active ? "active" : "not active");
-		if (sOSKextWasResetAfterUserspaceReboot) {
-			printf("KextLog: was reset after userspace reboot\n");
-		}
-		result = active ? kOSReturnSuccess : kIOReturnNotReady;
-	} else {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogDebugLevel |
-		    kOSKextLogIPCFlag,
-		    "Received '%s' invalid request from user space.",
-		    predicate->getCStringNoCopy());
-		goto finish;
-	}
-
-	/**********
-	 * Now we have handle the request, or not. Gather up the response & logging
-	 * info to ship to user space.
-	 *********/
-
-	/* Note: Nothing in OSKext is supposed to retain requestDict,
-	 * but you never know....
-	 */
-	if (requestDict->getRetainCount() > 1) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogWarningLevel |
-		    kOSKextLogIPCFlag,
-		    "Request from user space still retained by a kext; "
-		    "probable memory leak.");
-	}
-
-	if (responseOut && responseObject) {
-		serializer = OSSerialize::withCapacity(0);
-		if (!serializer) {
-			result = kOSKextReturnNoMemory;
-			goto finish;
-		}
-		/*
-		 * Before serializing the kernel requests, patch the dext launch requests so
-		 * that the value for kKextRequestArgumentCheckInToken is a mach port name for the
-		 * IOUserServerCheckInToken kernel object.
-		 */
-		if (predicate->isEqualTo(kKextRequestPredicateGetKernelRequests)) {
-			OSArray * requests = OSDynamicCast(OSArray, responseObject.get());
-			task_t calling_task = current_task();
-			if (!requests) {
-				OSKextLog(/* kext */ NULL,
-				    kOSKextLogGeneralFlag | kOSKextLogErrorLevel,
-				    "responseObject should be an OSArray if predicate is " kKextRequestPredicateGetKernelRequests);
-				result = kOSKextReturnInternalError;
-				goto finish;
-			}
-			result = patchDextLaunchRequests(calling_task, requests);
-			if (result != kOSReturnSuccess) {
-				OSKextLog(/* kext */ NULL,
-				    kOSKextLogGeneralFlag | kOSKextLogErrorLevel,
-				    "Failed to patch dext launch requests.");
-				goto finish;
-			}
-		}
-
-		if (!responseObject->serialize(serializer.get())) {
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogGeneralFlag | kOSKextLogErrorLevel,
-			    "Failed to serialize response to request from user space.");
-			result = kOSKextReturnSerialization;
-			goto finish;
-		}
-
-		response = (char *)serializer->text();
-		responseLength = serializer->getLength();
-	}
-
-	if (responseOut && response) {
-		char * buffer;
-
-		/* This kmem_alloc sets the return value of the function.
-		 */
-		kmem_result = kmem_alloc(kernel_map, (vm_offset_t *)&buffer,
-		    round_page(responseLength), KMA_DATA_SHARED, VM_KERN_MEMORY_OSKEXT);
-		if (kmem_result != KERN_SUCCESS) {
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogIPCFlag,
-			    "Failed to copy response to request from user space.");
-			result = kmem_result;
-			goto finish;
-		} else {
-			/* 11981737 - clear uninitialized data in last page */
-			bzero((void *)(buffer + responseLength),
-			    (round_page(responseLength) - responseLength));
-			memcpy(buffer, response, responseLength);
-			*responseOut = buffer;
-			*responseLengthOut = responseLength;
-		}
-	}
+    host_priv_t     hostPriv,
+    OSKextLogSpec   clientLogFilter,
+    char          * requestBuffer,
+    uint32_t        requestLength,
+    char         ** responseOut,
+    uint32_t      * responseLengthOut,
+    char         ** logInfoOut,
+    uint32_t      * logInfoLengthOut)
+{
+    OSReturn       result             = kOSReturnError;
+    kern_return_t  kmem_result        = KERN_FAILURE;
+
+    char         * response           = NULL;  // returned by reference
+    uint32_t       responseLength     = 0;
+
+    OSObject     * parsedXML          = NULL;  // must release
+    OSDictionary * requestDict        = NULL;  // do not release
+    OSString     * errorString        = NULL;  // must release
+
+    OSObject     * responseObject     = NULL;  // must release
+    
+    OSSerialize  * serializer         = NULL;  // must release
+
+    OSArray      * logInfoArray       = NULL;  // must release
+
+    OSString     * predicate          = NULL;  // do not release
+    OSString     * kextIdentifier     = NULL;  // do not release
+    OSArray      * kextIdentifiers    = NULL;  // do not release
+    OSKext       * theKext            = NULL;  // do not release
+    OSBoolean    * boolArg            = NULL;  // do not release
+
+    IORecursiveLockLock(sKextLock);
+
+    if (responseOut) {
+        *responseOut = NULL;
+        *responseLengthOut = 0;
+    }
+    if (logInfoOut) {
+        *logInfoOut = NULL;
+        *logInfoLengthOut = 0;
+    }
+
+    OSKext::setUserSpaceLogFilter(clientLogFilter, logInfoOut ? true : false);
+
+   /* XML must be nul-terminated.
+    */
+    if (requestBuffer[requestLength - 1] != '\0') {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogErrorLevel |
+            kOSKextLogIPCFlag,
+            "Invalid request from user space (not nul-terminated).");
+        result = kOSKextReturnBadData;
+        goto finish;
+    }
+    parsedXML = OSUnserializeXML((const char *)requestBuffer, &errorString);
+    if (parsedXML) {
+        requestDict = OSDynamicCast(OSDictionary, parsedXML);
+    }
+    if (!requestDict) {
+        const char * errorCString = "(unknown error)";
+        
+        if (errorString && errorString->getCStringNoCopy()) {
+            errorCString = errorString->getCStringNoCopy();
+        } else if (parsedXML) {
+            errorCString = "not a dictionary";
+        }
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogErrorLevel |
+            kOSKextLogIPCFlag,
+            "Error unserializing request from user space: %s.",
+            errorCString);
+        result = kOSKextReturnSerialization;
+        goto finish;
+    }
+
+    predicate = _OSKextGetRequestPredicate(requestDict);
+    if (!predicate) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogErrorLevel |
+            kOSKextLogIPCFlag,
+            "Recieved kext request from user space with no predicate.");
+        result = kOSKextReturnInvalidArgument;
+        goto finish;
+    }
+
+    OSKextLog(/* kext */ NULL,
+        kOSKextLogDebugLevel |
+        kOSKextLogIPCFlag,
+        "Received '%s' request from user space.",
+        predicate->getCStringNoCopy());
+      
+    result = kOSKextReturnNotPrivileged;
+    if (hostPriv == HOST_PRIV_NULL) {
+        /* must be root to use these kext requests */
+        if (predicate->isEqualTo(kKextRequestPredicateUnload) ||
+            predicate->isEqualTo(kKextRequestPredicateStart) ||
+            predicate->isEqualTo(kKextRequestPredicateStop) ||
+            predicate->isEqualTo(kKextRequestPredicateGetKernelRequests) ||
+            predicate->isEqualTo(kKextRequestPredicateSendResource) ) {
+            OSKextLog(/* kext */ NULL,
+                      kOSKextLogErrorLevel |
+                      kOSKextLogIPCFlag,
+                      "Access Failure - must be root user.");
+           goto finish;
+        }
+    }
+
+   /* Get common args in anticipation of use.
+    */
+    kextIdentifier = OSDynamicCast(OSString, _OSKextGetRequestArgument(
+        requestDict, kKextRequestArgumentBundleIdentifierKey));
+    kextIdentifiers = OSDynamicCast(OSArray, _OSKextGetRequestArgument(
+        requestDict, kKextRequestArgumentBundleIdentifierKey));
+    if (kextIdentifier) {
+        theKext = OSDynamicCast(OSKext, sKextsByID->getObject(kextIdentifier));
+    }
+    boolArg = OSDynamicCast(OSBoolean, _OSKextGetRequestArgument(
+        requestDict, kKextRequestArgumentValueKey));
+
+    result = kOSKextReturnInvalidArgument;
+
+    if (predicate->isEqualTo(kKextRequestPredicateStart)) {
+        if (!kextIdentifier) {
+            OSKextLog(/* kext */ NULL,
+                kOSKextLogErrorLevel |
+                kOSKextLogIPCFlag,
+                "Invalid arguments to kext start request.");
+        } else if (!theKext) {
+            OSKextLog(/* kext */ NULL,
+                kOSKextLogErrorLevel |
+                kOSKextLogIPCFlag,
+                "Kext %s not found for start request.",
+                kextIdentifier->getCStringNoCopy());
+            result = kOSKextReturnNotFound;
+        } else {
+            result = theKext->start();
+        }
+
+    } else if (predicate->isEqualTo(kKextRequestPredicateStop)) {
+        if (!kextIdentifier) {
+            OSKextLog(/* kext */ NULL,
+                kOSKextLogErrorLevel |
+                kOSKextLogIPCFlag,
+                "Invalid arguments to kext stop request.");
+        } else if (!theKext) {
+            OSKextLog(/* kext */ NULL,
+                kOSKextLogErrorLevel |
+                kOSKextLogIPCFlag,
+                "Kext %s not found for stop request.",
+                kextIdentifier->getCStringNoCopy());
+            result = kOSKextReturnNotFound;
+        } else {
+            result = theKext->stop();
+        }
+
+    } else if (predicate->isEqualTo(kKextRequestPredicateUnload)) {
+        if (!kextIdentifier) {
+            OSKextLog(/* kext */ NULL,
+                kOSKextLogErrorLevel |
+                kOSKextLogIPCFlag,
+                "Invalid arguments to kext unload request.");
+        } else if (!theKext) {
+            OSKextLog(/* kext */ NULL,
+                kOSKextLogErrorLevel |
+                kOSKextLogIPCFlag,
+                "Kext %s not found for unload request.",
+                kextIdentifier->getCStringNoCopy());
+            result = kOSKextReturnNotFound;
+        } else {
+            OSBoolean * terminateFlag = OSDynamicCast(OSBoolean,
+                _OSKextGetRequestArgument(requestDict,
+                    kKextRequestArgumentTerminateIOServicesKey));
+            result = OSKext::removeKext(theKext, terminateFlag == kOSBooleanTrue);
+        }
+
+    } else if (predicate->isEqualTo(kKextRequestPredicateSendResource)) {
+        result = OSKext::dispatchResource(requestDict);
+
+    } else if (predicate->isEqualTo(kKextRequestPredicateGetLoaded)) {
+        OSBoolean    * delayAutounloadBool = NULL;
+        OSObject     * infoKeysRaw         = NULL;
+        OSArray      * infoKeys            = NULL;
+        uint32_t       infoKeysCount       = 0;
+        
+        delayAutounloadBool = OSDynamicCast(OSBoolean,
+            _OSKextGetRequestArgument(requestDict,
+                kKextRequestArgumentDelayAutounloadKey));
+
+       /* If asked to delay autounload, reset the timer if it's currently set.
+        * (That is, don't schedule an unload if one isn't already pending.
+        */
+        if (delayAutounloadBool == kOSBooleanTrue) {
+            OSKext::considerUnloads(/* rescheduleOnly? */ true);
+        }
+
+        infoKeysRaw = _OSKextGetRequestArgument(requestDict,
+                kKextRequestArgumentInfoKeysKey);
+        infoKeys = OSDynamicCast(OSArray, infoKeysRaw);
+        if (infoKeysRaw && !infoKeys) {
+            OSKextLog(/* kext */ NULL,
+                kOSKextLogErrorLevel |
+                kOSKextLogIPCFlag,
+                "Invalid arguments to kext info request.");
+            goto finish;
+        }
+        
+        if (infoKeys) {
+            infoKeysCount = infoKeys->getCount();
+            for (uint32_t i = 0; i < infoKeysCount; i++) {
+                if (!OSDynamicCast(OSString, infoKeys->getObject(i))) {
+                    OSKextLog(/* kext */ NULL,
+                        kOSKextLogErrorLevel |
+                        kOSKextLogIPCFlag,
+                        "Invalid arguments to kext info request.");
+                    goto finish;
+                }
+            }
+        }
+
+        responseObject = OSKext::copyLoadedKextInfo(kextIdentifiers, infoKeys);
+        if (!responseObject) {
+            result = kOSKextReturnInternalError;
+        } else {
+            OSKextLog(/* kext */ NULL,
+                kOSKextLogDebugLevel |
+                kOSKextLogIPCFlag,
+                "Returning loaded kext info.");
+            result = kOSReturnSuccess;
+        }
+    } else if (predicate->isEqualTo(kKextRequestPredicateGetKernelRequests)) {
+
+       /* Hand the current sKernelRequests array to the caller
+        * (who must release it), and make a new one.
+        */
+        responseObject = sKernelRequests;
+        sKernelRequests = OSArray::withCapacity(0);
+        sPostedKextLoadIdentifiers->flushCollection();
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogDebugLevel |
+            kOSKextLogIPCFlag,
+            "Returning kernel requests.");
+        result = kOSReturnSuccess;
+
+    } else if (predicate->isEqualTo(kKextRequestPredicateGetAllLoadRequests)) {
+        
+        /* Return the set of all requested bundle identifiers */
+        responseObject = sAllKextLoadIdentifiers;
+        responseObject->retain();
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogDebugLevel |
+            kOSKextLogIPCFlag,
+            "Returning load requests.");
+        result = kOSReturnSuccess;
+    }
+    else {
+        OSKextLog(/* kext */ NULL,
+                  kOSKextLogDebugLevel |
+                  kOSKextLogIPCFlag,
+                  "Received '%s' invalid request from user space.",
+                  predicate->getCStringNoCopy());
+        goto finish;
+    }
+
+   /**********
+    * Now we have handle the request, or not. Gather up the response & logging
+    * info to ship to user space.
+    *********/
+    
+   /* Note: Nothing in OSKext is supposed to retain requestDict,
+    * but you never know....
+    */
+    if (requestDict->getRetainCount() > 1) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogWarningLevel |
+            kOSKextLogIPCFlag,
+            "Request from user space still retained by a kext; "
+            "probable memory leak.");
+    }
+
+    if (responseOut && responseObject) {
+        serializer = OSSerialize::withCapacity(0);
+        if (!serializer) {
+            result = kOSKextReturnNoMemory;
+            goto finish;
+        }
+
+        if (!responseObject->serialize(serializer)) {
+            OSKextLog(/* kext */ NULL,
+                kOSKextLogGeneralFlag | kOSKextLogErrorLevel,
+                "Failed to serialize response to request from user space.");
+            result = kOSKextReturnSerialization;
+            goto finish;
+        }
+
+        response = (char *)serializer->text();
+        responseLength = serializer->getLength();
+    }
+    
+    if (responseOut && response) {
+        char * buffer;
+
+       /* This kmem_alloc sets the return value of the function.
+        */
+        kmem_result = kmem_alloc(kernel_map, (vm_offset_t *)&buffer,
+            round_page(responseLength), VM_KERN_MEMORY_OSKEXT);
+        if (kmem_result != KERN_SUCCESS) {
+            OSKextLog(/* kext */ NULL,
+                kOSKextLogErrorLevel |
+                kOSKextLogIPCFlag,
+                "Failed to copy response to request from user space.");
+            result = kmem_result;
+            goto finish;
+        } else {
+            /* 11981737 - clear uninitialized data in last page */
+            bzero((void *)(buffer + responseLength),
+                  (round_page(responseLength) - responseLength));
+            memcpy(buffer, response, responseLength);
+            *responseOut = buffer;
+            *responseLengthOut = responseLength;
+        }
+    }
 
 finish:
 
-	/* Gather up the collected log messages for user space. Any messages
-	 * messages past this call will not make it up as log messages but
-	 * will be in the system log. Note that we ignore the return of the
-	 * serialize; it has no bearing on the operation at hand even if we
-	 * fail to get the log messages.
-	 */
-	logInfoArray = OSKext::clearUserSpaceLogFilter();
-
-	if (logInfoArray && logInfoOut && logInfoLengthOut) {
-		(void)OSKext::serializeLogInfo(logInfoArray.get(),
-		    logInfoOut, logInfoLengthOut);
-	}
-
-	IORecursiveLockUnlock(sKextLock);
-
-	return result;
-}
-
-#if PRAGMA_MARK
-#pragma mark Linked Kext Collection Support
-#endif
-
-static int
-__whereIsAddr(vm_offset_t theAddr, unsigned long *segSizes, vm_offset_t *segAddrs, int segCount)
-{
-	for (int i = 0; i < segCount; i++) {
-		vm_offset_t segStart = segAddrs[i];
-		vm_offset_t segEnd = segStart + (vm_offset_t)segSizes[i];
-
-		if (theAddr >= segStart && theAddr < segEnd) {
-			return i;
-		}
-	}
-	return -1;
-}
-
-static void
-__slideOldKaslrOffsets(kernel_mach_header_t *mh,
-    kernel_segment_command_t *kextTextSeg,
-    OSData *kaslrOffsets)
-{
-	static const char *plk_segNames[] = {
-		"__TEXT",
-		"__TEXT_EXEC",
-		"__DATA",
-		"__DATA_CONST",
-		"__LINKEDIT",
-		"__PRELINK_TEXT",
-		"__PLK_TEXT_EXEC",
-		"__PRELINK_DATA",
-		"__PLK_DATA_CONST",
-		"__PLK_LLVM_COV",
-		"__PLK_LINKEDIT",
-		"__PRELINK_INFO"
-	};
-	static const size_t num_plk_seg = (size_t)(sizeof(plk_segNames) / sizeof(plk_segNames[0]));
-
-	unsigned long plk_segSizes[num_plk_seg];
-	vm_offset_t   plk_segAddrs[num_plk_seg];
-
-	for (size_t i = 0; i < num_plk_seg; i++) {
-		plk_segSizes[i] = 0;
-		plk_segAddrs[i] = (vm_offset_t)getsegdatafromheader(mh, plk_segNames[i], &plk_segSizes[i]);
-	}
-
-	uint64_t kextTextStart = (uint64_t)kextTextSeg->vmaddr;
-
-	int slidKextAddrCount = 0;
-	int badSlideAddr = 0;
-	int badSlideTarget = 0;
-
-	struct kaslrPackedOffsets {
-		uint32_t    count;          /* number of offsets */
-		uint32_t    offsetsArray[];        /* offsets to slide */
-	};
-	const struct kaslrPackedOffsets *myOffsets = NULL;
-	myOffsets = (const struct kaslrPackedOffsets *)kaslrOffsets->getBytesNoCopy();
-
-	for (uint32_t j = 0; j < myOffsets->count; j++) {
-		uint64_t   slideOffset = (uint64_t)myOffsets->offsetsArray[j];
-		vm_offset_t *slideAddr = (vm_offset_t *)((uint64_t)kextTextStart + slideOffset);
-		int        slideAddrSegIndex = -1;
-		int        addrToSlideSegIndex = -1;
-
-		slideAddrSegIndex = __whereIsAddr((vm_offset_t)slideAddr, &plk_segSizes[0], &plk_segAddrs[0], num_plk_seg);
-		if (slideAddrSegIndex >= 0) {
-			addrToSlideSegIndex = __whereIsAddr(ml_static_slide(*slideAddr), &plk_segSizes[0], &plk_segAddrs[0], num_plk_seg);
-			if (addrToSlideSegIndex < 0) {
-				badSlideTarget++;
-				continue;
-			}
-		} else {
-			badSlideAddr++;
-			continue;
-		}
-
-		slidKextAddrCount++;
-		*slideAddr = ml_static_slide(*slideAddr);
-	}         // for ...
-}
-
-
-
-/********************************************************************
-* addKextsFromKextCollection
-*
-* Input: MachO header of kext collection. The MachO is assumed to
-*        have a section named 'info_seg_name,info_sect_name' that
-*        contains a serialized XML info dictionary. This dictionary
-*        contains a UUID, possibly a set of relocations (for older
-*        kxld-built binaries), and an array of kext personalities.
-*
-********************************************************************/
-bool
-OSKext::addKextsFromKextCollection(kernel_mach_header_t *mh,
-    OSDictionary *infoDict, const char *text_seg_name,
-    OSData **kcUUID, kc_kind_t type)
-{
-	bool result = false;
-
-	OSArray *kextArray     = NULL;        // do not release
-	OSData *infoDictKCUUID = NULL;         // do not release
-	OSData *kaslrOffsets   = NULL;        // do not release
-
-	IORegistryEntry *registryRoot = NULL;         // do not release
-	OSSharedPtr<OSNumber> kcKextCount;
-
-	/* extract the KC UUID from the dictionary */
-	infoDictKCUUID = OSDynamicCast(OSData, infoDict->getObject(kPrelinkInfoKCIDKey));
-	if (infoDictKCUUID) {
-		if (infoDictKCUUID->getLength() != sizeof(uuid_t)) {
-			panic("kcUUID length is %d, expected %lu",
-			    infoDictKCUUID->getLength(), sizeof(uuid_t));
-		}
-	}
-
-	/* locate the array of kext dictionaries */
-	kextArray = OSDynamicCast(OSArray, infoDict->getObject(kPrelinkInfoDictionaryKey));
-	if (!kextArray) {
-		OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogArchiveFlag,
-		    "The given KC has no kext info dictionaries");
-		goto finish;
-	}
-
-	/*
-	 * old-style KASLR offsets may be present in the info dictionary. If
-	 * we find them, use them and eventually slide them.
-	 */
-	kaslrOffsets = OSDynamicCast(OSData, infoDict->getObject(kPrelinkLinkKASLROffsetsKey));
-
-	/*
-	 * Before processing any kexts, locate the special kext bundle which
-	 * contains a list of kexts that we are to prevent from loading.
-	 */
-	createExcludeListFromPrelinkInfo(kextArray);
-
-	/*
-	 * Create OSKext objects for each kext we find in the array of kext
-	 * info plist dictionaries.
-	 */
-	for (int i = 0; i < (int)kextArray->getCount(); ++i) {
-		OSDictionary *kextDict = NULL;
-		kextDict = OSDynamicCast(OSDictionary, kextArray->getObject(i));
-		if (!kextDict) {
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogDirectoryScanFlag | kOSKextLogArchiveFlag,
-			    "Kext info dictionary for kext #%d isn't a dictionary?", i);
-			continue;
-		}
-
-		/*
-		 * Create the kext for the entry, then release it, because the
-		 * kext system keeps a reference around until the kext is
-		 * explicitly removed.  Any creation/registration failures are
-		 * already logged for us.
-		 */
-		withPrelinkedInfoDict(kextDict, (kaslrOffsets ? TRUE : FALSE), type);
-	}
-
-	/*
-	 * slide old-style kxld relocations
-	 * NOTE: this is still used on embedded KCs built with kcgen
-	 * TODO: Remove this once we use the new kext linker everywhere!
-	 */
-	if (kaslrOffsets && vm_kernel_slide > 0) {
-		kernel_segment_command_t *text_segment = NULL;
-		text_segment = getsegbynamefromheader(mh, text_seg_name);
-		if (!text_segment) {
-			OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogArchiveFlag,
-			    "Can't find a TEXT segment named '%s' in macho header", text_seg_name);
-			goto finish;
-		}
-
-		__slideOldKaslrOffsets(mh, text_segment, kaslrOffsets);
-		/* All kexts covered by the old-style kaslr relocation list are now slid, set VM protections for them */
-		setAllVMAttributes();
-	}
-
-	/* Store the number of prelinked kexts in the registry so we can tell
-	 * when the system has been started from a prelinked kernel.
-	 */
-	registryRoot = IORegistryEntry::getRegistryRoot();
-	assert(registryRoot);
-
-	kcKextCount = OSNumber::withNumber((unsigned long long)infoDict->getCount(), 8 * sizeof(uint32_t));
-	assert(kcKextCount);
-	if (kcKextCount) {
-		OSSharedPtr<OSObject> prop = registryRoot->copyProperty(kOSPrelinkKextCountKey);
-		OSNumber *num;
-		num = OSDynamicCast(OSNumber, prop.get());
-		if (num) {
-			kcKextCount->addValue(num->unsigned64BitValue());
-		}
-		registryRoot->setProperty(kOSPrelinkKextCountKey, kcKextCount.get());
-	}
-
-	OSKextLog(/* kext */ NULL,
-	    kOSKextLogProgressLevel |
-	    kOSKextLogGeneralFlag | kOSKextLogKextBookkeepingFlag |
-	    kOSKextLogDirectoryScanFlag | kOSKextLogArchiveFlag,
-	    "%u prelinked kexts", infoDict->getCount());
-
-
-	if (kcUUID && infoDictKCUUID) {
-		*kcUUID = OSData::withData(infoDictKCUUID).detach();
-	}
-
-	result = true;
-
-finish:
-	return result;
-}
-
-bool
-OSKext::addKextsFromKextCollection(kernel_mach_header_t *mh,
-    OSDictionary *infoDict, const char *text_seg_name,
-    OSSharedPtr<OSData> &kcUUID, kc_kind_t type)
-{
-	OSData  *result = NULL;
-	bool success = addKextsFromKextCollection(mh,
-	    infoDict,
-	    text_seg_name,
-	    &result,
-	    type);
-	if (success) {
-		kcUUID.reset(result, OSNoRetain);
-	}
-	return success;
-}
-
-static OSSharedPtr<OSObject> deferredAuxKCXML;
-bool
-OSKext::registerDeferredKextCollection(kernel_mach_header_t *mh,
-    OSSharedPtr<OSObject> &parsedXML, kc_kind_t type)
-{
-	if (type != KCKindAuxiliary) {
-		return false;
-	}
-
-	kernel_mach_header_t *_mh;
-	_mh = (kernel_mach_header_t*)PE_get_kc_header(type);
-	if (!_mh || _mh != mh) {
-		return false;
-	}
-
-	if (deferredAuxKCXML) {
-		/* only allow this to be called once */
-		OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogArchiveFlag,
-		    "An Aux KC has already been registered for deferred processing.");
-		return false;
-	}
-
-	OSDictionary *infoDict = OSDynamicCast(OSDictionary, parsedXML.get());
-	if (!infoDict) {
-		OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogArchiveFlag,
-		    "The Aux KC has info dictionary");
-		return false;
-	}
-
-	OSData *kcUUID = OSDynamicCast(OSData, infoDict->getObject(kPrelinkInfoKCIDKey));
-	if (!kcUUID || kcUUID->getLength() != sizeof(uuid_t)) {
-		OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogArchiveFlag,
-		    "The Aux KC has no UUID in %s", kPrelinkInfoKCIDKey);
-		return false;
-	}
-
-	/*
-	 * Copy the AuxKC UUID to make sure that the kern.auxiliaryfilesetuuid
-	 * sysctl can return the UUID to user space which will check this
-	 * value for errors.
-	 */
-	memcpy((void *)&auxkc_uuid, (const void *)kcUUID->getBytesNoCopy(),
-	    kcUUID->getLength());
-	uuid_unparse_upper(auxkc_uuid, auxkc_uuid_string);
-	auxkc_uuid_valid = TRUE;
-
-	deferredAuxKCXML = parsedXML;
-
-	return true;
-}
-
-OSSharedPtr<OSObject>
-OSKext::consumeDeferredKextCollection(kc_kind_t type)
-{
-	if (type != KCKindAuxiliary || !deferredAuxKCXML) {
-		return NULL;
-	}
-
-	return os::move(deferredAuxKCXML);
-}
-
-#if PRAGMA_MARK
-#pragma mark Profile-Guided-Optimization Support
-#endif
+   /* Gather up the collected log messages for user space. Any messages
+    * messages past this call will not make it up as log messages but
+    * will be in the system log. Note that we ignore the return of the
+    * serialize; it has no bearing on the operation at hand even if we
+    * fail to get the log messages.
+    */
+    logInfoArray = OSKext::clearUserSpaceLogFilter();
+
+    if (logInfoArray && logInfoOut && logInfoLengthOut) {
+        (void)OSKext::serializeLogInfo(logInfoArray,
+            logInfoOut, logInfoLengthOut);
+    }
+
+    IORecursiveLockUnlock(sKextLock);
+
+    OSSafeRelease(parsedXML);
+    OSSafeRelease(errorString);
+    OSSafeRelease(responseObject);
+    OSSafeRelease(serializer);
+    OSSafeRelease(logInfoArray);
+
+    return result;
+}
+
 
 // #include <InstrProfiling.h>
 extern "C" {
-uint64_t __llvm_profile_get_size_for_buffer_internal(
-	const char *DataBegin,
-	const char *DataEnd,
-	const char *CountersBegin,
-	const char *CountersEnd,
-	const char *BitmapBegin,
-	const char *BitmapEnd,
-	const char *NamesBegin,
-	const char *NamesEnd,
-	const char *VTableBegin,
-	const char *VTableEnd,
-	const char *VNamesBegin,
-	const char *VNamesEnd);
-int __llvm_profile_write_buffer_internal(
-	char *Buffer,
-	const char *DataBegin,
-	const char *DataEnd,
-	const char *CountersBegin,
-	const char *CountersEnd,
-	const char *BitmapBegin,
-	const char *BitmapEnd,
-	const char *NamesBegin,
-	const char *NamesEnd);
-}
+
+    uint64_t __llvm_profile_get_size_for_buffer_internal(const char *DataBegin,
+                                                         const char *DataEnd,
+                                                         const char *CountersBegin,
+                                                         const char *CountersEnd ,
+                                                         const char *NamesBegin,
+                                                         const char *NamesEnd);
+    int __llvm_profile_write_buffer_internal(char *Buffer,
+                                             const char *DataBegin,
+                                             const char *DataEnd,
+                                             const char *CountersBegin,
+                                             const char *CountersEnd ,
+                                             const char *NamesBegin,
+                                             const char *NamesEnd);
+}
+
 
 static
-void
-OSKextPgoMetadataPut(char *pBuffer,
-    size_t *position,
-    size_t bufferSize,
-    uint32_t *num_pairs,
-    const char *key,
-    const char *value)
-{
-	size_t strlen_key = strlen(key);
-	size_t strlen_value = strlen(value);
-	size_t len = strlen(key) + 1 + strlen(value) + 1;
-	char *pos = pBuffer + *position;
-	*position += len;
-	if (pBuffer && bufferSize && *position <= bufferSize) {
-		memcpy(pos, key, strlen_key); pos += strlen_key;
-		*(pos++) = '=';
-		memcpy(pos, value, strlen_value); pos += strlen_value;
-		*(pos++) = 0;
-		if (num_pairs) {
-			(*num_pairs)++;
-		}
-	}
+void OSKextPgoMetadataPut(char *pBuffer,
+                          size_t *position,
+                          size_t bufferSize,
+                          uint32_t *num_pairs,
+                          const char *key,
+                          const char *value)
+{
+    size_t strlen_key = strlen(key);
+    size_t strlen_value = strlen(value);
+    size_t len = strlen(key) + 1 + strlen(value) + 1;
+    char *pos = pBuffer + *position;
+    *position += len;
+    if (pBuffer && bufferSize && *position <= bufferSize) {
+        memcpy(pos, key, strlen_key); pos += strlen_key;
+        *(pos++) = '=';
+        memcpy(pos, value, strlen_value); pos += strlen_value;
+        *(pos++) = 0;
+        if (num_pairs) {
+            (*num_pairs)++;
+        }
+    }
 }
 
 
 static
-void
-OSKextPgoMetadataPutMax(size_t *position, const char *key, size_t value_max)
-{
-	*position += strlen(key) + 1 + value_max + 1;
+void OSKextPgoMetadataPutMax(size_t *position, const char *key, size_t value_max)
+{
+    *position += strlen(key) + 1 + value_max + 1;
 }
 
 
 static
-void
-OSKextPgoMetadataPutAll(OSKext *kext,
-    uuid_t instance_uuid,
-    char *pBuffer,
-    size_t *position,
-    size_t bufferSize,
-    uint32_t *num_pairs)
-{
-	_static_assert_1_arg(sizeof(clock_sec_t) % 2 == 0);
-	//log_10 2^16 ≈ 4.82
-	const size_t max_secs_string_size = 5 * sizeof(clock_sec_t) / 2;
-	const size_t max_timestamp_string_size = max_secs_string_size + 1 + 6;
-
-	if (!pBuffer) {
-		OSKextPgoMetadataPutMax(position, "INSTANCE", 36);
-		OSKextPgoMetadataPutMax(position, "UUID", 36);
-		OSKextPgoMetadataPutMax(position, "TIMESTAMP", max_timestamp_string_size);
-	} else {
-		uuid_string_t instance_uuid_string;
-		uuid_unparse(instance_uuid, instance_uuid_string);
-		OSKextPgoMetadataPut(pBuffer, position, bufferSize, num_pairs,
-		    "INSTANCE", instance_uuid_string);
-
-		OSSharedPtr<OSData> uuid_data;
-		uuid_t uuid;
-		uuid_string_t uuid_string;
-		uuid_data = kext->copyUUID();
-		if (uuid_data) {
-			memcpy(uuid, uuid_data->getBytesNoCopy(), sizeof(uuid));
-			uuid_unparse(uuid, uuid_string);
-			OSKextPgoMetadataPut(pBuffer, position, bufferSize, num_pairs,
-			    "UUID", uuid_string);
-		}
-
-		clock_sec_t secs;
-		clock_usec_t usecs;
-		clock_get_calendar_microtime(&secs, &usecs);
-		assert(usecs < 1000000);
-		char timestamp[max_timestamp_string_size + 1];
-		_static_assert_1_arg(sizeof(long) >= sizeof(clock_sec_t));
-		snprintf(timestamp, sizeof(timestamp), "%lu.%06d", (unsigned long)secs, (int)usecs);
-		OSKextPgoMetadataPut(pBuffer, position, bufferSize, num_pairs,
-		    "TIMESTAMP", timestamp);
-	}
-
-	OSKextPgoMetadataPut(pBuffer, position, bufferSize, num_pairs,
-	    "NAME", kext->getIdentifierCString());
-
-	char versionCString[kOSKextVersionMaxLength];
-	OSKextVersionGetString(kext->getVersion(), versionCString, kOSKextVersionMaxLength);
-	OSKextPgoMetadataPut(pBuffer, position, bufferSize, num_pairs,
-	    "VERSION", versionCString);
+void OSKextPgoMetadataPutAll(OSKext *kext,
+                             uuid_t instance_uuid,
+                             char *pBuffer,
+                             size_t *position,
+                             size_t bufferSize,
+                             uint32_t *num_pairs)
+{
+    assert_static(sizeof(clock_sec_t) % 2 == 0);
+    //log_10 2^16 ≈ 4.82
+    const size_t max_secs_string_size = 5 * sizeof(clock_sec_t)/2;
+    const size_t max_timestamp_string_size = max_secs_string_size + 1 + 6;
+
+    if (!pBuffer) {
+        OSKextPgoMetadataPutMax(position, "INSTANCE", 36);
+        OSKextPgoMetadataPutMax(position, "UUID", 36);
+        OSKextPgoMetadataPutMax(position, "TIMESTAMP", max_timestamp_string_size);
+    } else {
+        uuid_string_t instance_uuid_string;
+        uuid_unparse(instance_uuid, instance_uuid_string);
+        OSKextPgoMetadataPut(pBuffer, position, bufferSize, num_pairs,
+                             "INSTANCE", instance_uuid_string);
+
+        OSData *uuid_data;
+        uuid_t uuid;
+        uuid_string_t uuid_string;
+        uuid_data = kext->copyUUID();
+        if (uuid_data) {
+            memcpy(uuid, uuid_data->getBytesNoCopy(), sizeof(uuid));
+            OSSafeRelease(uuid_data);
+            uuid_unparse(uuid, uuid_string);
+            OSKextPgoMetadataPut(pBuffer, position, bufferSize, num_pairs,
+                                 "UUID", uuid_string);
+        }
+
+        clock_sec_t secs;
+        clock_usec_t usecs;
+        clock_get_calendar_microtime(&secs, &usecs);
+        assert(usecs < 1000000);
+        char timestamp[max_timestamp_string_size + 1];
+        assert_static(sizeof(long) >= sizeof(clock_sec_t));
+        snprintf(timestamp, sizeof(timestamp), "%lu.%06d", (unsigned long)secs, (int)usecs);
+        OSKextPgoMetadataPut(pBuffer, position, bufferSize, num_pairs,
+                             "TIMESTAMP", timestamp);
+    }
+
+    OSKextPgoMetadataPut(pBuffer, position, bufferSize, num_pairs,
+                         "NAME", kext->getIdentifierCString());
+
+    char versionCString[kOSKextVersionMaxLength];
+    OSKextVersionGetString(kext->getVersion(), versionCString, kOSKextVersionMaxLength);
+    OSKextPgoMetadataPut(pBuffer, position, bufferSize, num_pairs,
+                         "VERSION", versionCString);
+
 }
 
 static
-size_t
-OSKextPgoMetadataSize(OSKext *kext)
-{
-	size_t position = 0;
-	uuid_t fakeuuid = {};
-	OSKextPgoMetadataPutAll(kext, fakeuuid, NULL, &position, 0, NULL);
-	return position;
-}
-
-int
-OSKextGrabPgoDataLocked(OSKext *kext,
-    bool metadata,
-    uuid_t instance_uuid,
-    uint64_t *pSize,
-    char *pBuffer,
-    uint64_t bufferSize)
-{
-	int err = 0;
-
-	kernel_section_t *sect_prf_data = NULL;
-	kernel_section_t *sect_prf_name = NULL;
-	kernel_section_t *sect_prf_cnts = NULL;
-	uint64_t size;
-	size_t metadata_size = 0;
-	size_t offset_to_pairs = 0;
-
-	sect_prf_data = kext->lookupSection("__DATA", "__llvm_prf_data");
-	sect_prf_name = kext->lookupSection("__DATA", "__llvm_prf_names");
-	if (!sect_prf_name) {
-		// kextcache sometimes truncates the section name to 15 chars
-		// <rdar://problem/52080551> 16 character section name is truncated to 15 characters by kextcache
-		sect_prf_name = kext->lookupSection("__DATA", "__llvm_prf_name");
-	}
-	sect_prf_cnts = kext->lookupSection("__DATA", "__llvm_prf_cnts");
-
-	// Ignore some sections used by optional PGO variants.
-	const char *unused_section = NULL;
-
-	if (!sect_prf_data || !sect_prf_name || !sect_prf_cnts) {
-		err = ENOTSUP;
-		goto out;
-	}
-
-	size = __llvm_profile_get_size_for_buffer_internal(
-		(const char*) sect_prf_data->addr, (const char*) sect_prf_data->addr + sect_prf_data->size,
-		(const char*) sect_prf_cnts->addr, (const char*) sect_prf_cnts->addr + sect_prf_cnts->size,
-		unused_section /* bits */, unused_section /* bits end */,
-		(const char*) sect_prf_name->addr, (const char*) sect_prf_name->addr + sect_prf_name->size,
-		unused_section /* vtab */, unused_section /* vtab end */,
-		unused_section /* vnam */, unused_section /* vnam end */);
-
-	if (metadata) {
-		metadata_size = OSKextPgoMetadataSize(kext);
-		size += metadata_size;
-		size += sizeof(pgo_metadata_footer);
-	}
-
-
-	if (pSize) {
-		*pSize = size;
-	}
-
-	if (pBuffer && bufferSize) {
-		if (bufferSize < size) {
-			err = ERANGE;
-			goto out;
-		}
-
-		err = __llvm_profile_write_buffer_internal(
-			pBuffer,
-			(const char*) sect_prf_data->addr, (const char*) sect_prf_data->addr + sect_prf_data->size,
-			(const char*) sect_prf_cnts->addr, (const char*) sect_prf_cnts->addr + sect_prf_cnts->size,
-			unused_section /* bits */, unused_section /* bits end */,
-			(const char*) sect_prf_name->addr, (const char*) sect_prf_name->addr + sect_prf_name->size);
-
-		if (err) {
-			err = EIO;
-			goto out;
-		}
-
-		if (metadata) {
-			offset_to_pairs = sizeof(struct pgo_metadata_footer) + metadata_size;
-			if (offset_to_pairs > UINT32_MAX) {
-				err = E2BIG;
-				goto out;
-			}
-
-			char *end_of_buffer = pBuffer + size;
-			struct pgo_metadata_footer *footerp = (struct pgo_metadata_footer *) (end_of_buffer - sizeof(struct pgo_metadata_footer));
-			char *metadata_buffer = end_of_buffer - (sizeof(struct pgo_metadata_footer) + metadata_size);
-
-			size_t metadata_position = 0;
-			uint32_t num_pairs = 0;
-			OSKextPgoMetadataPutAll(kext, instance_uuid, metadata_buffer, &metadata_position, metadata_size, &num_pairs);
-			while (metadata_position < metadata_size) {
-				metadata_buffer[metadata_position++] = 0;
-			}
-
-			struct pgo_metadata_footer footer;
-			footer.magic = htonl(0x6d657461);
-			footer.number_of_pairs = htonl( num_pairs );
-			footer.offset_to_pairs = htonl((uint32_t)offset_to_pairs );
-			memcpy(footerp, &footer, sizeof(footer));
-		}
-	}
+size_t OSKextPgoMetadataSize(OSKext *kext)
+{
+    size_t position = 0;
+    uuid_t fakeuuid = {};
+    OSKextPgoMetadataPutAll(kext, fakeuuid, NULL, &position, 0, NULL);
+    return position;
+}
+
+
+int OSKextGrabPgoDataLocked(OSKext *kext,
+                            bool metadata,
+                            uuid_t instance_uuid,
+                            uint64_t *pSize,
+                            char *pBuffer,
+                            uint64_t bufferSize)
+{
+
+    int err = 0;
+
+    kernel_section_t *sect_prf_data = NULL;
+    kernel_section_t *sect_prf_name = NULL;
+    kernel_section_t *sect_prf_cnts = NULL;
+    uint64_t size;
+    size_t metadata_size = 0;
+
+    sect_prf_data = kext->lookupSection("__DATA", "__llvm_prf_data");
+    sect_prf_name = kext->lookupSection("__DATA", "__llvm_prf_name");
+    sect_prf_cnts = kext->lookupSection("__DATA", "__llvm_prf_cnts");
+
+    if (!sect_prf_data || !sect_prf_name || !sect_prf_cnts) {
+        err = ENOTSUP;
+        goto out;
+    }
+
+    size = __llvm_profile_get_size_for_buffer_internal(
+                         (const char*) sect_prf_data->addr, (const char*) sect_prf_data->addr + sect_prf_data->size,
+                         (const char*) sect_prf_cnts->addr, (const char*) sect_prf_cnts->addr + sect_prf_cnts->size,
+                         (const char*) sect_prf_name->addr, (const char*) sect_prf_name->addr + sect_prf_name->size);
+
+    if (metadata) {
+        metadata_size = OSKextPgoMetadataSize(kext);
+        size += metadata_size;
+        size += sizeof(pgo_metadata_footer);
+    }
+
+
+    if (pSize) {
+        *pSize = size;
+    }
+
+    if (pBuffer && bufferSize) {
+        if (bufferSize < size) {
+            err = ERANGE;
+            goto out;
+        }
+
+        err = __llvm_profile_write_buffer_internal(
+                    pBuffer,
+                    (const char*) sect_prf_data->addr, (const char*) sect_prf_data->addr + sect_prf_data->size,
+                    (const char*) sect_prf_cnts->addr, (const char*) sect_prf_cnts->addr + sect_prf_cnts->size,
+                    (const char*) sect_prf_name->addr, (const char*) sect_prf_name->addr + sect_prf_name->size);
+
+        if (err) {
+            err = EIO;
+            goto out;
+        }
+
+        if (metadata) {
+            char *end_of_buffer = pBuffer + size;
+            struct pgo_metadata_footer *footerp = (struct pgo_metadata_footer *) (end_of_buffer - sizeof(struct pgo_metadata_footer));
+            char *metadata_buffer = end_of_buffer - (sizeof(struct pgo_metadata_footer) + metadata_size);
+
+            size_t metadata_position = 0;
+            uint32_t num_pairs = 0;
+            OSKextPgoMetadataPutAll(kext, instance_uuid, metadata_buffer, &metadata_position, metadata_size, &num_pairs);
+            while (metadata_position < metadata_size) {
+                metadata_buffer[metadata_position++] = 0;
+            }
+
+            struct pgo_metadata_footer footer;
+            footer.magic = htonl(0x6d657461);
+            footer.number_of_pairs = htonl( num_pairs );
+            footer.offset_to_pairs = htonl( sizeof(struct pgo_metadata_footer) + metadata_size );
+            memcpy(footerp, &footer, sizeof(footer));
+        }
+
+    }
 
 out:
-	return err;
+    return err;
 }
 
 
 int
 OSKextGrabPgoData(uuid_t uuid,
-    uint64_t *pSize,
-    char *pBuffer,
-    uint64_t bufferSize,
-    int wait_for_unload,
-    int metadata)
-{
-	int err = 0;
-	OSSharedPtr<OSKext> kext;
-
-
-	IORecursiveLockLock(sKextLock);
-
-	kext = OSKext::lookupKextWithUUID(uuid);
-	if (!kext) {
-		err = ENOENT;
-		goto out;
-	}
-
-	if (wait_for_unload) {
-		OSKextGrabPgoStruct s;
-
-		s.metadata = metadata;
-		s.pSize = pSize;
-		s.pBuffer = pBuffer;
-		s.bufferSize = bufferSize;
-		s.err = EINTR;
-
-		struct list_head *prev = &kext->pendingPgoHead;
-		struct list_head *next = kext->pendingPgoHead.next;
-
-		s.list_head.prev = prev;
-		s.list_head.next = next;
-
-		prev->next = &s.list_head;
-		next->prev = &s.list_head;
-
-		kext.reset();
-
-		IORecursiveLockSleep(sKextLock, &s, THREAD_ABORTSAFE);
-
-		prev = s.list_head.prev;
-		next = s.list_head.next;
-
-		prev->next = next;
-		next->prev = prev;
-
-		err = s.err;
-	} else {
-		err = OSKextGrabPgoDataLocked(kext.get(), metadata, kext->instance_uuid, pSize, pBuffer, bufferSize);
-	}
-
-out:
-
-	IORecursiveLockUnlock(sKextLock);
-
-	return err;
-}
-
-void
-OSKextResetPgoCountersLock()
-{
-	IORecursiveLockLock(sKextLock);
-}
-
-void
-OSKextResetPgoCountersUnlock()
-{
-	IORecursiveLockUnlock(sKextLock);
-}
-
-
-extern unsigned int not_in_kdp;
-
-void
-OSKextResetPgoCounters()
-{
-	assert(!not_in_kdp);
-	uint32_t count = sLoadedKexts->getCount();
-	for (uint32_t i = 0; i < count; i++) {
-		OSKext *kext = OSDynamicCast(OSKext, sLoadedKexts->getObject(i));
-		kernel_section_t *sect_prf_cnts = kext->lookupSection("__DATA", "__llvm_prf_cnts");
-		if (!sect_prf_cnts) {
-			continue;
-		}
-		memset((void*)sect_prf_cnts->addr, 0, sect_prf_cnts->size);
-	}
-}
-
-OSSharedPtr<OSDictionary>
-OSKext::copyLoadedKextInfoByUUID(
-	OSArray * kextIdentifiers,
-	OSArray * infoKeys)
-{
-	OSSharedPtr<OSDictionary> result;
-	OSSharedPtr<OSDictionary> kextInfo;
-	uint32_t       max_count, i, j;
-	uint32_t       idCount = 0;
-	uint32_t       idIndex = 0;
-	IORecursiveLockLock(sKextLock);
-	OSArray *list[2] = {sLoadedKexts.get(), sLoadedDriverKitKexts.get()};
-	uint32_t count[2] = {sLoadedKexts->getCount(), sLoadedDriverKitKexts->getCount()};
+                  uint64_t *pSize,
+                  char *pBuffer,
+                  uint64_t bufferSize,
+                  int wait_for_unload,
+                  int metadata)
+{
+    int err = 0;
+    OSKext *kext = NULL;
+
+
+    IORecursiveLockLock(sKextLock);
+
+    kext = OSKext::lookupKextWithUUID(uuid);
+    if (!kext)  {
+        err = ENOENT;
+        goto out;
+    }
+
+    if (wait_for_unload) {
+        OSKextGrabPgoStruct s;
+
+        s.metadata = metadata;
+        s.pSize = pSize;
+        s.pBuffer = pBuffer;
+        s.bufferSize = bufferSize;
+        s.err = EINTR;
+
+        struct list_head *prev = &kext->pendingPgoHead;
+        struct list_head *next = kext->pendingPgoHead.next;
+
+        s.list_head.prev = prev;
+        s.list_head.next = next;
+
+        prev->next = &s.list_head;
+        next->prev = &s.list_head;
+
+        kext->release();
+        kext = NULL;
+
+        IORecursiveLockSleep(sKextLock, &s, THREAD_ABORTSAFE);
+
+        prev = s.list_head.prev;
+        next = s.list_head.next;
+
+        prev->next = next;
+        next->prev = prev;
+
+        err = s.err;
+
+    } else {
+        err = OSKextGrabPgoDataLocked(kext, metadata, kext->instance_uuid, pSize, pBuffer, bufferSize);
+    }
+
+ out:
+    if (kext) {
+        kext->release();
+    }
+
+    IORecursiveLockUnlock(sKextLock);
+
+    return err;
+}
+
+
+/*********************************************************************
+*********************************************************************/
+/* static */
+OSDictionary *
+OSKext::copyLoadedKextInfo(
+    OSArray * kextIdentifiers,
+    OSArray * infoKeys) 
+{
+    OSDictionary * result = NULL;
+    OSDictionary * kextInfo = NULL;  // must release
+    uint32_t       count, i;
+    uint32_t       idCount = 0;
+    uint32_t       idIndex = 0;
+
+    IORecursiveLockLock(sKextLock);
 
 #if CONFIG_MACF
-	/* Is the calling process allowed to query kext info? */
-	if (current_task() != kernel_task) {
-		int                 macCheckResult      = 0;
-		kauth_cred_t        cred                = NULL;
-
-		cred = kauth_cred_get_with_ref();
-		macCheckResult = mac_kext_check_query(cred);
-		kauth_cred_unref(&cred);
-
-		if (macCheckResult != 0) {
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogErrorLevel | kOSKextLogLoadFlag,
-			    "Failed to query kext info (MAC policy error 0x%x).",
-			    macCheckResult);
-			goto finish;
-		}
-	}
+    /* Is the calling process allowed to query kext info? */
+    if (current_task() != kernel_task) {
+        int                 macCheckResult      = 0;
+        kauth_cred_t        cred                = NULL;
+
+        cred = kauth_cred_get_with_ref();
+        macCheckResult = mac_kext_check_query(cred);
+        kauth_cred_unref(&cred);
+
+        if (macCheckResult != 0) {
+            OSKextLog(/* kext */ NULL,
+                      kOSKextLogErrorLevel | kOSKextLogLoadFlag,
+                      "Failed to query kext info (MAC policy error 0x%x).",
+                      macCheckResult);
+            goto finish;
+        }
+   }
 #endif
 
-	/* Empty list of UUIDs is equivalent to no list (get all).
-	 */
-	if (kextIdentifiers && !kextIdentifiers->getCount()) {
-		kextIdentifiers = NULL;
-	} else if (kextIdentifiers) {
-		idCount = kextIdentifiers->getCount();
-	}
-
-	/* Same for keys.
-	 */
-	if (infoKeys && !infoKeys->getCount()) {
-		infoKeys = NULL;
-	}
-
-	max_count = count[0] + count[1];
-	result = OSDictionary::withCapacity(max_count);
-	if (!result) {
-		goto finish;
-	}
-
-	for (j = 0; j < (sizeof(list) / sizeof(list[0])); j++) {
-		for (i = 0; i < count[j]; i++) {
-			OSKext       *thisKext     = NULL;        // do not release
-			Boolean       includeThis  = true;
-			uuid_t        thisKextUUID;
-			uuid_t        thisKextTextUUID;
-			OSSharedPtr<OSData> uuid_data;
-			uuid_string_t uuid_key;
-
-			thisKext = OSDynamicCast(OSKext, list[j]->getObject(i));
-			if (!thisKext) {
-				continue;
-			}
-
-			uuid_data = thisKext->copyUUID();
-			if (!uuid_data) {
-				continue;
-			}
-
-			memcpy(&thisKextUUID, uuid_data->getBytesNoCopy(), sizeof(thisKextUUID));
-
-			uuid_unparse(thisKextUUID, uuid_key);
-
-			uuid_data = thisKext->copyTextUUID();
-			if (!uuid_data) {
-				continue;
-			}
-			memcpy(&thisKextTextUUID, uuid_data->getBytesNoCopy(), sizeof(thisKextTextUUID));
-
-			/* Skip current kext if we have a list of UUIDs and
-			 * it isn't in the list.
-			 */
-			if (kextIdentifiers) {
-				includeThis = false;
-
-				for (idIndex = 0; idIndex < idCount; idIndex++) {
-					const OSString* wantedUUID = OSDynamicCast(OSString,
-					    kextIdentifiers->getObject(idIndex));
-
-					uuid_t uuid;
-					uuid_parse(wantedUUID->getCStringNoCopy(), uuid);
-
-					if ((0 == uuid_compare(uuid, thisKextUUID))
-					    || (0 == uuid_compare(uuid, thisKextTextUUID))) {
-						includeThis = true;
-						/* Only need to find the first kext if multiple match,
-						 * ie. asking for the kernel uuid does not need to find
-						 * interface kexts or builtin static kexts.
-						 */
-						kextIdentifiers->removeObject(idIndex);
-						uuid_unparse(uuid, uuid_key);
-						break;
-					}
-				}
-			}
-
-			if (!includeThis) {
-				continue;
-			}
-
-			kextInfo = thisKext->copyInfo(infoKeys);
-			if (kextInfo) {
-				result->setObject(uuid_key, kextInfo.get());
-			}
-
-			if (kextIdentifiers && !kextIdentifiers->getCount()) {
-				goto finish;
-			}
-		}
-	}
-
+   /* Empty list of bundle ids is equivalent to no list (get all).
+    */
+    if (kextIdentifiers && !kextIdentifiers->getCount()) {
+        kextIdentifiers = NULL;
+    } else if (kextIdentifiers) {
+        idCount = kextIdentifiers->getCount();
+    }
+
+   /* Same for keys.
+    */
+    if (infoKeys && !infoKeys->getCount()) {
+        infoKeys = NULL;
+    }
+
+    count = sLoadedKexts->getCount();
+    result = OSDictionary::withCapacity(count);
+    if (!result) {
+        goto finish;
+    }
+
+#if 0
+    OSKextLog(/* kext */ NULL,
+              kOSKextLogErrorLevel |
+              kOSKextLogGeneralFlag,
+              "kaslr: vm_kernel_slide 0x%lx \n",
+              vm_kernel_slide);
+    OSKextLog(/* kext */ NULL,
+              kOSKextLogErrorLevel |
+              kOSKextLogGeneralFlag,
+              "kaslr: vm_kernel_stext 0x%lx vm_kernel_etext 0x%lx \n",
+              vm_kernel_stext, vm_kernel_etext);
+    OSKextLog(/* kext */ NULL,
+              kOSKextLogErrorLevel |
+              kOSKextLogGeneralFlag,
+              "kaslr: vm_kernel_base 0x%lx vm_kernel_top 0x%lx \n",
+              vm_kernel_base, vm_kernel_top);
+    OSKextLog(/* kext */ NULL,
+              kOSKextLogErrorLevel |
+              kOSKextLogGeneralFlag,
+              "kaslr: vm_kext_base 0x%lx vm_kext_top 0x%lx \n",
+              vm_kext_base, vm_kext_top);
+    OSKextLog(/* kext */ NULL,
+              kOSKextLogErrorLevel |
+              kOSKextLogGeneralFlag,
+              "kaslr: vm_prelink_stext 0x%lx vm_prelink_etext 0x%lx \n",
+              vm_prelink_stext, vm_prelink_etext);
+    OSKextLog(/* kext */ NULL,
+              kOSKextLogErrorLevel |
+              kOSKextLogGeneralFlag,
+              "kaslr: vm_prelink_sinfo 0x%lx vm_prelink_einfo 0x%lx \n",
+              vm_prelink_sinfo, vm_prelink_einfo);
+    OSKextLog(/* kext */ NULL,
+              kOSKextLogErrorLevel |
+              kOSKextLogGeneralFlag,
+              "kaslr: vm_slinkedit 0x%lx vm_elinkedit 0x%lx \n",
+              vm_slinkedit, vm_elinkedit);
+#endif
+
+    for (i = 0; i < count; i++) {
+        OSKext   * thisKext     = NULL;  // do not release
+        Boolean    includeThis  = true;
+
+        if (kextInfo) {
+            kextInfo->release();
+            kextInfo = NULL;
+        }
+        thisKext = OSDynamicCast(OSKext, sLoadedKexts->getObject(i));
+        if (!thisKext) {
+            continue;
+        }
+
+       /* Skip current kext if we have a list of bundle IDs and
+        * it isn't in the list.
+        */
+        if (kextIdentifiers) {
+            const OSString * thisKextID = thisKext->getIdentifier();
+
+            includeThis = false;
+
+            for (idIndex = 0; idIndex < idCount; idIndex++) {
+                const OSString * thisRequestID = OSDynamicCast(OSString,
+                    kextIdentifiers->getObject(idIndex));
+                if (thisKextID->isEqualTo(thisRequestID)) {
+                    includeThis = true;
+                    break;
+                }
+            }
+        }
+        
+        if (!includeThis) {
+            continue;
+        }
+
+        kextInfo = thisKext->copyInfo(infoKeys);
+        if (kextInfo) {
+            result->setObject(thisKext->getIdentifier(), kextInfo);
+        }
+    }
+    
 finish:
-	IORecursiveLockUnlock(sKextLock);
-
-	return result;
-}
-
-/*********************************************************************
-*********************************************************************/
-/* static */
-OSSharedPtr<OSDictionary>
-OSKext::copyKextCollectionInfo(
-	OSDictionary *requestDict,
-	OSArray  *infoKeys)
-{
-	OSSharedPtr<OSDictionary> result;
-	OSString *collectionType = NULL;
-	OSObject *rawLoadedState = NULL;
-	OSString *loadedState    = NULL;
-
-	kc_kind_t kc_request_kind = KCKindUnknown;
-	bool onlyLoaded = false;
-	bool onlyUnloaded = false;
-
-#if CONFIG_MACF
-	/* Is the calling process allowed to query kext info? */
-	if (current_task() != kernel_task) {
-		int                 macCheckResult      = 0;
-		kauth_cred_t        cred                = NULL;
-
-		cred = kauth_cred_get_with_ref();
-		macCheckResult = mac_kext_check_query(cred);
-		kauth_cred_unref(&cred);
-
-		if (macCheckResult != 0) {
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogErrorLevel | kOSKextLogLoadFlag,
-			    "Failed to query kext info (MAC policy error 0x%x).",
-			    macCheckResult);
-			goto finish;
-		}
-	}
-#endif
-
-	if (infoKeys && !infoKeys->getCount()) {
-		infoKeys = NULL;
-	}
-
-	collectionType = OSDynamicCast(OSString,
-	    _OSKextGetRequestArgument(requestDict,
-	    kKextRequestArgumentCollectionTypeKey));
-	if (!collectionType) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogIPCFlag,
-		    "Invalid '%s' argument to kext collection info request.",
-		    kKextRequestArgumentCollectionTypeKey);
-		goto finish;
-	}
-	if (collectionType->isEqualTo(kKCTypePrimary)) {
-		kc_request_kind = KCKindPrimary;
-	} else if (collectionType->isEqualTo(kKCTypeSystem)) {
-		kc_request_kind = KCKindPageable;
-	} else if (collectionType->isEqualTo(kKCTypeAuxiliary)) {
-		kc_request_kind = KCKindAuxiliary;
-	} else if (collectionType->isEqualTo(kKCTypeCodeless)) {
-		kc_request_kind = KCKindNone;
-	} else if (!collectionType->isEqualTo(kKCTypeAny)) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogIPCFlag,
-		    "Invalid '%s' argument value '%s' to kext collection info request.",
-		    kKextRequestArgumentCollectionTypeKey,
-		    collectionType->getCStringNoCopy());
-		goto finish;
-	}
-
-	rawLoadedState = _OSKextGetRequestArgument(requestDict,
-	    kKextRequestArgumentLoadedStateKey);
-	if (rawLoadedState) {
-		loadedState = OSDynamicCast(OSString, rawLoadedState);
-		if (!loadedState) {
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogErrorLevel |
-			    kOSKextLogIPCFlag,
-			    "Invalid '%s' argument to kext collection info request.",
-			    kKextRequestArgumentLoadedStateKey);
-			goto finish;
-		}
-	}
-	if (loadedState) {
-		if (loadedState->isEqualTo("Loaded")) {
-			onlyLoaded = true;
-		} else if (loadedState->isEqualTo("Unloaded")) {
-			onlyUnloaded = true;
-		} else if (!loadedState->isEqualTo("Any")) {
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogErrorLevel | kOSKextLogLoadFlag,
-			    "Invalid '%s' argument value '%s' for '%s' collection info",
-			    kKextRequestArgumentLoadedStateKey,
-			    loadedState->getCStringNoCopy(),
-			    collectionType->getCStringNoCopy());
-			goto finish;
-		}
-	}
-
-	result = OSDictionary::withCapacity(sKextsByID->getCount());
-	if (!result) {
-		goto finish;
-	}
-
-	IORecursiveLockLock(sKextLock);
-	{         // start block scope
-		sKextsByID->iterateObjects(^bool (const OSSymbol *thisKextID, OSObject *obj)
-		{
-			OSKext       *thisKext    = NULL;  // do not release
-			OSSharedPtr<OSDictionary> kextInfo;
-
-			(void)thisKextID;
-
-			thisKext = OSDynamicCast(OSKext, obj);
-			if (!thisKext) {
-			        return false;
-			}
-
-			/*
-			 * skip the kext if it came from the wrong collection type
-			 * (and the caller requested a specific type)
-			 */
-			if ((kc_request_kind != KCKindUnknown) && (thisKext->kc_type != kc_request_kind)) {
-			        return false;
-			}
-
-			/*
-			 * respect the caller's desire to find only loaded or
-			 * unloaded kexts
-			 */
-			if (onlyLoaded && (-1U == sLoadedKexts->getNextIndexOfObject(thisKext, 0))) {
-			        return false;
-			}
-			if (onlyUnloaded && (-1U != sLoadedKexts->getNextIndexOfObject(thisKext, 0))) {
-			        return false;
-			}
-
-			kextInfo = thisKext->copyInfo(infoKeys);
-			if (kextInfo) {
-			        result->setObject(thisKext->getIdentifier(), kextInfo.get());
-			}
-			return false;
-		});
-	} // end block scope
-	IORecursiveLockUnlock(sKextLock);
-
-finish:
-	return result;
-}
-
-/* static */
-OSSharedPtr<OSArray>
-OSKext::copyDextsInfo(
-	OSArray *kextIdentifiers,
-	OSArray *infoKeys)
-{
-	OSSharedPtr<OSArray> result = NULL;
-	uint32_t idCount = 0;
-	bool getActive = false;
-	bool getLoaded = false;
-	bool getUnloaded = false;
-	bool getPendingUpgrade = false;
-	unsigned int avgDextCount = 0;
-
-#if CONFIG_MACF
-	/* Is the calling process allowed to query dext info? */
-	if (current_task() != kernel_task) {
-		int                 macCheckResult      = 0;
-		kauth_cred_t        cred                = NULL;
-
-		cred = kauth_cred_get_with_ref();
-		macCheckResult = mac_kext_check_query(cred);
-		kauth_cred_unref(&cred);
-
-		if (macCheckResult != 0) {
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogErrorLevel | kOSKextLogLoadFlag,
-			    "Failed to query kext info (MAC policy error 0x%x).",
-			    macCheckResult);
-			goto finish;
-		}
-	}
-#endif
-	/*
-	 * No infoKeys means return everything we
-	 * know about the dexts.
-	 */
-	if (infoKeys && !infoKeys->getCount()) {
-		infoKeys = NULL;
-	}
-
-	/*
-	 * Empty list of bundle ids is equivalent to
-	 * no list (get all).
-	 */
-	if (kextIdentifiers && !kextIdentifiers->getCount()) {
-		kextIdentifiers = NULL;
-	} else if (kextIdentifiers) {
-		idCount = kextIdentifiers->getCount();
-	}
-
-	/*
-	 * Caller can specify which state of dexts to query.
-	 */
-	if (infoKeys && _OSArrayContainsCString(infoKeys, kOSBundleDextStateActiveKey)) {
-		getActive = true;
-	}
-	if (infoKeys && _OSArrayContainsCString(infoKeys, kOSBundleDextStateActiveLoadedKey)) {
-		getLoaded = true;
-	}
-	if (infoKeys && _OSArrayContainsCString(infoKeys, kOSBundleDextStateActiveUnloadedKey)) {
-		getUnloaded = true;
-	}
-	if (infoKeys && _OSArrayContainsCString(infoKeys, kOSBundleDextStatePendingUpgradeKey)) {
-		getPendingUpgrade = true;
-	}
-
-	/*
-	 * By default we are going to return all active and pendingUpgrade dexts
-	 * only.
-	 */
-	if (!(getActive || getLoaded || getUnloaded || getPendingUpgrade)) {
-		getActive = true;
-		getPendingUpgrade = true;
-	}
-
-	/*
-	 * We return a dictionary of dexts
-	 * for every group requested.
-	 */
-	avgDextCount = sLoadedDriverKitKexts->getCount() + sDriverKitToUpgradeByID->getCount();
-	result = OSArray::withCapacity(avgDextCount);
-	if (!result) {
-		goto finish;
-	}
-
-	IORecursiveLockLock(sKextLock);
-	{ // start block scope
-		if (getActive || getLoaded || getUnloaded) {
-			sKextsByID->iterateObjects(^bool (const OSSymbol *thisKextID, OSObject *obj)
-			{
-				OSKext *thisKext = NULL;  // do not release
-				OSSharedPtr<OSDictionary> kextInfo;
-				Boolean includeThis = true;
-				(void)thisKextID;
-
-				thisKext = OSDynamicCast(OSKext, obj);
-				if (!thisKext || !thisKext->isDriverKit()) {
-				        return false;
-				}
-
-				/*
-				 * Skip current dext if we have a list of bundle IDs and
-				 * it isn't in the list.
-				 */
-				if (kextIdentifiers) {
-				        includeThis = false;
-
-				        for (uint32_t idIndex = 0; idIndex < idCount; idIndex++) {
-				                const OSString * thisRequestID = OSDynamicCast(OSString,
-				                kextIdentifiers->getObject(idIndex));
-				                if (thisKextID->isEqualTo(thisRequestID)) {
-				                        includeThis = true;
-				                        break;
-						}
-					}
-				}
-
-				if (!includeThis) {
-				        return false;
-				}
-
-				OSSharedPtr<OSString> state;
-				if (sLoadedDriverKitKexts->getNextIndexOfObject(thisKext, 0) == -1U) {
-				        if (!(getActive || getUnloaded)) {
-				                return false;
-					}
-				        state = OSString::withCString(kOSBundleDextStateActiveUnloadedKey);
-				} else {
-				        if (!(getActive || getLoaded)) {
-				                return false;
-					}
-				        state = OSString::withCString(kOSBundleDextStateActiveLoadedKey);
-				}
-
-				kextInfo = thisKext->copyInfo(infoKeys);
-				if (kextInfo) {
-				        kextInfo->setObject(kOSBundleDextStateKey, state.get());
-				        result->setObject(kextInfo.get());
-				}
-
-				return false;
-			});
-		}
-
-		if (getPendingUpgrade) {
-			sDriverKitToUpgradeByID->iterateObjects(^bool (const OSSymbol *thisKextID, OSObject *obj)
-			{
-				OSKext *thisKext = NULL;  // do not release
-				OSSharedPtr<OSDictionary> kextInfo;
-				Boolean includeThis = true;
-				(void)thisKextID;
-
-				thisKext = OSDynamicCast(OSKext, obj);
-				if (!thisKext) {
-				        return false;
-				}
-				__assert_only bool isDext = thisKext->isDriverKit();
-				assert(isDext == true);
-
-				/*
-				 * Skip current dext if we have a list of bundle IDs and
-				 * it isn't in the list.
-				 */
-				if (kextIdentifiers) {
-				        includeThis = false;
-
-				        for (uint32_t idIndex = 0; idIndex < idCount; idIndex++) {
-				                const OSString * thisRequestID = OSDynamicCast(OSString,
-				                kextIdentifiers->getObject(idIndex));
-				                if (thisKextID->isEqualTo(thisRequestID)) {
-				                        includeThis = true;
-				                        break;
-						}
-					}
-				}
-
-				if (!includeThis) {
-				        return false;
-				}
-
-				kextInfo = thisKext->copyInfo(infoKeys);
-				if (kextInfo) {
-				        OSSharedPtr<OSString> state = OSString::withCString(kOSBundleDextStatePendingUpgradeKey);
-				        kextInfo->setObject(kOSBundleDextStateKey, state.get());
-				        result->setObject(kextInfo.get());
-				}
-				return false;
-			});
-		}
-	} // end block scope
-	IORecursiveLockUnlock(sKextLock);
-finish:
-	return result;
-}
-
-/*********************************************************************
-*********************************************************************/
-/* static */
-OSSharedPtr<OSDictionary>
-OSKext::copyLoadedKextInfo(
-	OSArray * kextIdentifiers,
-	OSArray * infoKeys)
-{
-	OSSharedPtr<OSDictionary> result;
-	uint32_t       idCount = 0;
-	bool           onlyLoaded;
-
-	IORecursiveLockLock(sKextLock);
-
-#if CONFIG_MACF
-	/* Is the calling process allowed to query kext info? */
-	if (current_task() != kernel_task) {
-		int                 macCheckResult      = 0;
-		kauth_cred_t        cred                = NULL;
-
-		cred = kauth_cred_get_with_ref();
-		macCheckResult = mac_kext_check_query(cred);
-		kauth_cred_unref(&cred);
-
-		if (macCheckResult != 0) {
-			OSKextLog(/* kext */ NULL,
-			    kOSKextLogErrorLevel | kOSKextLogLoadFlag,
-			    "Failed to query kext info (MAC policy error 0x%x).",
-			    macCheckResult);
-			goto finish;
-		}
-	}
-#endif
-
-	/* Empty list of bundle ids is equivalent to no list (get all).
-	 */
-	if (kextIdentifiers && !kextIdentifiers->getCount()) {
-		kextIdentifiers = NULL;
-	} else if (kextIdentifiers) {
-		idCount = kextIdentifiers->getCount();
-	}
-
-	/* Same for keys.
-	 */
-	if (infoKeys && !infoKeys->getCount()) {
-		infoKeys = NULL;
-	}
-
-	onlyLoaded =  (!infoKeys || !_OSArrayContainsCString(infoKeys, kOSBundleAllPrelinkedKey));
-
-	result = OSDictionary::withCapacity(128);
-	if (!result) {
-		goto finish;
-	}
-
-#if 0
-	OSKextLog(/* kext */ NULL,
-	    kOSKextLogErrorLevel |
-	    kOSKextLogGeneralFlag,
-	    "kaslr: vm_kernel_slide 0x%lx \n",
-	    vm_kernel_slide);
-	OSKextLog(/* kext */ NULL,
-	    kOSKextLogErrorLevel |
-	    kOSKextLogGeneralFlag,
-	    "kaslr: vm_kernel_stext 0x%lx vm_kernel_etext 0x%lx \n",
-	    vm_kernel_stext, vm_kernel_etext);
-	OSKextLog(/* kext */ NULL,
-	    kOSKextLogErrorLevel |
-	    kOSKextLogGeneralFlag,
-	    "kaslr: vm_kernel_base 0x%lx vm_kernel_top 0x%lx \n",
-	    vm_kernel_base, vm_kernel_top);
-	OSKextLog(/* kext */ NULL,
-	    kOSKextLogErrorLevel |
-	    kOSKextLogGeneralFlag,
-	    "kaslr: vm_kext_base 0x%lx vm_kext_top 0x%lx \n",
-	    vm_kext_base, vm_kext_top);
-	OSKextLog(/* kext */ NULL,
-	    kOSKextLogErrorLevel |
-	    kOSKextLogGeneralFlag,
-	    "kaslr: vm_prelink_stext 0x%lx vm_prelink_etext 0x%lx \n",
-	    vm_prelink_stext, vm_prelink_etext);
-	OSKextLog(/* kext */ NULL,
-	    kOSKextLogErrorLevel |
-	    kOSKextLogGeneralFlag,
-	    "kaslr: vm_prelink_sinfo 0x%lx vm_prelink_einfo 0x%lx \n",
-	    vm_prelink_sinfo, vm_prelink_einfo);
-	OSKextLog(/* kext */ NULL,
-	    kOSKextLogErrorLevel |
-	    kOSKextLogGeneralFlag,
-	    "kaslr: vm_slinkedit 0x%lx vm_elinkedit 0x%lx \n",
-	    vm_slinkedit, vm_elinkedit);
-#endif
-	{         // start block scope
-		sKextsByID->iterateObjects(^bool (const OSSymbol * thisKextID, OSObject * obj)
-		{
-			OSKext       * thisKext     = NULL;        // do not release
-			Boolean        includeThis  = true;
-			OSSharedPtr<OSDictionary> kextInfo;
-
-			thisKext = OSDynamicCast(OSKext, obj);
-			if (!thisKext) {
-			        return false;
-			}
-
-			/* Skip current kext if not yet started and caller didn't request all.
-			 */
-			if (onlyLoaded && (-1U == sLoadedKexts->getNextIndexOfObject(thisKext, 0))) {
-			        return false;
-			}
-
-			/* Skip current kext if we have a list of bundle IDs and
-			 * it isn't in the list.
-			 */
-			if (kextIdentifiers) {
-			        includeThis = false;
-
-			        for (uint32_t idIndex = 0; idIndex < idCount; idIndex++) {
-			                const OSString * thisRequestID = OSDynamicCast(OSString,
-			                kextIdentifiers->getObject(idIndex));
-			                if (thisKextID->isEqualTo(thisRequestID)) {
-			                        includeThis = true;
-			                        break;
-					}
-				}
-			}
-
-			if (!includeThis) {
-			        return false;
-			}
-
-			kextInfo = thisKext->copyInfo(infoKeys);
-			if (kextInfo) {
-			        result->setObject(thisKext->getIdentifier(), kextInfo.get());
-			}
-			return false;
-		});
-	}         // end block scope
-
-finish:
-	IORecursiveLockUnlock(sKextLock);
-
-	return result;
+    IORecursiveLockUnlock(sKextLock);
+
+    if (kextInfo) kextInfo->release();
+
+    return result;
 }
 
 /*********************************************************************
@@ -12033,1023 +8311,624 @@
 *********************************************************************/
 #define _OSKextLoadInfoDictCapacity   (12)
 
-OSSharedPtr<OSDictionary>
+OSDictionary *
 OSKext::copyInfo(OSArray * infoKeys)
 {
-	OSSharedPtr<OSDictionary>  result;
-	bool                       success                     = false;
-	OSSharedPtr<OSData>        headerData;
-	OSSharedPtr<OSData>        logData;
-	OSSharedPtr<OSNumber>      cpuTypeNumber;
-	OSSharedPtr<OSNumber>      cpuSubtypeNumber;
-	OSString                 * versionString               = NULL;        // do not release
-	OSString                 * bundleType                  = NULL;        // do not release
-	uint32_t                   executablePathCStringSize   = 0;
-	char                     * executablePathCString       = NULL;        // must kfree
-	OSSharedPtr<OSString>      executablePathString;
-	OSSharedPtr<OSData>        uuid;
-	OSSharedPtr<OSArray>       dependencyLoadTags;
-	OSSharedPtr<OSCollectionIterator>      metaClassIterator;
-	OSSharedPtr<OSArray>       metaClassInfo;
-	OSSharedPtr<OSDictionary>  metaClassDict;
-	OSMetaClass              * thisMetaClass               = NULL;        // do not release
-	OSSharedPtr<OSString>      metaClassName;
-	OSSharedPtr<OSString>      superclassName;
-	kc_format_t                kcformat;
-	uint32_t                   count, i;
-
-	result = OSDictionary::withCapacity(_OSKextLoadInfoDictCapacity);
-	if (!result) {
-		goto finish;
-	}
-
-
-	/* Empty keys means no keys, but NULL is quicker to check.
-	 */
-	if (infoKeys && !infoKeys->getCount()) {
-		infoKeys = NULL;
-	}
-
-	if (!PE_get_primary_kc_format(&kcformat)) {
-		goto finish;
-	}
-
-	/* Headers, CPU type, and CPU subtype.
-	 */
-	if (!infoKeys ||
-	    _OSArrayContainsCString(infoKeys, kOSBundleMachOHeadersKey) ||
-	    _OSArrayContainsCString(infoKeys, kOSBundleLogStringsKey) ||
-	    _OSArrayContainsCString(infoKeys, kOSBundleCPUTypeKey) ||
-	    _OSArrayContainsCString(infoKeys, kOSBundleCPUSubtypeKey)) {
-		if (linkedExecutable && !isInterface()) {
-			kernel_mach_header_t *kext_mach_hdr = (kernel_mach_header_t *)
-			    linkedExecutable->getBytesNoCopy();
-
-#if !SECURE_KERNEL || XNU_TARGET_OS_OSX
-			// do not return macho header info on shipping embedded - 19095897
-			if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleMachOHeadersKey)) {
-				kernel_mach_header_t *  temp_kext_mach_hdr;
-				struct load_command *   lcp;
-
-				headerData = OSData::withBytes(kext_mach_hdr,
-				    (u_int) (sizeof(*kext_mach_hdr) + kext_mach_hdr->sizeofcmds));
-				if (!headerData) {
-					goto finish;
-				}
-
-				// unslide any vmaddrs we return to userspace - 10726716
-				temp_kext_mach_hdr = (kernel_mach_header_t *)
-				    headerData->getBytesNoCopy();
-				if (temp_kext_mach_hdr == NULL) {
-					goto finish;
-				}
-
-				lcp = (struct load_command *) (temp_kext_mach_hdr + 1);
-				for (i = 0; (i < temp_kext_mach_hdr->ncmds) && !flags.unslidMachO; i++) {
-					if (lcp->cmd == LC_SEGMENT_KERNEL) {
-						kernel_segment_command_t *  segp;
-						kernel_section_t *          secp;
-
-						segp = (kernel_segment_command_t *) lcp;
-						// 10543468 - if we jettisoned __LINKEDIT clear size info
-						if (flags.jettisonLinkeditSeg) {
-							if (strncmp(segp->segname, SEG_LINKEDIT, sizeof(segp->segname)) == 0) {
-								segp->vmsize = 0;
-								segp->fileoff = 0;
-								segp->filesize = 0;
-							}
-						}
-
-#if __arm__ || __arm64__
-						// iBoot disregards zero-size segments, just set their addresses to gVirtBase
-						// and unslide them to avoid vm assertion failures / kernel logging breakage.
-						if (segp->vmsize == 0 && segp->vmaddr < gVirtBase) {
-							segp->vmaddr = gVirtBase;
-							for (secp = firstsect(segp); secp != NULL; secp = nextsect(segp, secp)) {
-								secp->size = 0; // paranoia :)
-								secp->addr = gVirtBase;
-							}
-						}
+    OSDictionary         * result                      = NULL;
+    bool                   success                     = false;
+    OSData               * headerData                  = NULL;  // must release
+    OSNumber             * cpuTypeNumber               = NULL;  // must release
+    OSNumber             * cpuSubtypeNumber            = NULL;  // must release
+    OSString             * versionString               = NULL;  // do not release
+    uint32_t               executablePathCStringSize = 0;
+    char                 * executablePathCString       = NULL;  // must release
+    OSString             * executablePathString        = NULL;  // must release
+    OSData               * uuid                        = NULL;  // must release
+    OSNumber             * scratchNumber               = NULL;  // must release
+    OSArray              * dependencyLoadTags          = NULL;  // must release
+    OSCollectionIterator * metaClassIterator           = NULL;  // must release
+    OSArray              * metaClassInfo               = NULL;  // must release
+    OSDictionary         * metaClassDict               = NULL;  // must release
+    OSMetaClass          * thisMetaClass               = NULL;  // do not release
+    OSString             * metaClassName               = NULL;  // must release
+    OSString             * superclassName              = NULL;  // must release
+    uint32_t               count, i;
+
+    result = OSDictionary::withCapacity(_OSKextLoadInfoDictCapacity);
+    if (!result) {
+        goto finish;
+    }
+
+    
+   /* Empty keys means no keys, but NULL is quicker to check.
+    */
+    if (infoKeys && !infoKeys->getCount()) {
+        infoKeys = NULL;
+    }
+
+   /* Headers, CPU type, and CPU subtype.
+    */
+    if (!infoKeys ||
+        _OSArrayContainsCString(infoKeys, kOSBundleMachOHeadersKey) ||
+        _OSArrayContainsCString(infoKeys, kOSBundleCPUTypeKey) ||
+        _OSArrayContainsCString(infoKeys, kOSBundleCPUSubtypeKey))
+    {
+
+        if (linkedExecutable && !isInterface()) {
+
+            kernel_mach_header_t *kext_mach_hdr = (kernel_mach_header_t *)
+                linkedExecutable->getBytesNoCopy();
+
+#if !SECURE_KERNEL
+            // do not return macho header info on shipping iOS - 19095897
+            if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleMachOHeadersKey)) {
+                kernel_mach_header_t *  temp_kext_mach_hdr;
+                struct load_command *   lcp;
+
+                headerData = OSData::withBytes(kext_mach_hdr,
+                    (u_int) (sizeof(*kext_mach_hdr) + kext_mach_hdr->sizeofcmds));
+                if (!headerData) {
+                    goto finish;
+                }
+
+                // unslide any vmaddrs we return to userspace - 10726716
+               temp_kext_mach_hdr = (kernel_mach_header_t *)
+                    headerData->getBytesNoCopy();
+                if (temp_kext_mach_hdr == NULL) {
+                    goto finish;
+                }
+
+                lcp = (struct load_command *) (temp_kext_mach_hdr + 1);
+                for (i = 0; i < temp_kext_mach_hdr->ncmds; i++) {
+                    if (lcp->cmd == LC_SEGMENT_KERNEL) {
+                        kernel_segment_command_t *  segp;
+                        kernel_section_t *          secp;
+                        
+                        segp = (kernel_segment_command_t *) lcp;
+                        // 10543468 - if we jettisoned __LINKEDIT clear size info
+                        if (flags.jettisonLinkeditSeg) {
+                            if (strncmp(segp->segname, SEG_LINKEDIT, sizeof(segp->segname)) == 0) {
+                                segp->vmsize = 0;
+                                segp->fileoff = 0;
+                                segp->filesize = 0;
+                            }
+                        }
+#if 0
+                        OSKextLog(/* kext */ NULL,
+                                  kOSKextLogErrorLevel |
+                                  kOSKextLogGeneralFlag,
+                                  "%s: LC_SEGMENT_KERNEL segname '%s' vmaddr 0x%llX 0x%lX vmsize %llu nsects %u",
+                                  __FUNCTION__, segp->segname, segp->vmaddr,
+                                  VM_KERNEL_UNSLIDE(segp->vmaddr),
+                                  segp->vmsize, segp->nsects);
+                        if ( (VM_KERNEL_IS_SLID(segp->vmaddr) == false) &&
+                            (VM_KERNEL_IS_KEXT(segp->vmaddr) == false) &&
+                            (VM_KERNEL_IS_PRELINKTEXT(segp->vmaddr) == false) &&
+                            (VM_KERNEL_IS_PRELINKINFO(segp->vmaddr) == false) &&
+                            (VM_KERNEL_IS_KEXT_LINKEDIT(segp->vmaddr) == false) ) {
+                            OSKextLog(/* kext */ NULL,
+                                      kOSKextLogErrorLevel |
+                                      kOSKextLogGeneralFlag,
+                                      "%s: not in kext range - vmaddr 0x%llX vm_kext_base 0x%lX vm_kext_top 0x%lX",
+                                      __FUNCTION__, segp->vmaddr, vm_kext_base, vm_kext_top);
+                        }
 #endif
-
-#if 0
-						OSKextLog(/* kext */ NULL,
-						    kOSKextLogErrorLevel |
-						    kOSKextLogGeneralFlag,
-						    "%s: LC_SEGMENT_KERNEL segname '%s' vmaddr 0x%llX 0x%lX vmsize %llu nsects %u",
-						    __FUNCTION__, segp->segname, segp->vmaddr,
-						    VM_KERNEL_UNSLIDE(segp->vmaddr),
-						    segp->vmsize, segp->nsects);
-						if ((VM_KERNEL_IS_SLID(segp->vmaddr) == false) &&
-						    (VM_KERNEL_IS_KEXT(segp->vmaddr) == false) &&
-						    (VM_KERNEL_IS_PRELINKTEXT(segp->vmaddr) == false) &&
-						    (VM_KERNEL_IS_PRELINKINFO(segp->vmaddr) == false) &&
-						    (VM_KERNEL_IS_KEXT_LINKEDIT(segp->vmaddr) == false)) {
-							OSKextLog(/* kext */ NULL,
-							    kOSKextLogErrorLevel |
-							    kOSKextLogGeneralFlag,
-							    "%s: not in kext range - vmaddr 0x%llX vm_kext_base 0x%lX vm_kext_top 0x%lX",
-							    __FUNCTION__, segp->vmaddr, vm_kext_base, vm_kext_top);
-						}
-#endif
-						segp->vmaddr = ml_static_unslide(segp->vmaddr);
-
-						for (secp = firstsect(segp); secp != NULL; secp = nextsect(segp, secp)) {
-							secp->addr = ml_static_unslide(secp->addr);
-						}
-					}
-					lcp = (struct load_command *)((caddr_t)lcp + lcp->cmdsize);
-				}
-				result->setObject(kOSBundleMachOHeadersKey, headerData.get());
-			}
-#endif // !SECURE_KERNEL || XNU_TARGET_OS_OSX
-
-			if (_OSArrayContainsCString(infoKeys, kOSBundleLogStringsKey)) {
-				osLogDataHeaderRef *header;
-				char headerBytes[offsetof(osLogDataHeaderRef, sections) + NUM_OS_LOG_SECTIONS * sizeof(header->sections[0])];
-
-				void *os_log_data               = NULL;
-				void *cstring_data              = NULL;
-				void *asan_cstring_data         = NULL;
-				unsigned long os_log_size       = 0;
-				unsigned long cstring_size      = 0;
-				unsigned long asan_cstring_size = 0;
-				uint32_t os_log_offset          = 0;
-				uint32_t cstring_offset         = 0;
-				uint32_t asan_cstring_offset    = 0;
-				bool res;
-
-				os_log_data         = getsectdatafromheader(kext_mach_hdr, "__TEXT", "__os_log", &os_log_size);
-				cstring_data        = getsectdatafromheader(kext_mach_hdr, "__TEXT", "__cstring", &cstring_size);
-				asan_cstring_data   = getsectdatafromheader(kext_mach_hdr, "__TEXT", "__asan_cstring", &asan_cstring_size);
-
-				/*
-				 * If the addresses in the Mach-O header are unslid, manually
-				 * slide them to allow for dereferencing.
-				 */
-				if (flags.unslidMachO) {
-					os_log_data = (os_log_data != nullptr) ? (void*)ml_static_slide((vm_offset_t)os_log_data) : nullptr;
-					cstring_data = (cstring_data != nullptr) ? (void*)ml_static_slide((vm_offset_t)cstring_data) : nullptr;
-					asan_cstring_data = (asan_cstring_data != nullptr) ? (void*)ml_static_slide((vm_offset_t)asan_cstring_data) : nullptr;
-				}
-
-				os_log_offset       = (uintptr_t)os_log_data - (uintptr_t)kext_mach_hdr;
-				cstring_offset      = (uintptr_t)cstring_data - (uintptr_t)kext_mach_hdr;
-				asan_cstring_offset = (uintptr_t)asan_cstring_data - (uintptr_t)kext_mach_hdr;
-
-				header             = (osLogDataHeaderRef *) headerBytes;
-				header->version    = OS_LOG_HDR_VERSION;
-				header->sect_count = NUM_OS_LOG_SECTIONS;
-				header->sections[OS_LOG_SECT_IDX].sect_offset       = os_log_offset;
-				header->sections[OS_LOG_SECT_IDX].sect_size         = (uint32_t) os_log_size;
-				header->sections[CSTRING_SECT_IDX].sect_offset      = cstring_offset;
-				header->sections[CSTRING_SECT_IDX].sect_size        = (uint32_t) cstring_size;
-				header->sections[ASAN_CSTRING_SECT_IDX].sect_offset = asan_cstring_offset;
-				header->sections[ASAN_CSTRING_SECT_IDX].sect_size   = (uint32_t) asan_cstring_size;
-
-
-				logData = OSData::withValue(*header);
-				if (!logData) {
-					goto finish;
-				}
-				res = logData->appendBytes(&(header->sections[0]), (u_int)(header->sect_count * sizeof(header->sections[0])));
-				if (!res) {
-					goto finish;
-				}
-				if (os_log_data) {
-					res = logData->appendBytes(os_log_data, (u_int)header->sections[OS_LOG_SECT_IDX].sect_size);
-					if (!res) {
-						goto finish;
-					}
-				}
-				if (cstring_data) {
-					res = logData->appendBytes(cstring_data, (u_int)header->sections[CSTRING_SECT_IDX].sect_size);
-					if (!res) {
-						goto finish;
-					}
-				}
-				if (asan_cstring_data) {
-					res = logData->appendBytes(asan_cstring_data, (u_int)header->sections[ASAN_CSTRING_SECT_IDX].sect_size);
-					if (!res) {
-						goto finish;
-					}
-				}
-				result->setObject(kOSBundleLogStringsKey, logData.get());
-			}
-
-			if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleCPUTypeKey)) {
-				cpuTypeNumber = OSNumber::withNumber(
-					(uint64_t) kext_mach_hdr->cputype,
-					8 * sizeof(kext_mach_hdr->cputype));
-				if (!cpuTypeNumber) {
-					goto finish;
-				}
-				result->setObject(kOSBundleCPUTypeKey, cpuTypeNumber.get());
-			}
-
-			if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleCPUSubtypeKey)) {
-				cpuSubtypeNumber = OSNumber::withNumber(
-					(uint64_t) kext_mach_hdr->cpusubtype,
-					8 * sizeof(kext_mach_hdr->cpusubtype));
-				if (!cpuSubtypeNumber) {
-					goto finish;
-				}
-				result->setObject(kOSBundleCPUSubtypeKey, cpuSubtypeNumber.get());
-			}
-		} else {
-			if (isDriverKit() && _OSArrayContainsCString(infoKeys, kOSBundleLogStringsKey)) {
-				osLogDataHeaderRef *header;
-				char headerBytes[offsetof(osLogDataHeaderRef, sections) + NUM_OS_LOG_SECTIONS * sizeof(header->sections[0])];
-				bool res;
-
-				header             = (osLogDataHeaderRef *) headerBytes;
-				header->version    = OS_LOG_HDR_VERSION;
-				header->sect_count = NUM_OS_LOG_SECTIONS;
-				header->sections[OS_LOG_SECT_IDX].sect_offset       = 0;
-				header->sections[OS_LOG_SECT_IDX].sect_size         = (uint32_t) 0;
-				header->sections[CSTRING_SECT_IDX].sect_offset      = 0;
-				header->sections[CSTRING_SECT_IDX].sect_size        = (uint32_t) 0;
-				header->sections[ASAN_CSTRING_SECT_IDX].sect_offset = 0;
-				header->sections[ASAN_CSTRING_SECT_IDX].sect_size   = (uint32_t) 0;
-
-				logData = OSData::withValue(*header);
-				if (!logData) {
-					goto finish;
-				}
-				res = logData->appendBytes(&(header->sections[0]), (u_int)(header->sect_count * sizeof(header->sections[0])));
-				if (!res) {
-					goto finish;
-				}
-				result->setObject(kOSBundleLogStringsKey, logData.get());
-			}
-		}
-	}
-
-	/* CFBundleIdentifier. We set this regardless because it's just stupid not to.
-	 */
-	result->setObject(kCFBundleIdentifierKey, bundleID.get());
-
-	/* kOSBundleDextUniqueIdentifierKey if present.
-	 */
-	if (isDriverKit() && dextUniqueID != NULL) {
-		result->setObject(kOSBundleDextUniqueIdentifierKey, dextUniqueID.get());
-	}
-
-	/* CFBundlePackageType
-	 */
-	bundleType = infoDict ? OSDynamicCast(OSString, infoDict->getObject(kCFBundlePackageTypeKey)): NULL;
-	if (bundleType) {
-		result->setObject(kCFBundlePackageTypeKey, bundleType);
-	}
-
-	/* CFBundleVersion.
-	 */
-	if (!infoKeys || _OSArrayContainsCString(infoKeys, kCFBundleVersionKey)) {
-		versionString = OSDynamicCast(OSString,
-		    getPropertyForHostArch(kCFBundleVersionKey));
-		if (versionString) {
-			result->setObject(kCFBundleVersionKey, versionString);
-		}
-	}
-
-	/* OSBundleCompatibleVersion.
-	 */
-	if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleCompatibleVersionKey)) {
-		versionString = OSDynamicCast(OSString,
-		    getPropertyForHostArch(kOSBundleCompatibleVersionKey));
-		if (versionString) {
-			result->setObject(kOSBundleCompatibleVersionKey, versionString);
-		}
-	}
-
-	/* Path.
-	 */
-	if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundlePathKey)) {
-		if (path) {
-			result->setObject(kOSBundlePathKey, path.get());
-		}
-	}
-
-
-	/* OSBundleExecutablePath.
-	 */
-	if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleExecutablePathKey)) {
-		if (path && executableRelPath) {
-			uint32_t pathLength = path->getLength();         // gets incremented below
-
-			// +1 for slash, +1 for \0
-			executablePathCStringSize = pathLength + executableRelPath->getLength() + 2;
-
-			executablePathCString = (char *)kalloc_data_tag(executablePathCStringSize,
-			    Z_WAITOK, VM_KERN_MEMORY_OSKEXT);         // +1 for \0
-			if (!executablePathCString) {
-				goto finish;
-			}
-			strlcpy(executablePathCString, path->getCStringNoCopy(),
-			    executablePathCStringSize);
-			executablePathCString[pathLength++] = '/';
-			executablePathCString[pathLength++] = '\0';
-			strlcat(executablePathCString, executableRelPath->getCStringNoCopy(),
-			    executablePathCStringSize);
-
-			executablePathString = OSString::withCString(executablePathCString);
-
-			if (!executablePathString) {
-				goto finish;
-			}
-
-			result->setObject(kOSBundleExecutablePathKey, executablePathString.get());
-		} else if (flags.builtin) {
-			result->setObject(kOSBundleExecutablePathKey, bundleID.get());
-		} else if (isDriverKit()) {
-			if (path) {
-				// +1 for slash, +1 for \0
-				uint32_t pathLength = path->getLength();
-				executablePathCStringSize = pathLength + 2;
-
-				executablePathCString = (char *)kalloc_data_tag(executablePathCStringSize,
-				    Z_WAITOK, VM_KERN_MEMORY_OSKEXT);
-				if (!executablePathCString) {
-					goto finish;
-				}
-				strlcpy(executablePathCString, path->getCStringNoCopy(), executablePathCStringSize);
-				executablePathCString[pathLength++] = '/';
-				executablePathCString[pathLength++] = '\0';
-
-				executablePathString = OSString::withCString(executablePathCString);
-
-				if (!executablePathString) {
-					goto finish;
-				}
-
-				result->setObject(kOSBundleExecutablePathKey, executablePathString.get());
-			}
-		}
-	}
-
-	/* UUID, if the kext has one.
-	 */
-	if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleUUIDKey)) {
-		uuid = copyUUID();
-		if (uuid) {
-			result->setObject(kOSBundleUUIDKey, uuid.get());
-		}
-	}
-	if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleTextUUIDKey)) {
-		uuid = copyTextUUID();
-		if (uuid) {
-			result->setObject(kOSBundleTextUUIDKey, uuid.get());
-		}
-	}
-
-	/*
-	 * Info.plist digest
-	 */
-	if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSKextInfoPlistDigestKey)) {
-		OSData *digest;
-		digest = infoDict ? OSDynamicCast(OSData, infoDict->getObject(kOSKextInfoPlistDigestKey)) : NULL;
-		if (digest) {
-			result->setObject(kOSKextInfoPlistDigestKey, digest);
-		}
-	}
-
-	/*
-	 * Collection type
-	 */
-	if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSKextBundleCollectionTypeKey)) {
-		result->setObject(kOSKextBundleCollectionTypeKey, OSString::withCString(getKCTypeString()));
-	}
-
-	/*
-	 * Collection availability
-	 */
-	if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSKextAuxKCAvailabilityKey)) {
-		result->setObject(kOSKextAuxKCAvailabilityKey,
-		    isLoadable() ? kOSBooleanTrue : kOSBooleanFalse);
-	}
-
-	/*
-	 * Allows user load
-	 */
-	if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleAllowUserLoadKey)) {
-		OSBoolean *allowUserLoad = OSDynamicCast(OSBoolean, getPropertyForHostArch(kOSBundleAllowUserLoadKey));
-		if (allowUserLoad) {
-			result->setObject(kOSBundleAllowUserLoadKey, allowUserLoad);
-		}
-	}
-
-	/*
-	 * Bundle Dependencies (OSBundleLibraries)
-	 */
-	if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleLibrariesKey)) {
-		OSDictionary *libraries = OSDynamicCast(OSDictionary, getPropertyForHostArch(kOSBundleLibrariesKey));
-		if (libraries) {
-			result->setObject(kOSBundleLibrariesKey, libraries);
-		}
-	}
-
-	/*****
-	 * OSKernelResource, OSBundleIsInterface, OSBundlePrelinked, OSBundleStarted.
-	 */
-	if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSKernelResourceKey)) {
-		result->setObject(kOSKernelResourceKey,
-		    isKernelComponent() ? kOSBooleanTrue : kOSBooleanFalse);
-	}
-
-	if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleIsInterfaceKey)) {
-		result->setObject(kOSBundleIsInterfaceKey,
-		    isInterface() ? kOSBooleanTrue : kOSBooleanFalse);
-	}
-
-	if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundlePrelinkedKey)) {
-		result->setObject(kOSBundlePrelinkedKey,
-		    isPrelinked() ? kOSBooleanTrue : kOSBooleanFalse);
-	}
-
-	if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleStartedKey)) {
-		result->setObject(kOSBundleStartedKey,
-		    isStarted() ? kOSBooleanTrue : kOSBooleanFalse);
-	}
-
-	/* LoadTag (Index).
-	 */
-	if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleLoadTagKey)) {
-		OSSharedPtr<OSNumber> scratchNumber = OSNumber::withNumber((unsigned long long)loadTag,
-		    /* numBits */ 8 * sizeof(loadTag));
-		if (!scratchNumber) {
-			goto finish;
-		}
-		result->setObject(kOSBundleLoadTagKey, scratchNumber.get());
-	}
-
-	/* LoadAddress, LoadSize.
-	 */
-	if (!infoKeys ||
-	    _OSArrayContainsCString(infoKeys, kOSBundleLoadAddressKey) ||
-	    _OSArrayContainsCString(infoKeys, kOSBundleLoadSizeKey) ||
-	    _OSArrayContainsCString(infoKeys, kOSBundleExecLoadAddressKey) ||
-	    _OSArrayContainsCString(infoKeys, kOSBundleExecLoadSizeKey) ||
-	    _OSArrayContainsCString(infoKeys, kOSBundleWiredSizeKey)) {
-		bool is_dext = isDriverKit();
-		if (isInterface() || flags.builtin || linkedExecutable || is_dext) {
-			/* These go to userspace via serialization, so we don't want any doubts
-			 * about their size.
-			 */
-			uint64_t    loadAddress     = 0;
-			uint32_t    loadSize        = 0;
-			uint32_t    wiredSize       = 0;
-			uint64_t    execLoadAddress = 0;
-			uint32_t    execLoadSize    = 0;
-
-			/* Interfaces always report 0 load address & size.
-			 * Just the way they roll.
-			 *
-			 * xxx - leaving in # when we have a linkedExecutable...a kernelcomp
-			 * xxx - shouldn't have one!
-			 */
-
-			if (flags.builtin || linkedExecutable) {
-				kernel_mach_header_t     *mh  = NULL;
-				kernel_segment_command_t *seg = NULL;
-
-				if (flags.builtin) {
-					loadAddress = kmod_info->address;
-					loadSize    = (uint32_t)kmod_info->size;
-				} else {
-					loadAddress = (uint64_t)linkedExecutable->getBytesNoCopy();
-					loadSize = linkedExecutable->getLength();
-				}
-				mh = (kernel_mach_header_t *)loadAddress;
-				loadAddress = ml_static_unslide(loadAddress);
-
-				/* Walk through the kext, looking for the first executable
-				 * segment in case we were asked for its size/address.
-				 */
-				for (seg = firstsegfromheader(mh); seg != NULL; seg = nextsegfromheader(mh, seg)) {
-					if (seg->initprot & VM_PROT_EXECUTE) {
-						execLoadAddress = (flags.unslidMachO) ? seg->vmaddr : ml_static_unslide(seg->vmaddr);
-						execLoadSize = (uint32_t)seg->vmsize;
-						break;
-					}
-				}
-
-				/* If we have a kmod_info struct, calculated the wired size
-				 * from that. Otherwise it's the full load size.
-				 */
-				if (kmod_info) {
-					wiredSize = loadSize - (uint32_t)kmod_info->hdr_size;
-				} else {
-					wiredSize = loadSize;
-				}
-			} else if (is_dext) {
-				/*
-				 * DriverKit userspace executables do not have a kernel linkedExecutable,
-				 * so we "fake" their address range with the LoadTag.
-				 */
-				if (loadTag) {
-					loadAddress = execLoadAddress = loadTag;
-					loadSize = execLoadSize = 1;
-				}
-			}
-
-			if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleLoadAddressKey)) {
-				OSSharedPtr<OSNumber> scratchNumber = OSNumber::withNumber(
-					(unsigned long long)(loadAddress),
-					/* numBits */ 8 * sizeof(loadAddress));
-				if (!scratchNumber) {
-					goto finish;
-				}
-				result->setObject(kOSBundleLoadAddressKey, scratchNumber.get());
-			}
-			if (kcformat == KCFormatStatic || kcformat == KCFormatKCGEN) {
-				if ((!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleCacheLoadAddressKey))
-				    && loadAddress && loadSize) {
-					void *baseAddress = PE_get_kc_baseaddress(KCKindPrimary);
-					if (!baseAddress) {
-						goto finish;
-					}
-
-					OSSharedPtr<OSNumber> scratchNumber = OSNumber::withNumber(
-						(unsigned long long)ml_static_unslide((vm_offset_t)baseAddress),
-						/* numBits */ 8 * sizeof(loadAddress));
-					if (!scratchNumber) {
-						goto finish;
-					}
-					result->setObject(kOSBundleCacheLoadAddressKey, scratchNumber.get());
-				}
-				if ((!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleKextsInKernelTextKey))
-				    && (this == sKernelKext) && gBuiltinKmodsCount) {
-					result->setObject(kOSBundleKextsInKernelTextKey, kOSBooleanTrue);
-				}
-			}
-
-			if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleExecLoadAddressKey)) {
-				OSSharedPtr<OSNumber> scratchNumber = OSNumber::withNumber(
-					(unsigned long long)(execLoadAddress),
-					/* numBits */ 8 * sizeof(execLoadAddress));
-				if (!scratchNumber) {
-					goto finish;
-				}
-				result->setObject(kOSBundleExecLoadAddressKey, scratchNumber.get());
-			}
-			if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleLoadSizeKey)) {
-				OSSharedPtr<OSNumber> scratchNumber = OSNumber::withNumber(
-					(unsigned long long)(loadSize),
-					/* numBits */ 8 * sizeof(loadSize));
-				if (!scratchNumber) {
-					goto finish;
-				}
-				result->setObject(kOSBundleLoadSizeKey, scratchNumber.get());
-			}
-			if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleExecLoadSizeKey)) {
-				OSSharedPtr<OSNumber> scratchNumber = OSNumber::withNumber(
-					(unsigned long long)(execLoadSize),
-					/* numBits */ 8 * sizeof(execLoadSize));
-				if (!scratchNumber) {
-					goto finish;
-				}
-				result->setObject(kOSBundleExecLoadSizeKey, scratchNumber.get());
-			}
-			if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleWiredSizeKey)) {
-				OSSharedPtr<OSNumber> scratchNumber = OSNumber::withNumber(
-					(unsigned long long)(wiredSize),
-					/* numBits */ 8 * sizeof(wiredSize));
-				if (!scratchNumber) {
-					goto finish;
-				}
-				result->setObject(kOSBundleWiredSizeKey, scratchNumber.get());
-			}
-		}
-	}
-
-	/* OSBundleDependencies. In descending order for
-	 * easy compatibility with kextstat(8).
-	 */
-	if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleDependenciesKey)) {
-		if ((count = getNumDependencies())) {
-			dependencyLoadTags = OSArray::withCapacity(count);
-			result->setObject(kOSBundleDependenciesKey, dependencyLoadTags.get());
-
-			i = count - 1;
-			do {
-				OSKext * dependency = OSDynamicCast(OSKext,
-				    dependencies->getObject(i));
-
-				if (!dependency) {
-					continue;
-				}
-				OSSharedPtr<OSNumber> scratchNumber = OSNumber::withNumber(
-					(unsigned long long)dependency->getLoadTag(),
-					/* numBits*/ 8 * sizeof(loadTag));
-				if (!scratchNumber) {
-					goto finish;
-				}
-				dependencyLoadTags->setObject(scratchNumber.get());
-			} while (i--);
-		}
-	}
-
-	/* OSBundleMetaClasses.
-	 */
-	if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleClassesKey)) {
-		if (metaClasses && metaClasses->getCount()) {
-			metaClassIterator = OSCollectionIterator::withCollection(metaClasses.get());
-			metaClassInfo = OSArray::withCapacity(metaClasses->getCount());
-			if (!metaClassIterator || !metaClassInfo) {
-				goto finish;
-			}
-			result->setObject(kOSBundleClassesKey, metaClassInfo.get());
-
-			while ((thisMetaClass = OSDynamicCast(OSMetaClass,
-			    metaClassIterator->getNextObject()))) {
-				metaClassDict = OSDictionary::withCapacity(3);
-				if (!metaClassDict) {
-					goto finish;
-				}
-
-				metaClassName = OSString::withCString(thisMetaClass->getClassName());
-				if (thisMetaClass->getSuperClass()) {
-					superclassName = OSString::withCString(
-						thisMetaClass->getSuperClass()->getClassName());
-				}
-				OSSharedPtr<OSNumber> scratchNumber = OSNumber::withNumber(thisMetaClass->getInstanceCount(),
-				    8 * sizeof(unsigned int));
-
-				/* Bail if any of the essentials is missing. The root class lacks a superclass,
-				 * of course.
-				 */
-				if (!metaClassDict || !metaClassName || !scratchNumber) {
-					goto finish;
-				}
-
-				metaClassInfo->setObject(metaClassDict.get());
-				metaClassDict->setObject(kOSMetaClassNameKey, metaClassName.get());
-				if (superclassName) {
-					metaClassDict->setObject(kOSMetaClassSuperclassNameKey, superclassName.get());
-				}
-				metaClassDict->setObject(kOSMetaClassTrackingCountKey, scratchNumber.get());
-			}
-		}
-	}
-
-	/* OSBundleRetainCount.
-	 */
-	if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleRetainCountKey)) {
-		{
-			int kextRetainCount = getRetainCount() - 1;
-			if (isLoaded()) {
-				kextRetainCount--;
-			}
-			OSSharedPtr<OSNumber> scratchNumber = OSNumber::withNumber(
-				(int)kextRetainCount,
-				/* numBits*/ 8 * sizeof(int));
-			if (scratchNumber) {
-				result->setObject(kOSBundleRetainCountKey, scratchNumber.get());
-			}
-		}
-	}
-
-	success = true;
+                        segp->vmaddr = VM_KERNEL_UNSLIDE(segp->vmaddr);
+                        
+                        for (secp = firstsect(segp); secp != NULL; secp = nextsect(segp, secp)) {
+                            secp->addr = VM_KERNEL_UNSLIDE(secp->addr);
+                        }
+                    }
+                    lcp = (struct load_command *)((caddr_t)lcp + lcp->cmdsize);
+                }
+                result->setObject(kOSBundleMachOHeadersKey, headerData);
+            }
+#endif // SECURE_KERNEL
+
+            if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleCPUTypeKey)) {
+                cpuTypeNumber = OSNumber::withNumber(
+                    (uint64_t) kext_mach_hdr->cputype,
+                    8 * sizeof(kext_mach_hdr->cputype));
+                if (!cpuTypeNumber) {
+                    goto finish;
+                }
+                result->setObject(kOSBundleCPUTypeKey, cpuTypeNumber);
+            }
+
+            if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleCPUSubtypeKey)) {
+                cpuSubtypeNumber = OSNumber::withNumber(
+                    (uint64_t) kext_mach_hdr->cpusubtype,
+                    8 * sizeof(kext_mach_hdr->cpusubtype));
+                if (!cpuSubtypeNumber) {
+                    goto finish;
+                }
+                result->setObject(kOSBundleCPUSubtypeKey, cpuSubtypeNumber);
+            }
+        }
+    }
+    
+   /* CFBundleIdentifier. We set this regardless because it's just stupid not to.
+    */
+    result->setObject(kCFBundleIdentifierKey, bundleID);
+
+   /* CFBundleVersion.
+    */
+    if (!infoKeys || _OSArrayContainsCString(infoKeys, kCFBundleVersionKey)) {
+        versionString = OSDynamicCast(OSString,
+            getPropertyForHostArch(kCFBundleVersionKey));
+        if (versionString) {
+            result->setObject(kCFBundleVersionKey, versionString);
+        }
+    }
+
+   /* OSBundleCompatibleVersion.
+    */
+    if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleCompatibleVersionKey)) {
+        versionString = OSDynamicCast(OSString,
+            getPropertyForHostArch(kOSBundleCompatibleVersionKey));
+        if (versionString) {
+            result->setObject(kOSBundleCompatibleVersionKey, versionString);
+        }
+    }
+
+   /* Path.
+    */
+    if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundlePathKey)) {
+        if (path) {
+            result->setObject(kOSBundlePathKey, path);
+        }
+    }
+
+
+   /* OSBundleExecutablePath.
+    */
+    if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleExecutablePathKey)) {
+         if (path && executableRelPath) {
+
+            uint32_t pathLength = path->getLength();  // gets incremented below
+
+            // +1 for slash, +1 for \0
+            executablePathCStringSize = pathLength + executableRelPath->getLength() + 2;
+
+            executablePathCString = (char *)kalloc_tag((executablePathCStringSize) *
+                sizeof(char), VM_KERN_MEMORY_OSKEXT); // +1 for \0
+            if (!executablePathCString) {
+                goto finish;
+            }
+            strlcpy(executablePathCString, path->getCStringNoCopy(),
+                executablePathCStringSize);
+            executablePathCString[pathLength++] = '/';
+            executablePathCString[pathLength++] = '\0';
+            strlcat(executablePathCString, executableRelPath->getCStringNoCopy(),
+                executablePathCStringSize);
+
+            executablePathString = OSString::withCString(executablePathCString);
+
+            if (!executablePathCString) {
+                goto finish;
+            }
+
+            result->setObject(kOSBundleExecutablePathKey, executablePathString);
+        }
+    }
+
+   /* UUID, if the kext has one.
+    */
+    if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleUUIDKey)) {
+        uuid = copyUUID();
+        if (uuid) {
+            result->setObject(kOSBundleUUIDKey, uuid);
+        }
+    }
+    
+   /*****
+    * OSKernelResource, OSBundleIsInterface, OSBundlePrelinked, OSBundleStarted.
+    */
+    if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSKernelResourceKey)) {
+        result->setObject(kOSKernelResourceKey,
+            isKernelComponent() ? kOSBooleanTrue : kOSBooleanFalse);
+    }
+    
+    if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleIsInterfaceKey)) {
+        result->setObject(kOSBundleIsInterfaceKey,
+            isInterface() ? kOSBooleanTrue : kOSBooleanFalse);
+    }
+    
+    if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundlePrelinkedKey)) {
+        result->setObject(kOSBundlePrelinkedKey,
+            isPrelinked() ? kOSBooleanTrue : kOSBooleanFalse);
+    }
+    
+    if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleStartedKey)) {
+        result->setObject(kOSBundleStartedKey,
+            isStarted() ? kOSBooleanTrue : kOSBooleanFalse);
+    }
+
+   /* LoadTag (Index).
+    */
+    if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleLoadTagKey)) {
+        scratchNumber = OSNumber::withNumber((unsigned long long)loadTag,
+            /* numBits */ 8 * sizeof(loadTag));
+        if (!scratchNumber) {
+            goto finish;
+        }
+        result->setObject(kOSBundleLoadTagKey, scratchNumber);
+        OSSafeReleaseNULL(scratchNumber);
+    }
+    
+   /* LoadAddress, LoadSize.
+    */
+    if (!infoKeys ||
+        _OSArrayContainsCString(infoKeys, kOSBundleLoadAddressKey) ||
+        _OSArrayContainsCString(infoKeys, kOSBundleLoadSizeKey) ||
+        _OSArrayContainsCString(infoKeys, kOSBundleWiredSizeKey))
+    {
+        if (isInterface() || linkedExecutable) {
+           /* These go to userspace via serialization, so we don't want any doubts
+            * about their size.
+            */
+            uint64_t    loadAddress = 0;
+            uint32_t    loadSize    = 0;
+            uint32_t    wiredSize   = 0;
+
+           /* Interfaces always report 0 load address & size.
+            * Just the way they roll.
+            *
+            * xxx - leaving in # when we have a linkedExecutable...a kernelcomp
+            * xxx - shouldn't have one!
+            */
+            if (linkedExecutable /* && !isInterface() */) {
+                loadAddress = (uint64_t)linkedExecutable->getBytesNoCopy();
+                loadAddress = VM_KERNEL_UNSLIDE(loadAddress);
+                loadSize = linkedExecutable->getLength();
+                
+               /* If we have a kmod_info struct, calculated the wired size
+                * from that. Otherwise it's the full load size.
+                */
+                if (kmod_info) {
+                    wiredSize = loadSize - kmod_info->hdr_size;
+                } else {
+                    wiredSize = loadSize;
+                }
+            }
+
+            if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleLoadAddressKey)) {
+                scratchNumber = OSNumber::withNumber(
+                    (unsigned long long)(loadAddress),
+                    /* numBits */ 8 * sizeof(loadAddress));
+                if (!scratchNumber) {
+                    goto finish;
+                }
+                result->setObject(kOSBundleLoadAddressKey, scratchNumber);
+                OSSafeReleaseNULL(scratchNumber);
+            }
+            if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleLoadSizeKey)) {
+                scratchNumber = OSNumber::withNumber(
+                    (unsigned long long)(loadSize),
+                    /* numBits */ 8 * sizeof(loadSize));
+                if (!scratchNumber) {
+                    goto finish;
+                }
+                result->setObject(kOSBundleLoadSizeKey, scratchNumber);
+                OSSafeReleaseNULL(scratchNumber);
+            }
+            if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleWiredSizeKey)) {
+                scratchNumber = OSNumber::withNumber(
+                    (unsigned long long)(wiredSize),
+                    /* numBits */ 8 * sizeof(wiredSize));
+                if (!scratchNumber) {
+                    goto finish;
+                }
+                result->setObject(kOSBundleWiredSizeKey, scratchNumber);
+                OSSafeReleaseNULL(scratchNumber);
+            }
+        }
+    }
+
+   /* OSBundleDependencies. In descending order for
+    * easy compatibility with kextstat(8).
+    */
+    if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleDependenciesKey)) {
+        if ((count = getNumDependencies())) {
+            dependencyLoadTags = OSArray::withCapacity(count);
+            result->setObject(kOSBundleDependenciesKey, dependencyLoadTags);
+
+            i = count - 1;
+            do {
+                OSKext * dependency = OSDynamicCast(OSKext,
+                    dependencies->getObject(i));
+
+                OSSafeReleaseNULL(scratchNumber);
+                
+                if (!dependency) {
+                    continue;
+                }
+                scratchNumber = OSNumber::withNumber(
+                    (unsigned long long)dependency->getLoadTag(),
+                    /* numBits*/ 8 * sizeof(loadTag));
+                if (!scratchNumber) {
+                    goto finish;
+                }
+                dependencyLoadTags->setObject(scratchNumber);
+            } while (i--);
+        }
+    }
+
+    OSSafeReleaseNULL(scratchNumber);
+
+   /* OSBundleMetaClasses.
+    */
+    if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleClassesKey)) {
+        if (metaClasses && metaClasses->getCount()) {
+            metaClassIterator = OSCollectionIterator::withCollection(metaClasses);
+            metaClassInfo = OSArray::withCapacity(metaClasses->getCount());
+            if (!metaClassIterator || !metaClassInfo) {
+                goto finish;
+            }
+            result->setObject(kOSBundleClassesKey, metaClassInfo);
+
+            while ( (thisMetaClass = OSDynamicCast(OSMetaClass,
+                metaClassIterator->getNextObject())) ) {
+
+                OSSafeReleaseNULL(metaClassDict);
+                OSSafeReleaseNULL(scratchNumber);
+                OSSafeReleaseNULL(metaClassName);
+                OSSafeReleaseNULL(superclassName);
+
+                metaClassDict = OSDictionary::withCapacity(3);
+                if (!metaClassDict) {
+                    goto finish;
+                }
+
+                metaClassName = OSString::withCString(thisMetaClass->getClassName());
+                if (thisMetaClass->getSuperClass()) {
+                    superclassName = OSString::withCString(
+                        thisMetaClass->getSuperClass()->getClassName());
+                }
+                scratchNumber = OSNumber::withNumber(thisMetaClass->getInstanceCount(),
+                    8 * sizeof(unsigned int));
+                    
+               /* Bail if any of the essentials is missing. The root class lacks a superclass,
+                * of course.
+                */
+                if (!metaClassDict || !metaClassName || !scratchNumber) {
+                    goto finish;
+                }
+
+                metaClassInfo->setObject(metaClassDict);
+                metaClassDict->setObject(kOSMetaClassNameKey, metaClassName);
+                if (superclassName) {
+                    metaClassDict->setObject(kOSMetaClassSuperclassNameKey, superclassName);
+                }
+                metaClassDict->setObject(kOSMetaClassTrackingCountKey, scratchNumber);
+            }
+        }
+    }
+    
+   /* OSBundleRetainCount.
+    */
+    if (!infoKeys || _OSArrayContainsCString(infoKeys, kOSBundleRetainCountKey)) {
+        OSSafeReleaseNULL(scratchNumber);
+        {
+            int kextRetainCount = getRetainCount() - 1;
+            if (isLoaded()) {
+                kextRetainCount--;
+            }
+            scratchNumber = OSNumber::withNumber(
+                (int)kextRetainCount,
+                /* numBits*/ 8 * sizeof(int));
+            if (scratchNumber) {
+                result->setObject(kOSBundleRetainCountKey, scratchNumber);
+            }
+        }
+    }
+
+    success = true;
 
 finish:
-	if (executablePathCString) {
-		kfree_data(executablePathCString, executablePathCStringSize);
-	}
-	if (!success) {
-		result.reset();
-	}
-	return result;
-}
-
-/*********************************************************************
-*********************************************************************/
-/* static */
-bool
-OSKext::copyUserExecutablePath(const OSSymbol * bundleID, char * pathResult, size_t pathSize)
-{
-	bool ok;
-	OSSharedPtr<OSKext> kext;
-
-	IORecursiveLockLock(sKextLock);
-	kext.reset(OSDynamicCast(OSKext, sKextsByID->getObject(bundleID)), OSRetain);
-	IORecursiveLockUnlock(sKextLock);
-
-	if (!kext || !kext->path || !kext->userExecutableRelPath) {
-		return false;
-	}
-	snprintf(pathResult, pathSize, "%s/Contents/MacOS/%s",
-	    kext->path->getCStringNoCopy(),
-	    kext->userExecutableRelPath->getCStringNoCopy());
-	ok = true;
-
-	return ok;
-}
-
-/*********************************************************************
-*********************************************************************/
+    OSSafeRelease(headerData);
+    OSSafeRelease(cpuTypeNumber);
+    OSSafeRelease(cpuSubtypeNumber);
+    OSSafeRelease(executablePathString);
+    if (executablePathString) kfree(executablePathCString, executablePathCStringSize);
+    OSSafeRelease(uuid);
+    OSSafeRelease(scratchNumber);
+    OSSafeRelease(dependencyLoadTags);
+    OSSafeRelease(metaClassIterator);
+    OSSafeRelease(metaClassInfo);
+    OSSafeRelease(metaClassDict);
+    OSSafeRelease(metaClassName);
+    OSSafeRelease(superclassName);
+    if (!success) {
+        OSSafeReleaseNULL(result);
+    }
+    return result;
+}
+
+/*********************************************************************
+ *********************************************************************/
 /* static */
 OSReturn
 OSKext::requestResource(
-	const char                    * kextIdentifierCString,
-	const char                    * resourceNameCString,
-	OSKextRequestResourceCallback   callback,
-	void                          * context,
-	OSKextRequestTag              * requestTagOut)
-{
-	OSReturn                        result = kOSReturnError;
-	OSSharedPtr<OSKext>             callbackKext;        // looked up
-
-	OSKextRequestTag   requestTag      = -1;
-	OSSharedPtr<OSNumber>           requestTagNum;
-	OSSharedPtr<OSDictionary>       requestDict;
-	OSSharedPtr<OSString>           kextIdentifier;
-	OSSharedPtr<OSString>           resourceName;
-
-	OSSharedPtr<OSDictionary>       callbackRecord;
-	OSSharedPtr<OSValueObject<OSKextRequestResourceCallback> > callbackWrapper;
-
-	OSSharedPtr<OSValueObject<void *> > contextWrapper;
-
-	IORecursiveLockLock(sKextLock);
-
-	if (requestTagOut) {
-		*requestTagOut = kOSKextRequestTagInvalid;
-	}
-
-	/* If requests to user space are disabled, don't go any further */
-	if (!sKernelRequestsEnabled) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel | kOSKextLogIPCFlag,
-		    "Can't request resource %s for %s - requests to user space are disabled.",
-		    resourceNameCString,
-		    kextIdentifierCString);
-		result = kOSKextReturnDisabled;
-		goto finish;
-	}
-
-	if (!kextIdentifierCString || !resourceNameCString || !callback) {
-		result = kOSKextReturnInvalidArgument;
-		goto finish;
-	}
-
-	callbackKext = OSKext::lookupKextWithAddress((vm_address_t)callback);
-	if (!callbackKext) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel | kOSKextLogIPCFlag,
-		    "Resource request has bad callback address.");
-		result = kOSKextReturnInvalidArgument;
-		goto finish;
-	}
-	if (!callbackKext->flags.starting && !callbackKext->flags.started) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel | kOSKextLogIPCFlag,
-		    "Resource request callback is in a kext that is not started.");
-		result = kOSKextReturnInvalidArgument;
-		goto finish;
-	}
-
-	/* Do not allow any new requests to be made on a kext that is unloading.
-	 */
-	if (callbackKext->flags.stopping) {
-		result = kOSKextReturnStopping;
-		goto finish;
-	}
-
-	/* If we're wrapped the next available request tag around to the negative
-	 * numbers, we can't service any more requests.
-	 */
-	if (sNextRequestTag == kOSKextRequestTagInvalid) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel | kOSKextLogIPCFlag,
-		    "No more request tags available; restart required.");
-		result = kOSKextReturnNoResources;
-		goto finish;
-	}
-	requestTag = sNextRequestTag++;
-
-	result = _OSKextCreateRequest(kKextRequestPredicateRequestResource,
-	    requestDict);
-	if (result != kOSReturnSuccess) {
-		goto finish;
-	}
-
-	kextIdentifier = OSString::withCString(kextIdentifierCString);
-	resourceName   = OSString::withCString(resourceNameCString);
-	requestTagNum  = OSNumber::withNumber((long long unsigned int)requestTag,
-	    8 * sizeof(requestTag));
-	if (!kextIdentifier ||
-	    !resourceName ||
-	    !requestTagNum ||
-	    !_OSKextSetRequestArgument(requestDict.get(),
-	    kKextRequestArgumentBundleIdentifierKey, kextIdentifier.get()) ||
-	    !_OSKextSetRequestArgument(requestDict.get(),
-	    kKextRequestArgumentNameKey, resourceName.get()) ||
-	    !_OSKextSetRequestArgument(requestDict.get(),
-	    kKextRequestArgumentRequestTagKey, requestTagNum.get())) {
-		result = kOSKextReturnNoMemory;
-		goto finish;
-	}
-
-	callbackRecord = OSDynamicPtrCast<OSDictionary>(requestDict->copyCollection());
-	if (!callbackRecord) {
-		result = kOSKextReturnNoMemory;
-		goto finish;
-	}
-	// we validate callback address at call time
-	callbackWrapper = OSValueObjectWithValue(callback);
-	if (context) {
-		contextWrapper = OSValueObjectWithValue(context);
-	}
-	if (!callbackWrapper || !_OSKextSetRequestArgument(callbackRecord.get(),
-	    kKextRequestArgumentCallbackKey, callbackWrapper.get())) {
-		result = kOSKextReturnNoMemory;
-		goto finish;
-	}
-
-	if (context) {
-		if (!contextWrapper || !_OSKextSetRequestArgument(callbackRecord.get(),
-		    kKextRequestArgumentContextKey, contextWrapper.get())) {
-			result = kOSKextReturnNoMemory;
-			goto finish;
-		}
-	}
-
-	/* Only post the requests after all the other potential failure points
-	 * have been passed.
-	 */
-	if (!sKernelRequests->setObject(requestDict.get()) ||
-	    !sRequestCallbackRecords->setObject(callbackRecord.get())) {
-		result = kOSKextReturnNoMemory;
-		goto finish;
-	}
-
-	OSKext::pingIOKitDaemon();
-
-	result = kOSReturnSuccess;
-	if (requestTagOut) {
-		*requestTagOut = requestTag;
-	}
+    const char                    * kextIdentifierCString,
+    const char                    * resourceNameCString,
+    OSKextRequestResourceCallback   callback,
+    void                          * context,
+    OSKextRequestTag              * requestTagOut)
+{
+    OSReturn           result          = kOSReturnError;
+    OSKext           * callbackKext    = NULL;  // must release (looked up)
+
+    OSKextRequestTag   requestTag      = -1;
+    OSNumber         * requestTagNum   = NULL;  // must release
+
+    OSDictionary     * requestDict     = NULL;  // must release
+    OSString         * kextIdentifier  = NULL;  // must release
+    OSString         * resourceName    = NULL;  // must release
+
+    OSDictionary     * callbackRecord  = NULL;  // must release
+    OSData           * callbackWrapper = NULL;  // must release
+
+    OSData           * contextWrapper  = NULL;  // must release
+            
+    IORecursiveLockLock(sKextLock);
+
+    if (requestTagOut) {
+        *requestTagOut = kOSKextRequestTagInvalid;
+    }
+
+    /* If requests to user space are disabled, don't go any further */
+    if (!sKernelRequestsEnabled) {
+        OSKextLog(/* kext */ NULL, 
+            kOSKextLogErrorLevel | kOSKextLogIPCFlag,
+            "Can't request resource %s for %s - requests to user space are disabled.",
+            resourceNameCString,
+            kextIdentifierCString);
+        result = kOSKextReturnDisabled;
+        goto finish;
+    }
+
+    if (!kextIdentifierCString || !resourceNameCString || !callback) {
+        result = kOSKextReturnInvalidArgument;
+        goto finish;
+    }
+
+    callbackKext = OSKext::lookupKextWithAddress((vm_address_t)callback);
+    if (!callbackKext) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogErrorLevel | kOSKextLogIPCFlag,
+            "Resource request has bad callback address.");
+        result = kOSKextReturnInvalidArgument;
+        goto finish;
+    }
+    if (!callbackKext->flags.starting && !callbackKext->flags.started) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogErrorLevel | kOSKextLogIPCFlag,
+            "Resource request callback is in a kext that is not started.");
+        result = kOSKextReturnInvalidArgument;
+        goto finish;
+    }
+
+   /* Do not allow any new requests to be made on a kext that is unloading.
+    */
+    if (callbackKext->flags.stopping) {
+        result = kOSKextReturnStopping;
+        goto finish;
+    }
+
+   /* If we're wrapped the next available request tag around to the negative
+    * numbers, we can't service any more requests.
+    */
+    if (sNextRequestTag == kOSKextRequestTagInvalid) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogErrorLevel | kOSKextLogIPCFlag,
+            "No more request tags available; restart required.");
+        result = kOSKextReturnNoResources;
+        goto finish;
+    }
+    requestTag = sNextRequestTag++;
+
+    result = _OSKextCreateRequest(kKextRequestPredicateRequestResource,
+        &requestDict);
+    if (result != kOSReturnSuccess) {
+        goto finish;
+    }
+    
+    kextIdentifier = OSString::withCString(kextIdentifierCString);
+    resourceName   = OSString::withCString(resourceNameCString);
+    requestTagNum  = OSNumber::withNumber((long long unsigned int)requestTag,
+        8 * sizeof(requestTag));
+    if (!kextIdentifier ||
+        !resourceName   ||
+        !requestTagNum  ||
+        !_OSKextSetRequestArgument(requestDict,
+            kKextRequestArgumentBundleIdentifierKey, kextIdentifier) ||
+        !_OSKextSetRequestArgument(requestDict,
+            kKextRequestArgumentNameKey, resourceName) ||
+        !_OSKextSetRequestArgument(requestDict,
+            kKextRequestArgumentRequestTagKey, requestTagNum)) {
+
+        result = kOSKextReturnNoMemory;
+        goto finish;
+    }
+
+    callbackRecord = OSDynamicCast(OSDictionary, requestDict->copyCollection());
+    if (!callbackRecord) {
+        result = kOSKextReturnNoMemory;
+        goto finish;
+    }
+    // we validate callback address at call time
+    callbackWrapper = OSData::withBytes((void *)&callback, sizeof(void *));
+    if (context) {
+        contextWrapper = OSData::withBytes((void *)&context, sizeof(void *));
+    }
+    if (!callbackWrapper || !_OSKextSetRequestArgument(callbackRecord,
+            kKextRequestArgumentCallbackKey, callbackWrapper)) {
+
+        result = kOSKextReturnNoMemory;
+        goto finish;
+    }
+
+    if (context) {
+        if (!contextWrapper || !_OSKextSetRequestArgument(callbackRecord,
+            kKextRequestArgumentContextKey, contextWrapper)) {
+
+            result = kOSKextReturnNoMemory;
+            goto finish;
+        }
+    }
+
+   /* Only post the requests after all the other potential failure points
+    * have been passed.
+    */
+    if (!sKernelRequests->setObject(requestDict) ||
+        !sRequestCallbackRecords->setObject(callbackRecord)) {
+
+        result = kOSKextReturnNoMemory;
+        goto finish;
+    }
+
+    OSKext::pingKextd();
+
+    result = kOSReturnSuccess;
+    if (requestTagOut) {
+        *requestTagOut = requestTag;
+    }
 
 finish:
 
-	/* If we didn't succeed, yank the request & callback
-	 * from their holding arrays.
-	 */
-	if (result != kOSReturnSuccess) {
-		unsigned int index;
-
-		index = sKernelRequests->getNextIndexOfObject(requestDict.get(), 0);
-		if (index != (unsigned int)-1) {
-			sKernelRequests->removeObject(index);
-		}
-		index = sRequestCallbackRecords->getNextIndexOfObject(callbackRecord.get(), 0);
-		if (index != (unsigned int)-1) {
-			sRequestCallbackRecords->removeObject(index);
-		}
-	}
-
-	OSKext::considerUnloads(/* rescheduleOnly? */ true);
-
-	IORecursiveLockUnlock(sKextLock);
-
-	return result;
-}
-
-OSReturn
-OSKext::requestDaemonLaunch(
-	OSString *kextIdentifier,
-	OSString *serverName,
-	OSNumber *serverTag,
-	OSBoolean *reslide,
-	IOUserServerCheckInToken * checkInToken,
-	OSData *serverDUI)
-{
-	OSReturn       result        = kOSReturnError;
-	OSSharedPtr<OSDictionary> requestDict;
-	unsigned int size = 0;
-	const char *dextUniqueIDCString = NULL;
-
-	if (!kextIdentifier || !serverName || !serverTag || !checkInToken) {
-		return kOSKextReturnInvalidArgument;
-	}
-	if (!iokitDaemonAvailable()) {
-		panic("Received unexpected request in environment where " kIOKitDaemonName " is unavailable");
-	}
-
-	if (serverDUI != NULL) {
-		dextUniqueIDCString = getDextUniqueIDCString(serverDUI, &size);
-	}
-
-	IORecursiveLockLock(sKextLock);
-
-	OSKextLog(/* kext */ NULL,
-	    kOSKextLogDebugLevel |
-	    kOSKextLogGeneralFlag,
-	    "Requesting daemon launch for %s %s with serverName %s and tag %llu%s",
-	    kextIdentifier->getCStringNoCopy(),
-	    (dextUniqueIDCString != NULL)?dextUniqueIDCString:"",
-	    serverName->getCStringNoCopy(),
-	    serverTag->unsigned64BitValue(),
-	    reslide == kOSBooleanTrue ? " with reslid shared cache" : ""
-	    );
-
-	result = _OSKextCreateRequest(kKextRequestPredicateRequestDaemonLaunch, requestDict);
-	if (result != kOSReturnSuccess) {
-		goto finish;
-	}
-
-	if (!_OSKextSetRequestArgument(requestDict.get(),
-	    kKextRequestArgumentBundleIdentifierKey, kextIdentifier) ||
-	    !_OSKextSetRequestArgument(requestDict.get(),
-	    kKextRequestArgumentDriverExtensionServerName, serverName) ||
-	    !_OSKextSetRequestArgument(requestDict.get(),
-	    kKextRequestArgumentDriverExtensionServerTag, serverTag) ||
-	    !_OSKextSetRequestArgument(requestDict.get(),
-	    kKextRequestArgumentDriverExtensionReslideSharedCache, reslide) ||
-	    !_OSKextSetRequestArgument(requestDict.get(),
-	    kKextRequestArgumentCheckInToken, checkInToken)) {
-		result = kOSKextReturnNoMemory;
-		goto finish;
-	}
-
-	if (serverDUI) {
-		if (!_OSKextSetRequestArgument(requestDict.get(),
-		    kOSBundleDextUniqueIdentifierKey, serverDUI)) {
-			result = kOSKextReturnNoMemory;
-			goto finish;
-		}
-	}
-
-	/* Only post the requests after all the other potential failure points
-	 * have been passed.
-	 */
-	if (!sKernelRequests->setObject(requestDict.get())) {
-		result = kOSKextReturnNoMemory;
-		goto finish;
-	}
-	result = OSKext::pingIOKitDaemon();
-	if (result != kOSReturnSuccess) {
-		goto finish;
-	}
-
-	result = kOSReturnSuccess;
-finish:
-	IORecursiveLockUnlock(sKextLock);
-	if (dextUniqueIDCString) {
-		kfree_data(dextUniqueIDCString, size);
-	}
-	return result;
-}
-
-OSReturn
-OSKext::notifyDextUpgrade(
-	OSString *kextIdentifier,
-	OSData *dextUniqueIdentifier)
-{
-	OSReturn result = kOSReturnError;
-	OSSharedPtr<OSDictionary> requestDict;
-	unsigned int size = 0;
-	const char *dextUniqueIDCString = getDextUniqueIDCString(dextUniqueIdentifier, &size);
-	assert(dextUniqueIDCString != NULL);
-
-	IORecursiveLockLock(sKextLock);
-
-	OSKextLog(NULL,
-	    kOSKextLogDebugLevel |
-	    kOSKextLogGeneralFlag,
-	    "Notifying of dext upgrade for %s with UniqueID %s",
-	    kextIdentifier->getCStringNoCopy(), dextUniqueIDCString);
-
-	result = _OSKextCreateRequest(kKextRequestPredicateRequestDaemonUpgradeNotification, requestDict);
-	if (result != kOSReturnSuccess) {
-		goto finish;
-	}
-
-	if (!_OSKextSetRequestArgument(requestDict.get(),
-	    kKextRequestArgumentBundleIdentifierKey, kextIdentifier) ||
-	    !_OSKextSetRequestArgument(requestDict.get(),
-	    kKextRequestArgumentDriverUniqueIdentifier, dextUniqueIdentifier)) {
-		result = kOSKextReturnNoMemory;
-		goto finish;
-	}
-
-	/* Only post the requests after all the other potential failure points
-	 * have been passed.
-	 */
-	if (!sKernelRequests->setObject(requestDict.get())) {
-		result = kOSKextReturnNoMemory;
-		goto finish;
-	}
-	OSKext::pingIOKitDaemon();
-
-	result = kOSReturnSuccess;
-finish:
-	IORecursiveLockUnlock(sKextLock);
-
-	if (dextUniqueIDCString != NULL) {
-		kfree_data(dextUniqueIDCString, size);
-	}
-	return result;
+   /* If we didn't succeed, yank the request & callback
+    * from their holding arrays.
+    */
+    if (result != kOSReturnSuccess) {
+        unsigned int index;
+        
+        index = sKernelRequests->getNextIndexOfObject(requestDict, 0);
+        if (index != (unsigned int)-1) {
+            sKernelRequests->removeObject(index);
+        }
+        index = sRequestCallbackRecords->getNextIndexOfObject(callbackRecord, 0);
+        if (index != (unsigned int)-1) {
+            sRequestCallbackRecords->removeObject(index);
+        }
+    }
+
+    OSKext::considerUnloads(/* rescheduleOnly? */ true);
+
+    IORecursiveLockUnlock(sKextLock);
+
+    if (callbackKext)    callbackKext->release();
+    if (requestTagNum)   requestTagNum->release();
+
+    if (requestDict)     requestDict->release();
+    if (kextIdentifier)  kextIdentifier->release();
+    if (resourceName)    resourceName->release();
+
+    if (callbackRecord)  callbackRecord->release();
+    if (callbackWrapper) callbackWrapper->release();
+    if (contextWrapper)  contextWrapper->release();
+
+    return result;
 }
 
 /*********************************************************************
@@ -13058,40 +8937,25 @@
 /* static */
 OSReturn
 OSKext::dequeueCallbackForRequestTag(
-	OSKextRequestTag    requestTag,
-	OSSharedPtr<OSDictionary>     &callbackRecordOut)
-{
-	OSDictionary * callbackRecordOutRaw = NULL;
-	OSReturn result;
-
-	result = dequeueCallbackForRequestTag(requestTag,
-	    &callbackRecordOutRaw);
-
-	if (kOSReturnSuccess == result) {
-		callbackRecordOut.reset(callbackRecordOutRaw, OSNoRetain);
-	}
-
-	return result;
-}
-OSReturn
-OSKext::dequeueCallbackForRequestTag(
-	OSKextRequestTag    requestTag,
-	OSDictionary     ** callbackRecordOut)
-{
-	OSReturn   result = kOSReturnError;
-	OSSharedPtr<OSNumber> requestTagNum;
-
-	requestTagNum  = OSNumber::withNumber((long long unsigned int)requestTag,
-	    8 * sizeof(requestTag));
-	if (!requestTagNum) {
-		goto finish;
-	}
-
-	result = OSKext::dequeueCallbackForRequestTag(requestTagNum.get(),
-	    callbackRecordOut);
+    OSKextRequestTag    requestTag,
+    OSDictionary     ** callbackRecordOut)
+{
+    OSReturn   result = kOSReturnError;
+    OSNumber * requestTagNum  = NULL;  // must release
+
+    requestTagNum  = OSNumber::withNumber((long long unsigned int)requestTag,
+        8 * sizeof(requestTag));
+    if (!requestTagNum) {
+        goto finish;
+    }
+
+    result = OSKext::dequeueCallbackForRequestTag(requestTagNum,
+        callbackRecordOut);
 
 finish:
-	return result;
+    OSSafeRelease(requestTagNum);
+
+    return result;
 }
 
 /*********************************************************************
@@ -13100,1218 +8964,49 @@
 /* static */
 OSReturn
 OSKext::dequeueCallbackForRequestTag(
-	OSNumber     *    requestTagNum,
-	OSSharedPtr<OSDictionary>     &callbackRecordOut)
-{
-	OSDictionary * callbackRecordOutRaw = NULL;
-	OSReturn result;
-
-	result = dequeueCallbackForRequestTag(requestTagNum,
-	    &callbackRecordOutRaw);
-
-	if (kOSReturnSuccess == result) {
-		callbackRecordOut.reset(callbackRecordOutRaw, OSNoRetain);
-	}
-
-	return result;
-}
-OSReturn
-OSKext::dequeueCallbackForRequestTag(
-	OSNumber     *    requestTagNum,
-	OSDictionary ** callbackRecordOut)
-{
-	OSReturn        result          = kOSKextReturnInvalidArgument;
-	OSDictionary  * callbackRecord  = NULL;        // retain if matched!
-	OSNumber      * callbackTagNum  = NULL;        // do not release
-	unsigned int    count, i;
-
-	result = kOSReturnError;
-	count = sRequestCallbackRecords->getCount();
-	for (i = 0; i < count; i++) {
-		callbackRecord = OSDynamicCast(OSDictionary,
-		    sRequestCallbackRecords->getObject(i));
-		if (!callbackRecord) {
-			goto finish;
-		}
-
-		/* If we don't find a tag, we basically have a leak here. Maybe
-		 * we should just remove it.
-		 */
-		callbackTagNum = OSDynamicCast(OSNumber, _OSKextGetRequestArgument(
-			    callbackRecord, kKextRequestArgumentRequestTagKey));
-		if (!callbackTagNum) {
-			goto finish;
-		}
-
-		/* We could be even more paranoid and check that all the incoming
-		 * args match what's in the callback record.
-		 */
-		if (callbackTagNum->isEqualTo(requestTagNum)) {
-			if (callbackRecordOut) {
-				*callbackRecordOut = callbackRecord;
-				callbackRecord->retain();
-			}
-			sRequestCallbackRecords->removeObject(i);
-			result = kOSReturnSuccess;
-			goto finish;
-		}
-	}
-	result = kOSKextReturnNotFound;
+    OSNumber     *    requestTagNum,
+    OSDictionary ** callbackRecordOut)
+{
+    OSReturn        result          = kOSKextReturnInvalidArgument;
+    OSDictionary  * callbackRecord  = NULL;  // retain if matched!
+    OSNumber      * callbackTagNum  = NULL;  // do not release
+    unsigned int    count, i;
+
+    result = kOSReturnError;
+    count = sRequestCallbackRecords->getCount();
+    for (i = 0; i < count; i++) {
+        callbackRecord = OSDynamicCast(OSDictionary,
+            sRequestCallbackRecords->getObject(i));
+        if (!callbackRecord) {
+            goto finish;
+        }
+
+       /* If we don't find a tag, we basically have a leak here. Maybe
+        * we should just remove it.
+        */
+        callbackTagNum = OSDynamicCast(OSNumber, _OSKextGetRequestArgument(
+            callbackRecord, kKextRequestArgumentRequestTagKey));
+        if (!callbackTagNum) {
+            goto finish;
+        }
+
+       /* We could be even more paranoid and check that all the incoming
+        * args match what's in the callback record.
+        */
+        if (callbackTagNum->isEqualTo(requestTagNum)) {
+            if (callbackRecordOut) {
+                *callbackRecordOut = callbackRecord;
+                callbackRecord->retain();
+            }
+            sRequestCallbackRecords->removeObject(i);
+            result = kOSReturnSuccess;
+            goto finish;
+        }
+    }
+    result = kOSKextReturnNotFound;
 
 finish:
-	return result;
-}
-
-
-/*********************************************************************
-* Busy timeout triage
-*********************************************************************/
-/* static */
-bool
-OSKext::pendingIOKitDaemonRequests(void)
-{
-	return sRequestCallbackRecords && sRequestCallbackRecords->getCount();
-}
-
-/*********************************************************************
-* Acquires and releases sKextLock
-*
-* This function is designed to be called by kernelmanagerd and driverkitd
-* and it gathers all codeless kext and dext personalities, and then attempts
-* to map a System (pageable) KC and an Auxiliary (aux) KC.
-*
-* The pageable and aux KC can be loaded only once at boot time.
-* Even if the pageable or aux KC fail to load - this function will
-* not allow a new pageable or aux KC to be installed by subsequent calls.
-* This is done to avoid security issues where userspace has been compromised
-* or the pageable kc has been tampered with and the attacker
-* attempts to re-load a malicious variant.
-* However dexts can be dynamically loaded, so this function can be used
-* to request the installation of a new set of dexts even after boot time.
-*
-*
-*
-* Return: if a KC fails to load the return value will contain:
-*         kOSKextReturnKCLoadFailure. If the pageable KC fails,
-*         the return value will contain kOSKextReturnKCLoadFailureSystemKC.
-*         Similarly, if the aux kc load fails, the return value will
-*         contain kOSKextReturnKCLoadFailureAuxKC. The two values
-*         compose with each other and with kOSKextReturnKCLoadFailure.
-*********************************************************************/
-/* static */
-OSReturn
-OSKext::loadFileSetKexts(OSDictionary * requestDict __unused)
-{
-	static bool daemon_ready = false;
-
-	OSReturn ret = kOSKextReturnInvalidArgument;
-	OSReturn kcerr = 0;
-	bool start_matching = false;
-
-	bool allow_fileset_load = !daemon_ready;
-#if !(defined(__x86_64__) || defined(__i386__))
-	/* never allow KCs full of kexts on non-x86 machines */
-	allow_fileset_load = false;
-#endif
-
-	/*
-	 * Change with 70582300
-	 */
-#if 0 || !defined(VM_MAPPED_KEXTS)
-	/*
-	 * On platforms that don't support the SystemKC or a file-backed
-	 * AuxKC, the kext receipt for 3rd party kexts loaded by the booter
-	 * needs to be queried before we load any codeless kexts or release
-	 * any 3rd party kexts to run. On platforms that support a file-backed
-	 * AuxKC, this process is done via the kext audit mechanism.
-	 */
-
-	printf("KextLog: waiting for kext receipt to be queried.\n");
-	while (!IOServiceWaitForMatchingResource(kOSKextReceiptQueried, UINT64_MAX)) {
-		IOSleep(30);
-	}
-#endif /* !VM_MAPPED_KEXTS */
-
-	/*
-	 * Get the args from the request. Right now we need the file
-	 * name for the pageable and the aux kext collection file sets.
-	 */
-	OSDictionary * requestArgs                = NULL;        // do not release
-	OSString     * pageable_filepath          = NULL;        // do not release
-	OSString     * aux_filepath               = NULL;        // do not release
-	OSArray      * codeless_kexts             = NULL;        // do not release
-
-	kernel_mach_header_t *akc_mh              = NULL;
-
-	requestArgs = OSDynamicCast(OSDictionary,
-	    requestDict->getObject(kKextRequestArgumentsKey));
-
-	if (requestArgs == NULL) {
-		OSKextLog(/* kext */ NULL, kOSKextLogDebugLevel | kOSKextLogIPCFlag,
-		    "KextLog: No arguments in plist for loading fileset kext\n");
-		printf("KextLog: No arguments in plist for loading fileset kext\n");
-		return ret;
-	}
-
-	ret = kOSKextReturnDisabled;
-
-	IORecursiveLockLock(sKextLock);
-
-	if (!sLoadEnabled) {
-		OSKextLog(NULL, kOSKextLogErrorLevel | kOSKextLogIPCFlag,
-		    "KextLog: Kext loading is disabled (attempt to load KCs).");
-		IORecursiveLockUnlock(sKextLock);
-		return ret;
-	}
-
-	pageable_filepath = OSDynamicCast(OSString,
-	    requestArgs->getObject(kKextRequestArgumentPageableKCFilename));
-
-	if (allow_fileset_load && pageable_filepath != NULL) {
-		printf("KextLog: Loading Pageable KC from file %s\n", pageable_filepath->getCStringNoCopy());
-
-		ret = OSKext::loadKCFileSet(pageable_filepath->getCStringNoCopy(), KCKindPageable);
-		if (ret) {
-			OSKextLog(/* kext */ NULL, kOSKextLogDebugLevel | kOSKextLogIPCFlag,
-			    "KextLog: loadKCFileSet for Pageable KC returned %d\n", ret);
-
-			printf("KextLog: loadKCFileSet for Pageable KC returned %d\n", ret);
-			ret = kOSKextReturnKCLoadFailure;
-			kcerr |= kOSKextReturnKCLoadFailureSystemKC;
-			goto try_auxkc;
-		}
-		/*
-		 * Even if the AuxKC fails to load, we still want to send
-		 * the System KC personalities to the catalog for matching
-		 */
-		start_matching = true;
-	} else if (pageable_filepath != NULL) {
-		OSKextLog(/* kext */ NULL, kOSKextLogBasicLevel | kOSKextLogIPCFlag,
-		    "KextLog: ignoring Pageable KC load from %s\n", pageable_filepath->getCStringNoCopy());
-		ret = kOSKextReturnUnsupported;
-	}
-
-try_auxkc:
-	akc_mh = (kernel_mach_header_t*)PE_get_kc_header(KCKindAuxiliary);
-	if (akc_mh) {
-		/*
-		 * If we try to load a deferred AuxKC, then don't ever attempt
-		 * a filesystem map of a file
-		 */
-		allow_fileset_load = false;
-
-		/*
-		 * This function is only called once per boot, so we haven't
-		 * yet loaded an AuxKC. If we have registered the AuxKC mach
-		 * header, that means that the kext collection has been placed
-		 * in memory for us by the booter, and is waiting for us to
-		 * process it.  Grab the deferred XML plist of info
-		 * dictionaries and add all the kexts.
-		 */
-		OSSharedPtr<OSObject>  parsedXML;
-		OSSharedPtr<OSData>    loaded_kcUUID;
-		OSDictionary          *infoDict;
-		parsedXML = consumeDeferredKextCollection(KCKindAuxiliary);
-		infoDict = OSDynamicCast(OSDictionary, parsedXML.get());
-#if !defined(VM_MAPPED_KEXTS)
-		/*
-		 * On platforms where we don't dynamically wire-down / page-in
-		 * kext memory, we need to maintain the invariant that if the
-		 * AuxKC in memory does not contain a kext receipt, then we
-		 * should not load any of the kexts.
-		 */
-		size_t receipt_sz = 0;
-		if (getsectdatafromheader(akc_mh, kReceiptInfoSegment, kAuxKCReceiptSection, &receipt_sz) == NULL || receipt_sz == 0) {
-			OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogArchiveFlag,
-			    "KextLog: WARNING: Failed to load AuxKC from memory: missing receipt");
-			ret = kOSKextReturnKCLoadFailure;
-			goto try_codeless;
-		}
-#endif
-		if (infoDict) {
-			bool added;
-			printf("KextLog: Adding kexts from in-memory AuxKC\n");
-			added = OSKext::addKextsFromKextCollection(akc_mh, infoDict,
-			    kPrelinkTextSegment, loaded_kcUUID, KCKindAuxiliary);
-			if (!loaded_kcUUID) {
-				OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogArchiveFlag,
-				    "KextLog: WARNING: did not find UUID in deferred Aux KC!");
-			} else if (!added) {
-				OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogArchiveFlag,
-				    "KextLog: WARNING: Failed to load AuxKC from memory.");
-			}
-			/* only return success if the pageable load (above) was successful */
-			if (ret != kOSKextReturnKCLoadFailure) {
-				ret = kOSReturnSuccess;
-			}
-			/* the registration of the AuxKC parsed out the KC's UUID already */
-		} else {
-			if (daemon_ready) {
-				/*
-				 * Complain, but don't return an error if this isn't the first time the
-				 * IOKit daemon is checking in. If the daemon ever restarts, we will
-				 * hit this case because we've already consumed the deferred personalities.
-				 * We return success here so that a call to this function from a restarted
-				 * daemon with no codeless kexts will succeed.
-				 */
-				OSKextLog(/* kext */ NULL, kOSKextLogBasicLevel | kOSKextLogIPCFlag,
-				    "KextLog: can't re-parse deferred AuxKC personalities on IOKit daemon restart");
-				if (ret != kOSKextReturnKCLoadFailure) {
-					ret = kOSReturnSuccess;
-				}
-			} else {
-				/* this is a real error case */
-				OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogIPCFlag,
-				    "KextLog: ERROR loading deferred AuxKC: PRELINK_INFO wasn't an OSDictionary");
-				printf("KextLog: ERROR loading deferred AuxKC: PRELINK_INFO wasn't an OSDictionary\n");
-				ret = kOSKextReturnKCLoadFailure;
-				kcerr |= kOSKextReturnKCLoadFailureAuxKC;
-			}
-		}
-	}
-
-	aux_filepath = OSDynamicCast(OSString,
-	    requestArgs->getObject(kKextRequestArgumentAuxKCFilename));
-	if (allow_fileset_load && aux_filepath != NULL) {
-		printf("KextLog: Loading Aux KC from file %s\n", aux_filepath->getCStringNoCopy());
-
-		ret = OSKext::loadKCFileSet(aux_filepath->getCStringNoCopy(), KCKindAuxiliary);
-		if (ret) {
-			OSKextLog(/* kext */ NULL, kOSKextLogDebugLevel | kOSKextLogIPCFlag,
-			    "KextLog: loadKCFileSet for Aux KC returned %d\n", ret);
-
-			printf("KextLog: loadKCFileSet for Aux KC returned %d\n", ret);
-			ret = kOSKextReturnKCLoadFailure;
-			kcerr |= kOSKextReturnKCLoadFailureAuxKC;
-			goto try_codeless;
-		}
-		start_matching = true;
-	} else if (aux_filepath != NULL) {
-		OSKextLog(/* kext */ NULL, kOSKextLogBasicLevel | kOSKextLogIPCFlag,
-		    "KextLog: Ignoring AuxKC load from %s\n", aux_filepath->getCStringNoCopy());
-		if (ret != kOSKextReturnKCLoadFailure) {
-			ret = kOSKextReturnUnsupported;
-		}
-	}
-
-try_codeless:
-	/*
-	 * Load codeless kexts last so that there is no possibilty of a
-	 * codeless kext bundle ID preventing a kext in the system KC from
-	 * loading
-	 */
-	codeless_kexts = OSDynamicCast(OSArray,
-	    requestArgs->getObject(kKextRequestArgumentCodelessPersonalities));
-	if (codeless_kexts != NULL) {
-		uint32_t count = codeless_kexts->getCount();
-		OSKextLog(NULL, kOSKextLogDebugLevel | kOSKextLogIPCFlag,
-		    "KextLog: loading %d codeless kexts/dexts", count);
-		for (uint32_t i = 0; i < count; i++) {
-			OSDictionary *infoDict;
-			infoDict = OSDynamicCast(OSDictionary,
-			    codeless_kexts->getObject(i));
-			if (!infoDict) {
-				continue;
-			}
-			// instantiate a new kext, and don't hold a reference
-			// (the kext subsystem will hold one implicitly)
-			OSKext::withCodelessInfo(infoDict, NULL);
-		}
-		/* ignore errors that are not KC load failures */
-		if (ret != kOSKextReturnKCLoadFailure) {
-			ret = kOSReturnSuccess;
-		}
-		start_matching = true;
-	}
-
-	/* send personalities to the IOCatalog once */
-	if (ret == kOSReturnSuccess || start_matching || sOSKextWasResetAfterUserspaceReboot) {
-		OSKext::sendAllKextPersonalitiesToCatalog(true);
-		/*
-		 * This request necessarily came from the IOKit daemon (kernelmanagerd), so mark
-		 * things as active and start all the delayed matching: the
-		 * dext and codeless kext personalities should have all been
-		 * delivered via this one call.
-		 */
-		if (!daemon_ready) {
-			OSKext::setIOKitDaemonActive();
-			OSKext::setDeferredLoadSucceeded(TRUE);
-			IOService::iokitDaemonLaunched();
-		}
-		if (sOSKextWasResetAfterUserspaceReboot) {
-			sOSKextWasResetAfterUserspaceReboot = false;
-			OSKext::setIOKitDaemonActive();
-			IOService::startDeferredMatches();
-		}
-	}
-
-	if (ret == kOSKextReturnKCLoadFailure) {
-		ret |= kcerr;
-	}
-
-	/*
-	 * Only allow this function to attempt to load the pageable and
-	 * aux KCs once per boot.
-	 */
-	daemon_ready = true;
-
-	IORecursiveLockUnlock(sKextLock);
-
-	return ret;
-}
-
-OSReturn
-OSKext::resetMutableSegments(void)
-{
-	kernel_segment_command_t *seg = NULL;
-	kernel_mach_header_t *k_mh = (kernel_mach_header_t *)kmod_info->address;
-	u_int index = 0;
-	OSKextSavedMutableSegment *savedSegment = NULL;
-	uintptr_t kext_slide = PE_get_kc_slide(kc_type);
-	OSReturn err;
-
-	if (!savedMutableSegments) {
-		OSKextLog(this, kOSKextLogErrorLevel | kOSKextLogLoadFlag,
-		    "Kext %s cannot be reset, mutable segments were not saved.", getIdentifierCString());
-		err = kOSKextReturnInternalError;
-		goto finish;
-	}
-
-	for (seg = firstsegfromheader(k_mh), index = 0; seg; seg = nextsegfromheader(k_mh, seg)) {
-		if (!segmentIsMutable(seg)) {
-			continue;
-		}
-		uint64_t unslid_vmaddr = seg->vmaddr - kext_slide;
-		uint64_t vmsize = seg->vmsize;
-		err = kOSKextReturnInternalError;
-		for (index = 0; index < savedMutableSegments->getCount(); index++) {
-			savedSegment = OSDynamicCast(OSKextSavedMutableSegment, savedMutableSegments->getObject(index));
-			assert(savedSegment);
-			if (savedSegment->getVMAddr() == seg->vmaddr && savedSegment->getVMSize() == seg->vmsize) {
-				OSKextLog(this, kOSKextLogDebugLevel | kOSKextLogLoadFlag,
-				    "Resetting kext %s, mutable segment %.*s %llx->%llx.", getIdentifierCString(), (int)strnlen(seg->segname, sizeof(seg->segname)), seg->segname, unslid_vmaddr, unslid_vmaddr + vmsize - 1);
-				err = savedSegment->restoreContents(seg);
-				if (err != kOSReturnSuccess) {
-					panic("Kext %s cannot be reset, mutable segment %llx->%llx could not be restored.", getIdentifierCString(), unslid_vmaddr, unslid_vmaddr + vmsize - 1);
-				}
-			}
-		}
-		if (err != kOSReturnSuccess) {
-			panic("Kext %s cannot be reset, could not find saved mutable segment for %llx->%llx.", getIdentifierCString(), unslid_vmaddr, unslid_vmaddr + vmsize - 1);
-		}
-	}
-	err = kOSReturnSuccess;
-finish:
-	return err;
-}
-
-
-/*********************************************************************
-* Assumes sKextLock is held.
-*********************************************************************/
-/* static */
-OSReturn
-OSKext::loadKCFileSet(
-	const char *filepath,
-	kc_kind_t   type)
-{
-#if VM_MAPPED_KEXTS
-	/* we only need to load filesets on systems that support VM_MAPPED kexts */
-	OSReturn err;
-	struct vnode *vp = NULL;
-	void *fileset_control;
-	off_t fsize;
-	bool pageable = (type == KCKindPageable);
-
-	if ((pageable && pageableKCloaded) ||
-	    (!pageable && auxKCloaded)) {
-		OSKextLog(/* kext */ NULL, kOSKextLogDebugLevel | kOSKextLogIPCFlag,
-		    "KC FileSet of type %s is already loaded", (pageable ? "Pageable" : "Aux"));
-
-		return kOSKextReturnInvalidArgument;
-	}
-
-	/* Do not allow AuxKC to load if Pageable KC is not loaded */
-	if (!pageable && !pageableKCloaded) {
-		OSKextLog(/* kext */ NULL, kOSKextLogDebugLevel | kOSKextLogIPCFlag,
-		    "Trying to load the Aux KC without loading the Pageable KC");
-		return kOSKextReturnInvalidArgument;
-	}
-
-	fileset_control = ubc_getobject_from_filename(filepath, &vp, &fsize);
-
-	if (fileset_control == NULL) {
-		printf("Could not get memory control object for file %s", filepath);
-
-		OSKextLog(/* kext */ NULL, kOSKextLogDebugLevel | kOSKextLogIPCFlag,
-		    "Could not get memory control object for file %s", filepath);
-		return kOSKextReturnInvalidArgument;
-	}
-	if (vp == NULL) {
-		OSKextLog(/* kext */ NULL, kOSKextLogDebugLevel | kOSKextLogIPCFlag,
-		    "Could not find vnode for file %s", filepath);
-		return kOSKextReturnInvalidArgument;
-	}
-
-	kernel_mach_header_t *mh = NULL;
-	uintptr_t slide = 0;
-
-#if CONFIG_CSR
-	/*
-	 * When SIP is enabled, the KC we map must be SIP-protected
-	 */
-	if (csr_check(CSR_ALLOW_UNRESTRICTED_FS) != 0) {
-		struct vnode_attr va;
-		int error;
-		VATTR_INIT(&va);
-		VATTR_WANTED(&va, va_flags);
-		error = vnode_getattr(vp, &va, vfs_context_current());
-		if (error) {
-			OSKextLog(/* kext */ NULL, kOSKextLogDebugLevel | kOSKextLogIPCFlag,
-			    "vnode_getattr(%s) failed (error=%d)", filepath, error);
-			err = kOSKextReturnInternalError;
-			goto finish;
-		}
-		if (!(va.va_flags & SF_RESTRICTED)) {
-			OSKextLog(/* kext */ NULL, kOSKextLogDebugLevel | kOSKextLogIPCFlag,
-			    "Path to KC '%s' is not SIP-protected", filepath);
-			err = kOSKextReturnInvalidArgument;
-			goto finish;
-		}
-	}
-#endif
-
-	err = OSKext::mapKCFileSet(fileset_control, (vm_size_t)fsize, &mh, 0, &slide, pageable, NULL);
-	if (err) {
-		printf("KextLog: mapKCFileSet returned %d\n", err);
-
-		OSKextLog(/* kext */ NULL, kOSKextLogDebugLevel | kOSKextLogIPCFlag,
-		    "mapKCFileSet returned %d\n", err);
-
-		err = kOSKextReturnInvalidArgument;
-	}
-
-#if CONFIG_CSR
-finish:
-#endif
-	/* Drop the vnode ref returned by ubc_getobject_from_filename if mapKCFileSet failed */
-	assert(vp != NULL);
-	if (err == kOSReturnSuccess) {
-		PE_set_kc_vp(type, vp);
-		if (pageable) {
-			pageableKCloaded = true;
-		} else {
-			auxKCloaded = true;
-		}
-	} else {
-		vnode_put(vp);
-	}
-
-	return err;
-#else
-	(void)filepath;
-	(void)type;
-	return kOSKextReturnUnsupported;
-#endif // VM_MAPPED_KEXTS
-}
-
-#if defined(__x86_64__) || defined(__i386__)
-/*********************************************************************
-* Assumes sKextLock is held.
-*********************************************************************/
-/* static */
-OSReturn
-OSKext::mapKCFileSet(
-	void                 *control,
-	vm_size_t            fsize,
-	kernel_mach_header_t **mhp,
-	off_t                file_offset,
-	uintptr_t            *slidep,
-	bool                 pageable,
-	void                 *map_entry_list)
-{
-	bool fileset_load = false;
-	kern_return_t ret;
-	OSReturn err;
-	kernel_section_t *infoPlistSection = NULL;
-	OSDictionary *infoDict = NULL;
-
-	OSSharedPtr<OSObject> parsedXML;
-	OSSharedPtr<OSString> errorString;
-	OSSharedPtr<OSData> loaded_kcUUID;
-
-	/* Check if initial load for file set */
-	if (*mhp == NULL) {
-		fileset_load = true;
-
-		/* Get a page aligned address from kext map to map the file */
-		vm_map_offset_t pagealigned_addr = get_address_from_kext_map(fsize);
-		if (pagealigned_addr == 0) {
-			return kOSKextReturnNoMemory;
-		}
-
-		*mhp = (kernel_mach_header_t *)pagealigned_addr;
-
-		/* Allocate memory for bailout mechanism */
-		map_entry_list = allocate_kcfileset_map_entry_list();
-		if (map_entry_list == NULL) {
-			return kOSKextReturnNoMemory;
-		}
-	}
-
-	uintptr_t *slideptr = fileset_load ? slidep : NULL;
-	err = mapKCTextSegment(control, mhp, file_offset, slideptr, map_entry_list);
-	/* mhp and slideptr are updated by mapKCTextSegment */
-	if (err) {
-		if (fileset_load) {
-			deallocate_kcfileset_map_entry_list_and_unmap_entries(map_entry_list, TRUE, pageable);
-		}
-		return err;
-	}
-
-	/* Initialize the kc header globals */
-	if (fileset_load) {
-		if (pageable) {
-			PE_set_kc_header(KCKindPageable, *mhp, *slidep);
-		} else {
-			PE_set_kc_header(KCKindAuxiliary, *mhp, *slidep);
-		}
-	}
-
-	/* Iterate through all the segments and map necessary segments */
-	struct load_command *lcp = (struct load_command *) (*mhp + 1);
-	for (unsigned int i = 0; i < (*mhp)->ncmds; i++, lcp = (struct load_command *)((uintptr_t)lcp + lcp->cmdsize)) {
-		vm_map_offset_t start;
-		kernel_mach_header_t *k_mh = NULL;
-		kernel_segment_command_t * seg = NULL;
-		struct fileset_entry_command *fse = NULL;
-
-		if (lcp->cmd == LC_SEGMENT_KERNEL) {
-			seg = (kernel_segment_command_t *)lcp;
-			start = ((uintptr_t)(seg->vmaddr)) + *slidep;
-		} else if (lcp->cmd == LC_FILESET_ENTRY) {
-			fse = (struct fileset_entry_command *)lcp;
-			k_mh = (kernel_mach_header_t *)(((uintptr_t)(fse->vmaddr)) + *slidep);
-
-			/* Map the segments of the mach-o binary */
-			err = OSKext::mapKCFileSet(control, 0, &k_mh, fse->fileoff, slidep, pageable, map_entry_list);
-			if (err) {
-				deallocate_kcfileset_map_entry_list_and_unmap_entries(map_entry_list, TRUE, pageable);
-				return kOSKextReturnInvalidArgument;
-			}
-			continue;
-		} else if (lcp->cmd == LC_DYLD_CHAINED_FIXUPS) {
-			/* Check if the Aux KC is built pageable style */
-			if (!pageable && !fileset_load && !auxKCloaded) {
-				resetAuxKCSegmentOnUnload = true;
-			}
-			continue;
-		} else {
-			continue;
-		}
-
-		if (fileset_load) {
-			if (seg->vmsize == 0) {
-				continue;
-			}
-
-			/* Only map __PRELINK_INFO, __BRANCH_STUBS, __BRANCH_GOTS and __LINKEDIT sections */
-			if (strncmp(seg->segname, kPrelinkInfoSegment, sizeof(seg->segname)) != 0 &&
-			    strncmp(seg->segname, kKCBranchStubs, sizeof(seg->segname)) != 0 &&
-			    strncmp(seg->segname, kKCBranchGots, sizeof(seg->segname)) != 0 &&
-			    strncmp(seg->segname, SEG_LINKEDIT, sizeof(seg->segname)) != 0) {
-				continue;
-			}
-		} else {
-			if (seg->vmsize == 0) {
-				continue;
-			}
-
-			/* Skip the __LINKEDIT, __LINKINFO and __TEXT segments */
-			if (strncmp(seg->segname, SEG_LINKEDIT, sizeof(seg->segname)) == 0 ||
-			    strncmp(seg->segname, SEG_LINKINFO, sizeof(seg->segname)) == 0 ||
-			    strncmp(seg->segname, SEG_TEXT, sizeof(seg->segname)) == 0) {
-				continue;
-			}
-		}
-
-		ret = vm_map_kcfileset_segment(
-			&start, seg->vmsize,
-			(memory_object_control_t)control, seg->fileoff, seg->maxprot);
-
-		if (ret != KERN_SUCCESS) {
-			if (fileset_load) {
-				deallocate_kcfileset_map_entry_list_and_unmap_entries(map_entry_list, TRUE, pageable);
-			}
-			return kOSKextReturnInvalidArgument;
-		}
-		add_kcfileset_map_entry(map_entry_list, start, seg->vmsize);
-	}
-
-	/* Return if regular mach-o */
-	if (!fileset_load) {
-		return 0;
-	}
-
-	/*
-	 * Fixup for the Pageable KC and the Aux KC is done by
-	 * i386_slide_kext_collection_mh_addrs, but it differs in
-	 * following ways:
-	 *
-	 * PageableKC: Fixup only __BRANCH_STUBS segment and top level load commands.
-	 * The fixup of kext segments and kext load commands are done at kext
-	 * load time by calling i386_slide_individual_kext.
-	 *
-	 * AuxKC old style: Fixup all the segments and all the load commands.
-	 *
-	 * AuxKC pageable style: Same as the Pageable KC.
-	 */
-	bool adjust_mach_header = (pageable ? true : ((resetAuxKCSegmentOnUnload) ? true : false));
-	ret = i386_slide_kext_collection_mh_addrs(*mhp, *slidep, adjust_mach_header);
-	if (ret != KERN_SUCCESS) {
-		deallocate_kcfileset_map_entry_list_and_unmap_entries(map_entry_list, TRUE, pageable);
-		return kOSKextReturnInvalidArgument;
-	}
-
-	/* Get the prelink info dictionary */
-	infoPlistSection = getsectbynamefromheader(*mhp, kPrelinkInfoSegment, kPrelinkInfoSection);
-	parsedXML = OSUnserializeXML((const char *)infoPlistSection->addr, errorString);
-	if (parsedXML) {
-		infoDict = OSDynamicCast(OSDictionary, parsedXML.get());
-	}
-
-	if (!infoDict) {
-		const char *errorCString = "(unknown error)";
-
-		if (errorString && errorString->getCStringNoCopy()) {
-			errorCString = errorString->getCStringNoCopy();
-		} else if (parsedXML) {
-			errorCString = "not a dictionary";
-		}
-		OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogArchiveFlag,
-		    "Error unserializing kext info plist section: %s.", errorCString);
-		deallocate_kcfileset_map_entry_list_and_unmap_entries(map_entry_list, TRUE, pageable);
-		return kOSKextReturnInvalidArgument;
-	}
-
-	/* Validate that the Kext Collection is prelinked to the loaded KC */
-	err = OSKext::validateKCFileSetUUID(infoDict, pageable ? KCKindPageable : KCKindAuxiliary);
-	if (err) {
-		deallocate_kcfileset_map_entry_list_and_unmap_entries(map_entry_list, TRUE, pageable);
-		return kOSKextReturnInvalidArgument;
-	}
-
-	/* Set Protection of Segments */
-	OSKext::protectKCFileSet(*mhp, pageable ? KCKindPageable : KCKindAuxiliary);
-
-	OSKext::addKextsFromKextCollection(*mhp,
-	    infoDict, kPrelinkTextSegment,
-	    loaded_kcUUID, pageable ? KCKindPageable : KCKindAuxiliary);
-
-	/* Copy in the KC UUID */
-	if (!loaded_kcUUID) {
-		OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogArchiveFlag,
-		    "WARNING: did not find UUID in prelinked %s KC!", pageable ? "Pageable" : "Aux");
-	} else if (pageable) {
-		pageablekc_uuid_valid = TRUE;
-		memcpy((void *)&pageablekc_uuid, (const void *)loaded_kcUUID->getBytesNoCopy(), loaded_kcUUID->getLength());
-		uuid_unparse_upper(pageablekc_uuid, pageablekc_uuid_string);
-	} else {
-		auxkc_uuid_valid = TRUE;
-		memcpy((void *)&auxkc_uuid, (const void *)loaded_kcUUID->getBytesNoCopy(), loaded_kcUUID->getLength());
-		uuid_unparse_upper(auxkc_uuid, auxkc_uuid_string);
-	}
-
-	deallocate_kcfileset_map_entry_list_and_unmap_entries(map_entry_list, FALSE, pageable);
-
-	return 0;
-}
-
-/*********************************************************************
-* Assumes sKextLock is held.
-*********************************************************************/
-/* static */
-OSReturn
-OSKext::mapKCTextSegment(
-	void                 *control,
-	kernel_mach_header_t **mhp,
-	off_t                file_offset,
-	uintptr_t            *slidep,
-	void                 *map_entry_list)
-{
-	kern_return_t ret;
-	vm_map_offset_t mach_header_map_size = vm_map_round_page(sizeof(kernel_mach_header_t),
-	    PAGE_MASK);
-	vm_map_offset_t load_command_map_size = 0;
-	kernel_mach_header_t *base_mh = *mhp;
-
-	/* Map the mach header at start of fileset for now (vmaddr = 0) */
-	ret = vm_map_kcfileset_segment(
-		(vm_map_offset_t *)&base_mh, mach_header_map_size,
-		(memory_object_control_t)control, file_offset, (VM_PROT_READ | VM_PROT_WRITE));
-
-	if (ret != KERN_SUCCESS) {
-		printf("Kext Log: mapKCTextSegment failed to map mach header of fileset %x", ret);
-
-		OSKextLog(/* kext */ NULL, kOSKextLogDebugLevel | kOSKextLogIPCFlag,
-		    "Failed to map mach header of kc fileset with error %d", ret);
-		return kOSKextReturnInvalidArgument;
-	}
-
-	if (slidep) {
-		/* Verify that it's an MH_FILESET */
-		if (base_mh->filetype != MH_FILESET) {
-			printf("Kext Log: mapKCTextSegment mach header filetype"
-			    " is not an MH_FILESET, it is %x", base_mh->filetype);
-
-			OSKextLog(/* kext */ NULL, kOSKextLogDebugLevel | kOSKextLogIPCFlag,
-			    "mapKCTextSegment mach header filetype is not an MH_FILESET, it is %x", base_mh->filetype);
-
-			/* Unmap the mach header */
-			vm_unmap_kcfileset_segment((vm_map_offset_t *)&base_mh, mach_header_map_size);
-			return kOSKextReturnInvalidArgument;
-		}
-	}
-
-	/* Map the remaining pages of load commands */
-	if (base_mh->sizeofcmds > mach_header_map_size) {
-		vm_map_offset_t load_command_addr = ((vm_map_offset_t)base_mh) + mach_header_map_size;
-		load_command_map_size = base_mh->sizeofcmds - mach_header_map_size;
-
-		/* Map the load commands */
-		ret = vm_map_kcfileset_segment(
-			&load_command_addr, load_command_map_size,
-			(memory_object_control_t)control, file_offset + mach_header_map_size,
-			(VM_PROT_READ | VM_PROT_WRITE));
-
-		if (ret != KERN_SUCCESS) {
-			printf("KextLog: mapKCTextSegment failed to map load commands of fileset %x", ret);
-			OSKextLog(/* kext */ NULL, kOSKextLogDebugLevel | kOSKextLogIPCFlag,
-			    "Failed to map load commands of kc fileset with error %d", ret);
-
-			/* Unmap the mach header */
-			vm_unmap_kcfileset_segment((vm_map_offset_t *)&base_mh, mach_header_map_size);
-			return kOSKextReturnInvalidArgument;
-		}
-	}
-
-	kernel_segment_command_t *text_seg;
-	text_seg = getsegbynamefromheader((kernel_mach_header_t *)base_mh, SEG_TEXT);
-
-	/* Calculate the slide and vm addr of mach header */
-	if (slidep) {
-		*mhp = (kernel_mach_header_t *)((uintptr_t)base_mh + text_seg->vmaddr);
-		*slidep = ((uintptr_t)*mhp) - text_seg->vmaddr;
-	}
-
-	/* Cache the text segment size and file offset before unmapping */
-	vm_map_offset_t text_segment_size = text_seg->vmsize;
-	vm_object_offset_t text_segment_fileoff = text_seg->fileoff;
-	vm_prot_t text_maxprot = text_seg->maxprot;
-
-	/* Unmap the first page and loadcommands and map the text segment */
-	ret = vm_unmap_kcfileset_segment((vm_map_offset_t *)&base_mh, mach_header_map_size);
-	assert(ret == KERN_SUCCESS);
-
-	if (load_command_map_size) {
-		vm_map_offset_t load_command_addr = ((vm_map_offset_t)base_mh) + mach_header_map_size;
-		ret = vm_unmap_kcfileset_segment(&load_command_addr, load_command_map_size);
-		assert(ret == KERN_SUCCESS);
-	}
-
-	/* Map the text segment at actual vm addr specified in fileset */
-	ret = vm_map_kcfileset_segment((vm_map_offset_t *)mhp, text_segment_size,
-	    (memory_object_control_t)control, text_segment_fileoff, text_maxprot);
-	if (ret != KERN_SUCCESS) {
-		OSKextLog(/* kext */ NULL, kOSKextLogDebugLevel | kOSKextLogIPCFlag,
-		    "Failed to map Text segment of kc fileset with error %d", ret);
-		return kOSKextReturnInvalidArgument;
-	}
-
-	add_kcfileset_map_entry(map_entry_list, (vm_map_offset_t)*mhp, text_segment_size);
-	return 0;
-}
-
-/*********************************************************************
-* Assumes sKextLock is held.
-*********************************************************************/
-/* static */
-OSReturn
-OSKext::protectKCFileSet(
-	kernel_mach_header_t *mh,
-	kc_kind_t            type)
-{
-	vm_map_t                    kext_map        = g_kext_map;
-	kernel_segment_command_t  * seg             = NULL;
-	vm_map_offset_t             start           = 0;
-	vm_map_offset_t             end             = 0;
-	vm_map_size_t               size            = 0;
-	OSReturn                    ret             = 0;
-
-	/* Set VM permissions */
-	seg = firstsegfromheader((kernel_mach_header_t *)mh);
-	while (seg) {
-		start = round_page(seg->vmaddr);
-		end = trunc_page(seg->vmaddr + seg->vmsize);
-		size = end - start;
-
-		/*
-		 * Wire down and protect __TEXT, __BRANCH_STUBS and __BRANCH_GOTS
-		 * for the Pageable KC and the Aux KC, wire down and protect __LINKEDIT
-		 * for the Aux KC as well.
-		 */
-		if (strncmp(seg->segname, kKCBranchGots, sizeof(seg->segname)) == 0 ||
-		    strncmp(seg->segname, kKCBranchStubs, sizeof(seg->segname)) == 0 ||
-		    strncmp(seg->segname, SEG_TEXT, sizeof(seg->segname)) == 0 ||
-		    (type == KCKindAuxiliary && !resetAuxKCSegmentOnUnload &&
-		    strncmp(seg->segname, SEG_LINKEDIT, sizeof(seg->segname)) == 0)) {
-			ret = OSKext_protect((kernel_mach_header_t *)mh,
-			    kext_map, start, size, seg->maxprot, TRUE, type);
-			if (ret != KERN_SUCCESS) {
-				printf("OSKext protect failed with error %d", ret);
-				return kOSKextReturnInvalidArgument;
-			}
-
-			ret = OSKext_protect((kernel_mach_header_t *)mh,
-			    kext_map, start, size, seg->initprot, FALSE, type);
-			if (ret != KERN_SUCCESS) {
-				printf("OSKext protect failed with error %d", ret);
-				return kOSKextReturnInvalidArgument;
-			}
-
-			ret = OSKext_wire((kernel_mach_header_t *)mh,
-			    kext_map, start, end, seg->initprot, FALSE, type);
-			if (ret != KERN_SUCCESS) {
-				printf("OSKext wire failed with error %d", ret);
-				return kOSKextReturnInvalidArgument;
-			}
-		}
-
-		seg = nextsegfromheader((kernel_mach_header_t *) mh, seg);
-	}
-
-	return 0;
-}
-
-/*********************************************************************
-* Assumes sKextLock is held.
-*********************************************************************/
-/* static */
-void
-OSKext::freeKCFileSetcontrol(void)
-{
-	PE_reset_all_kc_vp();
-}
-
-/*********************************************************************
-* Assumes sKextLock is held.
-*
-* resetKCFileSetSegments: Kext start function expects data segment to
-* be pristine on every load, unmap the dirty segments on unload and
-* remap them from FileSet on disk. Remap all segments of kext since
-* fixups are done per kext and not per segment.
-*********************************************************************/
-OSReturn
-OSKext::resetKCFileSetSegments(void)
-{
-	kernel_segment_command_t *seg = NULL;
-	kernel_segment_command_t *text_seg;
-	uint32_t text_fileoff;
-	kernel_mach_header_t *k_mh = NULL;
-	uintptr_t slide;
-	struct vnode *vp = NULL;
-	void *fileset_control = NULL;
-	bool pageable = (kc_type == KCKindPageable);
-	OSReturn err;
-	kern_return_t kr;
-
-	/* Check the vnode reference is still available */
-	vp = (struct vnode *)PE_get_kc_vp(kc_type);
-	if (vp == NULL) {
-		OSKextLog(this, kOSKextLogProgressLevel | kOSKextLogLoadFlag,
-		    "Kext %s could not be reset, since reboot released the vnode ref", getIdentifierCString());
-		return kOSKextReturnInternalError;
-	}
-
-	fileset_control = ubc_getobject(vp, 0);
-	assert(fileset_control != NULL);
-
-	OSKextLog(this, kOSKextLogProgressLevel | kOSKextLogLoadFlag,
-	    "Kext %s resetting all segments", getIdentifierCString());
-
-	k_mh = (kernel_mach_header_t *)kmod_info->address;
-	text_seg = getsegbynamefromheader((kernel_mach_header_t *)kmod_info->address, SEG_TEXT);
-	text_fileoff = text_seg->fileoff;
-	slide = PE_get_kc_slide(kc_type);
-
-	seg = firstsegfromheader((kernel_mach_header_t *)k_mh);
-	while (seg) {
-		if (seg->vmsize == 0) {
-			seg = nextsegfromheader((kernel_mach_header_t *) k_mh, seg);
-			continue;
-		}
-
-		/* Skip the __LINKEDIT, __LINKINFO and __TEXT segments */
-		if (strncmp(seg->segname, SEG_LINKEDIT, sizeof(seg->segname)) == 0 ||
-		    strncmp(seg->segname, SEG_LINKINFO, sizeof(seg->segname)) == 0 ||
-		    strncmp(seg->segname, SEG_TEXT, sizeof(seg->segname)) == 0) {
-			seg = nextsegfromheader((kernel_mach_header_t *) k_mh, seg);
-			continue;
-		}
-
-		kr = vm_unmap_kcfileset_segment(&seg->vmaddr, seg->vmsize);
-		assert(kr == KERN_SUCCESS);
-		seg = nextsegfromheader((kernel_mach_header_t *) k_mh, seg);
-	}
-
-	/* Unmap the text segment */
-	kr = vm_unmap_kcfileset_segment(&text_seg->vmaddr, text_seg->vmsize);
-	assert(kr == KERN_SUCCESS);
-
-	/* Map all the segments of the kext */
-	err = OSKext::mapKCFileSet(fileset_control, 0, &k_mh, text_fileoff, &slide, pageable, NULL);
-	if (err) {
-		panic("Could not reset segments of a mapped kext, error %x", err);
-	}
-
-	/* Update address in kmod_info, since it has been reset */
-	if (kmod_info->address) {
-		kmod_info->address = (((uintptr_t)(kmod_info->address)) + slide);
-	}
-
-	return 0;
-}
-
-/*********************************************************************
-* Mechanism to track all segment mapping while mapping KC fileset.
-*********************************************************************/
-
-struct kcfileset_map_entry {
-	vm_map_offset_t me_start;
-	vm_map_offset_t me_size;
-};
-
-struct kcfileset_map_entry_list {
-	int                        kme_list_count;
-	int                        kme_list_index;
-	struct kcfileset_map_entry kme_list[];
-};
-
-#define KCFILESET_MAP_ENTRY_MAX (16380)
-
-static void *
-allocate_kcfileset_map_entry_list(void)
-{
-	struct kcfileset_map_entry_list *entry_list;
-
-	entry_list = kalloc_type(struct kcfileset_map_entry_list,
-	    struct kcfileset_map_entry, KCFILESET_MAP_ENTRY_MAX, Z_WAITOK_ZERO);
-
-	entry_list->kme_list_count = KCFILESET_MAP_ENTRY_MAX;
-	entry_list->kme_list_index = 0;
-	return entry_list;
-}
-
-static void
-add_kcfileset_map_entry(
-	void            *map_entry_list,
-	vm_map_offset_t start,
-	vm_map_offset_t size)
-{
-	if (map_entry_list == NULL) {
-		return;
-	}
-
-	struct kcfileset_map_entry_list *entry_list = (struct kcfileset_map_entry_list *)map_entry_list;
-
-	if (entry_list->kme_list_index >= entry_list->kme_list_count) {
-		panic("Ran out of map kc fileset list");
-	}
-
-	entry_list->kme_list[entry_list->kme_list_index].me_start = start;
-	entry_list->kme_list[entry_list->kme_list_index].me_size = size;
-
-	entry_list->kme_list_index++;
-}
-
-static void
-deallocate_kcfileset_map_entry_list_and_unmap_entries(
-	void      *map_entry_list,
-	boolean_t unmap_entries,
-	bool      pageable)
-{
-	struct kcfileset_map_entry_list *entry_list = (struct kcfileset_map_entry_list *)map_entry_list;
-
-	if (unmap_entries) {
-		for (int i = 0; i < entry_list->kme_list_index; i++) {
-			kern_return_t ret;
-			ret = vm_unmap_kcfileset_segment(
-				&(entry_list->kme_list[i].me_start),
-				entry_list->kme_list[i].me_size);
-			assert(ret == KERN_SUCCESS);
-		}
-
-		PE_reset_kc_header(pageable ? KCKindPageable : KCKindAuxiliary);
-	}
-
-	kfree_type(struct kcfileset_map_entry_list, struct kcfileset_map_entry,
-	    KCFILESET_MAP_ENTRY_MAX, entry_list);
-}
-
-/*********************************************************************
-* Mechanism to map kext segment.
-*********************************************************************/
-
-kern_return_t
-vm_map_kcfileset_segment(
-	vm_map_offset_t    *start,
-	vm_map_offset_t    size,
-	void               *control,
-	vm_object_offset_t fileoffset,
-	vm_prot_t          max_prot)
-{
-	vm_map_kernel_flags_t vmk_flags = {
-		.vmf_fixed = true,
-		.vmkf_no_copy_on_read = true,
-		.vmkf_cs_enforcement_override = true,
-		.vm_tag = VM_KERN_MEMORY_OSKEXT,
-	};
-	kern_return_t ret;
-
-	/* Add Write to max prot to allow fixups */
-	max_prot = max_prot | VM_PROT_WRITE;
-
-	/*
-	 * Map the segments from file as COPY mappings to
-	 * make sure changes on disk to the file does not affect
-	 * mapped segments.
-	 */
-	ret = vm_map_enter_mem_object_control(
-		g_kext_map,
-		start,
-		size,
-		(mach_vm_offset_t)0,
-		vmk_flags,
-		(memory_object_control_t)control,
-		fileoffset,
-		TRUE,         /* copy */
-		(VM_PROT_READ | VM_PROT_WRITE), max_prot,
-		VM_INHERIT_NONE);
-
-	return ret;
-}
-
-kern_return_t
-vm_unmap_kcfileset_segment(
-	vm_map_offset_t    *start,
-	vm_map_offset_t    size)
-{
-	return mach_vm_deallocate(g_kext_map, *start, size);
-}
-
-#endif //(__x86_64__) || defined(__i386__)
-
-/*********************************************************************
-* Assumes sKextLock is held.
-*********************************************************************/
-/* static */
-OSReturn
-OSKext::validateKCFileSetUUID(
-	OSDictionary         *infoDict,
-	kc_kind_t            type)
-{
-	OSReturn ret           = kOSReturnSuccess;
-
-	if (!kernelcache_uuid_valid) {
-		OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogArchiveFlag,
-		    "validateKCFileSetUUID Boot KC UUID was not set at boot.");
-		ret = kOSKextReturnInvalidArgument;
-		goto finish;
-	}
-	ret = OSKext::validateKCUUIDfromPrelinkInfo(&kernelcache_uuid, type, infoDict, kPrelinkInfoBootKCIDKey);
-	if (ret != 0) {
-		goto finish;
-	}
-
-#if defined(__x86_64__) || defined(__i386__)
-	/* Check if the Aux KC is prelinked to correct Pageable KC */
-	if (type == KCKindAuxiliary) {
-		if (!pageablekc_uuid_valid) {
-			OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogArchiveFlag,
-			    "validateKCFileSetUUID Pageable KC UUID was not set while loading Pageable KC.");
-			ret = kOSKextReturnInvalidArgument;
-			goto finish;
-		}
-		ret = OSKext::validateKCUUIDfromPrelinkInfo(&pageablekc_uuid, type, infoDict, kPrelinkInfoPageableKCIDKey);
-		if (ret != 0) {
-			goto finish;
-		}
-	}
-#endif //(__x86_64__) || defined(__i386__)
-
-	printf("KextLog: Collection UUID matches with loaded KCs.\n");
-finish:
-	return ret;
-}
-
-/*********************************************************************
-* Assumes sKextLock is held.
-*********************************************************************/
-/* static */
-OSReturn
-OSKext::validateKCUUIDfromPrelinkInfo(
-	uuid_t               *loaded_kcuuid,
-	kc_kind_t             type,
-	OSDictionary         *infoDict,
-	const char           *uuid_key)
-{
-	/* extract the UUID from the dictionary */
-	OSData *prelinkinfoKCUUID = OSDynamicCast(OSData, infoDict->getObject(uuid_key));
-	if (!prelinkinfoKCUUID) {
-		OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogArchiveFlag,
-		    "validateKCUUID Info plist does not contain %s KC UUID key.", uuid_key);
-		return kOSKextReturnInvalidArgument;
-	}
-
-	if (prelinkinfoKCUUID->getLength() != sizeof(uuid_t)) {
-		OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogArchiveFlag,
-		    "validateKCUUID %s KC UUID has wrong length: %d.", uuid_key, prelinkinfoKCUUID->getLength());
-		return kOSKextReturnInvalidArgument;
-	}
-
-	if (memcmp((void *)loaded_kcuuid, (const void *)prelinkinfoKCUUID->getBytesNoCopy(),
-	    prelinkinfoKCUUID->getLength())) {
-		OSData       *info_dict_uuid;
-		uuid_string_t info_dict_uuid_str = {};
-		uuid_string_t expected_uuid_str = {};
-		uuid_string_t given_uuid_str = {};
-		uuid_t        given_uuid;
-
-		/* extract the KC UUID from the dictionary */
-		info_dict_uuid = OSDynamicCast(OSData, infoDict->getObject(kPrelinkInfoKCIDKey));
-		if (info_dict_uuid && info_dict_uuid->getLength() == sizeof(uuid_t)) {
-			uuid_t tmp_uuid;
-			memcpy(tmp_uuid, (const void *)info_dict_uuid->getBytesNoCopy(), sizeof(tmp_uuid));
-			uuid_unparse(tmp_uuid, info_dict_uuid_str);
-		}
-
-		uuid_unparse(*loaded_kcuuid, expected_uuid_str);
-		memcpy(given_uuid, (const void *)prelinkinfoKCUUID->getBytesNoCopy(), sizeof(given_uuid));
-		uuid_unparse(given_uuid, given_uuid_str);
-
-		printf("KextLog: ERROR: UUID from key:%s %s != expected %s (KC UUID: %s)\n", uuid_key,
-		    given_uuid_str, expected_uuid_str, info_dict_uuid_str);
-		OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogArchiveFlag,
-		    "KextLog: ERROR: UUID from key:%s %s != expected %s (KC UUID: %s)\n", uuid_key,
-		    given_uuid_str, expected_uuid_str, info_dict_uuid_str);
-		if (type == KCKindPageable && sPanicOnKCMismatch) {
-			panic("System KC UUID %s linked against %s, but %s is loaded",
-			    info_dict_uuid_str, given_uuid_str, expected_uuid_str);
-		}
-		return kOSKextReturnInvalidArgument;
-	}
-
-	return 0;
+    return result;
 }
 
 /*********************************************************************
@@ -14321,163 +9016,93 @@
 OSReturn
 OSKext::dispatchResource(OSDictionary * requestDict)
 {
-	OSReturn                        result          = kOSReturnError;
-	OSSharedPtr<OSDictionary>       callbackRecord;
-	OSNumber                      * requestTag      = NULL;        // do not release
-	OSNumber                      * requestResult   = NULL;        // do not release
-	OSData                        * dataObj         = NULL;        // do not release
-	uint32_t                        dataLength      = 0;
-	const void                    * dataPtr         = NULL;        // do not free
-	OSValueObject<OSKextRequestResourceCallback> * callbackWrapper = nullptr; // do not release
-	OSKextRequestResourceCallback   callback        = NULL;
-	OSValueObject<void *>         * contextWrapper  = nullptr;     // do not release
-	void                          * context         = NULL;        // do not free
-	OSSharedPtr<OSKext>             callbackKext;
-
-	/* Get the args from the request. Right now we need the tag
-	 * to look up the callback record, and the result for invoking the callback.
-	 */
-	requestTag = OSDynamicCast(OSNumber, _OSKextGetRequestArgument(requestDict,
-	    kKextRequestArgumentRequestTagKey));
-	requestResult = OSDynamicCast(OSNumber, _OSKextGetRequestArgument(requestDict,
-	    kKextRequestArgumentResultKey));
-	if (!requestTag || !requestResult) {
-		result = kOSKextReturnInvalidArgument;
-		goto finish;
-	}
-
-	/* Look for a callback record matching this request's tag.
-	 */
-	result = dequeueCallbackForRequestTag(requestTag, callbackRecord);
-	if (result != kOSReturnSuccess) {
-		goto finish;
-	}
-
-	/*****
-	 * Get the context pointer of the callback record (if there is one).
-	 */
-	contextWrapper = OSDynamicCast(OSValueObject<void *>, _OSKextGetRequestArgument(
-		    callbackRecord.get(), kKextRequestArgumentContextKey));
-	context = _OSKextExtractPointer(contextWrapper);
-	if (contextWrapper && !context) {
-		goto finish;
-	}
-
-	callbackWrapper = OSDynamicCast(OSValueObject<OSKextRequestResourceCallback>,
-	    _OSKextGetRequestArgument(callbackRecord.get(),
-	    kKextRequestArgumentCallbackKey));
-	callback = _OSKextExtractCallbackPointer(callbackWrapper);
-	if (!callback) {
-		goto finish;
-	}
-
-	/* Check for a data obj. We might not have one and that's ok, that means
-	 * we didn't find the requested resource, and we still have to tell the
-	 * caller that via the callback.
-	 */
-	dataObj = OSDynamicCast(OSData, _OSKextGetRequestArgument(requestDict,
-	    kKextRequestArgumentValueKey));
-	if (dataObj) {
-		dataPtr = dataObj->getBytesNoCopy();
-		dataLength = dataObj->getLength();
-	}
-
-	callbackKext = OSKext::lookupKextWithAddress((vm_address_t)callback);
-	if (!callbackKext) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel | kOSKextLogIPCFlag,
-		    "Can't invoke callback for resource request; ");
-		goto finish;
-	}
-	if (!callbackKext->flags.starting && !callbackKext->flags.started) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel | kOSKextLogIPCFlag,
-		    "Can't invoke kext resource callback; ");
-		goto finish;
-	}
-
-	(void)callback(requestTag->unsigned32BitValue(),
-	    (OSReturn)requestResult->unsigned32BitValue(),
-	    dataPtr, dataLength, context);
-
-	result = kOSReturnSuccess;
+    OSReturn                        result          = kOSReturnError;
+    OSDictionary                  * callbackRecord  = NULL;  // must release
+    OSNumber                      * requestTag      = NULL;  // do not release
+    OSNumber                      * requestResult   = NULL;  // do not release
+    OSData                        * dataObj         = NULL;  // do not release
+    uint32_t                        dataLength      = 0;
+    const void                    * dataPtr         = NULL;  // do not free
+    OSData                        * callbackWrapper = NULL;  // do not release
+    OSKextRequestResourceCallback   callback        = NULL;
+    OSData                        * contextWrapper  = NULL;  // do not release
+    void                          * context         = NULL;  // do not free
+    OSKext                        * callbackKext    = NULL;  // must release (looked up)
+
+   /* Get the args from the request. Right now we need the tag
+    * to look up the callback record, and the result for invoking the callback.
+    */
+    requestTag = OSDynamicCast(OSNumber, _OSKextGetRequestArgument(requestDict,
+        kKextRequestArgumentRequestTagKey));
+    requestResult = OSDynamicCast(OSNumber, _OSKextGetRequestArgument(requestDict,
+        kKextRequestArgumentResultKey));
+    if (!requestTag || !requestResult) {
+        result = kOSKextReturnInvalidArgument;
+        goto finish;
+    }
+
+   /* Look for a callback record matching this request's tag.
+    */
+    result = dequeueCallbackForRequestTag(requestTag, &callbackRecord);
+    if (result != kOSReturnSuccess) {
+        goto finish;
+    }
+
+   /*****
+    * Get the context pointer of the callback record (if there is one).
+    */
+    contextWrapper = OSDynamicCast(OSData, _OSKextGetRequestArgument(callbackRecord,
+        kKextRequestArgumentContextKey));
+    context = _OSKextExtractPointer(contextWrapper);
+    if (contextWrapper && !context) {
+        goto finish;
+    }
+
+    callbackWrapper = OSDynamicCast(OSData,
+        _OSKextGetRequestArgument(callbackRecord,
+            kKextRequestArgumentCallbackKey));
+    callback = (OSKextRequestResourceCallback)
+        _OSKextExtractPointer(callbackWrapper);
+    if (!callback) {
+        goto finish;
+    }
+
+   /* Check for a data obj. We might not have one and that's ok, that means
+    * we didn't find the requested resource, and we still have to tell the
+    * caller that via the callback.
+    */
+    dataObj = OSDynamicCast(OSData, _OSKextGetRequestArgument(requestDict,
+        kKextRequestArgumentValueKey));
+    if (dataObj) {
+        dataPtr = dataObj->getBytesNoCopy();
+        dataLength = dataObj->getLength();
+    }
+    
+    callbackKext = OSKext::lookupKextWithAddress((vm_address_t)callback);
+    if (!callbackKext) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogErrorLevel | kOSKextLogIPCFlag,
+            "Can't invoke callback for resource request; ");
+        goto finish;
+    }
+    if (!callbackKext->flags.starting && !callbackKext->flags.started) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogErrorLevel | kOSKextLogIPCFlag,
+            "Can't invoke kext resource callback; ");
+        goto finish;
+    }
+
+    (void)callback(requestTag->unsigned32BitValue(),
+        (OSReturn)requestResult->unsigned32BitValue(),
+        dataPtr, dataLength, context);
+        
+    result = kOSReturnSuccess;
 
 finish:
-	return result;
-}
-
-/*********************************************************************
-* Assumes sKextLock is held.
-*********************************************************************/
-/* static */
-OSReturn
-OSKext::setMissingAuxKCBundles(OSDictionary * requestDict)
-{
-	OSSharedPtr<OSDictionary> missingIDs;
-	OSArray *bundleIDList     = NULL; // do not release
-
-	bundleIDList = OSDynamicCast(OSArray, _OSKextGetRequestArgument(
-		    requestDict, kKextRequestArgumentMissingBundleIDs));
-	if (!bundleIDList) {
-		return kOSKextReturnInvalidArgument;
-	}
-
-	missingIDs = OSDictionary::withCapacity(bundleIDList->getCount());
-	if (!missingIDs) {
-		return kOSKextReturnNoMemory;
-	}
-
-	uint32_t count, i;
-	count = bundleIDList->getCount();
-	for (i = 0; i < count; i++) {
-		OSString *thisID = OSDynamicCast(OSString, bundleIDList->getObject(i));
-		if (thisID) {
-			missingIDs->setObject(thisID, kOSBooleanFalse);
-		}
-	}
-
-	sNonLoadableKextsByID.reset(missingIDs.get(), OSRetain);
-
-	return kOSReturnSuccess;
-}
-
-/*********************************************************************
-* Assumes sKextLock is held.
-*********************************************************************/
-/* static */
-OSReturn
-OSKext::setAuxKCBundleAvailable(OSString *kextIdentifier, OSDictionary *requestDict)
-{
-	bool loadable = true;
-	if (!kextIdentifier) {
-		return kOSKextReturnInvalidArgument;
-	}
-
-	if (requestDict) {
-		OSBoolean *loadableArg;
-		loadableArg = OSDynamicCast(OSBoolean, _OSKextGetRequestArgument(
-			    requestDict, kKextRequestArgumentBundleAvailability));
-		/* If we find the "Bundle Available" arg, and it's false, then
-		 * mark the bundle ID as _not_ loadable
-		 */
-		if (loadableArg && !loadableArg->getValue()) {
-			loadable = false;
-		}
-	}
-
-	if (!sNonLoadableKextsByID) {
-		sNonLoadableKextsByID = OSDictionary::withCapacity(1);
-	}
-
-	sNonLoadableKextsByID->setObject(kextIdentifier, OSBoolean::withBoolean(loadable));
-
-	OSKextLog(/* kext */ NULL,
-	    kOSKextLogBasicLevel | kOSKextLogIPCFlag,
-	    "KextLog: AuxKC bundle %s marked as %s",
-	    kextIdentifier->getCStringNoCopy(),
-	    (loadable ? "loadable" : "NOT loadable"));
-
-	return kOSReturnSuccess;
+    if (callbackKext)   callbackKext->release();
+    if (callbackRecord) callbackRecord->release();
+
+    return result;
 }
 
 /*********************************************************************
@@ -14485,36 +9110,37 @@
 /* static */
 void
 OSKext::invokeRequestCallback(
-	OSDictionary * callbackRecord,
-	OSReturn       callbackResult)
-{
-	OSString * predicate  = _OSKextGetRequestPredicate(callbackRecord);
-	OSSharedPtr<OSNumber> resultNum;
-
-	if (!predicate) {
-		goto finish;
-	}
-
-	resultNum  = OSNumber::withNumber((long long unsigned int)callbackResult,
-	    8 * sizeof(callbackResult));
-	if (!resultNum) {
-		goto finish;
-	}
-
-	/* Insert the result into the callback record and dispatch it as if it
-	 * were the reply coming down from user space.
-	 */
-	_OSKextSetRequestArgument(callbackRecord, kKextRequestArgumentResultKey,
-	    resultNum.get());
-
-	if (predicate->isEqualTo(kKextRequestPredicateRequestResource)) {
-		/* This removes the pending callback record.
-		 */
-		OSKext::dispatchResource(callbackRecord);
-	}
+    OSDictionary * callbackRecord,
+    OSReturn       callbackResult)
+{
+    OSString * predicate  = _OSKextGetRequestPredicate(callbackRecord);
+    OSNumber * resultNum  = NULL;  // must release
+
+    if (!predicate) {
+        goto finish;
+    }
+
+    resultNum  = OSNumber::withNumber((long long unsigned int)callbackResult,
+        8 * sizeof(callbackResult));
+    if (!resultNum) {
+        goto finish;
+    }
+    
+   /* Insert the result into the callback record and dispatch it as if it
+    * were the reply coming down from user space.
+    */
+    _OSKextSetRequestArgument(callbackRecord, kKextRequestArgumentResultKey,
+        resultNum);
+
+    if (predicate->isEqualTo(kKextRequestPredicateRequestResource)) {
+       /* This removes the pending callback record.
+        */
+        OSKext::dispatchResource(callbackRecord);
+    }
 
 finish:
-	return;
+    if (resultNum) resultNum->release();
+    return;
 }
 
 /*********************************************************************
@@ -14523,26 +9149,28 @@
 /* static */
 OSReturn
 OSKext::cancelRequest(
-	OSKextRequestTag    requestTag,
-	void             ** contextOut)
-{
-	OSReturn       result         = kOSKextReturnNoMemory;
-	OSSharedPtr<OSDictionary> callbackRecord;
-	OSValueObject<void *> * contextWrapper = nullptr; // do not release
-
-	IORecursiveLockLock(sKextLock);
-	result = OSKext::dequeueCallbackForRequestTag(requestTag,
-	    callbackRecord);
-	IORecursiveLockUnlock(sKextLock);
-
-	if (result == kOSReturnSuccess && contextOut) {
-		contextWrapper = OSDynamicCast(OSValueObject<void *>,
-		    _OSKextGetRequestArgument(callbackRecord.get(),
-		    kKextRequestArgumentContextKey));
-		*contextOut = _OSKextExtractPointer(contextWrapper);
-	}
-
-	return result;
+    OSKextRequestTag    requestTag,
+    void             ** contextOut)
+{
+    OSReturn       result         = kOSKextReturnNoMemory;
+    OSDictionary * callbackRecord = NULL;  // must release
+    OSData       * contextWrapper = NULL;  // do not release
+
+    IORecursiveLockLock(sKextLock);
+    result = OSKext::dequeueCallbackForRequestTag(requestTag,
+        &callbackRecord);
+    IORecursiveLockUnlock(sKextLock);
+
+    if (result == kOSReturnSuccess && contextOut) {
+        contextWrapper = OSDynamicCast(OSData,
+            _OSKextGetRequestArgument(callbackRecord,
+                kKextRequestArgumentContextKey));
+        *contextOut = _OSKextExtractPointer(contextWrapper);
+    }
+        
+    if (callbackRecord) callbackRecord->release();
+
+    return result;
 }
 
 /*********************************************************************
@@ -14550,50 +9178,51 @@
 *********************************************************************/
 void
 OSKext::invokeOrCancelRequestCallbacks(
-	OSReturn callbackResult,
-	bool     invokeFlag)
-{
-	unsigned int count, i;
-
-	count = sRequestCallbackRecords->getCount();
-	if (!count) {
-		goto finish;
-	}
-
-	i = count - 1;
-	do {
-		OSDictionary * request = OSDynamicCast(OSDictionary,
-		    sRequestCallbackRecords->getObject(i));
-
-		if (!request) {
-			continue;
-		}
-		auto * callbackWrapper = OSDynamicCast(OSValueObject<OSKextRequestResourceCallback>,
-		    _OSKextGetRequestArgument(request,
-		    kKextRequestArgumentCallbackKey));
-
-		if (!callbackWrapper) {
-			sRequestCallbackRecords->removeObject(i);
-			continue;
-		}
-
-		vm_address_t callbackAddress = (vm_address_t)
-		    ptrauth_strip(_OSKextExtractPointer(callbackWrapper), ptrauth_key_function_pointer);
-
-		if ((kmod_info->address <= callbackAddress) &&
-		    (callbackAddress < (kmod_info->address + kmod_info->size))) {
-			if (invokeFlag) {
-				/* This removes the callback record.
-				 */
-				invokeRequestCallback(request, callbackResult);
-			} else {
-				sRequestCallbackRecords->removeObject(i);
-			}
-		}
-	} while (i--);
+    OSReturn callbackResult,
+    bool     invokeFlag)
+{
+    unsigned int count, i;
+    
+    count = sRequestCallbackRecords->getCount();
+    if (!count) {
+        goto finish;
+    }
+
+    i = count - 1;
+    do {
+        OSDictionary * request = OSDynamicCast(OSDictionary,
+            sRequestCallbackRecords->getObject(i));
+
+        if (!request) {
+            continue;
+        }
+        OSData * callbackWrapper = OSDynamicCast(OSData,
+            _OSKextGetRequestArgument(request,
+                kKextRequestArgumentCallbackKey));
+            
+        if (!callbackWrapper) {
+            sRequestCallbackRecords->removeObject(i);
+            continue;
+        }
+
+        vm_address_t callbackAddress = (vm_address_t)
+            _OSKextExtractPointer(callbackWrapper);
+
+        if ((kmod_info->address <= callbackAddress) &&
+            (callbackAddress < (kmod_info->address + kmod_info->size))) {
+
+            if (invokeFlag) {
+               /* This removes the callback record.
+                */
+                invokeRequestCallback(request, callbackResult);
+            } else {
+                sRequestCallbackRecords->removeObject(i);
+            }
+        }
+    } while (i--);
 
 finish:
-	return;
+    return;
 }
 
 /*********************************************************************
@@ -14602,265 +9231,251 @@
 uint32_t
 OSKext::countRequestCallbacks(void)
 {
-	uint32_t     result = 0;
-	unsigned int count, i;
-
-	count = sRequestCallbackRecords->getCount();
-	if (!count) {
-		goto finish;
-	}
-
-	i = count - 1;
-	do {
-		OSDictionary * request = OSDynamicCast(OSDictionary,
-		    sRequestCallbackRecords->getObject(i));
-
-		if (!request) {
-			continue;
-		}
-		auto * callbackWrapper = OSDynamicCast(OSValueObject<OSKextRequestResourceCallback>,
-		    _OSKextGetRequestArgument(request,
-		    kKextRequestArgumentCallbackKey));
-
-		if (!callbackWrapper) {
-			continue;
-		}
-
-		vm_address_t callbackAddress = (vm_address_t)
-		    ptrauth_strip(_OSKextExtractPointer(callbackWrapper), ptrauth_key_function_pointer);
-
-		if ((kmod_info->address <= callbackAddress) &&
-		    (callbackAddress < (kmod_info->address + kmod_info->size))) {
-			result++;
-		}
-	} while (i--);
+    uint32_t     result = 0;
+    unsigned int count, i;
+    
+    count = sRequestCallbackRecords->getCount();
+    if (!count) {
+        goto finish;
+    }
+
+    i = count - 1;
+    do {
+        OSDictionary * request = OSDynamicCast(OSDictionary,
+            sRequestCallbackRecords->getObject(i));
+
+        if (!request) {
+            continue;
+        }
+        OSData * callbackWrapper = OSDynamicCast(OSData,
+            _OSKextGetRequestArgument(request,
+                kKextRequestArgumentCallbackKey));
+            
+        if (!callbackWrapper) {
+            continue;
+        }
+
+        vm_address_t callbackAddress = (vm_address_t)
+            _OSKextExtractPointer(callbackWrapper);
+
+        if ((kmod_info->address <= callbackAddress) &&
+            (callbackAddress < (kmod_info->address + kmod_info->size))) {
+
+            result++;
+        }
+    } while (i--);
 
 finish:
-	return result;
-}
-
-/*********************************************************************
-*********************************************************************/
-static OSReturn
-_OSKextCreateRequest(
-	const char    * predicate,
-	OSSharedPtr<OSDictionary> & requestR)
-{
-	OSReturn result = kOSKextReturnNoMemory;
-	OSSharedPtr<OSDictionary> request;
-
-	request = OSDictionary::withCapacity(2);
-	if (!request) {
-		goto finish;
-	}
-	result = _OSDictionarySetCStringValue(request.get(),
-	    kKextRequestPredicateKey, predicate);
-	if (result != kOSReturnSuccess) {
-		goto finish;
-	}
-	result = kOSReturnSuccess;
+    return result;
+}
+
+/*********************************************************************
+*********************************************************************/
+static OSReturn _OSKextCreateRequest(
+    const char    * predicate,
+    OSDictionary ** requestP)
+{
+    OSReturn result = kOSKextReturnNoMemory;
+    OSDictionary * request = NULL;  // must release on error
+    
+    request = OSDictionary::withCapacity(2);
+    if (!request) {
+        goto finish;
+    }
+    result = _OSDictionarySetCStringValue(request,
+        kKextRequestPredicateKey, predicate);
+    if (result != kOSReturnSuccess) {
+        goto finish;
+    }
+    result = kOSReturnSuccess;
 
 finish:
-	if (result == kOSReturnSuccess) {
-		requestR = os::move(request);
-	}
-
-	return result;
-}
-
-/*********************************************************************
-*********************************************************************/
-static OSString *
-_OSKextGetRequestPredicate(OSDictionary * requestDict)
-{
-	return OSDynamicCast(OSString,
-	           requestDict->getObject(kKextRequestPredicateKey));
-}
-
-/*********************************************************************
-*********************************************************************/
-static OSObject *
-_OSKextGetRequestArgument(
-	OSDictionary * requestDict,
-	const char   * argName)
-{
-	OSDictionary * args = OSDynamicCast(OSDictionary,
-	    requestDict->getObject(kKextRequestArgumentsKey));
-	if (args) {
-		return args->getObject(argName);
-	}
-	return NULL;
-}
-
-/*********************************************************************
-*********************************************************************/
-static bool
-_OSKextSetRequestArgument(
-	OSDictionary    * requestDict,
-	const char      * argName,
-	OSMetaClassBase * value)
-{
-	OSDictionary * args = OSDynamicCast(OSDictionary,
-	    requestDict->getObject(kKextRequestArgumentsKey));
-	OSSharedPtr<OSDictionary> newArgs;
-	if (!args) {
-		newArgs = OSDictionary::withCapacity(2);
-		args = newArgs.get();
-		if (!args) {
-			goto finish;
-		}
-		requestDict->setObject(kKextRequestArgumentsKey, args);
-	}
-	if (args) {
-		return args->setObject(argName, value);
-	}
+    if (result != kOSReturnSuccess) {
+        if (request) request->release();
+    } else {
+        *requestP = request;
+    }
+
+    return result;
+}
+    
+/*********************************************************************
+*********************************************************************/
+static OSString * _OSKextGetRequestPredicate(OSDictionary * requestDict)
+{
+    return OSDynamicCast(OSString,
+        requestDict->getObject(kKextRequestPredicateKey));
+}
+
+/*********************************************************************
+*********************************************************************/
+static OSObject * _OSKextGetRequestArgument(
+    OSDictionary * requestDict,
+    const char   * argName)
+{
+    OSDictionary * args = OSDynamicCast(OSDictionary,
+        requestDict->getObject(kKextRequestArgumentsKey));
+    if (args) {
+        return args->getObject(argName);
+    }
+    return NULL;
+}
+
+/*********************************************************************
+*********************************************************************/
+static bool _OSKextSetRequestArgument(
+    OSDictionary * requestDict,
+    const char   * argName,
+    OSObject     * value)
+{
+    OSDictionary * args = OSDynamicCast(OSDictionary,
+        requestDict->getObject(kKextRequestArgumentsKey));
+    if (!args) {
+        args = OSDictionary::withCapacity(2);
+        if (!args) {
+            goto finish;
+        }
+        requestDict->setObject(kKextRequestArgumentsKey, args);
+        args->release();
+    }
+    if (args) {
+        return args->setObject(argName, value);
+    }
 finish:
-	return false;
-}
-
-/*********************************************************************
-*********************************************************************/
-template <typename T>
-static T *
-_OSKextExtractPointer(OSValueObject<T *> * wrapper)
-{
-	if (!wrapper) {
-		return nullptr;
-	}
-	return wrapper->getRef();
-}
-
-/*********************************************************************
-*********************************************************************/
-static OSKextRequestResourceCallback
-_OSKextExtractCallbackPointer(OSValueObject<OSKextRequestResourceCallback> * wrapper)
-{
-	if (!wrapper) {
-		return nullptr;
-	}
-	return wrapper->getRef();
-}
-
-
-/*********************************************************************
-*********************************************************************/
-static OSReturn
-_OSDictionarySetCStringValue(
-	OSDictionary * dict,
-	const char   * cKey,
-	const char   * cValue)
-{
-	OSReturn result = kOSKextReturnNoMemory;
-	OSSharedPtr<const OSSymbol> key;
-	OSSharedPtr<OSString> value;
-
-	key = OSSymbol::withCString(cKey);
-	value = OSString::withCString(cValue);
-	if (!key || !value) {
-		goto finish;
-	}
-	if (dict->setObject(key.get(), value.get())) {
-		result = kOSReturnSuccess;
-	}
-
+    return false;
+}
+
+/*********************************************************************
+*********************************************************************/
+static void * _OSKextExtractPointer(OSData * wrapper)
+{
+    void       * result = NULL;
+    const void * resultPtr = NULL;
+    
+    if (!wrapper) {
+        goto finish;
+    }
+    resultPtr = wrapper->getBytesNoCopy();
+    result = *(void **)resultPtr;
 finish:
-	return result;
-}
-
-/*********************************************************************
-*********************************************************************/
-static bool
-_OSArrayContainsCString(
-	OSArray    * array,
-	const char * cString)
-{
-	bool             result = false;
-	OSSharedPtr<const OSSymbol> symbol;
-	uint32_t         count, i;
-
-	if (!array || !cString) {
-		goto finish;
-	}
-
-	symbol = OSSymbol::withCStringNoCopy(cString);
-	if (!symbol) {
-		goto finish;
-	}
-
-	count = array->getCount();
-	for (i = 0; i < count; i++) {
-		OSObject * thisObject = array->getObject(i);
-		if (symbol->isEqualTo(thisObject)) {
-			result = true;
-			goto finish;
-		}
-	}
+    return result;
+}
+
+/*********************************************************************
+*********************************************************************/
+static OSReturn _OSDictionarySetCStringValue(
+    OSDictionary * dict,
+    const char   * cKey,
+    const char   * cValue)
+{
+    OSReturn result = kOSKextReturnNoMemory;
+    const OSSymbol * key = NULL;  // must release
+    OSString * value = NULL;  // must release
+    
+    key = OSSymbol::withCString(cKey);
+    value = OSString::withCString(cValue);
+    if (!key || !value) {
+        goto finish;
+    }
+    if (dict->setObject(key, value)) {
+        result = kOSReturnSuccess;
+    }
 
 finish:
-	return result;
-}
-
-#if CONFIG_KXLD
-/*********************************************************************
-* We really only care about boot / system start up related kexts.
-* We return true if we're less than REBUILD_MAX_TIME since start up,
-* otherwise return false.
-*********************************************************************/
-bool
-_OSKextInPrelinkRebuildWindow(void)
-{
-	static bool     outside_the_window = false;
-	AbsoluteTime    my_abstime;
-	UInt64          my_ns;
-	SInt32          my_secs;
-
-	if (outside_the_window) {
-		return false;
-	}
-	clock_get_uptime(&my_abstime);
-	absolutetime_to_nanoseconds(my_abstime, &my_ns);
-	my_secs = (SInt32)(my_ns / NSEC_PER_SEC);
-	if (my_secs > REBUILD_MAX_TIME) {
-		outside_the_window = true;
-		return false;
-	}
-	return true;
-}
-#endif /* CONFIG_KXLD */
-
-/*********************************************************************
-*********************************************************************/
-bool
-_OSKextInUnloadedPrelinkedKexts( const OSSymbol * theBundleID )
-{
-	int unLoadedCount, i;
-	bool result = false;
-
-	IORecursiveLockLock(sKextLock);
-
-	if (sUnloadedPrelinkedKexts == NULL) {
-		goto finish;
-	}
-	unLoadedCount = sUnloadedPrelinkedKexts->getCount();
-	if (unLoadedCount == 0) {
-		goto finish;
-	}
-
-	for (i = 0; i < unLoadedCount; i++) {
-		const OSSymbol *    myBundleID;        // do not release
-
-		myBundleID = OSDynamicCast(OSSymbol, sUnloadedPrelinkedKexts->getObject(i));
-		if (!myBundleID) {
-			continue;
-		}
-		if (theBundleID->isEqualTo(myBundleID->getCStringNoCopy())) {
-			result = true;
-			break;
-		}
-	}
+    if (key)   key->release();
+    if (value) value->release();
+
+    return result;
+}
+
+/*********************************************************************
+*********************************************************************/
+static bool _OSArrayContainsCString(
+    OSArray    * array,
+    const char * cString)
+{
+    bool             result = false;
+    const OSSymbol * symbol = NULL;
+    uint32_t         count, i;
+    
+    if (!array || !cString) {
+        goto finish;
+    }
+
+    symbol = OSSymbol::withCStringNoCopy(cString);
+    if (!symbol) {
+        goto finish;
+    }
+
+    count = array->getCount();
+    for (i = 0; i < count; i++) {
+        OSObject * thisObject = array->getObject(i);
+        if (symbol->isEqualTo(thisObject)) {
+            result = true;
+            goto finish;
+        }
+    }
+
 finish:
-	IORecursiveLockUnlock(sKextLock);
-	return result;
+    if (symbol) symbol->release();
+    return result;
+}
+
+/*********************************************************************
+ * We really only care about boot / system start up related kexts. 
+ * We return true if we're less than REBUILD_MAX_TIME since start up,
+ * otherwise return false.
+ *********************************************************************/
+bool _OSKextInPrelinkRebuildWindow(void)
+{
+    static bool     outside_the_window = false;
+    AbsoluteTime    my_abstime;
+    UInt64          my_ns;
+    SInt32          my_secs;
+    
+    if (outside_the_window) {
+        return(false);
+    }
+    clock_get_uptime(&my_abstime);
+    absolutetime_to_nanoseconds(my_abstime, &my_ns);
+    my_secs = (SInt32)(my_ns / NSEC_PER_SEC);
+    if (my_secs > REBUILD_MAX_TIME) {
+        outside_the_window = true;
+        return(false);
+    }
+    return(true);
+}
+
+/*********************************************************************
+ *********************************************************************/
+bool _OSKextInUnloadedPrelinkedKexts( const OSSymbol * theBundleID )
+{
+    int unLoadedCount, i;
+    bool result = false;
+    
+    IORecursiveLockLock(sKextLock);
+    
+    if (sUnloadedPrelinkedKexts == NULL) {
+        goto finish;
+    }
+    unLoadedCount = sUnloadedPrelinkedKexts->getCount();
+    if (unLoadedCount == 0) {
+        goto finish;
+    }
+    
+    for (i = 0; i < unLoadedCount; i++) {
+        const OSSymbol *    myBundleID;     // do not release
+        
+        myBundleID = OSDynamicCast(OSSymbol, sUnloadedPrelinkedKexts->getObject(i));
+        if (!myBundleID) continue;
+        if (theBundleID->isEqualTo(myBundleID->getCStringNoCopy())) {
+            result = true;
+            break;
+        }
+    }
+finish:
+    IORecursiveLockUnlock(sKextLock);
+    return(result);
 }
 
 #if PRAGMA_MARK
@@ -14869,61 +9484,69 @@
 /*********************************************************************
 *********************************************************************/
 /* static */
-OSSharedPtr<OSArray>
+OSArray *
 OSKext::copyAllKextPersonalities(bool filterSafeBootFlag)
 {
-	OSSharedPtr<OSArray>              result;
-	OSSharedPtr<OSCollectionIterator> kextIterator;
-	OSSharedPtr<OSArray>              personalities;
-
-	OSString             * kextID                = NULL;        // do not release
-	OSKext               * theKext               = NULL;        // do not release
-
-	IORecursiveLockLock(sKextLock);
-
-	/* Let's conservatively guess that any given kext has around 3
-	 * personalities for now.
-	 */
-	result = OSArray::withCapacity(sKextsByID->getCount() * 3);
-	if (!result) {
-		goto finish;
-	}
-
-	kextIterator = OSCollectionIterator::withCollection(sKextsByID.get());
-	if (!kextIterator) {
-		goto finish;
-	}
-
-	while ((kextID = OSDynamicCast(OSString, kextIterator->getNextObject()))) {
-		theKext = OSDynamicCast(OSKext, sKextsByID->getObject(kextID));
-		if (theKext->flags.requireExplicitLoad) {
-			OSKextLog(theKext,
-			    kOSKextLogDebugLevel |
-			    kOSKextLogLoadFlag,
-			    "Kext %s requires an explicit kextload; "
-			    "omitting its personalities.",
-			    theKext->getIdentifierCString());
-		} else if (!sSafeBoot || !filterSafeBootFlag || theKext->isLoadableInSafeBoot()) {
-			personalities = theKext->copyPersonalitiesArray();
-			if (!personalities) {
-				continue;
-			}
-			result->merge(personalities.get());
-		} else {
-			// xxx - check for better place to put this log msg
-			OSKextLog(theKext,
-			    kOSKextLogWarningLevel |
-			    kOSKextLogLoadFlag,
-			    "Kext %s is not loadable during safe boot; "
-			    "omitting its personalities.",
-			    theKext->getIdentifierCString());
-		}
-	}
+    OSArray              * result                = NULL;  // returned
+    OSCollectionIterator * kextIterator          = NULL;  // must release
+    OSArray              * personalities         = NULL;  // must release
+    OSCollectionIterator * personalitiesIterator = NULL;  // must release
+
+    OSString             * kextID                = NULL;  // do not release
+    OSKext               * theKext               = NULL;  // do not release
+    
+    IORecursiveLockLock(sKextLock);
+
+   /* Let's conservatively guess that any given kext has around 3
+    * personalities for now.
+    */
+    result = OSArray::withCapacity(sKextsByID->getCount() * 3);
+    if (!result) {
+        goto finish;
+    }
+    
+    kextIterator = OSCollectionIterator::withCollection(sKextsByID);
+    if (!kextIterator) {
+        goto finish;
+    }
+    
+    while ((kextID = OSDynamicCast(OSString, kextIterator->getNextObject()))) {
+        if (personalitiesIterator) {
+            personalitiesIterator->release();
+            personalitiesIterator = NULL;
+        }
+        if (personalities) {
+            personalities->release();
+            personalities = NULL;
+        }
+        
+        theKext = OSDynamicCast(OSKext, sKextsByID->getObject(kextID));
+        if (!sSafeBoot || !filterSafeBootFlag || theKext->isLoadableInSafeBoot()) {
+            personalities = theKext->copyPersonalitiesArray();
+            if (!personalities) {
+                continue;
+            }
+            result->merge(personalities);
+        } else {
+            // xxx - check for better place to put this log msg
+            OSKextLog(theKext,
+                kOSKextLogWarningLevel |
+                kOSKextLogLoadFlag,
+                "Kext %s is not loadable during safe boot; "
+                "omitting its personalities.",
+                theKext->getIdentifierCString());
+        }
+
+    }
 
 finish:
-	IORecursiveLockUnlock(sKextLock);
-
-	return result;
+    IORecursiveLockUnlock(sKextLock);
+
+    if (kextIterator)          kextIterator->release();
+    if (personalitiesIterator) personalitiesIterator->release();
+    if (personalities)         personalities->release();
+
+    return result;
 }
 
 /*********************************************************************
@@ -14932,167 +9555,172 @@
 void
 OSKext::sendAllKextPersonalitiesToCatalog(bool startMatching)
 {
-	int numPersonalities = 0;
-
-	OSKextLog(/* kext */ NULL,
-	    kOSKextLogStepLevel |
-	    kOSKextLogLoadFlag,
-	    "Sending all eligible registered kexts' personalities "
-	    "to the IOCatalogue %s.",
-	    startMatching ? "and starting matching" : "but not starting matching");
-
-	OSSharedPtr<OSArray> personalities = OSKext::copyAllKextPersonalities(
-		/* filterSafeBootFlag */ true);
-
-	if (personalities) {
-		gIOCatalogue->addDrivers(personalities.get(), startMatching);
-		numPersonalities = personalities->getCount();
-	}
-
-	OSKextLog(/* kext */ NULL,
-	    kOSKextLogStepLevel |
-	    kOSKextLogLoadFlag,
-	    "%d kext personalit%s sent to the IOCatalogue; %s.",
-	    numPersonalities, numPersonalities > 0 ? "ies" : "y",
-	    startMatching ? "matching started" : "matching not started");
-	return;
+    int numPersonalities = 0;
+
+    OSKextLog(/* kext */ NULL,
+        kOSKextLogStepLevel |
+        kOSKextLogLoadFlag,
+        "Sending all eligible registered kexts' personalities "
+        "to the IOCatalogue %s.",
+        startMatching ? "and starting matching" : "but not starting matching");
+
+    OSArray * personalities = OSKext::copyAllKextPersonalities(
+        /* filterSafeBootFlag */ true);
+
+    if (personalities) {
+        gIOCatalogue->addDrivers(personalities, startMatching);
+        numPersonalities = personalities->getCount();
+        personalities->release();
+    }
+
+    OSKextLog(/* kext */ NULL,
+        kOSKextLogStepLevel |
+        kOSKextLogLoadFlag,
+        "%d kext personalit%s sent to the IOCatalogue; %s.",
+        numPersonalities, numPersonalities > 0 ? "ies" : "y",
+        startMatching ? "matching started" : "matching not started");
+    return;
 }
 
 /*********************************************************************
 * Do not make a deep copy, just convert the IOKitPersonalities dict
 * to an array for sending to the IOCatalogue.
 *********************************************************************/
-OSSharedPtr<OSArray>
+OSArray *
 OSKext::copyPersonalitiesArray(void)
 {
-	OSSharedPtr<OSArray>              result;
-	OSDictionary         * personalities               = NULL;        // do not release
-	OSSharedPtr<OSCollectionIterator> personalitiesIterator;
-
-	OSString             * personalityName             = NULL;        // do not release
-	OSString             * personalityBundleIdentifier = NULL;        // do not release
-
-	personalities = OSDynamicCast(OSDictionary,
-	    getPropertyForHostArch(kIOKitPersonalitiesKey));
-	if (!personalities) {
-		goto finish;
-	}
-
-	result = OSArray::withCapacity(personalities->getCount());
-	if (!result) {
-		goto finish;
-	}
-
-	personalitiesIterator =
-	    OSCollectionIterator::withCollection(personalities);
-	if (!personalitiesIterator) {
-		goto finish;
-	}
-	while ((personalityName = OSDynamicCast(OSString,
-	    personalitiesIterator->getNextObject()))) {
-		OSDictionary * personality = OSDynamicCast(OSDictionary,
-		    personalities->getObject(personalityName));
-
-		if (personality) {
-			/******
-			 * If the personality doesn't have a CFBundleIdentifier, or if it
-			 * differs from the kext's, insert the kext's ID so we can find it.
-			 * The publisher ID is used to remove personalities from bundles
-			 * correctly.
-			 */
-			personalityBundleIdentifier = OSDynamicCast(OSString,
-			    personality->getObject(kCFBundleIdentifierKey));
-
-			if (!personalityBundleIdentifier) {
-				personality->setObject(kCFBundleIdentifierKey, bundleID.get());
-			} else if (!personalityBundleIdentifier->isEqualTo(bundleID.get())) {
-				personality->setObject(kIOPersonalityPublisherKey, bundleID.get());
-			}
-		}
-
-		result->setObject(personality);
-	}
+    OSArray              * result                      = NULL;
+    OSDictionary         * personalities               = NULL;  // do not release
+    OSCollectionIterator * personalitiesIterator       = NULL;  // must release
+
+    OSString             * personalityName             = NULL;  // do not release    
+    OSString             * personalityBundleIdentifier = NULL;  // do not release
+
+    personalities = OSDynamicCast(OSDictionary,
+        getPropertyForHostArch(kIOKitPersonalitiesKey));
+    if (!personalities) {
+        goto finish;
+    }
+
+    result = OSArray::withCapacity(personalities->getCount());
+    if (!result) {
+        goto finish;
+    }
+
+    personalitiesIterator =
+        OSCollectionIterator::withCollection(personalities);
+    if (!personalitiesIterator) {
+        goto finish;
+    }
+    while ((personalityName = OSDynamicCast(OSString,
+            personalitiesIterator->getNextObject()))) {
+                
+        OSDictionary * personality = OSDynamicCast(OSDictionary,
+            personalities->getObject(personalityName));
+
+       /******
+        * If the personality doesn't have a CFBundleIdentifier, or if it
+        * differs from the kext's, insert the kext's ID so we can find it.
+        * The publisher ID is used to remove personalities from bundles
+        * correctly.
+        */
+        personalityBundleIdentifier = OSDynamicCast(OSString,
+            personality->getObject(kCFBundleIdentifierKey));
+
+        if (!personalityBundleIdentifier) {
+            personality->setObject(kCFBundleIdentifierKey, bundleID);
+        } else if (!personalityBundleIdentifier->isEqualTo(bundleID)) {
+            personality->setObject(kIOPersonalityPublisherKey, bundleID);
+        }
+
+        result->setObject(personality);
+    }
 
 finish:
-	return result;
-}
-
-/*********************************************************************
-*   Might want to change this to a bool return?
+    if (personalitiesIterator) personalitiesIterator->release();
+
+    return result;
+}
+
+/*********************************************************************
+Might want to change this to a bool return?
 *********************************************************************/
 OSReturn
 OSKext::sendPersonalitiesToCatalog(
-	bool      startMatching,
-	OSArray * personalityNames)
-{
-	OSReturn       result              = kOSReturnSuccess;
-	OSSharedPtr<OSArray> personalitiesToSend;
-	OSDictionary * kextPersonalities   = NULL;        // do not release
-	int            count, i;
-
-	if (!sLoadEnabled) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag,
-		    "Kext loading is disabled (attempt to start matching for kext %s).",
-		    getIdentifierCString());
-		result = kOSKextReturnDisabled;
-		goto finish;
-	}
-
-	if (sSafeBoot && !isLoadableInSafeBoot()) {
-		OSKextLog(this,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogLoadFlag,
-		    "Kext %s is not loadable during safe boot; "
-		    "not sending personalities to the IOCatalogue.",
-		    getIdentifierCString());
-		result = kOSKextReturnNotLoadable;
-		goto finish;
-	}
-
-	if (!personalityNames || !personalityNames->getCount()) {
-		personalitiesToSend = copyPersonalitiesArray();
-	} else {
-		kextPersonalities = OSDynamicCast(OSDictionary,
-		    getPropertyForHostArch(kIOKitPersonalitiesKey));
-		if (!kextPersonalities || !kextPersonalities->getCount()) {
-			// not an error
-			goto finish;
-		}
-		personalitiesToSend = OSArray::withCapacity(0);
-		if (!personalitiesToSend) {
-			result = kOSKextReturnNoMemory;
-			goto finish;
-		}
-		count = personalityNames->getCount();
-		for (i = 0; i < count; i++) {
-			OSString * name = OSDynamicCast(OSString,
-			    personalityNames->getObject(i));
-			if (!name) {
-				continue;
-			}
-			OSDictionary * personality = OSDynamicCast(OSDictionary,
-			    kextPersonalities->getObject(name));
-			if (personality) {
-				personalitiesToSend->setObject(personality);
-			}
-		}
-	}
-	if (personalitiesToSend) {
-		unsigned numPersonalities = personalitiesToSend->getCount();
-		OSKextLog(this,
-		    kOSKextLogStepLevel |
-		    kOSKextLogLoadFlag,
-		    "Kext %s sending %d personalit%s to the IOCatalogue%s.",
-		    getIdentifierCString(),
-		    numPersonalities,
-		    numPersonalities > 1 ? "ies" : "y",
-		    startMatching ? " and starting matching" : " but not starting matching");
-		gIOCatalogue->addDrivers(personalitiesToSend.get(), startMatching);
-	}
+    bool      startMatching,
+    OSArray * personalityNames)
+{
+    OSReturn       result              = kOSReturnSuccess;
+    OSArray      * personalitiesToSend = NULL;  // must release
+    OSDictionary * kextPersonalities   = NULL;  // do not release
+    int            count, i;
+
+    if (!sLoadEnabled) {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogLoadFlag,
+            "Kext loading is disabled (attempt to start matching for kext %s).",
+            getIdentifierCString());
+        result = kOSKextReturnDisabled;
+        goto finish;
+    }
+
+    if (sSafeBoot && !isLoadableInSafeBoot()) {
+        OSKextLog(this,
+            kOSKextLogErrorLevel |
+            kOSKextLogLoadFlag,
+            "Kext %s is not loadable during safe boot; "
+            "not sending personalities to the IOCatalogue.",
+            getIdentifierCString());
+        result = kOSKextReturnNotLoadable;
+        goto finish;
+    }
+
+    if (!personalityNames || !personalityNames->getCount()) {
+        personalitiesToSend = copyPersonalitiesArray();
+    } else {
+        kextPersonalities = OSDynamicCast(OSDictionary,
+            getPropertyForHostArch(kIOKitPersonalitiesKey));
+        if (!kextPersonalities || !kextPersonalities->getCount()) {
+            // not an error
+            goto finish;
+        }
+        personalitiesToSend = OSArray::withCapacity(0);
+        if (!personalitiesToSend) {
+            result = kOSKextReturnNoMemory;
+            goto finish;
+        }
+        count = personalityNames->getCount();
+        for (i = 0; i < count; i++) {
+            OSString * name = OSDynamicCast(OSString,
+                personalityNames->getObject(i));
+            if (!name) {
+                continue;
+            }
+            OSDictionary * personality = OSDynamicCast(OSDictionary,
+                kextPersonalities->getObject(name));
+            if (personality) {
+                personalitiesToSend->setObject(personality);
+            }
+        }
+    }
+    if (personalitiesToSend) {
+        unsigned numPersonalities = personalitiesToSend->getCount();
+        OSKextLog(this,
+            kOSKextLogStepLevel |
+            kOSKextLogLoadFlag,
+            "Kext %s sending %d personalit%s to the IOCatalogue%s.",
+            getIdentifierCString(),
+            numPersonalities,
+            numPersonalities > 1 ? "ies" : "y",
+            startMatching ? " and starting matching" : " but not starting matching");
+        gIOCatalogue->addDrivers(personalitiesToSend, startMatching);
+    }
 finish:
-	return result;
+    if (personalitiesToSend) {
+        personalitiesToSend->release();
+    }
+    return result;
 }
 
 /*********************************************************************
@@ -15102,49 +9730,31 @@
 void
 OSKext::removePersonalitiesFromCatalog(void)
 {
-	OSSharedPtr<OSDictionary> personality;
-
-	personality = OSDictionary::withCapacity(1);
-	if (!personality) {
-		goto finish;
-	}
-	personality->setObject(kCFBundleIdentifierKey, getIdentifier());
-
-	OSKextLog(this,
-	    kOSKextLogStepLevel |
-	    kOSKextLogLoadFlag,
-	    "Kext %s removing all personalities naming it from the IOCatalogue.",
-	    getIdentifierCString());
-
-	/* Have the IOCatalog remove all personalities matching this kext's
-	 * bundle ID and trigger matching anew.
-	 */
-	gIOCatalogue->removeDrivers(personality.get(), /* startMatching */ true);
-
-finish:
-	return;
-}
-
-void
-OSKext::updatePersonalitiesInCatalog(OSArray *upgradedPersonalities)
-{
-	if (!upgradedPersonalities || upgradedPersonalities->getCount() == 0) {
-		return;
-	}
-
-	OSSharedPtr<OSDictionary> personalityToRemove = OSDictionary::withCapacity(1);
-	if (!personalityToRemove) {
-		return;
-	}
-
-	/*
-	 * Create a personality dictionary with just the bundleID.
-	 * We will remove any personality that has a matching bundleID,
-	 * irrespective of which other keys are present on the dictionary.
-	 */
-	personalityToRemove->setObject(kCFBundleIdentifierKey, getIdentifier());
-	gIOCatalogue->exchangeDrivers(personalityToRemove.get(), upgradedPersonalities, true);
-}
+    OSDictionary * personality = NULL;   // do not release
+
+    personality = OSDictionary::withCapacity(1);
+    if (!personality) {
+        goto finish;
+    }
+    personality->setObject(kCFBundleIdentifierKey, getIdentifier());
+
+    OSKextLog(this,
+        kOSKextLogStepLevel |
+        kOSKextLogLoadFlag,
+        "Kext %s removing all personalities naming it from the IOCatalogue.",
+        getIdentifierCString());
+
+   /* Have the IOCatalog remove all personalities matching this kext's
+    * bundle ID and trigger matching anew.
+    */
+    gIOCatalogue->removeDrivers(personality, /* startMatching */ true);
+
+ finish:
+    if (personality) personality->release();
+
+    return;
+}
+
 
 #if PRAGMA_MARK
 #pragma mark Logging
@@ -15155,96 +9765,99 @@
 /* static */
 OSKextLogSpec
 OSKext::setUserSpaceLogFilter(
-	OSKextLogSpec   newUserLogFilter,
-	bool            captureFlag)
-{
-	OSKextLogSpec result;
-	bool          allocError = false;
-
-	/* Do not call any function that takes sKextLoggingLock during
-	 * this critical block. That means do logging after.
-	 */
-	IOLockLock(sKextLoggingLock);
-
-	result = sUserSpaceKextLogFilter;
-	sUserSpaceKextLogFilter = newUserLogFilter;
-
-	if (newUserLogFilter && captureFlag &&
-	    !sUserSpaceLogSpecArray && !sUserSpaceLogMessageArray) {
-		// xxx - do some measurements for a good initial capacity?
-		sUserSpaceLogSpecArray = OSArray::withCapacity(0);
-		sUserSpaceLogMessageArray = OSArray::withCapacity(0);
-
-		if (!sUserSpaceLogSpecArray || !sUserSpaceLogMessageArray) {
-			allocError = true;
-		}
-	}
-
-	IOLockUnlock(sKextLoggingLock);
-
-	/* If the config flag itself is changing, log the state change
-	 * going both ways, before setting up the user-space log arrays,
-	 * so that this is only logged in the kernel.
-	 */
-	if (result != newUserLogFilter) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogDebugLevel |
-		    kOSKextLogGeneralFlag,
-		    "User-space log flags changed from 0x%x to 0x%x.",
-		    result, newUserLogFilter);
-	}
-	if (allocError) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel |
-		    kOSKextLogGeneralFlag,
-		    "Failed to allocate user-space log message arrays.");
-	}
-
-	return result;
+    OSKextLogSpec   newUserLogFilter,
+    bool            captureFlag)
+{
+    OSKextLogSpec result;
+    bool          allocError = false;
+
+   /* Do not call any function that takes sKextLoggingLock during
+    * this critical block. That means do logging after.
+    */
+    IOLockLock(sKextLoggingLock);
+
+    result = sUserSpaceKextLogFilter;
+    sUserSpaceKextLogFilter = newUserLogFilter;
+
+    if (newUserLogFilter && captureFlag &&
+        !sUserSpaceLogSpecArray && !sUserSpaceLogMessageArray) {
+
+        // xxx - do some measurements for a good initial capacity?
+        sUserSpaceLogSpecArray = OSArray::withCapacity(0);
+        sUserSpaceLogMessageArray = OSArray::withCapacity(0);
+        
+        if (!sUserSpaceLogSpecArray || !sUserSpaceLogMessageArray) {
+            OSSafeReleaseNULL(sUserSpaceLogSpecArray);
+            OSSafeReleaseNULL(sUserSpaceLogMessageArray);
+            allocError = true;
+        }
+    }
+
+    IOLockUnlock(sKextLoggingLock);
+
+   /* If the config flag itself is changing, log the state change
+    * going both ways, before setting up the user-space log arrays,
+    * so that this is only logged in the kernel.
+    */
+    if (result != newUserLogFilter) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogDebugLevel |
+            kOSKextLogGeneralFlag,
+            "User-space log flags changed from 0x%x to 0x%x.",
+            result, newUserLogFilter);
+    }
+    if (allocError) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogErrorLevel |
+            kOSKextLogGeneralFlag,
+            "Failed to allocate user-space log message arrays.");
+    }
+
+    return result;
 }
 
 /*********************************************************************
 * Do not call any function that takes sKextLock here!
 *********************************************************************/
 /* static */
-OSSharedPtr<OSArray>
+OSArray *
 OSKext::clearUserSpaceLogFilter(void)
 {
-	OSSharedPtr<OSArray>       result;
-	OSKextLogSpec   oldLogFilter;
-	OSKextLogSpec   newLogFilter = kOSKextLogSilentFilter;
-
-	/* Do not call any function that takes sKextLoggingLock during
-	 * this critical block. That means do logging after.
-	 */
-	IOLockLock(sKextLoggingLock);
-
-	result = OSArray::withCapacity(2);
-	if (result) {
-		result->setObject(sUserSpaceLogSpecArray.get());
-		result->setObject(sUserSpaceLogMessageArray.get());
-	}
-	sUserSpaceLogSpecArray.reset();
-	sUserSpaceLogMessageArray.reset();
-
-	oldLogFilter = sUserSpaceKextLogFilter;
-	sUserSpaceKextLogFilter = newLogFilter;
-
-	IOLockUnlock(sKextLoggingLock);
-
-	/* If the config flag itself is changing, log the state change
-	 * going both ways, after tearing down the user-space log
-	 * arrays, so this is only logged within the kernel.
-	 */
-	if (oldLogFilter != newLogFilter) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogDebugLevel |
-		    kOSKextLogGeneralFlag,
-		    "User-space log flags changed from 0x%x to 0x%x.",
-		    oldLogFilter, newLogFilter);
-	}
-
-	return result;
+    OSArray       * result       = NULL;
+    OSKextLogSpec   oldLogFilter;
+    OSKextLogSpec   newLogFilter = kOSKextLogSilentFilter;
+
+   /* Do not call any function that takes sKextLoggingLock during
+    * this critical block. That means do logging after.
+    */
+    IOLockLock(sKextLoggingLock);
+
+    result = OSArray::withCapacity(2);
+    if (result) {
+        result->setObject(sUserSpaceLogSpecArray);
+        result->setObject(sUserSpaceLogMessageArray);
+    }
+    OSSafeReleaseNULL(sUserSpaceLogSpecArray);
+    OSSafeReleaseNULL(sUserSpaceLogMessageArray);
+
+    oldLogFilter = sUserSpaceKextLogFilter;
+    sUserSpaceKextLogFilter = newLogFilter;
+
+    IOLockUnlock(sKextLoggingLock);
+
+   /* If the config flag itself is changing, log the state change
+    * going both ways, after tearing down the user-space log
+    * arrays, so this is only logged within the kernel.
+    */
+    if (oldLogFilter != newLogFilter) {
+        OSKextLog(/* kext */ NULL,
+            kOSKextLogDebugLevel |
+            kOSKextLogGeneralFlag,
+            "User-space log flags changed from 0x%x to 0x%x.",
+            oldLogFilter, newLogFilter);
+    }
+
+    return result;
 }
 
 
@@ -15255,13 +9868,13 @@
 OSKextLogSpec
 OSKext::getUserSpaceLogFilter(void)
 {
-	OSKextLogSpec result;
-
-	IOLockLock(sKextLoggingLock);
-	result = sUserSpaceKextLogFilter;
-	IOLockUnlock(sKextLoggingLock);
-
-	return result;
+    OSKextLogSpec result;
+
+    IOLockLock(sKextLoggingLock);
+    result = sUserSpaceKextLogFilter;
+    IOLockUnlock(sKextLoggingLock);
+
+    return result;
 }
 
 /*********************************************************************
@@ -15283,366 +9896,384 @@
 #define VTMAGENTA "\033[35m"
 #define VTCYAN    "\033[36m"
 
-inline const char *
-colorForFlags(OSKextLogSpec flags)
-{
-	OSKextLogSpec logLevel = flags & kOSKextLogLevelMask;
-
-	switch (logLevel) {
-	case kOSKextLogErrorLevel:
-		return VTRED VTBOLD;
-	case kOSKextLogWarningLevel:
-		return VTRED;
-	case kOSKextLogBasicLevel:
-		return VTYELLOW VTUNDER;
-	case kOSKextLogProgressLevel:
-		return VTYELLOW;
-	case kOSKextLogStepLevel:
-		return VTGREEN;
-	case kOSKextLogDetailLevel:
-		return VTCYAN;
-	case kOSKextLogDebugLevel:
-		return VTMAGENTA;
-	default:
-		return "";         // white
-	}
-}
-
-inline bool
-logSpecMatch(
-	OSKextLogSpec msgLogSpec,
-	OSKextLogSpec logFilter)
-{
-	OSKextLogSpec filterKextGlobal  = logFilter & kOSKextLogKextOrGlobalMask;
-	OSKextLogSpec filterLevel       = logFilter & kOSKextLogLevelMask;
-	OSKextLogSpec filterFlags       = logFilter & kOSKextLogFlagsMask;
-
-	OSKextLogSpec msgKextGlobal    = msgLogSpec & kOSKextLogKextOrGlobalMask;
-	OSKextLogSpec msgLevel         = msgLogSpec & kOSKextLogLevelMask;
-	OSKextLogSpec msgFlags         = msgLogSpec & kOSKextLogFlagsMask;
-
-	/* Explicit messages always get logged.
-	 */
-	if (msgLevel == kOSKextLogExplicitLevel) {
-		return true;
-	}
-
-	/* Warnings and errors are logged regardless of the flags.
-	 */
-	if (msgLevel <= kOSKextLogBasicLevel && (msgLevel <= filterLevel)) {
-		return true;
-	}
-
-	/* A verbose message that isn't for a logging-enabled kext and isn't global
-	 * does *not* get logged.
-	 */
-	if (!msgKextGlobal && !filterKextGlobal) {
-		return false;
-	}
-
-	/* Warnings and errors are logged regardless of the flags.
-	 * All other messages must fit the flags and
-	 * have a level at or below the filter.
-	 *
-	 */
-	if ((msgFlags & filterFlags) && (msgLevel <= filterLevel)) {
-		return true;
-	}
-	return false;
+inline const char * colorForFlags(OSKextLogSpec flags)
+{
+    OSKextLogSpec logLevel = flags & kOSKextLogLevelMask;
+
+    switch (logLevel) {
+    case kOSKextLogErrorLevel:
+        return VTRED VTBOLD;
+        break;
+    case kOSKextLogWarningLevel:
+        return VTRED;
+        break;
+    case kOSKextLogBasicLevel:
+        return VTYELLOW VTUNDER;
+        break;
+    case kOSKextLogProgressLevel:
+        return VTYELLOW;
+        break;
+    case kOSKextLogStepLevel:
+        return VTGREEN;
+        break;
+    case kOSKextLogDetailLevel:
+        return VTCYAN;
+        break;
+    case kOSKextLogDebugLevel:
+        return VTMAGENTA;
+        break;
+    default:
+        return "";  // white
+        break;
+    }
+    return "";
+}
+
+inline bool logSpecMatch(
+    OSKextLogSpec msgLogSpec,
+    OSKextLogSpec logFilter)
+{
+    OSKextLogSpec filterKextGlobal  = logFilter & kOSKextLogKextOrGlobalMask;
+    OSKextLogSpec filterLevel       = logFilter & kOSKextLogLevelMask;
+    OSKextLogSpec filterFlags       = logFilter & kOSKextLogFlagsMask;
+
+    OSKextLogSpec msgKextGlobal    = msgLogSpec & kOSKextLogKextOrGlobalMask;
+    OSKextLogSpec msgLevel         = msgLogSpec & kOSKextLogLevelMask;
+    OSKextLogSpec msgFlags         = msgLogSpec & kOSKextLogFlagsMask;
+
+   /* Explicit messages always get logged.
+    */
+    if (msgLevel == kOSKextLogExplicitLevel) {
+        return true;
+    }
+
+   /* Warnings and errors are logged regardless of the flags.
+    */
+    if (msgLevel <= kOSKextLogBasicLevel && (msgLevel <= filterLevel)) {
+        return true;
+    }
+
+   /* A verbose message that isn't for a logging-enabled kext and isn't global
+    * does *not* get logged.
+    */
+    if (!msgKextGlobal && !filterKextGlobal) {
+        return false;
+    }
+
+   /* Warnings and errors are logged regardless of the flags.
+    * All other messages must fit the flags and
+    * have a level at or below the filter.
+    *
+    */
+    if ((msgFlags & filterFlags) && (msgLevel <= filterLevel)) {
+        return true;
+    }
+    return false;
 }
 
 extern "C" {
+
 void
 OSKextLog(
-	OSKext         * aKext,
-	OSKextLogSpec    msgLogSpec,
-	const char     * format, ...)
-{
-	va_list argList;
-
-	va_start(argList, format);
-	OSKextVLog(aKext, msgLogSpec, format, argList);
-	va_end(argList);
+    OSKext         * aKext,
+    OSKextLogSpec    msgLogSpec,
+    const char     * format, ...)
+{
+    va_list argList;
+
+    va_start(argList, format);
+    OSKextVLog(aKext, msgLogSpec, format, argList);
+    va_end(argList);
 }
 
 void
 OSKextVLog(
-	OSKext         * aKext,
-	OSKextLogSpec    msgLogSpec,
-	const char     * format,
-	va_list          srcArgList)
-{
-	bool             logForKernel       = false;
-	bool             logForUser         = false;
-	va_list          argList;
-	char             stackBuffer[120];
-	uint32_t         length            = 0;
-	char           * allocBuffer       = NULL;        // must kfree
-	OSSharedPtr<OSNumber> logSpecNum;
-	OSSharedPtr<OSString> logString;
-	char           * buffer            = stackBuffer;        // do not free
-
-	IOLockLock(sKextLoggingLock);
-
-	/* Set the kext/global bit in the message spec if we have no
-	 * kext or if the kext requests logging.
-	 */
-	if (!aKext || aKext->flags.loggingEnabled) {
-		msgLogSpec = msgLogSpec | kOSKextLogKextOrGlobalMask;
-	}
-
-	logForKernel = logSpecMatch(msgLogSpec, sKernelLogFilter);
-	if (sUserSpaceLogSpecArray && sUserSpaceLogMessageArray) {
-		logForUser = logSpecMatch(msgLogSpec, sUserSpaceKextLogFilter);
-	}
-
-	if (!(logForKernel || logForUser)) {
-		goto finish;
-	}
-
-	/* No goto from here until past va_end()!
-	 */
-	va_copy(argList, srcArgList);
-	length = vsnprintf(stackBuffer, sizeof(stackBuffer), format, argList);
-	va_end(argList);
-
-	if (length + 1 >= sizeof(stackBuffer)) {
-		allocBuffer = (char *)kalloc_data_tag(length + 1,
-		    Z_WAITOK, VM_KERN_MEMORY_OSKEXT);
-		if (!allocBuffer) {
-			goto finish;
-		}
-
-		/* No goto from here until past va_end()!
-		 */
-		va_copy(argList, srcArgList);
-		vsnprintf(allocBuffer, length + 1, format, argList);
-		va_end(argList);
-
-		buffer = allocBuffer;
-	}
-
-	/* If user space wants the log message, queue it up.
-	 */
-	if (logForUser && sUserSpaceLogSpecArray && sUserSpaceLogMessageArray) {
-		logSpecNum = OSNumber::withNumber(msgLogSpec, 8 * sizeof(msgLogSpec));
-		logString = OSString::withCString(buffer);
-		if (logSpecNum && logString) {
-			sUserSpaceLogSpecArray->setObject(logSpecNum.get());
-			sUserSpaceLogMessageArray->setObject(logString.get());
-		}
-	}
-
-	/* Always log messages from the kernel according to the kernel's
-	 * log flags.
-	 */
-	if (logForKernel) {
-		/* If we are in console mode and have a custom log filter,
-		 * colorize the log message.
-		 */
-		if (sBootArgLogFilterFound) {
-			const char * color = "";         // do not free
-			color = colorForFlags(msgLogSpec);
-			printf("%s%s%s\n", colorForFlags(msgLogSpec),
-			    buffer, color[0] ? VTRESET : "");
-		} else {
-			printf("%s\n", buffer);
-		}
-	}
+    OSKext         * aKext,
+    OSKextLogSpec    msgLogSpec,
+    const char     * format,
+    va_list          srcArgList)
+{
+    extern int       disableConsoleOutput;
+
+    bool             logForKernel       = false;
+    bool             logForUser         = false;
+    va_list          argList;
+    char             stackBuffer[120];
+    uint32_t         length            = 0;
+    char           * allocBuffer       = NULL;         // must kfree
+    OSNumber       * logSpecNum        = NULL;         // must release
+    OSString       * logString         = NULL;         // must release
+    char           * buffer            = stackBuffer;  // do not free
+
+    IOLockLock(sKextLoggingLock);
+
+   /* Set the kext/global bit in the message spec if we have no
+    * kext or if the kext requests logging.
+    */
+    if (!aKext || aKext->flags.loggingEnabled) {
+        msgLogSpec = msgLogSpec | kOSKextLogKextOrGlobalMask;
+    }
+
+    logForKernel = logSpecMatch(msgLogSpec, sKernelLogFilter);
+    if (sUserSpaceLogSpecArray && sUserSpaceLogMessageArray) {
+        logForUser = logSpecMatch(msgLogSpec, sUserSpaceKextLogFilter);
+    }
+
+    if (! (logForKernel || logForUser) ) {
+        goto finish;
+    }
+    
+   /* No goto from here until past va_end()!
+    */    
+    va_copy(argList, srcArgList);
+    length = vsnprintf(stackBuffer, sizeof(stackBuffer), format, argList);
+    va_end(argList);
+
+    if (length + 1 >= sizeof(stackBuffer)) {
+        allocBuffer = (char *)kalloc_tag((length + 1) * sizeof(char), VM_KERN_MEMORY_OSKEXT);
+        if (!allocBuffer) {
+            goto finish;
+        }
+
+       /* No goto from here until past va_end()!
+        */    
+        va_copy(argList, srcArgList);
+        vsnprintf(allocBuffer, length + 1, format, argList);
+        va_end(argList);
+
+        buffer = allocBuffer;
+    }
+
+   /* If user space wants the log message, queue it up.
+    */
+    if (logForUser && sUserSpaceLogSpecArray && sUserSpaceLogMessageArray) {
+        logSpecNum = OSNumber::withNumber(msgLogSpec, 8 * sizeof(msgLogSpec));
+        logString = OSString::withCString(buffer);
+        if (logSpecNum && logString) {
+            sUserSpaceLogSpecArray->setObject(logSpecNum);
+            sUserSpaceLogMessageArray->setObject(logString);
+        }
+    }
+
+   /* Always log messages from the kernel according to the kernel's
+    * log flags.
+    */
+    if (logForKernel) {
+
+       /* If we are in console mode and have a custom log filter,
+        * colorize the log message.
+        */
+        if (!disableConsoleOutput && sBootArgLogFilterFound) {
+            const char * color = "";  // do not free
+            color = colorForFlags(msgLogSpec);
+            printf("%s%s%s\n", colorForFlags(msgLogSpec),
+                buffer, color[0] ? VTRESET : "");
+        } else {
+            printf("%s\n", buffer);
+        }
+    }
 
 finish:
-	IOLockUnlock(sKextLoggingLock);
-
-	if (allocBuffer) {
-		kfree_data(allocBuffer, length + 1);
-	}
-	return;
+    IOLockUnlock(sKextLoggingLock);
+
+    if (allocBuffer) {
+        kfree(allocBuffer, (length + 1) * sizeof(char));
+    }
+    OSSafeRelease(logString);
+    OSSafeRelease(logSpecNum);
+    return;
 }
 
 #if KASLR_IOREG_DEBUG
-
+    
 #define IOLOG_INDENT( the_indention ) \
 { \
     int     i; \
     for ( i = 0; i < (the_indention); i++ ) { \
-	IOLog(" "); \
+        IOLog(" "); \
     } \
 }
-
-extern vm_offset_t       vm_kernel_stext;
-extern vm_offset_t       vm_kernel_etext;
-extern mach_vm_offset_t kext_alloc_base;
+    
+extern vm_offset_t	 vm_kernel_stext;
+extern vm_offset_t	 vm_kernel_etext;
+extern mach_vm_offset_t kext_alloc_base; 
 extern mach_vm_offset_t kext_alloc_max;
-
-bool ScanForAddrInObject(OSObject * theObject,
-    int indent );
-
-bool
-ScanForAddrInObject(OSObject * theObject,
-    int indent)
-{
-	const OSMetaClass *     myTypeID;
-	OSSharedPtr<OSCollectionIterator>  myIter;
-	OSSymbol *              myKey;
-	OSObject *              myValue;
-	bool                    myResult = false;
-
-	if (theObject == NULL) {
-		IOLog("%s: theObject is NULL \n",
-		    __FUNCTION__);
-		return myResult;
-	}
-
-	myTypeID = OSTypeIDInst(theObject);
-
-	if (myTypeID == OSTypeID(OSDictionary)) {
-		OSDictionary *      myDictionary;
-
-		myDictionary = OSDynamicCast(OSDictionary, theObject);
-		myIter = OSCollectionIterator::withCollection( myDictionary );
-		if (myIter == NULL) {
-			return myResult;
-		}
-
-		// !! reset the iterator
-		myIter->reset();
-
-		while ((myKey = OSDynamicCast(OSSymbol, myIter->getNextObject()))) {
-			bool    myTempResult;
-
-			myValue = myDictionary->getObject(myKey);
-			myTempResult = ScanForAddrInObject(myValue, (indent + 4));
-			if (myTempResult) {
-				// if we ever get a true result return true
-				myResult = true;
-				IOLOG_INDENT(indent);
-				IOLog("OSDictionary key \"%s\" \n", myKey->getCStringNoCopy());
-			}
-		}
-
-		// !! release the iterator
-		myIter.reset();
-	} else if (myTypeID == OSTypeID(OSArray)) {
-		OSArray *   myArray;
-
-		myArray = OSDynamicCast(OSArray, theObject);
-		myIter = OSCollectionIterator::withCollection(myArray);
-		if (myIter == NULL) {
-			return myResult;
-		}
-		// !! reset the iterator
-		myIter->reset();
-
-		while ((myValue = myIter->getNextObject())) {
-			bool        myTempResult;
-			myTempResult = ScanForAddrInObject(myValue, (indent + 4));
-			if (myTempResult) {
-				// if we ever get a true result return true
-				myResult = true;
-				IOLOG_INDENT(indent);
-				IOLog("OSArray: \n");
-			}
-		}
-		// !! release the iterator
-		myIter.reset();
-	} else if (myTypeID == OSTypeID(OSString) || myTypeID == OSTypeID(OSSymbol)) {
-		// should we look for addresses in strings?
-	} else if (myTypeID == OSTypeID(OSData)) {
-		void * *        myPtrPtr;
-		unsigned int    myLen;
-		OSData *        myDataObj;
-
-		myDataObj =    OSDynamicCast(OSData, theObject);
-		myPtrPtr = (void * *) myDataObj->getBytesNoCopy();
-		myLen = myDataObj->getLength();
-
-		if (myPtrPtr && myLen && myLen > 7) {
-			int     i;
-			int     myPtrCount = (myLen / sizeof(void *));
-
-			for (i = 0; i < myPtrCount; i++) {
-				UInt64 numberValue = (UInt64) * (myPtrPtr);
-
-				if (kext_alloc_max != 0 &&
-				    numberValue >= kext_alloc_base &&
-				    numberValue < kext_alloc_max) {
-					OSSharedPtr<OSKext> myKext;
-					// IOLog("found OSData %p in kext map %p to %p  \n",
-					//       *(myPtrPtr),
-					//       (void *) kext_alloc_base,
-					//       (void *) kext_alloc_max);
-
-					myKext = OSKext::lookupKextWithAddress((vm_address_t) *(myPtrPtr));
-					if (myKext) {
-						IOLog("found addr %p from an OSData obj within kext \"%s\"  \n",
-						    *(myPtrPtr),
-						    myKext->getIdentifierCString());
-					}
-					myResult = true;
-				}
-				if (vm_kernel_etext != 0 &&
-				    numberValue >= vm_kernel_stext &&
-				    numberValue < vm_kernel_etext) {
-					IOLog("found addr %p from an OSData obj within kernel text segment %p to %p  \n",
-					    *(myPtrPtr),
-					    (void *) vm_kernel_stext,
-					    (void *) vm_kernel_etext);
-					myResult = true;
-				}
-				myPtrPtr++;
-			}
-		}
-	} else if (myTypeID == OSTypeID(OSBoolean)) {
-		// do nothing here...
-	} else if (myTypeID == OSTypeID(OSNumber)) {
-		OSNumber * number = OSDynamicCast(OSNumber, theObject);
-
-		UInt64 numberValue = number->unsigned64BitValue();
-
-		if (kext_alloc_max != 0 &&
-		    numberValue >= kext_alloc_base &&
-		    numberValue < kext_alloc_max) {
-			OSSharedPtr<OSKext> myKext;
-			IOLog("found OSNumber in kext map %p to %p  \n",
-			    (void *) kext_alloc_base,
-			    (void *) kext_alloc_max);
-			IOLog("OSNumber 0x%08llx (%llu) \n", numberValue, numberValue);
-
-			myKext = OSKext::lookupKextWithAddress((vm_address_t) numberValue );
-			if (myKext) {
-				IOLog("found in kext \"%s\"  \n",
-				    myKext->getIdentifierCString());
-			}
-
-			myResult = true;
-		}
-		if (vm_kernel_etext != 0 &&
-		    numberValue >= vm_kernel_stext &&
-		    numberValue < vm_kernel_etext) {
-			IOLog("found OSNumber in kernel text segment %p to %p  \n",
-			    (void *) vm_kernel_stext,
-			    (void *) vm_kernel_etext);
-			IOLog("OSNumber 0x%08llx (%llu) \n", numberValue, numberValue);
-			myResult = true;
-		}
-	}
+    
+bool ScanForAddrInObject(OSObject * theObject, 
+                         int indent );
+
+bool ScanForAddrInObject(OSObject * theObject, 
+                         int indent)
+{
+    const OSMetaClass *     myTypeID;
+    OSCollectionIterator *  myIter;
+    OSSymbol *              myKey;
+    OSObject *              myValue;
+    bool                    myResult = false;
+    
+    if ( theObject == NULL ) {
+        IOLog("%s: theObject is NULL \n", 
+              __FUNCTION__);
+        return myResult;
+    }
+    
+    myTypeID = OSTypeIDInst(theObject);
+    
+    if ( myTypeID == OSTypeID(OSDictionary) ) {
+        OSDictionary *      myDictionary;
+        
+        myDictionary = OSDynamicCast(OSDictionary, theObject);
+        myIter = OSCollectionIterator::withCollection( myDictionary );
+        if ( myIter == NULL ) 
+            return myResult;
+        myIter->reset();
+        
+        while ( (myKey = OSDynamicCast(OSSymbol, myIter->getNextObject())) ) {
+            bool    myTempResult;
+            
+            myValue = myDictionary->getObject(myKey);
+            myTempResult = ScanForAddrInObject(myValue, (indent + 4));
+            if (myTempResult) {
+                // if we ever get a true result return true
+                myResult = true;
+                IOLOG_INDENT(indent);
+                IOLog("OSDictionary key \"%s\" \n", myKey->getCStringNoCopy());
+            }
+        }
+        myIter->release();
+    }
+    else if ( myTypeID == OSTypeID(OSArray) ) {
+        OSArray *   myArray;
+        
+        myArray = OSDynamicCast(OSArray, theObject);
+        myIter = OSCollectionIterator::withCollection(myArray);
+        if ( myIter == NULL ) 
+            return myResult;
+        myIter->reset();
+        
+        while ( (myValue = myIter->getNextObject()) ) {
+            bool        myTempResult;
+            myTempResult = ScanForAddrInObject(myValue, (indent + 4));
+            if (myTempResult) {
+                // if we ever get a true result return true
+                myResult = true;
+                IOLOG_INDENT(indent);
+                IOLog("OSArray: \n");
+            }
+        }
+        myIter->release();
+    }
+    else if ( myTypeID == OSTypeID(OSString) || myTypeID == OSTypeID(OSSymbol) ) {
+        
+        // should we look for addresses in strings?
+    }
+    else if ( myTypeID == OSTypeID(OSData) ) {
+        
+        void * *        myPtrPtr;
+        unsigned int    myLen;
+        OSData *        myDataObj;
+        
+        myDataObj =    OSDynamicCast(OSData, theObject);
+        myPtrPtr = (void * *) myDataObj->getBytesNoCopy();
+        myLen = myDataObj->getLength();
+        
+        if (myPtrPtr && myLen && myLen > 7) {
+            int     i;
+            int     myPtrCount = (myLen / sizeof(void *));
+            
+            for (i = 0; i < myPtrCount; i++) {
+                UInt64 numberValue = (UInt64) *(myPtrPtr);
+                
+                if ( kext_alloc_max != 0 &&
+                    numberValue >= kext_alloc_base && 
+                    numberValue < kext_alloc_max ) {
+                    
+                    OSKext * myKext    = NULL;  // must release (looked up)
+                                                // IOLog("found OSData %p in kext map %p to %p  \n",
+                                                //       *(myPtrPtr),
+                                                //       (void *) kext_alloc_base,
+                                                //       (void *) kext_alloc_max);
+                    
+                    myKext = OSKext::lookupKextWithAddress( (vm_address_t) *(myPtrPtr) );
+                    if (myKext) {
+                        IOLog("found addr %p from an OSData obj within kext \"%s\"  \n",
+                              *(myPtrPtr),
+                              myKext->getIdentifierCString());
+                        myKext->release();
+                    }
+                    myResult = true;
+                }
+                if ( vm_kernel_etext != 0 &&
+                    numberValue >= vm_kernel_stext && 
+                    numberValue < vm_kernel_etext ) {
+                    IOLog("found addr %p from an OSData obj within kernel text segment %p to %p  \n",
+                          *(myPtrPtr),
+                          (void *) vm_kernel_stext,
+                          (void *) vm_kernel_etext);
+                    myResult = true;
+                }
+                myPtrPtr++;
+            }
+        }
+    }
+    else if ( myTypeID == OSTypeID(OSBoolean) ) {
+        
+        // do nothing here...
+    }
+    else if ( myTypeID == OSTypeID(OSNumber) ) {
+        
+        OSNumber * number = OSDynamicCast(OSNumber, theObject);
+        
+        UInt64 numberValue = number->unsigned64BitValue();
+        
+        if ( kext_alloc_max != 0 &&
+            numberValue >= kext_alloc_base && 
+            numberValue < kext_alloc_max ) {
+            
+            OSKext * myKext    = NULL;  // must release (looked up)
+            IOLog("found OSNumber in kext map %p to %p  \n",
+                  (void *) kext_alloc_base,
+                  (void *) kext_alloc_max);
+            IOLog("OSNumber 0x%08llx (%llu) \n", numberValue, numberValue);
+            
+            myKext = OSKext::lookupKextWithAddress( (vm_address_t) numberValue );
+            if (myKext) {
+                IOLog("found in kext \"%s\"  \n",
+                      myKext->getIdentifierCString());
+                myKext->release();
+            }
+            
+            myResult = true;
+        }
+        if ( vm_kernel_etext != 0 &&
+            numberValue >= vm_kernel_stext && 
+            numberValue < vm_kernel_etext ) {
+            IOLog("found OSNumber in kernel text segment %p to %p  \n",
+                  (void *) vm_kernel_stext,
+                  (void *) vm_kernel_etext);
+            IOLog("OSNumber 0x%08llx (%llu) \n", numberValue, numberValue);
+            myResult = true;
+        }
+    }
 #if 0
-	else {
-		const OSMetaClass* myMetaClass = NULL;
-
-		myMetaClass = theObject->getMetaClass();
-		if (myMetaClass) {
-			IOLog("class %s \n", myMetaClass->getClassName());
-		} else {
-			IOLog("Unknown object \n" );
-		}
-	}
+    else {
+        const OSMetaClass* myMetaClass = NULL;
+        
+        myMetaClass = theObject->getMetaClass();
+        if ( myMetaClass ) {
+            IOLog("class %s \n", myMetaClass->getClassName() );
+        }
+        else {
+            IOLog("Unknown object \n" );
+        }
+    }
 #endif
-
-	return myResult;
-}
-#endif // KASLR_KEXT_DEBUG
-};         /* extern "C" */
+    
+    return myResult;
+}
+#endif // KASLR_KEXT_DEBUG 
+
+}; /* extern "C" */
 
 #if PRAGMA_MARK
 #pragma mark Backtrace Dump & kmod_get_info() support
@@ -15653,86 +10284,63 @@
 /* static */
 void
 OSKext::printKextsInBacktrace(
-	vm_offset_t  * addr __unused,
-	unsigned int   cnt __unused,
-	int         (* printf_func)(const char *fmt, ...) __unused,
-	uint32_t       flags __unused)
-{
-	addr64_t    summary_page = 0;
-	addr64_t    last_summary_page = 0;
-
-	if (kPrintKextsLock & flags) {
-		if (!sKextSummariesLock) {
-			return;
-		}
-		IOLockLock(sKextSummariesLock);
-	}
-
-	if (!gLoadedKextSummaries) {
-		(*printf_func)("         can't perform kext scan: no kext summary");
-		goto finish;
-	}
-
-	summary_page = trunc_page((addr64_t)(uintptr_t)gLoadedKextSummaries);
-	last_summary_page = round_page(summary_page + sLoadedKextSummariesAllocSize);
-	for (; summary_page < last_summary_page; summary_page += PAGE_SIZE) {
-		if (pmap_find_phys(kernel_pmap, summary_page) == 0) {
-			(*printf_func)("         can't perform kext scan: "
-			    "missing kext summary page %p", summary_page);
-			goto finish;
-		}
-	}
-
-	foreachKextInBacktrace(addr, cnt, 0, ^(OSKextLoadedKextSummary *summary, uint32_t index) {
-		if (index == 0 && !(kPrintKextsTerse & flags)) {
-		        (*printf_func)("      Kernel Extensions in backtrace:\n");
-		}
-
-		printSummary(summary, printf_func, flags);
-	});
+    vm_offset_t  * addr,
+    unsigned int   cnt,
+    int         (* printf_func)(const char *fmt, ...),
+    bool           lockFlag,
+    bool           doUnslide)
+{
+    addr64_t    summary_page = 0;
+    addr64_t    last_summary_page = 0;
+    bool        found_kmod = false;
+    u_int       i = 0;
+
+    if (lockFlag) {
+        if (!sKextSummariesLock) return;
+        IOLockLock(sKextSummariesLock);
+    }
+
+    if (!gLoadedKextSummaries) {
+        (*printf_func)("         can't perform kext scan: no kext summary");
+        goto finish;
+    }
+
+    summary_page = trunc_page((addr64_t)(uintptr_t)gLoadedKextSummaries);
+    last_summary_page = round_page(summary_page + sLoadedKextSummariesAllocSize);
+    for (; summary_page < last_summary_page; summary_page += PAGE_SIZE) {
+        if (pmap_find_phys(kernel_pmap, summary_page) == 0) {
+            (*printf_func)("         can't perform kext scan: "
+                "missing kext summary page %p", summary_page);
+            goto finish;
+        }
+    }
+
+    for (i = 0; i < gLoadedKextSummaries->numSummaries; ++i) {
+        OSKextLoadedKextSummary * summary;
+        
+        summary = gLoadedKextSummaries->summaries + i;
+        if (!summary->address) {
+            continue;
+        }
+        
+        if (!summaryIsInBacktrace(summary, addr, cnt)) {
+            continue;
+        }
+        
+        if (!found_kmod) {
+            (*printf_func)("      Kernel Extensions in backtrace:\n");
+            found_kmod = true;
+        }
+
+        printSummary(summary, printf_func, doUnslide);
+    }
 
 finish:
-	if (kPrintKextsLock & flags) {
-		IOLockUnlock(sKextSummariesLock);
-	}
-
-	return;
-}
-
-void
-OSKext::foreachKextInBacktrace(
-	vm_offset_t   * addr,
-	uint32_t        cnt,
-	uint32_t        flags,
-	void         (^ handler)(OSKextLoadedKextSummary *summary, uint32_t index))
-{
-	uint32_t n = 0;
-
-	if (kPrintKextsLock & flags) {
-		if (!sKextSummariesLock) {
-			return;
-		}
-		IOLockLock(sKextSummariesLock);
-	}
-
-	for (uint32_t i = 0; i < gLoadedKextSummaries->numSummaries; ++i) {
-		OSKextLoadedKextSummary * summary;
-
-		summary = gLoadedKextSummaries->summaries + i;
-		if (!summary->address) {
-			continue;
-		}
-
-		if (!summaryIsInBacktrace(summary, addr, cnt)) {
-			continue;
-		}
-
-		handler(summary, n++);
-	}
-
-	if (kPrintKextsLock & flags) {
-		IOLockUnlock(sKextSummariesLock);
-	}
+    if (lockFlag) {
+        IOLockUnlock(sKextSummariesLock);
+    }
+
+    return;
 }
 
 /*********************************************************************
@@ -15741,264 +10349,120 @@
 /* static */
 boolean_t
 OSKext::summaryIsInBacktrace(
-	OSKextLoadedKextSummary   * summary,
-	vm_offset_t               * addr,
-	unsigned int                cnt)
-{
-	u_int i = 0;
-
-	for (i = 0; i < cnt; i++) {
-		vm_offset_t kscan_addr = addr[i];
-#if  __has_feature(ptrauth_calls)
-		kscan_addr = (vm_offset_t)VM_KERNEL_STRIP_PTR(kscan_addr);
-#endif /*  __has_feature(ptrauth_calls) */
-		if ((kscan_addr >= summary->text_exec_address) &&
-		    (kscan_addr < (summary->text_exec_address + summary->text_exec_size))) {
-			return TRUE;
-		}
-	}
-
-	return FALSE;
-}
-
-/*
- * Get the kext summary object for the kext where 'addr' lies. Must be called with
- * sKextSummariesLock held.
- */
-OSKextLoadedKextSummary *
-OSKext::summaryForAddress(uintptr_t addr)
-{
-#if  __has_feature(ptrauth_calls)
-	addr = (uintptr_t)VM_KERNEL_STRIP_PTR(addr);
-#endif /*  __has_feature(ptrauth_calls) */
-	for (unsigned i = 0; i < gLoadedKextSummaries->numSummaries; ++i) {
-		OSKextLoadedKextSummary *summary = &gLoadedKextSummaries->summaries[i];
-		if (!summary->address) {
-			continue;
-		}
-
-#if VM_MAPPED_KEXTS
-		/* On our platforms that use VM_MAPPED_KEXTS, we currently do not
-		 * support split kexts, but we also may unmap the kexts, which can
-		 * race with the above codepath (see OSKext::unload).  As such,
-		 * use a simple range lookup if we are using VM_MAPPED_KEXTS.
-		 */
-		if ((addr >= summary->address) && (addr < (summary->address + summary->size))) {
-			return summary;
-		}
-#else
-		kernel_mach_header_t *mh = (kernel_mach_header_t *)summary->address;
-		kernel_segment_command_t *seg;
-
-		for (seg = firstsegfromheader(mh); seg != NULL; seg = nextsegfromheader(mh, seg)) {
-			if ((addr >= seg->vmaddr) && (addr < (seg->vmaddr + seg->vmsize))) {
-				return summary;
-			}
-		}
-#endif
-	}
-
-	/* addr did not map to any kext */
-	return NULL;
-}
-
-/* static */
-void *
-OSKext::kextForAddress(const void *address)
-{
-	OSKextActiveAccount * active;
-	OSKext              * kext = NULL;
-	uint32_t              baseIdx;
-	uint32_t              lim;
-	uintptr_t             addr = (uintptr_t) address;
-	size_t                i;
-
-	if (!addr) {
-		return NULL;
-	}
-#if  __has_feature(ptrauth_calls)
-	addr = (uintptr_t)VM_KERNEL_STRIP_PTR(addr);
-#endif /*  __has_feature(ptrauth_calls) */
-
-	if (sKextAccountsCount) {
-		lck_ticket_lock(sKextAccountsLock, sKextAccountsLockGrp);
-		// bsearch sKextAccounts list
-		for (baseIdx = 0, lim = sKextAccountsCount; lim; lim >>= 1) {
-			active = &sKextAccounts[baseIdx + (lim >> 1)];
-			if ((addr >= active->address) && (addr < active->address_end)) {
-				if (active->account &&
-				    (kext = active->account->kext) &&
-				    kext->kmod_info) {
-					lck_ticket_unlock(sKextAccountsLock);
-					return (void *)kext->kmod_info->address;
-				}
-				break;
-			} else if (addr > active->address) {
-				// move right
-				baseIdx += (lim >> 1) + 1;
-				lim--;
-			}
-			// else move left
-		}
-		lck_ticket_unlock(sKextAccountsLock);
-	}
-	if (kernel_text_contains(addr)) {
-		return (void *)&_mh_execute_header;
-	}
-	if (gLoadedKextSummaries) {
-		IOLockLock(sKextSummariesLock);
-		for (i = 0; i < gLoadedKextSummaries->numSummaries; i++) {
-			OSKextLoadedKextSummary *summary = gLoadedKextSummaries->summaries + i;
-			if (addr >= summary->address && addr < summary->address + summary->size) {
-				void *kextAddress = (void *)summary->address;
-				IOLockUnlock(sKextSummariesLock);
-				return kextAddress;
-			}
-		}
-		IOLockUnlock(sKextSummariesLock);
-	}
-
-	return NULL;
-}
-
-/* static */
-kern_return_t
-OSKext::summaryForAddressExt(
-	const void              * address,
-	OSKextLoadedKextSummary * summary)
-{
-	kern_return_t                   result = KERN_FAILURE;
-	const OSKextLoadedKextSummary * foundSummary = NULL;
-
-	/*
-	 * This needs to be safe to call even before the lock has been initialized
-	 * in OSKext::initialize(), as we might get here from the ksancov runtime
-	 * when instrumenting XNU itself with sanitizer coverage.
-	 */
-	if (!sKextSummariesLock) {
-		return result;
-	}
-
-	IOLockLock(sKextSummariesLock);
-	if (gLoadedKextSummaries) {
-		foundSummary = summaryForAddress((uintptr_t)address);
-		if (foundSummary) {
-			memcpy(summary, foundSummary, sizeof(*summary));
-			result = KERN_SUCCESS;
-		} else {
-			result = KERN_NOT_FOUND;
-		}
-	}
-	IOLockUnlock(sKextSummariesLock);
-
-	return result;
-}
-
-/*
- * Find a OSKextLoadedKextSummary given the ID from a kmod_info_t *
- * Safe to call in panic context.
- */
-static OSKextLoadedKextSummary *
-findSummary(uint32_t tagID)
-{
-	OSKextLoadedKextSummary * summary;
-	for (size_t i = 0; i < gLoadedKextSummaries->numSummaries; ++i) {
-		summary = gLoadedKextSummaries->summaries + i;
-		if (summary->loadTag == tagID) {
-			return summary;
-		}
-	}
-	return NULL;
+    OSKextLoadedKextSummary   * summary,
+    vm_offset_t               * addr,
+    unsigned int                cnt)
+{
+    u_int i = 0;
+
+    for (i = 0; i < cnt; i++) {
+        vm_offset_t kscan_addr = addr[i];
+        if ((kscan_addr >= summary->address) &&
+            (kscan_addr < (summary->address + summary->size))) 
+        {
+            return TRUE;
+        }
+    }
+
+    return FALSE;
+}
+
+/*********************************************************************
+ * scan list of loaded kext summaries looking for a load address match and if
+ * found return the UUID C string.  If not found then set empty string.
+ *********************************************************************/
+static void findSummaryUUID(
+                            uint32_t        tag_ID,
+                            uuid_string_t   uuid);
+
+static void findSummaryUUID(
+                            uint32_t        tag_ID, 
+                            uuid_string_t   uuid)
+{
+    u_int     i;
+    
+    uuid[0] = 0x00; // default to no UUID
+    
+    for (i = 0; i < gLoadedKextSummaries->numSummaries; ++i) {
+        OSKextLoadedKextSummary * summary;
+        
+        summary = gLoadedKextSummaries->summaries + i;
+        
+        if (summary->loadTag == tag_ID) {
+            (void) uuid_unparse(summary->uuid, uuid);
+            break;
+        }
+    }
+    return;
 }
 
 /*********************************************************************
 * This function must be safe to call in panic context.
 *********************************************************************/
-void
-OSKext::printSummary(
-	OSKextLoadedKextSummary * summary,
-	int                    (* printf_func)(const char *fmt, ...),
-	uint32_t                  flags)
-{
-	kmod_reference_t * kmod_ref = NULL;
-	uuid_string_t uuid;
-	char version[kOSKextVersionMaxLength];
-	uint64_t tmpAddr;
-	uint64_t tmpSize;
-	OSKextLoadedKextSummary *dependencySummary;
-
-	if (!OSKextVersionGetString(summary->version, version, sizeof(version))) {
-		strlcpy(version, "unknown version", sizeof(version));
-	}
-	(void) uuid_unparse(summary->uuid, uuid);
-
-#if defined(__arm__) || defined(__arm64__)
-	tmpAddr = summary->text_exec_address;
-	tmpSize = summary->text_exec_size;
-#else
-	tmpAddr = summary->address;
-	tmpSize = summary->size;
-#endif
-	if (kPrintKextsUnslide & flags) {
-		tmpAddr = ml_static_unslide(tmpAddr);
-	}
-	(*printf_func)("%s%s(%s)[%s]@0x%llx->0x%llx\n",
-	    (kPrintKextsTerse & flags) ? "" : "         ",
-	    summary->name, version, uuid,
-	    tmpAddr, tmpAddr + tmpSize - 1);
-
-	if (kPrintKextsTerse & flags) {
-		return;
-	}
-
-	/* print dependency info */
-	for (kmod_ref = (kmod_reference_t *) summary->reference_list;
-	    kmod_ref;
-	    kmod_ref = kmod_ref->next) {
-		kmod_info_t * rinfo;
-
-		if (pmap_find_phys(kernel_pmap, (addr64_t)((uintptr_t)kmod_ref)) == 0) {
-			(*printf_func)("            kmod dependency scan stopped "
-			    "due to missing dependency page: %p\n",
-			    (kPrintKextsUnslide & flags) ? (void *)ml_static_unslide((vm_offset_t)kmod_ref) : kmod_ref);
-			break;
-		}
-		rinfo = kmod_ref->info;
-
-		if (pmap_find_phys(kernel_pmap, (addr64_t)((uintptr_t)rinfo)) == 0) {
-			(*printf_func)("            kmod dependency scan stopped "
-			    "due to missing kmod page: %p\n",
-			    (kPrintKextsUnslide & flags) ? (void *)ml_static_unslide((vm_offset_t)rinfo) : rinfo);
-			break;
-		}
-
-		if (!rinfo->address) {
-			continue;         // skip fake entries for built-ins
-		}
-
-		dependencySummary = findSummary(rinfo->id);
-		uuid[0] = 0x00;
-		tmpAddr = rinfo->address;
-		tmpSize = rinfo->size;
-		if (dependencySummary) {
-			(void) uuid_unparse(dependencySummary->uuid, uuid);
-#if defined(__arm__) || defined(__arm64__)
-			tmpAddr = dependencySummary->text_exec_address;
-			tmpSize = dependencySummary->text_exec_size;
-#endif
-		}
-
-		if (kPrintKextsUnslide & flags) {
-			tmpAddr = ml_static_unslide(tmpAddr);
-		}
-		(*printf_func)("            dependency: %s(%s)[%s]@%p->%p\n",
-		    rinfo->name, rinfo->version, uuid, tmpAddr, tmpAddr + tmpSize - 1);
-	}
-	return;
-}
-
-
-#if !defined(__arm__) && !defined(__arm64__)
+void OSKext::printSummary(
+    OSKextLoadedKextSummary * summary,
+    int                    (* printf_func)(const char *fmt, ...),
+    bool                      doUnslide)
+{
+    kmod_reference_t * kmod_ref = NULL;
+    uuid_string_t uuid;
+    char version[kOSKextVersionMaxLength];
+    uint64_t tmpAddr;
+
+    if (!OSKextVersionGetString(summary->version, version, sizeof(version))) {
+        strlcpy(version, "unknown version", sizeof(version));
+    }
+    (void) uuid_unparse(summary->uuid, uuid);
+    
+    if (doUnslide) {
+        tmpAddr = VM_KERNEL_UNSLIDE(summary->address);
+    }
+    else {
+        tmpAddr = summary->address;
+    }
+    (*printf_func)("         %s(%s)[%s]@0x%llx->0x%llx\n",
+        summary->name, version, uuid,
+        tmpAddr, tmpAddr + summary->size - 1);
+    
+    /* print dependency info */
+    for (kmod_ref = (kmod_reference_t *) summary->reference_list; 
+         kmod_ref; 
+         kmod_ref = kmod_ref->next) {
+        kmod_info_t * rinfo;
+        
+        if (pmap_find_phys(kernel_pmap, (addr64_t)((uintptr_t)kmod_ref)) == 0) {
+            (*printf_func)("            kmod dependency scan stopped "
+                           "due to missing dependency page: %p\n", kmod_ref);
+            break;
+        }
+        rinfo = kmod_ref->info;
+        
+        if (pmap_find_phys(kernel_pmap, (addr64_t)((uintptr_t)rinfo)) == 0) {
+            (*printf_func)("            kmod dependency scan stopped "
+                           "due to missing kmod page: %p\n", rinfo);
+            break;
+        }
+        
+        if (!rinfo->address) {
+            continue; // skip fake entries for built-ins
+        }
+        
+        /* locate UUID in gLoadedKextSummaries */
+        findSummaryUUID(rinfo->id, uuid);
+        
+        if (doUnslide) {
+            tmpAddr = VM_KERNEL_UNSLIDE(rinfo->address);
+        }
+        else {
+            tmpAddr = rinfo->address;
+        }
+        (*printf_func)("            dependency: %s(%s)[%s]@%p\n",
+                       rinfo->name, rinfo->version, uuid, tmpAddr);
+    }
+    return;
+}
+
+
 /*******************************************************************************
 * substitute() looks at an input string (a pointer within a larger buffer)
 * for a match to a substring, and on match it writes the marker & substitution
@@ -16006,42 +10470,42 @@
 * output (to) indexes as appropriate.
 *******************************************************************************/
 static int substitute(
-	const char * scan_string,
-	char       * string_out,
-	uint32_t   * to_index,
-	uint32_t   * from_index,
-	const char * substring,
-	char         marker,
-	char         substitution);
+    const char * scan_string,
+    char       * string_out,
+    uint32_t   * to_index,
+    uint32_t   * from_index,
+    const char * substring,
+    char         marker,
+    char         substitution);
 
 /* string_out must be at least KMOD_MAX_NAME bytes.
  */
 static int
 substitute(
-	const char * scan_string,
-	char       * string_out,
-	uint32_t   * to_index,
-	uint32_t   * from_index,
-	const char * substring,
-	char         marker,
-	char         substitution)
-{
-	size_t substring_length = strnlen(substring, KMOD_MAX_NAME - 1);
-
-	/* On a substring match, append the marker (if there is one) and then
-	 * the substitution character, updating the output (to) index accordingly.
-	 * Then update the input (from) length by the length of the substring
-	 * that got replaced.
-	 */
-	if (!strncmp(scan_string, substring, substring_length)) {
-		if (marker) {
-			string_out[(*to_index)++] = marker;
-		}
-		string_out[(*to_index)++] = substitution;
-		(*from_index) += substring_length;
-		return 1;
-	}
-	return 0;
+    const char * scan_string,
+    char       * string_out,
+    uint32_t   * to_index,
+    uint32_t   * from_index,
+    const char * substring,
+    char         marker,
+    char         substitution)
+{
+    uint32_t substring_length = strnlen(substring, KMOD_MAX_NAME - 1);
+
+   /* On a substring match, append the marker (if there is one) and then
+    * the substitution character, updating the output (to) index accordingly.
+    * Then update the input (from) length by the length of the substring
+    * that got replaced.
+    */
+    if (!strncmp(scan_string, substring, substring_length)) {
+        if (marker) {
+            string_out[(*to_index)++] = marker;
+        }
+        string_out[(*to_index)++] = substitution;
+        (*from_index) += substring_length;
+        return 1;
+    }
+    return 0;
 }
 
 /*******************************************************************************
@@ -16050,72 +10514,74 @@
 * prefixes & substrings as defined by tables in kext_panic_report.h.
 *******************************************************************************/
 static void compactIdentifier(
-	const char * identifier,
-	char       * identifier_out,
-	char      ** identifier_out_end);
+    const char * identifier,
+    char       * identifier_out,
+    char      ** identifier_out_end);
 
 static void
 compactIdentifier(
-	const char * identifier,
-	char       * identifier_out,
-	char      ** identifier_out_end)
-{
-	uint32_t       from_index, to_index;
-	uint32_t       scan_from_index = 0;
-	uint32_t       scan_to_index   = 0;
-	subs_entry_t * subs_entry    = NULL;
-	int            did_sub       = 0;
-
-	from_index = to_index = 0;
-	identifier_out[0] = '\0';
-
-	/* Replace certain identifier prefixes with shorter @+character sequences.
-	 * Check the return value of substitute() so we only replace the prefix.
-	 */
-	for (subs_entry = &kext_identifier_prefix_subs[0];
-	    subs_entry->substring && !did_sub;
-	    subs_entry++) {
-		did_sub = substitute(identifier, identifier_out,
-		    &scan_to_index, &scan_from_index,
-		    subs_entry->substring, /* marker */ '\0', subs_entry->substitute);
-	}
-	did_sub = 0;
-
-	/* Now scan through the identifier looking for the common substrings
-	 * and replacing them with shorter !+character sequences via substitute().
-	 */
-	for (/* see above */;
-	    scan_from_index < KMOD_MAX_NAME - 1 && identifier[scan_from_index];
-	    /* see loop */) {
-		const char   * scan_string = &identifier[scan_from_index];
-
-		did_sub = 0;
-
-		if (scan_from_index) {
-			for (subs_entry = &kext_identifier_substring_subs[0];
-			    subs_entry->substring && !did_sub;
-			    subs_entry++) {
-				did_sub = substitute(scan_string, identifier_out,
-				    &scan_to_index, &scan_from_index,
-				    subs_entry->substring, '!', subs_entry->substitute);
-			}
-		}
-
-		/* If we didn't substitute, copy the input character to the output.
-		 */
-		if (!did_sub) {
-			identifier_out[scan_to_index++] = identifier[scan_from_index++];
-		}
-	}
-
-	identifier_out[scan_to_index] = '\0';
-	if (identifier_out_end) {
-		*identifier_out_end = &identifier_out[scan_to_index];
-	}
-
-	return;
-}
-#endif /* !defined(__arm__) && !defined(__arm64__) */
+    const char * identifier,
+    char       * identifier_out,
+    char      ** identifier_out_end)
+{
+    uint32_t       from_index, to_index;
+    uint32_t       scan_from_index = 0;
+    uint32_t       scan_to_index   = 0;
+    subs_entry_t * subs_entry    = NULL;
+    int            did_sub       = 0;
+
+    from_index = to_index = 0;
+    identifier_out[0] = '\0';
+
+   /* Replace certain identifier prefixes with shorter @+character sequences.
+    * Check the return value of substitute() so we only replace the prefix.
+    */
+    for (subs_entry = &kext_identifier_prefix_subs[0];
+         subs_entry->substring && !did_sub;
+         subs_entry++) {
+
+        did_sub = substitute(identifier, identifier_out,
+            &scan_to_index, &scan_from_index,
+            subs_entry->substring, /* marker */ '\0', subs_entry->substitute);
+    }
+    did_sub = 0;
+
+   /* Now scan through the identifier looking for the common substrings
+    * and replacing them with shorter !+character sequences via substitute().
+    */
+    for (/* see above */;
+         scan_from_index < KMOD_MAX_NAME - 1 && identifier[scan_from_index];
+         /* see loop */) {
+         
+        const char   * scan_string = &identifier[scan_from_index];
+
+        did_sub = 0;
+
+        if (scan_from_index) {
+            for (subs_entry = &kext_identifier_substring_subs[0];
+                 subs_entry->substring && !did_sub;
+                 subs_entry++) {
+
+                did_sub = substitute(scan_string, identifier_out,
+                    &scan_to_index, &scan_from_index,
+                    subs_entry->substring, '!', subs_entry->substitute);
+            }
+        }
+
+       /* If we didn't substitute, copy the input character to the output.
+        */
+        if (!did_sub) {
+            identifier_out[scan_to_index++] = identifier[scan_from_index++];
+        }
+    }
+    
+    identifier_out[scan_to_index] = '\0';
+    if (identifier_out_end) {
+        *identifier_out_end = &identifier_out[scan_to_index];
+    }
+    
+    return;
+}
 
 /*******************************************************************************
 * assemble_identifier_and_version() adds to a string buffer a compacted
@@ -16124,34 +10590,30 @@
 
 /* identPlusVers must be at least 2*KMOD_MAX_NAME in length.
  */
-static size_t assemble_identifier_and_version(
-	kmod_info_t * kmod_info,
-	char        * identPlusVers,
-	size_t        bufSize);
-
-static size_t
+static int assemble_identifier_and_version(
+                                           kmod_info_t * kmod_info,
+                                           char        * identPlusVers,
+                                           int           bufSize);
+
+static int
 assemble_identifier_and_version(
-	kmod_info_t * kmod_info,
-	char        * identPlusVers,
-	size_t        bufSize)
-{
-	size_t result = 0;
-
-#if defined(__arm__) || defined(__arm64__)
-	result = strlcpy(identPlusVers, kmod_info->name, KMOD_MAX_NAME);
-#else
-	compactIdentifier(kmod_info->name, identPlusVers, NULL);
-	result = strnlen(identPlusVers, KMOD_MAX_NAME - 1);
-#endif
-	identPlusVers[result++] = '\t';         // increment for real char
-	identPlusVers[result] = '\0';         // don't increment for nul char
-	result = strlcat(identPlusVers, kmod_info->version, bufSize);
-	if (result >= bufSize) {
-		identPlusVers[bufSize - 1] = '\0';
-		result = bufSize - 1;
-	}
-
-	return result;
+                                kmod_info_t * kmod_info, 
+                                char        * identPlusVers,
+                                int           bufSize)
+{
+    int result = 0;
+
+    compactIdentifier(kmod_info->name, identPlusVers, NULL);
+    result = strnlen(identPlusVers, KMOD_MAX_NAME - 1);
+    identPlusVers[result++] = '\t';  // increment for real char
+    identPlusVers[result] = '\0';    // don't increment for nul char
+    result = strlcat(identPlusVers, kmod_info->version, bufSize);
+    if (result >= bufSize) {
+        identPlusVers[bufSize - 1] = '\0';
+        result = bufSize - 1;
+    }
+    
+    return result;
 }
 
 /*******************************************************************************
@@ -16160,100 +10622,102 @@
 /* static */
 int
 OSKext::saveLoadedKextPanicListTyped(
-	const char * prefix,
-	int          invertFlag,
-	int          libsFlag,
-	char       * paniclist,
-	uint32_t     list_size)
-{
-	int             result = -1;
-	unsigned int    count, i;
-
-	count = sLoadedKexts->getCount();
-	if (!count) {
-		goto finish;
-	}
-
-	i = count - 1;
-	do {
-		OSObject    * rawKext = sLoadedKexts->getObject(i);
-		OSKext      * theKext = OSDynamicCast(OSKext, rawKext);
-		int           match;
-		size_t        identPlusVersLength;
-		size_t        tempLen;
-		char          identPlusVers[2 * KMOD_MAX_NAME];
-
-		if (!rawKext) {
-			printf("OSKext::saveLoadedKextPanicListTyped - "
-			    "NULL kext in loaded kext list; continuing\n");
-			continue;
-		}
-
-		if (!theKext) {
-			printf("OSKext::saveLoadedKextPanicListTyped - "
-			    "Kext type cast failed in loaded kext list; continuing\n");
-			continue;
-		}
-
-		/* Skip all built-in kexts.
-		 */
-		if (theKext->isKernelComponent()) {
-			continue;
-		}
-
-		kmod_info_t * kmod_info = theKext->kmod_info;
-
-		/* Filter for kmod name (bundle identifier).
-		 */
-		match = !strncmp(kmod_info->name, prefix, strnlen(prefix, KMOD_MAX_NAME));
-		if ((match && invertFlag) || (!match && !invertFlag)) {
-			continue;
-		}
-
-		/* Filter for libraries (kexts that have a compatible version).
-		 */
-		if ((libsFlag == 0 && theKext->getCompatibleVersion() > 1) ||
-		    (libsFlag == 1 && theKext->getCompatibleVersion() < 1)) {
-			continue;
-		}
-
-		if (!kmod_info ||
-		    !pmap_find_phys(kernel_pmap, (addr64_t)((uintptr_t)kmod_info))) {
-			printf("kext scan stopped due to missing kmod_info page: %p\n",
-			    kmod_info);
-			goto finish;
-		}
-
-		identPlusVersLength = assemble_identifier_and_version(kmod_info,
-		    identPlusVers,
-		    sizeof(identPlusVers));
-		if (!identPlusVersLength) {
-			printf("error saving loaded kext info\n");
-			goto finish;
-		}
-
-		/* make sure everything fits and we null terminate.
-		 */
-		tempLen = strlcat(paniclist, identPlusVers, list_size);
-		if (tempLen >= list_size) {
-			// panic list is full, keep it and null terminate
-			paniclist[list_size - 1] = 0x00;
-			result = 0;
-			goto finish;
-		}
-		tempLen = strlcat(paniclist, "\n", list_size);
-		if (tempLen >= list_size) {
-			// panic list is full, keep it and null terminate
-			paniclist[list_size - 1] = 0x00;
-			result = 0;
-			goto finish;
-		}
-	} while (i--);
-
-	result = 0;
+    const char * prefix,
+    int          invertFlag,
+    int          libsFlag,
+    char       * paniclist,
+    uint32_t     list_size)
+{
+    int             result = -1;
+    unsigned int    count, i;
+
+    count = sLoadedKexts->getCount();
+    if (!count) {
+        goto finish;
+    }
+
+    i = count - 1;
+    do {
+        OSObject    * rawKext = sLoadedKexts->getObject(i);
+        OSKext      * theKext = OSDynamicCast(OSKext, rawKext);
+        int           match;
+        uint32_t      identPlusVersLength;
+        uint32_t      tempLen;
+        char          identPlusVers[2*KMOD_MAX_NAME];
+        
+        if (!rawKext) {
+            printf("OSKext::saveLoadedKextPanicListTyped - "
+                "NULL kext in loaded kext list; continuing\n");
+            continue;
+        }
+
+        if (!theKext) {
+            printf("OSKext::saveLoadedKextPanicListTyped - "
+                "Kext type cast failed in loaded kext list; continuing\n");
+            continue;
+        }
+
+       /* Skip all built-in kexts.
+        */
+        if (theKext->isKernelComponent()) {
+            continue;
+        }
+
+        kmod_info_t * kmod_info = theKext->kmod_info;
+
+       /* Filter for kmod name (bundle identifier).
+        */
+        match = !strncmp(kmod_info->name, prefix, strnlen(prefix, KMOD_MAX_NAME));
+        if ((match && invertFlag) || (!match && !invertFlag)) {
+            continue;
+        }
+
+       /* Filter for libraries (kexts that have a compatible version).
+        */
+        if ((libsFlag == 0 && theKext->getCompatibleVersion() > 1) ||
+            (libsFlag == 1 && theKext->getCompatibleVersion() < 1)) {
+
+            continue;
+        }
+
+        if (!kmod_info ||
+            !pmap_find_phys(kernel_pmap, (addr64_t)((uintptr_t)kmod_info))) {
+
+            printf("kext scan stopped due to missing kmod_info page: %p\n",
+                   kmod_info);
+            goto finish;
+        }
+
+        identPlusVersLength = assemble_identifier_and_version(kmod_info,
+                                                              identPlusVers,
+                                                              sizeof(identPlusVers));
+        if (!identPlusVersLength) {
+            printf("error saving loaded kext info\n");
+            goto finish;
+        }
+
+        /* make sure everything fits and we null terminate.
+         */
+        tempLen = strlcat(paniclist, identPlusVers, list_size);
+        if (tempLen >= list_size) {
+            // panic list is full, keep it and null terminate
+            paniclist[list_size - 1] = 0x00;
+            result = 0;
+            goto finish;
+        }
+        tempLen = strlcat(paniclist, "\n", list_size);
+        if (tempLen >= list_size) {
+            // panic list is full, keep it and null terminate
+            paniclist[list_size - 1] = 0x00;
+            result = 0;
+            goto finish;
+        }
+    } while (i--);
+    
+    result = 0;
 finish:
-
-	return result;
+    
+    return result;
 }
 
 /*********************************************************************
@@ -16262,86 +10726,88 @@
 void
 OSKext::saveLoadedKextPanicList(void)
 {
-	char     * newlist        = NULL;
-	uint32_t   newlist_size   = 0;
-
-	newlist_size = KEXT_PANICLIST_SIZE;
-	newlist = (char *)kalloc_data_tag(newlist_size,
-	    Z_WAITOK, VM_KERN_MEMORY_OSKEXT);
-
-	if (!newlist) {
-		OSKextLog(/* kext */ NULL,
-		    kOSKextLogErrorLevel | kOSKextLogGeneralFlag,
-		    "Couldn't allocate kext panic log buffer.");
-		goto finish;
-	}
-
-	newlist[0] = '\0';
-
-	// non-"com.apple." kexts
-	if (OSKext::saveLoadedKextPanicListTyped("com.apple.", /* invert? */ 1,
-	    /* libs? */ -1, newlist, newlist_size) != 0) {
-		goto finish;
-	}
-	// "com.apple." nonlibrary kexts
-	if (OSKext::saveLoadedKextPanicListTyped("com.apple.", /* invert? */ 0,
-	    /* libs? */ 0, newlist, newlist_size) != 0) {
-		goto finish;
-	}
-	// "com.apple." library kexts
-	if (OSKext::saveLoadedKextPanicListTyped("com.apple.", /* invert? */ 0,
-	    /* libs? */ 1, newlist, newlist_size) != 0) {
-		goto finish;
-	}
-
-	if (loaded_kext_paniclist) {
-		kfree_data(loaded_kext_paniclist, loaded_kext_paniclist_size);
-	}
-	loaded_kext_paniclist = newlist;
-	newlist = NULL;
-	loaded_kext_paniclist_size = newlist_size;
-
+    char     * newlist        = NULL;
+    uint32_t   newlist_size   = 0;
+    
+    newlist_size = KEXT_PANICLIST_SIZE;
+    newlist = (char *)kalloc_tag(newlist_size, VM_KERN_MEMORY_OSKEXT);
+    
+    if (!newlist) {
+        OSKextLog(/* kext */ NULL,
+                  kOSKextLogErrorLevel | kOSKextLogGeneralFlag,
+                  "Couldn't allocate kext panic log buffer.");
+        goto finish;
+    }
+    
+    newlist[0] = '\0';
+    
+    // non-"com.apple." kexts
+    if (OSKext::saveLoadedKextPanicListTyped("com.apple.", /* invert? */ 1,
+                                             /* libs? */ -1, newlist, newlist_size) != 0) {
+        
+        goto finish;
+    }
+    // "com.apple." nonlibrary kexts
+    if (OSKext::saveLoadedKextPanicListTyped("com.apple.", /* invert? */ 0,
+                                             /* libs? */ 0, newlist, newlist_size) != 0) {
+        
+        goto finish;
+    }
+    // "com.apple." library kexts
+    if (OSKext::saveLoadedKextPanicListTyped("com.apple.", /* invert? */ 0,
+                                             /* libs? */ 1, newlist, newlist_size) != 0) {
+        
+        goto finish;
+    }
+    
+    if (loaded_kext_paniclist) {
+        kfree(loaded_kext_paniclist, loaded_kext_paniclist_size);
+    }
+    loaded_kext_paniclist = newlist;
+    newlist = NULL;
+    loaded_kext_paniclist_size = newlist_size;
+    
 finish:
-	if (newlist) {
-		kfree_data(newlist, newlist_size);
-	}
-	return;
-}
-
+    if (newlist) {
+        kfree(newlist, newlist_size);
+    }
+    return;
+}
+    
 /*********************************************************************
 * Assumes sKextLock is held.
 *********************************************************************/
 void
 OSKext::savePanicString(bool isLoading)
 {
-	u_long len;
-
-	if (!kmod_info) {
-		return;         // do not goto finish here b/c of lock
-	}
-
-	len = assemble_identifier_and_version( kmod_info,
-	    (isLoading) ? last_loaded_str_buf : last_unloaded_str_buf,
-	    (isLoading) ? sizeof(last_loaded_str_buf) : sizeof(last_unloaded_str_buf));
-	if (!len) {
-		printf("error saving unloaded kext info\n");
-		goto finish;
-	}
-
-	if (isLoading) {
-		last_loaded_strlen = len;
-		last_loaded_address = (void *)kmod_info->address;
-		last_loaded_size = kmod_info->size;
-		clock_get_uptime(&last_loaded_timestamp);
-	} else {
-		last_unloaded_strlen = len;
-		last_unloaded_address = (void *)kmod_info->address;
-		last_unloaded_size = kmod_info->size;
-		clock_get_uptime(&last_unloaded_timestamp);
-	}
+    u_long len;
+
+    if (!kmod_info) {
+        return;  // do not goto finish here b/c of lock
+    }
+
+    len = assemble_identifier_and_version( kmod_info,
+        (isLoading) ? last_loaded_str_buf : last_unloaded_str_buf,
+        (isLoading) ? sizeof(last_loaded_str_buf) : sizeof(last_unloaded_str_buf) );
+    if (!len) {
+        printf("error saving unloaded kext info\n");
+        goto finish;
+    }
+
+    if (isLoading) {
+        last_loaded_strlen = len;
+        last_loaded_address = (void *)kmod_info->address;
+        last_loaded_size = kmod_info->size;
+        clock_get_uptime(&last_loaded_timestamp);
+    } else {
+        last_unloaded_strlen = len;
+        last_unloaded_address = (void *)kmod_info->address;
+        last_unloaded_size = kmod_info->size;
+        clock_get_uptime(&last_unloaded_timestamp);
+    }
 
 finish:
-	return;
+    return;
 }
 
 /*********************************************************************
@@ -16350,39 +10816,32 @@
 void
 OSKext::printKextPanicLists(int (*printf_func)(const char *fmt, ...))
 {
-	if (last_loaded_strlen) {
-		printf_func("last started kext at %llu: %.*s (addr %p, size %lu)\n",
-		    AbsoluteTime_to_scalar(&last_loaded_timestamp),
-		    last_loaded_strlen, last_loaded_str_buf,
-		    last_loaded_address, last_loaded_size);
-	}
-
-	if (last_unloaded_strlen) {
-		printf_func("last stopped kext at %llu: %.*s (addr %p, size %lu)\n",
-		    AbsoluteTime_to_scalar(&last_unloaded_timestamp),
-		    last_unloaded_strlen, last_unloaded_str_buf,
-		    last_unloaded_address, last_unloaded_size);
-	}
-
-	/*
-	 * In most cases the set of loaded kexts is statically determined by the
-	 * Boot KC, so it isn't very interesting to see in the paniclog.
-	 */
-	if (auxKCloaded) {
-		printf_func("loaded kexts:\n");
-		if (loaded_kext_paniclist &&
-		    pmap_find_phys(kernel_pmap, (addr64_t) (uintptr_t) loaded_kext_paniclist) &&
-		    loaded_kext_paniclist[0]) {
-			printf_func("%.*s",
-			    strnlen(loaded_kext_paniclist, loaded_kext_paniclist_size),
-			    loaded_kext_paniclist);
-		} else {
-			printf_func("(none)\n");
-		}
-	} else {
-		printf_func("loaded kexts: (skipped, see boot kernelcache)\n");
-	}
-	return;
+    if (last_loaded_strlen) {
+        printf_func("last loaded kext at %llu: %.*s (addr %p, size %lu)\n",
+            AbsoluteTime_to_scalar(&last_loaded_timestamp),
+            last_loaded_strlen, last_loaded_str_buf,
+            last_loaded_address, last_loaded_size);
+    }
+
+    if (last_unloaded_strlen) {
+        printf_func("last unloaded kext at %llu: %.*s (addr %p, size %lu)\n",
+            AbsoluteTime_to_scalar(&last_unloaded_timestamp),
+            last_unloaded_strlen, last_unloaded_str_buf,
+            last_unloaded_address, last_unloaded_size);
+    }
+
+    printf_func("loaded kexts:\n");
+    if (loaded_kext_paniclist &&
+        pmap_find_phys(kernel_pmap, (addr64_t) (uintptr_t) loaded_kext_paniclist) &&
+        loaded_kext_paniclist[0]) {
+
+        printf_func("%.*s",
+                    strnlen(loaded_kext_paniclist, loaded_kext_paniclist_size),
+                    loaded_kext_paniclist);
+    } else {
+        printf_func("(none)\n");
+    }
+    return;
 }
 
 /*********************************************************************
@@ -16392,167 +10851,158 @@
 void
 OSKext::updateLoadedKextSummaries(void)
 {
-	kern_return_t result = KERN_FAILURE;
-	OSKextLoadedKextSummaryHeader *summaryHeader = NULL;
-	OSKextLoadedKextSummaryHeader *summaryHeaderAlloc = NULL;
-	OSKext *aKext;
-	vm_map_offset_t start;
-	size_t summarySize = 0;
-	size_t size;
-	u_int count;
-	u_int maxKexts;
-	u_int i, j;
-	OSKextActiveAccount * accountingList;
-	OSKextActiveAccount * prevAccountingList;
-	uint32_t idx, accountingListAlloc, accountingListCount, prevAccountingListCount;
-
-	prevAccountingList = NULL;
-	prevAccountingListCount = 0;
+    kern_return_t result = KERN_FAILURE;
+    OSKextLoadedKextSummaryHeader *summaryHeader = NULL;
+    OSKextLoadedKextSummaryHeader *summaryHeaderAlloc = NULL;
+    OSKext *aKext;
+    vm_map_offset_t start, end;
+    size_t summarySize = 0;
+    size_t size;
+    u_int count;
+    u_int maxKexts;
+    u_int i, j;
+    OSKextActiveAccount * accountingList;
+    OSKextActiveAccount * prevAccountingList;
+    uint32_t idx, accountingListAlloc, accountingListCount, prevAccountingListCount;
+    
+    prevAccountingList = NULL;
+    prevAccountingListCount = 0;
 
 #if DEVELOPMENT || DEBUG
-	if (IORecursiveLockHaveLock(sKextLock) == false) {
-		panic("sKextLock must be held");
+    if (IORecursiveLockHaveLock(sKextLock) == false) {
+        panic("sKextLock must be held");
+    }
+#endif
+    
+    IOLockLock(sKextSummariesLock);
+    
+    count = sLoadedKexts->getCount();
+    for (i = 0, maxKexts = 0; i < count; ++i) {
+        aKext = OSDynamicCast(OSKext, sLoadedKexts->getObject(i));
+        maxKexts += (aKext && aKext->isExecutable());
+    }
+    
+    if (!maxKexts) goto finish;
+    if (maxKexts < kOSKextTypicalLoadCount) maxKexts = kOSKextTypicalLoadCount;
+    
+    /* Calculate the size needed for the new summary headers.
+     */
+    
+    size = sizeof(*gLoadedKextSummaries);
+    size += maxKexts * sizeof(*gLoadedKextSummaries->summaries);
+    size = round_page(size);
+    
+    if (gLoadedKextSummaries == NULL || sLoadedKextSummariesAllocSize < size) {
+        if (gLoadedKextSummaries) {
+            kmem_free(kernel_map,
+                      (vm_offset_t)gLoadedKextSummaries,
+                      sLoadedKextSummariesAllocSize);
+            gLoadedKextSummaries = NULL;
+            sLoadedKextSummariesAllocSize = 0;
+        }
+        result = kmem_alloc(kernel_map,
+                            (vm_offset_t*)&summaryHeaderAlloc,
+                            size, VM_KERN_MEMORY_OSKEXT);
+        if (result != KERN_SUCCESS) goto finish;
+        summaryHeader = summaryHeaderAlloc;
+        summarySize = size;
+    }
+    else {
+        summaryHeader = gLoadedKextSummaries;
+        summarySize = sLoadedKextSummariesAllocSize;
+        
+        start = (vm_map_offset_t) summaryHeader;
+        end = start + summarySize;
+        result = vm_map_protect(kernel_map,
+                                start,
+                                end,
+                                VM_PROT_DEFAULT,
+                                FALSE);
+        if (result != KERN_SUCCESS) goto finish;
+    }
+    
+    /* Populate the summary header.
+     */
+    
+    bzero(summaryHeader, summarySize);
+    summaryHeader->version = kOSKextLoadedKextSummaryVersion;
+    summaryHeader->entry_size = sizeof(OSKextLoadedKextSummary);
+
+    /* Populate each kext summary.
+     */
+    
+    count = sLoadedKexts->getCount();
+    accountingListAlloc = 0;
+    for (i = 0, j = 0; i < count && j < maxKexts; ++i) {
+        aKext = OSDynamicCast(OSKext, sLoadedKexts->getObject(i));
+        if (!aKext || !aKext->isExecutable()) {
+            continue;
+        }
+        
+        aKext->updateLoadedKextSummary(&summaryHeader->summaries[j++]);
+        summaryHeader->numSummaries++;
+	accountingListAlloc++;
+    }
+
+    accountingList = IONew(typeof(accountingList[0]), accountingListAlloc);
+    accountingListCount = 0;
+    for (i = 0, j = 0; i < count && j < maxKexts; ++i) {
+        aKext = OSDynamicCast(OSKext, sLoadedKexts->getObject(i));
+        if (!aKext || !aKext->isExecutable()) {
+            continue;
+        }
+
+	OSKextActiveAccount activeAccount;
+	aKext->updateActiveAccount(&activeAccount);
+	// order by address
+	for (idx = 0; idx < accountingListCount; idx++)
+	{
+	    if (activeAccount.address < accountingList[idx].address) break;
 	}
-#endif
-
-	IOLockLock(sKextSummariesLock);
-
-	count = sLoadedKexts->getCount();
-	for (i = 0, maxKexts = 0; i < count; ++i) {
-		aKext = OSDynamicCast(OSKext, sLoadedKexts->getObject(i));
-		maxKexts += (aKext && (aKext->isExecutable() || aKext->isSpecialKernelBinary()));
-	}
-
-	if (!maxKexts) {
-		goto finish;
-	}
-	if (maxKexts < kOSKextTypicalLoadCount) {
-		maxKexts = kOSKextTypicalLoadCount;
-	}
-
-	/* Calculate the size needed for the new summary headers.
-	 */
-
-	size = sizeof(*gLoadedKextSummaries);
-	size += maxKexts * sizeof(*gLoadedKextSummaries->summaries);
-	size = round_page(size);
-
-	if (gLoadedKextSummaries == NULL || sLoadedKextSummariesAllocSize < size) {
-		if (gLoadedKextSummaries) {
-			kmem_free(kernel_map, (vm_offset_t)gLoadedKextSummaries, sLoadedKextSummariesAllocSize);
-			gLoadedKextSummaries = NULL;
-			gLoadedKextSummariesTimestamp = mach_absolute_time();
-			sLoadedKextSummariesAllocSize = 0;
-		}
-		result = kmem_alloc(kernel_map, (vm_offset_t *)&summaryHeaderAlloc, size,
-		    KMA_NONE, VM_KERN_MEMORY_OSKEXT);
-		if (result != KERN_SUCCESS) {
-			goto finish;
-		}
-		summaryHeader = summaryHeaderAlloc;
-		summarySize = size;
-	} else {
-		summaryHeader = gLoadedKextSummaries;
-		summarySize = sLoadedKextSummariesAllocSize;
-
-		start = (vm_map_offset_t) summaryHeader;
-		result = mach_vm_protect(kernel_map,
-		    start,
-		    summarySize,
-		    false,
-		    VM_PROT_DEFAULT);
-		if (result != KERN_SUCCESS) {
-			goto finish;
-		}
-	}
-
-	/* Populate the summary header.
-	 */
-
-	bzero(summaryHeader, summarySize);
-	summaryHeader->version = kOSKextLoadedKextSummaryVersion;
-	summaryHeader->entry_size = sizeof(OSKextLoadedKextSummary);
-
-	/* Populate each kext summary.
-	 */
-
-	count = sLoadedKexts->getCount();
-	accountingListAlloc = 0;
-	for (i = 0, j = 0; i < count && j < maxKexts; ++i) {
-		aKext = OSDynamicCast(OSKext, sLoadedKexts->getObject(i));
-		if (!aKext || (!aKext->isExecutable() && !aKext->isSpecialKernelBinary())) {
-			continue;
-		}
-
-		aKext->updateLoadedKextSummary(&summaryHeader->summaries[j++]);
-		summaryHeader->numSummaries++;
-		accountingListAlloc++;
-	}
-
-	accountingList = IONew(typeof(accountingList[0]), accountingListAlloc);
-	accountingListCount = 0;
-	for (i = 0, j = 0; i < count && j < maxKexts; ++i) {
-		aKext = OSDynamicCast(OSKext, sLoadedKexts->getObject(i));
-		if (!aKext || (!aKext->isExecutable() && !aKext->isSpecialKernelBinary())) {
-			continue;
-		}
-
-		OSKextActiveAccount activeAccount;
-		aKext->updateActiveAccount(&activeAccount);
-		// order by address
-		for (idx = 0; idx < accountingListCount; idx++) {
-			if (activeAccount.address < accountingList[idx].address) {
-				break;
-			}
-		}
-		bcopy(&accountingList[idx], &accountingList[idx + 1], (accountingListCount - idx) * sizeof(accountingList[0]));
-		accountingList[idx] = activeAccount;
-		accountingListCount++;
-	}
-	assert(accountingListCount == accountingListAlloc);
-	/* Write protect the buffer and move it into place.
-	 */
-
-	start = (vm_map_offset_t) summaryHeader;
-
-	result = mach_vm_protect(kernel_map, start, summarySize, false, VM_PROT_READ);
-	if (result != KERN_SUCCESS) {
-		goto finish;
-	}
-
-	gLoadedKextSummaries = summaryHeader;
-	gLoadedKextSummariesTimestamp = mach_absolute_time();
-	sLoadedKextSummariesAllocSize = summarySize;
-	summaryHeaderAlloc = NULL;
-
-	/* Call the magic breakpoint function through a static function pointer so
-	 * the compiler can't optimize the function away.
-	 */
-	if (sLoadedKextSummariesUpdated) {
-		(*sLoadedKextSummariesUpdated)();
-	}
-
-	lck_ticket_lock(sKextAccountsLock, sKextAccountsLockGrp);
-	prevAccountingList      = sKextAccounts;
-	prevAccountingListCount = sKextAccountsCount;
-	sKextAccounts           = accountingList;
-	sKextAccountsCount      = accountingListCount;
-	lck_ticket_unlock(sKextAccountsLock);
+	bcopy(&accountingList[idx], &accountingList[idx + 1], (accountingListCount - idx) * sizeof(accountingList[0]));
+	accountingList[idx] = activeAccount;
+	accountingListCount++;
+    }
+    assert(accountingListCount == accountingListAlloc);
+    /* Write protect the buffer and move it into place.
+     */
+    
+    start = (vm_map_offset_t) summaryHeader;
+    end = start + summarySize;
+    
+    result = vm_map_protect(kernel_map, start, end, VM_PROT_READ, FALSE);
+    if (result != KERN_SUCCESS) goto finish;
+    
+    gLoadedKextSummaries = summaryHeader;
+    sLoadedKextSummariesAllocSize = summarySize;
+    summaryHeaderAlloc = NULL;
+    
+   /* Call the magic breakpoint function through a static function pointer so
+    * the compiler can't optimize the function away.
+    */
+    if (sLoadedKextSummariesUpdated) (*sLoadedKextSummariesUpdated)();
+
+    IOSimpleLockLock(sKextAccountsLock);
+    prevAccountingList      = sKextAccounts;
+    prevAccountingListCount = sKextAccountsCount;
+    sKextAccounts           = accountingList;
+    sKextAccountsCount      = accountingListCount;
+    IOSimpleLockUnlock(sKextAccountsLock);
 
 finish:
-	IOLockUnlock(sKextSummariesLock);
-
-	/* If we had to allocate a new buffer but failed to generate the summaries,
-	 * free that now.
-	 */
-	if (summaryHeaderAlloc) {
-		kmem_free(kernel_map, (vm_offset_t)summaryHeaderAlloc, summarySize);
-	}
-	if (prevAccountingList) {
-		IODelete(prevAccountingList, typeof(accountingList[0]), prevAccountingListCount);
-	}
-
-	return;
+    IOLockUnlock(sKextSummariesLock);
+
+   /* If we had to allocate a new buffer but failed to generate the summaries,
+    * free that now.
+    */
+    if (summaryHeaderAlloc) {
+        kmem_free(kernel_map, (vm_offset_t)summaryHeaderAlloc, summarySize);
+    }
+    if (prevAccountingList) {
+        IODelete(prevAccountingList, typeof(accountingList[0]), prevAccountingListCount);
+    }
+
+    return;
 }
 
 /*********************************************************************
@@ -16560,467 +11010,149 @@
 void
 OSKext::updateLoadedKextSummary(OSKextLoadedKextSummary *summary)
 {
-	OSSharedPtr<OSData> uuid;
-
-	strlcpy(summary->name, getIdentifierCString(),
-	    sizeof(summary->name));
-
-	uuid = copyUUID();
-	if (uuid) {
-		memcpy(summary->uuid, uuid->getBytesNoCopy(), sizeof(summary->uuid));
+    OSData *uuid;
+
+    strlcpy(summary->name, getIdentifierCString(), 
+        sizeof(summary->name));
+
+    uuid = copyUUID();
+    if (uuid) {
+        memcpy(summary->uuid, uuid->getBytesNoCopy(), sizeof(summary->uuid));
+        OSSafeRelease(uuid);
+    }
+
+    summary->address = kmod_info->address;
+    summary->size = kmod_info->size;
+    summary->version = getVersion();
+    summary->loadTag = kmod_info->id;
+    summary->flags = 0;
+    summary->reference_list = (uint64_t) kmod_info->reference_list;
+
+    return;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+void
+OSKext::updateActiveAccount(OSKextActiveAccount *account)
+{
+    bzero(account, sizeof(*account));
+    account->address = kmod_info->address;
+    if (account->address) {
+        account->address_end = kmod_info->address + kmod_info->size;
+    }
+    account->account = this->account;
+}
+
+extern "C" const vm_allocation_site_t * 
+OSKextGetAllocationSiteForCaller(uintptr_t address)
+{
+    OSKextActiveAccount *  active;
+    vm_allocation_site_t * site;
+    uint32_t baseIdx;
+    uint32_t lim;
+
+    IOSimpleLockLock(sKextAccountsLock);
+    site = NULL;
+    // bsearch sKextAccounts list
+    for (baseIdx = 0, lim = sKextAccountsCount; lim; lim >>= 1)
+    {
+	active = &sKextAccounts[baseIdx + (lim >> 1)];
+	if ((address >= active->address) && (address < active->address_end))
+	{
+	    site = &active->account->site;
+	    if (!site->tag) vm_tag_alloc_locked(site);
+	    break;
 	}
-
-	if (flags.builtin) {
-//      this value will stop lldb from parsing the mach-o header
-//      summary->address = UINT64_MAX;
-//      summary->size = 0;
-		summary->address = kmod_info->address;
-		summary->size = kmod_info->size;
-	} else {
-		summary->address = kmod_info->address;
-		summary->size = kmod_info->size;
+	else if (address > active->address) 
+	{	
+	    // move right
+	    baseIdx += (lim >> 1) + 1;
+	    lim--;
 	}
-	summary->version = getVersion();
-	summary->loadTag = kmod_info->id;
-	summary->flags = 0;
-	summary->reference_list = (uint64_t) kmod_info->reference_list;
-
-	summary->text_exec_address = (uint64_t) getsegdatafromheader((kernel_mach_header_t *)summary->address, "__TEXT_EXEC", &summary->text_exec_size);
-	if (summary->text_exec_address == 0) {
-		// Fallback to __TEXT
-		summary->text_exec_address = (uint64_t) getsegdatafromheader((kernel_mach_header_t *)summary->address, "__TEXT", &summary->text_exec_size);
-	}
-
-	/**
-	 * If the addresses within the Mach-O are unslid, then manually slide any
-	 * addresses coming from the Mach-O as higher layer software using these
-	 * summaries expects a slid address here.
-	 */
-	if (flags.unslidMachO) {
-		summary->text_exec_address = (uint64_t) ml_static_slide((vm_offset_t) summary->text_exec_address);
-	}
-
-	return;
-}
-
-/*********************************************************************
-*********************************************************************/
-
-void
-OSKext::updateActiveAccount(OSKextActiveAccount *accountp)
-{
-	kernel_mach_header_t     *hdr = NULL;
-	kernel_segment_command_t *seg = NULL;
-
-	bzero(accountp, sizeof(*accountp));
-
-	hdr = (kernel_mach_header_t *)kmod_info->address;
-	if (getcommandfromheader(hdr, LC_SEGMENT_SPLIT_INFO) || isInFileset()) {
-		/*
-		 * If this kext supports split segments (or is in a new
-		 * MH_FILESET kext collection), use the first
-		 * executable segment as the range for instructions
-		 * (and thus for backtracing.
-		 */
-		for (seg = firstsegfromheader(hdr); seg != NULL; seg = nextsegfromheader(hdr, seg)) {
-			if (seg->initprot & VM_PROT_EXECUTE) {
-				break;
-			}
-		}
-	}
-	if (seg) {
-		accountp->address = seg->vmaddr;
-		if (accountp->address) {
-			accountp->address_end = seg->vmaddr + seg->vmsize;
-		}
-	} else {
-		/* For non-split kexts and for kexts without executable
-		 * segments, just use the kmod_info range (as the kext
-		 * is either all in one range or should not show up in
-		 * instruction backtraces).
-		 */
-		accountp->address = kmod_info->address;
-		if (accountp->address) {
-			accountp->address_end = kmod_info->address + kmod_info->size;
-		}
-	}
-
-	accountp->account = this->account;
-}
-
-bool
-OSKext::isDriverKit(void)
-{
-	OSString *bundleType;
-
-	if (infoDict) {
-		bundleType = OSDynamicCast(OSString, infoDict->getObject(kCFBundlePackageTypeKey));
-		if (bundleType && bundleType->isEqualTo(kOSKextBundlePackageTypeDriverKit)) {
-			return TRUE;
-		}
-	}
-	return FALSE;
-}
-
-bool
-OSKext::isInFileset(void)
-{
-	if (!kmod_info) {
-		goto check_prelinked;
-	}
-
-	if (kmod_info->address && kernel_mach_header_is_in_fileset((kernel_mach_header_t *)kmod_info->address)) {
-		return true;
-	}
-
-check_prelinked:
-	if (isPrelinked()) {
-		/*
-		 * If we haven't setup kmod_info yet, but we know
-		 * we're loading a prelinked kext in an MH_FILESET KC,
-		 * then return true
-		 */
-		kc_format_t kc_format;
-		if (PE_get_primary_kc_format(&kc_format) && kc_format == KCFormatFileset) {
-			return true;
-		}
-	}
-	return false;
-}
-
-OSSharedPtr<OSDextStatistics>
-OSKext::copyDextStatistics(void)
-{
-	return dextStatistics;
-}
-
-bool
-OSKextSavedMutableSegment::initWithSegment(kernel_segment_command_t *seg)
-{
-	kern_return_t result;
-	if (!super::init()) {
-		return false;
-	}
-	if (seg == nullptr) {
-		return false;
-	}
-	result = kmem_alloc(kernel_map, (vm_offset_t *)&data, seg->vmsize,
-	    KMA_PAGEABLE, VM_KERN_MEMORY_KEXT);
-	if (result != KERN_SUCCESS) {
-		return false;
-	}
-	memcpy((void *)data, (const void *)seg->vmaddr, seg->vmsize);
-	savedSegment = seg;
-	vmsize = seg->vmsize;
-	vmaddr = seg->vmaddr;
-	return true;
-}
-
-OSSharedPtr<OSKextSavedMutableSegment>
-OSKextSavedMutableSegment::withSegment(kernel_segment_command_t *seg)
-{
-	OSSharedPtr<OSKextSavedMutableSegment> me = OSMakeShared<OSKextSavedMutableSegment>();
-	if (me && !me->initWithSegment(seg)) {
-		return nullptr;
-	}
-	return me;
-}
-
-void
-OSKextSavedMutableSegment::free(void)
-{
-	if (data) {
-		kmem_free(kernel_map, (vm_offset_t)data, vmsize);
-	}
-}
-
-vm_offset_t
-OSKextSavedMutableSegment::getVMAddr() const
-{
-	return vmaddr;
-}
-
-vm_offset_t
-OSKextSavedMutableSegment::getVMSize() const
-{
-	return vmsize;
-}
-
-OSReturn
-OSKextSavedMutableSegment::restoreContents(kernel_segment_command_t *seg)
-{
-	if (seg != savedSegment) {
-		return kOSKextReturnInvalidArgument;
-	}
-	if (seg->vmaddr != vmaddr || seg->vmsize != vmsize) {
-		return kOSKextReturnInvalidArgument;
-	}
-	memcpy((void *)seg->vmaddr, data, vmsize);
-	return kOSReturnSuccess;
-}
-
-extern "C" kern_return_t
-OSKextSetReceiptQueried(void)
-{
-	OSKextLog(/* kext */ NULL,
-	    kOSKextLogStepLevel | kOSKextLogGeneralFlag,
-	    "Setting kext receipt as queried");
-
-	IOService::publishResource(kOSKextReceiptQueried, kOSBooleanTrue);
-	return KERN_SUCCESS;
-}
-
-extern "C" const vm_allocation_site_t *
-OSKextGetAllocationSiteForCaller(uintptr_t address)
-{
-	OSKextActiveAccount *  active;
-	vm_allocation_site_t * site;
-	vm_allocation_site_t * releasesite;
-
-	uint32_t baseIdx;
-	uint32_t lim;
-#if  __has_feature(ptrauth_calls)
-	address = (uintptr_t)VM_KERNEL_STRIP_PTR(address);
-#endif /*  __has_feature(ptrauth_calls) */
-
-	lck_ticket_lock(sKextAccountsLock, sKextAccountsLockGrp);
-	site = releasesite = NULL;
-
-	// bsearch sKextAccounts list
-	for (baseIdx = 0, lim = sKextAccountsCount; lim; lim >>= 1) {
-		active = &sKextAccounts[baseIdx + (lim >> 1)];
-		if ((address >= active->address) && (address < active->address_end)) {
-			site = &active->account->site;
-			if (!site->tag) {
-				vm_tag_alloc_locked(site, &releasesite);
-			}
-			break;
-		} else if (address > active->address) {
-			// move right
-			baseIdx += (lim >> 1) + 1;
-			lim--;
-		}
-		// else move left
-	}
-	lck_ticket_unlock(sKextAccountsLock);
-	if (releasesite) {
-		kern_allocation_name_release(releasesite);
-	}
-
-	return site;
-}
-
-#if DEVELOPMENT || DEBUG
-extern "C" void
-OSKextGetRefGrpForCaller(uintptr_t address, void (^cb)(struct os_refgrp *))
-{
-	OSKextActiveAccount *  active;
-
-	uint32_t baseIdx;
-	uint32_t lim;
-#if  __has_feature(ptrauth_calls)
-	address = (uintptr_t)VM_KERNEL_STRIP_PTR(address);
-#endif /*  __has_feature(ptrauth_calls) */
-
-	lck_ticket_lock(sKextAccountsLock, sKextAccountsLockGrp);
-
-	// bsearch sKextAccounts list
-	for (baseIdx = 0, lim = sKextAccountsCount; lim; lim >>= 1) {
-		active = &sKextAccounts[baseIdx + (lim >> 1)];
-		if ((address >= active->address) && (address < active->address_end)) {
-			cb(&active->account->task_refgrp);
-			break;
-		} else if (address > active->address) {
-			// move right
-			baseIdx += (lim >> 1) + 1;
-			lim--;
-		}
-		// else move left
-	}
-	lck_ticket_unlock(sKextAccountsLock);
-}
-#endif /* DEVELOPMENT || DEBUG */
-
-extern "C" uint32_t
-OSKextGetKmodIDForSite(const vm_allocation_site_t * site, char * name, vm_size_t namelen)
-{
-	OSKextAccount * account = (typeof(account))site;
-	const char    * kname;
-
-	if (name) {
-		if (account->kext) {
-			kname = account->kext->getIdentifierCString();
-		} else {
-			kname = "<>";
-		}
-		strlcpy(name, kname, namelen);
-	}
-
-	return account->loadTag;
-}
-
-extern "C" void
+	// else move left
+    }
+    IOSimpleLockUnlock(sKextAccountsLock);
+
+    return (site);
+}
+
+extern "C" uint32_t 
+OSKextGetKmodIDForSite(vm_allocation_site_t * site)
+{
+    OSKextAccount * account = (typeof(account)) site;
+    return (account->loadTag);
+}
+
+extern "C" void 
 OSKextFreeSite(vm_allocation_site_t * site)
 {
-	OSKextAccount * freeAccount = (typeof(freeAccount))site;
-	IOFreeType(freeAccount, OSKextAccount);
-}
-
-/*********************************************************************
-*********************************************************************/
-
-#if CONFIG_IMAGEBOOT
-int
-OSKextGetUUIDForName(const char *name, uuid_t uuid)
-{
-	OSSharedPtr<OSKext> kext = OSKext::lookupKextWithIdentifier(name);
-	if (!kext) {
-		return 1;
-	}
-
-	OSSharedPtr<OSData> uuid_data = kext->copyUUID();
-	if (uuid_data) {
-		memcpy(uuid, uuid_data->getBytesNoCopy(), sizeof(uuid_t));
-		return 0;
-	}
-
-	return 1;
-}
+    OSKextAccount * freeAccount = (typeof(freeAccount)) site;
+    IODelete(freeAccount, OSKextAccount, 1);
+}
+
+/*********************************************************************
+*********************************************************************/
+    
+#if CONFIG_KEC_FIPS
+    
+#if PRAGMA_MARK
+#pragma mark Kernel External Components for FIPS compliance
 #endif
-
-
-
-class OSDextCrash : public OSObject {
-	OSDeclareDefaultStructors(OSDextCrash);
-public:
-	static OSPtr<OSDextCrash> withTimestamp(uint64_t timestamp);
-	uint64_t getTimestamp();
-
-private:
-	virtual bool initWithTimestamp(uint64_t timestamp);
-	uint64_t fTimestamp;
-};
-
-OSDefineMetaClassAndStructors(OSDextCrash, OSObject);
-
-OSSharedPtr<OSDextCrash>
-OSDextCrash::withTimestamp(uint64_t timestamp)
-{
-	OSSharedPtr<OSDextCrash> result = OSMakeShared<OSDextCrash>();
-	if (!result->initWithTimestamp(timestamp)) {
-		return NULL;
-	}
-	return result;
-}
-
-bool
-OSDextCrash::initWithTimestamp(uint64_t timestamp)
-{
-	if (!OSObject::init()) {
-		return false;
-	}
-	fTimestamp = timestamp;
-	return true;
-}
-
-uint64_t
-OSDextCrash::getTimestamp()
-{
-	return fTimestamp;
-}
-
-OSSharedPtr<OSDextStatistics>
-OSDextStatistics::create()
-{
-	OSSharedPtr<OSDextStatistics> result = OSMakeShared<OSDextStatistics>();
-	if (!result->init()) {
-		return NULL;
-	}
-	return result;
-}
-
-bool
-OSDextStatistics::init()
-{
-	if (!OSObject::init()) {
-		return false;
-	}
-
-	lock = IOLockAlloc();
-	crashes = OSArray::withCapacity(kMaxDextCrashesInOneDay);
-	return true;
-}
-
-void
-OSDextStatistics::free()
-{
-	if (lock) {
-		IOLockFree(lock);
-	}
-	crashes.reset();
-	OSObject::free();
-}
-
-OSDextCrashPolicy
-OSDextStatistics::recordCrash()
-{
-	size_t i = 0;
-	uint64_t timestamp = mach_continuous_time();
-	uint64_t interval;
-	nanoseconds_to_absolutetime(86400 * NSEC_PER_SEC /* 1 day */, &interval);
-	uint64_t lastTimestamp = timestamp > interval ? timestamp - interval : 0;
-	OSDextCrashPolicy policy;
-
-	IOLockLock(lock);
-	OSSharedPtr<OSDextCrash> crash = OSDextCrash::withTimestamp(timestamp);
-	for (i = 0; i < crashes->getCount();) {
-		OSDextCrash * current = OSDynamicCast(OSDextCrash, crashes->getObject(i));
-		assert(current != NULL);
-		if (current->getTimestamp() < lastTimestamp) {
-			crashes->removeObject(i);
-		} else {
-			i++;
-		}
-	}
-
-	crashes->setObject(crash);
-
-	if (crashes->getCount() > kMaxDextCrashesInOneDay) {
-		policy = kOSDextCrashPolicyReboot;
-	} else {
-		policy = kOSDextCrashPolicyNone;
-	}
-
-	IOLockUnlock(lock);
-
-	return policy;
-}
-
-size_t
-OSDextStatistics::getCrashCount()
-{
-	size_t result = 0;
-	IOLockLock(lock);
-	result = crashes->getCount();
-	IOLockUnlock(lock);
-	return result;
-}
-
-static int
-sysctl_willuserspacereboot
-(__unused struct sysctl_oid *oidp, __unused void *arg1, __unused int arg2, struct sysctl_req *req)
-{
-	int new_value = 0, old_value = get_system_inuserspacereboot(), changed = 0;
-	int error = sysctl_io_number(req, old_value, sizeof(int), &new_value, &changed);
-	if (error) {
-		return error;
-	}
-	if (changed) {
-		OSKext::setWillUserspaceReboot();
-	}
-	return 0;
-}
-
-static SYSCTL_PROC(_kern, OID_AUTO, willuserspacereboot,
-    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_LOCKED,
-    NULL, 0, sysctl_willuserspacereboot, "I", "");
+    
+/*********************************************************************
+ * Kernel External Components for FIPS compliance (KEC_FIPS)
+ *********************************************************************/
+static void * 
+GetAppleTEXTHashForKext(OSKext * theKext, OSDictionary *theInfoDict)
+{
+    AppleTEXTHash_t         my_ath = {1, 0, NULL};
+    AppleTEXTHash_t *       my_athp = NULL;         // do not release
+    OSDictionary *          textHashDict = NULL;    // do not release
+    OSData *                segmentHash = NULL;     // do not release
+    
+    if (theKext == NULL || theInfoDict == NULL) {
+        return(NULL);
+    }
+    
+    textHashDict = OSDynamicCast(OSDictionary, theInfoDict->getObject(kAppleTextHashesKey));
+    if (textHashDict == NULL) {
+        return(NULL);
+    }
+    
+    segmentHash = OSDynamicCast(OSData,
+                                textHashDict->getObject(ARCHNAME));
+    if (segmentHash == NULL) {
+        return(NULL);
+    }
+    
+    // KEC_FIPS type kexts never unload so we don't have to clean up our 
+    // AppleTEXTHash_t
+    if (kmem_alloc(kernel_map, (vm_offset_t *) &my_athp, 
+                   sizeof(AppleTEXTHash_t), VM_KERN_MEMORY_OSKEXT) != KERN_SUCCESS) {
+        return(NULL);
+    }
+    
+    memcpy(my_athp, &my_ath, sizeof(my_ath));
+    my_athp->ath_length = segmentHash->getLength();
+    if (my_athp->ath_length > 0) {
+        my_athp->ath_hash = (void *)segmentHash->getBytesNoCopy();
+    }
+        
+#if 0
+    OSKextLog(theKext,
+              kOSKextLogErrorLevel |
+              kOSKextLogGeneralFlag,
+              "Kext %s ath_version %d ath_length %d ath_hash %p",
+              theKext->getIdentifierCString(), 
+              my_athp->ath_version,
+              my_athp->ath_length,
+              my_athp->ath_hash); 
+#endif
+        
+    return( (void *) my_athp );
+}
+    
+#endif // CONFIG_KEC_FIPS
+