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