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