]> git.saurik.com Git - apple/xnu.git/blobdiff - libkern/kxld/kxld_reloc.c
xnu-7195.101.1.tar.gz
[apple/xnu.git] / libkern / kxld / kxld_reloc.c
index bb93003a85c6631ce3d5a69d77ec0e50e28aad21..f9a9b850d02f749de770d4340a10f71c0c00601e 100644 (file)
@@ -1,8 +1,8 @@
 /*
 /*
- * Copyright (c) 2007-2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2007-2020 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
  * @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
  * 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
  * 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.
  * 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.
  * 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,
  * 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,
  * 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.
  * 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@
  */
 #include <string.h>
 #include <mach/boolean.h>
 #include <sys/types.h>
  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 #include <string.h>
 #include <mach/boolean.h>
 #include <sys/types.h>
+#include <os/base.h>
 
 #if KERNEL
     #include <libkern/libkern.h>
 
 #if KERNEL
     #include <libkern/libkern.h>
@@ -36,9 +37,9 @@
     #include <stdlib.h>
     #include <libkern/OSByteOrder.h>
 
     #include <stdlib.h>
     #include <libkern/OSByteOrder.h>
 
-    /* Get machine.h from the kernel source so we can support all platforms
    * that the kernel supports. Otherwise we're at the mercy of the host.
    */
+/* Get machine.h from the kernel source so we can support all platforms
+ * that the kernel supports. Otherwise we're at the mercy of the host.
+ */
     #include "../../osfmk/mach/machine.h"
 #endif
 
     #include "../../osfmk/mach/machine.h"
 #endif
 
 #include <mach-o/arm64/reloc.h>
 #endif
 
 #include <mach-o/arm64/reloc.h>
 #endif
 
+extern uint32_t     kaslr_offsets_index;
+extern uint32_t     kaslr_offsets_count;
+extern uint32_t    *kaslr_offsets;
+
 #define KXLD_TARGET_NONE        (u_int) 0x0
 #define KXLD_TARGET_VALUE       (u_int) 0x1
 #define KXLD_TARGET_SECTNUM     (u_int) 0x2
 #define KXLD_TARGET_NONE        (u_int) 0x0
 #define KXLD_TARGET_VALUE       (u_int) 0x1
 #define KXLD_TARGET_SECTNUM     (u_int) 0x2
 #define FLIP_PREDICT_BIT(x) x ^= 0x00200000
 
 #define SIGN_EXTEND_MASK(n) (1 << ((n) - 1))
 #define FLIP_PREDICT_BIT(x) x ^= 0x00200000
 
 #define SIGN_EXTEND_MASK(n) (1 << ((n) - 1))
-#define SIGN_EXTEND(x,n) (((x) ^ SIGN_EXTEND_MASK(n)) - SIGN_EXTEND_MASK(n))
+#define SIGN_EXTEND(x, n) (((x) ^ SIGN_EXTEND_MASK(n)) - SIGN_EXTEND_MASK(n))
 #define BR14_NBITS_DISPLACEMENT 16
 #define BR24_NBITS_DISPLACEMENT 26
 
 #define BR14_NBITS_DISPLACEMENT 16
 #define BR24_NBITS_DISPLACEMENT 26
 
 * Prototypes
 *******************************************************************************/
 #if KXLD_USER_OR_I386
 * Prototypes
 *******************************************************************************/
 #if KXLD_USER_OR_I386
-static boolean_t generic_reloc_has_pair(u_int _type) 
-    __attribute__((const));
+static boolean_t generic_reloc_has_pair(u_int _type)
+__attribute__((const));
 static u_int generic_reloc_get_pair_type(u_int _prev_type)
 static u_int generic_reloc_get_pair_type(u_int _prev_type)
-    __attribute__((const));
+__attribute__((const));
 static boolean_t generic_reloc_has_got(u_int _type)
 static boolean_t generic_reloc_has_got(u_int _type)
-    __attribute__((const));
+__attribute__((const));
 static kern_return_t generic_process_reloc(const KXLDRelocator *relocator,
 static kern_return_t generic_process_reloc(const KXLDRelocator *relocator,
-    u_char *instruction, u_int length, u_int pcrel, kxld_addr_t base_pc, 
-    kxld_addr_t link_pc, kxld_addr_t link_disp, u_int type, kxld_addr_t target, 
+    u_char *instruction, u_int length, u_int pcrel, kxld_addr_t base_pc,
+    kxld_addr_t link_pc, kxld_addr_t link_disp, u_int type, kxld_addr_t target,
     kxld_addr_t pair_target, boolean_t swap);
 #endif /* KXLD_USER_OR_I386 */
 
     kxld_addr_t pair_target, boolean_t swap);
 #endif /* KXLD_USER_OR_I386 */
 
-#if KXLD_USER_OR_X86_64 
-static boolean_t x86_64_reloc_has_pair(u_int _type) 
-    __attribute__((const));
-static u_int x86_64_reloc_get_pair_type(u_int _prev_type) 
-    __attribute__((const));
+#if KXLD_USER_OR_X86_64
+static boolean_t x86_64_reloc_has_pair(u_int _type)
+__attribute__((const));
+static u_int x86_64_reloc_get_pair_type(u_int _prev_type)
+__attribute__((const));
 static boolean_t x86_64_reloc_has_got(u_int _type)
 static boolean_t x86_64_reloc_has_got(u_int _type)
-    __attribute__((const));
-static kern_return_t x86_64_process_reloc(const KXLDRelocator *relocator, 
-    u_char *instruction, u_int length, u_int pcrel, kxld_addr_t base_pc, 
-    kxld_addr_t link_pc, kxld_addr_t link_disp, u_int type, kxld_addr_t target, 
+__attribute__((const));
+static kern_return_t x86_64_process_reloc(const KXLDRelocator *relocator,
+    u_char *instruction, u_int length, u_int pcrel, kxld_addr_t base_pc,
+    kxld_addr_t link_pc, kxld_addr_t link_disp, u_int type, kxld_addr_t target,
     kxld_addr_t pair_target, boolean_t swap);
     kxld_addr_t pair_target, boolean_t swap);
-static kern_return_t calculate_displacement_x86_64(uint64_t target, 
+static kern_return_t calculate_displacement_x86_64(uint64_t target,
     uint64_t adjustment, int32_t *instr32);
 #endif /* KXLD_USER_OR_X86_64 */
 
 #if KXLD_USER_OR_ARM
     uint64_t adjustment, int32_t *instr32);
 #endif /* KXLD_USER_OR_X86_64 */
 
 #if KXLD_USER_OR_ARM
-static boolean_t arm_reloc_has_pair(u_int _type) 
-    __attribute__((const));
-static u_int arm_reloc_get_pair_type(u_int _prev_type) 
-    __attribute__((const));
+static boolean_t arm_reloc_has_pair(u_int _type)
+__attribute__((const));
+static u_int arm_reloc_get_pair_type(u_int _prev_type)
+__attribute__((const));
 static boolean_t arm_reloc_has_got(u_int _type)
 static boolean_t arm_reloc_has_got(u_int _type)
-    __attribute__((const));
-static kern_return_t arm_process_reloc(const KXLDRelocator *relocator, 
-    u_char *instruction, u_int length, u_int pcrel, kxld_addr_t base_pc, 
-    kxld_addr_t link_pc, kxld_addr_t link_disp, u_int type, kxld_addr_t target, 
+__attribute__((const));
+static kern_return_t arm_process_reloc(const KXLDRelocator *relocator,
+    u_char *instruction, u_int length, u_int pcrel, kxld_addr_t base_pc,
+    kxld_addr_t link_pc, kxld_addr_t link_disp, u_int type, kxld_addr_t target,
     kxld_addr_t pair_target, boolean_t swap);
 #endif /* KXLD_USER_OR_ARM */
 
 #if KXLD_USER_OR_ARM64
     kxld_addr_t pair_target, boolean_t swap);
 #endif /* KXLD_USER_OR_ARM */
 
 #if KXLD_USER_OR_ARM64
-static boolean_t arm64_reloc_has_pair(u_int _type) 
-    __attribute__((const));
-static u_int arm64_reloc_get_pair_type(u_int _prev_type) 
-    __attribute__((const));
+static boolean_t arm64_reloc_has_pair(u_int _type)
+__attribute__((const));
+static u_int arm64_reloc_get_pair_type(u_int _prev_type)
+__attribute__((const));
 static boolean_t arm64_reloc_has_got(u_int _type)
 static boolean_t arm64_reloc_has_got(u_int _type)
-    __attribute__((const));
-static kern_return_t arm64_process_reloc(const KXLDRelocator *relocator, 
-    u_char *instruction, u_int length, u_int pcrel, kxld_addr_t base_pc, 
-    kxld_addr_t link_pc, kxld_addr_t link_disp, u_int type, kxld_addr_t target, 
+__attribute__((const));
+static kern_return_t arm64_process_reloc(const KXLDRelocator *relocator,
+    u_char *instruction, u_int length, u_int pcrel, kxld_addr_t base_pc,
+    kxld_addr_t link_pc, kxld_addr_t link_disp, u_int type, kxld_addr_t target,
     kxld_addr_t pair_target, boolean_t swap);
 #endif /* KXLD_USER_OR_ARM64 */
 
 #if KXLD_USER_OR_ILP32
     kxld_addr_t pair_target, boolean_t swap);
 #endif /* KXLD_USER_OR_ARM64 */
 
 #if KXLD_USER_OR_ILP32
-static kxld_addr_t get_pointer_at_addr_32(const KXLDRelocator *relocator, 
+static kxld_addr_t get_pointer_at_addr_32(const KXLDRelocator *relocator,
     const u_char *data, u_long offset)
     const u_char *data, u_long offset)
-    __attribute__((pure, nonnull));
+__attribute__((pure, nonnull));
 #endif /* KXLD_USER_OR_ILP32 */
 #if KXLD_USER_OR_LP64
 #endif /* KXLD_USER_OR_ILP32 */
 #if KXLD_USER_OR_LP64
-static kxld_addr_t get_pointer_at_addr_64(const KXLDRelocator *relocator, 
+static kxld_addr_t get_pointer_at_addr_64(const KXLDRelocator *relocator,
     const u_char *data, u_long offset)
     const u_char *data, u_long offset)
-    __attribute__((pure, nonnull));
+__attribute__((pure, nonnull));
 #endif /* KXLD_USER_OR_LP64 */
 
 #endif /* KXLD_USER_OR_LP64 */
 
-static u_int count_relocatable_relocs(const KXLDRelocator *relocator, 
+static u_int count_relocatable_relocs(const KXLDRelocator *relocator,
     const struct relocation_info *relocs, u_int nrelocs)
     const struct relocation_info *relocs, u_int nrelocs)
-    __attribute__((pure));
+__attribute__((pure));
 
 
-static kern_return_t calculate_targets(KXLDRelocator *relocator, 
+static kern_return_t calculate_targets(KXLDRelocator *relocator,
     kxld_addr_t *_target, kxld_addr_t *_pair_target, const KXLDReloc *reloc);
 
     kxld_addr_t *_target, kxld_addr_t *_pair_target, const KXLDReloc *reloc);
 
-static kxld_addr_t align_raw_function_address(const KXLDRelocator *relocator, 
+static kxld_addr_t align_raw_function_address(const KXLDRelocator *relocator,
     kxld_addr_t value);
 
     kxld_addr_t value);
 
-static kern_return_t get_target_by_address_lookup(kxld_addr_t *target, 
+static kern_return_t get_target_by_address_lookup(kxld_addr_t *target,
     kxld_addr_t addr, const KXLDArray *sectarray);
 
 static kern_return_t check_for_direct_pure_virtual_call(
     kxld_addr_t addr, const KXLDArray *sectarray);
 
 static kern_return_t check_for_direct_pure_virtual_call(
-    const KXLDRelocator *relocator, u_long offset);
+       const KXLDRelocator *relocator, u_long offset);
 
 #if KXLD_PIC_KEXTS
 static u_long get_macho_data_size_for_array(const KXLDArray *relocs);
 
 #if KXLD_PIC_KEXTS
 static u_long get_macho_data_size_for_array(const KXLDArray *relocs);
