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