1 /*
2 * Copyright (c) 2009-2014 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
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.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
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.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28 #include <string.h>
29 #include <sys/types.h>
30
31 #if KERNEL
32 #include <libkern/kernel_mach_header.h>
33 #include <mach/machine.h>
34 #include <mach/vm_param.h>
35 #include <mach-o/fat.h>
36 #else /* !KERNEL */
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.
39 */
40 #include "../../osfmk/mach/machine.h"
41
42 #include <architecture/byte_order.h>
43 #include <mach/mach_init.h>
44 #include <mach-o/arch.h>
45 #include <mach-o/swap.h>
46 #endif /* KERNEL */
47
48 #include <mach-o/loader.h>
49 #include <mach-o/nlist.h>
50 #include <mach-o/reloc.h>
51 #include <os/overflow.h>
52
53 #define DEBUG_ASSERT_COMPONENT_NAME_STRING "kxld"
54 #include <AssertMacros.h>
55
56 #include "kxld_demangle.h"
57 #include "kxld_dict.h"
58 #include "kxld_reloc.h"
59 #include "kxld_sect.h"
60 #include "kxld_seg.h"
61 #include "kxld_srcversion.h"
62 #include "kxld_symtab.h"
63 #include "kxld_util.h"
64 #include "kxld_uuid.h"
65 #include "kxld_versionmin.h"
66 #include "kxld_vtable.h"
67 #include "kxld_splitinfolc.h"
68
69 #include "kxld_object.h"
70
71 /* NXArchInfo and friends are deprecated */
72 #pragma clang diagnostic push
73 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
74
75
76 extern boolean_t isSplitKext;
77 extern boolean_t isOldInterface;
78
79 /*******************************************************************************
80 * Data structures
81 *******************************************************************************/
82
83 struct kxld_object {
84 u_char *file; // used by old interface
85 u_long size; // used by old interface
86 const char *name;
87 uint32_t filetype;
88 cpu_type_t cputype;
89 cpu_subtype_t cpusubtype;
90 KXLDArray segs;
91 KXLDArray sects;
92 KXLDArray extrelocs;
93 KXLDArray locrelocs;
94 KXLDRelocator relocator;
95 KXLDuuid uuid;
96 KXLDversionmin versionmin;
97 KXLDsrcversion srcversion;
98 KXLDSymtab *symtab;
99 struct dysymtab_command *dysymtab_hdr;
100 KXLDsplitinfolc splitinfolc;
101 splitKextLinkInfo split_info;
102 kxld_addr_t link_addr;
103 u_long output_buffer_size;
104 boolean_t is_kernel;
105 boolean_t is_final_image;
106 boolean_t is_linked;
107 boolean_t got_is_created;
108 #if KXLD_USER_OR_OBJECT
109 KXLDArray *section_order;
110 #endif
111 #if KXLD_PIC_KEXTS
112 boolean_t include_kaslr_relocs;
113 #endif
114 #if !KERNEL
115 enum NXByteOrder host_order;
116 enum NXByteOrder target_order;
117 #endif
118 };
119
120 /*******************************************************************************
121 * Prototypes
122 *******************************************************************************/
123
124 static kern_return_t get_target_machine_info(KXLDObject *object,
125 cpu_type_t cputype, cpu_subtype_t cpusubtype);
126 static kern_return_t get_macho_slice_for_arch(KXLDObject *object,
127 u_char *file, u_long size);
128
129 static u_long get_macho_header_size(const KXLDObject *object);
130 static u_long get_macho_data_size(const KXLDObject *object) __unused;
131
132 static kern_return_t init_from_execute(KXLDObject *object);
133 static kern_return_t init_from_final_linked_image(KXLDObject *object,
134 u_int *filetype_out, struct symtab_command **symtab_hdr_out);
135
136 static boolean_t target_supports_protected_segments(const KXLDObject *object)
137 __attribute__((pure));
138 static void set_is_object_linked(KXLDObject *object);
139
140 #if KXLD_USER_OR_BUNDLE
141 static boolean_t target_supports_bundle(const KXLDObject *object)
142 __attribute((pure));
143 static kern_return_t init_from_bundle(KXLDObject *object);
144 static kern_return_t process_relocs_from_tables(KXLDObject *object);
145 static KXLDSeg *get_seg_by_base_addr(KXLDObject *object,
146 kxld_addr_t base_addr);
147 static kern_return_t process_symbol_pointers(KXLDObject *object);
148 static void add_to_ptr(u_char *symptr, kxld_addr_t val, boolean_t is_32_bit);
149 #endif /* KXLD_USER_OR_BUNDLE */
150
151 #if KXLD_USER_OR_OBJECT
152 static boolean_t target_supports_object(const KXLDObject *object)
153 __attribute((pure));
154 static kern_return_t init_from_object(KXLDObject *object);
155 static kern_return_t process_relocs_from_sections(KXLDObject *object);
156 #endif /* KXLD_USER_OR_OBJECT */
157
158 #if KXLD_PIC_KEXTS
159 static boolean_t target_supports_slideable_kexts(const KXLDObject *object);
160 #endif /* KXLD_PIC_KEXTS */
161
162
163 static kern_return_t export_macho_header(const KXLDObject *object, u_char *buf,
164 u_int ncmds, u_long *header_offset, u_long header_size);
165 #if KXLD_USER_OR_ILP32
166 static u_long get_macho_cmd_data_32(u_char *file, u_long offset,
167 u_int *filetype, u_int *ncmds);
168 static kern_return_t export_macho_header_32(const KXLDObject *object,
169 u_char *buf, u_int ncmds, u_long *header_offset, u_long header_size);
170 #endif /* KXLD_USER_OR_ILP32 */
171 #if KXLD_USER_OR_LP64
172 static u_long get_macho_cmd_data_64(u_char *file, u_long offset,
173 u_int *filetype, u_int *ncmds);
174 static kern_return_t export_macho_header_64(const KXLDObject *object,
175 u_char *buf, u_int ncmds, u_long *header_offset, u_long header_size);
176 #endif /* KXLD_USER_OR_LP64 */
177
178 #if KXLD_USER_OR_GOT || KXLD_USER_OR_COMMON
179 static kern_return_t add_section(KXLDObject *object, KXLDSect **sect);
180 #endif /* KXLD_USER_OR_GOT || KXLD_USER_OR_COMMON */
181
182 #if KXLD_USER_OR_COMMON
183 static kern_return_t resolve_common_symbols(KXLDObject *object);
184 #endif /* KXLD_USER_OR_COMMON */
185
186 #if KXLD_USER_OR_GOT
187 static boolean_t target_has_got(const KXLDObject *object) __attribute__((pure));
188 static kern_return_t create_got(KXLDObject *object);
189 static kern_return_t populate_got(KXLDObject *object);
190 #endif /* KXLD_USER_OR_GOT */
191
192 static KXLDSym *get_mutable_sym(const KXLDObject *object, const KXLDSym *sym);
193
194 static kern_return_t populate_kmod_info(KXLDObject *object);
195
196 /*******************************************************************************
197 * Prototypes that may need to be exported
198 *******************************************************************************/
199 static boolean_t kxld_object_target_needs_swap(const KXLDObject *object __unused);
200 static KXLDSeg * kxld_object_get_seg_by_name(const KXLDObject *object, const char *segname);
201 static KXLDSect * kxld_object_get_sect_by_name(const KXLDObject *object, const char *segname,
202 const char *sectname);
203
204 /*******************************************************************************
205 *******************************************************************************/
206 size_t
kxld_object_sizeof(void)207 kxld_object_sizeof(void)
208 {
209 return sizeof(KXLDObject);
210 }
211
212 /*******************************************************************************
213 *******************************************************************************/
214 kern_return_t
kxld_object_init_from_macho(KXLDObject * object,u_char * file,u_long size,const char * name,KXLDArray * section_order __unused,cpu_type_t cputype,cpu_subtype_t cpusubtype,KXLDFlags flags __unused)215 kxld_object_init_from_macho(KXLDObject *object, u_char *file, u_long size,
216 const char *name, KXLDArray *section_order __unused,
217 cpu_type_t cputype, cpu_subtype_t cpusubtype, KXLDFlags flags __unused)
218 {
219 kern_return_t rval = KERN_FAILURE;
220 KXLDSeg * seg = NULL;
221 u_int i = 0;
222 u_char * my_file;
223
224 check(object);
225 check(file);
226 check(name);
227
228 object->name = name;
229
230 #if KXLD_USER_OR_OBJECT
231 object->section_order = section_order;
232 #endif
233 #if KXLD_PIC_KEXTS
234 object->include_kaslr_relocs = ((flags & kKXLDFlagIncludeRelocs) == kKXLDFlagIncludeRelocs);
235 #endif
236
237 /* Find the local architecture */
238
239 rval = get_target_machine_info(object, cputype, cpusubtype);
240 require_noerr(rval, finish);
241
242 /* Find the Mach-O slice for the target architecture */
243
244 rval = get_macho_slice_for_arch(object, file, size);
245 require_noerr(rval, finish);
246
247 if (isOldInterface) {
248 my_file = object->file;
249 } else {
250 my_file = object->split_info.kextExecutable;
251 }
252
253 /* Allocate the symbol table */
254
255 if (!object->symtab) {
256 object->symtab = kxld_calloc(kxld_symtab_sizeof());
257 require_action(object->symtab, finish, rval = KERN_RESOURCE_SHORTAGE);
258 }
259
260 /* Build the relocator */
261
262 rval = kxld_relocator_init(&object->relocator,
263 my_file,
264 object->symtab, &object->sects,
265 object->cputype,
266 object->cpusubtype,
267 kxld_object_target_needs_swap(object));
268 require_noerr(rval, finish);
269
270 /* There are four types of Mach-O files that we can support:
271 * 1) 32-bit MH_OBJECT - Snow Leopard and earlier
272 * 2) 32-bit MH_KEXT_BUNDLE - Lion and Later
273 * 3) 64-bit MH_OBJECT - Unsupported
274 * 4) 64-bit MH_KEXT_BUNDLE - Snow Leopard and Later
275 */
276
277 if (kxld_object_is_32_bit(object)) {
278 struct mach_header *mach_hdr = (struct mach_header *) ((void *) my_file);
279 object->filetype = mach_hdr->filetype;
280 } else {
281 struct mach_header_64 *mach_hdr = (struct mach_header_64 *) ((void *) my_file);
282 object->filetype = mach_hdr->filetype;
283 }
284
285 switch (object->filetype) {
286 #if KXLD_USER_OR_BUNDLE
287 case MH_KEXT_BUNDLE:
288 rval = init_from_bundle(object);
289 require_noerr(rval, finish);
290 break;
291 #endif /* KXLD_USER_OR_BUNDLE */
292 #if KXLD_USER_OR_OBJECT
293 case MH_OBJECT:
294 rval = init_from_object(object);
295 require_noerr(rval, finish);
296 break;
297 #endif /* KXLD_USER_OR_OBJECT */
298 case MH_EXECUTE:
299 object->is_kernel = TRUE;
300 rval = init_from_execute(object);
301 require_noerr(rval, finish);
302 break;
303 default:
304 rval = KERN_FAILURE;
305 kxld_log(kKxldLogLinking, kKxldLogErr,
306 kKxldLogFiletypeNotSupported, object->filetype);
307 goto finish;
308 }
309
310 if (!kxld_object_is_kernel(object)) {
311 for (i = 0; i < object->segs.nitems; ++i) {
312 seg = kxld_array_get_item(&object->segs, i);
313 kxld_seg_set_vm_protections(seg,
314 target_supports_protected_segments(object));
315 }
316
317 seg = kxld_object_get_seg_by_name(object, SEG_LINKEDIT);
318 if (seg) {
319 (void) kxld_seg_populate_linkedit(seg, object->symtab,
320 kxld_object_is_32_bit(object)
321 #if KXLD_PIC_KEXTS
322 , &object->locrelocs, &object->extrelocs,
323 target_supports_slideable_kexts(object)
324 #endif
325 , isOldInterface ? 0 : object->splitinfolc.datasize
326 );
327 }
328 }
329
330 (void) set_is_object_linked(object);
331
332 rval = KERN_SUCCESS;
333 finish:
334 return rval;
335 }
336
337 /*******************************************************************************
338 *******************************************************************************/
339 splitKextLinkInfo *
kxld_object_get_link_info(KXLDObject * object)340 kxld_object_get_link_info(KXLDObject *object)
341 {
342 check(object);
343
344 return &object->split_info;
345 }
346
347
348 /*******************************************************************************
349 *******************************************************************************/
350 void
kxld_object_set_link_info(KXLDObject * object,splitKextLinkInfo * link_info)351 kxld_object_set_link_info(KXLDObject *object, splitKextLinkInfo *link_info)
352 {
353 check(object);
354 check(link_info);
355
356 object->split_info.vmaddr_TEXT = link_info->vmaddr_TEXT;
357 object->split_info.vmaddr_TEXT_EXEC = link_info->vmaddr_TEXT_EXEC;
358 object->split_info.vmaddr_DATA = link_info->vmaddr_DATA;
359 object->split_info.vmaddr_DATA_CONST = link_info->vmaddr_DATA_CONST;
360 object->split_info.vmaddr_LLVM_COV = link_info->vmaddr_LLVM_COV;
361 object->split_info.vmaddr_LINKEDIT = link_info->vmaddr_LINKEDIT;
362
363 return;
364 }
365
366 /*******************************************************************************
367 *******************************************************************************/
368 kern_return_t
get_target_machine_info(KXLDObject * object,cpu_type_t cputype __unused,cpu_subtype_t cpusubtype __unused)369 get_target_machine_info(KXLDObject *object, cpu_type_t cputype __unused,
370 cpu_subtype_t cpusubtype __unused)
371 {
372 #if KERNEL
373
374 /* Because the kernel can only link for its own architecture, we know what
375 * the host and target architectures are at compile time, so we can use
376 * a vastly simplified version of this function.
377 */
378
379 check(object);
380
381 #if defined(__x86_64__)
382 object->cputype = CPU_TYPE_X86_64;
383 /* FIXME: we need clang to provide a __x86_64h__ macro for the sub-type. Using
384 * __AVX2__ is a temporary solution until this is available. */
385 #if defined(__AVX2__)
386 object->cpusubtype = CPU_SUBTYPE_X86_64_H;
387 #else
388 object->cpusubtype = CPU_SUBTYPE_X86_64_ALL;
389 #endif
390 return KERN_SUCCESS;
391 #elif defined(__arm__)
392 object->cputype = CPU_TYPE_ARM;
393 object->cpusubtype = CPU_SUBTYPE_ARM_ALL;
394 return KERN_SUCCESS;
395 #elif defined(__arm64__)
396 object->cputype = CPU_TYPE_ARM64;
397 object->cpusubtype = CPU_SUBTYPE_ARM64_ALL;
398 return KERN_SUCCESS;
399 #else
400 kxld_log(kKxldLogLinking, kKxldLogErr,
401 kKxldLogArchNotSupported, _mh_execute_header->cputype);
402 return KERN_NOT_SUPPORTED;
403 #endif /* Supported architecture defines */
404
405
406 #else /* !KERNEL */
407
408 /* User-space must look up the architecture it's running on and the target
409 * architecture at run-time.
410 */
411
412 kern_return_t rval = KERN_FAILURE;
413 const NXArchInfo *host_arch = NULL;
414
415 check(object);
416
417 host_arch = NXGetLocalArchInfo();
418 require_action(host_arch, finish, rval = KERN_FAILURE);
419
420 object->host_order = host_arch->byteorder;
421
422 /* If the user did not specify a cputype, use the local architecture.
423 */
424
425 if (cputype) {
426 object->cputype = cputype;
427 object->cpusubtype = cpusubtype;
428 } else {
429 object->cputype = host_arch->cputype;
430 object->target_order = object->host_order;
431
432 switch (object->cputype) {
433 case CPU_TYPE_I386:
434 object->cpusubtype = CPU_SUBTYPE_I386_ALL;
435 break;
436 case CPU_TYPE_X86_64:
437 object->cpusubtype = CPU_SUBTYPE_X86_64_ALL;
438 break;
439 case CPU_TYPE_ARM:
440 object->cpusubtype = CPU_SUBTYPE_ARM_ALL;
441 break;
442 case CPU_TYPE_ARM64:
443 object->cpusubtype = CPU_SUBTYPE_ARM64_ALL;
444 break;
445 default:
446 object->cpusubtype = 0;
447 break;
448 }
449 }
450
451 /* Validate that we support the target architecture and record its
452 * endianness.
453 */
454
455 switch (object->cputype) {
456 case CPU_TYPE_ARM:
457 case CPU_TYPE_ARM64:
458 case CPU_TYPE_I386:
459 case CPU_TYPE_X86_64:
460 object->target_order = NX_LittleEndian;
461 break;
462 default:
463 rval = KERN_NOT_SUPPORTED;
464 kxld_log(kKxldLogLinking, kKxldLogErr,
465 kKxldLogArchNotSupported, object->cputype);
466 goto finish;
467 }
468
469 rval = KERN_SUCCESS;
470
471 finish:
472 return rval;
473 #endif /* KERNEL */
474 }
475
476 /*******************************************************************************
477 *******************************************************************************/
478 static kern_return_t
get_macho_slice_for_arch(KXLDObject * object,u_char * file,u_long size)479 get_macho_slice_for_arch(KXLDObject *object, u_char *file, u_long size)
480 {
481 kern_return_t rval = KERN_FAILURE;
482 struct mach_header *mach_hdr = NULL;
483 #if !KERNEL
484 struct fat_header *fat = (struct fat_header *) ((void *) file);
485 struct fat_arch *archs = (struct fat_arch *) &fat[1];
486 boolean_t swap = FALSE;
487 #endif /* KERNEL */
488 u_char *my_file = file;
489 u_long my_file_size = size;
490
491 check(object);
492 check(file);
493 check(size);
494
495 /* We are assuming that we will never receive a fat file in the kernel */
496
497 #if !KERNEL
498 require_action(size >= sizeof(*fat), finish,
499 rval = KERN_FAILURE;
500 kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogTruncatedMachO));
501
502 /* The fat header is always big endian, so swap if necessary */
503 if (fat->magic == FAT_CIGAM) {
504 (void) swap_fat_header(fat, object->host_order);
505 swap = TRUE;
506 }
507
508 if (fat->magic == FAT_MAGIC) {
509 struct fat_arch *arch = NULL;
510 u_long arch_size;
511 boolean_t ovr = os_mul_and_add_overflow(fat->nfat_arch, sizeof(*archs), sizeof(*fat), &arch_size);
512
513 require_action(!ovr && size >= arch_size,
514 finish,
515 rval = KERN_FAILURE;
516 kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogTruncatedMachO));
517
518 /* Swap the fat_arch structures if necessary */
519 if (swap) {
520 (void) swap_fat_arch(archs, fat->nfat_arch, object->host_order);
521 }
522
523 /* Locate the Mach-O for the requested architecture */
524
525 arch = NXFindBestFatArch(object->cputype, object->cpusubtype, archs, fat->nfat_arch);
526 require_action(arch, finish, rval = KERN_FAILURE;
527 kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogArchNotFound));
528 require_action(size >= arch->offset + arch->size, finish,
529 rval = KERN_FAILURE;
530 kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogTruncatedMachO));
531
532 my_file = my_file + arch->offset;
533 my_file_size = arch->size;
534 }
535 #endif /* !KERNEL */
536
537 /* Swap the Mach-O's headers to this architecture if necessary */
538 if (kxld_object_is_32_bit(object)) {
539 rval = validate_and_swap_macho_32(my_file, my_file_size
540 #if !KERNEL
541 , object->host_order
542 #endif /* !KERNEL */
543 );
544 } else {
545 rval = validate_and_swap_macho_64(my_file, my_file_size
546 #if !KERNEL
547 , object->host_order
548 #endif /* !KERNEL */
549 );
550 }
551 require_noerr(rval, finish);
552
553 mach_hdr = (struct mach_header *) ((void *) my_file);
554 require_action(object->cputype == mach_hdr->cputype, finish,
555 rval = KERN_FAILURE;
556 kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogTruncatedMachO));
557 object->cpusubtype = mach_hdr->cpusubtype; /* <rdar://problem/16008438> */
558
559 if (isOldInterface) {
560 object->file = my_file;
561 object->size = my_file_size;
562 } else {
563 object->split_info.kextExecutable = my_file;
564 object->split_info.kextSize = my_file_size;
565 }
566
567 rval = KERN_SUCCESS;
568 finish:
569 return rval;
570 }
571
572 /*******************************************************************************
573 *******************************************************************************/
574 static kern_return_t
init_from_final_linked_image(KXLDObject * object,u_int * filetype_out,struct symtab_command ** symtab_hdr_out)575 init_from_final_linked_image(KXLDObject *object, u_int *filetype_out,
576 struct symtab_command **symtab_hdr_out)
577 {
578 kern_return_t rval = KERN_FAILURE;
579 KXLDSeg *seg = NULL;
580 KXLDSect *sect = NULL;
581 struct load_command *cmd_hdr = NULL;
582 struct symtab_command *symtab_hdr = NULL;
583 struct uuid_command *uuid_hdr = NULL;
584 struct version_min_command *versionmin_hdr = NULL;
585 struct build_version_command *build_version_hdr = NULL;
586 struct source_version_command *source_version_hdr = NULL;
587 u_long base_offset = 0;
588 u_long offset = 0;
589 u_long sect_offset = 0;
590 u_int filetype = 0;
591 u_int i = 0;
592 u_int j = 0;
593 u_int segi = 0;
594 u_int secti = 0;
595 u_int nsegs = 0;
596 u_int nsects = 0;
597 u_int ncmds = 0;
598 u_char *my_file;
599
600 if (isOldInterface) {
601 my_file = object->file;
602 } else {
603 my_file = object->split_info.kextExecutable;
604 }
605
606 KXLD_3264_FUNC(kxld_object_is_32_bit(object), base_offset,
607 get_macho_cmd_data_32, get_macho_cmd_data_64,
608 my_file, offset, &filetype, &ncmds);
609
610 /* First pass to count segments and sections */
611
612 offset = base_offset;
613 for (i = 0; i < ncmds; ++i, offset += cmd_hdr->cmdsize) {
614 cmd_hdr = (struct load_command *) ((void *) (my_file + offset));
615
616 switch (cmd_hdr->cmd) {
617 #if KXLD_USER_OR_ILP32
618 case LC_SEGMENT:
619 {
620 struct segment_command *seg_hdr =
621 (struct segment_command *) cmd_hdr;
622
623 /* Ignore segments with no vm size */
624 if (!seg_hdr->vmsize) {
625 continue;
626 }
627
628 ++nsegs;
629 nsects += seg_hdr->nsects;
630 }
631 break;
632 #endif /* KXLD_USER_OR_ILP32 */
633 #if KXLD_USER_OR_LP64
634 case LC_SEGMENT_64:
635 {
636 struct segment_command_64 *seg_hdr =
637 (struct segment_command_64 *) ((void *) cmd_hdr);
638
639 /* Ignore segments with no vm size */
640 if (!seg_hdr->vmsize) {
641 continue;
642 }
643
644 ++nsegs;
645 nsects += seg_hdr->nsects;
646 }
647 break;
648 #endif /* KXLD_USER_OR_LP64 */
649 default:
650 continue;
651 }
652 }
653
654 /* Allocate the segments and sections */
655
656 if (nsegs) {
657 rval = kxld_array_init(&object->segs, sizeof(KXLDSeg), nsegs);
658 require_noerr(rval, finish);
659
660 rval = kxld_array_init(&object->sects, sizeof(KXLDSect), nsects);
661 require_noerr(rval, finish);
662 }
663
664 /* Initialize the segments and sections */
665
666 offset = base_offset;
667 for (i = 0; i < ncmds; ++i, offset += cmd_hdr->cmdsize) {
668 cmd_hdr = (struct load_command *) ((void *) (my_file + offset));
669 seg = NULL;
670
671 switch (cmd_hdr->cmd) {
672 #if KXLD_USER_OR_ILP32
673 case LC_SEGMENT:
674 {
675 struct segment_command *seg_hdr =
676 (struct segment_command *) cmd_hdr;
677
678 /* Ignore segments with no vm size */
679 if (!seg_hdr->vmsize) {
680 continue;
681 }
682
683 seg = kxld_array_get_item(&object->segs, segi++);
684
685 rval = kxld_seg_init_from_macho_32(seg, seg_hdr);
686 require_noerr(rval, finish);
687
688 sect_offset = offset + sizeof(*seg_hdr);
689 }
690 break;
691 #endif /* KXLD_USER_OR_ILP32 */
692 #if KXLD_USER_OR_LP64
693 case LC_SEGMENT_64:
694 {
695 struct segment_command_64 *seg_hdr =
696 (struct segment_command_64 *) ((void *) cmd_hdr);
697
698 /* Ignore segments with no vm size */
699 if (!seg_hdr->vmsize) {
700 continue;
701 }
702
703 seg = kxld_array_get_item(&object->segs, segi++);
704
705 rval = kxld_seg_init_from_macho_64(seg, seg_hdr);
706 require_noerr(rval, finish);
707
708 sect_offset = offset + sizeof(*seg_hdr);
709 }
710 break;
711 #endif /* KXLD_USER_OR_LP64 */
712 case LC_SYMTAB:
713 symtab_hdr = (struct symtab_command *) cmd_hdr;
714 break;
715 case LC_UUID:
716 uuid_hdr = (struct uuid_command *) cmd_hdr;
717 kxld_uuid_init_from_macho(&object->uuid, uuid_hdr);
718 break;
719 case LC_VERSION_MIN_MACOSX:
720 case LC_VERSION_MIN_IPHONEOS:
721 case LC_VERSION_MIN_TVOS:
722 case LC_VERSION_MIN_WATCHOS:
723 versionmin_hdr = (struct version_min_command *) cmd_hdr;
724 kxld_versionmin_init_from_macho(&object->versionmin, versionmin_hdr);
725 break;
726 case LC_BUILD_VERSION:
727 build_version_hdr = (struct build_version_command *)cmd_hdr;
728 kxld_versionmin_init_from_build_cmd(&object->versionmin, build_version_hdr);
729 break;
730 case LC_SOURCE_VERSION:
731 source_version_hdr = (struct source_version_command *) (void *) cmd_hdr;
732 kxld_srcversion_init_from_macho(&object->srcversion, source_version_hdr);
733 break;
734 case LC_DYSYMTAB:
735 object->dysymtab_hdr = (struct dysymtab_command *) cmd_hdr;
736 rval = kxld_reloc_create_macho(&object->extrelocs, &object->relocator,
737 (struct relocation_info *) ((void *) (my_file + object->dysymtab_hdr->extreloff)),
738 object->dysymtab_hdr->nextrel);
739 require_noerr(rval, finish);
740
741 rval = kxld_reloc_create_macho(&object->locrelocs, &object->relocator,
742 (struct relocation_info *) ((void *) (my_file + object->dysymtab_hdr->locreloff)),
743 object->dysymtab_hdr->nlocrel);
744 require_noerr(rval, finish);
745
746 break;
747 case LC_UNIXTHREAD:
748 case LC_MAIN:
749 /* Don't need to do anything with UNIXTHREAD or MAIN for the kernel */
750 require_action(kxld_object_is_kernel(object),
751 finish, rval = KERN_FAILURE;
752 kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogMalformedMachO
753 "LC_UNIXTHREAD/LC_MAIN segment is not valid in a kext."));
754 break;
755 case LC_SEGMENT_SPLIT_INFO:
756 if (isSplitKext) {
757 struct linkedit_data_command *split_info_hdr = NULL;
758 split_info_hdr = (struct linkedit_data_command *) (void *) cmd_hdr;
759 kxld_splitinfolc_init_from_macho(&object->splitinfolc, split_info_hdr);
760 }
761 break;
762 case LC_NOTE:
763 /* binary blob of data */
764 break;
765 case LC_CODE_SIGNATURE:
766 case LC_DYLD_INFO:
767 case LC_DYLD_INFO_ONLY:
768 case LC_FUNCTION_STARTS:
769 case LC_DATA_IN_CODE:
770 case LC_DYLIB_CODE_SIGN_DRS:
771 /* Various metadata that might be stored in the linkedit segment */
772 break;
773 default:
774 rval = KERN_FAILURE;
775 kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogMalformedMachO
776 "Invalid load command type in MH_KEXT_BUNDLE kext: %u.", cmd_hdr->cmd);
777 goto finish;
778 }
779
780 if (seg) {
781 /* Initialize the sections */
782 for (j = 0; j < seg->sects.nitems; ++j, ++secti) {
783 sect = kxld_array_get_item(&object->sects, secti);
784
785 KXLD_3264_FUNC(kxld_object_is_32_bit(object), rval,
786 kxld_sect_init_from_macho_32, kxld_sect_init_from_macho_64,
787 sect, my_file, §_offset, secti, &object->relocator);
788 require_noerr(rval, finish);
789
790 /* Add the section to the segment. This will also make sure
791 * that the sections and segments have the same segname.
792 */
793 rval = kxld_seg_add_section(seg, sect);
794 require_noerr(rval, finish);
795 }
796 rval = kxld_seg_finish_init(seg);
797 require_noerr(rval, finish);
798 }
799 }
800
801 if (filetype_out) {
802 *filetype_out = filetype;
803 }
804 if (symtab_hdr_out) {
805 *symtab_hdr_out = symtab_hdr;
806 }
807 object->is_final_image = TRUE;
808 rval = KERN_SUCCESS;
809 finish:
810 return rval;
811 }
812
813 /*******************************************************************************
814 *******************************************************************************/
815 static kern_return_t
init_from_execute(KXLDObject * object)816 init_from_execute(KXLDObject *object)
817 {
818 kern_return_t rval = KERN_FAILURE;
819 struct symtab_command *symtab_hdr = NULL;
820 u_int filetype = 0;
821 KXLDSeg * kernel_linkedit_seg = NULL; // used if running kernel
822 #if KXLD_USER_OR_OBJECT
823 KXLDSeg *seg = NULL;
824 KXLDSect *sect = NULL;
825 KXLDSectionName *sname = NULL;
826 u_int i = 0, j = 0, k = 0;
827 #endif /* KXLD_USER_OR_OBJECT */
828 u_char *my_file;
829
830 check(object);
831
832 if (isOldInterface) {
833 my_file = object->file;
834 } else {
835 my_file = object->split_info.kextExecutable;
836 }
837
838 require_action(kxld_object_is_kernel(object), finish, rval = KERN_FAILURE);
839
840 rval = init_from_final_linked_image(object, &filetype, &symtab_hdr);
841 require_noerr(rval, finish);
842
843 require_action(filetype == MH_EXECUTE, finish, rval = KERN_FAILURE;
844 kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogMalformedMachO
845 "The kernel file is not of type MH_EXECUTE."));
846
847 /* Initialize the symbol table. If this is the running kernel
848 * we will work from the in-memory linkedit segment;
849 * otherwise we work from the whole mach-o image.
850 */
851 #if KERNEL
852 kernel_linkedit_seg = kxld_object_get_seg_by_name(object, SEG_LINKEDIT);
853 require_action(kernel_linkedit_seg, finish, rval = KERN_FAILURE;
854 kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogMalformedMachO));
855 #endif
856
857 KXLD_3264_FUNC(kxld_object_is_32_bit(object), rval,
858 kxld_symtab_init_from_macho_32, kxld_symtab_init_from_macho_64,
859 object->symtab, symtab_hdr, my_file, kernel_linkedit_seg);
860 require_noerr(rval, finish);
861
862 #if KXLD_USER_OR_OBJECT
863 /* Save off the order of section names so that we can lay out kext
864 * sections for MH_OBJECT-based systems.
865 */
866 if (target_supports_object(object)) {
867 rval = kxld_array_init(object->section_order, sizeof(KXLDSectionName),
868 object->sects.nitems);
869 require_noerr(rval, finish);
870
871 /* Copy the section names into the section_order array for future kext
872 * section ordering.
873 */
874 for (i = 0, k = 0; i < object->segs.nitems; ++i) {
875 seg = kxld_array_get_item(&object->segs, i);
876
877 for (j = 0; j < seg->sects.nitems; ++j, ++k) {
878 sect = *(KXLDSect **) kxld_array_get_item(&seg->sects, j);
879 sname = kxld_array_get_item(object->section_order, k);
880
881 strlcpy(sname->segname, sect->segname, sizeof(sname->segname));
882 strlcpy(sname->sectname, sect->sectname, sizeof(sname->sectname));
883 }
884 }
885 }
886 #endif /* KXLD_USER_OR_OBJECT */
887
888 rval = KERN_SUCCESS;
889 finish:
890 return rval;
891 }
892
893 #if KXLD_USER_OR_BUNDLE
894 /*******************************************************************************
895 *******************************************************************************/
896 static boolean_t
target_supports_bundle(const KXLDObject * object __unused)897 target_supports_bundle(const KXLDObject *object __unused)
898 {
899 return TRUE;
900 }
901
902 /*******************************************************************************
903 *******************************************************************************/
904 static kern_return_t
init_from_bundle(KXLDObject * object)905 init_from_bundle(KXLDObject *object)
906 {
907 kern_return_t rval = KERN_FAILURE;
908 struct symtab_command *symtab_hdr = NULL;
909 u_int filetype = 0;
910 u_char *my_file;
911
912 check(object);
913
914 if (isOldInterface) {
915 my_file = object->file;
916 } else {
917 my_file = object->split_info.kextExecutable;
918 }
919
920 require_action(target_supports_bundle(object), finish,
921 rval = KERN_FAILURE;
922 kxld_log(kKxldLogLinking, kKxldLogErr,
923 kKxldLogFiletypeNotSupported, MH_KEXT_BUNDLE));
924
925 rval = init_from_final_linked_image(object, &filetype, &symtab_hdr);
926 require_noerr(rval, finish);
927
928 require_action(filetype == MH_KEXT_BUNDLE, finish,
929 rval = KERN_FAILURE);
930
931 KXLD_3264_FUNC(kxld_object_is_32_bit(object), rval,
932 kxld_symtab_init_from_macho_32, kxld_symtab_init_from_macho_64,
933 object->symtab, symtab_hdr, my_file,
934 /* kernel_linkedit_seg */ NULL);
935 require_noerr(rval, finish);
936
937 rval = KERN_SUCCESS;
938 finish:
939 return rval;
940 }
941 #endif /* KXLD_USER_OR_BUNDLE */
942
943 #if KXLD_USER_OR_OBJECT
944 /*******************************************************************************
945 *******************************************************************************/
946 static boolean_t
target_supports_object(const KXLDObject * object)947 target_supports_object(const KXLDObject *object)
948 {
949 return object->cputype == CPU_TYPE_I386;
950 }
951
952 /*******************************************************************************
953 *******************************************************************************/
954 static kern_return_t
init_from_object(KXLDObject * object)955 init_from_object(KXLDObject *object)
956 {
957 kern_return_t rval = KERN_FAILURE;
958 struct load_command *cmd_hdr = NULL;
959 struct symtab_command *symtab_hdr = NULL;
960 struct uuid_command *uuid_hdr = NULL;
961 KXLDSect *sect = NULL;
962 u_long offset = 0;
963 u_long sect_offset = 0;
964 u_int filetype = 0;
965 u_int ncmds = 0;
966 u_int nsects = 0;
967 u_int i = 0;
968 boolean_t has_segment = FALSE;
969 u_char *my_file;
970
971 check(object);
972
973 if (isOldInterface) {
974 my_file = object->file;
975 } else {
976 my_file = object->split_info.kextExecutable;
977 }
978
979 require_action(target_supports_object(object),
980 finish, rval = KERN_FAILURE;
981 kxld_log(kKxldLogLinking, kKxldLogErr,
982 kKxldLogFiletypeNotSupported, MH_OBJECT));
983
984 KXLD_3264_FUNC(kxld_object_is_32_bit(object), offset,
985 get_macho_cmd_data_32, get_macho_cmd_data_64,
986 my_file, offset, &filetype, &ncmds);
987
988 require_action(filetype == MH_OBJECT, finish, rval = KERN_FAILURE);
989
990 /* MH_OBJECTs use one unnamed segment to contain all of the sections. We
991 * loop over all of the load commands to initialize the structures we
992 * expect. Then, we'll use the unnamed segment to get to all of the
993 * sections, and then use those sections to create the actual segments.
994 */
995
996 for (; i < ncmds; ++i, offset += cmd_hdr->cmdsize) {
997 cmd_hdr = (struct load_command *) ((void *) (my_file + offset));
998
999 switch (cmd_hdr->cmd) {
1000 #if KXLD_USER_OR_ILP32
1001 case LC_SEGMENT:
1002 {
1003 struct segment_command *seg_hdr =
1004 (struct segment_command *) cmd_hdr;
1005
1006 /* Ignore segments with no vm size */
1007 if (!seg_hdr->vmsize) {
1008 continue;
1009 }
1010
1011 /* Ignore LINKEDIT segments */
1012 if (streq_safe(seg_hdr->segname, SEG_LINKEDIT,
1013 const_strlen(SEG_LINKEDIT))) {
1014 continue;
1015 }
1016
1017 require_action(kxld_object_is_32_bit(object), finish, rval = KERN_FAILURE;
1018 kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogMalformedMachO
1019 "LC_SEGMENT in 64-bit kext."));
1020 require_action(!has_segment, finish, rval = KERN_FAILURE;
1021 kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogMalformedMachO
1022 "Multiple segments in an MH_OBJECT kext."));
1023
1024 nsects = seg_hdr->nsects;
1025 sect_offset = offset + sizeof(*seg_hdr);
1026 has_segment = TRUE;
1027 }
1028 break;
1029 #endif /* KXLD_USER_OR_ILP32 */
1030 #if KXLD_USER_OR_LP64
1031 case LC_SEGMENT_64:
1032 {
1033 struct segment_command_64 *seg_hdr =
1034 (struct segment_command_64 *) ((void *) cmd_hdr);
1035
1036 /* Ignore segments with no vm size */
1037 if (!seg_hdr->vmsize) {
1038 continue;
1039 }
1040
1041 /* Ignore LINKEDIT segments */
1042 if (streq_safe(seg_hdr->segname, SEG_LINKEDIT,
1043 const_strlen(SEG_LINKEDIT))) {
1044 continue;
1045 }
1046
1047 require_action(!kxld_object_is_32_bit(object), finish, rval = KERN_FAILURE;
1048 kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogMalformedMachO
1049 "LC_SEGMENT_64 in a 32-bit kext."));
1050 require_action(!has_segment, finish, rval = KERN_FAILURE;
1051 kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogMalformedMachO
1052 "Multiple segments in an MH_OBJECT kext."));
1053
1054 nsects = seg_hdr->nsects;
1055 sect_offset = offset + sizeof(*seg_hdr);
1056 has_segment = TRUE;
1057 }
1058 break;
1059 #endif /* KXLD_USER_OR_LP64 */
1060 case LC_SYMTAB:
1061 symtab_hdr = (struct symtab_command *) cmd_hdr;
1062
1063 KXLD_3264_FUNC(kxld_object_is_32_bit(object), rval,
1064 kxld_symtab_init_from_macho_32, kxld_symtab_init_from_macho_64,
1065 object->symtab, symtab_hdr, my_file,
1066 /* kernel_linkedit_seg */ NULL);
1067 require_noerr(rval, finish);
1068 break;
1069 case LC_UUID:
1070 uuid_hdr = (struct uuid_command *) cmd_hdr;
1071 kxld_uuid_init_from_macho(&object->uuid, uuid_hdr);
1072 break;
1073 case LC_UNIXTHREAD:
1074 case LC_MAIN:
1075 /* Don't need to do anything with UNIXTHREAD or MAIN */
1076 break;
1077 case LC_CODE_SIGNATURE:
1078 case LC_DYLD_INFO:
1079 case LC_DYLD_INFO_ONLY:
1080 case LC_FUNCTION_STARTS:
1081 case LC_DATA_IN_CODE:
1082 case LC_DYLIB_CODE_SIGN_DRS:
1083 /* Various metadata that might be stored in the linkedit segment */
1084 break;
1085 case LC_NOTE:
1086 /* bag-of-bits carried with the binary: ignore */
1087 break;
1088 case LC_BUILD_VERSION:
1089 /* should be able to ignore build version commands */
1090 kxld_log(kKxldLogLinking, kKxldLogWarn,
1091 "Ignoring LC_BUILD_VERSION (%u) in MH_OBJECT kext: (platform:%d)",
1092 cmd_hdr->cmd, ((struct build_version_command *)cmd_hdr)->platform);
1093 break;
1094 case LC_VERSION_MIN_MACOSX:
1095 case LC_VERSION_MIN_IPHONEOS:
1096 case LC_VERSION_MIN_TVOS:
1097 case LC_VERSION_MIN_WATCHOS:
1098 case LC_SOURCE_VERSION:
1099 /* Not supported for object files, fall through */
1100 default:
1101 rval = KERN_FAILURE;
1102 kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogMalformedMachO
1103 "Invalid load command type in MH_OBJECT kext: %u.", cmd_hdr->cmd);
1104 goto finish;
1105 }
1106 }
1107
1108 if (has_segment) {
1109 /* Get the number of sections from the segment and build the section index */
1110
1111 rval = kxld_array_init(&object->sects, sizeof(KXLDSect), nsects);
1112 require_noerr(rval, finish);
1113
1114 /* Loop over all of the sections to initialize the section index */
1115
1116 for (i = 0; i < nsects; ++i) {
1117 sect = kxld_array_get_item(&object->sects, i);
1118
1119 KXLD_3264_FUNC(kxld_object_is_32_bit(object), rval,
1120 kxld_sect_init_from_macho_32, kxld_sect_init_from_macho_64,
1121 sect, my_file, §_offset, i, &object->relocator);
1122 require_noerr(rval, finish);
1123 }
1124
1125 /* Create special sections */
1126
1127 #if KXLD_USER_OR_GOT
1128 rval = create_got(object);
1129 require_noerr(rval, finish);
1130 #endif /* KXLD_USER_OR_GOT */
1131
1132 #if KXLD_USER_OR_COMMON
1133 rval = resolve_common_symbols(object);
1134 require_noerr(rval, finish);
1135 #endif /* KXLD_USER_OR_COMMON */
1136
1137 /* Create the segments from the section index */
1138
1139 rval = kxld_seg_create_seg_from_sections(&object->segs, &object->sects);
1140 require_noerr(rval, finish);
1141
1142 rval = kxld_seg_finalize_object_segment(&object->segs,
1143 object->section_order, get_macho_header_size(object));
1144 require_noerr(rval, finish);
1145
1146 rval = kxld_seg_init_linkedit(&object->segs);
1147 require_noerr(rval, finish);
1148 }
1149
1150 rval = KERN_SUCCESS;
1151 finish:
1152 return rval;
1153 }
1154 #endif /* KXLD_USER_OR_OBJECT */
1155
1156 #if KXLD_USER_OR_ILP32
1157 /*******************************************************************************
1158 *******************************************************************************/
1159 static u_long
get_macho_cmd_data_32(u_char * file,u_long offset,u_int * filetype,u_int * ncmds)1160 get_macho_cmd_data_32(u_char *file, u_long offset, u_int *filetype, u_int *ncmds)
1161 {
1162 struct mach_header *mach_hdr = (struct mach_header *) ((void *) (file + offset));
1163
1164 if (filetype) {
1165 *filetype = mach_hdr->filetype;
1166 }
1167 if (ncmds) {
1168 *ncmds = mach_hdr->ncmds;
1169 }
1170
1171 return sizeof(*mach_hdr);
1172 }
1173
1174 #endif /* KXLD_USER_OR_ILP32 */
1175
1176 #if KXLD_USER_OR_LP64
1177 /*******************************************************************************
1178 *******************************************************************************/
1179 static u_long
get_macho_cmd_data_64(u_char * file,u_long offset,u_int * filetype,u_int * ncmds)1180 get_macho_cmd_data_64(u_char *file, u_long offset, u_int *filetype, u_int *ncmds)
1181 {
1182 struct mach_header_64 *mach_hdr = (struct mach_header_64 *) ((void *) (file + offset));
1183
1184 if (filetype) {
1185 *filetype = mach_hdr->filetype;
1186 }
1187 if (ncmds) {
1188 *ncmds = mach_hdr->ncmds;
1189 }
1190
1191 return sizeof(*mach_hdr);
1192 }
1193 #endif /* KXLD_USER_OR_LP64 */
1194
1195 /*******************************************************************************
1196 *******************************************************************************/
1197 static u_long
get_macho_header_size(const KXLDObject * object)1198 get_macho_header_size(const KXLDObject *object)
1199 {
1200 KXLDSeg *seg = NULL;
1201 u_long header_size = 0;
1202 u_int i = 0;
1203 boolean_t object_is_32_bit = kxld_object_is_32_bit(object);
1204
1205 check(object);
1206
1207 /* Mach, segment, symtab, and UUID headers */
1208
1209 header_size += object_is_32_bit ? sizeof(struct mach_header) : sizeof(struct mach_header_64);
1210
1211 for (i = 0; i < object->segs.nitems; ++i) {
1212 seg = kxld_array_get_item(&object->segs, i);
1213 header_size += kxld_seg_get_macho_header_size(seg, object_is_32_bit);
1214 }
1215
1216 header_size += kxld_symtab_get_macho_header_size();
1217
1218 #if KXLD_PIC_KEXTS
1219 if (target_supports_slideable_kexts(object)) {
1220 header_size += kxld_reloc_get_macho_header_size();
1221 }
1222 #endif /* KXLD_PIC_KEXTS */
1223
1224 if (object->uuid.has_uuid) {
1225 header_size += kxld_uuid_get_macho_header_size();
1226 }
1227
1228 if (object->versionmin.has_versionmin) {
1229 header_size += kxld_versionmin_get_macho_header_size(&object->versionmin);
1230 }
1231
1232 if (object->srcversion.has_srcversion) {
1233 header_size += kxld_srcversion_get_macho_header_size();
1234 }
1235
1236 if (isSplitKext && object->splitinfolc.has_splitinfolc) {
1237 header_size += kxld_splitinfolc_get_macho_header_size();
1238 }
1239
1240 return header_size;
1241 }
1242
1243 /*******************************************************************************
1244 *******************************************************************************/
1245 static u_long
get_macho_data_size(const KXLDObject * object)1246 get_macho_data_size(const KXLDObject *object)
1247 {
1248 KXLDSeg *seg = NULL;
1249 u_long data_size = 0;
1250 u_int i = 0;
1251
1252 check(object);
1253
1254 /* total all segment vmsize values */
1255 for (i = 0; i < object->segs.nitems; ++i) {
1256 seg = kxld_array_get_item(&object->segs, i);
1257 data_size += (u_long) kxld_seg_get_vmsize(seg);
1258 }
1259
1260 #if KXLD_PIC_KEXTS
1261 {
1262 /* ensure that when we eventually emit the final linked object,
1263 * appending the __DYSYMTAB data after the __LINKEDIT data will
1264 * not overflow the space allocated for the __LINKEDIT segment
1265 */
1266
1267 u_long seg_vmsize = 0;
1268 u_long symtab_size = 0;
1269 u_long reloc_size = 0;
1270
1271 /* get current __LINKEDIT sizes */
1272 seg = kxld_object_get_seg_by_name(object, SEG_LINKEDIT);
1273
1274 seg_vmsize = (u_long) kxld_seg_get_vmsize(seg);
1275
1276 /* get size of symbol table data that will eventually be dumped
1277 * into the __LINKEDIT segment
1278 */
1279 symtab_size = kxld_symtab_get_macho_data_size(object->symtab, kxld_object_is_32_bit(object));
1280
1281 if (target_supports_slideable_kexts(object)) {
1282 /* get size of __DYSYMTAB relocation entries */
1283 reloc_size = kxld_reloc_get_macho_data_size(&object->locrelocs, &object->extrelocs);
1284 }
1285
1286 /* combine, and ensure they'll both fit within the page(s)
1287 * allocated for the __LINKEDIT segment. If they'd overflow,
1288 * increase the vmsize appropriately so no overflow will occur
1289 */
1290 if ((symtab_size + reloc_size) > seg_vmsize) {
1291 u_long overflow = (symtab_size + reloc_size) - seg_vmsize;
1292 data_size += kxld_round_page_cross_safe(overflow);
1293 }
1294 }
1295 #endif // KXLD_PIC_KEXTS
1296
1297 return data_size;
1298 }
1299
1300 /*******************************************************************************
1301 *******************************************************************************/
1302 boolean_t
kxld_object_target_needs_swap(const KXLDObject * object __unused)1303 kxld_object_target_needs_swap(const KXLDObject *object __unused)
1304 {
1305 #if KERNEL
1306 return FALSE;
1307 #else
1308 return object->target_order != object->host_order;
1309 #endif /* KERNEL */
1310 }
1311
1312 /*******************************************************************************
1313 *******************************************************************************/
1314 KXLDSeg *
kxld_object_get_seg_by_name(const KXLDObject * object,const char * segname)1315 kxld_object_get_seg_by_name(const KXLDObject *object, const char *segname)
1316 {
1317 KXLDSeg *seg = NULL;
1318 u_int i = 0;
1319
1320 for (i = 0; i < object->segs.nitems; ++i) {
1321 seg = kxld_array_get_item(&object->segs, i);
1322
1323 if (streq_safe(segname, seg->segname, sizeof(seg->segname))) {
1324 break;
1325 }
1326
1327 seg = NULL;
1328 }
1329
1330 return seg;
1331 }
1332
1333 /*******************************************************************************
1334 *******************************************************************************/
1335 const KXLDRelocator *
kxld_object_get_relocator(const KXLDObject * object)1336 kxld_object_get_relocator(const KXLDObject * object)
1337 {
1338 check(object);
1339
1340 return &object->relocator;
1341 }
1342
1343 /*******************************************************************************
1344 *******************************************************************************/
1345 KXLDSect *
kxld_object_get_sect_by_name(const KXLDObject * object,const char * segname,const char * sectname)1346 kxld_object_get_sect_by_name(const KXLDObject *object, const char *segname,
1347 const char *sectname)
1348 {
1349 KXLDSect *sect = NULL;
1350 u_int i = 0;
1351
1352 for (i = 0; i < object->sects.nitems; ++i) {
1353 sect = kxld_array_get_item(&object->sects, i);
1354
1355 if (streq_safe(segname, sect->segname, sizeof(sect->segname)) &&
1356 streq_safe(sectname, sect->sectname, sizeof(sect->sectname))) {
1357 break;
1358 }
1359
1360 sect = NULL;
1361 }
1362
1363 return sect;
1364 }
1365
1366 /*******************************************************************************
1367 *******************************************************************************/
1368 const KXLDReloc *
kxld_object_get_reloc_at_symbol(const KXLDObject * object,const KXLDSym * sym)1369 kxld_object_get_reloc_at_symbol(const KXLDObject *object, const KXLDSym *sym)
1370 {
1371 const KXLDReloc *reloc = NULL;
1372 const KXLDSect *sect = NULL;
1373 uint32_t offset = 0;
1374
1375 check(object);
1376 check(sym);
1377
1378 sect = kxld_object_get_section_by_index(object, sym->sectnum);
1379 require(sect, finish);
1380
1381 if (kxld_object_is_final_image(object)) {
1382 reloc = kxld_reloc_get_reloc_by_offset(&object->extrelocs,
1383 sym->base_addr);
1384 if (!reloc) {
1385 reloc = kxld_reloc_get_reloc_by_offset(&object->locrelocs,
1386 sym->base_addr);
1387 }
1388 } else {
1389 offset = kxld_sym_get_section_offset(sym, sect);
1390 reloc = kxld_reloc_get_reloc_by_offset(§->relocs, offset);
1391 }
1392
1393 finish:
1394 return reloc;
1395 }
1396
1397 /*******************************************************************************
1398 *******************************************************************************/
1399 const KXLDSym *
kxld_object_get_symbol_of_reloc(const KXLDObject * object,const KXLDReloc * reloc,const KXLDSect * sect)1400 kxld_object_get_symbol_of_reloc(const KXLDObject *object,
1401 const KXLDReloc *reloc, const KXLDSect *sect)
1402 {
1403 const KXLDSym *sym = NULL;
1404 u_char *my_file;
1405
1406 if (isOldInterface) {
1407 my_file = object->file;
1408 } else {
1409 my_file = object->split_info.kextExecutable;
1410 }
1411
1412 if (kxld_object_is_final_image(object)) {
1413 sym = kxld_reloc_get_symbol(&object->relocator, reloc, my_file);
1414 } else {
1415 sym = kxld_reloc_get_symbol(&object->relocator, reloc, sect->data);
1416 }
1417 return sym;
1418 }
1419
1420 /*******************************************************************************
1421 *******************************************************************************/
1422 const KXLDSect *
kxld_object_get_section_by_index(const KXLDObject * object,u_int sectnum)1423 kxld_object_get_section_by_index(const KXLDObject *object, u_int sectnum)
1424 {
1425 KXLDSect *sect = NULL;
1426
1427 check(object);
1428
1429 if (sectnum < object->sects.nitems) {
1430 sect = kxld_array_get_item(&object->sects, sectnum);
1431 }
1432
1433 return sect;
1434 }
1435
1436 /*******************************************************************************
1437 *******************************************************************************/
1438 const KXLDArray *
kxld_object_get_extrelocs(const KXLDObject * object)1439 kxld_object_get_extrelocs(const KXLDObject *object)
1440 {
1441 const KXLDArray *rval = NULL;
1442
1443 check(object);
1444
1445 if (kxld_object_is_final_image(object)) {
1446 rval = &object->extrelocs;
1447 }
1448
1449 return rval;
1450 }
1451
1452 /*******************************************************************************
1453 *******************************************************************************/
1454 const KXLDSymtab *
kxld_object_get_symtab(const KXLDObject * object)1455 kxld_object_get_symtab(const KXLDObject *object)
1456 {
1457 check(object);
1458
1459 return object->symtab;
1460 }
1461
1462 #if KXLD_USER_OR_GOT || KXLD_USER_OR_COMMON
1463 /*******************************************************************************
1464 *******************************************************************************/
1465 static kern_return_t
add_section(KXLDObject * object,KXLDSect ** sect)1466 add_section(KXLDObject *object, KXLDSect **sect)
1467 {
1468 kern_return_t rval = KERN_FAILURE;
1469 u_int nsects = object->sects.nitems;
1470
1471 rval = kxld_array_resize(&object->sects, nsects + 1);
1472 require_noerr(rval, finish);
1473
1474 *sect = kxld_array_get_item(&object->sects, nsects);
1475
1476 rval = KERN_SUCCESS;
1477
1478 finish:
1479 return rval;
1480 }
1481 #endif /* KXLD_USER_OR_GOT || KXLD_USER_OR_COMMON */
1482
1483 #if KXLD_USER_OR_COMMON
1484 /*******************************************************************************
1485 * If there are common symbols, calculate how much space they'll need
1486 * and create/grow the __DATA __common section to accommodate them.
1487 * Then, resolve them against that section.
1488 *******************************************************************************/
1489 static kern_return_t
resolve_common_symbols(KXLDObject * object)1490 resolve_common_symbols(KXLDObject *object)
1491 {
1492 kern_return_t rval = KERN_FAILURE;
1493 KXLDSymtabIterator iter;
1494 KXLDSym *sym = NULL;
1495 KXLDSect *sect = NULL;
1496 kxld_addr_t base_addr = 0;
1497 kxld_size_t size = 0;
1498 kxld_size_t total_size = 0;
1499 u_int align = 0;
1500 u_int max_align = 0;
1501 u_int sectnum = 0;
1502
1503 if (!kxld_object_target_supports_common_symbols(object)) {
1504 rval = KERN_SUCCESS;
1505 goto finish;
1506 }
1507
1508 /* Iterate over the common symbols to calculate their total aligned size */
1509 kxld_symtab_iterator_init(&iter, object->symtab, kxld_sym_is_common, FALSE);
1510 while ((sym = kxld_symtab_iterator_get_next(&iter))) {
1511 align = kxld_sym_get_common_align(sym);
1512 size = kxld_sym_get_common_size(sym);
1513
1514 if (align > max_align) {
1515 max_align = align;
1516 }
1517
1518 total_size = kxld_align_address(total_size, align) + size;
1519 }
1520
1521 /* If there are common symbols, grow or create the __DATA __common section
1522 * to hold them.
1523 */
1524 if (total_size) {
1525 sect = kxld_object_get_sect_by_name(object, SEG_DATA, SECT_COMMON);
1526 if (sect) {
1527 base_addr = sect->base_addr + sect->size;
1528
1529 kxld_sect_grow(sect, total_size, max_align);
1530 } else {
1531 base_addr = 0;
1532
1533 rval = add_section(object, §);
1534 require_noerr(rval, finish);
1535
1536 kxld_sect_init_zerofill(sect, SEG_DATA, SECT_COMMON,
1537 total_size, max_align);
1538 }
1539
1540 /* Resolve the common symbols against the new section */
1541 rval = kxld_array_get_index(&object->sects, sect, §num);
1542 require_noerr(rval, finish);
1543
1544 kxld_symtab_iterator_reset(&iter);
1545 while ((sym = kxld_symtab_iterator_get_next(&iter))) {
1546 align = kxld_sym_get_common_align(sym);
1547 size = kxld_sym_get_common_size(sym);
1548
1549 base_addr = kxld_align_address(base_addr, align);
1550 kxld_sym_resolve_common(sym, sectnum, base_addr);
1551
1552 base_addr += size;
1553 }
1554 }
1555
1556 rval = KERN_SUCCESS;
1557
1558 finish:
1559 return rval;
1560 }
1561 #endif /* KXLD_USER_OR_COMMON */
1562
1563 #if KXLD_USER_OR_GOT
1564 /*******************************************************************************
1565 *******************************************************************************/
1566 static boolean_t
target_has_got(const KXLDObject * object)1567 target_has_got(const KXLDObject *object)
1568 {
1569 return FALSE:
1570 }
1571
1572 /*******************************************************************************
1573 * Create and initialize the Global Offset Table
1574 *******************************************************************************/
1575 static kern_return_t
1576 create_got(KXLDObject *object)
1577 {
1578 kern_return_t rval = KERN_FAILURE;
1579 KXLDSect *sect = NULL;
1580 u_int ngots = 0;
1581 u_int i = 0;
1582
1583 if (!target_has_got(object)) {
1584 rval = KERN_SUCCESS;
1585 goto finish;
1586 }
1587
1588 for (i = 0; i < object->sects.nitems; ++i) {
1589 sect = kxld_array_get_item(&object->sects, i);
1590 ngots += kxld_sect_get_ngots(sect, &object->relocator,
1591 object->symtab);
1592 }
1593
1594 rval = add_section(object, §);
1595 require_noerr(rval, finish);
1596
1597 rval = kxld_sect_init_got(sect, ngots);
1598 require_noerr(rval, finish);
1599
1600 object->got_is_created = TRUE;
1601 rval = KERN_SUCCESS;
1602
1603 finish:
1604 return rval;
1605 }
1606
1607 /*******************************************************************************
1608 *******************************************************************************/
1609 static kern_return_t
1610 populate_got(KXLDObject *object)
1611 {
1612 kern_return_t rval = KERN_FAILURE;
1613 KXLDSect *sect = NULL;
1614 u_int i = 0;
1615
1616 if (!target_has_got(object) || !object->got_is_created) {
1617 rval = KERN_SUCCESS;
1618 goto finish;
1619 }
1620
1621 for (i = 0; i < object->sects.nitems; ++i) {
1622 sect = kxld_array_get_item(&object->sects, i);
1623 if (streq_safe(sect->segname, KXLD_SEG_GOT, sizeof(KXLD_SEG_GOT)) &&
1624 streq_safe(sect->sectname, KXLD_SECT_GOT, sizeof(KXLD_SECT_GOT))) {
1625 kxld_sect_populate_got(sect, object->symtab,
1626 kxld_object_target_needs_swap(object));
1627 break;
1628 }
1629 }
1630
1631 require_action(i < object->sects.nitems, finish, rval = KXLD_MISSING_GOT);
1632
1633 rval = KERN_SUCCESS;
1634
1635 finish:
1636 return rval;
1637 }
1638 #endif /* KXLD_USER_OR_GOT */
1639
1640 /*******************************************************************************
1641 *******************************************************************************/
1642 static boolean_t
1643 target_supports_protected_segments(const KXLDObject *object)
1644 {
1645 return object->is_final_image &&
1646 (object->cputype == CPU_TYPE_X86_64 ||
1647 object->cputype == CPU_TYPE_ARM ||
1648 object->cputype == CPU_TYPE_ARM64);
1649 }
1650
1651 /*******************************************************************************
1652 *******************************************************************************/
1653 static void
1654 set_is_object_linked(KXLDObject *object)
1655 {
1656 u_int i = 0;
1657
1658 if (kxld_object_is_kernel(object)) {
1659 object->is_linked = TRUE;
1660 return;
1661 }
1662
1663 if (object->is_final_image) {
1664 object->is_linked = !object->extrelocs.nitems;
1665 return;
1666 }
1667
1668 object->is_linked = TRUE;
1669 for (i = 0; i < object->sects.nitems; ++i) {
1670 KXLDSect *sect = kxld_array_get_item(&object->sects, i);
1671 if (sect->relocs.nitems) {
1672 object->is_linked = FALSE;
1673 break;
1674 }
1675 }
1676 }
1677
1678
1679 /*******************************************************************************
1680 *******************************************************************************/
1681 void
1682 kxld_object_clear(KXLDObject *object)
1683 {
1684 KXLDSeg *seg = NULL;
1685 KXLDSect *sect = NULL;
1686 u_int i;
1687 u_char *my_file;
1688
1689 check(object);
1690
1691 if (isOldInterface) {
1692 my_file = object->file;
1693 } else {
1694 my_file = object->split_info.kextExecutable;
1695 }
1696
1697 #if !KERNEL
1698 if (kxld_object_is_kernel(object)) {
1699 unswap_macho(my_file, object->host_order, object->target_order);
1700 }
1701 #endif /* !KERNEL */
1702
1703 for (i = 0; i < object->segs.nitems; ++i) {
1704 seg = kxld_array_get_item(&object->segs, i);
1705 kxld_seg_clear(seg);
1706 }
1707 kxld_array_reset(&object->segs);
1708
1709 for (i = 0; i < object->sects.nitems; ++i) {
1710 sect = kxld_array_get_item(&object->sects, i);
1711 kxld_sect_clear(sect);
1712 }
1713 kxld_array_reset(&object->sects);
1714
1715 kxld_array_reset(&object->extrelocs);
1716 kxld_array_reset(&object->locrelocs);
1717 kxld_relocator_clear(&object->relocator);
1718 kxld_uuid_clear(&object->uuid);
1719 kxld_versionmin_clear(&object->versionmin);
1720 kxld_srcversion_clear(&object->srcversion);
1721
1722 if (object->symtab) {
1723 kxld_symtab_clear(object->symtab);
1724 }
1725
1726 if (isOldInterface) {
1727 object->file = NULL;
1728 object->size = 0;
1729 } else {
1730 kxld_splitinfolc_clear(&object->splitinfolc);
1731 object->split_info.kextExecutable = NULL;
1732 object->split_info.kextSize = 0;
1733 }
1734 object->filetype = 0;
1735 object->cputype = 0;
1736 object->cpusubtype = 0;
1737 object->is_kernel = FALSE;
1738 object->is_final_image = FALSE;
1739 object->is_linked = FALSE;
1740 object->got_is_created = FALSE;
1741
1742 #if KXLD_USER_OR_OBJECT
1743 object->section_order = NULL;
1744 #endif
1745 #if !KERNEL
1746 object->host_order = 0;
1747 object->target_order = 0;
1748 #endif
1749 }
1750
1751 /*******************************************************************************
1752 *******************************************************************************/
1753 void
1754 kxld_object_deinit(KXLDObject *object __unused)
1755 {
1756 KXLDSeg *seg = NULL;
1757 KXLDSect *sect = NULL;
1758 u_int i;
1759 u_char *my_file;
1760
1761 check(object);
1762
1763 if (isOldInterface) {
1764 my_file = object->file;
1765 } else {
1766 my_file = object->split_info.kextExecutable;
1767 }
1768
1769 #if !KERNEL
1770 if (my_file && kxld_object_is_kernel(object)) {
1771 unswap_macho(my_file, object->host_order, object->target_order);
1772 }
1773 #endif /* !KERNEL */
1774
1775 for (i = 0; i < object->segs.maxitems; ++i) {
1776 seg = kxld_array_get_slot(&object->segs, i);
1777 kxld_seg_deinit(seg);
1778 }
1779 kxld_array_deinit(&object->segs);
1780
1781 for (i = 0; i < object->sects.maxitems; ++i) {
1782 sect = kxld_array_get_slot(&object->sects, i);
1783 kxld_sect_deinit(sect);
1784 }
1785 kxld_array_deinit(&object->sects);
1786
1787 kxld_array_deinit(&object->extrelocs);
1788 kxld_array_deinit(&object->locrelocs);
1789
1790 if (object->symtab) {
1791 kxld_symtab_deinit(object->symtab);
1792 kxld_free(object->symtab, kxld_symtab_sizeof());
1793 }
1794
1795 bzero(object, sizeof(*object));
1796 }
1797
1798 /*******************************************************************************
1799 *******************************************************************************/
1800 const u_char *
1801 kxld_object_get_file(const KXLDObject *object)
1802 {
1803 const u_char *my_file;
1804
1805 check(object);
1806
1807 if (isOldInterface) {
1808 my_file = object->file;
1809 } else {
1810 my_file = object->split_info.kextExecutable;
1811 }
1812
1813 return my_file;
1814 }
1815
1816 /*******************************************************************************
1817 *******************************************************************************/
1818 const char *
1819 kxld_object_get_name(const KXLDObject *object)
1820 {
1821 check(object);
1822
1823 return object->name;
1824 }
1825
1826 /*******************************************************************************
1827 *******************************************************************************/
1828 boolean_t
1829 kxld_object_is_32_bit(const KXLDObject *object)
1830 {
1831 check(object);
1832
1833 return kxld_is_32_bit(object->cputype);
1834 }
1835
1836 /*******************************************************************************
1837 *******************************************************************************/
1838 boolean_t
1839 kxld_object_is_final_image(const KXLDObject *object)
1840 {
1841 check(object);
1842
1843 return object->is_final_image;
1844 }
1845
1846 /*******************************************************************************
1847 *******************************************************************************/
1848 boolean_t
1849 kxld_object_is_kernel(const KXLDObject *object)
1850 {
1851 check(object);
1852
1853 return object->is_kernel;
1854 }
1855
1856 /*******************************************************************************
1857 *******************************************************************************/
1858 boolean_t
1859 kxld_object_is_linked(const KXLDObject *object)
1860 {
1861 check(object);
1862
1863 return object->is_linked;
1864 }
1865
1866 /*******************************************************************************
1867 *******************************************************************************/
1868 boolean_t
1869 kxld_object_target_supports_strict_patching(const KXLDObject *object)
1870 {
1871 check(object);
1872
1873 return object->cputype != CPU_TYPE_I386;
1874 }
1875
1876 /*******************************************************************************
1877 *******************************************************************************/
1878 boolean_t
1879 kxld_object_target_supports_common_symbols(const KXLDObject *object)
1880 {
1881 check(object);
1882
1883 return object->cputype == CPU_TYPE_I386;
1884 }
1885
1886
1887 /*******************************************************************************
1888 *******************************************************************************/
1889 void
1890 kxld_object_get_vmsize_for_seg_by_name(const KXLDObject *object,
1891 const char *segname,
1892 u_long *vmsize)
1893 {
1894 check(object);
1895 check(segname);
1896 check(vmsize);
1897
1898 KXLDSeg *seg = NULL;
1899 u_long my_size = 0;
1900
1901 /* segment vmsize */
1902 seg = kxld_object_get_seg_by_name(object, segname);
1903
1904 my_size = (u_long) kxld_seg_get_vmsize(seg);
1905
1906 #if KXLD_PIC_KEXTS
1907 if (kxld_seg_is_linkedit_seg(seg)) {
1908 u_long reloc_size = 0;
1909
1910 if (target_supports_slideable_kexts(object)) {
1911 /* get size of __DYSYMTAB relocation entries */
1912 reloc_size = kxld_reloc_get_macho_data_size(&object->locrelocs, &object->extrelocs);
1913 my_size += reloc_size;
1914 }
1915 }
1916 #endif
1917
1918 *vmsize = my_size;
1919 }
1920
1921 /*******************************************************************************
1922 *******************************************************************************/
1923 void
1924 kxld_object_get_vmsize(const KXLDObject *object, u_long *header_size,
1925 u_long *vmsize)
1926 {
1927 check(object);
1928 check(header_size);
1929 check(vmsize);
1930 *header_size = 0;
1931 *vmsize = 0;
1932
1933 /* vmsize is the padded header page(s) + segment vmsizes */
1934
1935 *header_size = (object->is_final_image) ?
1936 0 : (u_long)kxld_round_page_cross_safe(get_macho_header_size(object));
1937
1938 *vmsize = *header_size + get_macho_data_size(object);
1939 }
1940
1941 /*******************************************************************************
1942 *******************************************************************************/
1943 void
1944 kxld_object_set_linked_object_size(KXLDObject *object, u_long vmsize)
1945 {
1946 check(object);
1947
1948 if (isOldInterface) {
1949 object->output_buffer_size = vmsize; /* cache this for use later */
1950 } else {
1951 object->split_info.linkedKextSize = vmsize;
1952 }
1953 return;
1954 }
1955
1956 /*******************************************************************************
1957 *******************************************************************************/
1958 kern_return_t
1959 kxld_object_export_linked_object(const KXLDObject *object,
1960 void *linked_object
1961 )
1962 {
1963 kern_return_t rval = KERN_FAILURE;
1964 KXLDSeg *seg = NULL;
1965 u_long size = 0;
1966 u_long header_size = 0;
1967 u_long header_offset = 0;
1968 u_long data_offset = 0;
1969 u_int ncmds = 0;
1970 u_int i = 0;
1971 boolean_t is_32bit_object = kxld_object_is_32_bit(object);
1972 kxld_addr_t link_addr;
1973 u_char *my_linked_object;
1974
1975 check(object);
1976 check(linked_object);
1977
1978 if (isOldInterface) {
1979 size = object->output_buffer_size;
1980 link_addr = object->link_addr;
1981 my_linked_object = (u_char *) linked_object;
1982 } else {
1983 size = ((splitKextLinkInfo *)linked_object)->linkedKextSize;
1984 link_addr = ((splitKextLinkInfo *)linked_object)->vmaddr_TEXT;
1985 my_linked_object = ((splitKextLinkInfo *)linked_object)->linkedKext;
1986 }
1987
1988 /* Calculate the size of the headers and data */
1989
1990 header_size = get_macho_header_size(object);
1991
1992 /* Copy data to the file */
1993
1994 ncmds = object->segs.nitems + 1 /* LC_SYMTAB */;
1995
1996 #if KXLD_PIC_KEXTS
1997 /* don't write out a DYSYMTAB segment for targets that can't digest it
1998 */
1999 if (target_supports_slideable_kexts(object)) {
2000 ncmds++; /* dysymtab */
2001 }
2002 #endif /* KXLD_PIC_KEXTS */
2003
2004 if (object->uuid.has_uuid == TRUE) {
2005 ncmds++;
2006 }
2007
2008 if (object->versionmin.has_versionmin == TRUE) {
2009 ncmds++;
2010 }
2011
2012 if (object->srcversion.has_srcversion == TRUE) {
2013 ncmds++;
2014 }
2015
2016 if (isSplitKext && object->splitinfolc.has_splitinfolc) {
2017 ncmds++;
2018 }
2019
2020 rval = export_macho_header(object, my_linked_object, ncmds, &header_offset, header_size);
2021 require_noerr(rval, finish);
2022
2023 for (i = 0; i < object->segs.nitems; ++i) {
2024 seg = kxld_array_get_item(&object->segs, i);
2025
2026 rval = kxld_seg_export_macho_to_vm(seg, my_linked_object, &header_offset,
2027 header_size, size, link_addr, is_32bit_object);
2028 require_noerr(rval, finish);
2029 }
2030
2031 seg = kxld_object_get_seg_by_name(object, SEG_LINKEDIT);
2032 data_offset = (u_long) (seg->link_addr - link_addr);
2033
2034 // data_offset is used to set the fileoff in the macho header load commands
2035 rval = kxld_symtab_export_macho(object->symtab,
2036 my_linked_object,
2037 &header_offset,
2038 header_size,
2039 &data_offset, size, is_32bit_object);
2040 require_noerr(rval, finish);
2041
2042 // data_offset now points past the symbol tab and strings data in the linkedit
2043 // segment - (it was used to set new values for symoff and stroff)
2044
2045 #if KXLD_PIC_KEXTS
2046 if (target_supports_slideable_kexts(object)) {
2047 rval = kxld_reloc_export_macho(&object->relocator,
2048 &object->locrelocs,
2049 &object->extrelocs,
2050 my_linked_object,
2051 &header_offset,
2052 header_size,
2053 &data_offset, size);
2054 require_noerr(rval, finish);
2055 }
2056 #endif /* KXLD_PIC_KEXTS */
2057
2058 if (object->uuid.has_uuid) {
2059 rval = kxld_uuid_export_macho(&object->uuid, my_linked_object, &header_offset, header_size);
2060 require_noerr(rval, finish);
2061 }
2062
2063 if (object->versionmin.has_versionmin) {
2064 rval = kxld_versionmin_export_macho(&object->versionmin, my_linked_object, &header_offset, header_size);
2065 require_noerr(rval, finish);
2066 }
2067
2068 if (object->srcversion.has_srcversion) {
2069 rval = kxld_srcversion_export_macho(&object->srcversion, my_linked_object, &header_offset, header_size);
2070 require_noerr(rval, finish);
2071 }
2072
2073 if (isSplitKext && object->splitinfolc.has_splitinfolc) {
2074 rval = kxld_splitinfolc_export_macho(&object->splitinfolc,
2075 linked_object,
2076 &header_offset,
2077 header_size,
2078 &data_offset,
2079 size);
2080 require_noerr(rval, finish);
2081 }
2082
2083 #if !KERNEL
2084 unswap_macho(my_linked_object, object->host_order, object->target_order);
2085 #endif /* KERNEL */
2086
2087 rval = KERN_SUCCESS;
2088
2089 finish:
2090 return rval;
2091 }
2092
2093 /*******************************************************************************
2094 *******************************************************************************/
2095 static kern_return_t
2096 export_macho_header(const KXLDObject *object, u_char *buf, u_int ncmds,
2097 u_long *header_offset, u_long header_size)
2098 {
2099 kern_return_t rval = KERN_FAILURE;
2100
2101 check(object);
2102 check(buf);
2103 check(header_offset);
2104
2105 KXLD_3264_FUNC(kxld_object_is_32_bit(object), rval,
2106 export_macho_header_32, export_macho_header_64,
2107 object, buf, ncmds, header_offset, header_size);
2108 require_noerr(rval, finish);
2109
2110 rval = KERN_SUCCESS;
2111
2112 finish:
2113 return rval;
2114 }
2115
2116 #if KXLD_USER_OR_ILP32
2117 /*******************************************************************************
2118 *******************************************************************************/
2119 static kern_return_t
2120 export_macho_header_32(const KXLDObject *object, u_char *buf, u_int ncmds,
2121 u_long *header_offset, u_long header_size)
2122 {
2123 kern_return_t rval = KERN_FAILURE;
2124 struct mach_header *mach = NULL;
2125
2126 check(object);
2127 check(buf);
2128 check(header_offset);
2129
2130 require_action(sizeof(*mach) <= header_size - *header_offset, finish,
2131 rval = KERN_FAILURE);
2132 mach = (struct mach_header *) ((void *) (buf + *header_offset));
2133
2134 mach->magic = MH_MAGIC;
2135 mach->cputype = object->cputype;
2136 mach->cpusubtype = object->cpusubtype;
2137 mach->filetype = object->filetype;
2138 mach->ncmds = ncmds;
2139 mach->sizeofcmds = (uint32_t) (header_size - sizeof(*mach));
2140 mach->flags = MH_NOUNDEFS;
2141
2142 *header_offset += sizeof(*mach);
2143
2144 rval = KERN_SUCCESS;
2145
2146 finish:
2147 return rval;
2148 }
2149 #endif /* KXLD_USER_OR_ILP32 */
2150
2151 #if KXLD_USER_OR_LP64
2152 /*******************************************************************************
2153 *******************************************************************************/
2154 static kern_return_t
2155 export_macho_header_64(const KXLDObject *object, u_char *buf, u_int ncmds,
2156 u_long *header_offset, u_long header_size)
2157 {
2158 kern_return_t rval = KERN_FAILURE;
2159 struct mach_header_64 *mach = NULL;
2160
2161 check(object);
2162 check(buf);
2163 check(header_offset);
2164
2165 require_action(sizeof(*mach) <= header_size - *header_offset, finish,
2166 rval = KERN_FAILURE);
2167 mach = (struct mach_header_64 *) ((void *) (buf + *header_offset));
2168
2169 mach->magic = MH_MAGIC_64;
2170 mach->cputype = object->cputype;
2171 mach->cpusubtype = object->cpusubtype;
2172 mach->filetype = object->filetype;
2173 mach->ncmds = ncmds;
2174 mach->sizeofcmds = (uint32_t) (header_size - sizeof(*mach));
2175 mach->flags = MH_NOUNDEFS;
2176
2177 *header_offset += sizeof(*mach);
2178
2179 #if SPLIT_KEXTS_DEBUG
2180 {
2181 kxld_log(kKxldLogLinking, kKxldLogErr,
2182 " %p >>> Start of macho header (size %lu) <%s>",
2183 (void *) mach,
2184 sizeof(*mach),
2185 __func__);
2186 kxld_log(kKxldLogLinking, kKxldLogErr,
2187 " %p <<< End of macho header <%s>",
2188 (void *) ((u_char *)mach + sizeof(*mach)),
2189 __func__);
2190 }
2191 #endif
2192
2193 rval = KERN_SUCCESS;
2194
2195 finish:
2196 return rval;
2197 }
2198 #endif /* KXLD_USER_OR_LP64 */
2199
2200 /*******************************************************************************
2201 *******************************************************************************/
2202 kern_return_t
2203 kxld_object_index_symbols_by_name(KXLDObject *object)
2204 {
2205 return kxld_symtab_index_symbols_by_name(object->symtab);
2206 }
2207
2208 /*******************************************************************************
2209 *******************************************************************************/
2210 kern_return_t
2211 kxld_object_index_cxx_symbols_by_value(KXLDObject *object)
2212 {
2213 return kxld_symtab_index_cxx_symbols_by_value(object->symtab);
2214 }
2215
2216 /*******************************************************************************
2217 *******************************************************************************/
2218 kern_return_t
2219 kxld_object_relocate(KXLDObject *object, kxld_addr_t link_address)
2220 {
2221 kern_return_t rval = KERN_FAILURE;
2222 KXLDSeg *seg = NULL;
2223 u_int i = 0;
2224
2225 check(object);
2226
2227 object->link_addr = link_address;
2228
2229 /* Relocate segments (which relocates the sections) */
2230 for (i = 0; i < object->segs.nitems; ++i) {
2231 seg = kxld_array_get_item(&object->segs, i);
2232 kxld_seg_relocate(seg, link_address);
2233 } // for...
2234
2235 /* Relocate symbols */
2236 rval = kxld_symtab_relocate(object->symtab, &object->sects);
2237 require_noerr(rval, finish);
2238
2239 rval = KERN_SUCCESS;
2240 finish:
2241 return rval;
2242 }
2243
2244 /*******************************************************************************
2245 *******************************************************************************/
2246 static KXLDSym *
2247 get_mutable_sym(const KXLDObject *object, const KXLDSym *sym)
2248 {
2249 KXLDSym *rval = NULL;
2250 kern_return_t result = KERN_FAILURE;
2251 u_int i = 0;
2252
2253 result = kxld_symtab_get_sym_index(object->symtab, sym, &i);
2254 require_noerr(result, finish);
2255
2256 rval = kxld_symtab_get_symbol_by_index(object->symtab, i);
2257 require_action(rval == sym, finish, rval = NULL);
2258
2259 finish:
2260 return rval;
2261 }
2262
2263 /*******************************************************************************
2264 *******************************************************************************/
2265 kern_return_t
2266 kxld_object_resolve_symbol(KXLDObject *object,
2267 const KXLDSym *sym, kxld_addr_t addr)
2268 {
2269 kern_return_t rval = KERN_FAILURE;
2270 KXLDSym *resolved_sym = NULL;
2271
2272 resolved_sym = get_mutable_sym(object, sym);
2273 require_action(resolved_sym, finish, rval = KERN_FAILURE);
2274
2275 rval = kxld_sym_resolve(resolved_sym, addr);
2276 require_noerr(rval, finish);
2277
2278 rval = KERN_SUCCESS;
2279 finish:
2280 return rval;
2281 }
2282
2283 /*******************************************************************************
2284 *******************************************************************************/
2285 kern_return_t
2286 kxld_object_patch_symbol(KXLDObject *object, const struct kxld_sym *sym)
2287 {
2288 kern_return_t rval = KERN_FAILURE;
2289 KXLDSym *patched_sym = NULL;
2290
2291 patched_sym = get_mutable_sym(object, sym);
2292 require_action(patched_sym, finish, rval = KERN_FAILURE);
2293
2294 (void) kxld_sym_patch(patched_sym);
2295 rval = KERN_SUCCESS;
2296 finish:
2297 return rval;
2298 }
2299
2300 /*******************************************************************************
2301 *******************************************************************************/
2302 kern_return_t
2303 kxld_object_add_symbol(KXLDObject *object, char *name, kxld_addr_t link_addr,
2304 const KXLDSym **sym_out)
2305 {
2306 kern_return_t rval = KERN_FAILURE;
2307 KXLDSym *sym = NULL;
2308
2309 rval = kxld_symtab_add_symbol(object->symtab, name, link_addr, &sym);
2310 require_noerr(rval, finish);
2311
2312 *sym_out = sym;
2313 rval = KERN_SUCCESS;
2314 finish:
2315 return rval;
2316 }
2317
2318 /*******************************************************************************
2319 *******************************************************************************/
2320 kern_return_t
2321 kxld_object_process_relocations(KXLDObject *object,
2322 const KXLDDict *patched_vtables)
2323 {
2324 kern_return_t rval = KERN_FAILURE;
2325
2326 (void) kxld_relocator_set_vtables(&object->relocator, patched_vtables);
2327
2328 /* Process relocation entries and populate the global offset table.
2329 *
2330 * For final linked images: the relocation entries are contained in a couple
2331 * of tables hanging off the end of the symbol table. The GOT has its own
2332 * section created by the linker; we simply need to fill it.
2333 *
2334 * For object files: the relocation entries are bound to each section.
2335 * The GOT, if it exists for the target architecture, is created by kxld,
2336 * and we must populate it according to our internal structures.
2337 */
2338 if (object->is_final_image) {
2339 #if KXLD_USER_OR_BUNDLE
2340 rval = process_symbol_pointers(object);
2341 require_noerr(rval, finish);
2342
2343 rval = process_relocs_from_tables(object);
2344 require_noerr(rval, finish);
2345 #else
2346 require_action(FALSE, finish, rval = KERN_FAILURE);
2347 #endif /* KXLD_USER_OR_BUNDLE */
2348 } else {
2349 #if KXLD_USER_OR_GOT
2350 /* Populate GOT */
2351 rval = populate_got(object);
2352 require_noerr(rval, finish);
2353 #endif /* KXLD_USER_OR_GOT */
2354 #if KXLD_USER_OR_OBJECT
2355 rval = process_relocs_from_sections(object);
2356 require_noerr(rval, finish);
2357 #else
2358 require_action(FALSE, finish, rval = KERN_FAILURE);
2359 #endif /* KXLD_USER_OR_OBJECT */
2360 }
2361
2362 /* Populate kmod info structure */
2363 rval = populate_kmod_info(object);
2364 require_noerr(rval, finish);
2365
2366 rval = KERN_SUCCESS;
2367 finish:
2368 return rval;
2369 }
2370
2371 #if KXLD_USER_OR_BUNDLE
2372
2373 #if SPLIT_KEXTS_DEBUG
2374 static boolean_t kxld_show_ptr_value;
2375 #endif
2376
2377 #define SECT_SYM_PTRS "__nl_symbol_ptr"
2378
2379 /*******************************************************************************
2380 * Final linked images create an __nl_symbol_ptr section for the global offset
2381 * table and for symbol pointer lookups in general. Rather than use relocation
2382 * entries, the linker creates an "indirect symbol table" which stores indexes
2383 * into the symbol table corresponding to the entries of this section. This
2384 * function populates the section with the relocated addresses of those symbols.
2385 *******************************************************************************/
2386 static kern_return_t
2387 process_symbol_pointers(KXLDObject *object)
2388 {
2389 kern_return_t rval = KERN_FAILURE;
2390 KXLDSect *sect = NULL;
2391 KXLDSym *sym = NULL;
2392 int32_t *symidx = NULL;
2393 u_char *symptr = NULL;
2394 u_long symptrsize = 0;
2395 u_int nsyms = 0;
2396 u_int firstsym = 0;
2397 u_int i = 0;
2398
2399 check(object);
2400
2401 require_action(object->is_final_image && object->dysymtab_hdr,
2402 finish, rval = KERN_FAILURE);
2403
2404 /* Get the __DATA,__nl_symbol_ptr section. If it doesn't exist, we have
2405 * nothing to do.
2406 */
2407
2408 sect = kxld_object_get_sect_by_name(object, SEG_DATA, SECT_SYM_PTRS);
2409 if (!sect || !(sect->flags & S_NON_LAZY_SYMBOL_POINTERS)) {
2410 rval = KERN_SUCCESS;
2411 goto finish;
2412 }
2413
2414 /* Calculate the table offset and number of entries in the section */
2415
2416 if (kxld_object_is_32_bit(object)) {
2417 symptrsize = sizeof(uint32_t);
2418 } else {
2419 symptrsize = sizeof(uint64_t);
2420 }
2421
2422 nsyms = (u_int) (sect->size / symptrsize);
2423 firstsym = sect->reserved1;
2424
2425 require_action(firstsym + nsyms <= object->dysymtab_hdr->nindirectsyms,
2426 finish, rval = KERN_FAILURE;
2427 kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogMalformedMachO
2428 "firstsym + nsyms > object->dysymtab_hdr->nindirectsyms"));
2429
2430 /* Iterate through the indirect symbol table and fill in the section of
2431 * symbol pointers. There are three cases:
2432 * 1) A normal symbol - put its value directly in the table
2433 * 2) An INDIRECT_SYMBOL_LOCAL - symbols that are local and already have
2434 * their offset from the start of the file in the section. Simply
2435 * add the file's link address to fill this entry.
2436 * 3) An INDIRECT_SYMBOL_ABS - prepopulated absolute symbols. No
2437 * action is required.
2438 */
2439
2440 if (isOldInterface) {
2441 symidx = (int32_t *) ((void *) (object->file + object->dysymtab_hdr->indirectsymoff));
2442 } else {
2443 symidx = (int32_t *) ((void *) (object->split_info.kextExecutable + object->dysymtab_hdr->indirectsymoff));
2444 }
2445
2446 symidx += firstsym;
2447 symptr = sect->data;
2448 for (i = 0; i < nsyms; ++i, ++symidx, symptr += symptrsize) {
2449 if (*symidx & INDIRECT_SYMBOL_LOCAL) {
2450 if (*symidx & INDIRECT_SYMBOL_ABS) {
2451 continue;
2452 }
2453
2454 if (isOldInterface) {
2455 add_to_ptr(symptr, object->link_addr, kxld_object_is_32_bit(object));
2456 } else {
2457 add_to_ptr(symptr, object->split_info.vmaddr_TEXT, kxld_object_is_32_bit(object));
2458 }
2459 } else {
2460 sym = kxld_symtab_get_symbol_by_index(object->symtab, *symidx);
2461 require_action(sym, finish, rval = KERN_FAILURE);
2462
2463 if (isOldInterface) {
2464 add_to_ptr(symptr, sym->link_addr, kxld_object_is_32_bit(object));
2465 } else {
2466 add_to_ptr(symptr, object->split_info.vmaddr_TEXT, kxld_object_is_32_bit(object));
2467 }
2468 }
2469 }
2470
2471 rval = KERN_SUCCESS;
2472 finish:
2473 return rval;
2474 }
2475
2476 /*******************************************************************************
2477 *******************************************************************************/
2478 static KXLDSeg *
2479 get_seg_by_base_addr(KXLDObject *object, kxld_addr_t base_addr)
2480 {
2481 KXLDSeg *seg = NULL;
2482 kxld_addr_t start = 0;
2483 kxld_addr_t end = 0;
2484 u_int i = 0;
2485
2486 for (i = 0; i < object->segs.nitems; ++i) {
2487 seg = kxld_array_get_item(&object->segs, i);
2488 start = seg->base_addr;
2489 end = seg->base_addr + seg->vmsize;
2490
2491 if (start <= base_addr && base_addr < end) {
2492 return seg;
2493 }
2494 }
2495
2496 return NULL;
2497 }
2498
2499 /*******************************************************************************
2500 *******************************************************************************/
2501 static kern_return_t
2502 process_relocs_from_tables(KXLDObject *object)
2503 {
2504 kern_return_t rval = KERN_FAILURE;
2505 KXLDReloc *reloc = NULL;
2506 KXLDSeg *seg = NULL;
2507 u_int i = 0;
2508
2509 /* Process external relocations */
2510 for (i = 0; i < object->extrelocs.nitems; ++i) {
2511 reloc = kxld_array_get_item(&object->extrelocs, i);
2512
2513 seg = get_seg_by_base_addr(object, reloc->address);
2514 require_action(seg, finish, rval = KERN_FAILURE);
2515
2516 if (isOldInterface) {
2517 rval = kxld_relocator_process_table_reloc(&object->relocator, reloc,
2518 seg, object->link_addr);
2519 } else {
2520 kxld_addr_t my_link_addr = object->split_info.vmaddr_TEXT;
2521 if (isSplitKext) {
2522 if (kxld_seg_is_text_exec_seg(seg)) {
2523 my_link_addr = object->split_info.vmaddr_TEXT_EXEC;
2524 } else if (kxld_seg_is_data_seg(seg)) {
2525 my_link_addr = object->split_info.vmaddr_DATA;
2526 } else if (kxld_seg_is_data_const_seg(seg)) {
2527 my_link_addr = object->split_info.vmaddr_DATA_CONST;
2528 } else if (kxld_seg_is_llvm_cov_seg(seg)) {
2529 my_link_addr = object->split_info.vmaddr_LLVM_COV;
2530 } else if (kxld_seg_is_linkedit_seg(seg)) {
2531 my_link_addr = object->split_info.vmaddr_LINKEDIT;
2532 }
2533 }
2534 rval = kxld_relocator_process_table_reloc(&object->relocator,
2535 reloc,
2536 seg,
2537 my_link_addr);
2538 }
2539 require_noerr(rval, finish);
2540 }
2541
2542 /* Process local relocations */
2543 for (i = 0; i < object->locrelocs.nitems; ++i) {
2544 reloc = kxld_array_get_item(&object->locrelocs, i);
2545
2546 seg = get_seg_by_base_addr(object, reloc->address);
2547 require_action(seg, finish, rval = KERN_FAILURE);
2548
2549 if (isOldInterface) {
2550 rval = kxld_relocator_process_table_reloc(&object->relocator, reloc,
2551 seg, object->link_addr);
2552 } else {
2553 kxld_addr_t my_link_addr = object->split_info.vmaddr_TEXT;
2554 if (isSplitKext) {
2555 if (kxld_seg_is_text_exec_seg(seg)) {
2556 my_link_addr = object->split_info.vmaddr_TEXT_EXEC;
2557 } else if (kxld_seg_is_data_seg(seg)) {
2558 my_link_addr = object->split_info.vmaddr_DATA;
2559 } else if (kxld_seg_is_data_const_seg(seg)) {
2560 my_link_addr = object->split_info.vmaddr_DATA_CONST;
2561 } else if (kxld_seg_is_llvm_cov_seg(seg)) {
2562 my_link_addr = object->split_info.vmaddr_LLVM_COV;
2563 } else if (kxld_seg_is_linkedit_seg(seg)) {
2564 my_link_addr = object->split_info.vmaddr_LINKEDIT;
2565 }
2566 }
2567 rval = kxld_relocator_process_table_reloc(&object->relocator,
2568 reloc,
2569 seg,
2570 my_link_addr);
2571 }
2572 require_noerr(rval, finish);
2573 }
2574
2575 rval = KERN_SUCCESS;
2576 finish:
2577 return rval;
2578 }
2579
2580 /*******************************************************************************
2581 *******************************************************************************/
2582 static void
2583 add_to_ptr(u_char *symptr, kxld_addr_t val, boolean_t is_32_bit)
2584 {
2585 if (is_32_bit) {
2586 uint32_t *ptr = (uint32_t *) ((void *) symptr);
2587
2588 *ptr += (uint32_t) val;
2589 } else {
2590 uint64_t *ptr = (uint64_t *) ((void *) symptr);
2591
2592 *ptr += (uint64_t) val;
2593 }
2594
2595 #if SPLIT_KEXTS_DEBUG
2596 kxld_show_ptr_value = FALSE;
2597 #endif
2598 }
2599 #endif /* KXLD_USER_OR_BUNDLE */
2600
2601 #if KXLD_USER_OR_OBJECT
2602 /*******************************************************************************
2603 *******************************************************************************/
2604 static kern_return_t
2605 process_relocs_from_sections(KXLDObject *object)
2606 {
2607 kern_return_t rval = KERN_FAILURE;
2608 KXLDSect *sect = NULL;
2609 u_int i = 0;
2610
2611 for (i = 0; i < object->sects.nitems; ++i) {
2612 sect = kxld_array_get_item(&object->sects, i);
2613 rval = kxld_sect_process_relocs(sect, &object->relocator);
2614 require_noerr(rval, finish);
2615 }
2616
2617 rval = KERN_SUCCESS;
2618 finish:
2619 return rval;
2620 }
2621 #endif /* KXLD_USER_OR_OBJECT */
2622
2623 /*******************************************************************************
2624 *******************************************************************************/
2625 static kern_return_t
2626 populate_kmod_info(KXLDObject *object)
2627 {
2628 kern_return_t rval = KERN_FAILURE;
2629 KXLDSect *kmodsect = NULL;
2630 KXLDSym *kmodsym = NULL;
2631 kmod_info_t *kmod_info = NULL;
2632 u_long kmod_offset = 0;
2633 u_long header_size;
2634 u_long size;
2635
2636 if (kxld_object_is_kernel(object)) {
2637 rval = KERN_SUCCESS;
2638 goto finish;
2639 }
2640
2641 kxld_object_get_vmsize(object, &header_size, &size);
2642
2643 kmodsym = kxld_symtab_get_locally_defined_symbol_by_name(object->symtab,
2644 KXLD_KMOD_INFO_SYMBOL);
2645 require_action(kmodsym, finish, rval = KERN_FAILURE;
2646 kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogNoKmodInfo));
2647
2648 kmodsect = kxld_array_get_item(&object->sects, kmodsym->sectnum);
2649
2650 kmod_offset = (u_long) (kmodsym->base_addr - kmodsect->base_addr);
2651 kmod_info = (kmod_info_t *) ((void *) (kmodsect->data + kmod_offset));
2652
2653 if (kxld_object_is_32_bit(object)) {
2654 kmod_info_32_v1_t *kmod = (kmod_info_32_v1_t *) (kmod_info);
2655
2656 if (isOldInterface) {
2657 kmod->address = (uint32_t) object->link_addr;
2658 } else {
2659 kmod->address = (uint32_t) object->split_info.vmaddr_TEXT;
2660 }
2661
2662 kmod->size = (uint32_t) size;
2663 kmod->hdr_size = (uint32_t) header_size;
2664
2665 #if !KERNEL
2666 if (kxld_object_target_needs_swap(object)) {
2667 kmod->address = OSSwapInt32(kmod->address);
2668 kmod->size = OSSwapInt32(kmod->size);
2669 kmod->hdr_size = OSSwapInt32(kmod->hdr_size);
2670 }
2671 #endif /* !KERNEL */
2672 } else {
2673 kmod_info_64_v1_t *kmod = (kmod_info_64_v1_t *) (kmod_info);
2674
2675 if (isOldInterface) {
2676 kmod->address = object->link_addr;
2677 } else {
2678 kmod->address = object->split_info.vmaddr_TEXT;
2679 }
2680
2681 kmod->size = size;
2682 kmod->hdr_size = header_size;
2683
2684 #if !KERNEL
2685 if (kxld_object_target_needs_swap(object)) {
2686 kmod->address = OSSwapInt64(kmod->address);
2687 kmod->size = OSSwapInt64(kmod->size);
2688 kmod->hdr_size = OSSwapInt64(kmod->hdr_size);
2689 }
2690 #endif /* !KERNEL */
2691
2692 #if SPLIT_KEXTS_DEBUG
2693 {
2694 kxld_log(kKxldLogLinking, kKxldLogErr,
2695 " kmodsect %p kmod_info %p = kmodsect->data %p + kmod_offset %lu <%s>",
2696 (void *) kmodsect,
2697 (void *) kmod_info,
2698 (void *) kmodsect->data,
2699 kmod_offset,
2700 __func__);
2701
2702 kxld_log(kKxldLogLinking, kKxldLogErr,
2703 " kmod_info data: address %p size %llu hdr_size %llu start_addr %p stop_addr %p <%s>",
2704 (void *) kmod->address,
2705 kmod->size,
2706 kmod->hdr_size,
2707 (void *) kmod->start_addr,
2708 (void *) kmod->stop_addr,
2709 __func__);
2710 }
2711 #endif
2712 }
2713
2714 rval = KERN_SUCCESS;
2715
2716 finish:
2717 return rval;
2718 }
2719
2720 #if KXLD_PIC_KEXTS
2721 /*******************************************************************************
2722 *******************************************************************************/
2723 static boolean_t
2724 target_supports_slideable_kexts(const KXLDObject *object)
2725 {
2726 check(object);
2727
2728 return object->cputype != CPU_TYPE_I386 && object->include_kaslr_relocs;
2729 }
2730 #endif /* KXLD_PIC_KEXTS */
2731
2732 #pragma clang diagnostic pop
2733