@@ -200,202 +205,199 @@ static kern_return_t export_macho_for_array(const KXLDRelocator *relocator,
 
 /*******************************************************************************
 *******************************************************************************/
 
 /*******************************************************************************
 *******************************************************************************/
-kern_return_t 
+kern_return_t
 kxld_relocator_init(KXLDRelocator *relocator, u_char *file,
 kxld_relocator_init(KXLDRelocator *relocator, u_char *file,
-    const KXLDSymtab *symtab, const KXLDArray *sectarray, cpu_type_t cputype, 
+    const KXLDSymtab *symtab, const KXLDArray *sectarray, cpu_type_t cputype,
     cpu_subtype_t cpusubtype __unused, boolean_t swap)
 {
     cpu_subtype_t cpusubtype __unused, boolean_t swap)
 {
-    kern_return_t rval = KERN_FAILURE;
+       kern_return_t rval = KERN_FAILURE;
 
 
-    check(relocator);
+       check(relocator);
 
 
-    switch(cputype) {
+       switch (cputype) {
 #if KXLD_USER_OR_I386
 #if KXLD_USER_OR_I386
-    case CPU_TYPE_I386:
-        relocator->reloc_has_pair = generic_reloc_has_pair;
-        relocator->reloc_get_pair_type = generic_reloc_get_pair_type;
-        relocator->reloc_has_got = generic_reloc_has_got;
-        relocator->process_reloc = generic_process_reloc;
-        relocator->function_align = 0;
-        relocator->is_32_bit = TRUE;
-        relocator->may_scatter = TRUE;
-        break;
+       case CPU_TYPE_I386:
+               relocator->reloc_has_pair = generic_reloc_has_pair;
+               relocator->reloc_get_pair_type = generic_reloc_get_pair_type;
+               relocator->reloc_has_got = generic_reloc_has_got;
+               relocator->process_reloc = generic_process_reloc;
+               relocator->function_align = 0;
+               relocator->is_32_bit = TRUE;
+               relocator->may_scatter = TRUE;
+               break;
 #endif /* KXLD_USER_OR_I386 */
 #if KXLD_USER_OR_X86_64
 #endif /* KXLD_USER_OR_I386 */
 #if KXLD_USER_OR_X86_64
-    case CPU_TYPE_X86_64:
-        relocator->reloc_has_pair = x86_64_reloc_has_pair;
-        relocator->reloc_get_pair_type = x86_64_reloc_get_pair_type;
-        relocator->reloc_has_got = x86_64_reloc_has_got;
-        relocator->process_reloc = x86_64_process_reloc;
-        relocator->function_align = 0;
-        relocator->is_32_bit = FALSE;
-        relocator->may_scatter = FALSE;
-        break;
+       case CPU_TYPE_X86_64:
+               relocator->reloc_has_pair = x86_64_reloc_has_pair;
+               relocator->reloc_get_pair_type = x86_64_reloc_get_pair_type;
+               relocator->reloc_has_got = x86_64_reloc_has_got;
+               relocator->process_reloc = x86_64_process_reloc;
+               relocator->function_align = 0;
+               relocator->is_32_bit = FALSE;
+               relocator->may_scatter = FALSE;
+               break;
 #endif /* KXLD_USER_OR_X86_64 */
 #if KXLD_USER_OR_ARM
 #endif /* KXLD_USER_OR_X86_64 */
 #if KXLD_USER_OR_ARM
-    case CPU_TYPE_ARM:
-        relocator->reloc_has_pair = arm_reloc_has_pair;
-        relocator->reloc_get_pair_type = arm_reloc_get_pair_type;
-        relocator->reloc_has_got = arm_reloc_has_got;
-        relocator->process_reloc = arm_process_reloc;
-        relocator->function_align = 1;
-        relocator->is_32_bit = TRUE;
-        relocator->may_scatter = FALSE;
-        break;
+       case CPU_TYPE_ARM:
+               relocator->reloc_has_pair = arm_reloc_has_pair;
+               relocator->reloc_get_pair_type = arm_reloc_get_pair_type;
+               relocator->reloc_has_got = arm_reloc_has_got;
+               relocator->process_reloc = arm_process_reloc;
+               relocator->function_align = 1;
+               relocator->is_32_bit = TRUE;
+               relocator->may_scatter = FALSE;
+               break;
 #endif /* KXLD_USER_OR_ARM */
 #if KXLD_USER_OR_ARM64
 #endif /* KXLD_USER_OR_ARM */
 #if KXLD_USER_OR_ARM64
-    case CPU_TYPE_ARM64:
-        relocator->reloc_has_pair = arm64_reloc_has_pair;
-        relocator->reloc_get_pair_type = arm64_reloc_get_pair_type;
-        relocator->reloc_has_got = arm64_reloc_has_got;
-        relocator->process_reloc = arm64_process_reloc;
-        relocator->function_align = 0;
-        relocator->is_32_bit = FALSE;
-        relocator->may_scatter = FALSE;
-        break;
+       case CPU_TYPE_ARM64:
+               relocator->reloc_has_pair = arm64_reloc_has_pair;
+               relocator->reloc_get_pair_type = arm64_reloc_get_pair_type;
+               relocator->reloc_has_got = arm64_reloc_has_got;
+               relocator->process_reloc = arm64_process_reloc;
+               relocator->function_align = 0;
+               relocator->is_32_bit = FALSE;
+               relocator->may_scatter = FALSE;
+               break;
 #endif /* KXLD_USER_OR_ARM64 */
 
 #endif /* KXLD_USER_OR_ARM64 */
 
-    default:
-        rval = KERN_FAILURE;
-        kxld_log(kKxldLogLinking, kKxldLogErr,
-            kKxldLogArchNotSupported, cputype);
-        goto finish;
-    }
+       default:
+               rval = KERN_FAILURE;
+               kxld_log(kKxldLogLinking, kKxldLogErr,
+                   kKxldLogArchNotSupported, cputype);
+               goto finish;
+       }
 
 
-    relocator->file = file;
-    relocator->symtab = symtab;
-    relocator->sectarray = sectarray;
-    relocator->is_32_bit = kxld_is_32_bit(cputype);
-    relocator->swap = swap;
+       relocator->file = file;
+       relocator->symtab = symtab;
+       relocator->sectarray = sectarray;
+       relocator->is_32_bit = kxld_is_32_bit(cputype);
+       relocator->swap = swap;
 
 
-    rval = KERN_SUCCESS;
+       rval = KERN_SUCCESS;
 
 finish:
 
 finish:
-    return rval;
+       return rval;
 }
 
 /*******************************************************************************
 *******************************************************************************/
 kern_return_t
 }
 
 /*******************************************************************************
 *******************************************************************************/
 kern_return_t
-kxld_reloc_create_macho(KXLDArray *relocarray, const KXLDRelocator *relocator, 
+kxld_reloc_create_macho(KXLDArray *relocarray, const KXLDRelocator *relocator,
     const struct relocation_info *srcs, u_int nsrcs)
 {
     const struct relocation_info *srcs, u_int nsrcs)
 {
-    kern_return_t rval = KERN_FAILURE;
-    KXLDReloc *reloc = NULL;
-    u_int nrelocs = 0;
-    const struct relocation_info *src = NULL;
-    const struct scattered_relocation_info *scatsrc = NULL;
-    u_int i = 0;
-    u_int reloc_index = 0;
-
-    check(relocarray);
-    check(srcs);
-
-    /* If there are no relocation entries, just return */
-    if (!nsrcs) {
-        rval = KERN_SUCCESS;
-        goto finish;
-    }
-
-    /* Count the number of non-pair relocs */
-    nrelocs = count_relocatable_relocs(relocator, srcs, nsrcs);
-
-    if (nrelocs) {
-
-        /* Allocate the array of relocation entries */
-
-        rval = kxld_array_init(relocarray, sizeof(KXLDReloc), nrelocs);
-        require_noerr(rval, finish);
-
-        /* Initialize the relocation entries */
-        
-        for (i = 0; i < nsrcs; ++i) {
-            src = srcs + i;
-            scatsrc = (const struct scattered_relocation_info *) src;
-
-            /* A section-based relocation entry can be skipped for absolute 
-             * symbols.
-             */
-
-            if (!(relocator->may_scatter && (src->r_address & R_SCATTERED)) &&
-                !(src->r_extern) && (R_ABS == src->r_symbolnum))
-            {
-                continue;
-            }
-            
-            /* Pull out the data from the relocation entries.  The target_type
-             * depends on the r_extern bit:
-             *  Scattered -> Section Lookup by Address
-             *  Local (not extern) -> Section by Index
-             *  Extern -> Symbolnum by Index
-             */
-            reloc = kxld_array_get_item(relocarray, reloc_index++);
-            if (relocator->may_scatter && (src->r_address & R_SCATTERED)) {
-                reloc->address = scatsrc->r_address;
-                reloc->pcrel = scatsrc->r_pcrel;
-                reloc->length = scatsrc->r_length;
-                reloc->reloc_type = scatsrc->r_type;
-                reloc->target = scatsrc->r_value;
-                reloc->target_type = KXLD_TARGET_LOOKUP;
-            } else {
-                reloc->address = src->r_address;
-                reloc->pcrel = src->r_pcrel;
-                reloc->length = src->r_length;
-                reloc->reloc_type = src->r_type;
-                reloc->target = src->r_symbolnum;
-
-                if (0 == src->r_extern) {
-                    reloc->target_type = KXLD_TARGET_SECTNUM;
-                    reloc->target -= 1;
-                } else {
-                    reloc->target_type = KXLD_TARGET_SYMBOLNUM;
-                }
-            }
-            
-            /* Find the pair entry if it exists */
-
-            if (relocator->reloc_has_pair(reloc->reloc_type)) {
-                ++i;
-                require_action(i < nsrcs, finish, rval=KERN_FAILURE);
-
-                src = srcs + i;
-                scatsrc = (const struct scattered_relocation_info *) src;
-                 
-                if (relocator->may_scatter && (src->r_address & R_SCATTERED)) {
-                    require_action(relocator->reloc_get_pair_type(
-                        reloc->reloc_type) == scatsrc->r_type,
-                        finish, rval=KERN_FAILURE);
-                    reloc->pair_address= scatsrc->r_address;
-                    reloc->pair_target = scatsrc->r_value;
-                    reloc->pair_target_type = KXLD_TARGET_LOOKUP;
-                } else {
-                    require_action(relocator->reloc_get_pair_type(
-                        reloc->reloc_type) == scatsrc->r_type,
-                        finish, rval=KERN_FAILURE);
-                    reloc->pair_address = scatsrc->r_address;
-                    if (src->r_extern) {
-                        reloc->pair_target = src->r_symbolnum;
-                        reloc->pair_target_type = KXLD_TARGET_SYMBOLNUM;
-                    } else {
-                        reloc->pair_target = src->r_address;
-                        reloc->pair_target_type = KXLD_TARGET_VALUE;
-                    }
-                }
-            } else {
-                reloc->pair_target = 0;
-                if (relocator->reloc_has_got(reloc->reloc_type)) {
-                   reloc->pair_target_type = KXLD_TARGET_GOT;
-                } else {
-                   reloc->pair_target_type = KXLD_TARGET_NONE;
-                }
-            }
-        }
-    }
-
-    rval = KERN_SUCCESS;
+       kern_return_t rval = KERN_FAILURE;
+       KXLDReloc *reloc = NULL;
+       u_int nrelocs = 0;
+       const struct relocation_info *src = NULL;
+       const struct scattered_relocation_info *scatsrc = NULL;
+       u_int i = 0;
+       u_int reloc_index = 0;
+
+       check(relocarray);
+       check(srcs);
+
+       /* If there are no relocation entries, just return */
+       if (!nsrcs) {
+               rval = KERN_SUCCESS;
+               goto finish;
+       }
+
+       /* Count the number of non-pair relocs */
+       nrelocs = count_relocatable_relocs(relocator, srcs, nsrcs);
+
+       if (nrelocs) {
+               /* Allocate the array of relocation entries */
+
+               rval = kxld_array_init(relocarray, sizeof(KXLDReloc), nrelocs);
+               require_noerr(rval, finish);
+
+               /* Initialize the relocation entries */
+
+               for (i = 0; i < nsrcs; ++i) {
+                       src = srcs + i;
+                       scatsrc = (const struct scattered_relocation_info *) src;
+
+                       /* A section-based relocation entry can be skipped for absolute
+                        * symbols.
+                        */
+
+                       if (!(relocator->may_scatter && (src->r_address & R_SCATTERED)) &&
+                           !(src->r_extern) && (R_ABS == src->r_symbolnum)) {
+                               continue;
+                       }
+
+                       /* Pull out the data from the relocation entries.  The target_type
+                        * depends on the r_extern bit:
+                        *  Scattered -> Section Lookup by Address
+                        *  Local (not extern) -> Section by Index
+                        *  Extern -> Symbolnum by Index
+                        */
+                       reloc = kxld_array_get_item(relocarray, reloc_index++);
+                       if (relocator->may_scatter && (src->r_address & R_SCATTERED)) {
+                               reloc->address = scatsrc->r_address;
+                               reloc->pcrel = scatsrc->r_pcrel;
+                               reloc->length = scatsrc->r_length;
+                               reloc->reloc_type = scatsrc->r_type;
+                               reloc->target = scatsrc->r_value;
+                               reloc->target_type = KXLD_TARGET_LOOKUP;
+                       } else {
+                               reloc->address = src->r_address;
+                               reloc->pcrel = src->r_pcrel;
+                               reloc->length = src->r_length;
+                               reloc->reloc_type = src->r_type;
+                               reloc->target = src->r_symbolnum;
+
+                               if (0 == src->r_extern) {
+                                       reloc->target_type = KXLD_TARGET_SECTNUM;
+                                       reloc->target -= 1;
+                               } else {
+                                       reloc->target_type = KXLD_TARGET_SYMBOLNUM;
+                               }
+                       }
+
+                       /* Find the pair entry if it exists */
+
+                       if (relocator->reloc_has_pair(reloc->reloc_type)) {
+                               ++i;
+                               require_action(i < nsrcs, finish, rval = KERN_FAILURE);
+
+                               src = srcs + i;
+                               scatsrc = (const struct scattered_relocation_info *) src;
+
+                               if (relocator->may_scatter && (src->r_address & R_SCATTERED)) {
+                                       require_action(relocator->reloc_get_pair_type(
+                                                   reloc->reloc_type) == scatsrc->r_type,
+                                           finish, rval = KERN_FAILURE);
+                                       reloc->pair_address = scatsrc->r_address;
+                                       reloc->pair_target = scatsrc->r_value;
+                                       reloc->pair_target_type = KXLD_TARGET_LOOKUP;
+                               } else {
+                                       require_action(relocator->reloc_get_pair_type(
+                                                   reloc->reloc_type) == scatsrc->r_type,
+                                           finish, rval = KERN_FAILURE);
+                                       reloc->pair_address = scatsrc->r_address;
+                                       if (src->r_extern) {
+                                               reloc->pair_target = src->r_symbolnum;
+                                               reloc->pair_target_type = KXLD_TARGET_SYMBOLNUM;
+                                       } else {
+                                               reloc->pair_target = src->r_address;
+                                               reloc->pair_target_type = KXLD_TARGET_VALUE;
+                                       }
+                               }
+                       } else {
+                               reloc->pair_target = 0;
+                               if (relocator->reloc_has_got(reloc->reloc_type)) {
+                                       reloc->pair_target_type = KXLD_TARGET_GOT;
+                               } else {
+                                       reloc->pair_target_type = KXLD_TARGET_NONE;
+                               }
+                       }
+               } // for...
+       }
+       rval = KERN_SUCCESS;
 
 finish:
 
 finish:
-    return rval;
+       return rval;
 }
 
 
 }
 
 
@@ -405,43 +407,42 @@ finish:
 *   2) Don't reference N_ABS symbols
 *******************************************************************************/
 static u_int
 *   2) Don't reference N_ABS symbols
 *******************************************************************************/
 static u_int
