1/*
2 * Copyright (c) 2009-2012 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28#include <string.h>
29#include <sys/types.h>
30
31#if KERNEL
32    #include <libkern/kernel_mach_header.h>
33    #include <mach/machine.h>
34    #include <mach/vm_param.h>
35    #include <mach-o/fat.h>
36#else /* !KERNEL */
37    /* Get machine.h from the kernel source so we can support all platforms
38     * that the kernel supports. Otherwise we're at the mercy of the host.
39     */
40    #include "../../osfmk/mach/machine.h"
41
42    #include <architecture/byte_order.h>
43    #include <mach/mach_init.h>
44    #include <mach-o/arch.h>
45    #include <mach-o/swap.h>
46#endif /* KERNEL */
47
48#include <mach-o/loader.h>
49#include <mach-o/nlist.h>
50#include <mach-o/reloc.h>
51
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"
60#include "kxld_srcversion.h"
61#include "kxld_symtab.h"
62#include "kxld_util.h"
63#include "kxld_uuid.h"
64#include "kxld_versionmin.h"
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;
86    KXLDversionmin versionmin;
87    KXLDsrcversion srcversion;
88    KXLDSymtab *symtab;
89    struct dysymtab_command *dysymtab_hdr;
90    kxld_addr_t link_addr;
91    u_long    output_buffer_size;
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
99#if KXLD_PIC_KEXTS
100    boolean_t include_kaslr_relocs;
101#endif
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
146#if KXLD_PIC_KEXTS
147static boolean_t target_supports_slideable_kexts(const KXLDObject *object);
148#endif  /* KXLD_PIC_KEXTS */
149
150
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,
205    cpu_type_t cputype, cpu_subtype_t cpusubtype, KXLDFlags flags __unused)
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
220#if KXLD_PIC_KEXTS
221    object->include_kaslr_relocs = ((flags & kKXLDFlagIncludeRelocs) == kKXLDFlagIncludeRelocs);
222#endif
223
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)) {
257        struct mach_header *mach_hdr = (struct mach_header *) ((void *) object->file);
258        object->filetype = mach_hdr->filetype;
259    } else {
260        struct mach_header_64 *mach_hdr = (struct mach_header_64 *) ((void *) object->file);
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,
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                );
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(__x86_64__)
331    object->cputype = CPU_TYPE_X86_64;
332    object->cpusubtype = CPU_SUBTYPE_X86_64_ALL;
333    return KERN_SUCCESS;
334#else
335    kxld_log(kKxldLogLinking, kKxldLogErr,
336        kKxldLogArchNotSupported, _mh_execute_header->cputype);
337    return KERN_NOT_SUPPORTED;
338#endif /* Supported architecture defines */
339
340
341#else /* !KERNEL */
342
343    /* User-space must look up the architecture it's running on and the target
344     * architecture at run-time.
345     */
346
347    kern_return_t rval = KERN_FAILURE;
348    const NXArchInfo *host_arch = NULL;
349
350    check(object);
351
352    host_arch = NXGetLocalArchInfo();
353    require_action(host_arch, finish, rval=KERN_FAILURE);
354
355    object->host_order = host_arch->byteorder;
356
357    /* If the user did not specify a cputype, use the local architecture.
358     */
359
360    if (cputype) {
361        object->cputype = cputype;
362        object->cpusubtype = cpusubtype;
363    } else {
364        object->cputype = host_arch->cputype;
365        object->target_order = object->host_order;
366
367        switch (object->cputype) {
368        case CPU_TYPE_I386:
369            object->cpusubtype = CPU_SUBTYPE_I386_ALL;
370            break;
371        case CPU_TYPE_X86_64:
372            object->cpusubtype = CPU_SUBTYPE_X86_64_ALL;
373            break;
374        case CPU_TYPE_ARM:
375            object->cpusubtype = CPU_SUBTYPE_ARM_ALL;
376            break;
377        default:
378            object->cpusubtype = 0;
379            break;
380        }
381    }
382
383    /* Validate that we support the target architecture and record its
384     * endianness.
385     */
386
387    switch(object->cputype) {
388    case CPU_TYPE_ARM:
389    case CPU_TYPE_I386:
390    case CPU_TYPE_X86_64:
391        object->target_order = NX_LittleEndian;
392        break;
393    default:
394        rval = KERN_NOT_SUPPORTED;
395        kxld_log(kKxldLogLinking, kKxldLogErr,
396            kKxldLogArchNotSupported, object->cputype);
397        goto finish;
398    }
399
400    rval = KERN_SUCCESS;
401
402finish:
403    return rval;
404#endif /* KERNEL */
405}
406
407/*******************************************************************************
408*******************************************************************************/
409static kern_return_t
410get_macho_slice_for_arch(KXLDObject *object, u_char *file, u_long size)
411{
412    kern_return_t rval = KERN_FAILURE;
413    struct mach_header *mach_hdr = NULL;
414#if !KERNEL
415    struct fat_header *fat = (struct fat_header *) ((void *) file);
416    struct fat_arch *archs = (struct fat_arch *) &fat[1];
417    boolean_t swap = FALSE;
418#endif /* KERNEL */
419
420    check(object);
421    check(file);
422    check(size);
423
424    object->file = file;
425    object->size = size;
426
427    /* We are assuming that we will never receive a fat file in the kernel */
428
429#if !KERNEL
430    require_action(size >= sizeof(*fat), finish,
431        rval=KERN_FAILURE;
432        kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogTruncatedMachO));
433
434    /* The fat header is always big endian, so swap if necessary */
435    if (fat->magic == FAT_CIGAM) {
436        (void) swap_fat_header(fat, object->host_order);
437        swap = TRUE;
438    }
439
440    if (fat->magic == FAT_MAGIC) {
441        struct fat_arch *arch = NULL;
442
443        require_action(size >= (sizeof(*fat) + (fat->nfat_arch * sizeof(*archs))),
444            finish,
445            rval=KERN_FAILURE;
446            kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogTruncatedMachO));
447
448        /* Swap the fat_arch structures if necessary */
449        if (swap) {
450            (void) swap_fat_arch(archs, fat->nfat_arch, object->host_order);
451        }
452
453        /* Locate the Mach-O for the requested architecture */
454
455        arch = NXFindBestFatArch(object->cputype, object->cpusubtype, archs,
456            fat->nfat_arch);
457        require_action(arch, finish, rval=KERN_FAILURE;
458            kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogArchNotFound));
459        require_action(size >= arch->offset + arch->size, finish,
460            rval=KERN_FAILURE;
461            kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogTruncatedMachO));
462
463        object->file = file + arch->offset;
464        object->size = arch->size;
465    }
466#endif /* !KERNEL */
467
468    /* Swap the Mach-O's headers to this architecture if necessary */
469    if (kxld_object_is_32_bit(object)) {
470        rval = validate_and_swap_macho_32(object->file, object->size
471#if !KERNEL
472            , object->host_order
473#endif /* !KERNEL */
474            );
475    } else {
476        rval = validate_and_swap_macho_64(object->file, object->size
477#if !KERNEL
478            , object->host_order
479#endif /* !KERNEL */
480            );
481    }
482    require_noerr(rval, finish);
483
484    mach_hdr = (struct mach_header *) ((void *) object->file);
485    require_action(object->cputype == mach_hdr->cputype, finish,
486        rval=KERN_FAILURE;
487        kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogTruncatedMachO));
488
489    rval = KERN_SUCCESS;
490finish:
491    return rval;
492}
493
494/*******************************************************************************
495*******************************************************************************/
496static kern_return_t
497init_from_final_linked_image(KXLDObject *object, u_int *filetype_out,
498    struct symtab_command **symtab_hdr_out)
499{
500    kern_return_t rval = KERN_FAILURE;
501    KXLDSeg *seg = NULL;
502    KXLDSect *sect = NULL;
503    struct load_command *cmd_hdr = NULL;
504    struct symtab_command *symtab_hdr = NULL;
505    struct uuid_command *uuid_hdr = NULL;
506    struct version_min_command *versionmin_hdr = NULL;
507    struct source_version_command *source_version_hdr = NULL;
508    u_long base_offset = 0;
509    u_long offset = 0;
510    u_long sect_offset = 0;
511    u_int filetype = 0;
512    u_int i = 0;
513    u_int j = 0;
514    u_int segi = 0;
515    u_int secti = 0;
516    u_int nsegs = 0;
517    u_int nsects = 0;
518    u_int ncmds = 0;
519
520    KXLD_3264_FUNC(kxld_object_is_32_bit(object), base_offset,
521        get_macho_cmd_data_32, get_macho_cmd_data_64,
522        object->file, offset, &filetype, &ncmds);
523
524    /* First pass to count segments and sections */
525
526    offset = base_offset;
527    for (i = 0; i < ncmds; ++i, offset += cmd_hdr->cmdsize) {
528        cmd_hdr = (struct load_command *) ((void *) (object->file + offset));
529
530        switch(cmd_hdr->cmd) {
531#if KXLD_USER_OR_ILP32
532        case LC_SEGMENT:
533            {
534                struct segment_command *seg_hdr =
535                    (struct segment_command *) cmd_hdr;
536
537                /* Ignore segments with no vm size */
538                if (!seg_hdr->vmsize) continue;
539
540                ++nsegs;
541                nsects += seg_hdr->nsects;
542            }
543            break;
544#endif /* KXLD_USER_OR_ILP32 */
545#if KXLD_USER_OR_LP64
546        case LC_SEGMENT_64:
547            {
548                struct segment_command_64 *seg_hdr =
549                    (struct segment_command_64 *) ((void *) cmd_hdr);
550
551                /* Ignore segments with no vm size */
552                if (!seg_hdr->vmsize) continue;
553
554                ++nsegs;
555                nsects += seg_hdr->nsects;
556            }
557            break;
558#endif /* KXLD_USER_OR_LP64 */
559        default:
560            continue;
561        }
562    }
563
564    /* Allocate the segments and sections */
565
566    if (nsegs) {
567        rval = kxld_array_init(&object->segs, sizeof(KXLDSeg), nsegs);
568        require_noerr(rval, finish);
569
570        rval = kxld_array_init(&object->sects, sizeof(KXLDSect), nsects);
571        require_noerr(rval, finish);
572    }
573
574    /* Initialize the segments and sections */
575
576    offset = base_offset;
577    for (i = 0; i < ncmds; ++i, offset += cmd_hdr->cmdsize) {
578        cmd_hdr = (struct load_command *) ((void *) (object->file + offset));
579        seg = NULL;
580
581        switch(cmd_hdr->cmd) {
582#if KXLD_USER_OR_ILP32
583        case LC_SEGMENT:
584            {
585                struct segment_command *seg_hdr =
586                    (struct segment_command *) cmd_hdr;
587
588                /* Ignore segments with no vm size */
589                if (!seg_hdr->vmsize) continue;
590
591                seg = kxld_array_get_item(&object->segs, segi++);
592
593                rval = kxld_seg_init_from_macho_32(seg, seg_hdr);
594                require_noerr(rval, finish);
595
596                sect_offset = offset + sizeof(*seg_hdr);
597            }
598            break;
599#endif /* KXLD_USER_OR_ILP32 */
600#if KXLD_USER_OR_LP64
601        case LC_SEGMENT_64:
602            {
603                struct segment_command_64 *seg_hdr =
604                    (struct segment_command_64 *) ((void *) cmd_hdr);
605
606                /* Ignore segments with no vm size */
607                if (!seg_hdr->vmsize) continue;
608
609                seg = kxld_array_get_item(&object->segs, segi++);
610
611                rval = kxld_seg_init_from_macho_64(seg, seg_hdr);
612                require_noerr(rval, finish);
613
614                sect_offset = offset + sizeof(*seg_hdr);
615            }
616            break;
617#endif /* KXLD_USER_OR_LP64 */
618        case LC_SYMTAB:
619            symtab_hdr = (struct symtab_command *) cmd_hdr;
620            break;
621        case LC_UUID:
622            uuid_hdr = (struct uuid_command *) cmd_hdr;
623            kxld_uuid_init_from_macho(&object->uuid, uuid_hdr);
624            break;
625        case LC_VERSION_MIN_MACOSX:
626        case LC_VERSION_MIN_IPHONEOS:
627            versionmin_hdr = (struct version_min_command *) cmd_hdr;
628            kxld_versionmin_init_from_macho(&object->versionmin, versionmin_hdr);
629            break;
630        case LC_SOURCE_VERSION:
631            source_version_hdr = (struct source_version_command *) (void *) cmd_hdr;
632            kxld_srcversion_init_from_macho(&object->srcversion, source_version_hdr);
633            break;
634        case LC_DYSYMTAB:
635            object->dysymtab_hdr = (struct dysymtab_command *) cmd_hdr;
636
637            rval = kxld_reloc_create_macho(&object->extrelocs, &object->relocator,
638                (struct relocation_info *) ((void *) (object->file + object->dysymtab_hdr->extreloff)),
639                object->dysymtab_hdr->nextrel);
640            require_noerr(rval, finish);
641
642            rval = kxld_reloc_create_macho(&object->locrelocs, &object->relocator,
643                (struct relocation_info *) ((void *) (object->file + object->dysymtab_hdr->locreloff)),
644                object->dysymtab_hdr->nlocrel);
645            require_noerr(rval, finish);
646
647            break;
648        case LC_UNIXTHREAD:
649        case LC_MAIN:
650            /* Don't need to do anything with UNIXTHREAD or MAIN for the kernel */
651            require_action(kxld_object_is_kernel(object),
652                finish, rval=KERN_FAILURE;
653                kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogMalformedMachO
654                    "LC_UNIXTHREAD/LC_MAIN segment is not valid in a kext."));
655            break;
656        case LC_SEGMENT_SPLIT_INFO:
657            /* To be implemented later; treat as uninteresting for now */
658        case LC_CODE_SIGNATURE:
659        case LC_DYLD_INFO:
660        case LC_DYLD_INFO_ONLY:
661        case LC_FUNCTION_STARTS:
662        case LC_DATA_IN_CODE:
663        case LC_DYLIB_CODE_SIGN_DRS:
664            /* Various metadata that might be stored in the linkedit segment */
665            break;
666        default:
667            rval=KERN_FAILURE;
668            kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogMalformedMachO
669                "Invalid segment type in MH_KEXT_BUNDLE kext: %u.", cmd_hdr->cmd);
670            goto finish;
671        }
672
673        if (seg) {
674
675            /* Initialize the sections */
676            for (j = 0; j < seg->sects.nitems; ++j, ++secti) {
677                sect = kxld_array_get_item(&object->sects, secti);
678                KXLD_3264_FUNC(kxld_object_is_32_bit(object), rval,
679                    kxld_sect_init_from_macho_32, kxld_sect_init_from_macho_64,
680                    sect, object->file, &sect_offset, secti, &object->relocator);
681                require_noerr(rval, finish);
682
683                /* Add the section to the segment.  This will also make sure
684                 * that the sections and segments have the same segname.
685                 */
686                rval = kxld_seg_add_section(seg, sect);
687                require_noerr(rval, finish);
688            }
689            rval = kxld_seg_finish_init(seg);
690            require_noerr(rval, finish);
691        }
692    }
693
694    if (filetype_out) *filetype_out = filetype;
695    if (symtab_hdr_out) *symtab_hdr_out = symtab_hdr;
696    object->is_final_image = TRUE;
697    rval = KERN_SUCCESS;
698finish:
699    return rval;
700}
701
702/*******************************************************************************
703*******************************************************************************/
704static kern_return_t
705init_from_execute(KXLDObject *object)
706{
707    kern_return_t rval = KERN_FAILURE;
708    struct symtab_command *symtab_hdr = NULL;
709    u_int filetype = 0;
710    KXLDSeg * kernel_linkedit_seg = NULL;  // used if running kernel
711#if KXLD_USER_OR_OBJECT
712    KXLDSeg *seg = NULL;
713    KXLDSect *sect = NULL;
714    KXLDSectionName *sname = NULL;
715    u_int i = 0, j = 0, k = 0;
716#endif /* KXLD_USER_OR_OBJECT */
717
718    check(object);
719
720    require_action(kxld_object_is_kernel(object), finish, rval=KERN_FAILURE);
721
722    rval = init_from_final_linked_image(object, &filetype, &symtab_hdr);
723    require_noerr(rval, finish);
724
725    require_action(filetype == MH_EXECUTE, finish, rval=KERN_FAILURE;
726        kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogMalformedMachO
727            "The kernel file is not of type MH_EXECUTE."));
728
729   /* Initialize the symbol table. If this is the running kernel
730    * we  will work from the in-memory linkedit segment;
731    * otherwise we work from the whole mach-o image.
732    */
733#if KERNEL
734    kernel_linkedit_seg = kxld_object_get_seg_by_name(object, SEG_LINKEDIT);
735    require_action(kernel_linkedit_seg, finish, rval=KERN_FAILURE;
736        kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogMalformedMachO));
737#endif
738
739    KXLD_3264_FUNC(kxld_object_is_32_bit(object), rval,
740        kxld_symtab_init_from_macho_32, kxld_symtab_init_from_macho_64,
741        object->symtab, symtab_hdr, object->file, kernel_linkedit_seg);
742    require_noerr(rval, finish);
743
744#if KXLD_USER_OR_OBJECT
745    /* Save off the order of section names so that we can lay out kext
746     * sections for MH_OBJECT-based systems.
747     */
748    if (target_supports_object(object)) {
749
750        rval = kxld_array_init(object->section_order, sizeof(KXLDSectionName),
751            object->sects.nitems);
752        require_noerr(rval, finish);
753
754        /* Copy the section names into the section_order array for future kext
755         * section ordering.
756         */
757        for (i = 0, k = 0; i < object->segs.nitems; ++i) {
758            seg = kxld_array_get_item(&object->segs, i);
759
760            for (j = 0; j < seg->sects.nitems; ++j, ++k) {
761                sect = *(KXLDSect **) kxld_array_get_item(&seg->sects, j);
762                sname = kxld_array_get_item(object->section_order, k);
763
764                strlcpy(sname->segname, sect->segname, sizeof(sname->segname));
765                strlcpy(sname->sectname, sect->sectname, sizeof(sname->sectname));
766            }
767        }
768    }
769#endif /* KXLD_USER_OR_OBJECT */
770
771    rval = KERN_SUCCESS;
772finish:
773    return rval;
774}
775
776#if KXLD_USER_OR_BUNDLE
777/*******************************************************************************
778*******************************************************************************/
779static boolean_t
780target_supports_bundle(const KXLDObject *object __unused)
781{
782    return TRUE;
783}
784
785/*******************************************************************************
786*******************************************************************************/
787static kern_return_t
788init_from_bundle(KXLDObject *object)
789{
790    kern_return_t rval = KERN_FAILURE;
791    struct symtab_command *symtab_hdr = NULL;
792    u_int filetype = 0;
793
794    check(object);
795
796    require_action(target_supports_bundle(object), finish,
797        rval=KERN_FAILURE;
798        kxld_log(kKxldLogLinking, kKxldLogErr,
799            kKxldLogFiletypeNotSupported, MH_KEXT_BUNDLE));
800
801    rval = init_from_final_linked_image(object, &filetype, &symtab_hdr);
802    require_noerr(rval, finish);
803
804    require_action(filetype == MH_KEXT_BUNDLE, finish,
805        rval=KERN_FAILURE);
806
807    KXLD_3264_FUNC(kxld_object_is_32_bit(object), rval,
808        kxld_symtab_init_from_macho_32, kxld_symtab_init_from_macho_64,
809        object->symtab, symtab_hdr, object->file,
810        /* kernel_linkedit_seg */ NULL);
811    require_noerr(rval, finish);
812
813    rval = KERN_SUCCESS;
814finish:
815    return rval;
816}
817#endif /* KXLD_USER_OR_BUNDLE */
818
819#if KXLD_USER_OR_OBJECT
820/*******************************************************************************
821*******************************************************************************/
822static boolean_t target_supports_object(const KXLDObject *object)
823{
824    return (object->cputype == CPU_TYPE_I386);
825}
826
827/*******************************************************************************
828*******************************************************************************/
829static kern_return_t
830init_from_object(KXLDObject *object)
831{
832    kern_return_t rval = KERN_FAILURE;
833    struct load_command *cmd_hdr = NULL;
834    struct symtab_command *symtab_hdr = NULL;
835    struct uuid_command *uuid_hdr = NULL;
836    KXLDSect *sect = NULL;
837    u_long offset = 0;
838    u_long sect_offset = 0;
839    u_int filetype = 0;
840    u_int ncmds = 0;
841    u_int nsects = 0;
842    u_int i = 0;
843    boolean_t has_segment = FALSE;
844
845    check(object);
846
847    require_action(target_supports_object(object),
848        finish, rval=KERN_FAILURE;
849        kxld_log(kKxldLogLinking, kKxldLogErr,
850            kKxldLogFiletypeNotSupported, MH_OBJECT));
851
852    KXLD_3264_FUNC(kxld_object_is_32_bit(object), offset,
853        get_macho_cmd_data_32, get_macho_cmd_data_64,
854        object->file, offset, &filetype, &ncmds);
855
856    require_action(filetype == MH_OBJECT, finish, rval=KERN_FAILURE);
857
858    /* MH_OBJECTs use one unnamed segment to contain all of the sections.  We
859     * loop over all of the load commands to initialize the structures we
860     * expect.  Then, we'll use the unnamed segment to get to all of the
861     * sections, and then use those sections to create the actual segments.
862     */
863
864    for (; i < ncmds; ++i, offset += cmd_hdr->cmdsize) {
865        cmd_hdr = (struct load_command *) ((void *) (object->file + offset));
866
867        switch(cmd_hdr->cmd) {
868#if KXLD_USER_OR_ILP32
869        case LC_SEGMENT:
870            {
871                struct segment_command *seg_hdr =
872                    (struct segment_command *) cmd_hdr;
873
874                /* Ignore segments with no vm size */
875                if (!seg_hdr->vmsize) continue;
876
877                /* Ignore LINKEDIT segments */
878                if (streq_safe(seg_hdr->segname, SEG_LINKEDIT,
879                        const_strlen(SEG_LINKEDIT)))
880                {
881                    continue;
882                }
883
884                require_action(kxld_object_is_32_bit(object), finish, rval=KERN_FAILURE;
885                    kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogMalformedMachO
886                        "LC_SEGMENT in 64-bit kext."));
887                require_action(!has_segment, finish, rval=KERN_FAILURE;
888                    kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogMalformedMachO
889                        "Multiple segments in an MH_OBJECT kext."));
890
891                nsects = seg_hdr->nsects;
892                sect_offset = offset + sizeof(*seg_hdr);
893                has_segment = TRUE;
894            }
895            break;
896#endif /* KXLD_USER_OR_ILP32 */
897#if KXLD_USER_OR_LP64
898        case LC_SEGMENT_64:
899            {
900                struct segment_command_64 *seg_hdr =
901                    (struct segment_command_64 *) ((void *) cmd_hdr);
902
903                /* Ignore segments with no vm size */
904                if (!seg_hdr->vmsize) continue;
905
906                /* Ignore LINKEDIT segments */
907                if (streq_safe(seg_hdr->segname, SEG_LINKEDIT,
908                        const_strlen(SEG_LINKEDIT)))
909                {
910                    continue;
911                }
912
913                require_action(!kxld_object_is_32_bit(object), finish, rval=KERN_FAILURE;
914                    kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogMalformedMachO
915                        "LC_SEGMENT_64 in a 32-bit kext."));
916                require_action(!has_segment, finish, rval=KERN_FAILURE;
917                    kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogMalformedMachO
918                        "Multiple segments in an MH_OBJECT kext."));
919
920                nsects = seg_hdr->nsects;
921                sect_offset = offset + sizeof(*seg_hdr);
922                has_segment = TRUE;
923            }
924            break;
925#endif /* KXLD_USER_OR_LP64 */
926        case LC_SYMTAB:
927            symtab_hdr = (struct symtab_command *) cmd_hdr;
928
929            KXLD_3264_FUNC(kxld_object_is_32_bit(object), rval,
930                kxld_symtab_init_from_macho_32, kxld_symtab_init_from_macho_64,
931                object->symtab, symtab_hdr, object->file,
932                /* kernel_linkedit_seg */ NULL);
933            require_noerr(rval, finish);
934            break;
935        case LC_UUID:
936            uuid_hdr = (struct uuid_command *) cmd_hdr;
937            kxld_uuid_init_from_macho(&object->uuid, uuid_hdr);
938            break;
939        case LC_UNIXTHREAD:
940        case LC_MAIN:
941            /* Don't need to do anything with UNIXTHREAD or MAIN */
942            break;
943        case LC_CODE_SIGNATURE:
944        case LC_DYLD_INFO:
945        case LC_DYLD_INFO_ONLY:
946        case LC_FUNCTION_STARTS:
947        case LC_DATA_IN_CODE:
948        case LC_DYLIB_CODE_SIGN_DRS:
949            /* Various metadata that might be stored in the linkedit segment */
950            break;
951        case LC_VERSION_MIN_MACOSX:
952        case LC_VERSION_MIN_IPHONEOS:
953        case LC_SOURCE_VERSION:
954            /* Not supported for object files, fall through */
955        default:
956            rval = KERN_FAILURE;
957            kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogMalformedMachO
958                "Invalid segment type in MH_OBJECT kext: %u.", cmd_hdr->cmd);
959            goto finish;
960        }
961    }
962
963    if (has_segment) {
964
965        /* Get the number of sections from the segment and build the section index */
966
967        rval = kxld_array_init(&object->sects, sizeof(KXLDSect), nsects);
968        require_noerr(rval, finish);
969
970        /* Loop over all of the sections to initialize the section index */
971
972        for (i = 0; i < nsects; ++i) {
973            sect = kxld_array_get_item(&object->sects, i);
974            KXLD_3264_FUNC(kxld_object_is_32_bit(object), rval,
975                kxld_sect_init_from_macho_32, kxld_sect_init_from_macho_64,
976                sect, object->file, &sect_offset, i, &object->relocator);
977            require_noerr(rval, finish);
978        }
979
980        /* Create special sections */
981
982#if KXLD_USER_OR_GOT
983        rval = create_got(object);
984        require_noerr(rval, finish);
985#endif /* KXLD_USER_OR_GOT */
986
987#if KXLD_USER_OR_COMMON
988        rval = resolve_common_symbols(object);
989        require_noerr(rval, finish);
990#endif /* KXLD_USER_OR_COMMON */
991
992        /* Create the segments from the section index */
993
994        rval = kxld_seg_create_seg_from_sections(&object->segs, &object->sects);
995        require_noerr(rval, finish);
996
997        rval = kxld_seg_finalize_object_segment(&object->segs,
998            object->section_order, get_macho_header_size(object));
999        require_noerr(rval, finish);
1000
1001        rval = kxld_seg_init_linkedit(&object->segs);
1002        require_noerr(rval, finish);
1003    }
1004
1005    rval = KERN_SUCCESS;
1006finish:
1007    return rval;
1008}
1009#endif /* KXLD_USER_OR_OBJECT */
1010
1011#if KXLD_USER_OR_ILP32
1012/*******************************************************************************
1013*******************************************************************************/
1014static u_long
1015get_macho_cmd_data_32(u_char *file, u_long offset, u_int *filetype, u_int *ncmds)
1016{
1017    struct mach_header *mach_hdr = (struct mach_header *) ((void *) (file + offset));
1018
1019    if (filetype) *filetype = mach_hdr->filetype;
1020    if (ncmds) *ncmds = mach_hdr->ncmds;
1021
1022    return sizeof(*mach_hdr);
1023}
1024
1025#endif /* KXLD_USER_OR_ILP32 */
1026
1027#if KXLD_USER_OR_LP64
1028/*******************************************************************************
1029*******************************************************************************/
1030static u_long
1031get_macho_cmd_data_64(u_char *file, u_long offset, u_int *filetype,  u_int *ncmds)
1032{
1033    struct mach_header_64 *mach_hdr = (struct mach_header_64 *) ((void *) (file + offset));
1034
1035    if (filetype) *filetype = mach_hdr->filetype;
1036    if (ncmds) *ncmds = mach_hdr->ncmds;
1037
1038    return sizeof(*mach_hdr);
1039}
1040#endif /* KXLD_USER_OR_LP64 */
1041
1042/*******************************************************************************
1043*******************************************************************************/
1044static u_long
1045get_macho_header_size(const KXLDObject *object)
1046{
1047    KXLDSeg *seg = NULL;
1048    u_long header_size = 0;
1049    u_int i = 0;
1050    boolean_t   object_is_32_bit = kxld_object_is_32_bit(object);
1051
1052    check(object);
1053
1054    /* Mach, segment, symtab, and UUID headers */
1055
1056    header_size += object_is_32_bit ? sizeof(struct mach_header) : sizeof(struct mach_header_64);
1057
1058    for (i = 0; i < object->segs.nitems; ++i) {
1059        seg = kxld_array_get_item(&object->segs, i);
1060        header_size += kxld_seg_get_macho_header_size(seg, object_is_32_bit);
1061    }
1062
1063    header_size += kxld_symtab_get_macho_header_size();
1064
1065#if KXLD_PIC_KEXTS
1066    if (target_supports_slideable_kexts(object)) {
1067        header_size += kxld_reloc_get_macho_header_size();
1068    }
1069#endif	/* KXLD_PIC_KEXTS */
1070
1071    if (object->uuid.has_uuid) {
1072        header_size += kxld_uuid_get_macho_header_size();
1073    }
1074
1075    if (object->versionmin.has_versionmin) {
1076        header_size += kxld_versionmin_get_macho_header_size();
1077    }
1078
1079    if (object->srcversion.has_srcversion) {
1080        header_size += kxld_srcversion_get_macho_header_size();
1081    }
1082
1083    return header_size;
1084}
1085
1086/*******************************************************************************
1087*******************************************************************************/
1088static u_long
1089get_macho_data_size(const KXLDObject *object)
1090{
1091    KXLDSeg *seg = NULL;
1092    u_long data_size = 0;
1093    u_int i = 0;
1094
1095    check(object);
1096
1097    /* total all segment vmsize values */
1098    for (i = 0; i < object->segs.nitems; ++i) {
1099        seg = kxld_array_get_item(&object->segs, i);
1100        data_size += (u_long) kxld_seg_get_vmsize(seg);
1101    }
1102
1103#if KXLD_PIC_KEXTS
1104    {
1105        /* ensure that when we eventually emit the final linked object,
1106         * appending the __DYSYMTAB data after the __LINKEDIT data will
1107         * not overflow the space allocated for the __LINKEDIT segment
1108         */
1109
1110        u_long  seg_vmsize = 0;
1111        u_long  symtab_size = 0;
1112        u_long  reloc_size = 0;
1113
1114        /* get current __LINKEDIT sizes */
1115        seg = kxld_object_get_seg_by_name(object, SEG_LINKEDIT);
1116        seg_vmsize = (u_long) kxld_seg_get_vmsize(seg);
1117
1118        /* get size of symbol table data that will eventually be dumped
1119         * into the __LINKEDIT segment
1120         */
1121        symtab_size = kxld_symtab_get_macho_data_size(object->symtab, kxld_object_is_32_bit(object));
1122
1123        if (target_supports_slideable_kexts(object)) {
1124            /* get size of __DYSYMTAB relocation entries */
1125            reloc_size = kxld_reloc_get_macho_data_size(&object->locrelocs, &object->extrelocs);
1126        }
1127
1128        /* combine, and ensure they'll both fit within the page(s)
1129         * allocated for the __LINKEDIT segment. If they'd overflow,
1130         * increase the vmsize appropriately so no overflow will occur
1131         */
1132        if ((symtab_size + reloc_size) > seg_vmsize) {
1133            u_long  overflow = (symtab_size + reloc_size) - seg_vmsize;
1134            data_size += round_page(overflow);
1135        }
1136    }
1137#endif  // KXLD_PIC_KEXTS
1138
1139    return data_size;
1140}
1141
1142/*******************************************************************************
1143*******************************************************************************/
1144boolean_t
1145kxld_object_target_needs_swap(const KXLDObject *object __unused)
1146{
1147#if KERNEL
1148    return FALSE;
1149#else
1150    return (object->target_order != object->host_order);
1151#endif /* KERNEL */
1152}
1153
1154/*******************************************************************************
1155*******************************************************************************/
1156KXLDSeg *
1157kxld_object_get_seg_by_name(const KXLDObject *object, const char *segname)
1158{
1159    KXLDSeg *seg = NULL;
1160    u_int i = 0;
1161
1162    for (i = 0; i < object->segs.nitems; ++i) {
1163        seg = kxld_array_get_item(&object->segs, i);
1164
1165        if (streq_safe(segname, seg->segname, sizeof(seg->segname))) break;
1166
1167        seg = NULL;
1168    }
1169
1170    return seg;
1171}
1172
1173/*******************************************************************************
1174*******************************************************************************/
1175const KXLDRelocator *
1176kxld_object_get_relocator(const KXLDObject * object)
1177{
1178    check(object);
1179
1180    return &object->relocator;
1181}
1182
1183/*******************************************************************************
1184*******************************************************************************/
1185KXLDSect *
1186kxld_object_get_sect_by_name(const KXLDObject *object, const char *segname,
1187    const char *sectname)
1188{
1189    KXLDSect *sect = NULL;
1190    u_int i = 0;
1191
1192    for (i = 0; i < object->sects.nitems; ++i) {
1193        sect = kxld_array_get_item(&object->sects, i);
1194
1195        if (streq_safe(segname, sect->segname, sizeof(sect->segname)) &&
1196            streq_safe(sectname, sect->sectname, sizeof(sect->sectname)))
1197        {
1198            break;
1199        }
1200
1201        sect = NULL;
1202    }
1203
1204    return sect;
1205}
1206
1207/*******************************************************************************
1208*******************************************************************************/
1209const KXLDReloc *
1210kxld_object_get_reloc_at_symbol(const KXLDObject *object, const KXLDSym *sym)
1211{
1212    const KXLDReloc *reloc = NULL;
1213    const KXLDSect *sect = NULL;
1214    uint32_t offset = 0;
1215
1216    check(object);
1217    check(sym);
1218
1219    sect = kxld_object_get_section_by_index(object, sym->sectnum);
1220    require(sect, finish);
1221
1222    if (kxld_object_is_final_image(object)) {
1223        reloc = kxld_reloc_get_reloc_by_offset(&object->extrelocs,
1224            sym->base_addr);
1225        if (!reloc) {
1226            reloc = kxld_reloc_get_reloc_by_offset(&object->locrelocs,
1227                sym->base_addr);
1228        }
1229    } else {
1230        offset = kxld_sym_get_section_offset(sym, sect);
1231        reloc = kxld_reloc_get_reloc_by_offset(&sect->relocs, offset);
1232    }
1233
1234finish:
1235    return reloc;
1236}
1237
1238/*******************************************************************************
1239*******************************************************************************/
1240const KXLDSym *
1241kxld_object_get_symbol_of_reloc(const KXLDObject *object,
1242    const KXLDReloc *reloc, const KXLDSect *sect)
1243{
1244    const KXLDSym *sym = NULL;
1245
1246    if (kxld_object_is_final_image(object)) {
1247        sym = kxld_reloc_get_symbol(&object->relocator, reloc, object->file);
1248    } else {
1249        sym = kxld_reloc_get_symbol(&object->relocator, reloc, sect->data);
1250    }
1251
1252    return sym;
1253}
1254
1255/*******************************************************************************
1256*******************************************************************************/
1257const KXLDSect *
1258kxld_object_get_section_by_index(const KXLDObject *object, u_int sectnum)
1259{
1260    KXLDSect *sect = NULL;
1261
1262    check(object);
1263
1264    if (sectnum < object->sects.nitems) {
1265        sect = kxld_array_get_item(&object->sects, sectnum);
1266    }
1267
1268    return sect;
1269}
1270
1271/*******************************************************************************
1272*******************************************************************************/
1273const KXLDArray  *
1274kxld_object_get_extrelocs(const KXLDObject *object)
1275{
1276    const KXLDArray *rval = NULL;
1277
1278    check(object);
1279
1280    if (kxld_object_is_final_image(object)) {
1281        rval = &object->extrelocs;
1282    }
1283
1284    return rval;
1285}
1286
1287/*******************************************************************************
1288*******************************************************************************/
1289const KXLDSymtab *
1290kxld_object_get_symtab(const KXLDObject *object)
1291{
1292    check(object);
1293
1294    return object->symtab;
1295}
1296
1297#if KXLD_USER_OR_GOT || KXLD_USER_OR_COMMON
1298/*******************************************************************************
1299*******************************************************************************/
1300static kern_return_t
1301add_section(KXLDObject *object, KXLDSect **sect)
1302{
1303    kern_return_t rval = KERN_FAILURE;
1304    u_int nsects = object->sects.nitems;
1305
1306    rval = kxld_array_resize(&object->sects, nsects + 1);
1307    require_noerr(rval, finish);
1308
1309    *sect = kxld_array_get_item(&object->sects, nsects);
1310
1311    rval = KERN_SUCCESS;
1312
1313finish:
1314    return rval;
1315}
1316#endif /* KXLD_USER_OR_GOT || KXLD_USER_OR_COMMON */
1317
1318#if KXLD_USER_OR_COMMON
1319/*******************************************************************************
1320* If there are common symbols, calculate how much space they'll need
1321* and create/grow the __DATA __common section to accommodate them.
1322* Then, resolve them against that section.
1323*******************************************************************************/
1324static kern_return_t
1325resolve_common_symbols(KXLDObject *object)
1326{
1327    kern_return_t rval = KERN_FAILURE;
1328    KXLDSymtabIterator iter;
1329    KXLDSym *sym = NULL;
1330    KXLDSect *sect = NULL;
1331    kxld_addr_t base_addr = 0;
1332    kxld_size_t size = 0;
1333    kxld_size_t total_size = 0;
1334    u_int align = 0;
1335    u_int max_align = 0;
1336    u_int sectnum = 0;
1337
1338    if (!kxld_object_target_supports_common_symbols(object)) {
1339        rval = KERN_SUCCESS;
1340        goto finish;
1341    }
1342
1343    /* Iterate over the common symbols to calculate their total aligned size */
1344    kxld_symtab_iterator_init(&iter, object->symtab, kxld_sym_is_common, FALSE);
1345    while ((sym = kxld_symtab_iterator_get_next(&iter))) {
1346        align = kxld_sym_get_common_align(sym);
1347        size = kxld_sym_get_common_size(sym);
1348
1349        if (align > max_align) max_align = align;
1350
1351        total_size = kxld_align_address(total_size, align) + size;
1352    }
1353
1354    /* If there are common symbols, grow or create the __DATA __common section
1355     * to hold them.
1356     */
1357    if (total_size) {
1358        sect = kxld_object_get_sect_by_name(object, SEG_DATA, SECT_COMMON);
1359        if (sect) {
1360            base_addr = sect->base_addr + sect->size;
1361
1362            kxld_sect_grow(sect, total_size, max_align);
1363        } else {
1364            base_addr = 0;
1365
1366            rval = add_section(object, &sect);
1367            require_noerr(rval, finish);
1368
1369            kxld_sect_init_zerofill(sect, SEG_DATA, SECT_COMMON,
1370                total_size, max_align);
1371        }
1372
1373        /* Resolve the common symbols against the new section */
1374        rval = kxld_array_get_index(&object->sects, sect, &sectnum);
1375        require_noerr(rval, finish);
1376
1377        kxld_symtab_iterator_reset(&iter);
1378        while ((sym = kxld_symtab_iterator_get_next(&iter))) {
1379            align = kxld_sym_get_common_align(sym);
1380            size = kxld_sym_get_common_size(sym);
1381
1382            base_addr = kxld_align_address(base_addr, align);
1383            kxld_sym_resolve_common(sym, sectnum, base_addr);
1384
1385            base_addr += size;
1386        }
1387    }
1388
1389    rval = KERN_SUCCESS;
1390
1391finish:
1392    return rval;
1393}
1394#endif /* KXLD_USER_OR_COMMON */
1395
1396#if KXLD_USER_OR_GOT
1397/*******************************************************************************
1398*******************************************************************************/
1399static boolean_t
1400target_has_got(const KXLDObject *object)
1401{
1402    return FALSE:
1403}
1404
1405/*******************************************************************************
1406* Create and initialize the Global Offset Table
1407*******************************************************************************/
1408static kern_return_t
1409create_got(KXLDObject *object)
1410{
1411    kern_return_t rval = KERN_FAILURE;
1412    KXLDSect *sect = NULL;
1413    u_int ngots = 0;
1414    u_int i = 0;
1415
1416    if (!target_has_got(object)) {
1417        rval = KERN_SUCCESS;
1418        goto finish;
1419    }
1420
1421    for (i = 0; i < object->sects.nitems; ++i) {
1422        sect = kxld_array_get_item(&object->sects, i);
1423        ngots += kxld_sect_get_ngots(sect, &object->relocator,
1424            object->symtab);
1425    }
1426
1427    rval = add_section(object, &sect);
1428    require_noerr(rval, finish);
1429
1430    rval = kxld_sect_init_got(sect, ngots);
1431    require_noerr(rval, finish);
1432
1433    object->got_is_created = TRUE;
1434    rval = KERN_SUCCESS;
1435
1436finish:
1437    return rval;
1438}
1439
1440/*******************************************************************************
1441*******************************************************************************/
1442static kern_return_t
1443populate_got(KXLDObject *object)
1444{
1445    kern_return_t rval = KERN_FAILURE;
1446    KXLDSect *sect = NULL;
1447    u_int i = 0;
1448
1449    if (!target_has_got(object) || !object->got_is_created) {
1450        rval = KERN_SUCCESS;
1451        goto finish;
1452    }
1453
1454    for (i = 0; i < object->sects.nitems; ++i) {
1455        sect = kxld_array_get_item(&object->sects, i);
1456        if (streq_safe(sect->segname, KXLD_SEG_GOT, sizeof(KXLD_SEG_GOT)) &&
1457            streq_safe(sect->sectname, KXLD_SECT_GOT, sizeof(KXLD_SECT_GOT)))
1458        {
1459            kxld_sect_populate_got(sect, object->symtab,
1460                kxld_object_target_needs_swap(object));
1461            break;
1462        }
1463    }
1464
1465    require_action(i < object->sects.nitems, finish, rval=KXLD_MISSING_GOT);
1466
1467    rval = KERN_SUCCESS;
1468
1469finish:
1470    return rval;
1471}
1472#endif /* KXLD_USER_OR_GOT */
1473
1474/*******************************************************************************
1475*******************************************************************************/
1476static boolean_t
1477target_supports_protected_segments(const KXLDObject *object)
1478{
1479    return (object->is_final_image &&
1480            (object->cputype == CPU_TYPE_X86_64 ||
1481             object->cputype == CPU_TYPE_ARM));
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) {
1497        object->is_linked = !object->extrelocs.nitems;
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);
1544    kxld_versionmin_clear(&object->versionmin);
1545    kxld_srcversion_clear(&object->srcversion);
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
1674    return (object->cputype != CPU_TYPE_I386);
1675}
1676
1677/*******************************************************************************
1678*******************************************************************************/
1679boolean_t
1680kxld_object_target_supports_common_symbols(const KXLDObject *object)
1681{
1682    check(object);
1683
1684    return (object->cputype == CPU_TYPE_I386);
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
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
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;
1730    boolean_t   is_32bit_object = kxld_object_is_32_bit(object);
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);
1739    size = object->output_buffer_size;
1740
1741    /* Copy data to the file */
1742
1743    ncmds = object->segs.nitems + 1 /* LC_SYMTAB */;
1744
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);
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
1771        rval = kxld_seg_export_macho_to_vm(seg, linked_object, &header_offset,
1772            header_size, size, object->link_addr, is_32bit_object);
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);
1778
1779    rval = kxld_symtab_export_macho(object->symtab, linked_object, &header_offset,
1780        header_size, &data_offset, size, is_32bit_object);
1781    require_noerr(rval, finish);
1782
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
1792    if (object->uuid.has_uuid) {
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);
1799        require_noerr(rval, finish);
1800    }
1801
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
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);
1856    mach = (struct mach_header *) ((void *) (buf + *header_offset));
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);
1891    mach = (struct mach_header_64 *) ((void *) (buf + *header_offset));
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);
2115    if (!sect || !(sect->flags & S_NON_LAZY_SYMBOL_POINTERS)) {
2116        rval = KERN_SUCCESS;
2117        goto finish;
2118    }
2119
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;
2133        kxld_log(kKxldLogLinking, kKxldLogErr, kKxldLogMalformedMachO
2134            "firstsym + nsyms > object->dysymtab_hdr->nindirectsyms"));
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
2146    symidx = (int32_t *) ((void *) (object->file + object->dysymtab_hdr->indirectsymoff));
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) {
2233        uint32_t *ptr = (uint32_t *) ((void *) symptr);
2234        *ptr += (uint32_t) val;
2235    } else {
2236        uint64_t *ptr = (uint64_t *) ((void *) symptr);
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);
2291    kmod_info = (kmod_info_t *) ((void *) (kmodsect->data + kmod_offset));
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
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 && object->include_kaslr_relocs);
2337}
2338#endif  /* KXLD_PIC_KEXTS */
2339