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