-count_relocatable_relocs(const KXLDRelocator *relocator, 
+count_relocatable_relocs(const KXLDRelocator *relocator,
     const struct relocation_info *relocs, u_int nrelocs)
 {
     const struct relocation_info *relocs, u_int nrelocs)
 {
-    u_int num_nonpair_relocs = 0;
-    u_int i = 0;
-    const struct relocation_info *reloc = NULL;
-    const struct scattered_relocation_info *sreloc = NULL;
-
-    check(relocator);
-    check(relocs);
-
-    /* Loop over all of the relocation entries */
-
-    num_nonpair_relocs = 1;
-    for (i = 1; i < nrelocs; ++i) {
-        reloc = relocs + i;
-
-        if (reloc->r_address & R_SCATTERED) {
-            /* A scattered relocation entry is relocatable as long as it's not a
-             * pair.
-             */
-            sreloc = (const struct scattered_relocation_info *) reloc;
-
-            num_nonpair_relocs += 
-                !relocator->reloc_has_pair(sreloc->r_type);
-        } else {
-            /* A normal relocation entry is relocatable if it is not a pair and
-             * if it is not a section-based relocation for an absolute symbol.
-             */
-            num_nonpair_relocs += 
-                !(relocator->reloc_has_pair(reloc->r_type)
-                 || (0 == reloc->r_extern && R_ABS == reloc->r_symbolnum));
-        }
-
-    }
-    
-    return num_nonpair_relocs;
+       u_int num_nonpair_relocs = 0;
+       u_int i = 0;
+       const struct relocation_info *reloc = NULL;
+       const struct scattered_relocation_info *sreloc = NULL;
+
+       check(relocator);
+       check(relocs);
+
+       /* Loop over all of the relocation entries */
+
+       num_nonpair_relocs = 1;
+       for (i = 1; i < nrelocs; ++i) {
+               reloc = relocs + i;
+
+               if (reloc->r_address & R_SCATTERED) {
+                       /* A scattered relocation entry is relocatable as long as it's not a
+                        * pair.
+                        */
+                       sreloc = (const struct scattered_relocation_info *) reloc;
+
+                       num_nonpair_relocs +=
+                           !relocator->reloc_has_pair(sreloc->r_type);
+               } else {
+                       /* A normal relocation entry is relocatable if it is not a pair and
+                        * if it is not a section-based relocation for an absolute symbol.
+                        */
+                       num_nonpair_relocs +=
+                           !(relocator->reloc_has_pair(reloc->r_type)
+                           || (0 == reloc->r_extern && R_ABS == reloc->r_symbolnum));
+               }
+       }
+
+       return num_nonpair_relocs;
 }
 
 /*******************************************************************************
 }
 
 /*******************************************************************************
@@ -449,38 +450,38 @@ count_relocatable_relocs(const KXLDRelocator *relocator,
 void
 kxld_relocator_clear(KXLDRelocator *relocator)
 {
 void
 kxld_relocator_clear(KXLDRelocator *relocator)
 {
-    bzero(relocator, sizeof(*relocator));
+       bzero(relocator, sizeof(*relocator));
 }
 
 /*******************************************************************************
 *******************************************************************************/
 }
 
 /*******************************************************************************
 *******************************************************************************/
-boolean_t 
+boolean_t
 kxld_relocator_has_pair(const KXLDRelocator *relocator, u_int r_type)
 {
 kxld_relocator_has_pair(const KXLDRelocator *relocator, u_int r_type)
 {
-    check(relocator);
+       check(relocator);
 
 
-    return relocator->reloc_has_pair(r_type);
+       return relocator->reloc_has_pair(r_type);
 }
 
 /*******************************************************************************
 *******************************************************************************/
 }
 
 /*******************************************************************************
 *******************************************************************************/
-u_int 
+u_int
 kxld_relocator_get_pair_type(const KXLDRelocator *relocator,
     u_int prev_r_type)
 {
 kxld_relocator_get_pair_type(const KXLDRelocator *relocator,
     u_int prev_r_type)
 {
-    check(relocator);
+       check(relocator);
 
 
-    return relocator->reloc_get_pair_type(prev_r_type);
+       return relocator->reloc_get_pair_type(prev_r_type);
 }
 
 /*******************************************************************************
 *******************************************************************************/
 }
 
 /*******************************************************************************
 *******************************************************************************/
-boolean_t 
+boolean_t
 kxld_relocator_has_got(const KXLDRelocator *relocator, u_int r_type)
 {
 kxld_relocator_has_got(const KXLDRelocator *relocator, u_int r_type)
 {
-    check(relocator);
+       check(relocator);
 
 
-    return relocator->reloc_has_got(r_type);
+       return relocator->reloc_has_got(r_type);
 }
 
 /*******************************************************************************
 }
 
 /*******************************************************************************
@@ -489,55 +490,57 @@ KXLDSym *
 kxld_reloc_get_symbol(const KXLDRelocator *relocator, const KXLDReloc *reloc,
     const u_char *data)
 {
 kxld_reloc_get_symbol(const KXLDRelocator *relocator, const KXLDReloc *reloc,
     const u_char *data)
 {
-    KXLDSym *sym = NULL;
-    kxld_addr_t value = 0;
-
-    check(reloc);
-
-    switch (reloc->target_type) {
-    case KXLD_TARGET_SYMBOLNUM:
-        sym = kxld_symtab_get_symbol_by_index(relocator->symtab, reloc->target);
-        break;
-    case KXLD_TARGET_SECTNUM:
-        if (data) { 
-            value = kxld_relocator_get_pointer_at_addr(relocator, data, 
-                reloc->address);
-            sym = kxld_symtab_get_cxx_symbol_by_value(relocator->symtab, value);           
-        }
-        break;
-    default:
-        sym = NULL;
-        break;
-    }
-
-    return sym;
+       KXLDSym *sym = NULL;
+       kxld_addr_t value = 0;
+
+       check(reloc);
+
+       switch (reloc->target_type) {
+       case KXLD_TARGET_SYMBOLNUM:
+               sym = kxld_symtab_get_symbol_by_index(relocator->symtab, reloc->target);
+               break;
+       case KXLD_TARGET_SECTNUM:
+               if (data) {
+                       value = kxld_relocator_get_pointer_at_addr(relocator, data,
+                           reloc->address);
+                       sym = kxld_symtab_get_cxx_symbol_by_value(relocator->symtab, value);
+               }
+               break;
+       default:
+               sym = NULL;
+               break;
+       }
+
+       return sym;
 }
 
 /*******************************************************************************
 *******************************************************************************/
 kern_return_t
 }
 
 /*******************************************************************************
 *******************************************************************************/
 kern_return_t
-kxld_reloc_get_reloc_index_by_offset(const KXLDArray *relocs, 
+kxld_reloc_get_reloc_index_by_offset(const KXLDArray *relocs,
     kxld_size_t offset, u_int *idx)
 {
     kxld_size_t offset, u_int *idx)
 {
-    kern_return_t rval = KERN_FAILURE;
-    KXLDReloc *reloc = NULL;
-    u_int i = 0;
-
-    for (i = 0; i < relocs->nitems; ++i) {
-        reloc = kxld_array_get_item(relocs, i);
-        if (reloc->address == offset) break;
-    }
-    
-    if (i >= relocs->nitems) {
-        rval = KERN_FAILURE;
-        goto finish;
-    }
-
-    *idx = i;
-    rval = KERN_SUCCESS;
+       kern_return_t rval = KERN_FAILURE;
+       KXLDReloc *reloc = NULL;
+       u_int i = 0;
+
+       for (i = 0; i < relocs->nitems; ++i) {
+               reloc = kxld_array_get_item(relocs, i);
+               if (reloc->address == offset) {
+                       break;
+               }
+       }
+
+       if (i >= relocs->nitems) {
+               rval = KERN_FAILURE;
+               goto finish;
+       }
+
+       *idx = i;
+       rval = KERN_SUCCESS;
 
 finish:
 
 finish:
-    return rval;
+       return rval;
 }
 
 /*******************************************************************************
 }
 
 /*******************************************************************************
@@ -545,17 +548,19 @@ finish:
 KXLDReloc *
 kxld_reloc_get_reloc_by_offset(const KXLDArray *relocs, kxld_addr_t offset)
 {
 KXLDReloc *
 kxld_reloc_get_reloc_by_offset(const KXLDArray *relocs, kxld_addr_t offset)
 {
-    kern_return_t rval = KERN_FAILURE;
-    KXLDReloc *reloc = NULL;
-    u_int i = 0;
+       kern_return_t rval = KERN_FAILURE;
+       KXLDReloc *reloc = NULL;
+       u_int i = 0;
+
+       rval = kxld_reloc_get_reloc_index_by_offset(relocs, offset, &i);
+       if (rval) {
+               goto finish;
+       }
 
 
-    rval = kxld_reloc_get_reloc_index_by_offset(relocs, offset, &i);
-    if (rval) goto finish;
+       reloc = kxld_array_get_item(relocs, i);
 
 
-    reloc = kxld_array_get_item(relocs, i);
-    
 finish:
 finish:
-    return reloc;
+       return reloc;
 }
 
 #if KXLD_PIC_KEXTS
 }
 
 #if KXLD_PIC_KEXTS
@@ -564,21 +569,22 @@ finish:
 u_long
 kxld_reloc_get_macho_header_size()
 {
 u_long
 kxld_reloc_get_macho_header_size()
 {
-    return sizeof(struct dysymtab_command);
+       return sizeof(struct dysymtab_command);
 }
 
 /*******************************************************************************
 *******************************************************************************/
 u_long
 }
 
 /*******************************************************************************
 *******************************************************************************/
 u_long
-kxld_reloc_get_macho_data_size(const KXLDArray *locrelocs,
-    const KXLDArray *extrelocs)
+kxld_reloc_get_macho_data_size(
+       const KXLDArray *locrelocs,
+       const KXLDArray *extrelocs)
 {
 {
-    u_long    rval = 0;
+       u_long    rval = 0;
 
 
-    rval += get_macho_data_size_for_array(locrelocs);
-    rval += get_macho_data_size_for_array(extrelocs);
+       rval += get_macho_data_size_for_array(locrelocs);
+       rval += get_macho_data_size_for_array(extrelocs);
 
 
-    return (rval);
+       return rval;
 }
 
 /*******************************************************************************
 }
 
 /*******************************************************************************
@@ -589,47 +595,79 @@ kxld_reloc_export_macho(const KXLDRelocator *relocator,
     u_char *buf, u_long *header_offset, u_long header_size,
     u_long *data_offset, u_long size)
 {
     u_char *buf, u_long *header_offset, u_long header_size,
     u_long *data_offset, u_long size)
 {
-    kern_return_t rval = KERN_FAILURE;
-    struct dysymtab_command *dysymtabhdr = NULL;
-    struct relocation_info *start = NULL;
-    struct relocation_info *dst = NULL;
-    u_long count = 0;
-    u_long data_size = 0;
-
-    check(locrelocs);
-    check(extrelocs);
-    check(buf);
-    check(header_offset);
-    check(data_offset);
-
-    require_action(sizeof(*dysymtabhdr) <= header_size - *header_offset, finish, rval=KERN_FAILURE);
-    dysymtabhdr = (struct dysymtab_command *) ((void *) (buf + *header_offset));
-    *header_offset += sizeof(*dysymtabhdr);
-
-    data_size = kxld_reloc_get_macho_data_size(locrelocs, extrelocs);
-    require_action((*data_offset + data_size) <= size, finish, rval=KERN_FAILURE);
-    
-    start = dst = (struct relocation_info *) ((void *) (buf + *data_offset));
-
-    rval = export_macho_for_array(relocator, locrelocs, &dst);
-    require_noerr(rval, finish);
-    
-    rval = export_macho_for_array(relocator, extrelocs, &dst);
-    require_noerr(rval, finish);
-
-    count = dst - start;
-
-    memset(dysymtabhdr, 0, sizeof(*dysymtabhdr));
-    dysymtabhdr->cmd = LC_DYSYMTAB;
-    dysymtabhdr->cmdsize = (uint32_t) sizeof(*dysymtabhdr);
-    dysymtabhdr->locreloff = (uint32_t) *data_offset;
-    dysymtabhdr->nlocrel = (uint32_t) count;
-    
-    *data_offset += count * sizeof(struct relocation_info);
-
-    rval = KERN_SUCCESS;
+       kern_return_t rval = KERN_FAILURE;
+       struct dysymtab_command *dysymtabhdr = NULL;
+       struct relocation_info *start = NULL;
+       struct relocation_info *dst = NULL;
+       u_long count = 0;
+       u_long data_size = 0;
+
+       check(locrelocs);
+       check(extrelocs);
+       check(buf);
+       check(header_offset);
+       check(data_offset);
+
+       require_action(sizeof(*dysymtabhdr) <= header_size - *header_offset, finish, rval = KERN_FAILURE);
+       dysymtabhdr = (struct dysymtab_command *) ((void *) (buf + *header_offset));
+       *header_offset += sizeof(*dysymtabhdr);
+
+       data_size = kxld_reloc_get_macho_data_size(locrelocs, extrelocs);
+       require_action((*data_offset + data_size) <= size, finish, rval = KERN_FAILURE);
+
+       start = dst = (struct relocation_info *) ((void *) (buf + *data_offset));
+
+       if (kaslr_offsets == NULL) {
+               kaslr_offsets_index = 0;
+               kaslr_offsets_count = locrelocs->nitems + extrelocs->nitems;
+               kaslr_offsets = (uint32_t *)calloc(kaslr_offsets_count, sizeof(*kaslr_offsets));
+       }
+
+       // copies the reloc data into the __LINKEDIT segment
+       // data_offset is the new value for locreloff
+       rval = export_macho_for_array(relocator, locrelocs, &dst);
+       require_noerr(rval, finish);
+
+       rval = export_macho_for_array(relocator, extrelocs, &dst);
+       require_noerr(rval, finish);
+
+       count = dst - start;
+
+       memset(dysymtabhdr, 0, sizeof(*dysymtabhdr));
+       dysymtabhdr->cmd = LC_DYSYMTAB;
+       dysymtabhdr->cmdsize = (uint32_t) sizeof(*dysymtabhdr);
+       dysymtabhdr->locreloff = (uint32_t) *data_offset;
+       dysymtabhdr->nlocrel = (uint32_t) count;
+
+       *data_offset += count * sizeof(struct relocation_info);
+
+#if SPLIT_KEXTS_DEBUG
+       kxld_log(kKxldLogLinking, kKxldLogErr,
+           "%p >>> Start of dysymtabhdr (size %lu) <%s> ",
+           (void *) dysymtabhdr,
+           sizeof(*dysymtabhdr),
+           __func__);
+       kxld_log(kKxldLogLinking, kKxldLogErr,
+           "%p <<< End of dysymtabhdr <%s> ",
+           (void *) ((u_char *)dysymtabhdr + sizeof(*dysymtabhdr)),
+           __func__);
+
+       kxld_log(kKxldLogLinking, kKxldLogErr,
+           "dysymtabhdr at %p: cmdsize %u indirectsymoff %u nindirectsyms %u extreloff %u nextrel %u locreloff %u nlocrel %u <%s>",
+           (void *) dysymtabhdr,
+           dysymtabhdr->cmdsize,
+           dysymtabhdr->indirectsymoff,
+           dysymtabhdr->nindirectsyms,
+           dysymtabhdr->extreloff,
+           dysymtabhdr->nextrel,
+           dysymtabhdr->locreloff,
+           dysymtabhdr->nlocrel,
+           __func__);
+#endif
+
+       rval = KERN_SUCCESS;
 finish:
 finish:
-    return rval;
+       return rval;
 }
 #endif /* KXLD_PIC_KEXTS */
 
 }
 #endif /* KXLD_PIC_KEXTS */
 
