2 * Copyright (c) 2009-2014 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 <sys/types.h>
32 #include <libkern/kernel_mach_header.h>
33 #include <mach/machine.h>
34 #include <mach/vm_param.h>
35 #include <mach-o/fat.h>
37 /* Get machine.h from the kernel source so we can support all platforms
38 * that the kernel supports. Otherwise we're at the mercy of the host.
40 #include "../../osfmk/mach/machine.h"
42 #include <architecture/byte_order.h>
43 #include <mach/mach_init.h>
44 #include <mach-o/arch.h>
45 #include <mach-o/swap.h>
48 #include <mach-o/loader.h>
49 #include <mach-o/nlist.h>
50 #include <mach-o/reloc.h>
52 #define DEBUG_ASSERT_COMPONENT_NAME_STRING "kxld"
53 #include <AssertMacros.h>
55 #include "kxld_demangle.h"
56 #include "kxld_dict.h"
57 #include "kxld_reloc.h"
58 #include "kxld_sect.h"
60 #include "kxld_srcversion.h"
61 #include "kxld_symtab.h"
62 #include "kxld_util.h"
63 #include "kxld_uuid.h"
64 #include "kxld_versionmin.h"
65 #include "kxld_vtable.h"
67 #include "kxld_object.h"
69 /*******************************************************************************
71 *******************************************************************************/
79 cpu_subtype_t cpusubtype
;
84 KXLDRelocator relocator
;
86 KXLDversionmin versionmin
;
87 KXLDsrcversion srcversion
;
89 struct dysymtab_command
*dysymtab_hdr
;
90 kxld_addr_t link_addr
;
91 u_long output_buffer_size
;
93 boolean_t is_final_image
;
95 boolean_t got_is_created
;
96 #if KXLD_USER_OR_OBJECT
97 KXLDArray
*section_order
;
100 boolean_t include_kaslr_relocs
;
103 enum NXByteOrder host_order
;
104 enum NXByteOrder target_order
;
108 /*******************************************************************************
110 *******************************************************************************/
112 static kern_return_t
get_target_machine_info(KXLDObject
*object
,
113 cpu_type_t cputype
, cpu_subtype_t cpusubtype
);
114 static kern_return_t
get_macho_slice_for_arch(KXLDObject
*object
,
115 u_char
*file
, u_long size
);
117 static u_long
get_macho_header_size(const KXLDObject
*object
);
118 static u_long
get_macho_data_size(const KXLDObject
*object
) __unused
;
120 static kern_return_t
init_from_execute(KXLDObject
*object
);
121 static kern_return_t
init_from_final_linked_image(KXLDObject
*object
,
122 u_int
*filetype_out
, struct symtab_command
**symtab_hdr_out
);
124 static boolean_t
target_supports_protected_segments(const KXLDObject
*object
)
125 __attribute__((pure
));
126 static void set_is_object_linked(KXLDObject
*object
);
128 #if KXLD_USER_OR_BUNDLE
129 static boolean_t
target_supports_bundle(const KXLDObject
*object
)
131 static kern_return_t
init_from_bundle(KXLDObject
*object
);
132 static kern_return_t
process_relocs_from_tables(KXLDObject
*object
);
133 static KXLDSeg
*get_seg_by_base_addr(KXLDObject
*object
,
134 kxld_addr_t base_addr
);
135 static kern_return_t
process_symbol_pointers(KXLDObject
*object
);
136 static void add_to_ptr(u_char
*symptr
, kxld_addr_t val
, boolean_t is_32_bit
);
137 #endif /* KXLD_USER_OR_BUNDLE */
139 #if KXLD_USER_OR_OBJECT
140 static boolean_t
target_supports_object(const KXLDObject
*object
)
142 static kern_return_t
init_from_object(KXLDObject
*object
);
143 static kern_return_t
process_relocs_from_sections(KXLDObject
*object
);
144 #endif /* KXLD_USER_OR_OBJECT */
147 static boolean_t
target_supports_slideable_kexts(const KXLDObject
*object
);
148 #endif /* KXLD_PIC_KEXTS */
151 static kern_return_t
export_macho_header(const KXLDObject
*object
, u_char
*buf
,
152 u_int ncmds
, u_long
*header_offset
, u_long header_size
);
153 #if KXLD_USER_OR_ILP32
154 static u_long
get_macho_cmd_data_32(u_char
*file
, u_long offset
,
155 u_int
*filetype
, u_int
*ncmds
);
156 static kern_return_t
export_macho_header_32(const KXLDObject
*object
,
157 u_char
*buf
, u_int ncmds
, u_long
*header_offset
, u_long header_size
);
158 #endif /* KXLD_USER_OR_ILP32 */
159 #if KXLD_USER_OR_LP64
160 static u_long
get_macho_cmd_data_64(u_char
*file
, u_long offset
,
161 u_int
*filetype
, u_int
*ncmds
);
162 static kern_return_t
export_macho_header_64(const KXLDObject
*object
,
163 u_char
*buf
, u_int ncmds
, u_long
*header_offset
, u_long header_size
);
164 #endif /* KXLD_USER_OR_LP64 */
166 #if KXLD_USER_OR_GOT || KXLD_USER_OR_COMMON
167 static kern_return_t
add_section(KXLDObject
*object
, KXLDSect
**sect
);
168 #endif /* KXLD_USER_OR_GOT || KXLD_USER_OR_COMMON */
170 #if KXLD_USER_OR_COMMON
171 static kern_return_t
resolve_common_symbols(KXLDObject
*object
);
172 #endif /* KXLD_USER_OR_COMMON */
175 static boolean_t
target_has_got(const KXLDObject
*object
) __attribute__((pure
));
176 static kern_return_t
create_got(KXLDObject
*object
);
177 static kern_return_t
populate_got(KXLDObject
*object
);
178 #endif /* KXLD_USER_OR_GOT */
180 static KXLDSym
*get_mutable_sym(const KXLDObject
*object
, const KXLDSym
*sym
);
182 static kern_return_t
populate_kmod_info(KXLDObject
*object
);
184 /*******************************************************************************
185 * Prototypes that may need to be exported
186 *******************************************************************************/
187 static boolean_t
kxld_object_target_needs_swap(const KXLDObject
*object __unused
);
188 static KXLDSeg
* kxld_object_get_seg_by_name(const KXLDObject
*object
, const char *segname
);
189 static KXLDSect
* kxld_object_get_sect_by_name(const KXLDObject
*object
, const char *segname
,
190 const char *sectname
);
192 /*******************************************************************************
193 *******************************************************************************/
195 kxld_object_sizeof(void)
197 return sizeof(KXLDObject
);
200 /*******************************************************************************
201 *******************************************************************************/
203 kxld_object_init_from_macho(KXLDObject
*object
, u_char
*file
, u_long size
,
204 const char *name
, KXLDArray
*section_order __unused
,
205 cpu_type_t cputype
, cpu_subtype_t cpusubtype
, KXLDFlags flags __unused
)
207 kern_return_t rval
= KERN_FAILURE
;
208 KXLDSeg
* seg
= NULL
;
217 #if KXLD_USER_OR_OBJECT
218 object
->section_order
= section_order
;
221 object
->include_kaslr_relocs
= ((flags
& kKXLDFlagIncludeRelocs
) == kKXLDFlagIncludeRelocs
);
224 /* Find the local architecture */
226 rval
= get_target_machine_info(object
, cputype
, cpusubtype
);
227 require_noerr(rval
, finish
);
229 /* Find the Mach-O slice for the target architecture */
231 rval
= get_macho_slice_for_arch(object
, file
, size
);
232 require_noerr(rval
, finish
);
234 /* Allocate the symbol table */
236 if (!object
->symtab
) {
237 object
->symtab
= kxld_alloc(kxld_symtab_sizeof());
238 require_action(object
->symtab
, finish
, rval
=KERN_RESOURCE_SHORTAGE
);
239 bzero(object
->symtab
, kxld_symtab_sizeof());
242 /* Build the relocator */
244 rval
= kxld_relocator_init(&object
->relocator
, object
->file
,
245 object
->symtab
, &object
->sects
, object
->cputype
,
246 object
->cpusubtype
, kxld_object_target_needs_swap(object
));
247 require_noerr(rval
, finish
);
249 /* There are four types of Mach-O files that we can support:
250 * 1) 32-bit MH_OBJECT - Snow Leopard and earlier
251 * 2) 32-bit MH_KEXT_BUNDLE - Lion and Later
252 * 3) 64-bit MH_OBJECT - Unsupported
253 * 4) 64-bit MH_KEXT_BUNDLE - Snow Leopard and Later
256 if (kxld_object_is_32_bit(object
)) {
257 struct mach_header
*mach_hdr
= (struct mach_header
*) ((void *) object
->file
);
258 object
->filetype
= mach_hdr
->filetype
;
260 struct mach_header_64
*mach_hdr
= (struct mach_header_64
*) ((void *) object
->file
);
261 object
->filetype
= mach_hdr
->filetype
;
264 switch (object
->filetype
) {
265 #if KXLD_USER_OR_BUNDLE
267 rval
= init_from_bundle(object
);
268 require_noerr(rval
, finish
);
270 #endif /* KXLD_USER_OR_BUNDLE */
271 #if KXLD_USER_OR_OBJECT
273 rval
= init_from_object(object
);
274 require_noerr(rval
, finish
);
276 #endif /* KXLD_USER_OR_OBJECT */
278 object
->is_kernel
= TRUE
;
279 rval
= init_from_execute(object
);
280 require_noerr(rval
, finish
);
284 kxld_log(kKxldLogLinking
, kKxldLogErr
,
285 kKxldLogFiletypeNotSupported
, object
->filetype
);
289 if (!kxld_object_is_kernel(object
)) {
290 for (i
= 0; i
< object
->segs
.nitems
; ++i
) {
291 seg
= kxld_array_get_item(&object
->segs
, i
);
292 kxld_seg_set_vm_protections(seg
,
293 target_supports_protected_segments(object
));
296 seg
= kxld_object_get_seg_by_name(object
, SEG_LINKEDIT
);
298 (void) kxld_seg_populate_linkedit(seg
, object
->symtab
,
299 kxld_object_is_32_bit(object
)
301 , &object
->locrelocs
, &object
->extrelocs
,
302 target_supports_slideable_kexts(object
)
308 (void) set_is_object_linked(object
);
315 /*******************************************************************************
316 *******************************************************************************/
318 get_target_machine_info(KXLDObject
*object
, cpu_type_t cputype __unused
,
319 cpu_subtype_t cpusubtype __unused
)
323 /* Because the kernel can only link for its own architecture, we know what
324 * the host and target architectures are at compile time, so we can use
325 * a vastly simplified version of this function.
330 #if defined(__x86_64__)
331 object
->cputype
= CPU_TYPE_X86_64
;
332 /* FIXME: we need clang to provide a __x86_64h__ macro for the sub-type. Using
333 * __AVX2__ is a temporary solution until this is available. */
334 #if defined(__AVX2__)
335 object
->cpusubtype
= CPU_SUBTYPE_X86_64_H
;
337 object
->cpusubtype
= CPU_SUBTYPE_X86_64_ALL
;
341 kxld_log(kKxldLogLinking
, kKxldLogErr
,
342 kKxldLogArchNotSupported
, _mh_execute_header
->cputype
);
343 return KERN_NOT_SUPPORTED
;
344 #endif /* Supported architecture defines */
349 /* User-space must look up the architecture it's running on and the target
350 * architecture at run-time.
353 kern_return_t rval
= KERN_FAILURE
;
354 const NXArchInfo
*host_arch
= NULL
;
358 host_arch
= NXGetLocalArchInfo();
359 require_action(host_arch
, finish
, rval
=KERN_FAILURE
);
361 object
->host_order
= host_arch
->byteorder
;
363 /* If the user did not specify a cputype, use the local architecture.
367 object
->cputype
= cputype
;
368 object
->cpusubtype
= cpusubtype
;
370 object
->cputype
= host_arch
->cputype
;
371 object
->target_order
= object
->host_order
;
373 switch (object
->cputype
) {
375 object
->cpusubtype
= CPU_SUBTYPE_I386_ALL
;
377 case CPU_TYPE_X86_64
:
378 object
->cpusubtype
= CPU_SUBTYPE_X86_64_ALL
;
381 object
->cpusubtype
= CPU_SUBTYPE_ARM_ALL
;
384 object
->cpusubtype
= CPU_SUBTYPE_ARM64_ALL
;
387 object
->cpusubtype
= 0;
392 /* Validate that we support the target architecture and record its
396 switch(object
->cputype
) {
400 case CPU_TYPE_X86_64
:
401 object
->target_order
= NX_LittleEndian
;
404 rval
= KERN_NOT_SUPPORTED
;
405 kxld_log(kKxldLogLinking
, kKxldLogErr
,
406 kKxldLogArchNotSupported
, object
->cputype
);
417 /*******************************************************************************
418 *******************************************************************************/
420 get_macho_slice_for_arch(KXLDObject
*object
, u_char
*file
, u_long size
)
422 kern_return_t rval
= KERN_FAILURE
;
423 struct mach_header
*mach_hdr
= NULL
;
425 struct fat_header
*fat
= (struct fat_header
*) ((void *) file
);
426 struct fat_arch
*archs
= (struct fat_arch
*) &fat
[1];
427 boolean_t swap
= FALSE
;
437 /* We are assuming that we will never receive a fat file in the kernel */
440 require_action(size
>= sizeof(*fat
), finish
,
442 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
444 /* The fat header is always big endian, so swap if necessary */
445 if (fat
->magic
== FAT_CIGAM
) {
446 (void) swap_fat_header(fat
, object
->host_order
);
450 if (fat
->magic
== FAT_MAGIC
) {
451 struct fat_arch
*arch
= NULL
;
453 require_action(size
>= (sizeof(*fat
) + (fat
->nfat_arch
* sizeof(*archs
))),
456 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
458 /* Swap the fat_arch structures if necessary */
460 (void) swap_fat_arch(archs
, fat
->nfat_arch
, object
->host_order
);
463 /* Locate the Mach-O for the requested architecture */
465 arch
= NXFindBestFatArch(object
->cputype
, object
->cpusubtype
, archs
, fat
->nfat_arch
);
466 require_action(arch
, finish
, rval
=KERN_FAILURE
;
467 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogArchNotFound
));
468 require_action(size
>= arch
->offset
+ arch
->size
, finish
,
470 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
472 object
->file
= file
+ arch
->offset
;
473 object
->size
= arch
->size
;
477 /* Swap the Mach-O's headers to this architecture if necessary */
478 if (kxld_object_is_32_bit(object
)) {
479 rval
= validate_and_swap_macho_32(object
->file
, object
->size
485 rval
= validate_and_swap_macho_64(object
->file
, object
->size
491 require_noerr(rval
, finish
);
493 mach_hdr
= (struct mach_header
*) ((void *) object
->file
);
494 require_action(object
->cputype
== mach_hdr
->cputype
, finish
,
496 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogTruncatedMachO
));
497 object
->cpusubtype
= mach_hdr
->cpusubtype
; /* <rdar://problem/16008438> */
504 /*******************************************************************************
505 *******************************************************************************/
507 init_from_final_linked_image(KXLDObject
*object
, u_int
*filetype_out
,
508 struct symtab_command
**symtab_hdr_out
)
510 kern_return_t rval
= KERN_FAILURE
;
512 KXLDSect
*sect
= NULL
;
513 struct load_command
*cmd_hdr
= NULL
;
514 struct symtab_command
*symtab_hdr
= NULL
;
515 struct uuid_command
*uuid_hdr
= NULL
;
516 struct version_min_command
*versionmin_hdr
= NULL
;
517 struct source_version_command
*source_version_hdr
= NULL
;
518 u_long base_offset
= 0;
520 u_long sect_offset
= 0;
530 KXLD_3264_FUNC(kxld_object_is_32_bit(object
), base_offset
,
531 get_macho_cmd_data_32
, get_macho_cmd_data_64
,
532 object
->file
, offset
, &filetype
, &ncmds
);
534 /* First pass to count segments and sections */
536 offset
= base_offset
;
537 for (i
= 0; i
< ncmds
; ++i
, offset
+= cmd_hdr
->cmdsize
) {
538 cmd_hdr
= (struct load_command
*) ((void *) (object
->file
+ offset
));
540 switch(cmd_hdr
->cmd
) {
541 #if KXLD_USER_OR_ILP32
544 struct segment_command
*seg_hdr
=
545 (struct segment_command
*) cmd_hdr
;
547 /* Ignore segments with no vm size */
548 if (!seg_hdr
->vmsize
) continue;
551 nsects
+= seg_hdr
->nsects
;
554 #endif /* KXLD_USER_OR_ILP32 */
555 #if KXLD_USER_OR_LP64
558 struct segment_command_64
*seg_hdr
=
559 (struct segment_command_64
*) ((void *) cmd_hdr
);
561 /* Ignore segments with no vm size */
562 if (!seg_hdr
->vmsize
) continue;
565 nsects
+= seg_hdr
->nsects
;
568 #endif /* KXLD_USER_OR_LP64 */
574 /* Allocate the segments and sections */
577 rval
= kxld_array_init(&object
->segs
, sizeof(KXLDSeg
), nsegs
);
578 require_noerr(rval
, finish
);
580 rval
= kxld_array_init(&object
->sects
, sizeof(KXLDSect
), nsects
);
581 require_noerr(rval
, finish
);
584 /* Initialize the segments and sections */
586 offset
= base_offset
;
587 for (i
= 0; i
< ncmds
; ++i
, offset
+= cmd_hdr
->cmdsize
) {
588 cmd_hdr
= (struct load_command
*) ((void *) (object
->file
+ offset
));
591 switch(cmd_hdr
->cmd
) {
592 #if KXLD_USER_OR_ILP32
595 struct segment_command
*seg_hdr
=
596 (struct segment_command
*) cmd_hdr
;
598 /* Ignore segments with no vm size */
599 if (!seg_hdr
->vmsize
) continue;
601 seg
= kxld_array_get_item(&object
->segs
, segi
++);
603 rval
= kxld_seg_init_from_macho_32(seg
, seg_hdr
);
604 require_noerr(rval
, finish
);
606 sect_offset
= offset
+ sizeof(*seg_hdr
);
609 #endif /* KXLD_USER_OR_ILP32 */
610 #if KXLD_USER_OR_LP64
613 struct segment_command_64
*seg_hdr
=
614 (struct segment_command_64
*) ((void *) cmd_hdr
);
616 /* Ignore segments with no vm size */
617 if (!seg_hdr
->vmsize
) continue;
619 seg
= kxld_array_get_item(&object
->segs
, segi
++);
621 rval
= kxld_seg_init_from_macho_64(seg
, seg_hdr
);
622 require_noerr(rval
, finish
);
624 sect_offset
= offset
+ sizeof(*seg_hdr
);
627 #endif /* KXLD_USER_OR_LP64 */
629 symtab_hdr
= (struct symtab_command
*) cmd_hdr
;
632 uuid_hdr
= (struct uuid_command
*) cmd_hdr
;
633 kxld_uuid_init_from_macho(&object
->uuid
, uuid_hdr
);
635 case LC_VERSION_MIN_MACOSX
:
636 case LC_VERSION_MIN_IPHONEOS
:
637 case LC_VERSION_MIN_WATCHOS
:
638 versionmin_hdr
= (struct version_min_command
*) cmd_hdr
;
639 kxld_versionmin_init_from_macho(&object
->versionmin
, versionmin_hdr
);
641 case LC_SOURCE_VERSION
:
642 source_version_hdr
= (struct source_version_command
*) (void *) cmd_hdr
;
643 kxld_srcversion_init_from_macho(&object
->srcversion
, source_version_hdr
);
646 object
->dysymtab_hdr
= (struct dysymtab_command
*) cmd_hdr
;
648 rval
= kxld_reloc_create_macho(&object
->extrelocs
, &object
->relocator
,
649 (struct relocation_info
*) ((void *) (object
->file
+ object
->dysymtab_hdr
->extreloff
)),
650 object
->dysymtab_hdr
->nextrel
);
651 require_noerr(rval
, finish
);
653 rval
= kxld_reloc_create_macho(&object
->locrelocs
, &object
->relocator
,
654 (struct relocation_info
*) ((void *) (object
->file
+ object
->dysymtab_hdr
->locreloff
)),
655 object
->dysymtab_hdr
->nlocrel
);
656 require_noerr(rval
, finish
);
661 /* Don't need to do anything with UNIXTHREAD or MAIN for the kernel */
662 require_action(kxld_object_is_kernel(object
),
663 finish
, rval
=KERN_FAILURE
;
664 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogMalformedMachO
665 "LC_UNIXTHREAD/LC_MAIN segment is not valid in a kext."));
667 case LC_SEGMENT_SPLIT_INFO
:
668 /* To be implemented later; treat as uninteresting for now */
669 case LC_CODE_SIGNATURE
:
671 case LC_DYLD_INFO_ONLY
:
672 case LC_FUNCTION_STARTS
:
673 case LC_DATA_IN_CODE
:
674 case LC_DYLIB_CODE_SIGN_DRS
:
675 /* Various metadata that might be stored in the linkedit segment */
679 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogMalformedMachO
680 "Invalid load command type in MH_KEXT_BUNDLE kext: %u.", cmd_hdr
->cmd
);
686 /* Initialize the sections */
687 for (j
= 0; j
< seg
->sects
.nitems
; ++j
, ++secti
) {
688 sect
= kxld_array_get_item(&object
->sects
, secti
);
689 KXLD_3264_FUNC(kxld_object_is_32_bit(object
), rval
,
690 kxld_sect_init_from_macho_32
, kxld_sect_init_from_macho_64
,
691 sect
, object
->file
, §_offset
, secti
, &object
->relocator
);
692 require_noerr(rval
, finish
);
694 /* Add the section to the segment. This will also make sure
695 * that the sections and segments have the same segname.
697 rval
= kxld_seg_add_section(seg
, sect
);
698 require_noerr(rval
, finish
);
700 rval
= kxld_seg_finish_init(seg
);
701 require_noerr(rval
, finish
);
705 if (filetype_out
) *filetype_out
= filetype
;
706 if (symtab_hdr_out
) *symtab_hdr_out
= symtab_hdr
;
707 object
->is_final_image
= TRUE
;
713 /*******************************************************************************
714 *******************************************************************************/
716 init_from_execute(KXLDObject
*object
)
718 kern_return_t rval
= KERN_FAILURE
;
719 struct symtab_command
*symtab_hdr
= NULL
;
721 KXLDSeg
* kernel_linkedit_seg
= NULL
; // used if running kernel
722 #if KXLD_USER_OR_OBJECT
724 KXLDSect
*sect
= NULL
;
725 KXLDSectionName
*sname
= NULL
;
726 u_int i
= 0, j
= 0, k
= 0;
727 #endif /* KXLD_USER_OR_OBJECT */
731 require_action(kxld_object_is_kernel(object
), finish
, rval
=KERN_FAILURE
);
733 rval
= init_from_final_linked_image(object
, &filetype
, &symtab_hdr
);
734 require_noerr(rval
, finish
);
736 require_action(filetype
== MH_EXECUTE
, finish
, rval
=KERN_FAILURE
;
737 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogMalformedMachO
738 "The kernel file is not of type MH_EXECUTE."));
740 /* Initialize the symbol table. If this is the running kernel
741 * we will work from the in-memory linkedit segment;
742 * otherwise we work from the whole mach-o image.
745 kernel_linkedit_seg
= kxld_object_get_seg_by_name(object
, SEG_LINKEDIT
);
746 require_action(kernel_linkedit_seg
, finish
, rval
=KERN_FAILURE
;
747 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogMalformedMachO
));
750 KXLD_3264_FUNC(kxld_object_is_32_bit(object
), rval
,
751 kxld_symtab_init_from_macho_32
, kxld_symtab_init_from_macho_64
,
752 object
->symtab
, symtab_hdr
, object
->file
, kernel_linkedit_seg
);
753 require_noerr(rval
, finish
);
755 #if KXLD_USER_OR_OBJECT
756 /* Save off the order of section names so that we can lay out kext
757 * sections for MH_OBJECT-based systems.
759 if (target_supports_object(object
)) {
761 rval
= kxld_array_init(object
->section_order
, sizeof(KXLDSectionName
),
762 object
->sects
.nitems
);
763 require_noerr(rval
, finish
);
765 /* Copy the section names into the section_order array for future kext
768 for (i
= 0, k
= 0; i
< object
->segs
.nitems
; ++i
) {
769 seg
= kxld_array_get_item(&object
->segs
, i
);
771 for (j
= 0; j
< seg
->sects
.nitems
; ++j
, ++k
) {
772 sect
= *(KXLDSect
**) kxld_array_get_item(&seg
->sects
, j
);
773 sname
= kxld_array_get_item(object
->section_order
, k
);
775 strlcpy(sname
->segname
, sect
->segname
, sizeof(sname
->segname
));
776 strlcpy(sname
->sectname
, sect
->sectname
, sizeof(sname
->sectname
));
780 #endif /* KXLD_USER_OR_OBJECT */
787 #if KXLD_USER_OR_BUNDLE
788 /*******************************************************************************
789 *******************************************************************************/
791 target_supports_bundle(const KXLDObject
*object __unused
)
796 /*******************************************************************************
797 *******************************************************************************/
799 init_from_bundle(KXLDObject
*object
)
801 kern_return_t rval
= KERN_FAILURE
;
802 struct symtab_command
*symtab_hdr
= NULL
;
807 require_action(target_supports_bundle(object
), finish
,
809 kxld_log(kKxldLogLinking
, kKxldLogErr
,
810 kKxldLogFiletypeNotSupported
, MH_KEXT_BUNDLE
));
812 rval
= init_from_final_linked_image(object
, &filetype
, &symtab_hdr
);
813 require_noerr(rval
, finish
);
815 require_action(filetype
== MH_KEXT_BUNDLE
, finish
,
818 KXLD_3264_FUNC(kxld_object_is_32_bit(object
), rval
,
819 kxld_symtab_init_from_macho_32
, kxld_symtab_init_from_macho_64
,
820 object
->symtab
, symtab_hdr
, object
->file
,
821 /* kernel_linkedit_seg */ NULL
);
822 require_noerr(rval
, finish
);
828 #endif /* KXLD_USER_OR_BUNDLE */
830 #if KXLD_USER_OR_OBJECT
831 /*******************************************************************************
832 *******************************************************************************/
833 static boolean_t
target_supports_object(const KXLDObject
*object
)
835 return (object
->cputype
== CPU_TYPE_I386
);
838 /*******************************************************************************
839 *******************************************************************************/
841 init_from_object(KXLDObject
*object
)
843 kern_return_t rval
= KERN_FAILURE
;
844 struct load_command
*cmd_hdr
= NULL
;
845 struct symtab_command
*symtab_hdr
= NULL
;
846 struct uuid_command
*uuid_hdr
= NULL
;
847 KXLDSect
*sect
= NULL
;
849 u_long sect_offset
= 0;
854 boolean_t has_segment
= FALSE
;
858 require_action(target_supports_object(object
),
859 finish
, rval
=KERN_FAILURE
;
860 kxld_log(kKxldLogLinking
, kKxldLogErr
,
861 kKxldLogFiletypeNotSupported
, MH_OBJECT
));
863 KXLD_3264_FUNC(kxld_object_is_32_bit(object
), offset
,
864 get_macho_cmd_data_32
, get_macho_cmd_data_64
,
865 object
->file
, offset
, &filetype
, &ncmds
);
867 require_action(filetype
== MH_OBJECT
, finish
, rval
=KERN_FAILURE
);
869 /* MH_OBJECTs use one unnamed segment to contain all of the sections. We
870 * loop over all of the load commands to initialize the structures we
871 * expect. Then, we'll use the unnamed segment to get to all of the
872 * sections, and then use those sections to create the actual segments.
875 for (; i
< ncmds
; ++i
, offset
+= cmd_hdr
->cmdsize
) {
876 cmd_hdr
= (struct load_command
*) ((void *) (object
->file
+ offset
));
878 switch(cmd_hdr
->cmd
) {
879 #if KXLD_USER_OR_ILP32
882 struct segment_command
*seg_hdr
=
883 (struct segment_command
*) cmd_hdr
;
885 /* Ignore segments with no vm size */
886 if (!seg_hdr
->vmsize
) continue;
888 /* Ignore LINKEDIT segments */
889 if (streq_safe(seg_hdr
->segname
, SEG_LINKEDIT
,
890 const_strlen(SEG_LINKEDIT
)))
895 require_action(kxld_object_is_32_bit(object
), finish
, rval
=KERN_FAILURE
;
896 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogMalformedMachO
897 "LC_SEGMENT in 64-bit kext."));
898 require_action(!has_segment
, finish
, rval
=KERN_FAILURE
;
899 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogMalformedMachO
900 "Multiple segments in an MH_OBJECT kext."));
902 nsects
= seg_hdr
->nsects
;
903 sect_offset
= offset
+ sizeof(*seg_hdr
);
907 #endif /* KXLD_USER_OR_ILP32 */
908 #if KXLD_USER_OR_LP64
911 struct segment_command_64
*seg_hdr
=
912 (struct segment_command_64
*) ((void *) cmd_hdr
);
914 /* Ignore segments with no vm size */
915 if (!seg_hdr
->vmsize
) continue;
917 /* Ignore LINKEDIT segments */
918 if (streq_safe(seg_hdr
->segname
, SEG_LINKEDIT
,
919 const_strlen(SEG_LINKEDIT
)))
924 require_action(!kxld_object_is_32_bit(object
), finish
, rval
=KERN_FAILURE
;
925 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogMalformedMachO
926 "LC_SEGMENT_64 in a 32-bit kext."));
927 require_action(!has_segment
, finish
, rval
=KERN_FAILURE
;
928 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogMalformedMachO
929 "Multiple segments in an MH_OBJECT kext."));
931 nsects
= seg_hdr
->nsects
;
932 sect_offset
= offset
+ sizeof(*seg_hdr
);
936 #endif /* KXLD_USER_OR_LP64 */
938 symtab_hdr
= (struct symtab_command
*) cmd_hdr
;
940 KXLD_3264_FUNC(kxld_object_is_32_bit(object
), rval
,
941 kxld_symtab_init_from_macho_32
, kxld_symtab_init_from_macho_64
,
942 object
->symtab
, symtab_hdr
, object
->file
,
943 /* kernel_linkedit_seg */ NULL
);
944 require_noerr(rval
, finish
);
947 uuid_hdr
= (struct uuid_command
*) cmd_hdr
;
948 kxld_uuid_init_from_macho(&object
->uuid
, uuid_hdr
);
952 /* Don't need to do anything with UNIXTHREAD or MAIN */
954 case LC_CODE_SIGNATURE
:
956 case LC_DYLD_INFO_ONLY
:
957 case LC_FUNCTION_STARTS
:
958 case LC_DATA_IN_CODE
:
959 case LC_DYLIB_CODE_SIGN_DRS
:
960 /* Various metadata that might be stored in the linkedit segment */
962 case LC_VERSION_MIN_MACOSX
:
963 case LC_VERSION_MIN_IPHONEOS
:
964 case LC_VERSION_MIN_WATCHOS
:
965 case LC_SOURCE_VERSION
:
966 /* Not supported for object files, fall through */
969 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogMalformedMachO
970 "Invalid load command type in MH_OBJECT kext: %u.", cmd_hdr
->cmd
);
977 /* Get the number of sections from the segment and build the section index */
979 rval
= kxld_array_init(&object
->sects
, sizeof(KXLDSect
), nsects
);
980 require_noerr(rval
, finish
);
982 /* Loop over all of the sections to initialize the section index */
984 for (i
= 0; i
< nsects
; ++i
) {
985 sect
= kxld_array_get_item(&object
->sects
, i
);
986 KXLD_3264_FUNC(kxld_object_is_32_bit(object
), rval
,
987 kxld_sect_init_from_macho_32
, kxld_sect_init_from_macho_64
,
988 sect
, object
->file
, §_offset
, i
, &object
->relocator
);
989 require_noerr(rval
, finish
);
992 /* Create special sections */
995 rval
= create_got(object
);
996 require_noerr(rval
, finish
);
997 #endif /* KXLD_USER_OR_GOT */
999 #if KXLD_USER_OR_COMMON
1000 rval
= resolve_common_symbols(object
);
1001 require_noerr(rval
, finish
);
1002 #endif /* KXLD_USER_OR_COMMON */
1004 /* Create the segments from the section index */
1006 rval
= kxld_seg_create_seg_from_sections(&object
->segs
, &object
->sects
);
1007 require_noerr(rval
, finish
);
1009 rval
= kxld_seg_finalize_object_segment(&object
->segs
,
1010 object
->section_order
, get_macho_header_size(object
));
1011 require_noerr(rval
, finish
);
1013 rval
= kxld_seg_init_linkedit(&object
->segs
);
1014 require_noerr(rval
, finish
);
1017 rval
= KERN_SUCCESS
;
1021 #endif /* KXLD_USER_OR_OBJECT */
1023 #if KXLD_USER_OR_ILP32
1024 /*******************************************************************************
1025 *******************************************************************************/
1027 get_macho_cmd_data_32(u_char
*file
, u_long offset
, u_int
*filetype
, u_int
*ncmds
)
1029 struct mach_header
*mach_hdr
= (struct mach_header
*) ((void *) (file
+ offset
));
1031 if (filetype
) *filetype
= mach_hdr
->filetype
;
1032 if (ncmds
) *ncmds
= mach_hdr
->ncmds
;
1034 return sizeof(*mach_hdr
);
1037 #endif /* KXLD_USER_OR_ILP32 */
1039 #if KXLD_USER_OR_LP64
1040 /*******************************************************************************
1041 *******************************************************************************/
1043 get_macho_cmd_data_64(u_char
*file
, u_long offset
, u_int
*filetype
, u_int
*ncmds
)
1045 struct mach_header_64
*mach_hdr
= (struct mach_header_64
*) ((void *) (file
+ offset
));
1047 if (filetype
) *filetype
= mach_hdr
->filetype
;
1048 if (ncmds
) *ncmds
= mach_hdr
->ncmds
;
1050 return sizeof(*mach_hdr
);
1052 #endif /* KXLD_USER_OR_LP64 */
1054 /*******************************************************************************
1055 *******************************************************************************/
1057 get_macho_header_size(const KXLDObject
*object
)
1059 KXLDSeg
*seg
= NULL
;
1060 u_long header_size
= 0;
1062 boolean_t object_is_32_bit
= kxld_object_is_32_bit(object
);
1066 /* Mach, segment, symtab, and UUID headers */
1068 header_size
+= object_is_32_bit
? sizeof(struct mach_header
) : sizeof(struct mach_header_64
);
1070 for (i
= 0; i
< object
->segs
.nitems
; ++i
) {
1071 seg
= kxld_array_get_item(&object
->segs
, i
);
1072 header_size
+= kxld_seg_get_macho_header_size(seg
, object_is_32_bit
);
1075 header_size
+= kxld_symtab_get_macho_header_size();
1078 if (target_supports_slideable_kexts(object
)) {
1079 header_size
+= kxld_reloc_get_macho_header_size();
1081 #endif /* KXLD_PIC_KEXTS */
1083 if (object
->uuid
.has_uuid
) {
1084 header_size
+= kxld_uuid_get_macho_header_size();
1087 if (object
->versionmin
.has_versionmin
) {
1088 header_size
+= kxld_versionmin_get_macho_header_size();
1091 if (object
->srcversion
.has_srcversion
) {
1092 header_size
+= kxld_srcversion_get_macho_header_size();
1098 /*******************************************************************************
1099 *******************************************************************************/
1101 get_macho_data_size(const KXLDObject
*object
)
1103 KXLDSeg
*seg
= NULL
;
1104 u_long data_size
= 0;
1109 /* total all segment vmsize values */
1110 for (i
= 0; i
< object
->segs
.nitems
; ++i
) {
1111 seg
= kxld_array_get_item(&object
->segs
, i
);
1112 data_size
+= (u_long
) kxld_seg_get_vmsize(seg
);
1117 /* ensure that when we eventually emit the final linked object,
1118 * appending the __DYSYMTAB data after the __LINKEDIT data will
1119 * not overflow the space allocated for the __LINKEDIT segment
1122 u_long seg_vmsize
= 0;
1123 u_long symtab_size
= 0;
1124 u_long reloc_size
= 0;
1126 /* get current __LINKEDIT sizes */
1127 seg
= kxld_object_get_seg_by_name(object
, SEG_LINKEDIT
);
1128 seg_vmsize
= (u_long
) kxld_seg_get_vmsize(seg
);
1130 /* get size of symbol table data that will eventually be dumped
1131 * into the __LINKEDIT segment
1133 symtab_size
= kxld_symtab_get_macho_data_size(object
->symtab
, kxld_object_is_32_bit(object
));
1135 if (target_supports_slideable_kexts(object
)) {
1136 /* get size of __DYSYMTAB relocation entries */
1137 reloc_size
= kxld_reloc_get_macho_data_size(&object
->locrelocs
, &object
->extrelocs
);
1140 /* combine, and ensure they'll both fit within the page(s)
1141 * allocated for the __LINKEDIT segment. If they'd overflow,
1142 * increase the vmsize appropriately so no overflow will occur
1144 if ((symtab_size
+ reloc_size
) > seg_vmsize
) {
1145 u_long overflow
= (symtab_size
+ reloc_size
) - seg_vmsize
;
1146 data_size
+= kxld_round_page_cross_safe(overflow
);
1149 #endif // KXLD_PIC_KEXTS
1154 /*******************************************************************************
1155 *******************************************************************************/
1157 kxld_object_target_needs_swap(const KXLDObject
*object __unused
)
1162 return (object
->target_order
!= object
->host_order
);
1166 /*******************************************************************************
1167 *******************************************************************************/
1169 kxld_object_get_seg_by_name(const KXLDObject
*object
, const char *segname
)
1171 KXLDSeg
*seg
= NULL
;
1174 for (i
= 0; i
< object
->segs
.nitems
; ++i
) {
1175 seg
= kxld_array_get_item(&object
->segs
, i
);
1177 if (streq_safe(segname
, seg
->segname
, sizeof(seg
->segname
))) break;
1185 /*******************************************************************************
1186 *******************************************************************************/
1187 const KXLDRelocator
*
1188 kxld_object_get_relocator(const KXLDObject
* object
)
1192 return &object
->relocator
;
1195 /*******************************************************************************
1196 *******************************************************************************/
1198 kxld_object_get_sect_by_name(const KXLDObject
*object
, const char *segname
,
1199 const char *sectname
)
1201 KXLDSect
*sect
= NULL
;
1204 for (i
= 0; i
< object
->sects
.nitems
; ++i
) {
1205 sect
= kxld_array_get_item(&object
->sects
, i
);
1207 if (streq_safe(segname
, sect
->segname
, sizeof(sect
->segname
)) &&
1208 streq_safe(sectname
, sect
->sectname
, sizeof(sect
->sectname
)))
1219 /*******************************************************************************
1220 *******************************************************************************/
1222 kxld_object_get_reloc_at_symbol(const KXLDObject
*object
, const KXLDSym
*sym
)
1224 const KXLDReloc
*reloc
= NULL
;
1225 const KXLDSect
*sect
= NULL
;
1226 uint32_t offset
= 0;
1231 sect
= kxld_object_get_section_by_index(object
, sym
->sectnum
);
1232 require(sect
, finish
);
1234 if (kxld_object_is_final_image(object
)) {
1235 reloc
= kxld_reloc_get_reloc_by_offset(&object
->extrelocs
,
1238 reloc
= kxld_reloc_get_reloc_by_offset(&object
->locrelocs
,
1242 offset
= kxld_sym_get_section_offset(sym
, sect
);
1243 reloc
= kxld_reloc_get_reloc_by_offset(§
->relocs
, offset
);
1250 /*******************************************************************************
1251 *******************************************************************************/
1253 kxld_object_get_symbol_of_reloc(const KXLDObject
*object
,
1254 const KXLDReloc
*reloc
, const KXLDSect
*sect
)
1256 const KXLDSym
*sym
= NULL
;
1258 if (kxld_object_is_final_image(object
)) {
1259 sym
= kxld_reloc_get_symbol(&object
->relocator
, reloc
, object
->file
);
1261 sym
= kxld_reloc_get_symbol(&object
->relocator
, reloc
, sect
->data
);
1267 /*******************************************************************************
1268 *******************************************************************************/
1270 kxld_object_get_section_by_index(const KXLDObject
*object
, u_int sectnum
)
1272 KXLDSect
*sect
= NULL
;
1276 if (sectnum
< object
->sects
.nitems
) {
1277 sect
= kxld_array_get_item(&object
->sects
, sectnum
);
1283 /*******************************************************************************
1284 *******************************************************************************/
1286 kxld_object_get_extrelocs(const KXLDObject
*object
)
1288 const KXLDArray
*rval
= NULL
;
1292 if (kxld_object_is_final_image(object
)) {
1293 rval
= &object
->extrelocs
;
1299 /*******************************************************************************
1300 *******************************************************************************/
1302 kxld_object_get_symtab(const KXLDObject
*object
)
1306 return object
->symtab
;
1309 #if KXLD_USER_OR_GOT || KXLD_USER_OR_COMMON
1310 /*******************************************************************************
1311 *******************************************************************************/
1312 static kern_return_t
1313 add_section(KXLDObject
*object
, KXLDSect
**sect
)
1315 kern_return_t rval
= KERN_FAILURE
;
1316 u_int nsects
= object
->sects
.nitems
;
1318 rval
= kxld_array_resize(&object
->sects
, nsects
+ 1);
1319 require_noerr(rval
, finish
);
1321 *sect
= kxld_array_get_item(&object
->sects
, nsects
);
1323 rval
= KERN_SUCCESS
;
1328 #endif /* KXLD_USER_OR_GOT || KXLD_USER_OR_COMMON */
1330 #if KXLD_USER_OR_COMMON
1331 /*******************************************************************************
1332 * If there are common symbols, calculate how much space they'll need
1333 * and create/grow the __DATA __common section to accommodate them.
1334 * Then, resolve them against that section.
1335 *******************************************************************************/
1336 static kern_return_t
1337 resolve_common_symbols(KXLDObject
*object
)
1339 kern_return_t rval
= KERN_FAILURE
;
1340 KXLDSymtabIterator iter
;
1341 KXLDSym
*sym
= NULL
;
1342 KXLDSect
*sect
= NULL
;
1343 kxld_addr_t base_addr
= 0;
1344 kxld_size_t size
= 0;
1345 kxld_size_t total_size
= 0;
1347 u_int max_align
= 0;
1350 if (!kxld_object_target_supports_common_symbols(object
)) {
1351 rval
= KERN_SUCCESS
;
1355 /* Iterate over the common symbols to calculate their total aligned size */
1356 kxld_symtab_iterator_init(&iter
, object
->symtab
, kxld_sym_is_common
, FALSE
);
1357 while ((sym
= kxld_symtab_iterator_get_next(&iter
))) {
1358 align
= kxld_sym_get_common_align(sym
);
1359 size
= kxld_sym_get_common_size(sym
);
1361 if (align
> max_align
) max_align
= align
;
1363 total_size
= kxld_align_address(total_size
, align
) + size
;
1366 /* If there are common symbols, grow or create the __DATA __common section
1370 sect
= kxld_object_get_sect_by_name(object
, SEG_DATA
, SECT_COMMON
);
1372 base_addr
= sect
->base_addr
+ sect
->size
;
1374 kxld_sect_grow(sect
, total_size
, max_align
);
1378 rval
= add_section(object
, §
);
1379 require_noerr(rval
, finish
);
1381 kxld_sect_init_zerofill(sect
, SEG_DATA
, SECT_COMMON
,
1382 total_size
, max_align
);
1385 /* Resolve the common symbols against the new section */
1386 rval
= kxld_array_get_index(&object
->sects
, sect
, §num
);
1387 require_noerr(rval
, finish
);
1389 kxld_symtab_iterator_reset(&iter
);
1390 while ((sym
= kxld_symtab_iterator_get_next(&iter
))) {
1391 align
= kxld_sym_get_common_align(sym
);
1392 size
= kxld_sym_get_common_size(sym
);
1394 base_addr
= kxld_align_address(base_addr
, align
);
1395 kxld_sym_resolve_common(sym
, sectnum
, base_addr
);
1401 rval
= KERN_SUCCESS
;
1406 #endif /* KXLD_USER_OR_COMMON */
1408 #if KXLD_USER_OR_GOT
1409 /*******************************************************************************
1410 *******************************************************************************/
1412 target_has_got(const KXLDObject
*object
)
1417 /*******************************************************************************
1418 * Create and initialize the Global Offset Table
1419 *******************************************************************************/
1420 static kern_return_t
1421 create_got(KXLDObject
*object
)
1423 kern_return_t rval
= KERN_FAILURE
;
1424 KXLDSect
*sect
= NULL
;
1428 if (!target_has_got(object
)) {
1429 rval
= KERN_SUCCESS
;
1433 for (i
= 0; i
< object
->sects
.nitems
; ++i
) {
1434 sect
= kxld_array_get_item(&object
->sects
, i
);
1435 ngots
+= kxld_sect_get_ngots(sect
, &object
->relocator
,
1439 rval
= add_section(object
, §
);
1440 require_noerr(rval
, finish
);
1442 rval
= kxld_sect_init_got(sect
, ngots
);
1443 require_noerr(rval
, finish
);
1445 object
->got_is_created
= TRUE
;
1446 rval
= KERN_SUCCESS
;
1452 /*******************************************************************************
1453 *******************************************************************************/
1454 static kern_return_t
1455 populate_got(KXLDObject
*object
)
1457 kern_return_t rval
= KERN_FAILURE
;
1458 KXLDSect
*sect
= NULL
;
1461 if (!target_has_got(object
) || !object
->got_is_created
) {
1462 rval
= KERN_SUCCESS
;
1466 for (i
= 0; i
< object
->sects
.nitems
; ++i
) {
1467 sect
= kxld_array_get_item(&object
->sects
, i
);
1468 if (streq_safe(sect
->segname
, KXLD_SEG_GOT
, sizeof(KXLD_SEG_GOT
)) &&
1469 streq_safe(sect
->sectname
, KXLD_SECT_GOT
, sizeof(KXLD_SECT_GOT
)))
1471 kxld_sect_populate_got(sect
, object
->symtab
,
1472 kxld_object_target_needs_swap(object
));
1477 require_action(i
< object
->sects
.nitems
, finish
, rval
=KXLD_MISSING_GOT
);
1479 rval
= KERN_SUCCESS
;
1484 #endif /* KXLD_USER_OR_GOT */
1486 /*******************************************************************************
1487 *******************************************************************************/
1489 target_supports_protected_segments(const KXLDObject
*object
)
1491 return (object
->is_final_image
&&
1492 (object
->cputype
== CPU_TYPE_X86_64
||
1493 object
->cputype
== CPU_TYPE_ARM
||
1494 object
->cputype
== CPU_TYPE_ARM64
));
1497 /*******************************************************************************
1498 *******************************************************************************/
1500 set_is_object_linked(KXLDObject
*object
)
1504 if (kxld_object_is_kernel(object
)) {
1505 object
->is_linked
= TRUE
;
1509 if (object
->is_final_image
) {
1510 object
->is_linked
= !object
->extrelocs
.nitems
;
1514 object
->is_linked
= TRUE
;
1515 for (i
= 0; i
< object
->sects
.nitems
; ++i
) {
1516 KXLDSect
*sect
= kxld_array_get_item(&object
->sects
, i
);
1517 if (sect
->relocs
.nitems
) {
1518 object
->is_linked
= FALSE
;
1525 /*******************************************************************************
1526 *******************************************************************************/
1527 void kxld_object_clear(KXLDObject
*object __unused
)
1529 KXLDSeg
*seg
= NULL
;
1530 KXLDSect
*sect
= NULL
;
1536 if (kxld_object_is_kernel(object
)) {
1537 unswap_macho(object
->file
, object
->host_order
, object
->target_order
);
1539 #endif /* !KERNEL */
1541 for (i
= 0; i
< object
->segs
.nitems
; ++i
) {
1542 seg
= kxld_array_get_item(&object
->segs
, i
);
1543 kxld_seg_clear(seg
);
1545 kxld_array_reset(&object
->segs
);
1547 for (i
= 0; i
< object
->sects
.nitems
; ++i
) {
1548 sect
= kxld_array_get_item(&object
->sects
, i
);
1549 kxld_sect_clear(sect
);
1551 kxld_array_reset(&object
->sects
);
1553 kxld_array_reset(&object
->extrelocs
);
1554 kxld_array_reset(&object
->locrelocs
);
1555 kxld_relocator_clear(&object
->relocator
);
1556 kxld_uuid_clear(&object
->uuid
);
1557 kxld_versionmin_clear(&object
->versionmin
);
1558 kxld_srcversion_clear(&object
->srcversion
);
1560 if (object
->symtab
) kxld_symtab_clear(object
->symtab
);
1562 object
->file
= NULL
;
1564 object
->filetype
= 0;
1565 object
->cputype
= 0;
1566 object
->cpusubtype
= 0;
1567 object
->is_kernel
= FALSE
;
1568 object
->is_final_image
= FALSE
;
1569 object
->is_linked
= FALSE
;
1570 object
->got_is_created
= FALSE
;
1572 #if KXLD_USER_OR_OBJECT
1573 object
->section_order
= NULL
;
1576 object
->host_order
= 0;
1577 object
->target_order
= 0;
1581 /*******************************************************************************
1582 *******************************************************************************/
1583 void kxld_object_deinit(KXLDObject
*object __unused
)
1585 KXLDSeg
*seg
= NULL
;
1586 KXLDSect
*sect
= NULL
;
1592 if (object
->file
&& kxld_object_is_kernel(object
)) {
1593 unswap_macho(object
->file
, object
->host_order
, object
->target_order
);
1595 #endif /* !KERNEL */
1597 for (i
= 0; i
< object
->segs
.maxitems
; ++i
) {
1598 seg
= kxld_array_get_slot(&object
->segs
, i
);
1599 kxld_seg_deinit(seg
);
1601 kxld_array_deinit(&object
->segs
);
1603 for (i
= 0; i
< object
->sects
.maxitems
; ++i
) {
1604 sect
= kxld_array_get_slot(&object
->sects
, i
);
1605 kxld_sect_deinit(sect
);
1607 kxld_array_deinit(&object
->sects
);
1609 kxld_array_deinit(&object
->extrelocs
);
1610 kxld_array_deinit(&object
->locrelocs
);
1612 if (object
->symtab
) {
1613 kxld_symtab_deinit(object
->symtab
);
1614 kxld_free(object
->symtab
, kxld_symtab_sizeof());
1617 bzero(object
, sizeof(*object
));
1620 /*******************************************************************************
1621 *******************************************************************************/
1623 kxld_object_get_file(const KXLDObject
*object
)
1627 return object
->file
;
1630 /*******************************************************************************
1631 *******************************************************************************/
1633 kxld_object_get_name(const KXLDObject
*object
)
1637 return object
->name
;
1640 /*******************************************************************************
1641 *******************************************************************************/
1643 kxld_object_is_32_bit(const KXLDObject
*object
)
1647 return kxld_is_32_bit(object
->cputype
);
1650 /*******************************************************************************
1651 *******************************************************************************/
1653 kxld_object_is_final_image(const KXLDObject
*object
)
1657 return object
->is_final_image
;
1660 /*******************************************************************************
1661 *******************************************************************************/
1663 kxld_object_is_kernel(const KXLDObject
*object
)
1667 return object
->is_kernel
;
1670 /*******************************************************************************
1671 *******************************************************************************/
1673 kxld_object_is_linked(const KXLDObject
*object
)
1677 return object
->is_linked
;
1680 /*******************************************************************************
1681 *******************************************************************************/
1683 kxld_object_target_supports_strict_patching(const KXLDObject
*object
)
1687 return (object
->cputype
!= CPU_TYPE_I386
);
1690 /*******************************************************************************
1691 *******************************************************************************/
1693 kxld_object_target_supports_common_symbols(const KXLDObject
*object
)
1697 return (object
->cputype
== CPU_TYPE_I386
);
1700 /*******************************************************************************
1701 *******************************************************************************/
1703 kxld_object_get_vmsize(const KXLDObject
*object
, u_long
*header_size
,
1712 /* vmsize is the padded header page(s) + segment vmsizes */
1714 *header_size
= (object
->is_final_image
) ?
1715 0 : (u_long
)kxld_round_page_cross_safe(get_macho_header_size(object
));
1716 *vmsize
= *header_size
+ get_macho_data_size(object
);
1720 /*******************************************************************************
1721 *******************************************************************************/
1723 kxld_object_set_linked_object_size(KXLDObject
*object
, u_long vmsize
)
1725 object
->output_buffer_size
= vmsize
; /* cache this for use later */
1729 /*******************************************************************************
1730 *******************************************************************************/
1732 kxld_object_export_linked_object(const KXLDObject
*object
,
1733 u_char
*linked_object
)
1735 kern_return_t rval
= KERN_FAILURE
;
1736 KXLDSeg
*seg
= NULL
;
1738 u_long header_size
= 0;
1739 u_long header_offset
= 0;
1740 u_long data_offset
= 0;
1743 boolean_t is_32bit_object
= kxld_object_is_32_bit(object
);
1746 check(linked_object
);
1748 /* Calculate the size of the headers and data */
1750 header_size
= get_macho_header_size(object
);
1751 size
= object
->output_buffer_size
;
1753 /* Copy data to the file */
1755 ncmds
= object
->segs
.nitems
+ 1 /* LC_SYMTAB */;
1758 /* don't write out a DYSYMTAB segment for targets that can't digest it
1760 if (target_supports_slideable_kexts(object
)) {
1761 ncmds
++; /* dysymtab */
1763 #endif /* KXLD_PIC_KEXTS */
1765 if (object
->uuid
.has_uuid
== TRUE
) {
1769 if (object
->versionmin
.has_versionmin
== TRUE
) {
1773 if (object
->srcversion
.has_srcversion
== TRUE
) {
1777 rval
= export_macho_header(object
, linked_object
, ncmds
, &header_offset
, header_size
);
1778 require_noerr(rval
, finish
);
1780 for (i
= 0; i
< object
->segs
.nitems
; ++i
) {
1781 seg
= kxld_array_get_item(&object
->segs
, i
);
1783 rval
= kxld_seg_export_macho_to_vm(seg
, linked_object
, &header_offset
,
1784 header_size
, size
, object
->link_addr
, is_32bit_object
);
1785 require_noerr(rval
, finish
);
1788 seg
= kxld_object_get_seg_by_name(object
, SEG_LINKEDIT
);
1789 data_offset
= (u_long
) (seg
->link_addr
- object
->link_addr
);
1791 rval
= kxld_symtab_export_macho(object
->symtab
, linked_object
, &header_offset
,
1792 header_size
, &data_offset
, size
, is_32bit_object
);
1793 require_noerr(rval
, finish
);
1796 if (target_supports_slideable_kexts(object
)) {
1797 rval
= kxld_reloc_export_macho(&object
->relocator
, &object
->locrelocs
,
1798 &object
->extrelocs
, linked_object
, &header_offset
, header_size
,
1799 &data_offset
, size
);
1800 require_noerr(rval
, finish
);
1802 #endif /* KXLD_PIC_KEXTS */
1804 if (object
->uuid
.has_uuid
) {
1805 rval
= kxld_uuid_export_macho(&object
->uuid
, linked_object
, &header_offset
, header_size
);
1806 require_noerr(rval
, finish
);
1809 if (object
->versionmin
.has_versionmin
) {
1810 rval
= kxld_versionmin_export_macho(&object
->versionmin
, linked_object
, &header_offset
, header_size
);
1811 require_noerr(rval
, finish
);
1814 if (object
->srcversion
.has_srcversion
) {
1815 rval
= kxld_srcversion_export_macho(&object
->srcversion
, linked_object
, &header_offset
, header_size
);
1816 require_noerr(rval
, finish
);
1820 unswap_macho(linked_object
, object
->host_order
, object
->target_order
);
1823 rval
= KERN_SUCCESS
;
1829 /*******************************************************************************
1830 *******************************************************************************/
1831 static kern_return_t
1832 export_macho_header(const KXLDObject
*object
, u_char
*buf
, u_int ncmds
,
1833 u_long
*header_offset
, u_long header_size
)
1835 kern_return_t rval
= KERN_FAILURE
;
1839 check(header_offset
);
1841 KXLD_3264_FUNC(kxld_object_is_32_bit(object
), rval
,
1842 export_macho_header_32
, export_macho_header_64
,
1843 object
, buf
, ncmds
, header_offset
, header_size
);
1844 require_noerr(rval
, finish
);
1846 rval
= KERN_SUCCESS
;
1852 #if KXLD_USER_OR_ILP32
1853 /*******************************************************************************
1854 *******************************************************************************/
1855 static kern_return_t
1856 export_macho_header_32(const KXLDObject
*object
, u_char
*buf
, u_int ncmds
,
1857 u_long
*header_offset
, u_long header_size
)
1859 kern_return_t rval
= KERN_FAILURE
;
1860 struct mach_header
*mach
= NULL
;
1864 check(header_offset
);
1866 require_action(sizeof(*mach
) <= header_size
- *header_offset
, finish
,
1868 mach
= (struct mach_header
*) ((void *) (buf
+ *header_offset
));
1870 mach
->magic
= MH_MAGIC
;
1871 mach
->cputype
= object
->cputype
;
1872 mach
->cpusubtype
= object
->cpusubtype
;
1873 mach
->filetype
= object
->filetype
;
1874 mach
->ncmds
= ncmds
;
1875 mach
->sizeofcmds
= (uint32_t) (header_size
- sizeof(*mach
));
1876 mach
->flags
= MH_NOUNDEFS
;
1878 *header_offset
+= sizeof(*mach
);
1880 rval
= KERN_SUCCESS
;
1885 #endif /* KXLD_USER_OR_ILP32 */
1887 #if KXLD_USER_OR_LP64
1888 /*******************************************************************************
1889 *******************************************************************************/
1890 static kern_return_t
1891 export_macho_header_64(const KXLDObject
*object
, u_char
*buf
, u_int ncmds
,
1892 u_long
*header_offset
, u_long header_size
)
1894 kern_return_t rval
= KERN_FAILURE
;
1895 struct mach_header_64
*mach
= NULL
;
1899 check(header_offset
);
1901 require_action(sizeof(*mach
) <= header_size
- *header_offset
, finish
,
1903 mach
= (struct mach_header_64
*) ((void *) (buf
+ *header_offset
));
1905 mach
->magic
= MH_MAGIC_64
;
1906 mach
->cputype
= object
->cputype
;
1907 mach
->cpusubtype
= object
->cpusubtype
;
1908 mach
->filetype
= object
->filetype
;
1909 mach
->ncmds
= ncmds
;
1910 mach
->sizeofcmds
= (uint32_t) (header_size
- sizeof(*mach
));
1911 mach
->flags
= MH_NOUNDEFS
;
1913 *header_offset
+= sizeof(*mach
);
1915 rval
= KERN_SUCCESS
;
1920 #endif /* KXLD_USER_OR_LP64 */
1922 /*******************************************************************************
1923 *******************************************************************************/
1925 kxld_object_index_symbols_by_name(KXLDObject
*object
)
1927 return kxld_symtab_index_symbols_by_name(object
->symtab
);
1930 /*******************************************************************************
1931 *******************************************************************************/
1933 kxld_object_index_cxx_symbols_by_value(KXLDObject
*object
)
1935 return kxld_symtab_index_cxx_symbols_by_value(object
->symtab
);
1938 /*******************************************************************************
1939 *******************************************************************************/
1941 kxld_object_relocate(KXLDObject
*object
, kxld_addr_t link_address
)
1943 kern_return_t rval
= KERN_FAILURE
;
1944 KXLDSeg
*seg
= NULL
;
1949 object
->link_addr
= link_address
;
1951 /* Relocate segments (which relocates the sections) */
1952 for (i
= 0; i
< object
->segs
.nitems
; ++i
) {
1953 seg
= kxld_array_get_item(&object
->segs
, i
);
1954 kxld_seg_relocate(seg
, link_address
);
1957 /* Relocate symbols */
1958 rval
= kxld_symtab_relocate(object
->symtab
, &object
->sects
);
1959 require_noerr(rval
, finish
);
1961 rval
= KERN_SUCCESS
;
1966 /*******************************************************************************
1967 *******************************************************************************/
1969 get_mutable_sym(const KXLDObject
*object
, const KXLDSym
*sym
)
1971 KXLDSym
*rval
= NULL
;
1972 kern_return_t result
= KERN_FAILURE
;
1975 result
= kxld_symtab_get_sym_index(object
->symtab
, sym
, &i
);
1976 require_noerr(result
, finish
);
1978 rval
= kxld_symtab_get_symbol_by_index(object
->symtab
, i
);
1979 require_action(rval
== sym
, finish
, rval
=NULL
);
1985 /*******************************************************************************
1986 *******************************************************************************/
1988 kxld_object_resolve_symbol(KXLDObject
*object
,
1989 const KXLDSym
*sym
, kxld_addr_t addr
)
1991 kern_return_t rval
= KERN_FAILURE
;
1992 KXLDSym
*resolved_sym
= NULL
;
1994 resolved_sym
= get_mutable_sym(object
, sym
);
1995 require_action(resolved_sym
, finish
, rval
=KERN_FAILURE
);
1997 rval
= kxld_sym_resolve(resolved_sym
, addr
);
1998 require_noerr(rval
, finish
);
2000 rval
= KERN_SUCCESS
;
2005 /*******************************************************************************
2006 *******************************************************************************/
2008 kxld_object_patch_symbol(KXLDObject
*object
, const struct kxld_sym
*sym
)
2010 kern_return_t rval
= KERN_FAILURE
;
2011 KXLDSym
*patched_sym
= NULL
;
2013 patched_sym
= get_mutable_sym(object
, sym
);
2014 require_action(patched_sym
, finish
, rval
=KERN_FAILURE
);
2016 (void) kxld_sym_patch(patched_sym
);
2017 rval
= KERN_SUCCESS
;
2022 /*******************************************************************************
2023 *******************************************************************************/
2025 kxld_object_add_symbol(KXLDObject
*object
, char *name
, kxld_addr_t link_addr
,
2026 const KXLDSym
**sym_out
)
2028 kern_return_t rval
= KERN_FAILURE
;
2029 KXLDSym
*sym
= NULL
;
2031 rval
= kxld_symtab_add_symbol(object
->symtab
, name
, link_addr
, &sym
);
2032 require_noerr(rval
, finish
);
2035 rval
= KERN_SUCCESS
;
2040 /*******************************************************************************
2041 *******************************************************************************/
2043 kxld_object_process_relocations(KXLDObject
*object
,
2044 const KXLDDict
*patched_vtables
)
2046 kern_return_t rval
= KERN_FAILURE
;
2048 (void) kxld_relocator_set_vtables(&object
->relocator
, patched_vtables
);
2050 /* Process relocation entries and populate the global offset table.
2052 * For final linked images: the relocation entries are contained in a couple
2053 * of tables hanging off the end of the symbol table. The GOT has its own
2054 * section created by the linker; we simply need to fill it.
2056 * For object files: the relocation entries are bound to each section.
2057 * The GOT, if it exists for the target architecture, is created by kxld,
2058 * and we must populate it according to our internal structures.
2060 if (object
->is_final_image
) {
2061 #if KXLD_USER_OR_BUNDLE
2062 rval
= process_symbol_pointers(object
);
2063 require_noerr(rval
, finish
);
2065 rval
= process_relocs_from_tables(object
);
2066 require_noerr(rval
, finish
);
2068 require_action(FALSE
, finish
, rval
=KERN_FAILURE
);
2069 #endif /* KXLD_USER_OR_BUNDLE */
2071 #if KXLD_USER_OR_GOT
2073 rval
= populate_got(object
);
2074 require_noerr(rval
, finish
);
2075 #endif /* KXLD_USER_OR_GOT */
2076 #if KXLD_USER_OR_OBJECT
2077 rval
= process_relocs_from_sections(object
);
2078 require_noerr(rval
, finish
);
2080 require_action(FALSE
, finish
, rval
=KERN_FAILURE
);
2081 #endif /* KXLD_USER_OR_OBJECT */
2084 /* Populate kmod info structure */
2085 rval
= populate_kmod_info(object
);
2086 require_noerr(rval
, finish
);
2088 rval
= KERN_SUCCESS
;
2093 #if KXLD_USER_OR_BUNDLE
2095 #define SECT_SYM_PTRS "__nl_symbol_ptr"
2097 /*******************************************************************************
2098 * Final linked images create an __nl_symbol_ptr section for the global offset
2099 * table and for symbol pointer lookups in general. Rather than use relocation
2100 * entries, the linker creates an "indirect symbol table" which stores indexes
2101 * into the symbol table corresponding to the entries of this section. This
2102 * function populates the section with the relocated addresses of those symbols.
2103 *******************************************************************************/
2104 static kern_return_t
2105 process_symbol_pointers(KXLDObject
*object
)
2107 kern_return_t rval
= KERN_FAILURE
;
2108 KXLDSect
*sect
= NULL
;
2109 KXLDSym
*sym
= NULL
;
2110 int32_t *symidx
= NULL
;
2111 u_char
*symptr
= NULL
;
2112 u_long symptrsize
= 0;
2119 require_action(object
->is_final_image
&& object
->dysymtab_hdr
,
2120 finish
, rval
=KERN_FAILURE
);
2122 /* Get the __DATA,__nl_symbol_ptr section. If it doesn't exist, we have
2126 sect
= kxld_object_get_sect_by_name(object
, SEG_DATA
, SECT_SYM_PTRS
);
2127 if (!sect
|| !(sect
->flags
& S_NON_LAZY_SYMBOL_POINTERS
)) {
2128 rval
= KERN_SUCCESS
;
2132 /* Calculate the table offset and number of entries in the section */
2134 if (kxld_object_is_32_bit(object
)) {
2135 symptrsize
= sizeof(uint32_t);
2137 symptrsize
= sizeof(uint64_t);
2140 nsyms
= (u_int
) (sect
->size
/ symptrsize
);
2141 firstsym
= sect
->reserved1
;
2143 require_action(firstsym
+ nsyms
<= object
->dysymtab_hdr
->nindirectsyms
,
2144 finish
, rval
=KERN_FAILURE
;
2145 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogMalformedMachO
2146 "firstsym + nsyms > object->dysymtab_hdr->nindirectsyms"));
2148 /* Iterate through the indirect symbol table and fill in the section of
2149 * symbol pointers. There are three cases:
2150 * 1) A normal symbol - put its value directly in the table
2151 * 2) An INDIRECT_SYMBOL_LOCAL - symbols that are local and already have
2152 * their offset from the start of the file in the section. Simply
2153 * add the file's link address to fill this entry.
2154 * 3) An INDIRECT_SYMBOL_ABS - prepopulated absolute symbols. No
2155 * action is required.
2158 symidx
= (int32_t *) ((void *) (object
->file
+ object
->dysymtab_hdr
->indirectsymoff
));
2160 symptr
= sect
->data
;
2161 for (i
= 0; i
< nsyms
; ++i
, ++symidx
, symptr
+=symptrsize
) {
2162 if (*symidx
& INDIRECT_SYMBOL_LOCAL
) {
2163 if (*symidx
& INDIRECT_SYMBOL_ABS
) continue;
2165 add_to_ptr(symptr
, object
->link_addr
, kxld_object_is_32_bit(object
));
2167 sym
= kxld_symtab_get_symbol_by_index(object
->symtab
, *symidx
);
2168 require_action(sym
, finish
, rval
=KERN_FAILURE
);
2170 add_to_ptr(symptr
, sym
->link_addr
, kxld_object_is_32_bit(object
));
2174 rval
= KERN_SUCCESS
;
2179 /*******************************************************************************
2180 *******************************************************************************/
2182 get_seg_by_base_addr(KXLDObject
*object
, kxld_addr_t base_addr
)
2184 KXLDSeg
*seg
= NULL
;
2185 kxld_addr_t start
= 0;
2186 kxld_addr_t end
= 0;
2189 for (i
= 0; i
< object
->segs
.nitems
; ++i
) {
2190 seg
= kxld_array_get_item(&object
->segs
, i
);
2191 start
= seg
->base_addr
;
2192 end
= seg
->base_addr
+ seg
->vmsize
;
2194 if (start
<= base_addr
&& base_addr
< end
) return seg
;
2200 /*******************************************************************************
2201 *******************************************************************************/
2202 static kern_return_t
2203 process_relocs_from_tables(KXLDObject
*object
)
2205 kern_return_t rval
= KERN_FAILURE
;
2206 KXLDReloc
*reloc
= NULL
;
2207 KXLDSeg
*seg
= NULL
;
2210 /* Process external relocations */
2211 for (i
= 0; i
< object
->extrelocs
.nitems
; ++i
) {
2212 reloc
= kxld_array_get_item(&object
->extrelocs
, i
);
2214 seg
= get_seg_by_base_addr(object
, reloc
->address
);
2215 require_action(seg
, finish
, rval
=KERN_FAILURE
);
2217 rval
= kxld_relocator_process_table_reloc(&object
->relocator
, reloc
,
2218 seg
, object
->link_addr
);
2219 require_noerr(rval
, finish
);
2222 /* Process local relocations */
2223 for (i
= 0; i
< object
->locrelocs
.nitems
; ++i
) {
2224 reloc
= kxld_array_get_item(&object
->locrelocs
, i
);
2226 seg
= get_seg_by_base_addr(object
, reloc
->address
);
2227 require_action(seg
, finish
, rval
=KERN_FAILURE
);
2229 rval
= kxld_relocator_process_table_reloc(&object
->relocator
, reloc
,
2230 seg
, object
->link_addr
);
2231 require_noerr(rval
, finish
);
2234 rval
= KERN_SUCCESS
;
2239 /*******************************************************************************
2240 *******************************************************************************/
2242 add_to_ptr(u_char
*symptr
, kxld_addr_t val
, boolean_t is_32_bit
)
2245 uint32_t *ptr
= (uint32_t *) ((void *) symptr
);
2246 *ptr
+= (uint32_t) val
;
2248 uint64_t *ptr
= (uint64_t *) ((void *) symptr
);
2249 *ptr
+= (uint64_t) val
;
2252 #endif /* KXLD_USER_OR_BUNDLE */
2254 #if KXLD_USER_OR_OBJECT
2255 /*******************************************************************************
2256 *******************************************************************************/
2257 static kern_return_t
2258 process_relocs_from_sections(KXLDObject
*object
)
2260 kern_return_t rval
= KERN_FAILURE
;
2261 KXLDSect
*sect
= NULL
;
2264 for (i
= 0; i
< object
->sects
.nitems
; ++i
) {
2265 sect
= kxld_array_get_item(&object
->sects
, i
);
2266 rval
= kxld_sect_process_relocs(sect
, &object
->relocator
);
2267 require_noerr(rval
, finish
);
2270 rval
= KERN_SUCCESS
;
2274 #endif /* KXLD_USER_OR_OBJECT */
2276 /*******************************************************************************
2277 *******************************************************************************/
2278 static kern_return_t
2279 populate_kmod_info(KXLDObject
*object
)
2281 kern_return_t rval
= KERN_FAILURE
;
2282 KXLDSect
*kmodsect
= NULL
;
2283 KXLDSym
*kmodsym
= NULL
;
2284 kmod_info_t
*kmod_info
= NULL
;
2285 u_long kmod_offset
= 0;
2289 if (kxld_object_is_kernel(object
)) {
2290 rval
= KERN_SUCCESS
;
2294 kxld_object_get_vmsize(object
, &header_size
, &size
);
2296 kmodsym
= kxld_symtab_get_locally_defined_symbol_by_name(object
->symtab
,
2297 KXLD_KMOD_INFO_SYMBOL
);
2298 require_action(kmodsym
, finish
, rval
=KERN_FAILURE
;
2299 kxld_log(kKxldLogLinking
, kKxldLogErr
, kKxldLogNoKmodInfo
));
2301 kmodsect
= kxld_array_get_item(&object
->sects
, kmodsym
->sectnum
);
2302 kmod_offset
= (u_long
) (kmodsym
->base_addr
- kmodsect
->base_addr
);
2303 kmod_info
= (kmod_info_t
*) ((void *) (kmodsect
->data
+ kmod_offset
));
2305 if (kxld_object_is_32_bit(object
)) {
2306 kmod_info_32_v1_t
*kmod
= (kmod_info_32_v1_t
*) (kmod_info
);
2307 kmod
->address
= (uint32_t) object
->link_addr
;
2308 kmod
->size
= (uint32_t) size
;
2309 kmod
->hdr_size
= (uint32_t) header_size
;
2312 if (kxld_object_target_needs_swap(object
)) {
2313 kmod
->address
= OSSwapInt32(kmod
->address
);
2314 kmod
->size
= OSSwapInt32(kmod
->size
);
2315 kmod
->hdr_size
= OSSwapInt32(kmod
->hdr_size
);
2317 #endif /* !KERNEL */
2319 kmod_info_64_v1_t
*kmod
= (kmod_info_64_v1_t
*) (kmod_info
);
2320 kmod
->address
= object
->link_addr
;
2322 kmod
->hdr_size
= header_size
;
2325 if (kxld_object_target_needs_swap(object
)) {
2326 kmod
->address
= OSSwapInt64(kmod
->address
);
2327 kmod
->size
= OSSwapInt64(kmod
->size
);
2328 kmod
->hdr_size
= OSSwapInt64(kmod
->hdr_size
);
2330 #endif /* !KERNEL */
2334 rval
= KERN_SUCCESS
;
2341 /*******************************************************************************
2342 *******************************************************************************/
2344 target_supports_slideable_kexts(const KXLDObject
*object
)
2348 return (object
->cputype
!= CPU_TYPE_I386
&& object
->include_kaslr_relocs
);
2350 #endif /* KXLD_PIC_KEXTS */