2 * Copyright (c) 2007-2008 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 #include <mach/boolean.h>
30 #include <sys/types.h>
33 #include <libkern/libkern.h>
34 #include <mach/machine.h>
37 #include <libkern/OSByteOrder.h>
39 /* Get machine.h from the kernel source so we can support all platforms
40 * that the kernel supports. Otherwise we're at the mercy of the host.
42 #include "../../osfmk/mach/machine.h"
45 #define DEBUG_ASSERT_COMPONENT_NAME_STRING "kxld"
46 #include <AssertMacros.h>
48 #include "kxld_array.h"
49 #include "kxld_demangle.h"
50 #include "kxld_dict.h"
51 #include "kxld_reloc.h"
52 #include "kxld_sect.h"
55 #include "kxld_symtab.h"
56 #include "kxld_util.h"
57 #include "kxld_vtable.h"
60 /* This will try to pull in mach/machine.h, so it has to come after the
61 * explicit include above.
63 #include <mach-o/loader.h>
66 /* include target-specific relocation prototypes */
67 #include <mach-o/reloc.h>
68 #if KXLD_USER_OR_X86_64
69 #include <mach-o/x86_64/reloc.h>
72 #include <mach-o/arm/reloc.h>
75 #define KXLD_TARGET_NONE (u_int) 0x0
76 #define KXLD_TARGET_VALUE (u_int) 0x1
77 #define KXLD_TARGET_SECTNUM (u_int) 0x2
78 #define KXLD_TARGET_SYMBOLNUM (u_int) 0x3
79 #define KXLD_TARGET_LOOKUP (u_int) 0x4
80 #define KXLD_TARGET_GOT (u_int) 0x5
82 #define ABSOLUTE_VALUE(x) (((x) < 0) ? -(x) : (x))
84 #define LO16(x) (0x0000FFFF & x)
85 #define LO16S(x) ((0x0000FFFF & x) << 16)
86 #define HI16(x) (0xFFFF0000 & x)
87 #define HI16S(x) ((0xFFFF0000 & x) >> 16)
88 #define BIT15(x) (0x00008000 & x)
89 #define BR14I(x) (0xFFFF0003 & x)
90 #define BR14D(x) (0x0000FFFC & x)
91 #define BR24I(x) (0xFC000003 & x)
92 #define BR24D(x) (0x03FFFFFC & x)
93 #define HADISP 0x00010000
94 #define BR14_LIMIT 0x00008000
95 #define BR24_LIMIT 0x02000000
96 #define IS_COND_BR_INSTR(x) ((x & 0xFC000000) == 0x40000000)
97 #define IS_NOT_ALWAYS_TAKEN(x) ((x & 0x03E00000) != 0x02800000)
98 #define FLIP_PREDICT_BIT(x) x ^= 0x00200000
100 #define SIGN_EXTEND_MASK(n) (1 << ((n) - 1))
101 #define SIGN_EXTEND(x,n) (((x) ^ SIGN_EXTEND_MASK(n)) - SIGN_EXTEND_MASK(n))
102 #define BR14_NBITS_DISPLACEMENT 16
103 #define BR24_NBITS_DISPLACEMENT 26
105 #define X86_64_RIP_RELATIVE_LIMIT 0x80000000UL
107 /*******************************************************************************
109 *******************************************************************************/
110 #if KXLD_USER_OR_I386
111 static boolean_t
generic_reloc_has_pair(u_int _type
)
112 __attribute__((const));
113 static u_int
generic_reloc_get_pair_type(u_int _prev_type
)
114 __attribute__((const));
115 static boolean_t
generic_reloc_has_got(u_int _type
)
116 __attribute__((const));
117 static kern_return_t
generic_process_reloc(const KXLDRelocator
*relocator
,
118 u_char
*instruction
, u_int length
, u_int pcrel
, kxld_addr_t base_pc
,
119 kxld_addr_t link_pc
, kxld_addr_t link_disp
, u_int type
, kxld_addr_t target
,
120 kxld_addr_t pair_target
, boolean_t swap
);
121 #endif /* KXLD_USER_OR_I386 */
123 #if KXLD_USER_OR_X86_64
124 static boolean_t
x86_64_reloc_has_pair(u_int _type
)
125 __attribute__((const));
126 static u_int
x86_64_reloc_get_pair_type(u_int _prev_type
)
127 __attribute__((const));
128 static boolean_t
x86_64_reloc_has_got(u_int _type
)
129 __attribute__((const));
130 static kern_return_t
x86_64_process_reloc(const KXLDRelocator
*relocator
,
131 u_char
*instruction
, u_int length
, u_int pcrel
, kxld_addr_t base_pc
,
132 kxld_addr_t link_pc
, kxld_addr_t link_disp
, u_int type
, kxld_addr_t target
,
133 kxld_addr_t pair_target
, boolean_t swap
);
134 static kern_return_t
calculate_displacement_x86_64(uint64_t target
,
135 uint64_t adjustment
, int32_t *instr32
);
136 #endif /* KXLD_USER_OR_X86_64 */
139 static boolean_t
arm_reloc_has_pair(u_int _type
)
140 __attribute__((const));
141 static u_int
arm_reloc_get_pair_type(u_int _prev_type
)
142 __attribute__((const));
143 static boolean_t
arm_reloc_has_got(u_int _type
)
144 __attribute__((const));
145 static kern_return_t
arm_process_reloc(const KXLDRelocator
*relocator
,
146 u_char
*instruction
, u_int length
, u_int pcrel
, kxld_addr_t base_pc
,
147 kxld_addr_t link_pc
, kxld_addr_t link_disp
, u_int type
, kxld_addr_t target
,
148 kxld_addr_t pair_target
, boolean_t swap
);
149 #endif /* KXLD_USER_OR_ARM */
151 #if KXLD_USER_OR_ILP32
152 static kxld_addr_t
get_pointer_at_addr_32(const KXLDRelocator
*relocator
,
153 const u_char
*data
, u_long offset
)
154 __attribute__((pure
, nonnull
));
155 #endif /* KXLD_USER_OR_ILP32 */
156 #if KXLD_USER_OR_LP64
157 static kxld_addr_t
get_pointer_at_addr_64(const KXLDRelocator
*relocator
,
158 const u_char
*data
, u_long offset
)
159 __attribute__((pure
, nonnull
));
160 #endif /* KXLD_USER_OR_LP64 */
162 static u_int
count_relocatable_relocs(const KXLDRelocator
*relocator
,
163 const struct relocation_info
*relocs
, u_int nrelocs
)
164 __attribute__((pure
));
166 static kern_return_t
calculate_targets(KXLDRelocator
*relocator
,
167 kxld_addr_t
*_target
, kxld_addr_t
*_pair_target
, const KXLDReloc
*reloc
);
169 static kxld_addr_t
align_raw_function_address(const KXLDRelocator
*relocator
,
172 static kern_return_t
get_target_by_address_lookup(kxld_addr_t
*target
,
173 kxld_addr_t addr
, const KXLDArray
*sectarray
);
175 static kern_return_t
check_for_direct_pure_virtual_call(
176 const KXLDRelocator
*relocator
, u_long offset
);
179 static u_long
get_macho_data_size_for_array(const KXLDArray
*relocs
);
181 static kern_return_t
export_macho_for_array(const KXLDRelocator
*relocator
,
182 const KXLDArray
*relocs
, struct relocation_info
**dstp
);
183 #endif /* KXLD_PIC_KEXTS */
185 /*******************************************************************************
186 *******************************************************************************/
188 kxld_relocator_init(KXLDRelocator
*relocator
, u_char
*file
,
189 const KXLDSymtab
*symtab
, const KXLDArray
*sectarray
, cpu_type_t cputype
,
190 cpu_subtype_t cpusubtype __unused
, boolean_t swap
)
192 kern_return_t rval
= KERN_FAILURE
;
197 #if KXLD_USER_OR_I386
199 relocator
->reloc_has_pair
= generic_reloc_has_pair
;
200 relocator
->reloc_get_pair_type
= generic_reloc_get_pair_type
;
201 relocator
->reloc_has_got
= generic_reloc_has_got
;
202 relocator
->process_reloc
= generic_process_reloc
;
203 relocator
->function_align
= 0;
204 relocator
->is_32_bit
= TRUE
;
205 relocator
->may_scatter
= TRUE
;
207 #endif /* KXLD_USER_OR_I386 */
208 #if KXLD_USER_OR_X86_64
209 case CPU_TYPE_X86_64
:
210 relocator
->reloc_has_pair
= x86_64_reloc_has_pair
;
211 relocator
->reloc_get_pair_type
= x86_64_reloc_get_pair_type
;
212 relocator
->reloc_has_got
= x86_64_reloc_has_got
;
213 relocator
->process_reloc
= x86_64_process_reloc
;
214 relocator
->function_align
= 0;
215 relocator
->is_32_bit
= FALSE
;
216 relocator
->may_scatter
= FALSE
;
218 #endif /* KXLD_USER_OR_X86_64 */
221 relocator
->reloc_has_pair
= arm_reloc_has_pair
;
222 relocator
->reloc_get_pair_type
= arm_reloc_get_pair_type
;
223 relocator
->reloc_has_got
= arm_reloc_has_got
;
224 relocator
->process_reloc
= arm_process_reloc
;
225 relocator
->function_align
= 1;
226 relocator
->is_32_bit
= TRUE
;
227 relocator
->may_scatter
= FALSE
;
229 #endif /* KXLD_USER_OR_ARM */
233 kxld_log(kKxldLogLinking
, kKxldLogErr
,
234 kKxldLogArchNotSupported
, cputype
);
238 relocator
->file
= file
;
239 relocator
->symtab
= symtab
;
240 relocator
->sectarray
= sectarray
;
241 relocator
->is_32_bit
= kxld_is_32_bit(cputype
);
242 relocator
->swap
= swap
;
250 /*******************************************************************************
251 *******************************************************************************/
253 kxld_reloc_create_macho(KXLDArray
*relocarray
, const KXLDRelocator
*relocator
,
254 const struct relocation_info
*srcs
, u_int nsrcs
)
256 kern_return_t rval
= KERN_FAILURE
;
257 KXLDReloc
*reloc
= NULL
;
259 const struct relocation_info
*src
= NULL
;
260 const struct scattered_relocation_info
*scatsrc
= NULL
;
262 u_int reloc_index
= 0;
267 /* If there are no relocation entries, just return */
273 /* Count the number of non-pair relocs */
274 nrelocs
= count_relocatable_relocs(relocator
, srcs
, nsrcs
);
278 /* Allocate the array of relocation entries */
280 rval
= kxld_array_init(relocarray
, sizeof(KXLDReloc
), nrelocs
);
281 require_noerr(rval
, finish
);
283 /* Initialize the relocation entries */
285 for (i
= 0; i
< nsrcs
; ++i
) {
287 scatsrc
= (const struct scattered_relocation_info
*) src
;
289 /* A section-based relocation entry can be skipped for absolute
293 if (!(relocator
->may_scatter
&& (src
->r_address
& R_SCATTERED
)) &&
294 !(src
->r_extern
) && (R_ABS
== src
->r_symbolnum
))
299 /* Pull out the data from the relocation entries. The target_type
300 * depends on the r_extern bit:
301 * Scattered -> Section Lookup by Address
302 * Local (not extern) -> Section by Index
303 * Extern -> Symbolnum by Index
305 reloc
= kxld_array_get_item(relocarray
, reloc_index
++);
306 if (relocator
->may_scatter
&& (src
->r_address
& R_SCATTERED
)) {
307 reloc
->address
= scatsrc
->r_address
;
308 reloc
->pcrel
= scatsrc
->r_pcrel
;
309 reloc
->length
= scatsrc
->r_length
;
310 reloc
->reloc_type
= scatsrc
->r_type
;
311 reloc
->target
= scatsrc
->r_value
;
312 reloc
->target_type
= KXLD_TARGET_LOOKUP
;
314 reloc
->address
= src
->r_address
;
315 reloc
->pcrel
= src
->r_pcrel
;
316 reloc
->length
= src
->r_length
;
317 reloc
->reloc_type
= src
->r_type
;
318 reloc
->target
= src
->r_symbolnum
;
320 if (0 == src
->r_extern
) {
321 reloc
->target_type
= KXLD_TARGET_SECTNUM
;
324 reloc
->target_type
= KXLD_TARGET_SYMBOLNUM
;
328 /* Find the pair entry if it exists */
330 if (relocator
->reloc_has_pair(reloc
->reloc_type
)) {
332 require_action(i
< nsrcs
, finish
, rval
=KERN_FAILURE
);
335 scatsrc
= (const struct scattered_relocation_info
*) src
;
337 if (relocator
->may_scatter
&& (src
->r_address
& R_SCATTERED
)) {
338 require_action(relocator
->reloc_get_pair_type(
339 reloc
->reloc_type
) == scatsrc
->r_type
,
340 finish
, rval
=KERN_FAILURE
);
341 reloc
->pair_address
= scatsrc
->r_address
;
342 reloc
->pair_target
= scatsrc
->r_value
;
343 reloc
->pair_target_type
= KXLD_TARGET_LOOKUP
;
345 require_action(relocator
->reloc_get_pair_type(
346 reloc
->reloc_type
) == scatsrc
->r_type
,
347 finish
, rval
=KERN_FAILURE
);
348 reloc
->pair_address
= scatsrc
->r_address
;
350 reloc
->pair_target
= src
->r_symbolnum
;
351 reloc
->pair_target_type
= KXLD_TARGET_SYMBOLNUM
;
353 reloc
->pair_target
= src
->r_address
;
354 reloc
->pair_target_type
= KXLD_TARGET_VALUE
;
358 reloc
->pair_target
= 0;
359 if (relocator
->reloc_has_got(reloc
->reloc_type
)) {
360 reloc
->pair_target_type
= KXLD_TARGET_GOT
;
362 reloc
->pair_target_type
= KXLD_TARGET_NONE
;
375 /*******************************************************************************
376 * Relocatable relocs :
377 * 1) Are not _PAIR_ relocs
378 * 2) Don't reference N_ABS symbols
379 *******************************************************************************/
381 count_relocatable_relocs(const KXLDRelocator
*relocator
,
382 const struct relocation_info
*relocs
, u_int nrelocs
)
384 u_int num_nonpair_relocs
= 0;
386 const struct relocation_info
*reloc
= NULL
;
387 const struct scattered_relocation_info
*sreloc
= NULL
;
392 /* Loop over all of the relocation entries */
394 num_nonpair_relocs
= 1;
395 for (i
= 1; i
< nrelocs
; ++i
) {
398 if (reloc
->r_address
& R_SCATTERED
) {
399 /* A scattered relocation entry is relocatable as long as it's not a
402 sreloc
= (const struct scattered_relocation_info
*) reloc
;
404 num_nonpair_relocs
+=
405 !relocator
->reloc_has_pair(sreloc
->r_type
);
407 /* A normal relocation entry is relocatable if it is not a pair and
408 * if it is not a section-based relocation for an absolute symbol.
410 num_nonpair_relocs
+=
411 !(relocator
->reloc_has_pair(reloc
->r_type
)
412 || (0 == reloc
->r_extern
&& R_ABS
== reloc
->r_symbolnum
));
417 return num_nonpair_relocs
;
420 /*******************************************************************************
421 *******************************************************************************/
423 kxld_relocator_clear(KXLDRelocator
*relocator
)
425 bzero(relocator
, sizeof(*relocator
));
428 /*******************************************************************************
429 *******************************************************************************/
431 kxld_relocator_has_pair(const KXLDRelocator
*relocator
, u_int r_type
)
435 return relocator
->reloc_has_pair(r_type
);
438 /*******************************************************************************
439 *******************************************************************************/
441 kxld_relocator_get_pair_type(const KXLDRelocator
*relocator
,
446 return relocator
->reloc_get_pair_type(prev_r_type
);
449 /*******************************************************************************
450 *******************************************************************************/
452 kxld_relocator_has_got(const KXLDRelocator
*relocator
, u_int r_type
)
456 return relocator
->reloc_has_got(r_type
);
459 /*******************************************************************************
460 *******************************************************************************/
462 kxld_reloc_get_symbol(const KXLDRelocator
*relocator
, const KXLDReloc
*reloc
,
466 kxld_addr_t value
= 0;
470 switch (reloc
->target_type
) {
471 case KXLD_TARGET_SYMBOLNUM
:
472 sym
= kxld_symtab_get_symbol_by_index(relocator
->symtab
, reloc
->target
);
474 case KXLD_TARGET_SECTNUM
:
476 value
= kxld_relocator_get_pointer_at_addr(relocator
, data
,
478 sym
= kxld_symtab_get_cxx_symbol_by_value(relocator
->symtab
, value
);
489 /*******************************************************************************
490 *******************************************************************************/
492 kxld_reloc_get_reloc_index_by_offset(const KXLDArray
*relocs
,
493 kxld_size_t offset
, u_int
*idx
)
495 kern_return_t rval
= KERN_FAILURE
;
496 KXLDReloc
*reloc
= NULL
;
499 for (i
= 0; i
< relocs
->nitems
; ++i
) {
500 reloc
= kxld_array_get_item(relocs
, i
);
501 if (reloc
->address
== offset
) break;
504 if (i
>= relocs
->nitems
) {
516 /*******************************************************************************
517 *******************************************************************************/
519 kxld_reloc_get_reloc_by_offset(const KXLDArray
*relocs
, kxld_addr_t offset
)
521 kern_return_t rval
= KERN_FAILURE
;
522 KXLDReloc
*reloc
= NULL
;
525 rval
= kxld_reloc_get_reloc_index_by_offset(relocs
, offset
, &i
);
526 if (rval
) goto finish
;
528 reloc
= kxld_array_get_item(relocs
, i
);
535 /*******************************************************************************
536 *******************************************************************************/
538 kxld_reloc_get_macho_header_size()
540 return sizeof(struct dysymtab_command
);
543 /*******************************************************************************
544 *******************************************************************************/
546 kxld_reloc_get_macho_data_size(const KXLDArray
*locrelocs
,
547 const KXLDArray
*extrelocs
)
551 rval
+= get_macho_data_size_for_array(locrelocs
);
552 rval
+= get_macho_data_size_for_array(extrelocs
);
557 /*******************************************************************************
558 *******************************************************************************/
560 kxld_reloc_export_macho(const KXLDRelocator
*relocator
,
561 const KXLDArray
*locrelocs
, const KXLDArray
*extrelocs
,
562 u_char
*buf
, u_long
*header_offset
, u_long header_size
,
563 u_long
*data_offset
, u_long size
)
565 kern_return_t rval
= KERN_FAILURE
;
566 struct dysymtab_command
*dysymtabhdr
= NULL
;
567 struct relocation_info
*start
= NULL
;
568 struct relocation_info
*dst
= NULL
;
570 u_long data_size
= 0;
575 check(header_offset
);
578 require_action(sizeof(*dysymtabhdr
) <= header_size
- *header_offset
, finish
, rval
=KERN_FAILURE
);
579 dysymtabhdr
= (struct dysymtab_command
*) ((void *) (buf
+ *header_offset
));
580 *header_offset
+= sizeof(*dysymtabhdr
);
582 data_size
= kxld_reloc_get_macho_data_size(locrelocs
, extrelocs
);
583 require_action((*data_offset
+ data_size
) <= size
, finish
, rval
=KERN_FAILURE
);
585 start
= dst
= (struct relocation_info
*) ((void *) (buf
+ *data_offset
));
587 rval
= export_macho_for_array(relocator
, locrelocs
, &dst
);
588 require_noerr(rval
, finish
);
590 rval
= export_macho_for_array(relocator
, extrelocs
, &dst
);
591 require_noerr(rval
, finish
);
595 memset(dysymtabhdr
, 0, sizeof(*dysymtabhdr
));
596 dysymtabhdr
->cmd
= LC_DYSYMTAB
;
597 dysymtabhdr
->cmdsize
= (uint32_t) sizeof(*dysymtabhdr
);
598 dysymtabhdr
->locreloff
= (uint32_t) *data_offset
;
599 dysymtabhdr
->nlocrel
= (uint32_t) count
;
601 *data_offset
+= count
* sizeof(struct relocation_info
);
607 #endif /* KXLD_PIC_KEXTS */
609 /*******************************************************************************
610 *******************************************************************************/
612 kxld_relocator_get_pointer_at_addr(const KXLDRelocator
*relocator
,
613 const u_char
*data
, u_long offset
)
617 KXLD_3264_FUNC(relocator
->is_32_bit
, value
,
618 get_pointer_at_addr_32
, get_pointer_at_addr_64
,
619 relocator
, data
, offset
);
624 #if KXLD_USER_OR_ILP32
625 /*******************************************************************************
626 *******************************************************************************/
628 get_pointer_at_addr_32(const KXLDRelocator
*relocator
,
629 const u_char
*data
, u_long offset
)
635 addr
= *(const uint32_t *) ((void *) (data
+ offset
));
637 if (relocator
->swap
) {
638 addr
= OSSwapInt32(addr
);
642 return align_raw_function_address(relocator
, addr
);
644 #endif /* KXLD_USER_OR_ILP32 */
646 #if KXLD_USER_OR_LP64
647 /*******************************************************************************
648 *******************************************************************************/
650 get_pointer_at_addr_64(const KXLDRelocator
*relocator
,
651 const u_char
*data
, u_long offset
)
657 addr
= *(const uint64_t *) ((void *) (data
+ offset
));
659 if (relocator
->swap
) {
660 addr
= OSSwapInt64(addr
);
664 return align_raw_function_address(relocator
, addr
);
666 #endif /* KXLD_USER_OR_LP64 */
668 /*******************************************************************************
669 *******************************************************************************/
671 kxld_relocator_set_vtables(KXLDRelocator
*relocator
, const KXLDDict
*vtables
)
673 relocator
->vtables
= vtables
;
676 /*******************************************************************************
677 * When we're inspecting the raw binary and not the symbol table, value may
678 * hold a THUMB address (with bit 0 set to 1) but the index will have the real
679 * address (bit 0 set to 0). So if bit 0 is set here, we clear it. This only
680 * impacts ARM for now, but it's implemented as a generic function alignment
682 *******************************************************************************/
684 align_raw_function_address(const KXLDRelocator
*relocator
, kxld_addr_t value
)
686 if (relocator
->function_align
) {
687 value
&= ~((1ULL << relocator
->function_align
) - 1);
693 /*******************************************************************************
694 *******************************************************************************/
696 kxld_relocator_process_sect_reloc(KXLDRelocator
*relocator
,
697 const KXLDReloc
*reloc
, const KXLDSect
*sect
)
699 kern_return_t rval
= KERN_FAILURE
;
700 u_char
*instruction
= NULL
;
701 kxld_addr_t target
= 0;
702 kxld_addr_t pair_target
= 0;
703 kxld_addr_t base_pc
= 0;
704 kxld_addr_t link_pc
= 0;
705 kxld_addr_t link_disp
= 0;
711 /* Find the instruction */
713 instruction
= sect
->data
+ reloc
->address
;
715 /* Calculate the target */
717 rval
= calculate_targets(relocator
, &target
, &pair_target
, reloc
);
718 require_noerr(rval
, finish
);
720 base_pc
= reloc
->address
;
721 link_pc
= base_pc
+ sect
->link_addr
;
722 link_disp
= sect
->link_addr
- sect
->base_addr
;
726 rval
= relocator
->process_reloc(relocator
, instruction
, reloc
->length
,
727 reloc
->pcrel
, base_pc
, link_pc
, link_disp
, reloc
->reloc_type
, target
,
728 pair_target
, relocator
->swap
);
729 require_noerr(rval
, finish
);
733 relocator
->current_vtable
= NULL
;
740 /*******************************************************************************
741 *******************************************************************************/
743 kxld_reloc_update_symindex(KXLDReloc
*reloc
, u_int symindex
)
745 kern_return_t rval
= KERN_FAILURE
;
747 require_action(reloc
->target_type
== KXLD_TARGET_SYMBOLNUM
,
748 finish
, rval
= KERN_FAILURE
);
750 reloc
->target
= symindex
;
758 /*******************************************************************************
759 *******************************************************************************/
761 kxld_relocator_process_table_reloc(KXLDRelocator
*relocator
,
762 const KXLDReloc
*reloc
, const KXLDSeg
*seg
, kxld_addr_t link_addr
)
764 kern_return_t rval
= KERN_FAILURE
;
765 u_char
*instruction
= NULL
;
766 kxld_addr_t target
= 0;
767 kxld_addr_t pair_target
= 0;
768 kxld_addr_t base_pc
= 0;
769 kxld_addr_t link_pc
= 0;
775 /* Find the instruction */
777 offset
= (u_long
)(seg
->fileoff
+ (reloc
->address
- seg
->base_addr
));
778 instruction
= relocator
->file
+ offset
;
780 /* Calculate the target */
782 rval
= calculate_targets(relocator
, &target
, &pair_target
, reloc
);
783 require_noerr(rval
, finish
);
785 base_pc
= reloc
->address
;
786 link_pc
= base_pc
+ link_addr
;
790 rval
= relocator
->process_reloc(relocator
, instruction
, reloc
->length
,
791 reloc
->pcrel
, base_pc
, link_pc
, link_addr
, reloc
->reloc_type
, target
,
792 pair_target
, relocator
->swap
);
793 require_noerr(rval
, finish
);
797 relocator
->current_vtable
= NULL
;
804 /*******************************************************************************
805 *******************************************************************************/
807 calculate_targets(KXLDRelocator
*relocator
, kxld_addr_t
*_target
,
808 kxld_addr_t
*_pair_target
, const KXLDReloc
*reloc
)
810 kern_return_t rval
= KERN_FAILURE
;
811 const KXLDSect
*sect
= NULL
;
812 const KXLDSym
*sym
= NULL
;
813 kxld_addr_t target
= 0;
814 kxld_addr_t pair_target
= 0;
815 char *demangled_name
= NULL
;
816 size_t demangled_length
= 0;
823 /* Find the target based on the lookup type */
825 switch(reloc
->target_type
) {
826 case KXLD_TARGET_LOOKUP
:
827 require_action(reloc
->pair_target_type
== KXLD_TARGET_NONE
||
828 reloc
->pair_target_type
== KXLD_TARGET_LOOKUP
||
829 reloc
->pair_target_type
== KXLD_TARGET_VALUE
,
830 finish
, rval
=KERN_FAILURE
);
832 rval
= get_target_by_address_lookup(&target
, reloc
->target
,
833 relocator
->sectarray
);
834 require_noerr(rval
, finish
);
836 if (reloc
->pair_target_type
== KXLD_TARGET_LOOKUP
) {
837 rval
= get_target_by_address_lookup(&pair_target
,
838 reloc
->pair_target
, relocator
->sectarray
);
839 require_noerr(rval
, finish
);
840 } else if (reloc
->pair_target_type
== KXLD_TARGET_VALUE
) {
841 pair_target
= reloc
->pair_target
;
844 case KXLD_TARGET_SECTNUM
:
845 require_action(reloc
->pair_target_type
== KXLD_TARGET_NONE
||
846 reloc
->pair_target_type
== KXLD_TARGET_VALUE
,
847 finish
, rval
=KERN_FAILURE
);
849 /* Get the target's section by section number */
850 sect
= kxld_array_get_item(relocator
->sectarray
, reloc
->target
);
851 require_action(sect
, finish
, rval
=KERN_FAILURE
);
853 /* target is the change in the section's address */
854 target
= sect
->link_addr
- sect
->base_addr
;
856 if (reloc
->pair_target_type
) {
857 pair_target
= reloc
->pair_target
;
859 /* x86_64 needs to know when we have a non-external relocation,
860 * so we hack that information in here.
865 case KXLD_TARGET_SYMBOLNUM
:
866 require_action(reloc
->pair_target_type
== KXLD_TARGET_NONE
||
867 reloc
->pair_target_type
== KXLD_TARGET_GOT
||
868 reloc
->pair_target_type
== KXLD_TARGET_SYMBOLNUM
||
869 reloc
->pair_target_type
== KXLD_TARGET_VALUE
, finish
,
872 /* Get the target's symbol by symbol number */
873 sym
= kxld_symtab_get_symbol_by_index(relocator
->symtab
, reloc
->target
);
874 require_action(sym
, finish
, rval
=KERN_FAILURE
);
876 /* If this symbol is a padslot that has already been replaced, then the
877 * only way a relocation entry can still reference it is if there is a
878 * vtable that has not been patched. The vtable patcher uses the
879 * MetaClass structure to find classes for patching, so an unpatched
880 * vtable means that there is an OSObject-dervied class that is missing
881 * its OSDeclare/OSDefine macros.
883 require_action(!kxld_sym_is_padslot(sym
) || !kxld_sym_is_replaced(sym
),
884 finish
, rval
=KERN_FAILURE
;
885 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogRelocatingPatchedSym
,
886 kxld_demangle(sym
->name
, &demangled_name
, &demangled_length
)));
888 target
= sym
->link_addr
;
890 if (kxld_sym_is_vtable(sym
)) {
891 relocator
->current_vtable
= kxld_dict_find(relocator
->vtables
, sym
->name
);
894 /* Some relocation types need the GOT entry address instead of the
895 * symbol's actual address. These types don't have pair relocation
896 * entries, so we store the GOT entry address as the pair target.
898 if (reloc
->pair_target_type
== KXLD_TARGET_VALUE
) {
899 pair_target
= reloc
->pair_target
;
900 } else if (reloc
->pair_target_type
== KXLD_TARGET_SYMBOLNUM
) {
901 sym
= kxld_symtab_get_symbol_by_index(relocator
->symtab
,
903 require_action(sym
, finish
, rval
=KERN_FAILURE
);
904 pair_target
= sym
->link_addr
;
905 } else if (reloc
->pair_target_type
== KXLD_TARGET_GOT
) {
906 pair_target
= sym
->got_addr
;
915 *_pair_target
= pair_target
;
919 if (demangled_name
) kxld_free(demangled_name
, demangled_length
);
923 /*******************************************************************************
924 *******************************************************************************/
926 get_target_by_address_lookup(kxld_addr_t
*target
, kxld_addr_t addr
,
927 const KXLDArray
*sectarray
)
929 kern_return_t rval
= KERN_FAILURE
;
930 const KXLDSect
*sect
= NULL
;
931 kxld_addr_t start
= 0;
939 for (i
= 0; i
< sectarray
->nitems
; ++i
) {
940 sect
= kxld_array_get_item(sectarray
, i
);
941 start
= sect
->base_addr
;
942 end
= start
+ sect
->size
;
944 if (start
<= addr
&& addr
< end
) break;
948 require_action(sect
, finish
, rval
=KERN_FAILURE
);
950 *target
= sect
->link_addr
- sect
->base_addr
;
957 /*******************************************************************************
958 *******************************************************************************/
960 check_for_direct_pure_virtual_call(const KXLDRelocator
*relocator
, u_long offset
)
962 kern_return_t rval
= KERN_FAILURE
;
963 const KXLDVTableEntry
*entry
= NULL
;
965 if (relocator
->current_vtable
) {
966 entry
= kxld_vtable_get_entry_for_offset(relocator
->current_vtable
,
967 offset
, relocator
->is_32_bit
);
968 require_action(!entry
|| !entry
->patched
.name
||
969 !kxld_sym_name_is_pure_virtual(entry
->patched
.name
),
970 finish
, rval
=KERN_FAILURE
;
971 kxld_log(kKxldLogLinking
, kKxldLogErr
,
972 kKxldLogDirectPureVirtualCall
));
981 /*******************************************************************************
982 *******************************************************************************/
984 get_macho_data_size_for_array(const KXLDArray
*relocs
)
986 const KXLDReloc
*reloc
= NULL
;
992 for (i
= 0; i
< relocs
->nitems
; ++i
) {
993 reloc
= kxld_array_get_item(relocs
, i
);
995 size
+= sizeof(struct relocation_info
);
996 if(reloc
->pair_target_type
!= KXLD_TARGET_NONE
) {
997 size
+= sizeof(struct relocation_info
);
1005 /*******************************************************************************
1006 *******************************************************************************/
1007 static kern_return_t
1008 export_macho_for_array(const KXLDRelocator
*relocator
,
1009 const KXLDArray
*relocs
, struct relocation_info
**dstp
)
1011 kern_return_t rval
= KERN_FAILURE
;
1012 const KXLDReloc
*reloc
= NULL
;
1013 struct relocation_info
*dst
= NULL
;
1014 struct scattered_relocation_info
*scatdst
= NULL
;
1019 for (i
= 0; i
< relocs
->nitems
; ++i
) {
1020 reloc
= kxld_array_get_item(relocs
, i
);
1021 scatdst
= (struct scattered_relocation_info
*) dst
;
1027 switch (reloc
->target_type
) {
1028 case KXLD_TARGET_LOOKUP
:
1029 scatdst
->r_address
= reloc
->address
;
1030 scatdst
->r_pcrel
= reloc
->pcrel
;
1031 scatdst
->r_length
= reloc
->length
;
1032 scatdst
->r_type
= reloc
->reloc_type
;
1033 scatdst
->r_value
= reloc
->target
;
1034 scatdst
->r_scattered
= 1;
1036 case KXLD_TARGET_SECTNUM
:
1037 dst
->r_address
= reloc
->address
;
1038 dst
->r_pcrel
= reloc
->pcrel
;
1039 dst
->r_length
= reloc
->length
;
1040 dst
->r_type
= reloc
->reloc_type
;
1041 dst
->r_symbolnum
= reloc
->target
+ 1;
1044 case KXLD_TARGET_SYMBOLNUM
:
1045 /* Assume that everything will be slid together; otherwise,
1046 * there is no sensible value for the section number.
1048 dst
->r_address
= reloc
->address
;
1049 dst
->r_pcrel
= reloc
->pcrel
;
1050 dst
->r_length
= reloc
->length
;
1051 dst
->r_type
= reloc
->reloc_type
;
1052 dst
->r_symbolnum
= 1;
1056 rval
= KERN_FAILURE
;
1062 if(reloc
->pair_target_type
!= KXLD_TARGET_NONE
) {
1064 require_action(i
< relocs
->nitems
, finish
, rval
=KERN_FAILURE
);
1065 scatdst
= (struct scattered_relocation_info
*) dst
;
1066 switch (reloc
->pair_target_type
) {
1067 case KXLD_TARGET_LOOKUP
:
1068 scatdst
->r_address
= reloc
->pair_address
;
1069 scatdst
->r_pcrel
= reloc
->pcrel
;
1070 scatdst
->r_length
= reloc
->length
;
1071 scatdst
->r_type
= relocator
->reloc_get_pair_type(reloc
->reloc_type
);
1072 scatdst
->r_value
= reloc
->pair_target
;
1073 scatdst
->r_scattered
= 1;
1075 case KXLD_TARGET_SECTNUM
:
1076 dst
->r_address
= reloc
->pair_address
;
1077 dst
->r_pcrel
= reloc
->pcrel
;
1078 dst
->r_length
= reloc
->length
;
1079 dst
->r_type
= relocator
->reloc_get_pair_type(reloc
->reloc_type
);
1080 dst
->r_symbolnum
= reloc
->pair_target
+ 1;
1083 case KXLD_TARGET_SYMBOLNUM
:
1084 dst
->r_address
= reloc
->pair_address
;
1085 dst
->r_pcrel
= reloc
->pcrel
;
1086 dst
->r_length
= reloc
->length
;
1087 dst
->r_type
= relocator
->reloc_get_pair_type(reloc
->reloc_type
);
1088 dst
->r_symbolnum
= 1;
1092 rval
= KERN_FAILURE
;
1099 rval
= KERN_SUCCESS
;
1104 #endif /* KXLD_PIC_KEXTS */
1106 #if KXLD_USER_OR_I386
1107 /*******************************************************************************
1108 *******************************************************************************/
1110 generic_reloc_has_pair(u_int _type
)
1112 enum reloc_type_generic type
= _type
;
1114 return (type
== GENERIC_RELOC_SECTDIFF
||
1115 type
== GENERIC_RELOC_LOCAL_SECTDIFF
);
1118 /*******************************************************************************
1119 *******************************************************************************/
1121 generic_reloc_get_pair_type(u_int _prev_type __unused
)
1123 return GENERIC_RELOC_PAIR
;
1126 /*******************************************************************************
1127 *******************************************************************************/
1128 static boolean_t
generic_reloc_has_got(u_int _type __unused
)
1133 /*******************************************************************************
1134 *******************************************************************************/
1135 static kern_return_t
1136 generic_process_reloc(const KXLDRelocator
*relocator
, u_char
*instruction
,
1137 u_int length
, u_int pcrel
, kxld_addr_t _base_pc
, kxld_addr_t _link_pc
,
1138 kxld_addr_t _link_disp __unused
, u_int _type
, kxld_addr_t _target
,
1139 kxld_addr_t _pair_target
, boolean_t swap __unused
)
1141 kern_return_t rval
= KERN_FAILURE
;
1142 uint32_t base_pc
= (uint32_t) _base_pc
;
1143 uint32_t link_pc
= (uint32_t) _link_pc
;
1144 uint32_t *instr_addr
= NULL
;
1145 uint32_t instr_data
= 0;
1146 uint32_t target
= (uint32_t) _target
;
1147 uint32_t pair_target
= (uint32_t) _pair_target
;
1148 enum reloc_type_generic type
= _type
;
1151 require_action(length
== 2, finish
, rval
=KERN_FAILURE
);
1153 if (pcrel
) target
= target
+ base_pc
- link_pc
;
1155 instr_addr
= (uint32_t *) ((void *) instruction
);
1156 instr_data
= *instr_addr
;
1159 if (swap
) instr_data
= OSSwapInt32(instr_data
);
1162 rval
= check_for_direct_pure_virtual_call(relocator
, instr_data
);
1163 require_noerr(rval
, finish
);
1166 case GENERIC_RELOC_VANILLA
:
1167 instr_data
+= target
;
1169 case GENERIC_RELOC_SECTDIFF
:
1170 case GENERIC_RELOC_LOCAL_SECTDIFF
:
1171 instr_data
= instr_data
+ target
- pair_target
;
1173 case GENERIC_RELOC_PB_LA_PTR
:
1174 rval
= KERN_FAILURE
;
1176 case GENERIC_RELOC_PAIR
:
1178 rval
= KERN_FAILURE
;
1183 if (swap
) instr_data
= OSSwapInt32(instr_data
);
1186 *instr_addr
= instr_data
;
1188 rval
= KERN_SUCCESS
;
1193 #endif /* KXLD_USER_OR_I386 */
1195 #if KXLD_USER_OR_X86_64
1196 /*******************************************************************************
1197 *******************************************************************************/
1199 x86_64_reloc_has_pair(u_int _type
)
1201 enum reloc_type_x86_64 type
= _type
;
1203 return (type
== X86_64_RELOC_SUBTRACTOR
);
1206 /*******************************************************************************
1207 *******************************************************************************/
1209 x86_64_reloc_get_pair_type(u_int _prev_type __unused
)
1211 return X86_64_RELOC_UNSIGNED
;
1214 /*******************************************************************************
1215 *******************************************************************************/
1217 x86_64_reloc_has_got(u_int _type
)
1219 enum reloc_type_x86_64 type
= _type
;
1221 return (type
== X86_64_RELOC_GOT_LOAD
|| type
== X86_64_RELOC_GOT
);
1224 /*******************************************************************************
1225 *******************************************************************************/
1226 static kern_return_t
1227 x86_64_process_reloc(const KXLDRelocator
*relocator __unused
, u_char
*instruction
,
1228 u_int length
, u_int pcrel
, kxld_addr_t _base_pc __unused
,
1229 kxld_addr_t _link_pc
, kxld_addr_t _link_disp
, u_int _type
,
1230 kxld_addr_t _target
, kxld_addr_t _pair_target
, boolean_t swap __unused
)
1232 kern_return_t rval
= KERN_FAILURE
;
1233 enum reloc_type_x86_64 type
= _type
;
1234 int32_t *instr32p
= NULL
;
1235 int32_t instr32
= 0;
1236 uint64_t *instr64p
= NULL
;
1237 uint64_t instr64
= 0;
1238 uint64_t target
= _target
;
1239 uint64_t pair_target
= _pair_target
;
1240 uint64_t link_pc
= (uint64_t) _link_pc
;
1241 uint64_t link_disp
= (uint64_t) _link_disp
;
1242 uint64_t adjustment
= 0;
1245 require_action(length
== 2 || length
== 3,
1246 finish
, rval
=KERN_FAILURE
);
1249 instr32p
= (int32_t *) ((void *) instruction
);
1250 instr32
= *instr32p
;
1253 if (swap
) instr32
= OSSwapInt32(instr32
);
1256 rval
= check_for_direct_pure_virtual_call(relocator
, instr32
);
1257 require_noerr(rval
, finish
);
1259 /* There are a number of different small adjustments for pc-relative
1260 * relocation entries. The general case is to subtract the size of the
1261 * relocation (represented by the length parameter), and it applies to
1262 * the GOT types and external SIGNED types. The non-external signed types
1263 * have a different adjustment corresponding to the specific type.
1266 case X86_64_RELOC_SIGNED
:
1272 case X86_64_RELOC_SIGNED_1
:
1278 case X86_64_RELOC_SIGNED_2
:
1284 case X86_64_RELOC_SIGNED_4
:
1290 case X86_64_RELOC_BRANCH
:
1291 case X86_64_RELOC_GOT
:
1292 case X86_64_RELOC_GOT_LOAD
:
1293 adjustment
= (1 << length
);
1299 /* Perform the actual relocation. All of the 32-bit relocations are
1300 * pc-relative except for SUBTRACTOR, so a good chunk of the logic is
1301 * stuck in calculate_displacement_x86_64. The signed relocations are
1302 * a special case, because when they are non-external, the instruction
1303 * already contains the pre-relocation displacement, so we only need to
1304 * find the difference between how far the PC was relocated, and how
1305 * far the target is relocated. Since the target variable already
1306 * contains the difference between the target's base and link
1307 * addresses, we add the difference between the PC's base and link
1308 * addresses to the adjustment variable. This will yield the
1309 * appropriate displacement in calculate_displacement.
1312 case X86_64_RELOC_BRANCH
:
1313 require_action(pcrel
, finish
, rval
=KERN_FAILURE
);
1314 adjustment
+= link_pc
;
1316 case X86_64_RELOC_SIGNED
:
1317 case X86_64_RELOC_SIGNED_1
:
1318 case X86_64_RELOC_SIGNED_2
:
1319 case X86_64_RELOC_SIGNED_4
:
1320 require_action(pcrel
, finish
, rval
=KERN_FAILURE
);
1321 adjustment
+= (pair_target
) ? (link_disp
) : (link_pc
);
1323 case X86_64_RELOC_GOT
:
1324 case X86_64_RELOC_GOT_LOAD
:
1325 require_action(pcrel
, finish
, rval
=KERN_FAILURE
);
1326 adjustment
+= link_pc
;
1327 target
= pair_target
;
1329 case X86_64_RELOC_SUBTRACTOR
:
1330 require_action(!pcrel
, finish
, rval
=KERN_FAILURE
);
1331 instr32
= (int32_t) (target
- pair_target
);
1333 case X86_64_RELOC_UNSIGNED
:
1335 rval
= KERN_FAILURE
;
1339 /* Call calculate_displacement for the pc-relative relocations */
1341 rval
= calculate_displacement_x86_64(target
, adjustment
, &instr32
);
1342 require_noerr(rval
, finish
);
1346 if (swap
) instr32
= OSSwapInt32(instr32
);
1349 *instr32p
= instr32
;
1351 instr64p
= (uint64_t *) ((void *) instruction
);
1352 instr64
= *instr64p
;
1355 if (swap
) instr64
= OSSwapInt64(instr64
);
1358 rval
= check_for_direct_pure_virtual_call(relocator
, (u_long
) instr64
);
1359 require_noerr(rval
, finish
);
1362 case X86_64_RELOC_UNSIGNED
:
1363 require_action(!pcrel
, finish
, rval
=KERN_FAILURE
);
1367 case X86_64_RELOC_SUBTRACTOR
:
1368 require_action(!pcrel
, finish
, rval
=KERN_FAILURE
);
1370 instr64
= target
- pair_target
;
1372 case X86_64_RELOC_SIGNED_1
:
1373 case X86_64_RELOC_SIGNED_2
:
1374 case X86_64_RELOC_SIGNED_4
:
1375 case X86_64_RELOC_GOT_LOAD
:
1376 case X86_64_RELOC_BRANCH
:
1377 case X86_64_RELOC_SIGNED
:
1378 case X86_64_RELOC_GOT
:
1380 rval
= KERN_FAILURE
;
1385 if (swap
) instr64
= OSSwapInt64(instr64
);
1388 *instr64p
= instr64
;
1391 rval
= KERN_SUCCESS
;
1397 /*******************************************************************************
1398 *******************************************************************************/
1399 static kern_return_t
1400 calculate_displacement_x86_64(uint64_t target
, uint64_t adjustment
,
1403 kern_return_t rval
= KERN_FAILURE
;
1404 int64_t displacement
;
1405 uint64_t difference
;
1407 displacement
= *instr32
+ target
- adjustment
;
1408 difference
= ABSOLUTE_VALUE(displacement
);
1409 require_action(difference
< X86_64_RIP_RELATIVE_LIMIT
, finish
,
1411 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogRelocationOverflow
));
1413 *instr32
= (int32_t) displacement
;
1414 rval
= KERN_SUCCESS
;
1419 #endif /* KXLD_USER_OR_X86_64 */
1421 #if KXLD_USER_OR_ARM
1422 /*******************************************************************************
1423 *******************************************************************************/
1425 arm_reloc_has_pair(u_int _type
)
1427 enum reloc_type_arm type
= _type
;
1430 case ARM_RELOC_SECTDIFF
:
1438 /*******************************************************************************
1439 *******************************************************************************/
1441 arm_reloc_get_pair_type(u_int _prev_type __unused
)
1443 return ARM_RELOC_PAIR
;
1446 /*******************************************************************************
1447 *******************************************************************************/
1449 arm_reloc_has_got(u_int _type __unused
)
1454 /*******************************************************************************
1455 *******************************************************************************/
1456 static kern_return_t
1457 arm_process_reloc(const KXLDRelocator
*relocator __unused
, u_char
*instruction
,
1458 u_int length
, u_int pcrel
, kxld_addr_t _base_pc __unused
,
1459 kxld_addr_t _link_pc __unused
, kxld_addr_t _link_disp __unused
,
1460 u_int _type __unused
, kxld_addr_t _target __unused
,
1461 kxld_addr_t _pair_target __unused
, boolean_t swap __unused
)
1463 kern_return_t rval
= KERN_FAILURE
;
1464 uint32_t *instr_addr
= NULL
;
1465 uint32_t instr_data
= 0;
1466 uint32_t base_pc
= (uint32_t) _base_pc
;
1467 uint32_t link_pc
= (uint32_t) _link_pc
;
1468 uint32_t target
= (uint32_t) _target
;
1469 int32_t displacement
= 0;
1470 enum reloc_type_arm type
= _type
;
1473 require_action(length
== 2, finish
, rval
=KERN_FAILURE
);
1475 if (pcrel
) displacement
= target
+ base_pc
- link_pc
;
1477 instr_addr
= (uint32_t *) ((void *) instruction
);
1478 instr_data
= *instr_addr
;
1481 if (swap
) instr_data
= OSSwapInt32(instr_data
);
1484 rval
= check_for_direct_pure_virtual_call(relocator
, instr_data
);
1485 require_noerr(rval
, finish
);
1488 case ARM_RELOC_VANILLA
:
1489 instr_data
+= target
;
1493 * If the displacement is 0 (the offset between the pc and the target has
1494 * not changed), then we don't need to do anything for BR24 and BR22
1495 * relocs. As it turns out, because kexts build with -mlong-calls all
1496 * relocations currently end up being either vanilla (handled above) or
1497 * BR22/BR24 with a displacement of 0.
1498 * We could handle other displacements here but to keep things simple, we
1499 * won't until it is needed (at which point the kernelcache will fail to
1502 case ARM_RELOC_BR24
:
1503 require_action(pcrel
, finish
, rval
=KERN_FAILURE
);
1504 require_action(displacement
== 0, finish
, rval
=KERN_FAILURE
);
1506 case ARM_THUMB_RELOC_BR22
:
1507 require_action(pcrel
, finish
, rval
=KERN_FAILURE
);
1508 require_action(displacement
== 0, finish
, rval
=KERN_FAILURE
);
1511 case ARM_RELOC_SECTDIFF
:
1512 case ARM_RELOC_LOCAL_SECTDIFF
:
1513 case ARM_RELOC_PB_LA_PTR
:
1514 rval
= KERN_FAILURE
;
1517 case ARM_RELOC_PAIR
:
1519 rval
= KERN_FAILURE
;
1524 if (swap
) instr_data
= OSSwapInt32(instr_data
);
1527 *instr_addr
= instr_data
;
1529 rval
= KERN_SUCCESS
;
1535 #endif /* KXLD_USER_OR_ARM */