@@ -639,34 +677,34 @@ kxld_addr_t
 kxld_relocator_get_pointer_at_addr(const KXLDRelocator *relocator,
     const u_char *data, u_long offset)
 {
 kxld_relocator_get_pointer_at_addr(const KXLDRelocator *relocator,
     const u_char *data, u_long offset)
 {
-    kxld_addr_t value;
+       kxld_addr_t value;
 
 
-    KXLD_3264_FUNC(relocator->is_32_bit, value,
-        get_pointer_at_addr_32, get_pointer_at_addr_64,
-        relocator, data, offset);
+       KXLD_3264_FUNC(relocator->is_32_bit, value,
+           get_pointer_at_addr_32, get_pointer_at_addr_64,
+           relocator, data, offset);
 
 
-    return value;
+       return value;
 }
 
 #if KXLD_USER_OR_ILP32
 /*******************************************************************************
 *******************************************************************************/
 static kxld_addr_t
 }
 
 #if KXLD_USER_OR_ILP32
 /*******************************************************************************
 *******************************************************************************/
 static kxld_addr_t
-get_pointer_at_addr_32(const KXLDRelocator *relocator, 
+get_pointer_at_addr_32(const KXLDRelocator *relocator,
     const u_char *data, u_long offset)
 {
     const u_char *data, u_long offset)
 {
-    uint32_t addr = 0;
-    
-    check(relocator);
+       uint32_t addr = 0;
+
+       check(relocator);
 
 
-    addr = *(const uint32_t *) ((const void *) (data + offset));
+       addr = *(const uint32_t *) ((const void *) (data + offset));
 #if !KERNEL
 #if !KERNEL
-    if (relocator->swap) {
-        addr = OSSwapInt32(addr);
-    }
+       if (relocator->swap) {
+               addr = OSSwapInt32(addr);
+       }
 #endif
 
 #endif
 
-    return align_raw_function_address(relocator, addr);
+       return align_raw_function_address(relocator, addr);
 }
 #endif /* KXLD_USER_OR_ILP32 */
 
 }
 #endif /* KXLD_USER_OR_ILP32 */
 
