- 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;