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