@@ -674,30 +712,31 @@ get_pointer_at_addr_32(const KXLDRelocator *relocator,
 /*******************************************************************************
 *******************************************************************************/
 static kxld_addr_t
 /*******************************************************************************
 *******************************************************************************/
 static kxld_addr_t
-get_pointer_at_addr_64(const KXLDRelocator *relocator, 
+get_pointer_at_addr_64(const KXLDRelocator *relocator,
     const u_char *data, u_long offset)
 {
     const u_char *data, u_long offset)
 {
-    uint64_t addr = 0;
-    
-    check(relocator);
+       uint64_t addr = 0;
+
+       check(relocator);
+
+       addr = *(const uint64_t *) ((const void *) (data + offset));
 
 
-    addr = *(const uint64_t *) ((const void *) (data + offset));
 #if !KERNEL
 #if !KERNEL
-    if (relocator->swap) {
-        addr = OSSwapInt64(addr);
-    }
+       if (relocator->swap) {
+               addr = OSSwapInt64(addr);
+       }
 #endif
 
 #endif
 
-    return align_raw_function_address(relocator, addr);
+       return align_raw_function_address(relocator, addr);
 }
 #endif /* KXLD_USER_OR_LP64 */
 
 /*******************************************************************************
 *******************************************************************************/
 }
 #endif /* KXLD_USER_OR_LP64 */
 
 /*******************************************************************************
 *******************************************************************************/
-void 
+void
 kxld_relocator_set_vtables(KXLDRelocator *relocator, const KXLDDict *vtables)
 {
 kxld_relocator_set_vtables(KXLDRelocator *relocator, const KXLDDict *vtables)
 {
-    relocator->vtables = vtables;
+       relocator->vtables = vtables;
 }
 
 /*******************************************************************************
 }
 
 /*******************************************************************************
@@ -710,241 +749,249 @@ kxld_relocator_set_vtables(KXLDRelocator *relocator, const KXLDDict *vtables)
 static kxld_addr_t
 align_raw_function_address(const KXLDRelocator *relocator, kxld_addr_t value)
 {
 static kxld_addr_t
 align_raw_function_address(const KXLDRelocator *relocator, kxld_addr_t value)
 {
-    if (relocator->function_align) { 
-        value &= ~((1ULL << relocator->function_align) - 1); 
-    }
+       if (relocator->function_align) {
+               value &= ~((1ULL << relocator->function_align) - 1);
+       }
 
 
-    return value; 
+       return value;
 }
 
 /*******************************************************************************
 *******************************************************************************/
 }
 
 /*******************************************************************************
 *******************************************************************************/
-kern_return_t 
+kern_return_t
 kxld_relocator_process_sect_reloc(KXLDRelocator *relocator,
     const KXLDReloc *reloc, const KXLDSect *sect)
 {
 kxld_relocator_process_sect_reloc(KXLDRelocator *relocator,
     const KXLDReloc *reloc, const KXLDSect *sect)
 {
-    kern_return_t rval = KERN_FAILURE;
-    u_char *instruction = NULL;
-    kxld_addr_t target = 0;
-    kxld_addr_t pair_target = 0;
-    kxld_addr_t base_pc = 0;
-    kxld_addr_t link_pc = 0;
-    kxld_addr_t link_disp = 0;
+       kern_return_t rval = KERN_FAILURE;
+       u_char *instruction = NULL;
+       kxld_addr_t target = 0;
+       kxld_addr_t pair_target = 0;
+       kxld_addr_t base_pc = 0;
+       kxld_addr_t link_pc = 0;
+       kxld_addr_t link_disp = 0;
 
 
-    check(relocator);
-    check(reloc);
-    check(sect);
+       check(relocator);
+       check(reloc);
+       check(sect);
 
 
-    /* Find the instruction */
+       /* Find the instruction */
 
 
-    instruction = sect->data + reloc->address;
+       instruction = sect->data + reloc->address;
 
 
-    /* Calculate the target */
+       /* Calculate the target */
 
 
-    rval = calculate_targets(relocator, &target, &pair_target, reloc);
-    require_noerr(rval, finish);
+       rval = calculate_targets(relocator, &target, &pair_target, reloc);
+       require_noerr(rval, finish);
 
 
-    base_pc = reloc->address;
-    link_pc = base_pc + sect->link_addr;
-    link_disp = sect->link_addr - sect->base_addr;
+       base_pc = reloc->address;
+       link_pc = base_pc + sect->link_addr;
+       link_disp = sect->link_addr - sect->base_addr;
 
 
-    /* Relocate */
+       /* Relocate */
 
 
-    rval = relocator->process_reloc(relocator, instruction, reloc->length, 
-        reloc->pcrel, base_pc, link_pc, link_disp, reloc->reloc_type, target, 
-        pair_target, relocator->swap);
-    require_noerr(rval, finish);
-    
-    /* Return */
+       rval = relocator->process_reloc(relocator, instruction, reloc->length,
+           reloc->pcrel, base_pc, link_pc, link_disp, reloc->reloc_type, target,
+           pair_target, relocator->swap);
+       require_noerr(rval, finish);
 
 
-    relocator->current_vtable = NULL;
-    rval = KERN_SUCCESS;
+       /* Return */
+
+       relocator->current_vtable = NULL;
+       rval = KERN_SUCCESS;
 
 finish:
 
 finish:
-    return rval;
+       return rval;
 }
 
 /*******************************************************************************
 *******************************************************************************/
 }
 
 /*******************************************************************************
 *******************************************************************************/
-kern_return_t 
+kern_return_t
 kxld_reloc_update_symindex(KXLDReloc *reloc, u_int symindex)
 {
 kxld_reloc_update_symindex(KXLDReloc *reloc, u_int symindex)
 {
-    kern_return_t rval = KERN_FAILURE;
+       kern_return_t rval = KERN_FAILURE;
 
 
-    require_action(reloc->target_type == KXLD_TARGET_SYMBOLNUM, 
-        finish, rval = KERN_FAILURE);
+       require_action(reloc->target_type == KXLD_TARGET_SYMBOLNUM,
+           finish, rval = KERN_FAILURE);
 
 
-    reloc->target = symindex;
+       reloc->target = symindex;
 
 
-    rval = KERN_SUCCESS;
+       rval = KERN_SUCCESS;
 
 finish:
 
 finish:
-    return rval;
+       return rval;
 }
 
 /*******************************************************************************
 *******************************************************************************/
 }
 
 /*******************************************************************************
 *******************************************************************************/
-kern_return_t 
+kern_return_t
 kxld_relocator_process_table_reloc(KXLDRelocator *relocator,
 kxld_relocator_process_table_reloc(KXLDRelocator *relocator,
-    const KXLDReloc *reloc, const KXLDSeg *seg, kxld_addr_t link_addr)
+    const KXLDReloc *reloc,
+    const KXLDSeg *seg,
+    kxld_addr_t link_addr)
 {
 {
-    kern_return_t rval = KERN_FAILURE;
-    u_char *instruction = NULL;
-    kxld_addr_t target = 0;
-    kxld_addr_t pair_target = 0;
-    kxld_addr_t base_pc = 0;
-    kxld_addr_t link_pc = 0;
-    u_long offset = 0;
+       kern_return_t rval = KERN_FAILURE;
+       u_char *instruction = NULL;
+       kxld_addr_t target = 0;
+       kxld_addr_t pair_target = 0;
+       kxld_addr_t base_pc = 0;
+       kxld_addr_t link_pc = 0;
+       u_long offset = 0;
 
 
-    check(relocator);
-    check(reloc);
+       check(relocator);
+       check(reloc);
 
 
-    /* Find the instruction */
+       /* Find the instruction in original kext file we are trying to link */
 
 
-    offset = (u_long)(seg->fileoff + (reloc->address - seg->base_addr));
-    instruction = relocator->file + offset;
+       offset = (u_long)(seg->fileoff + (reloc->address - seg->base_addr));
+       instruction = relocator->file + offset;
 
 
-    /* Calculate the target */
+       /* Calculate the target */
 
 
-    rval = calculate_targets(relocator, &target, &pair_target, reloc);
-    require_noerr(rval, finish);
+       rval = calculate_targets(relocator, &target, &pair_target, reloc);
+       require_noerr(rval, finish);
 
 
-    base_pc = reloc->address;
-    link_pc = base_pc + link_addr;
+       base_pc = reloc->address;
+       link_pc = base_pc + link_addr;
+       if (kxld_seg_is_split_seg(seg)) {
+               // link_pc for split segment special case, do not add in the base_pc
+               link_pc = link_addr;
+       }
 
 
-    /* Relocate */
+       /* Relocate */
 
 
-    rval = relocator->process_reloc(relocator, instruction, reloc->length, 
-        reloc->pcrel, base_pc, link_pc, link_addr, reloc->reloc_type, target,
-        pair_target, relocator->swap);
-    require_noerr(rval, finish);
-    
-    /* Return */
+       rval = relocator->process_reloc(relocator, instruction, reloc->length,
+           reloc->pcrel, base_pc, link_pc, link_addr, reloc->reloc_type, target,
+           pair_target, relocator->swap);
+       require_noerr(rval, finish);
 
 
-    relocator->current_vtable = NULL;
-    rval = KERN_SUCCESS;
+       /* Return */
+
+       relocator->current_vtable = NULL;
+       rval = KERN_SUCCESS;
 
 finish:
 
 finish:
-    return rval;
+       return rval;
 }
 
 /*******************************************************************************
 *******************************************************************************/
 static kern_return_t
 }
 
 /*******************************************************************************
 *******************************************************************************/
 static kern_return_t
-calculate_targets(KXLDRelocator *relocator, kxld_addr_t *_target, 
+calculate_targets(KXLDRelocator *relocator, kxld_addr_t *_target,
     kxld_addr_t *_pair_target, const KXLDReloc *reloc)
 {
     kxld_addr_t *_pair_target, const KXLDReloc *reloc)
 {
-    kern_return_t rval = KERN_FAILURE;
-    const KXLDSect *sect = NULL;
-    const KXLDSym *sym = NULL;
-    kxld_addr_t target = 0;
-    kxld_addr_t pair_target = 0;
-    char *demangled_name = NULL;
-    size_t demangled_length = 0;
-
-    check(_target);
-    check(_pair_target);
-    *_target = 0;
-    *_pair_target = 0;
-
-    /* Find the target based on the lookup type */
-
-    switch(reloc->target_type) {
-    case KXLD_TARGET_LOOKUP:
-        require_action(reloc->pair_target_type == KXLD_TARGET_NONE ||
-            reloc->pair_target_type == KXLD_TARGET_LOOKUP ||
-            reloc->pair_target_type == KXLD_TARGET_VALUE,
-            finish, rval=KERN_FAILURE);
-
-        rval = get_target_by_address_lookup(&target, reloc->target, 
-            relocator->sectarray);
-        require_noerr(rval, finish);
-
-        if (reloc->pair_target_type == KXLD_TARGET_LOOKUP) {
-            rval = get_target_by_address_lookup(&pair_target,
-                reloc->pair_target, relocator->sectarray);
-            require_noerr(rval, finish);
-        } else if (reloc->pair_target_type == KXLD_TARGET_VALUE) {
-            pair_target = reloc->pair_target;
-        }
-        break;
-    case KXLD_TARGET_SECTNUM:
-        require_action(reloc->pair_target_type == KXLD_TARGET_NONE ||
-            reloc->pair_target_type == KXLD_TARGET_VALUE, 
-            finish, rval=KERN_FAILURE);
-
-        /* Get the target's section by section number */
-        sect = kxld_array_get_item(relocator->sectarray, reloc->target);
-        require_action(sect, finish, rval=KERN_FAILURE);
-
-        /* target is the change in the section's address */
-        target = sect->link_addr - sect->base_addr;
-
-        if (reloc->pair_target_type) {
-            pair_target = reloc->pair_target;
-        } else {
-            /* x86_64 needs to know when we have a non-external relocation,
-             * so we hack that information in here.
-             */
-            pair_target = TRUE;
-        }
-        break;
-    case KXLD_TARGET_SYMBOLNUM:
-        require_action(reloc->pair_target_type == KXLD_TARGET_NONE ||
-            reloc->pair_target_type == KXLD_TARGET_GOT ||
-            reloc->pair_target_type == KXLD_TARGET_SYMBOLNUM ||
-            reloc->pair_target_type == KXLD_TARGET_VALUE, finish,
-            rval=KERN_FAILURE);
-
-        /* Get the target's symbol by symbol number */
-        sym = kxld_symtab_get_symbol_by_index(relocator->symtab, reloc->target);
-        require_action(sym, finish, rval=KERN_FAILURE);
-
-        /* If this symbol is a padslot that has already been replaced, then the
-         * only way a relocation entry can still reference it is if there is a
-         * vtable that has not been patched.  The vtable patcher uses the
-         * MetaClass structure to find classes for patching, so an unpatched
-         * vtable means that there is an OSObject-dervied class that is missing
-         * its OSDeclare/OSDefine macros.
-         */
-        require_action(!kxld_sym_is_padslot(sym) || !kxld_sym_is_replaced(sym), 
-            finish, rval=KERN_FAILURE;
-            kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogRelocatingPatchedSym,
-                kxld_demangle(sym->name, &demangled_name, &demangled_length)));
-
-        target = sym->link_addr;
-
-        if (kxld_sym_is_vtable(sym)) {
-            relocator->current_vtable = kxld_dict_find(relocator->vtables, sym->name);
-        }
-
-        /* Some relocation types need the GOT entry address instead of the
-         * symbol's actual address.  These types don't have pair relocation
-         * entries, so we store the GOT entry address as the pair target.
-         */
-        if (reloc->pair_target_type == KXLD_TARGET_VALUE) {
-            pair_target = reloc->pair_target;
-        } else if (reloc->pair_target_type == KXLD_TARGET_SYMBOLNUM ) {
-            sym = kxld_symtab_get_symbol_by_index(relocator->symtab, 
-                reloc->pair_target);
-            require_action(sym, finish, rval=KERN_FAILURE);
-            pair_target = sym->link_addr;
-        } else if (reloc->pair_target_type == KXLD_TARGET_GOT) {
-            pair_target = sym->got_addr;
-        }
-        break;
-    default:
-        rval = KERN_FAILURE;
-        goto finish;
-    }
-
-    *_target = target;
-    *_pair_target = pair_target;
-    rval = KERN_SUCCESS;
+       kern_return_t rval = KERN_FAILURE;
+       const KXLDSect *sect = NULL;
+       const KXLDSym *sym = NULL;
+       kxld_addr_t target = 0;
+       kxld_addr_t pair_target = 0;
+       char *demangled_name = NULL;
+       size_t demangled_length = 0;
+
+       check(_target);
+       check(_pair_target);
+       *_target = 0;
+       *_pair_target = 0;
+
+       /* Find the target based on the lookup type */
+
+       switch (reloc->target_type) {
+       case KXLD_TARGET_LOOKUP:
+               require_action(reloc->pair_target_type == KXLD_TARGET_NONE ||
+                   reloc->pair_target_type == KXLD_TARGET_LOOKUP ||
+                   reloc->pair_target_type == KXLD_TARGET_VALUE,
+                   finish, rval = KERN_FAILURE);
+
+               rval = get_target_by_address_lookup(&target, reloc->target,
+                   relocator->sectarray);
+               require_noerr(rval, finish);
+
+               if (reloc->pair_target_type == KXLD_TARGET_LOOKUP) {
+                       rval = get_target_by_address_lookup(&pair_target,
+                           reloc->pair_target, relocator->sectarray);
+                       require_noerr(rval, finish);
+               } else if (reloc->pair_target_type == KXLD_TARGET_VALUE) {
+                       pair_target = reloc->pair_target;
+               }
+               break;
+       case KXLD_TARGET_SECTNUM:
+               require_action(reloc->pair_target_type == KXLD_TARGET_NONE ||
+                   reloc->pair_target_type == KXLD_TARGET_VALUE,
+                   finish, rval = KERN_FAILURE);
+
+               /* Get the target's section by section number */
+               sect = kxld_array_get_item(relocator->sectarray, reloc->target);
+               require_action(sect, finish, rval = KERN_FAILURE);
+
+               /* target is the change in the section's address */
+               target = sect->link_addr - sect->base_addr;
+
+               if (reloc->pair_target_type) {
+                       pair_target = reloc->pair_target;
+               } else {
+                       /* x86_64 needs to know when we have a non-external relocation,
+                        * so we hack that information in here.
+                        */
+                       pair_target = TRUE;
+               }
+               break;
+       case KXLD_TARGET_SYMBOLNUM:
+               require_action(reloc->pair_target_type == KXLD_TARGET_NONE ||
+                   reloc->pair_target_type == KXLD_TARGET_GOT ||
+                   reloc->pair_target_type == KXLD_TARGET_SYMBOLNUM ||
+                   reloc->pair_target_type == KXLD_TARGET_VALUE, finish,
+                   rval = KERN_FAILURE);
+
+               /* Get the target's symbol by symbol number */
+               sym = kxld_symtab_get_symbol_by_index(relocator->symtab, reloc->target);
+               require_action(sym, finish, rval = KERN_FAILURE);
+
+               /* If this symbol is a padslot that has already been replaced, then the
+                * only way a relocation entry can still reference it is if there is a
+                * vtable that has not been patched.  The vtable patcher uses the
+                * MetaClass structure to find classes for patching, so an unpatched
+                * vtable means that there is an OSObject-dervied class that is missing
+                * its OSDeclare/OSDefine macros.
+                */
+               if (kxld_sym_is_padslot(sym) && kxld_sym_is_replaced(sym)) {
+                       kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogRelocatingPatchedSym,
+                           kxld_demangle(sym->name, &demangled_name, &demangled_length));
+               }
+
+               target = sym->link_addr;
+
+               if (kxld_sym_is_vtable(sym)) {
+                       relocator->current_vtable = kxld_dict_find(relocator->vtables, sym->name);
+               }
+
+               /* Some relocation types need the GOT entry address instead of the
+                * symbol's actual address.  These types don't have pair relocation
+                * entries, so we store the GOT entry address as the pair target.
+                */
+               if (reloc->pair_target_type == KXLD_TARGET_VALUE) {
+                       pair_target = reloc->pair_target;
+               } else if (reloc->pair_target_type == KXLD_TARGET_SYMBOLNUM) {
+                       sym = kxld_symtab_get_symbol_by_index(relocator->symtab,
+                           reloc->pair_target);
+                       require_action(sym, finish, rval = KERN_FAILURE);
+                       pair_target = sym->link_addr;
+               } else if (reloc->pair_target_type == KXLD_TARGET_GOT) {
+                       pair_target = sym->got_addr;
+               }
+               break;
+       default:
+               rval = KERN_FAILURE;
+               goto finish;
+       }
+
+       *_target = target;
+       *_pair_target = pair_target;
+       rval = KERN_SUCCESS;
 
 finish:
 
 finish:
-    if (demangled_name) kxld_free(demangled_name, demangled_length);
-    return rval;
+       if (demangled_name) {
+               kxld_free(demangled_name, demangled_length);
+       }
+       return rval;
 }
 
 /*******************************************************************************
 }
 
 /*******************************************************************************
@@ -953,32 +1000,34 @@ static kern_return_t
 get_target_by_address_lookup(kxld_addr_t *target, kxld_addr_t addr,
     const KXLDArray *sectarray)
 {
 get_target_by_address_lookup(kxld_addr_t *target, kxld_addr_t addr,
     const KXLDArray *sectarray)
 {
-    kern_return_t rval = KERN_FAILURE;
-    const KXLDSect *sect = NULL;
-    kxld_addr_t start = 0;
-    kxld_addr_t end = 0;
-    u_int i = 0;
-
-    check(target);
-    check(sectarray);
-    *target = 0;
-
-    for (i = 0; i < sectarray->nitems; ++i) {
-        sect = kxld_array_get_item(sectarray, i);
-        start = sect->base_addr;
-        end = start + sect->size;
-
-        if (start <= addr && addr < end) break;
-        
-        sect = NULL;
-    }
-    require_action(sect, finish, rval=KERN_FAILURE);
-
-    *target = sect->link_addr - sect->base_addr;
-    rval = KERN_SUCCESS;
+       kern_return_t rval = KERN_FAILURE;
+       const KXLDSect *sect = NULL;
+       kxld_addr_t start = 0;
+       kxld_addr_t end = 0;
+       u_int i = 0;
+
+       check(target);
+       check(sectarray);
+       *target = 0;
+
+       for (i = 0; i < sectarray->nitems; ++i) {
+               sect = kxld_array_get_item(sectarray, i);
+               start = sect->base_addr;
+               end = start + sect->size;
+
+               if (start <= addr && addr < end) {
+                       break;
+               }
+
+               sect = NULL;
+       }
+       require_action(sect, finish, rval = KERN_FAILURE);
+
+       *target = sect->link_addr - sect->base_addr;
+       rval = KERN_SUCCESS;
 
 finish:
 
 finish:
-    return rval;
+       return rval;
 }
 
 /*******************************************************************************
 }
 
 /*******************************************************************************
@@ -986,22 +1035,22 @@ finish:
 static kern_return_t
 check_for_direct_pure_virtual_call(const KXLDRelocator *relocator, u_long offset)
 {
 static kern_return_t
 check_for_direct_pure_virtual_call(const KXLDRelocator *relocator, u_long offset)
 {
-    kern_return_t rval = KERN_FAILURE;
-    const KXLDVTableEntry *entry = NULL;
-
-    if (relocator->current_vtable) {
-        entry = kxld_vtable_get_entry_for_offset(relocator->current_vtable, 
-            offset, relocator->is_32_bit);
-        require_action(!entry || !entry->patched.name ||
-            !kxld_sym_name_is_pure_virtual(entry->patched.name),
-            finish, rval=KERN_FAILURE;
-            kxld_log(kKxldLogLinking, kKxldLogErr, 
-                kKxldLogDirectPureVirtualCall));
-    }
-
-    rval = KERN_SUCCESS;
+       kern_return_t rval = KERN_FAILURE;
+       const KXLDVTableEntry *entry = NULL;
+
+       if (relocator->current_vtable) {
+               entry = kxld_vtable_get_entry_for_offset(relocator->current_vtable,
+                   offset, relocator->is_32_bit);
+               require_action(!entry || !entry->patched.name ||
+                   !kxld_sym_name_is_pure_virtual(entry->patched.name),
+                   finish, rval = KERN_FAILURE;
+                   kxld_log(kKxldLogLinking, kKxldLogErr,
+                   kKxldLogDirectPureVirtualCall));
+       }
+
+       rval = KERN_SUCCESS;
 finish:
 finish:
-    return rval;
+       return rval;
 }
 
 #if KXLD_PIC_KEXTS
 }
 
 #if KXLD_PIC_KEXTS
@@ -1010,23 +1059,23 @@ finish:
 static u_long
 get_macho_data_size_for_array(const KXLDArray *relocs)
 {
 static u_long
 get_macho_data_size_for_array(const KXLDArray *relocs)
 {
-    const KXLDReloc *reloc = NULL;
-    u_int i = 0;
-    u_long size = 0;
-
-    check(relocs);
-
-    for (i = 0; i < relocs->nitems; ++i) {
-        reloc = kxld_array_get_item(relocs, i);
-        if (!reloc->pcrel) {
-            size += sizeof(struct relocation_info);
-            if(reloc->pair_target_type != KXLD_TARGET_NONE) {
-                size += sizeof(struct relocation_info);
-            }
-        }
-    }
-
-    return size;
+       const KXLDReloc *reloc = NULL;
+       u_int i = 0;
+       u_long size = 0;
+
+       check(relocs);
+
+       for (i = 0; i < relocs->nitems; ++i) {
+               reloc = kxld_array_get_item(relocs, i);
+               if (!reloc->pcrel) {
+                       size += sizeof(struct relocation_info);
+                       if (reloc->pair_target_type != KXLD_TARGET_NONE) {
+                               size += sizeof(struct relocation_info);
+                       }
+               }
+       }
+
+       return size;
 }
 
 /*******************************************************************************
 }
 
 /*******************************************************************************
@@ -1035,528 +1084,577 @@ static kern_return_t
 export_macho_for_array(const KXLDRelocator *relocator,
     const KXLDArray *relocs, struct relocation_info **dstp)
 {
 export_macho_for_array(const KXLDRelocator *relocator,
     const KXLDArray *relocs, struct relocation_info **dstp)
 {
-    kern_return_t rval = KERN_FAILURE;
-    const KXLDReloc *reloc = NULL;
-    struct relocation_info *dst = NULL;
-    struct scattered_relocation_info *scatdst = NULL;
-    u_int i = 0;
-
-    dst = *dstp;
-
-    for (i = 0; i < relocs->nitems; ++i) {
-        reloc = kxld_array_get_item(relocs, i);
-        scatdst = (struct scattered_relocation_info *) dst;
-
-        if (reloc->pcrel) {
-            continue;
-        }
-
-        switch (reloc->target_type) {
-        case KXLD_TARGET_LOOKUP:
-            scatdst->r_address = reloc->address;
-            scatdst->r_pcrel = reloc->pcrel;
-            scatdst->r_length = reloc->length;
-            scatdst->r_type = reloc->reloc_type;
-            scatdst->r_value = reloc->target;
-            scatdst->r_scattered = 1;
-            break;
-        case KXLD_TARGET_SECTNUM:
-            dst->r_address = reloc->address;
-            dst->r_pcrel = reloc->pcrel;
-            dst->r_length = reloc->length;
-            dst->r_type = reloc->reloc_type;
-            dst->r_symbolnum = reloc->target + 1;
-            dst->r_extern = 0;
-            break;
-        case KXLD_TARGET_SYMBOLNUM:
-           /* Assume that everything will be slid together; otherwise,
-            * there is no sensible value for the section number.
-            */
-            dst->r_address = reloc->address;
-            dst->r_pcrel = reloc->pcrel;
-            dst->r_length = reloc->length;
-            dst->r_type = reloc->reloc_type;
-            dst->r_symbolnum = 1;
-            dst->r_extern = 0;
-            break;
-        default:
-            rval = KERN_FAILURE;
-            goto finish;
-        }
-
-        ++dst;
-
-        if(reloc->pair_target_type != KXLD_TARGET_NONE) {
-            ++i;
-            require_action(i < relocs->nitems, finish, rval=KERN_FAILURE);
-            scatdst = (struct scattered_relocation_info *) dst;
-            switch (reloc->pair_target_type) {
-            case KXLD_TARGET_LOOKUP:
-                scatdst->r_address = reloc->pair_address;
-                scatdst->r_pcrel = reloc->pcrel;
-                scatdst->r_length = reloc->length;
-                scatdst->r_type = relocator->reloc_get_pair_type(reloc->reloc_type);
-                scatdst->r_value = reloc->pair_target;
-                scatdst->r_scattered = 1;
-                break;
-            case KXLD_TARGET_SECTNUM:
-                dst->r_address = reloc->pair_address;
-                dst->r_pcrel = reloc->pcrel;
-                dst->r_length = reloc->length;
-                dst->r_type = relocator->reloc_get_pair_type(reloc->reloc_type);
-                dst->r_symbolnum = reloc->pair_target + 1;
-                dst->r_extern = 0;
-                break;
-            case KXLD_TARGET_SYMBOLNUM:
-                dst->r_address = reloc->pair_address;
-                dst->r_pcrel = reloc->pcrel;
-                dst->r_length = reloc->length;
-                dst->r_type = relocator->reloc_get_pair_type(reloc->reloc_type);
-                dst->r_symbolnum = 1;
-                dst->r_extern = 0;
-                break;
-            default:
-                rval = KERN_FAILURE;
-                goto finish;
-            }
-            ++dst;
-        }
-    }
-
-    rval = KERN_SUCCESS;
+       kern_return_t rval = KERN_FAILURE;
+       const KXLDReloc *reloc = NULL;
+       struct relocation_info *dst = NULL;
+       struct scattered_relocation_info *scatdst = NULL;
+       u_int i = 0;
+
+       dst = *dstp;
+
+       for (i = 0; i < relocs->nitems; ++i) {
+               reloc = kxld_array_get_item(relocs, i);
+               scatdst = (struct scattered_relocation_info *) dst;
+
+               if (reloc->pcrel) {
+                       continue;
+               }
+
+               switch (reloc->target_type) {
+               case KXLD_TARGET_LOOKUP:
+                       if (kaslr_offsets) {
+                               if (kaslr_offsets_index >= kaslr_offsets_count) {
+                                       kxld_log(kKxldLogLinking, kKxldLogErr,
+                                           "kaslr_offsets overflow %d > %d <%s> ",
+                                           kaslr_offsets_index, kaslr_offsets_count,
+                                           __func__);
+                                       abort();
+                               }
+                               // reloc->address is really an offset from the start of the kext
+                               *(kaslr_offsets + kaslr_offsets_index++) = reloc->address;
+                       }
+                       scatdst->r_address = reloc->address;
+                       scatdst->r_pcrel = reloc->pcrel;
+                       scatdst->r_length = reloc->length;
+                       scatdst->r_type = reloc->reloc_type;
+                       scatdst->r_value = reloc->target;
+                       scatdst->r_scattered = 1;
+                       break;
+               case KXLD_TARGET_SECTNUM:
+                       if (kaslr_offsets) {
+                               if (kaslr_offsets_index >= kaslr_offsets_count) {
+                                       kxld_log(kKxldLogLinking, kKxldLogErr,
+                                           "kaslr_offsets overflow <%s> ", __func__);
+                                       abort();
+                               }
+                               // reloc->address is really an offset from the start of the kext
+                               *(kaslr_offsets + kaslr_offsets_index++) = reloc->address;
+                       }
+                       dst->r_address = reloc->address;
+                       dst->r_pcrel = reloc->pcrel;
+                       dst->r_length = reloc->length;
+                       dst->r_type = reloc->reloc_type;
+                       dst->r_symbolnum = reloc->target + 1;
+                       dst->r_extern = 0;
+                       break;
+               case KXLD_TARGET_SYMBOLNUM:
+                       /* Assume that everything will be slid together; otherwise,
+                        * there is no sensible value for the section number.
+                        */
+                       if (kaslr_offsets) {
+                               if (kaslr_offsets_index >= kaslr_offsets_count) {
+                                       kxld_log(kKxldLogLinking, kKxldLogErr,
+                                           "kaslr_offsets overflow <%s> ", __func__);
+                                       abort();
+                               }
+                               // reloc->address is really an offset from the start of the kext
+                               *(kaslr_offsets + kaslr_offsets_index++) = reloc->address;
+                       }
+                       dst->r_address = reloc->address;
+                       dst->r_pcrel = reloc->pcrel;
+                       dst->r_length = reloc->length;
+                       dst->r_type = reloc->reloc_type;
+                       dst->r_symbolnum = 1;
+                       dst->r_extern = 0;
+                       break;
+               default:
+                       rval = KERN_FAILURE;
+                       goto finish;
+               }
+
+               ++dst;
+
+               if (reloc->pair_target_type != KXLD_TARGET_NONE) {
+                       ++i;
+                       require_action(i < relocs->nitems, finish, rval = KERN_FAILURE);
+                       scatdst = (struct scattered_relocation_info *) dst;
+                       switch (reloc->pair_target_type) {
+                       case KXLD_TARGET_LOOKUP:
+                               scatdst->r_address = reloc->pair_address;
+                               scatdst->r_pcrel = reloc->pcrel;
+                               scatdst->r_length = reloc->length;
+                               scatdst->r_type = relocator->reloc_get_pair_type(reloc->reloc_type);
+                               scatdst->r_value = reloc->pair_target;
+                               scatdst->r_scattered = 1;
+                               break;
+                       case KXLD_TARGET_SECTNUM:
+                               dst->r_address = reloc->pair_address;
+                               dst->r_pcrel = reloc->pcrel;
+                               dst->r_length = reloc->length;
+                               dst->r_type = relocator->reloc_get_pair_type(reloc->reloc_type);
+                               dst->r_symbolnum = reloc->pair_target + 1;
+                               dst->r_extern = 0;
+                               break;
+                       case KXLD_TARGET_SYMBOLNUM:
+                               dst->r_address = reloc->pair_address;
+                               dst->r_pcrel = reloc->pcrel;
+                               dst->r_length = reloc->length;
+                               dst->r_type = relocator->reloc_get_pair_type(reloc->reloc_type);
+                               dst->r_symbolnum = 1;
+                               dst->r_extern = 0;
+                               break;
+                       default:
+                               rval = KERN_FAILURE;
+                               goto finish;
+                       }
+                       ++dst;
+               }
+       }
+
+       rval = KERN_SUCCESS;
 finish:
 finish:
