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, §_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, §_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(§->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, §); 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, §num); 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, §); 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