-    *dstp = dst;
-    return rval;
+       *dstp = dst;
+       return rval;
 }
 #endif /* KXLD_PIC_KEXTS */
 
 }
 #endif /* KXLD_PIC_KEXTS */
 
-#if KXLD_USER_OR_I386 
+#if KXLD_USER_OR_I386
 /*******************************************************************************
 *******************************************************************************/
 static boolean_t
 generic_reloc_has_pair(u_int _type)
 {
 /*******************************************************************************
 *******************************************************************************/
 static boolean_t
 generic_reloc_has_pair(u_int _type)
 {
-    enum reloc_type_generic type = _type;
+       enum reloc_type_generic type = _type;
 
 
-    return (type == GENERIC_RELOC_SECTDIFF || 
-        type == GENERIC_RELOC_LOCAL_SECTDIFF);
+       return type == GENERIC_RELOC_SECTDIFF ||
+              type == GENERIC_RELOC_LOCAL_SECTDIFF;
 }
 
 /*******************************************************************************
 *******************************************************************************/
 }
 
 /*******************************************************************************
 *******************************************************************************/
-static u_int 
+static u_int
 generic_reloc_get_pair_type(u_int _prev_type __unused)
 {
 generic_reloc_get_pair_type(u_int _prev_type __unused)
 {
-    return GENERIC_RELOC_PAIR;
+       return GENERIC_RELOC_PAIR;
 }
 
 /*******************************************************************************
 *******************************************************************************/
 }
 
 /*******************************************************************************
 *******************************************************************************/
-static boolean_t generic_reloc_has_got(u_int _type __unused)
+static boolean_t
+generic_reloc_has_got(u_int _type __unused)
 {
 {
-    return FALSE;
+       return FALSE;
 }
 
 /*******************************************************************************
 *******************************************************************************/
 }
 
 /*******************************************************************************
 *******************************************************************************/
-static kern_return_t 
-generic_process_reloc(const KXLDRelocator *relocator, u_char *instruction, 
-    u_int length, u_int pcrel, kxld_addr_t _base_pc, kxld_addr_t _link_pc, 
-    kxld_addr_t _link_disp __unused, u_int _type, kxld_addr_t _target, 
+static kern_return_t
+generic_process_reloc(const KXLDRelocator *relocator, u_char *instruction,
+    u_int length, u_int pcrel, kxld_addr_t _base_pc, kxld_addr_t _link_pc,
+    kxld_addr_t _link_disp __unused, u_int _type, kxld_addr_t _target,
     kxld_addr_t _pair_target, boolean_t swap __unused)
 {
     kxld_addr_t _pair_target, boolean_t swap __unused)
 {
-    kern_return_t rval = KERN_FAILURE;
-    uint32_t base_pc = (uint32_t) _base_pc;
-    uint32_t link_pc = (uint32_t) _link_pc;
-    uint32_t *instr_addr = NULL;
-    uint32_t instr_data = 0;
-    uint32_t target = (uint32_t) _target;
-    uint32_t pair_target = (uint32_t) _pair_target;
-    enum reloc_type_generic type = _type;
+       kern_return_t rval = KERN_FAILURE;
+       uint32_t base_pc = (uint32_t) _base_pc;
+       uint32_t link_pc = (uint32_t) _link_pc;
+       uint32_t *instr_addr = NULL;
+       uint32_t instr_data = 0;
+       uint32_t target = (uint32_t) _target;
+       uint32_t pair_target = (uint32_t) _pair_target;
+       enum reloc_type_generic type = _type;
 
 
-    check(instruction);
-    require_action(length == 2, finish, rval=KERN_FAILURE);
+       check(instruction);
+       require_action(length == 2, finish, rval = KERN_FAILURE);
 
 
-    if (pcrel) target = target + base_pc - link_pc;
+       if (pcrel) {
+               target = target + base_pc - link_pc;
+       }
 
 
-    instr_addr = (uint32_t *) ((void *) instruction);
-    instr_data = *instr_addr;
+       instr_addr = (uint32_t *) ((void *) instruction);
+       instr_data = *instr_addr;
 
 #if !KERNEL
 
 #if !KERNEL
-    if (swap) instr_data = OSSwapInt32(instr_data);
+       if (swap) {
+               instr_data = OSSwapInt32(instr_data);
+       }
 #endif
 
 #endif
 
-    rval = check_for_direct_pure_virtual_call(relocator, instr_data);
-    require_noerr(rval, finish);
-
-    switch (type) {
-    case GENERIC_RELOC_VANILLA:
-        instr_data += target;
-        break;
-    case GENERIC_RELOC_SECTDIFF:
-    case GENERIC_RELOC_LOCAL_SECTDIFF:
-        instr_data = instr_data + target - pair_target;
-        break;
-    case GENERIC_RELOC_PB_LA_PTR:
-        rval = KERN_FAILURE;
-        goto finish;
-    case GENERIC_RELOC_PAIR:
-    default:
-        rval = KERN_FAILURE;
-        goto finish;
-    }
+       rval = check_for_direct_pure_virtual_call(relocator, instr_data);
+       require_noerr(rval, finish);
+
+       switch (type) {
+       case GENERIC_RELOC_VANILLA:
+               instr_data += target;
+               break;
+       case GENERIC_RELOC_SECTDIFF:
+       case GENERIC_RELOC_LOCAL_SECTDIFF:
+               instr_data = instr_data + target - pair_target;
+               break;
+       case GENERIC_RELOC_PB_LA_PTR:
+               rval = KERN_FAILURE;
+               goto finish;
+       case GENERIC_RELOC_PAIR:
+       default:
+               rval = KERN_FAILURE;
+               goto finish;
+       }
 
 #if !KERNEL
 
 #if !KERNEL
-    if (swap) instr_data = OSSwapInt32(instr_data);
+       if (swap) {
+               instr_data = OSSwapInt32(instr_data);
+       }
 #endif
 
 #endif
 
-    *instr_addr = instr_data;
+       *instr_addr = instr_data;
 
 
-    rval = KERN_SUCCESS;
+       rval = KERN_SUCCESS;
 
 finish:
 
 finish:
-    return rval;
+       return rval;
 }
 #endif /* KXLD_USER_OR_I386 */
 
 #if KXLD_USER_OR_X86_64
 /*******************************************************************************
 *******************************************************************************/
 }
 #endif /* KXLD_USER_OR_I386 */
 
 #if KXLD_USER_OR_X86_64
 /*******************************************************************************
 *******************************************************************************/
-static boolean_t 
+static boolean_t
 x86_64_reloc_has_pair(u_int _type)
 {
 x86_64_reloc_has_pair(u_int _type)
 {
-    enum reloc_type_x86_64 type = _type;
+       enum reloc_type_x86_64 type = _type;
 
 
-    return (type == X86_64_RELOC_SUBTRACTOR);
+       return type == X86_64_RELOC_SUBTRACTOR;
 }
 
 /*******************************************************************************
 *******************************************************************************/
 }
 
 /*******************************************************************************
 *******************************************************************************/
-static u_int 
+static u_int
 x86_64_reloc_get_pair_type(u_int _prev_type __unused)
 {
 x86_64_reloc_get_pair_type(u_int _prev_type __unused)
 {
-    return X86_64_RELOC_UNSIGNED;
+       return X86_64_RELOC_UNSIGNED;
 }
 
 /*******************************************************************************
 *******************************************************************************/
 }
 
 /*******************************************************************************
 *******************************************************************************/
-static boolean_t 
+static boolean_t
 x86_64_reloc_has_got(u_int _type)
 {
 x86_64_reloc_has_got(u_int _type)
 {
-    enum reloc_type_x86_64 type = _type;
+       enum reloc_type_x86_64 type = _type;
 
 
-    return (type == X86_64_RELOC_GOT_LOAD || type == X86_64_RELOC_GOT);
+       return type == X86_64_RELOC_GOT_LOAD || type == X86_64_RELOC_GOT;
 }
 
 /*******************************************************************************
 *******************************************************************************/
 }
 
 /*******************************************************************************
 *******************************************************************************/
-static kern_return_t 
-x86_64_process_reloc(const KXLDRelocator *relocator __unused, u_char *instruction, 
-    u_int length, u_int pcrel, kxld_addr_t _base_pc __unused, 
-    kxld_addr_t _link_pc, kxld_addr_t _link_disp, u_int _type, 
+static kern_return_t
+x86_64_process_reloc(const KXLDRelocator *relocator __unused, u_char *instruction,
+    u_int length, u_int pcrel, kxld_addr_t _base_pc __unused,
+    kxld_addr_t _link_pc, kxld_addr_t _link_disp, u_int _type,
     kxld_addr_t _target, kxld_addr_t _pair_target, boolean_t swap __unused)
 {
     kxld_addr_t _target, kxld_addr_t _pair_target, boolean_t swap __unused)
 {
-    kern_return_t rval = KERN_FAILURE;
-    enum reloc_type_x86_64 type = _type;
-    int32_t *instr32p = NULL;
-    int32_t instr32 = 0;
-    uint64_t *instr64p = NULL;
-    uint64_t instr64 = 0;
-    uint64_t target = _target;
-    uint64_t pair_target = _pair_target;
-    uint64_t link_pc = (uint64_t) _link_pc;
-    uint64_t link_disp = (uint64_t) _link_disp;
-    uint64_t adjustment = 0;
-
-    check(instruction);
-    require_action(length == 2 || length == 3, 
-        finish, rval=KERN_FAILURE);
-
-    if (length == 2) {
-        instr32p = (int32_t *) ((void *) instruction);
-        instr32 = *instr32p;
+       kern_return_t rval = KERN_FAILURE;
+       enum reloc_type_x86_64 type = _type;
+       int32_t *instr32p = NULL;
+       int32_t instr32 = 0;
+       uint64_t *instr64p = NULL;
+       uint64_t instr64 = 0;
+       uint64_t target = _target;
+       uint64_t pair_target = _pair_target;
+       uint64_t link_pc = (uint64_t) _link_pc;
+       uint64_t link_disp = (uint64_t) _link_disp;
+       uint64_t adjustment = 0;
+
+       check(instruction);
+       require_action(length == 2 || length == 3,
+           finish, rval = KERN_FAILURE);
+
+       if (length == 2) {
+               instr32p = (int32_t *) ((void *) instruction);
+               instr32 = *instr32p;
 
 #if !KERNEL
 
 #if !KERNEL
-        if (swap) instr32 = OSSwapInt32(instr32);
+               if (swap) {
+                       instr32 = OSSwapInt32(instr32);
+               }
 #endif
 
 #endif
 
-        rval = check_for_direct_pure_virtual_call(relocator, instr32);
-        require_noerr(rval, finish);
-
-        /* There are a number of different small adjustments for pc-relative
-         * relocation entries.  The general case is to subtract the size of the
-         * relocation (represented by the length parameter), and it applies to
-         * the GOT types and external SIGNED types.  The non-external signed types
-         * have a different adjustment corresponding to the specific type.
-         */
-        switch (type) {
-        case X86_64_RELOC_SIGNED:
-            if (pair_target) {
-                adjustment = 0;    
-                break;
-            }
-            /* Fall through */
-        case X86_64_RELOC_SIGNED_1:
-            if (pair_target) {
-                adjustment = 1;
-                break;
-            }
-            /* Fall through */
-        case X86_64_RELOC_SIGNED_2:
-            if (pair_target) {
-                adjustment = 2;
-                break;
-            }
-            /* Fall through */
-        case X86_64_RELOC_SIGNED_4:
-            if (pair_target) {
-                adjustment = 4;
-                break;
-            }
-            /* Fall through */
-        case X86_64_RELOC_BRANCH:
-        case X86_64_RELOC_GOT:
-        case X86_64_RELOC_GOT_LOAD:
-            adjustment = (1 << length);
-            break;
-        default:
-            break;
-        }
-
-        /* Perform the actual relocation.  All of the 32-bit relocations are 
-         * pc-relative except for SUBTRACTOR, so a good chunk of the logic is
-         * stuck in calculate_displacement_x86_64.  The signed relocations are
-         * a special case, because when they are non-external, the instruction
-         * already contains the pre-relocation displacement, so we only need to
-         * find the difference between how far the PC was relocated, and how
-         * far the target is relocated.  Since the target variable already
-         * contains the difference between the target's base and link
-         * addresses, we add the difference between the PC's base and link
-         * addresses to the adjustment variable.  This will yield the
-         * appropriate displacement in calculate_displacement.
-         */
-        switch (type) {
-        case X86_64_RELOC_BRANCH:
-            require_action(pcrel, finish, rval=KERN_FAILURE);
-            adjustment += link_pc;
-            break;
-        case X86_64_RELOC_SIGNED:
-        case X86_64_RELOC_SIGNED_1:
-        case X86_64_RELOC_SIGNED_2:
-        case X86_64_RELOC_SIGNED_4:
-            require_action(pcrel, finish, rval=KERN_FAILURE);
-            adjustment += (pair_target) ? (link_disp) : (link_pc);
-            break;
-        case X86_64_RELOC_GOT:
-        case X86_64_RELOC_GOT_LOAD:
-            require_action(pcrel, finish, rval=KERN_FAILURE);
-            adjustment += link_pc;
-            target = pair_target;
-            break;
-        case X86_64_RELOC_SUBTRACTOR:
-            require_action(!pcrel, finish, rval=KERN_FAILURE);
-            instr32 = (int32_t) (target - pair_target);
-            break;
-        case X86_64_RELOC_UNSIGNED:
-        default:
-            rval = KERN_FAILURE;
-            goto finish;
-        }
-
-        /* Call calculate_displacement for the pc-relative relocations */
-        if (pcrel) {
-            rval = calculate_displacement_x86_64(target, adjustment, &instr32); 
-            require_noerr(rval, finish);
-        }
+               rval = check_for_direct_pure_virtual_call(relocator, instr32);
+               require_noerr(rval, finish);
+
+               /* There are a number of different small adjustments for pc-relative
+                * relocation entries.  The general case is to subtract the size of the
+                * relocation (represented by the length parameter), and it applies to
+                * the GOT types and external SIGNED types.  The non-external signed types
+                * have a different adjustment corresponding to the specific type.
+                */
+               switch (type) {
+               case X86_64_RELOC_SIGNED:
+                       if (pair_target) {
+                               adjustment = 0;
+                               break;
+                       }
+                       OS_FALLTHROUGH;
+               case X86_64_RELOC_SIGNED_1:
+                       if (pair_target) {
+                               adjustment = 1;
+                               break;
+                       }
+                       OS_FALLTHROUGH;
+               case X86_64_RELOC_SIGNED_2:
+                       if (pair_target) {
+                               adjustment = 2;
+                               break;
+                       }
+                       OS_FALLTHROUGH;
+               case X86_64_RELOC_SIGNED_4:
+                       if (pair_target) {
+                               adjustment = 4;
+                               break;
+                       }
+                       OS_FALLTHROUGH;
+               case X86_64_RELOC_BRANCH:
+               case X86_64_RELOC_GOT:
+               case X86_64_RELOC_GOT_LOAD:
+                       adjustment = (1 << length);
+                       break;
+               default:
+                       break;
+               }
+
+               /* Perform the actual relocation.  All of the 32-bit relocations are
+                * pc-relative except for SUBTRACTOR, so a good chunk of the logic is
+                * stuck in calculate_displacement_x86_64.  The signed relocations are
+                * a special case, because when they are non-external, the instruction
+                * already contains the pre-relocation displacement, so we only need to
+                * find the difference between how far the PC was relocated, and how
+                * far the target is relocated.  Since the target variable already
+                * contains the difference between the target's base and link
+                * addresses, we add the difference between the PC's base and link
+                * addresses to the adjustment variable.  This will yield the
+                * appropriate displacement in calculate_displacement.
+                */
+               switch (type) {
+               case X86_64_RELOC_BRANCH:
+                       require_action(pcrel, finish, rval = KERN_FAILURE);
+                       adjustment += link_pc;
+                       break;
+               case X86_64_RELOC_SIGNED:
+               case X86_64_RELOC_SIGNED_1:
+               case X86_64_RELOC_SIGNED_2:
+               case X86_64_RELOC_SIGNED_4:
+                       require_action(pcrel, finish, rval = KERN_FAILURE);
+                       adjustment += (pair_target) ? (link_disp) : (link_pc);
+                       break;
+               case X86_64_RELOC_GOT:
+               case X86_64_RELOC_GOT_LOAD:
+                       require_action(pcrel, finish, rval = KERN_FAILURE);
+                       adjustment += link_pc;
+                       target = pair_target;
+                       break;
+               case X86_64_RELOC_SUBTRACTOR:
+                       require_action(!pcrel, finish, rval = KERN_FAILURE);
+                       instr32 = (int32_t) (target - pair_target);
+                       break;
+               case X86_64_RELOC_UNSIGNED:
+               default:
+                       rval = KERN_FAILURE;
+                       goto finish;
+               }
+
+               /* Call calculate_displacement for the pc-relative relocations */
+               if (pcrel) {
+                       rval = calculate_displacement_x86_64(target, adjustment, &instr32);
+                       require_noerr(rval, finish);
+               }
 
 #if !KERNEL
 
 #if !KERNEL
-        if (swap) instr32 = OSSwapInt32(instr32);
+               if (swap) {
+                       instr32 = OSSwapInt32(instr32);
+               }
 #endif
 
 #endif
 
-        *instr32p = instr32;
-    } else {
-        instr64p = (uint64_t *) ((void *) instruction);
-        instr64 = *instr64p;
+               *instr32p = instr32;
+       } else {
+               instr64p = (uint64_t *) ((void *) instruction);
+               instr64 = *instr64p;
 
 #if !KERNEL
 
 #if !KERNEL
-        if (swap) instr64 = OSSwapInt64(instr64);
+               if (swap) {
+                       instr64 = OSSwapInt64(instr64);
+               }
 #endif
 
 #endif
 
-        rval = check_for_direct_pure_virtual_call(relocator, (u_long) instr64);
-        require_noerr(rval, finish);
-
-        switch (type) {
-        case X86_64_RELOC_UNSIGNED:
-            require_action(!pcrel, finish, rval=KERN_FAILURE);
-            
-            instr64 += target;
-            break;
-        case X86_64_RELOC_SUBTRACTOR:
-            require_action(!pcrel, finish, rval=KERN_FAILURE);
-
-            instr64 = target - pair_target;
-            break;
-        case X86_64_RELOC_SIGNED_1:
-        case X86_64_RELOC_SIGNED_2:
-        case X86_64_RELOC_SIGNED_4:
-        case X86_64_RELOC_GOT_LOAD:
-        case X86_64_RELOC_BRANCH:
-        case X86_64_RELOC_SIGNED:
-        case X86_64_RELOC_GOT:
-        default:
-            rval = KERN_FAILURE;
-            goto finish;
-        }
+               rval = check_for_direct_pure_virtual_call(relocator, (u_long) instr64);
+               require_noerr(rval, finish);
+
+               switch (type) {
+               case X86_64_RELOC_UNSIGNED:
+                       require_action(!pcrel, finish, rval = KERN_FAILURE);
+
+                       instr64 += target;
+                       break;
+               case X86_64_RELOC_SUBTRACTOR:
+                       require_action(!pcrel, finish, rval = KERN_FAILURE);
+
+                       instr64 = target - pair_target;
+                       break;
+               case X86_64_RELOC_SIGNED_1:
+               case X86_64_RELOC_SIGNED_2:
+               case X86_64_RELOC_SIGNED_4:
+               case X86_64_RELOC_GOT_LOAD:
+               case X86_64_RELOC_BRANCH:
+               case X86_64_RELOC_SIGNED:
+               case X86_64_RELOC_GOT:
+               default:
+                       rval = KERN_FAILURE;
+                       goto finish;
+               }
 
 #if !KERNEL
 
 #if !KERNEL
-        if (swap) instr64 = OSSwapInt64(instr64);
+               if (swap) {
+                       instr64 = OSSwapInt64(instr64);
+               }
 #endif
 #endif
+               *instr64p = instr64;
+       }
 
 
-        *instr64p = instr64;
-    }
-
-    rval = KERN_SUCCESS;
+       rval = KERN_SUCCESS;
 
 finish:
 
 finish:
-    return rval;
+       return rval;
 }
 
 /*******************************************************************************
 *******************************************************************************/
 static kern_return_t
 }
 
 /*******************************************************************************
 *******************************************************************************/
 static kern_return_t
-calculate_displacement_x86_64(uint64_t target, uint64_t adjustment, 
+calculate_displacement_x86_64(uint64_t target, uint64_t adjustment,
     int32_t *instr32)
 {
     int32_t *instr32)
 {
-    kern_return_t rval = KERN_FAILURE;
-    int64_t displacement;
-    uint64_t difference;
+       kern_return_t rval = KERN_FAILURE;
+       int64_t displacement;
+       uint64_t difference;
 
 
-    displacement = *instr32 + target - adjustment;
-    difference = ABSOLUTE_VALUE(displacement);
-    require_action(difference < X86_64_RIP_RELATIVE_LIMIT, finish, 
-        rval=KERN_FAILURE;
-        kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogRelocationOverflow));
+       displacement = *instr32 + target - adjustment;
+       difference = ABSOLUTE_VALUE(displacement);
+       require_action(difference < X86_64_RIP_RELATIVE_LIMIT, finish,
+           rval = KERN_FAILURE;
+           kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogRelocationOverflow));
 
 
-    *instr32 = (int32_t) displacement;
-    rval = KERN_SUCCESS;
+       *instr32 = (int32_t) displacement;
+       rval = KERN_SUCCESS;
 
 finish:
 
 finish:
-    return rval;
+       return rval;
 }
 #endif /* KXLD_USER_OR_X86_64 */
 
 #if KXLD_USER_OR_ARM
 /*******************************************************************************
 *******************************************************************************/
 }
 #endif /* KXLD_USER_OR_X86_64 */
 
 #if KXLD_USER_OR_ARM
 /*******************************************************************************
 *******************************************************************************/
-static boolean_t 
+static boolean_t
 arm_reloc_has_pair(u_int _type)
 {
 arm_reloc_has_pair(u_int _type)
 {
-    enum reloc_type_arm type = _type;
-
-    switch(type) {
-    case ARM_RELOC_SECTDIFF:
-        return TRUE;
-    default:
-        return FALSE;
-    }
-    return FALSE;
+       enum reloc_type_arm type = _type;
+
+       switch (type) {
+       case ARM_RELOC_SECTDIFF:
+               return TRUE;
+       default:
+               return FALSE;
+       }
+       return FALSE;
 }
 
 /*******************************************************************************
 *******************************************************************************/
 }
 
 /*******************************************************************************
 *******************************************************************************/
-static u_int 
+static u_int
 arm_reloc_get_pair_type(u_int _prev_type __unused)
 {
 arm_reloc_get_pair_type(u_int _prev_type __unused)
 {
-    return ARM_RELOC_PAIR;
+       return ARM_RELOC_PAIR;
 }
 
 /*******************************************************************************
 *******************************************************************************/
 }
 
 /*******************************************************************************
 *******************************************************************************/
-static boolean_t 
+static boolean_t
 arm_reloc_has_got(u_int _type __unused)
 {
 arm_reloc_has_got(u_int _type __unused)
 {
-    return FALSE;
+       return FALSE;
 }
 
 /*******************************************************************************
 *******************************************************************************/
 }
 
 /*******************************************************************************
 *******************************************************************************/
-static kern_return_t 
-arm_process_reloc(const KXLDRelocator *relocator __unused, u_char *instruction, 
-    u_int length, u_int pcrel, kxld_addr_t _base_pc __unused, 
+static kern_return_t
+arm_process_reloc(const KXLDRelocator *relocator __unused, u_char *instruction,
+    u_int length, u_int pcrel, kxld_addr_t _base_pc __unused,
     kxld_addr_t _link_pc __unused, kxld_addr_t _link_disp __unused,
     kxld_addr_t _link_pc __unused, kxld_addr_t _link_disp __unused,
-    u_int _type __unused, kxld_addr_t _target __unused, 
-    kxld_addr_t _pair_target __unused,  boolean_t swap __unused)
+    u_int _type __unused, kxld_addr_t _target __unused,
+    kxld_addr_t _pair_target __unused, boolean_t swap __unused)
 {
 {
-    kern_return_t rval = KERN_FAILURE;
-    uint32_t *instr_addr = NULL;
-    uint32_t instr_data = 0;
-    uint32_t base_pc = (uint32_t) _base_pc;
-    uint32_t link_pc = (uint32_t) _link_pc;
-    uint32_t target = (uint32_t) _target;
-    int32_t displacement = 0;
-    enum reloc_type_arm type = _type;
-
-    check(instruction);
-    require_action(length == 2, finish, rval=KERN_FAILURE);
-
-    if (pcrel) displacement = target + base_pc - link_pc;
-
-    instr_addr = (uint32_t *) ((void *) instruction);
-    instr_data = *instr_addr;
-    
+       kern_return_t rval = KERN_FAILURE;
+       uint32_t *instr_addr = NULL;
+       uint32_t instr_data = 0;
+       uint32_t base_pc = (uint32_t) _base_pc;
+       uint32_t link_pc = (uint32_t) _link_pc;
+       uint32_t target = (uint32_t) _target;
+       int32_t displacement = 0;
+       enum reloc_type_arm type = _type;
+
+       check(instruction);
+       require_action(length == 2, finish, rval = KERN_FAILURE);
+
+       if (pcrel) {
+               displacement = target + base_pc - link_pc;
+       }
+
+       instr_addr = (uint32_t *) ((void *) instruction);
+       instr_data = *instr_addr;
+
 #if !KERNEL
 #if !KERNEL
-    if (swap) instr_data = OSSwapInt32(instr_data);
+       if (swap) {
+               instr_data = OSSwapInt32(instr_data);
+       }
 #endif
 
 #endif
 
-    rval = check_for_direct_pure_virtual_call(relocator, instr_data);
-    require_noerr(rval, finish);
-
-    switch (type) {
-    case ARM_RELOC_VANILLA:
-        instr_data += target;
-        break;
-
-    /*
-     * If the displacement is 0 (the offset between the pc and the target has
-     * not changed), then we don't need to do anything for BR24 and BR22
-     * relocs.  As it turns out, because kexts build with -mlong-calls all
-     * relocations currently end up being either vanilla (handled above) or 
-     * BR22/BR24 with a displacement of 0.
-     * We could handle other displacements here but to keep things simple, we
-     * won't until it is needed (at which point the kernelcache will fail to
-     * link)
-     */
-    case ARM_RELOC_BR24:
-        require_action(pcrel, finish, rval=KERN_FAILURE);
-        require_action(displacement == 0, finish, rval=KERN_FAILURE);
-        break;
-    case ARM_THUMB_RELOC_BR22:
-        require_action(pcrel, finish, rval=KERN_FAILURE);
-        require_action(displacement == 0, finish, rval=KERN_FAILURE);
-        break;
-
-    case ARM_RELOC_SECTDIFF:
-    case ARM_RELOC_LOCAL_SECTDIFF:
-    case ARM_RELOC_PB_LA_PTR:
-        rval = KERN_FAILURE;
-        goto finish;
-
-    case ARM_RELOC_PAIR:
-    default:
-        rval = KERN_FAILURE;
-        goto finish;
-    }
+       rval = check_for_direct_pure_virtual_call(relocator, instr_data);
+       require_noerr(rval, finish);
+
+       switch (type) {
+       case ARM_RELOC_VANILLA:
+               instr_data += target;
+               break;
+
+       /*
+        * If the displacement is 0 (the offset between the pc and the target has
+        * not changed), then we don't need to do anything for BR24 and BR22
+        * relocs.  As it turns out, because kexts build with -mlong-calls all
+        * relocations currently end up being either vanilla (handled above) or
+        * BR22/BR24 with a displacement of 0.
+        * We could handle other displacements here but to keep things simple, we
+        * won't until it is needed (at which point the kernelcache will fail to
+        * link)
+        */
+       case ARM_RELOC_BR24:
+               require_action(pcrel, finish, rval = KERN_FAILURE);
+               require_action(displacement == 0, finish, rval = KERN_FAILURE);
+               break;
+       case ARM_THUMB_RELOC_BR22:
+               require_action(pcrel, finish, rval = KERN_FAILURE);
+               require_action(displacement == 0, finish, rval = KERN_FAILURE);
+               break;
+
+       case ARM_RELOC_SECTDIFF:
+       case ARM_RELOC_LOCAL_SECTDIFF:
+       case ARM_RELOC_PB_LA_PTR:
+               rval = KERN_FAILURE;
+               goto finish;
+
+       case ARM_RELOC_PAIR:
+       default:
+               rval = KERN_FAILURE;
+               goto finish;
+       }
 
 #if !KERNEL
 
 #if !KERNEL
-    if (swap) instr_data = OSSwapInt32(instr_data);
+       if (swap) {
+               instr_data = OSSwapInt32(instr_data);
+       }
 #endif
 
 #endif
 
-    *instr_addr = instr_data;
+       *instr_addr = instr_data;
 
 
-    rval = KERN_SUCCESS;
+       rval = KERN_SUCCESS;
 
 finish:
 
 finish:
-    return rval;
+       return rval;
 }
 
 #endif /* KXLD_USER_OR_ARM */
 }
 
 #endif /* KXLD_USER_OR_ARM */
@@ -1567,7 +1665,7 @@ finish:
 boolean_t
 arm64_reloc_has_pair(u_int _type)
 {
 boolean_t
 arm64_reloc_has_pair(u_int _type)
 {
-    return (_type == ARM64_RELOC_SUBTRACTOR);
+       return _type == ARM64_RELOC_SUBTRACTOR;
 }
 
 /*******************************************************************************
 }
 
 /*******************************************************************************
@@ -1575,11 +1673,11 @@ arm64_reloc_has_pair(u_int _type)
 u_int
 arm64_reloc_get_pair_type(u_int _prev_type __unused)
 {
 u_int
 arm64_reloc_get_pair_type(u_int _prev_type __unused)
 {
-    if (_prev_type == ARM64_RELOC_SUBTRACTOR) {
-        return ARM64_RELOC_UNSIGNED;
-    } else {
-        return -1u;
-    }
+       if (_prev_type == ARM64_RELOC_SUBTRACTOR) {
+               return ARM64_RELOC_UNSIGNED;
+       } else {
+               return -1u;
+       }
 }
 
 /*******************************************************************************
 }
 
 /*******************************************************************************
@@ -1587,8 +1685,8 @@ arm64_reloc_get_pair_type(u_int _prev_type __unused)
 boolean_t
 arm64_reloc_has_got(u_int _type)
 {
 boolean_t
 arm64_reloc_has_got(u_int _type)
 {
-    return (_type == ARM64_RELOC_GOT_LOAD_PAGE21 ||
-            _type == ARM64_RELOC_GOT_LOAD_PAGEOFF12);
+       return _type == ARM64_RELOC_GOT_LOAD_PAGE21 ||
+              _type == ARM64_RELOC_GOT_LOAD_PAGEOFF12;
 }
 
 /*******************************************************************************
 }
 
 /*******************************************************************************
@@ -1599,77 +1697,86 @@ arm64_process_reloc(const KXLDRelocator *relocator __unused, u_char *instruction
     kxld_addr_t _link_disp __unused, u_int _type, kxld_addr_t _target,
     kxld_addr_t _pair_target __unused, boolean_t swap)
 {
     kxld_addr_t _link_disp __unused, u_int _type, kxld_addr_t _target,
     kxld_addr_t _pair_target __unused, boolean_t swap)
 {
-    kern_return_t rval = KERN_FAILURE;
-    enum reloc_type_arm64 type = _type;
-    uint64_t target = _target;
-    uint64_t link_pc = (uint64_t) _link_pc;
-    uint64_t difference = 0;
-    int64_t displacement = 0;
-    uint32_t addend = 0;
+       kern_return_t rval = KERN_FAILURE;
+       enum reloc_type_arm64 type = _type;
+       uint64_t target = _target;
+       uint64_t link_pc = (uint64_t) _link_pc;
+       uint64_t difference = 0;
+       int64_t displacement = 0;
+       uint32_t addend = 0;
 
 
-    check(instruction);
-    require_action((length == 2 || length == 3), finish, rval=KERN_FAILURE);
+       check(instruction);
+       require_action((length == 2 || length == 3), finish, rval = KERN_FAILURE);
 
 
-    if (length == 2) {
-        uint32_t *instr32p = (uint32_t *) (void *) instruction;
-        uint32_t instr32 = *instr32p;
+       if (length == 2) {
+               uint32_t *instr32p = (uint32_t *) (void *) instruction;
+               uint32_t instr32 = *instr32p;
 
 #if !KERNEL
 
 #if !KERNEL
-        if (swap) instr32 = OSSwapInt32(instr32);
+               if (swap) {
+                       instr32 = OSSwapInt32(instr32);
+               }
 #endif
 
 #endif
 
-        switch (type) {
-        case ARM64_RELOC_BRANCH26:
-            require_action(pcrel, finish, rval=KERN_FAILURE);
-            addend = (instr32 & 0x03FFFFFF) << 2;
-            addend = SIGN_EXTEND(addend, 27);
-            displacement = (target - link_pc + addend);
-            difference = ABSOLUTE_VALUE(displacement);
-            displacement = (displacement >> 2);
-            require_action(difference < (128 * 1024 * 1024), finish,
-                           rval = KERN_FAILURE;
-                           kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogRelocationOverflow));
-            instr32 = (instr32 & 0xFC000000) | (displacement & 0x03FFFFFF);
-            break;
-
-        default:
-            rval = KERN_FAILURE;
-            goto finish;
-        }
+               switch (type) {
+               case ARM64_RELOC_BRANCH26:
+                       require_action(pcrel, finish, rval = KERN_FAILURE);
+                       addend = (instr32 & 0x03FFFFFF) << 2;
+                       addend = SIGN_EXTEND(addend, 27);
+                       displacement = (target - link_pc + addend);
+                       difference = ABSOLUTE_VALUE(displacement);
+                       displacement = (displacement >> 2);
+                       require_action(difference < (128 * 1024 * 1024), finish,
+                           rval = KERN_FAILURE;
+                           kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogRelocationOverflow));
+                       instr32 = (instr32 & 0xFC000000) | (displacement & 0x03FFFFFF);
+                       break;
+
+               default:
+                       rval = KERN_FAILURE;
+                       goto finish;
+               }
 
 #if !KERNEL
 
 #if !KERNEL
-        if (swap) instr32 = OSSwapInt32(instr32);
+               if (swap) {
+                       instr32 = OSSwapInt32(instr32);
+               }
 #endif
 
 #endif
 
-        *instr32p = instr32;
-    } else { /* length == 3 */
-        uint64_t *instr64p = (uint64_t *) (void *) instruction;
-        uint64_t instr64 = *instr64p;
+               *instr32p = instr32;
+       } else { /* length == 3 */
+               uint64_t *instr64p = (uint64_t *) (void *) instruction;
+               uint64_t instr64 = *instr64p;
 
 #if !KERNEL
 
 #if !KERNEL
-        if (swap) instr64 = OSSwapInt64(instr64);
+               if (swap) {
+                       instr64 = OSSwapInt64(instr64);
+               }
 #endif
 
 #endif
 
-        switch (type) {
-        case ARM64_RELOC_UNSIGNED:
-            require_action(!pcrel, finish, rval=KERN_FAILURE);
-            instr64 += target;
-            break;
-        default:
-            rval = KERN_FAILURE;
-            goto finish;
-        }
+               switch (type) {
+               case ARM64_RELOC_UNSIGNED:
+                       require_action(!pcrel, finish, rval = KERN_FAILURE);
+                       instr64 += target;
+                       break;
+               default:
+                       rval = KERN_FAILURE;
+                       goto finish;
+               }
 
 #if !KERNEL
 
 #if !KERNEL
-        if (swap) instr64 = OSSwapInt64(instr64);
+               if (swap) {
+                       instr64 = OSSwapInt64(instr64);
+               }
 #endif
 
 #endif
 
-        *instr64p = instr64;
-    }
+               *instr64p = instr64;
+       }
 
 
-    rval = KERN_SUCCESS;
+       rval = KERN_SUCCESS;
 finish:
 finish:
-    return rval;
+       return rval;
 }
 
 }
 
+
 #endif /* KXLD_USER_OR_ARM64 */
 #endif /* KXLD_USER_OR_ARM64 */