1/* 2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_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. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23/* 24 * The lipo(1) program. This program creates, thins and operates on fat files. 25 * This program takes the following options: 26 * <input_file> 27 * -output <filename> 28 * -create 29 * -info 30 * -detailed_info 31 * -arch <arch_type> <input_file> 32 * -arch_blank <arch_type> 33 * -thin <arch_type> 34 * -extract <arch_type> 35 * -remove <arch_type> 36 * -replace <arch_type> <file_name> 37 * -segalign <arch_type> <value> 38 * -verify_arch <arch_type> ... 39 */ 40#include <stdio.h> 41#include <string.h> 42#include <stdlib.h> 43#include <ar.h> 44#ifndef AR_EFMT1 45#define AR_EFMT1 "#1/" /* extended format #1 */ 46#endif 47#include <limits.h> 48#include <errno.h> 49#include <ctype.h> 50#include <libc.h> 51#ifndef __OPENSTEP__ 52#include <utime.h> 53#endif 54#include <sys/file.h> 55#include <sys/types.h> 56#include <sys/stat.h> 57#include <sys/mman.h> 58#include <mach/mach.h> 59#include <mach-o/loader.h> 60#include <mach-o/fat.h> 61#include "stuff/arch.h" 62#include "stuff/errors.h" 63#include "stuff/allocate.h" 64#include "stuff/lto.h" 65 66/* The maximum section alignment allowed to be specified, as a power of two */ 67#define MAXSECTALIGN 15 /* 2**15 or 0x8000 */ 68 69/* These #undef's are because of the #define's in <mach.h> */ 70#undef TRUE 71#undef FALSE 72 73/* name of the program for error messages (argv[0]) */ 74char *progname = NULL; 75 76/* names and types (if any) of input file specified on the commmand line */ 77struct input_file { 78 char *name; 79 struct arch_flag arch_flag; 80 struct fat_header *fat_header; 81 struct fat_arch *fat_arches; 82 enum bool is_thin; 83}; 84static struct input_file *input_files = NULL; 85static uint32_t ninput_files = 0; 86 87/* Thin files from the input files to operate on */ 88struct thin_file { 89 char *name; 90 char *addr; 91 struct fat_arch fat_arch; 92 enum bool from_fat; 93 enum bool extract; 94 enum bool remove; 95 enum bool replace; 96}; 97static struct thin_file *thin_files = NULL; 98static uint32_t nthin_files = 0; 99 100/* The specified output file */ 101static char *output_file = NULL; 102static uint32_t output_filemode = 0; 103#ifndef __OPENSTEP__ 104static struct utimbuf output_timep = { 0 }; 105#else 106static time_t output_timep[2] = { 0 }; 107#endif 108static enum bool archives_in_input = FALSE; 109 110/* flags set from command line arguments to specify the operation */ 111static enum bool create_flag = FALSE; 112static enum bool info_flag = FALSE; 113static enum bool detailed_info_flag = FALSE; 114 115static enum bool thin_flag = FALSE; 116static struct arch_flag thin_arch_flag = { 0 }; 117 118static enum bool remove_flag = FALSE; 119static struct arch_flag *remove_arch_flags = NULL; 120static uint32_t nremove_arch_flags = 0; 121 122static enum bool extract_flag = FALSE; 123static struct arch_flag *extract_arch_flags = NULL; 124static uint32_t nextract_arch_flags = 0; 125static enum bool extract_family_flag = FALSE; 126 127static enum bool replace_flag = FALSE; 128struct replace { 129 struct arch_flag arch_flag; 130 struct thin_file thin_file; 131}; 132static struct replace *replaces = NULL; 133static uint32_t nreplaces = 0; 134 135struct segalign { 136 struct arch_flag arch_flag; 137 uint32_t align; 138}; 139static struct segalign *segaligns = NULL; 140static uint32_t nsegaligns = 0; 141 142static enum bool arch_blank_flag = FALSE; 143 144static struct fat_header fat_header = { 0 }; 145 146static enum bool verify_flag = FALSE; 147static struct arch_flag *verify_archs = NULL; 148static uint32_t nverify_archs = 0; 149 150static void create_fat( 151 void); 152static void process_input_file( 153 struct input_file *input); 154static void process_replace_file( 155 struct replace *replace); 156static void check_archive( 157 char *name, 158 char *addr, 159 uint32_t size, 160 cpu_type_t *cputype, 161 cpu_subtype_t *cpusubtype); 162static void check_extend_format_1( 163 char *name, 164 struct ar_hdr *ar_hdr, 165 uint32_t size_left, 166 uint32_t *member_name_size); 167static uint32_t get_align( 168 struct mach_header *mhp, 169 struct load_command *load_commands, 170 uint32_t size, 171 char *name, 172 enum bool swapped); 173static uint32_t get_align_64( 174 struct mach_header_64 *mhp64, 175 struct load_command *load_commands, 176 uint32_t size, 177 char *name, 178 enum bool swapped); 179static uint32_t guess_align( 180 uint32_t vmaddr); 181static void print_arch( 182 struct fat_arch *fat_arch); 183static void print_cputype( 184 cpu_type_t cputype, 185 cpu_subtype_t cpusubtype); 186static int size_ar_name( 187 char *ar_name); 188static struct input_file *new_input( 189 void); 190static struct thin_file *new_thin( 191 void); 192static struct arch_flag *new_arch_flag( 193 struct arch_flag **arch_flags, 194 uint32_t *narch_flags); 195static struct replace *new_replace( 196 void); 197static struct segalign *new_segalign( 198 void); 199static int cmp_qsort( 200 const struct thin_file *thin1, 201 const struct thin_file *thin2); 202static uint32_t rnd( 203 uint32_t v, 204 uint32_t r); 205static enum bool ispoweroftwo( 206 uint32_t x); 207static void check_arch( 208 struct input_file *input, 209 struct thin_file *thin); 210static void usage( 211 void); 212static struct thin_file *new_blank_dylib( 213 struct arch_flag *arch); 214 215/* apple_version is created by the libstuff/Makefile */ 216extern char apple_version[]; 217char *version = apple_version; 218 219int 220main( 221int argc, 222char *argv[], 223char *envp[]) 224{ 225 int fd, a; 226 uint32_t i, j, k, value; 227 char *p, *endp; 228 struct input_file *input; 229 struct arch_flag *arch_flag; 230 struct replace *replace; 231 struct segalign *segalign; 232 const struct arch_flag *arch_flags; 233 enum bool found; 234 struct arch_flag blank_arch; 235 236 input = NULL; 237 /* 238 * Process the command line arguments. 239 */ 240 progname = argv[0]; 241 for(a = 1; a < argc; a++){ 242 if(argv[a][0] == '-'){ 243 p = &(argv[a][1]); 244 switch(*p){ 245 case 'a': 246 if(strcmp(p, "arch") == 0 || strcmp(p, "a") == 0){ 247 if(a + 2 >= argc){ 248 error("missing argument(s) to %s option", argv[a]); 249 usage(); 250 } 251 input = new_input(); 252 if(get_arch_from_flag(argv[a+1], 253 &(input->arch_flag)) == 0){ 254 error("unknown architecture specification flag: %s " 255 "in specifying input file %s %s %s", argv[a+1], 256 argv[a], argv[a+1], argv[a+2]); 257 arch_usage(); 258 usage(); 259 } 260 input->name = argv[a+2]; 261 a += 2; 262 } 263 else if(strcmp(p, "arch_blank") == 0){ 264 arch_blank_flag = TRUE; 265 if(a + 1 >= argc){ 266 error("missing argument(s) to %s option", argv[a]); 267 usage(); 268 } 269 if(get_arch_from_flag(argv[a+1], &blank_arch) == 0){ 270 error("unknown architecture specification flag: %s " 271 "in specifying input file %s %s", argv[a+1], 272 argv[a], argv[a+1]); 273 arch_usage(); 274 usage(); 275 } 276 new_blank_dylib(&blank_arch); 277 a += 1; 278 } 279 else 280 goto unknown_flag; 281 break; 282 case 'c': 283 if(strcmp(p, "create") == 0 || strcmp(p, "c") == 0){ 284 create_flag = TRUE; 285 } 286 else 287 goto unknown_flag; 288 break; 289 case 'd': 290 if(strcmp(p, "detailed_info") == 0 || strcmp(p, "d") == 0){ 291 detailed_info_flag = TRUE; 292 } 293 else 294 goto unknown_flag; 295 break; 296 case 'e': 297 if(strcmp(p, "extract") == 0 || 298 strcmp(p, "extract_family") == 0 || 299 strcmp(p, "e") == 0){ 300 extract_flag = TRUE; 301 if(strcmp(p, "extract_family") == 0) 302 extract_family_flag = TRUE; 303 if(a + 1 >= argc){ 304 error("missing argument to %s option", argv[a]); 305 usage(); 306 } 307 arch_flag = new_arch_flag(&extract_arch_flags, 308 &nextract_arch_flags); 309 if(get_arch_from_flag(argv[a+1], arch_flag) == 0){ 310 error("unknown architecture specification flag: " 311 "%s in specifying extract operation: %s %s", 312 argv[a+1], argv[a], argv[a+1]); 313 arch_usage(); 314 usage(); 315 } 316 a++; 317 } 318 else 319 goto unknown_flag; 320 break; 321 case 'i': 322 if(strcmp(p, "info") == 0 || strcmp(p, "i") == 0){ 323 info_flag = TRUE; 324 } 325 else 326 goto unknown_flag; 327 break; 328 case 'o': 329 if(strcmp(p, "output") == 0 || strcmp(p, "o") == 0){ 330 if(a + 1 >= argc){ 331 error("missing argument to %s option", argv[a]); 332 usage(); 333 } 334 if(output_file != NULL) 335 fatal("more than one %s option specified", argv[a]); 336 output_file = argv[a + 1]; 337 a++; 338 } 339 else 340 goto unknown_flag; 341 break; 342 case 'r': 343 if(strcmp(p, "remove") == 0 || strcmp(p, "rem") == 0){ 344 remove_flag = TRUE; 345 if(a + 1 >= argc){ 346 error("missing argument to %s option", argv[a]); 347 usage(); 348 } 349 arch_flag = new_arch_flag(&remove_arch_flags, 350 &nremove_arch_flags); 351 if(get_arch_from_flag(argv[a+1], arch_flag) == 0){ 352 error("unknown architecture specification flag: " 353 "%s in specifying remove operation: %s %s", 354 argv[a+1], argv[a], argv[a+1]); 355 arch_usage(); 356 usage(); 357 } 358 a++; 359 } 360 else if(strcmp(p, "replace") == 0 || strcmp(p, "rep") == 0){ 361 replace_flag = TRUE; 362 if(a + 2 >= argc){ 363 error("missing argument(s) to %s option", argv[a]); 364 usage(); 365 } 366 replace = new_replace(); 367 if(get_arch_from_flag(argv[a+1], 368 &(replace->arch_flag)) == 0){ 369 error("unknown architecture specification flag: " 370 "%s in specifying replace operation: %s %s %s", 371 argv[a+1], argv[a], argv[a+1], argv[a+2]); 372 arch_usage(); 373 usage(); 374 } 375 replace->thin_file.name = argv[a+2]; 376 a += 2; 377 } 378 else 379 goto unknown_flag; 380 break; 381 case 's': 382 if(strcmp(p, "segalign") == 0 || strcmp(p, "s") == 0){ 383 if(a + 2 >= argc){ 384 error("missing argument(s) to %s option", argv[a]); 385 usage(); 386 } 387 segalign = new_segalign(); 388 if(get_arch_from_flag(argv[a+1], 389 &(segalign->arch_flag)) == 0){ 390 error("unknown architecture specification flag: " 391 "%s in specifying segment alignment: %s %s %s", 392 argv[a+1], argv[a], argv[a+1], argv[a+2]); 393 arch_usage(); 394 usage(); 395 } 396 value = strtoul(argv[a+2], &endp, 16); 397 if(*endp != '\0') 398 fatal("argument for -segalign <arch_type> %s not a " 399 "proper hexadecimal number", argv[a+2]); 400 if(!ispoweroftwo(value) || value == 0) 401 fatal("argument to -segalign <arch_type> %x (hex) " 402 "must be a non-zero power of two", value); 403 if(value > (1 << MAXSECTALIGN)) 404 fatal("argument to -segalign <arch_type> %x (hex) " 405 "must equal to or less than %x (hex)", 406 value, (unsigned int)(1 << MAXSECTALIGN)); 407 segalign->align = 0; 408 while((value & 0x1) != 1){ 409 value >>= 1; 410 segalign->align++; 411 } 412 a += 2; 413 } 414 else 415 goto unknown_flag; 416 break; 417 case 't': 418 if(strcmp(p, "thin") == 0 || strcmp(p, "t") == 0){ 419 if(thin_flag == TRUE) 420 fatal("more than one %s option specified", argv[a]); 421 thin_flag = TRUE; 422 if(a + 1 >= argc){ 423 error("missing argument to %s option", argv[a]); 424 usage(); 425 } 426 if(get_arch_from_flag(argv[a+1], &thin_arch_flag) == 0){ 427 error("unknown architecture specification flag: " 428 "%s in specifying thin operation: %s %s", 429 argv[a+1], argv[a], argv[a+1]); 430 arch_usage(); 431 usage(); 432 } 433 a++; 434 } 435 else 436 goto unknown_flag; 437 break; 438 case 'v': 439 if(strcmp(p, "verify_arch") == 0){ 440 verify_flag = TRUE; 441 if(a + 1 >= argc){ 442 error("missing argument(s) to %s option", argv[a]); 443 usage(); 444 } 445 a++; 446 nverify_archs = argc - a; 447 verify_archs = (struct arch_flag *)allocate( 448 sizeof(struct arch_flag) * nverify_archs); 449 for(i = 0; a < argc; a++, i++){ 450 if(get_arch_from_flag(argv[a], 451 verify_archs + i) == 0){ 452 error("unknown architecture specification " 453 "flag: %s in specifying -verify_arch " 454 "operation", argv[a]); 455 arch_usage(); 456 usage(); 457 } 458 } 459 } 460 else 461 goto unknown_flag; 462 break; 463 default: 464unknown_flag: 465 fatal("unknown flag: %s", argv[a]); 466 } 467 } 468 else{ 469 input = new_input(); 470 input->name = argv[a]; 471 } 472 } 473 474 /* 475 * Check to see the specified arguments are valid. 476 */ 477 if(info_flag == FALSE && detailed_info_flag == FALSE && 478 create_flag == FALSE && thin_flag == FALSE && 479 extract_flag == FALSE && remove_flag == FALSE && 480 replace_flag == FALSE && verify_flag == FALSE){ 481 error("one of -create, -thin <arch_type>, -extract <arch_type>, " 482 "-remove <arch_type>, -replace <arch_type> <file_name>, " 483 "-verify_arch <arch_type> ... , " 484 "-info or -detailed_info must be specified"); 485 usage(); 486 } 487 if((create_flag == TRUE || thin_flag == TRUE || extract_flag == TRUE || 488 remove_flag == TRUE || replace_flag == TRUE) && 489 output_file == NULL){ 490 error("no output file specified"); 491 usage(); 492 } 493 if(ninput_files == 0){ 494 error("no input files specified"); 495 usage(); 496 } 497 if(verify_flag == TRUE && ninput_files != 1){ 498 error("only one input file allowed with -verify_arch"); 499 usage(); 500 } 501 if(create_flag + thin_flag + extract_flag + remove_flag + replace_flag + 502 info_flag + detailed_info_flag + verify_flag > 1){ 503 error("only one of -create, -thin <arch_type>, -extract <arch_type>" 504 ", -remove <arch_type>, -replace <arch_type> <file_name>, " 505 "-verify_arch <arch_type> ..., " 506 "-info or -detailed_info can be specified"); 507 usage(); 508 } 509 if(arch_blank_flag == TRUE && create_flag == FALSE){ 510 error("-arch_blank may only be used with -create"); 511 usage(); 512 } 513 514 /* 515 * Determine the types of the input files. 516 */ 517 for(i = 0; i < ninput_files; i++) 518 process_input_file(input_files + i); 519 520 /* 521 * Do the specified operation. 522 */ 523 524 if(create_flag){ 525 /* check to make sure no two files have the same architectures */ 526 for(i = 0; i < nthin_files; i++) 527 for(j = i + 1; j < nthin_files; j++) 528 if(thin_files[i].fat_arch.cputype == 529 thin_files[j].fat_arch.cputype && 530 (thin_files[i].fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK)== 531 (thin_files[j].fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK)){ 532 arch_flags = get_arch_flags(); 533 for(k = 0; arch_flags[k].name != NULL; k++){ 534 if(arch_flags[k].cputype == 535 thin_files[j].fat_arch.cputype && 536 (arch_flags[k].cpusubtype & 537 ~CPU_SUBTYPE_MASK) == 538 (thin_files[j].fat_arch.cpusubtype & 539 ~CPU_SUBTYPE_MASK)) 540 fatal("%s and %s have the same architectures (%s) " 541 "and can't be in the same fat output file", 542 thin_files[i].name, thin_files[j].name, 543 arch_flags[k].name); 544 } 545 fatal("%s and %s have the same architectures (cputype " 546 "(%d) and cpusubtype (%d)) and can't be in the " 547 "same fat output file", thin_files[i].name, 548 thin_files[j].name,thin_files[i].fat_arch.cputype, 549 thin_files[i].fat_arch.cpusubtype & 550 ~CPU_SUBTYPE_MASK); 551 } 552 create_fat(); 553 } 554 555 if(thin_flag){ 556 if(ninput_files != 1) 557 fatal("only one input file can be specified with the -thin " 558 "option"); 559 if(input_files[0].fat_header == NULL) 560 fatal("input file (%s) must be a fat file when the -thin " 561 "option is specified", input_files[0].name); 562 for(i = 0; i < nthin_files; i++){ 563 if(thin_files[i].fat_arch.cputype == thin_arch_flag.cputype && 564 (thin_files[i].fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK) == 565 (thin_arch_flag.cpusubtype & ~CPU_SUBTYPE_MASK)){ 566 (void)unlink(output_file); 567 if((fd = open(output_file, O_WRONLY | O_CREAT | O_TRUNC, 568 output_filemode)) == -1) 569 system_fatal("can't create output file: %s", 570 output_file); 571 572 if(write(fd, thin_files[i].addr,thin_files[i].fat_arch.size) 573 != (int)(thin_files[i].fat_arch.size)) 574 system_fatal("can't write thin file to output file: %s", 575 output_file); 576 if(close(fd) == -1) 577 system_fatal("can't close output file: %s",output_file); 578 if(utime(output_file, 579#ifndef __OPENSTEP__ 580 &output_timep) == -1) 581#else 582 output_timep) == -1) 583#endif 584 system_fatal("can't set the modifiy times for " 585 "output file: %s", output_file); 586 break; 587 } 588 } 589 if(i == nthin_files) 590 fatal("fat input file (%s) does not contain the specified " 591 "architecture (%s) to thin it to", input->name, 592 thin_arch_flag.name); 593 } 594 595 if(extract_flag){ 596 if(ninput_files != 1) 597 fatal("only one input file can be specified with the -extract " 598 "option"); 599 if(input_files[0].fat_header == NULL) 600 fatal("input file (%s) must be a fat file when the -extract " 601 "option is specified", input_files[0].name); 602 for(i = 0; i < nextract_arch_flags; i++){ 603 for(j = i + 1; j < nextract_arch_flags; j++){ 604 if(extract_arch_flags[i].cputype == 605 extract_arch_flags[j].cputype && 606 (extract_arch_flags[i].cpusubtype & ~CPU_SUBTYPE_MASK) == 607 (thin_files[j].fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK)) 608 fatal("-extract %s specified multiple times", 609 extract_arch_flags[i].name); 610 } 611 } 612 /* mark those thin files for extraction */ 613 for(i = 0; i < nextract_arch_flags; i++){ 614 found = FALSE; 615 for(j = 0; j < nthin_files; j++){ 616 if(extract_arch_flags[i].cputype == 617 thin_files[j].fat_arch.cputype && 618 ((extract_arch_flags[i].cpusubtype & 619 ~CPU_SUBTYPE_MASK)== 620 (thin_files[j].fat_arch.cpusubtype & 621 ~CPU_SUBTYPE_MASK) || 622 extract_family_flag == TRUE)){ 623 thin_files[j].extract = TRUE; 624 found = TRUE; 625 } 626 } 627 if(found == FALSE) 628 fatal("-extract %s specified but fat file: %s does not " 629 "contain that architecture", 630 extract_arch_flags[i].name, input_files[0].name); 631 } 632 /* remove those thin files not marked for extraction */ 633 for(i = 0; i < nthin_files; ){ 634 if(thin_files[i].extract == FALSE){ 635 for(j = i; j < nthin_files - 1; j++) 636 thin_files[j] = thin_files[j + 1]; 637 nthin_files--; 638 } 639 else 640 i++; 641 } 642 create_fat(); 643 } 644 645 if(remove_flag){ 646 if(ninput_files != 1) 647 fatal("only one input file can be specified with the -remove " 648 "option"); 649 if(input_files[0].fat_header == NULL) 650 fatal("input file (%s) must be a fat file when the -remove " 651 "option is specified", input_files[0].name); 652 for(i = 0; i < nremove_arch_flags; i++){ 653 for(j = i + 1; j < nremove_arch_flags; j++){ 654 if(remove_arch_flags[i].cputype == 655 remove_arch_flags[j].cputype && 656 (remove_arch_flags[i].cpusubtype & ~CPU_SUBTYPE_MASK) == 657 (remove_arch_flags[j].cpusubtype & ~CPU_SUBTYPE_MASK)) 658 fatal("-remove %s specified multiple times", 659 remove_arch_flags[i].name); 660 } 661 } 662 /* mark those thin files for removal */ 663 for(i = 0; i < nremove_arch_flags; i++){ 664 for(j = 0; j < nthin_files; j++){ 665 if(remove_arch_flags[i].cputype == 666 thin_files[j].fat_arch.cputype && 667 (remove_arch_flags[i].cpusubtype & 668 ~CPU_SUBTYPE_MASK) == 669 (thin_files[j].fat_arch.cpusubtype & 670 ~CPU_SUBTYPE_MASK)){ 671 thin_files[j].remove = TRUE; 672 break; 673 } 674 } 675 if(j == nthin_files) 676 fatal("-remove %s specified but fat file: %s does not " 677 "contain that architecture", 678 remove_arch_flags[i].name, input_files[0].name); 679 } 680 /* remove those thin files marked for removal */ 681 for(i = 0; i < nthin_files; ){ 682 if(thin_files[i].remove == TRUE){ 683 for(j = i; j < nthin_files; j++) 684 thin_files[j] = thin_files[j + 1]; 685 nthin_files--; 686 } 687 else 688 i++; 689 } 690 if(nthin_files == 0) 691 fatal("-remove's specified would result in an empty fat file"); 692 create_fat(); 693 } 694 695 if(replace_flag){ 696 if(ninput_files != 1) 697 fatal("only one input file can be specified with the -replace " 698 "option"); 699 if(input_files[0].fat_header == NULL) 700 fatal("input file (%s) must be a fat file when the -replace " 701 "option is specified", input_files[0].name); 702 for(i = 0; i < nreplaces; i++){ 703 for(j = i + 1; j < nreplaces; j++){ 704 if(replaces[i].arch_flag.cputype == 705 replaces[j].arch_flag.cputype && 706 (replaces[i].arch_flag.cpusubtype & ~CPU_SUBTYPE_MASK) == 707 (replaces[j].arch_flag.cpusubtype & ~CPU_SUBTYPE_MASK)) 708 fatal("-replace %s <file_name> specified multiple times", 709 replaces[j].arch_flag.name); 710 } 711 } 712 for(i = 0; i < nreplaces; i++){ 713 process_replace_file(replaces + i); 714 for(j = 0; j < nthin_files; j++){ 715 if(replaces[i].arch_flag.cputype == 716 thin_files[j].fat_arch.cputype && 717 (replaces[i].arch_flag.cpusubtype & ~CPU_SUBTYPE_MASK) == 718 (thin_files[j].fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK)){ 719 thin_files[j] = replaces[i].thin_file; 720 break; 721 } 722 } 723 if(j == nthin_files) 724 fatal("-replace %s <file_name> specified but fat file: %s " 725 "does not contain that architecture", 726 replaces[i].arch_flag.name, input_files[0].name); 727 } 728 create_fat(); 729 } 730 731 if(info_flag){ 732 for(i = 0; i < ninput_files; i++){ 733 if(input_files[i].fat_header != NULL){ 734 printf("Architectures in the fat file: %s are: ", 735 input_files[i].name); 736 for(j = 0; j < input_files[i].fat_header->nfat_arch; j++){ 737 print_arch(&(input_files[i].fat_arches[j])); 738 printf(" "); 739 } 740 printf("\n"); 741 } 742 else{ 743 if(input_files[i].is_thin == FALSE) 744 printf("input file %s is not a fat file\n", 745 input_files[i].name); 746 } 747 } 748 for(i = 0; i < nthin_files; i++){ 749 if(thin_files[i].from_fat == TRUE) 750 continue; 751 printf("Non-fat file: %s is architecture: %s\n", 752 thin_files[i].name, 753 get_arch_name_from_types(thin_files[i].fat_arch.cputype, 754 thin_files[i].fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK)); 755 } 756 } 757 758 if(detailed_info_flag){ 759 for(i = 0; i < ninput_files; i++){ 760 if(input_files[i].fat_header != NULL){ 761 printf("Fat header in: %s\n", input_files[i].name); 762 printf("fat_magic 0x%x\n", 763 (unsigned int)(input_files[i].fat_header->magic)); 764 printf("nfat_arch %u\n", 765 input_files[i].fat_header->nfat_arch); 766 for(j = 0; j < input_files[i].fat_header->nfat_arch; j++){ 767 printf("architecture "); 768 print_arch(&(input_files[i].fat_arches[j])); 769 printf("\n"); 770 print_cputype(input_files[i].fat_arches[j].cputype, 771 input_files[i].fat_arches[j].cpusubtype & 772 ~CPU_SUBTYPE_MASK); 773 printf(" offset %u\n", 774 input_files[i].fat_arches[j].offset); 775 printf(" size %u\n", 776 input_files[i].fat_arches[j].size); 777 printf(" align 2^%u (%d)\n", 778 input_files[i].fat_arches[j].align, 779 1 << input_files[i].fat_arches[j].align); 780 } 781 } 782 else{ 783 printf("input file %s is not a fat file\n", 784 input_files[i].name); 785 } 786 } 787 for(i = 0; i < nthin_files; i++){ 788 if(thin_files[i].from_fat == TRUE) 789 continue; 790 printf("Non-fat file: %s is architecture: %s\n", 791 thin_files[i].name, 792 get_arch_name_from_types(thin_files[i].fat_arch.cputype, 793 thin_files[i].fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK)); 794 } 795 } 796 797 if(verify_flag == TRUE){ 798 for(i = 0; i < nverify_archs; i++){ 799 found = FALSE; 800 for(j = 0; j < nthin_files; j++){ 801 if(verify_archs[i].cputype == 802 thin_files[j].fat_arch.cputype && 803 (verify_archs[i].cpusubtype & ~CPU_SUBTYPE_MASK) == 804 (thin_files[j].fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK)){ 805 found = TRUE; 806 break; 807 } 808 } 809 if(found == FALSE) 810 exit(1); 811 } 812 } 813 814 return(0); 815} 816 817/* 818 * create_fat() creates a fat output file from the thin files. 819 */ 820static 821void 822create_fat(void) 823{ 824 uint32_t i, j, offset; 825 char *rename_file; 826 int fd; 827 828 /* fold in specified segment alignments */ 829 for(i = 0; i < nsegaligns; i++){ 830 for(j = i + 1; j < nsegaligns; j++){ 831 if(segaligns[i].arch_flag.cputype == 832 segaligns[j].arch_flag.cputype && 833 (segaligns[i].arch_flag.cpusubtype & ~CPU_SUBTYPE_MASK) == 834 (segaligns[j].arch_flag.cpusubtype & ~CPU_SUBTYPE_MASK)) 835 fatal("-segalign %s <value> specified multiple times", 836 segaligns[j].arch_flag.name); 837 } 838 } 839 for(i = 0; i < nsegaligns; i++){ 840 for(j = 0; j < nthin_files; j++){ 841 if(segaligns[i].arch_flag.cputype == 842 thin_files[j].fat_arch.cputype && 843 (segaligns[i].arch_flag.cpusubtype & ~CPU_SUBTYPE_MASK) == 844 (thin_files[j].fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK)){ 845/* 846 Since this program has to guess at alignments and guesses high when unsure this 847 check shouldn't be used so the the correct alignment can be specified by the 848 the user. 849 if(thin_files[j].fat_arch.align > segaligns[i].align) 850 fatal("specified segment alignment: %d for " 851 "architecture %s is less than the alignment: %d " 852 "required from the input file", 853 1 << segaligns[i].align, 854 segaligns[i].arch_flag.name, 855 1 << thin_files[j].fat_arch.align); 856*/ 857 thin_files[j].fat_arch.align = segaligns[i].align; 858 break; 859 } 860 } 861 if(j == nthin_files) 862 fatal("-segalign %s <value> specified but resulting fat " 863 "file does not contain that architecture", 864 segaligns[i].arch_flag.name); 865 } 866 867 /* sort the files by alignment to save space in the output file */ 868 qsort(thin_files, nthin_files, sizeof(struct thin_file), 869 (int (*)(const void *, const void *))cmp_qsort); 870 871 /* Fill in the fat header and the fat_arch's offsets. */ 872 fat_header.magic = FAT_MAGIC; 873 fat_header.nfat_arch = nthin_files; 874 offset = sizeof(struct fat_header) + 875 nthin_files * sizeof(struct fat_arch); 876 for(i = 0; i < nthin_files; i++){ 877 offset = rnd(offset, 1 << thin_files[i].fat_arch.align); 878 thin_files[i].fat_arch.offset = offset; 879 offset += thin_files[i].fat_arch.size; 880 } 881 882 rename_file = makestr(output_file, ".lipo", NULL); 883 if((fd = open(rename_file, O_WRONLY | O_CREAT | O_TRUNC, 884 output_filemode)) == -1) 885 system_fatal("can't create temporary output file: %s", rename_file); 886 887 /* 888 * If this is an extract_family_flag operation and the is just one 889 * thin file on the list don't create a fat file. 890 */ 891 if(extract_family_flag != TRUE || nthin_files != 1){ 892#ifdef __LITTLE_ENDIAN__ 893 swap_fat_header(&fat_header, BIG_ENDIAN_BYTE_SEX); 894#endif /* __LITTLE_ENDIAN__ */ 895 if(write(fd, &fat_header, sizeof(struct fat_header)) != 896 sizeof(struct fat_header)) 897 system_fatal("can't write fat header to output file: %s", 898 rename_file); 899#ifdef __LITTLE_ENDIAN__ 900 swap_fat_header(&fat_header, LITTLE_ENDIAN_BYTE_SEX); 901#endif /* __LITTLE_ENDIAN__ */ 902 for(i = 0; i < nthin_files; i++){ 903#ifdef __LITTLE_ENDIAN__ 904 swap_fat_arch(&(thin_files[i].fat_arch), 1,BIG_ENDIAN_BYTE_SEX); 905#endif /* __LITTLE_ENDIAN__ */ 906 if(write(fd, &(thin_files[i].fat_arch), 907 sizeof(struct fat_arch)) != sizeof(struct fat_arch)) 908 system_fatal("can't write fat arch to output file: %s", 909 rename_file); 910#ifdef __LITTLE_ENDIAN__ 911 swap_fat_arch(&(thin_files[i].fat_arch), 1, 912 LITTLE_ENDIAN_BYTE_SEX); 913 #endif /* __LITTLE_ENDIAN__ */ 914 } 915 } 916 for(i = 0; i < nthin_files; i++){ 917 if(extract_family_flag == FALSE || nthin_files > 1) 918 if(lseek(fd, thin_files[i].fat_arch.offset, L_SET) == -1) 919 system_fatal("can't lseek in output file: %s", rename_file); 920 if(write(fd, thin_files[i].addr, thin_files[i].fat_arch.size) 921 != (int)(thin_files[i].fat_arch.size)) 922 system_fatal("can't write to output file: %s", rename_file); 923 } 924 if(close(fd) == -1) 925 system_fatal("can't close output file: %s", rename_file); 926 if(rename(rename_file, output_file) == -1) 927 system_error("can't move temporary file: %s to file: %s", 928 output_file, rename_file); 929 free(rename_file); 930} 931 932/* 933 * process_input_file() checks input file and breaks it down into thin files 934 * for later operations. 935 */ 936static 937void 938process_input_file( 939struct input_file *input) 940{ 941 int fd; 942 struct stat stat_buf, stat_buf2; 943 uint32_t size, i, j; 944 char *addr; 945 struct thin_file *thin; 946 struct mach_header *mhp, mh; 947 struct mach_header_64 *mhp64, mh64; 948 struct load_command *lcp; 949 cpu_type_t cputype; 950 cpu_subtype_t cpusubtype; 951 enum bool swapped; 952 uint64_t big_size; 953 954 /* Open the input file and map it in */ 955 if((fd = open(input->name, O_RDONLY)) == -1) 956 system_fatal("can't open input file: %s", input->name); 957 if(fstat(fd, &stat_buf) == -1) 958 system_fatal("Can't stat input file: %s", input->name); 959 size = stat_buf.st_size; 960 /* pick up set uid, set gid and sticky text bits */ 961 output_filemode = stat_buf.st_mode & 07777; 962 /* 963 * Select the eariliest modifiy time so that if the output file 964 * contains archives with table of contents lipo will not make them 965 * out of date. This logic however could make an out of date table of 966 * contents appear up todate if another file is combined with it that 967 * has a date early enough. 968 */ 969#ifndef __OPENSTEP__ 970 if(output_timep.modtime == 0 || 971 output_timep.modtime > stat_buf.st_mtime){ 972 output_timep.actime = stat_buf.st_atime; 973 output_timep.modtime = stat_buf.st_mtime; 974 } 975#else 976 if(output_timep[1] == 0 || output_timep[1] > stat_buf.st_mtime){ 977 output_timep[0] = stat_buf.st_atime; 978 output_timep[1] = stat_buf.st_mtime; 979 } 980#endif 981 /* 982 * mmap() can't handle mapping regular files with zero size. So this 983 * is handled separately. 984 */ 985 if((stat_buf.st_mode & S_IFREG) == S_IFREG && size == 0) 986 addr = NULL; 987 else 988 addr = mmap(0, size, PROT_READ|PROT_WRITE, MAP_FILE|MAP_PRIVATE, 989 fd, 0); 990 if((intptr_t)addr == -1) 991 system_fatal("Can't map input file: %s", input->name); 992 993 /* 994 * Because of rdar://8087586 we do a second stat to see if the file 995 * is still there and the same file. 996 */ 997 if(fstat(fd, &stat_buf2) == -1) 998 system_fatal("Can't stat input file: %s", input->name); 999 if(stat_buf2.st_size != size || 1000 stat_buf2.st_mtime != stat_buf.st_mtime) 1001 system_fatal("Input file: %s changed since opened", input->name); 1002 1003 close(fd); 1004 1005 /* Try to figure out what kind of file this is */ 1006 1007 /* see if this file is a fat file */ 1008 if(size >= sizeof(struct fat_header) && 1009#ifdef __BIG_ENDIAN__ 1010 *((uint32_t *)addr) == FAT_MAGIC) 1011#endif /* __BIG_ENDIAN__ */ 1012#ifdef __LITTLE_ENDIAN__ 1013 *((uint32_t *)addr) == SWAP_INT(FAT_MAGIC)) 1014#endif /* __LITTLE_ENDIAN__ */ 1015 { 1016 1017 if(input->arch_flag.name != NULL) 1018 fatal("architecture specifed for fat input file: %s " 1019 "(architectures can't be specifed for fat input files)", 1020 input->name); 1021 1022 input->fat_header = (struct fat_header *)addr; 1023#ifdef __LITTLE_ENDIAN__ 1024 swap_fat_header(input->fat_header, LITTLE_ENDIAN_BYTE_SEX); 1025#endif /* __LITTLE_ENDIAN__ */ 1026 big_size = input->fat_header->nfat_arch; 1027 big_size *= sizeof(struct fat_arch); 1028 big_size += sizeof(struct fat_header); 1029 if(big_size > size) 1030 fatal("truncated or malformed fat file (fat_arch structs would " 1031 "extend past the end of the file) %s", input->name); 1032 input->fat_arches = (struct fat_arch *)(addr + 1033 sizeof(struct fat_header)); 1034#ifdef __LITTLE_ENDIAN__ 1035 swap_fat_arch(input->fat_arches, input->fat_header->nfat_arch, 1036 LITTLE_ENDIAN_BYTE_SEX); 1037#endif /* __LITTLE_ENDIAN__ */ 1038 for(i = 0; i < input->fat_header->nfat_arch; i++){ 1039 if(input->fat_arches[i].offset + input->fat_arches[i].size > 1040 size) 1041 fatal("truncated or malformed fat file (offset plus size " 1042 "of cputype (%d) cpusubtype (%d) extends past the " 1043 "end of the file) %s", input->fat_arches[i].cputype, 1044 input->fat_arches[i].cpusubtype & ~CPU_SUBTYPE_MASK, 1045 input->name); 1046 if(input->fat_arches[i].align > MAXSECTALIGN) 1047 fatal("align (2^%u) too large of fat file %s (cputype (%d)" 1048 " cpusubtype (%d)) (maximum 2^%d)", 1049 input->fat_arches[i].align, input->name, 1050 input->fat_arches[i].cputype, 1051 input->fat_arches[i].cpusubtype & ~CPU_SUBTYPE_MASK, 1052 MAXSECTALIGN); 1053 if(input->fat_arches[i].offset % 1054 (1 << input->fat_arches[i].align) != 0) 1055 fatal("offset %u of fat file %s (cputype (%d) cpusubtype " 1056 "(%d)) not aligned on its alignment (2^%u)", 1057 input->fat_arches[i].offset, input->name, 1058 input->fat_arches[i].cputype, 1059 input->fat_arches[i].cpusubtype & ~CPU_SUBTYPE_MASK, 1060 input->fat_arches[i].align); 1061 } 1062 for(i = 0; i < input->fat_header->nfat_arch; i++){ 1063 for(j = i + 1; j < input->fat_header->nfat_arch; j++){ 1064 if(input->fat_arches[i].cputype == 1065 input->fat_arches[j].cputype && 1066 (input->fat_arches[i].cpusubtype & ~CPU_SUBTYPE_MASK) == 1067 (input->fat_arches[j].cpusubtype & ~CPU_SUBTYPE_MASK)) 1068 fatal("fat file %s contains two of the same architecture " 1069 "(cputype (%d) cpusubtype (%d))", input->name, 1070 input->fat_arches[i].cputype, 1071 input->fat_arches[i].cpusubtype & ~CPU_SUBTYPE_MASK); 1072 } 1073 } 1074 1075 /* create a thin file struct for each arch in the fat file */ 1076 for(i = 0; i < input->fat_header->nfat_arch; i++){ 1077 thin = new_thin(); 1078 thin->name = input->name; 1079 thin->addr = addr + input->fat_arches[i].offset; 1080 thin->fat_arch = input->fat_arches[i]; 1081 thin->from_fat = TRUE; 1082 if(input->fat_arches[i].size >= SARMAG && 1083 strncmp(thin->addr, ARMAG, SARMAG) == 0) 1084 archives_in_input = TRUE; 1085 } 1086 } 1087 /* see if this file is Mach-O file for 32-bit architectures */ 1088 else if(size >= sizeof(struct mach_header) && 1089 (*((uint32_t *)addr) == MH_MAGIC || 1090 *((uint32_t *)addr) == SWAP_INT(MH_MAGIC))){ 1091 1092 /* this is a Mach-O file so create a thin file struct for it */ 1093 thin = new_thin(); 1094 input->is_thin = TRUE; 1095 thin->name = input->name; 1096 thin->addr = addr; 1097 mhp = (struct mach_header *)addr; 1098 lcp = (struct load_command *)((char *)mhp + 1099 sizeof(struct mach_header)); 1100 if(mhp->magic == SWAP_INT(MH_MAGIC)){ 1101 swapped = TRUE; 1102 mh = *mhp; 1103 swap_mach_header(&mh, get_host_byte_sex()); 1104 mhp = &mh; 1105 } 1106 else 1107 swapped = FALSE; 1108 thin->fat_arch.cputype = mhp->cputype; 1109 thin->fat_arch.cpusubtype = mhp->cpusubtype; 1110 thin->fat_arch.offset = 0; 1111 thin->fat_arch.size = size; 1112 thin->fat_arch.align = get_align(mhp, lcp, size, input->name, 1113 swapped); 1114 1115 /* if the arch type is specified make sure it matches the object */ 1116 if(input->arch_flag.name != NULL) 1117 check_arch(input, thin); 1118 } 1119 /* see if this file is Mach-O file for 64-bit architectures */ 1120 else if(size >= sizeof(struct mach_header_64) && 1121 (*((uint32_t *)addr) == MH_MAGIC_64 || 1122 *((uint32_t *)addr) == SWAP_INT(MH_MAGIC_64))){ 1123 1124 /* this is a Mach-O file so create a thin file struct for it */ 1125 thin = new_thin(); 1126 input->is_thin = TRUE; 1127 thin->name = input->name; 1128 thin->addr = addr; 1129 mhp64 = (struct mach_header_64 *)addr; 1130 lcp = (struct load_command *)((char *)mhp64 + 1131 sizeof(struct mach_header_64)); 1132 if(mhp64->magic == SWAP_INT(MH_MAGIC_64)){ 1133 swapped = TRUE; 1134 mh64 = *mhp64; 1135 swap_mach_header_64(&mh64, get_host_byte_sex()); 1136 mhp64 = &mh64; 1137 } 1138 else 1139 swapped = FALSE; 1140 thin->fat_arch.cputype = mhp64->cputype; 1141 thin->fat_arch.cpusubtype = mhp64->cpusubtype; 1142 thin->fat_arch.offset = 0; 1143 thin->fat_arch.size = size; 1144 thin->fat_arch.align = get_align_64(mhp64, lcp, size, input->name, 1145 swapped); 1146 1147 /* if the arch type is specified make sure it matches the object */ 1148 if(input->arch_flag.name != NULL) 1149 check_arch(input, thin); 1150 } 1151 /* see if this file is an archive file */ 1152 else if(size >= SARMAG && strncmp(addr, ARMAG, SARMAG) == 0){ 1153 1154 check_archive(input->name, addr, size, &cputype, &cpusubtype); 1155 archives_in_input = TRUE; 1156 1157 /* create a thin file struct for this archive */ 1158 thin = new_thin(); 1159 thin->name = input->name; 1160 thin->addr = addr; 1161 thin->fat_arch.cputype = cputype; 1162 thin->fat_arch.cpusubtype = cpusubtype; 1163 thin->fat_arch.offset = 0; 1164 thin->fat_arch.size = size; 1165 thin->fat_arch.align = 2; /* 2^2, sizeof(uint32_t) */ 1166 1167 /* if the arch type is specified make sure it matches the object */ 1168 if(input->arch_flag.name != NULL){ 1169 if(cputype == 0){ 1170 thin->fat_arch.cputype = input->arch_flag.cputype; 1171 thin->fat_arch.cpusubtype = input->arch_flag.cpusubtype; 1172 } 1173 else 1174 check_arch(input, thin); 1175 } 1176 else{ 1177 if(cputype == 0) 1178 fatal("archive with no architecture specification: %s " 1179 "(can't determine architecture for it)", input->name); 1180 } 1181 } 1182 /* this file type is now known to be unknown to this program */ 1183 else{ 1184 1185 if(input->arch_flag.name != NULL){ 1186 /* create a thin file struct for it */ 1187 thin = new_thin(); 1188 thin->name = input->name; 1189 thin->addr = addr; 1190 thin->fat_arch.cputype = input->arch_flag.cputype; 1191 thin->fat_arch.cpusubtype = input->arch_flag.cpusubtype; 1192 thin->fat_arch.offset = 0; 1193 thin->fat_arch.size = size; 1194 thin->fat_arch.align = 0; 1195 } 1196 else{ 1197#ifdef LTO_SUPPORT 1198 if(is_llvm_bitcode_from_memory(addr, size, &input->arch_flag, 1199 NULL) != 0){ 1200 /* create a thin file struct for it */ 1201 thin = new_thin(); 1202 thin->name = input->name; 1203 thin->addr = addr; 1204 thin->fat_arch.cputype = input->arch_flag.cputype; 1205 thin->fat_arch.cpusubtype = input->arch_flag.cpusubtype; 1206 thin->fat_arch.offset = 0; 1207 thin->fat_arch.size = size; 1208 thin->fat_arch.align = 0; 1209 } 1210 else 1211#endif /* LTO_SUPPORT */ 1212 fatal("can't figure out the architecture type of: %s", 1213 input->name); 1214 } 1215 } 1216} 1217 1218/* 1219 * process_replace_file() checks the replacement file and maps it in for later 1220 * processing. 1221 */ 1222static 1223void 1224process_replace_file( 1225struct replace *replace) 1226{ 1227 int fd; 1228 struct stat stat_buf; 1229 uint32_t size; 1230 char *addr; 1231 struct mach_header *mhp, mh; 1232 struct mach_header_64 *mhp64, mh64; 1233 struct load_command *lcp; 1234 cpu_type_t cputype; 1235 cpu_subtype_t cpusubtype; 1236 enum bool swapped; 1237 1238 /* Open the replacement file and map it in */ 1239 if((fd = open(replace->thin_file.name, O_RDONLY)) == -1) 1240 system_fatal("can't open replacement file: %s", 1241 replace->thin_file.name); 1242 if(fstat(fd, &stat_buf) == -1) 1243 system_fatal("Can't stat replacement file: %s", 1244 replace->thin_file.name); 1245 size = stat_buf.st_size; 1246 /* 1247 * mmap() can't handle mapping regular files with zero size. So this 1248 * is handled separately. 1249 */ 1250 if((stat_buf.st_mode & S_IFREG) == S_IFREG && size == 0) 1251 addr = NULL; 1252 else 1253 addr = mmap(0, size, PROT_READ|PROT_WRITE, MAP_FILE|MAP_PRIVATE, 1254 fd, 0); 1255 if((intptr_t)addr == -1) 1256 system_error("Can't map replacement file: %s", 1257 replace->thin_file.name); 1258 close(fd); 1259 1260 /* Try to figure out what kind of file this is */ 1261 1262 /* see if this file is a fat file */ 1263 if(size >= sizeof(struct fat_header) && 1264 *((uint32_t *)addr) == FAT_MAGIC){ 1265 1266 fatal("replacement file: %s is a fat file (must be a thin file)", 1267 replace->thin_file.name); 1268 } 1269 /* see if this file is Mach-O file for 32-bit architectures */ 1270 else if(size >= sizeof(struct mach_header) && 1271 (*((uint32_t *)addr) == MH_MAGIC || 1272 *((uint32_t *)addr) == SWAP_INT(MH_MAGIC))){ 1273 1274 /* this is a Mach-O file so fill in the thin file struct for it */ 1275 replace->thin_file.addr = addr; 1276 mhp = (struct mach_header *)addr; 1277 lcp = (struct load_command *)((char *)mhp + 1278 sizeof(struct mach_header)); 1279 if(mhp->magic == SWAP_INT(MH_MAGIC)){ 1280 swapped = TRUE; 1281 mh = *mhp; 1282 swap_mach_header(&mh, get_host_byte_sex()); 1283 mhp = &mh; 1284 } 1285 else 1286 swapped = FALSE; 1287 replace->thin_file.fat_arch.cputype = mhp->cputype; 1288 replace->thin_file.fat_arch.cpusubtype = mhp->cpusubtype; 1289 replace->thin_file.fat_arch.offset = 0; 1290 replace->thin_file.fat_arch.size = size; 1291 replace->thin_file.fat_arch.align = 1292 get_align(mhp, lcp, size, replace->thin_file.name, swapped); 1293 } 1294 /* see if this file is Mach-O file for 64-bit architectures */ 1295 else if(size >= sizeof(struct mach_header_64) && 1296 (*((uint32_t *)addr) == MH_MAGIC_64 || 1297 *((uint32_t *)addr) == SWAP_INT(MH_MAGIC_64))){ 1298 1299 /* this is a Mach-O file so fill in the thin file struct for it */ 1300 replace->thin_file.addr = addr; 1301 mhp64 = (struct mach_header_64 *)addr; 1302 lcp = (struct load_command *)((char *)mhp64 + 1303 sizeof(struct mach_header_64)); 1304 if(mhp64->magic == SWAP_INT(MH_MAGIC_64)){ 1305 swapped = TRUE; 1306 mh64 = *mhp64; 1307 swap_mach_header_64(&mh64, get_host_byte_sex()); 1308 mhp64 = &mh64; 1309 } 1310 else 1311 swapped = FALSE; 1312 replace->thin_file.fat_arch.cputype = mhp64->cputype; 1313 replace->thin_file.fat_arch.cpusubtype = mhp64->cpusubtype; 1314 replace->thin_file.fat_arch.offset = 0; 1315 replace->thin_file.fat_arch.size = size; 1316 replace->thin_file.fat_arch.align = 1317 get_align_64(mhp64, lcp, size, replace->thin_file.name, swapped); 1318 } 1319 /* see if this file is an archive file */ 1320 else if(size >= SARMAG && strncmp(addr, ARMAG, SARMAG) == 0){ 1321 1322 check_archive(replace->thin_file.name, addr, size, 1323 &cputype, &cpusubtype); 1324 1325 /* fill in the thin file struct for this archive */ 1326 replace->thin_file.addr = addr; 1327 replace->thin_file.fat_arch.cputype = cputype; 1328 replace->thin_file.fat_arch.cpusubtype = cpusubtype; 1329 replace->thin_file.fat_arch.offset = 0; 1330 replace->thin_file.fat_arch.size = size; 1331 replace->thin_file.fat_arch.align = 2; /* 2^2, sizeof(uint32_t) */ 1332 } 1333 else{ 1334 /* fill in the thin file struct for it */ 1335 replace->thin_file.addr = addr; 1336 replace->thin_file.fat_arch.cputype = replace->arch_flag.cputype; 1337 replace->thin_file.fat_arch.cpusubtype = 1338 replace->arch_flag.cpusubtype; 1339 replace->thin_file.fat_arch.offset = 0; 1340 replace->thin_file.fat_arch.size = size; 1341 replace->thin_file.fat_arch.align = 0; 1342 } 1343 1344 if(replace->thin_file.fat_arch.cputype != replace->arch_flag.cputype || 1345 (replace->thin_file.fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK) != 1346 (replace->arch_flag.cpusubtype & ~CPU_SUBTYPE_MASK)) 1347 fatal("specified architecture: %s for replacement file: %s does " 1348 "not match the file's architecture", replace->arch_flag.name, 1349 replace->thin_file.name); 1350} 1351 1352/* 1353 * check_archive() checks an archive (mapped in at 'addr' of size 'size') to 1354 * make sure it can be included in a fat file (all members are the same 1355 * architecture, no fat files, etc). It returns the cputype and cpusubtype. 1356 */ 1357static 1358void 1359check_archive( 1360char *name, 1361char *addr, 1362uint32_t size, 1363cpu_type_t *cputype, 1364cpu_subtype_t *cpusubtype) 1365{ 1366 uint32_t offset, magic, i, ar_name_size, ar_size; 1367 struct mach_header mh; 1368 struct mach_header_64 mh64; 1369 struct ar_hdr *ar_hdr; 1370 char *ar_name, *ar_addr; 1371 struct arch_flag arch_flag; 1372 1373 /* 1374 * Check this archive out to make sure that it does not contain 1375 * any fat files and that all object files it contains have the 1376 * same cputype and subsubtype. 1377 */ 1378 *cputype = 0; 1379 *cpusubtype = 0; 1380 offset = SARMAG; 1381 if(offset == size) 1382 fatal("empty archive with no architecture specification: %s " 1383 "(can't determine architecture for it)", name); 1384 if(offset != size && offset + sizeof(struct ar_hdr) > size) 1385 fatal("truncated or malformed archive: %s (archive header of " 1386 "first member extends past the end of the file)", name); 1387 while(size > offset){ 1388 ar_hdr = (struct ar_hdr *)(addr + offset); 1389 offset += sizeof(struct ar_hdr); 1390 if(strncmp(ar_hdr->ar_name, AR_EFMT1, sizeof(AR_EFMT1) - 1) == 0){ 1391 check_extend_format_1(name, ar_hdr, size-offset, &ar_name_size); 1392 i = ar_name_size; 1393 ar_name = ar_hdr->ar_name + sizeof(struct ar_hdr); 1394 } 1395 else{ 1396 i = size_ar_name(ar_hdr->ar_name); 1397 ar_name = ar_hdr->ar_name; 1398 ar_name_size = 0; 1399 } 1400 if(size + ar_name_size - offset > sizeof(uint32_t)){ 1401 memcpy(&magic, addr + offset + ar_name_size, 1402 sizeof(uint32_t)); 1403 if(magic == FAT_MAGIC) 1404 fatal("archive member %s(%.*s) is a fat file (not " 1405 "allowed in an archive)", name, (int)i, ar_name); 1406 if((size - ar_name_size) - offset >= 1407 sizeof(struct mach_header) && 1408 (magic == MH_MAGIC || magic == SWAP_INT(MH_MAGIC))){ 1409 memcpy(&mh, addr + offset + ar_name_size, 1410 sizeof(struct mach_header)); 1411 if(mh.magic == SWAP_INT(MH_MAGIC)) 1412 swap_mach_header(&mh, get_host_byte_sex()); 1413 if(*cputype == 0){ 1414 *cputype = mh.cputype; 1415 *cpusubtype = mh.cpusubtype; 1416 } 1417 else if(*cputype != mh.cputype){ 1418 fatal("archive member %s(%.*s) cputype (%d) and " 1419 "cpusubtype (%d) does not match previous " 1420 "archive members cputype (%d) and cpusubtype" 1421 " (%d) (all members must match)", name, 1422 (int)i, ar_name, mh.cputype, mh.cpusubtype & 1423 ~CPU_SUBTYPE_MASK, *cputype, (*cpusubtype) & 1424 ~CPU_SUBTYPE_MASK); 1425 } 1426 } 1427 else if((size - ar_name_size) - offset >= 1428 sizeof(struct mach_header_64) && 1429 (magic == MH_MAGIC_64 || magic == SWAP_INT(MH_MAGIC_64))){ 1430 memcpy(&mh64, addr + offset + ar_name_size, 1431 sizeof(struct mach_header_64)); 1432 if(mh64.magic == SWAP_INT(MH_MAGIC_64)) 1433 swap_mach_header_64(&mh64, get_host_byte_sex()); 1434 if(*cputype == 0){ 1435 *cputype = mh64.cputype; 1436 *cpusubtype = mh64.cpusubtype; 1437 } 1438 else if(*cputype != mh64.cputype){ 1439 fatal("archive member %s(%.*s) cputype (%d) and " 1440 "cpusubtype (%d) does not match previous " 1441 "archive members cputype (%d) and cpusubtype" 1442 " (%d) (all members must match)", name, 1443 (int)i, ar_name, mh64.cputype, mh64.cpusubtype & 1444 ~CPU_SUBTYPE_MASK, *cputype, (*cpusubtype) & 1445 ~CPU_SUBTYPE_MASK); 1446 } 1447 } 1448 else{ 1449 if(strncmp(ar_name, SYMDEF, sizeof(SYMDEF) - 1) != 0){ 1450 ar_addr = addr + offset + ar_name_size; 1451 ar_size = strtoul(ar_hdr->ar_size, NULL, 10); 1452#ifdef LTO_SUPPORT 1453 if(is_llvm_bitcode_from_memory(ar_addr, ar_size, 1454 &arch_flag, NULL) != 0){ 1455 if(*cputype == 0){ 1456 *cputype = arch_flag.cputype; 1457 *cpusubtype = arch_flag.cpusubtype; 1458 } 1459 else if(*cputype != arch_flag.cputype){ 1460 fatal("archive member %s(%.*s) cputype (%d) " 1461 "and cpusubtype (%d) does not match " 1462 "previous archive members cputype (%d) " 1463 "and cpusubtype (%d) (all members must " 1464 "match)", name, (int)i, ar_name, 1465 arch_flag.cputype, arch_flag.cpusubtype & 1466 ~CPU_SUBTYPE_MASK, *cputype, 1467 (*cpusubtype) & ~CPU_SUBTYPE_MASK); 1468 } 1469 } 1470#endif /* LTO_SUPPORT */ 1471 } 1472 } 1473 } 1474 offset += rnd(strtoul(ar_hdr->ar_size, NULL, 10), 1475 sizeof(short)); 1476 } 1477} 1478/* 1479 * check_extend_format_1() checks the archive header for extened format1. 1480 */ 1481static 1482void 1483check_extend_format_1( 1484char *name, 1485struct ar_hdr *ar_hdr, 1486uint32_t size_left, 1487uint32_t *member_name_size) 1488{ 1489 char *p, *endp, buf[sizeof(ar_hdr->ar_name)+1]; 1490 uint32_t ar_name_size; 1491 1492 *member_name_size = 0; 1493 1494 buf[sizeof(ar_hdr->ar_name)] = '\0'; 1495 memcpy(buf, ar_hdr->ar_name, sizeof(ar_hdr->ar_name)); 1496 p = buf + sizeof(AR_EFMT1) - 1; 1497 if(isdigit(*p) == 0) 1498 fatal("archive: %s malformed (ar_name: %.*s for archive extend " 1499 "format #1 starts with non-digit)", name, 1500 (int)sizeof(ar_hdr->ar_name), ar_hdr->ar_name); 1501 ar_name_size = strtoul(p, &endp, 10); 1502 if(ar_name_size == UINT_MAX && errno == ERANGE) 1503 fatal("archive: %s malformed (size in ar_name: %.*s for archive " 1504 "extend format #1 overflows uint32_t)", name, 1505 (int)sizeof(ar_hdr->ar_name), ar_hdr->ar_name); 1506 while(*endp == ' ' && *endp != '\0') 1507 endp++; 1508 if(*endp != '\0') 1509 fatal("archive: %s malformed (size in ar_name: %.*s for archive " 1510 "extend format #1 contains non-digit and non-space " 1511 "characters)", name, (int)sizeof(ar_hdr->ar_name), 1512 ar_hdr->ar_name); 1513 if(ar_name_size > size_left) 1514 fatal("archive: %s truncated or malformed (archive name " 1515 "of member extends past the end of the file)", name); 1516 *member_name_size = ar_name_size; 1517} 1518 1519/* 1520 * get_align is passed a pointer to a mach header and size of the object. It 1521 * returns the segment alignment the object was created with. It guesses but 1522 * it is conservative. The maximum alignment is that the link editor will allow 1523 * MAXSECTALIGN and the minimum is the conserative alignment for a uint32_t 1524 * which appears in a mach object files (2^2 worst case for all current 32-bit 1525 * machines). 1526 */ 1527static 1528uint32_t 1529get_align( 1530struct mach_header *mhp, 1531struct load_command *load_commands, 1532uint32_t size, 1533char *name, 1534enum bool swapped) 1535{ 1536 uint32_t i, j, cur_align, align; 1537 struct load_command *lcp, l; 1538 struct segment_command *sgp, sg; 1539 struct section *sp, s; 1540 enum byte_sex host_byte_sex; 1541 1542 /* 1543 * Special case ppc and i386 architectures and return 12. 1544 * We know that with those architectures that the kernel and mmap only 1545 * need file offsets to be page (4096 byte) aligned. 1546 */ 1547 if(mhp->cputype == CPU_TYPE_POWERPC || 1548 mhp->cputype == CPU_TYPE_I386) 1549 return(12); 1550 /* 1551 * Special case ARM and return 14. As it has 16k pages. 1552 */ 1553 if(mhp->cputype == CPU_TYPE_ARM) 1554 return(14); 1555 1556 host_byte_sex = get_host_byte_sex(); 1557 1558 /* set worst case the link editor uses first */ 1559 cur_align = MAXSECTALIGN; 1560 if(mhp->sizeofcmds + sizeof(struct mach_header) > size) 1561 fatal("truncated or malformed object (load commands would " 1562 "extend past the end of the file) in: %s", name); 1563 lcp = load_commands; 1564 for(i = 0; i < mhp->ncmds; i++){ 1565 l = *lcp; 1566 if(swapped) 1567 swap_load_command(&l, host_byte_sex); 1568 if(l.cmdsize % sizeof(uint32_t) != 0) 1569 error("load command %u size not a multiple of " 1570 "sizeof(uint32_t) in: %s", i, name); 1571 if(l.cmdsize <= 0) 1572 fatal("load command %u size is less than or equal to zero " 1573 "in: %s", i, name); 1574 if((char *)lcp + l.cmdsize > 1575 (char *)load_commands + mhp->sizeofcmds) 1576 fatal("load command %u extends past end of all load " 1577 "commands in: %s", i, name); 1578 if(l.cmd == LC_SEGMENT){ 1579 sgp = (struct segment_command *)lcp; 1580 sg = *sgp; 1581 if(swapped) 1582 swap_segment_command(&sg, host_byte_sex); 1583 if(mhp->filetype == MH_OBJECT){ 1584 /* this is the minimum alignment, then take largest */ 1585 align = 2; /* 2^2 sizeof(uint32_t) */ 1586 sp = (struct section *)((char *)sgp + 1587 sizeof(struct segment_command)); 1588 for(j = 0; j < sg.nsects; j++){ 1589 s = *sp; 1590 if(swapped) 1591 swap_section(&s, 1, host_byte_sex); 1592 if(s.align > align) 1593 align = s.align; 1594 sp++; 1595 } 1596 if(align < cur_align) 1597 cur_align = align; 1598 } 1599 else{ 1600 /* guess the smallest alignment and use that */ 1601 align = guess_align(sg.vmaddr); 1602 if(align < cur_align) 1603 cur_align = align; 1604 } 1605 } 1606 lcp = (struct load_command *)((char *)lcp + l.cmdsize); 1607 } 1608 return(cur_align); 1609} 1610 1611/* 1612 * get_align_64 is passed a pointer to a mach_header_64 and size of the object. 1613 * It returns the segment alignment the object was created with. It guesses but 1614 * it is conservative. The maximum alignment is that the link editor will allow 1615 * MAXSECTALIGN and the minimum is the conserative alignment for a long long 1616 * which appears in a mach object files (2^3 worst case for all 64-bit 1617 * machines). 1618 */ 1619static 1620uint32_t 1621get_align_64( 1622struct mach_header_64 *mhp64, 1623struct load_command *load_commands, 1624uint32_t size, 1625char *name, 1626enum bool swapped) 1627{ 1628 uint32_t i, j, cur_align, align; 1629 struct load_command *lcp, l; 1630 struct segment_command_64 *sgp, sg; 1631 struct section_64 *sp, s; 1632 enum byte_sex host_byte_sex; 1633 1634 /* 1635 * Special case ppc64 and x86_64 architectures and return 12. 1636 * We know that with those architectures that the kernel and mmap only 1637 * need file offsets to be page (4096 byte) aligned. 1638 */ 1639 if(mhp64->cputype == CPU_TYPE_POWERPC64 || 1640 mhp64->cputype == CPU_TYPE_X86_64) 1641 return(12); 1642 1643 host_byte_sex = get_host_byte_sex(); 1644 1645 /* set worst case the link editor uses first */ 1646 cur_align = MAXSECTALIGN; 1647 if(mhp64->sizeofcmds + sizeof(struct mach_header_64) > size) 1648 fatal("truncated or malformed object (load commands would " 1649 "extend past the end of the file) in: %s", name); 1650 lcp = load_commands; 1651 for(i = 0; i < mhp64->ncmds; i++){ 1652 l = *lcp; 1653 if(swapped) 1654 swap_load_command(&l, host_byte_sex); 1655 if(l.cmdsize % sizeof(long long) != 0) 1656 error("load command %u size not a multiple of " 1657 "sizeof(long long) in: %s", i, name); 1658 if(l.cmdsize <= 0) 1659 fatal("load command %u size is less than or equal to zero " 1660 "in: %s", i, name); 1661 if((char *)lcp + l.cmdsize > 1662 (char *)load_commands + mhp64->sizeofcmds) 1663 fatal("load command %u extends past end of all load " 1664 "commands in: %s", i, name); 1665 if(l.cmd == LC_SEGMENT_64){ 1666 sgp = (struct segment_command_64 *)lcp; 1667 sg = *sgp; 1668 if(swapped) 1669 swap_segment_command_64(&sg, host_byte_sex); 1670 if(mhp64->filetype == MH_OBJECT){ 1671 /* this is the minimum alignment, then take largest */ 1672 align = 3; /* 2^3 sizeof(long long) */ 1673 sp = (struct section_64 *)((char *)sgp + 1674 sizeof(struct segment_command_64)); 1675 for(j = 0; j < sg.nsects; j++){ 1676 s = *sp; 1677 if(swapped) 1678 swap_section_64(&s, 1, host_byte_sex); 1679 if(s.align > align) 1680 align = s.align; 1681 sp++; 1682 } 1683 if(align < cur_align) 1684 cur_align = align; 1685 } 1686 else{ 1687 /* guess the smallest alignment and use that */ 1688 align = guess_align(sg.vmaddr); 1689 if(align < cur_align) 1690 cur_align = align; 1691 } 1692 } 1693 lcp = (struct load_command *)((char *)lcp + l.cmdsize); 1694 } 1695 return(cur_align); 1696} 1697 1698/* 1699 * guess_align is passed a vmaddr of a segment and guesses what the segment 1700 * alignment was. It uses the most conservative guess up to the maximum 1701 * alignment that the link editor uses. 1702 */ 1703static 1704uint32_t 1705guess_align( 1706uint32_t vmaddr) 1707{ 1708 uint32_t align, segalign; 1709 1710 if(vmaddr == 0) 1711 return(MAXSECTALIGN); 1712 1713 align = 0; 1714 segalign = 1; 1715 while((segalign & vmaddr) == 0){ 1716 segalign = segalign << 1; 1717 align++; 1718 } 1719 1720 if(align < 2) 1721 return(2); 1722 if(align > MAXSECTALIGN) 1723 return(MAXSECTALIGN); 1724 1725 return(align); 1726} 1727 1728/* 1729 * print_arch() helps implement -info and -detailed_info by printing the 1730 * architecture name for the cputype and cpusubtype. 1731 */ 1732static 1733void 1734print_arch( 1735struct fat_arch *fat_arch) 1736{ 1737 switch(fat_arch->cputype){ 1738 case CPU_TYPE_MC680x0: 1739 switch(fat_arch->cpusubtype & ~CPU_SUBTYPE_MASK){ 1740 case CPU_SUBTYPE_MC680x0_ALL: 1741 printf("m68k"); 1742 break; 1743 case CPU_SUBTYPE_MC68030_ONLY: 1744 printf("m68030"); 1745 break; 1746 case CPU_SUBTYPE_MC68040: 1747 printf("m68040"); 1748 break; 1749 default: 1750 goto print_arch_unknown; 1751 } 1752 break; 1753 case CPU_TYPE_POWERPC: 1754 switch(fat_arch->cpusubtype & ~CPU_SUBTYPE_MASK){ 1755 case CPU_SUBTYPE_POWERPC_ALL: 1756 printf("ppc"); 1757 break; 1758 case CPU_SUBTYPE_POWERPC_601: 1759 printf("ppc601"); 1760 break; 1761 case CPU_SUBTYPE_POWERPC_603: 1762 printf("ppc603"); 1763 break; 1764 case CPU_SUBTYPE_POWERPC_603e: 1765 printf("ppc603e"); 1766 break; 1767 case CPU_SUBTYPE_POWERPC_603ev: 1768 printf("ppc603ev"); 1769 break; 1770 case CPU_SUBTYPE_POWERPC_604: 1771 printf("ppc604"); 1772 break; 1773 case CPU_SUBTYPE_POWERPC_604e: 1774 printf("ppc604e"); 1775 break; 1776 case CPU_SUBTYPE_POWERPC_750: 1777 printf("ppc750"); 1778 break; 1779 case CPU_SUBTYPE_POWERPC_7400: 1780 printf("ppc7400"); 1781 break; 1782 case CPU_SUBTYPE_POWERPC_7450: 1783 printf("ppc7450"); 1784 break; 1785 case CPU_SUBTYPE_POWERPC_970: 1786 printf("ppc970"); 1787 break; 1788 default: 1789 goto print_arch_unknown; 1790 } 1791 break; 1792 case CPU_TYPE_POWERPC64: 1793 switch(fat_arch->cpusubtype & ~CPU_SUBTYPE_MASK){ 1794 case CPU_SUBTYPE_POWERPC_ALL: 1795 printf("ppc64"); 1796 break; 1797 case CPU_SUBTYPE_POWERPC_970: 1798 printf("ppc970-64"); 1799 break; 1800 default: 1801 goto print_arch_unknown; 1802 } 1803 break; 1804 case CPU_TYPE_VEO: 1805 switch(fat_arch->cpusubtype & ~CPU_SUBTYPE_MASK){ 1806 case CPU_SUBTYPE_VEO_1: 1807 printf("veo1"); 1808 break; 1809 case CPU_SUBTYPE_VEO_2: 1810 printf("veo2"); 1811 break; 1812 case CPU_SUBTYPE_VEO_3: 1813 printf("veo3"); 1814 break; 1815 case CPU_SUBTYPE_VEO_4: 1816 printf("veo4"); 1817 break; 1818 default: 1819 goto print_arch_unknown; 1820 } 1821 break; 1822 case CPU_TYPE_MC88000: 1823 switch(fat_arch->cpusubtype & ~CPU_SUBTYPE_MASK){ 1824 case CPU_SUBTYPE_MC88000_ALL: 1825 case CPU_SUBTYPE_MC88110: 1826 printf("m88k"); 1827 break; 1828 default: 1829 goto print_arch_unknown; 1830 } 1831 break; 1832 case CPU_TYPE_I386: 1833 switch(fat_arch->cpusubtype & ~CPU_SUBTYPE_MASK){ 1834 case CPU_SUBTYPE_I386_ALL: 1835 /* case CPU_SUBTYPE_386: same as above */ 1836 printf("i386"); 1837 break; 1838 case CPU_SUBTYPE_486: 1839 printf("i486"); 1840 break; 1841 case CPU_SUBTYPE_486SX: 1842 printf("i486SX"); 1843 break; 1844 case CPU_SUBTYPE_PENT: /* same as 586 */ 1845 printf("pentium"); 1846 break; 1847 case CPU_SUBTYPE_PENTPRO: 1848 printf("pentpro"); 1849 break; 1850 case CPU_SUBTYPE_PENTII_M3: 1851 printf("pentIIm3"); 1852 break; 1853 case CPU_SUBTYPE_PENTII_M5: 1854 printf("pentIIm5"); 1855 break; 1856 default: 1857 goto print_arch_unknown; 1858 } 1859 break; 1860 case CPU_TYPE_X86_64: 1861 switch(fat_arch->cpusubtype & ~CPU_SUBTYPE_MASK){ 1862 case CPU_SUBTYPE_X86_64_ALL: 1863 printf("x86_64"); 1864 break; 1865 default: 1866 goto print_arch_unknown; 1867 } 1868 break; 1869 case CPU_TYPE_I860: 1870 switch(fat_arch->cpusubtype & ~CPU_SUBTYPE_MASK){ 1871 case CPU_SUBTYPE_I860_ALL: 1872 case CPU_SUBTYPE_I860_860: 1873 printf("i860"); 1874 break; 1875 default: 1876 goto print_arch_unknown; 1877 } 1878 break; 1879 case CPU_TYPE_HPPA: 1880 switch(fat_arch->cpusubtype & ~CPU_SUBTYPE_MASK){ 1881 case CPU_SUBTYPE_HPPA_ALL: 1882 case CPU_SUBTYPE_HPPA_7100LC: 1883 printf("hppa"); 1884 break; 1885 default: 1886 goto print_arch_unknown; 1887 } 1888 break; 1889 case CPU_TYPE_SPARC: 1890 switch(fat_arch->cpusubtype & ~CPU_SUBTYPE_MASK){ 1891 case CPU_SUBTYPE_SPARC_ALL: 1892 printf("sparc"); 1893 break; 1894 default: 1895 goto print_arch_unknown; 1896 } 1897 break; 1898 case CPU_TYPE_ARM: 1899 switch(fat_arch->cpusubtype){ 1900 case CPU_SUBTYPE_ARM_ALL: 1901 printf("arm"); 1902 break; 1903 case CPU_SUBTYPE_ARM_V4T: 1904 printf("armv4t"); 1905 break; 1906 case CPU_SUBTYPE_ARM_V5TEJ: 1907 printf("armv5"); 1908 break; 1909 case CPU_SUBTYPE_ARM_XSCALE: 1910 printf("xscale"); 1911 break; 1912 case CPU_SUBTYPE_ARM_V6: 1913 printf("armv6"); 1914 break; 1915 case CPU_SUBTYPE_ARM_V6M: 1916 printf("armv6m"); 1917 break; 1918 case CPU_SUBTYPE_ARM_V7: 1919 printf("armv7"); 1920 break; 1921 case CPU_SUBTYPE_ARM_V7F: 1922 printf("armv7f"); 1923 break; 1924 case CPU_SUBTYPE_ARM_V7S: 1925 printf("armv7s"); 1926 break; 1927 case CPU_SUBTYPE_ARM_V7K: 1928 printf("armv7k"); 1929 break; 1930 case CPU_SUBTYPE_ARM_V7M: 1931 printf("armv7m"); 1932 break; 1933 case CPU_SUBTYPE_ARM_V7EM: 1934 printf("armv7em"); 1935 break; 1936 default: 1937 goto print_arch_unknown; 1938 } 1939 break; 1940 case CPU_TYPE_ANY: 1941 switch(fat_arch->cpusubtype & ~CPU_SUBTYPE_MASK){ 1942 case CPU_SUBTYPE_MULTIPLE: 1943 printf("any"); 1944 break; 1945 case CPU_SUBTYPE_LITTLE_ENDIAN: 1946 printf("little"); 1947 break; 1948 case CPU_SUBTYPE_BIG_ENDIAN: 1949 printf("big"); 1950 break; 1951 default: 1952 goto print_arch_unknown; 1953 } 1954 break; 1955print_arch_unknown: 1956 default: 1957 printf("(cputype (%d) cpusubtype (%d))", fat_arch->cputype, 1958 fat_arch->cpusubtype & ~CPU_SUBTYPE_MASK); 1959 break; 1960 } 1961} 1962 1963/* 1964 * print_cputype() helps implement -detailed_info by printing the cputype and 1965 * cpusubtype (symbolicly for the one's it knows about). 1966 */ 1967static 1968void 1969print_cputype( 1970cpu_type_t cputype, 1971cpu_subtype_t cpusubtype) 1972{ 1973 switch(cputype){ 1974 case CPU_TYPE_MC680x0: 1975 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 1976 case CPU_SUBTYPE_MC680x0_ALL: 1977 printf(" cputype CPU_TYPE_MC680x0\n" 1978 " cpusubtype CPU_SUBTYPE_MC680x0_ALL\n"); 1979 break; 1980 case CPU_SUBTYPE_MC68030_ONLY: 1981 printf(" cputype CPU_TYPE_MC680x0\n" 1982 " cpusubtype CPU_SUBTYPE_MC68030_ONLY\n"); 1983 break; 1984 case CPU_SUBTYPE_MC68040: 1985 printf(" cputype CPU_TYPE_MC680x0\n" 1986 " cpusubtype CPU_SUBTYPE_MC68040\n"); 1987 break; 1988 default: 1989 goto print_arch_unknown; 1990 } 1991 break; 1992 case CPU_TYPE_POWERPC: 1993 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 1994 case CPU_SUBTYPE_POWERPC_ALL: 1995 printf(" cputype CPU_TYPE_POWERPC\n" 1996 " cpusubtype CPU_SUBTYPE_POWERPC_ALL\n"); 1997 break; 1998 case CPU_SUBTYPE_POWERPC_601: 1999 printf(" cputype CPU_TYPE_POWERPC\n" 2000 " cpusubtype CPU_SUBTYPE_POWERPC_601\n"); 2001 break; 2002 case CPU_SUBTYPE_POWERPC_603: 2003 printf(" cputype CPU_TYPE_POWERPC\n" 2004 " cpusubtype CPU_SUBTYPE_POWERPC_603\n"); 2005 break; 2006 case CPU_SUBTYPE_POWERPC_603e: 2007 printf(" cputype CPU_TYPE_POWERPC\n" 2008 " cpusubtype CPU_SUBTYPE_POWERPC_603e\n"); 2009 break; 2010 case CPU_SUBTYPE_POWERPC_603ev: 2011 printf(" cputype CPU_TYPE_POWERPC\n" 2012 " cpusubtype CPU_SUBTYPE_POWERPC_603ev\n"); 2013 break; 2014 case CPU_SUBTYPE_POWERPC_604: 2015 printf(" cputype CPU_TYPE_POWERPC\n" 2016 " cpusubtype CPU_SUBTYPE_POWERPC_604\n"); 2017 break; 2018 case CPU_SUBTYPE_POWERPC_604e: 2019 printf(" cputype CPU_TYPE_POWERPC\n" 2020 " cpusubtype CPU_SUBTYPE_POWERPC_604e\n"); 2021 break; 2022 case CPU_SUBTYPE_POWERPC_750: 2023 printf(" cputype CPU_TYPE_POWERPC\n" 2024 " cpusubtype CPU_SUBTYPE_POWERPC_750\n"); 2025 break; 2026 case CPU_SUBTYPE_POWERPC_7400: 2027 printf(" cputype CPU_TYPE_POWERPC\n" 2028 " cpusubtype CPU_SUBTYPE_POWERPC_7400\n"); 2029 break; 2030 case CPU_SUBTYPE_POWERPC_7450: 2031 printf(" cputype CPU_TYPE_POWERPC\n" 2032 " cpusubtype CPU_SUBTYPE_POWERPC_7450\n"); 2033 break; 2034 case CPU_SUBTYPE_POWERPC_970: 2035 printf(" cputype CPU_TYPE_POWERPC\n" 2036 " cpusubtype CPU_SUBTYPE_POWERPC_970\n"); 2037 break; 2038 default: 2039 goto print_arch_unknown; 2040 } 2041 break; 2042 case CPU_TYPE_POWERPC64: 2043 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 2044 case CPU_SUBTYPE_POWERPC_ALL: 2045 printf(" cputype CPU_TYPE_POWERPC64\n" 2046 " cpusubtype CPU_SUBTYPE_POWERPC_ALL\n"); 2047 break; 2048 case CPU_SUBTYPE_POWERPC_970: 2049 printf(" cputype CPU_TYPE_POWERPC64\n" 2050 " cpusubtype CPU_SUBTYPE_POWERPC_970\n"); 2051 break; 2052 default: 2053 goto print_arch_unknown; 2054 } 2055 break; 2056 case CPU_TYPE_VEO: 2057 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 2058 case CPU_SUBTYPE_VEO_1: 2059 printf(" cputype CPU_TYPE_VEO\n" 2060 " cpusubtype CPU_SUBTYPE_VEO_1\n"); 2061 break; 2062 case CPU_SUBTYPE_VEO_2: 2063 printf(" cputype CPU_TYPE_VEO\n" 2064 " cpusubtype CPU_SUBTYPE_VEO_2\n"); 2065 break; 2066 case CPU_SUBTYPE_VEO_3: 2067 printf(" cputype CPU_TYPE_VEO\n" 2068 " cpusubtype CPU_SUBTYPE_VEO_3\n"); 2069 break; 2070 case CPU_SUBTYPE_VEO_4: 2071 printf(" cputype CPU_TYPE_VEO\n" 2072 " cpusubtype CPU_SUBTYPE_VEO_4\n"); 2073 break; 2074 default: 2075 goto print_arch_unknown; 2076 } 2077 break; 2078 case CPU_TYPE_MC88000: 2079 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 2080 case CPU_SUBTYPE_MC88000_ALL: 2081 printf(" cputype CPU_TYPE_MC88000\n" 2082 " cpusubtype CPU_SUBTYPE_MC88000_ALL\n"); 2083 break; 2084 case CPU_SUBTYPE_MC88110: 2085 printf(" cputype CPU_TYPE_MC88000\n" 2086 " cpusubtype CPU_SUBTYPE_MC88110\n"); 2087 break; 2088 default: 2089 goto print_arch_unknown; 2090 } 2091 break; 2092 case CPU_TYPE_I386: 2093 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 2094 case CPU_SUBTYPE_I386_ALL: 2095 /* case CPU_SUBTYPE_386: same as above */ 2096 printf(" cputype CPU_TYPE_I386\n" 2097 " cpusubtype CPU_SUBTYPE_I386_ALL\n"); 2098 break; 2099 case CPU_SUBTYPE_486: 2100 printf(" cputype CPU_TYPE_I386\n" 2101 " cpusubtype CPU_SUBTYPE_486\n"); 2102 break; 2103 case CPU_SUBTYPE_486SX: 2104 printf(" cputype CPU_TYPE_I386\n" 2105 " cpusubtype CPU_SUBTYPE_486SX\n"); 2106 break; 2107 case CPU_SUBTYPE_PENT: /* same as 586 */ 2108 printf(" cputype CPU_TYPE_I386\n" 2109 " cpusubtype CPU_SUBTYPE_PENT\n"); 2110 break; 2111 case CPU_SUBTYPE_PENTPRO: 2112 printf(" cputype CPU_TYPE_I386\n" 2113 " cpusubtype CPU_SUBTYPE_PENTPRO\n"); 2114 break; 2115 case CPU_SUBTYPE_PENTII_M3: 2116 printf(" cputype CPU_TYPE_I386\n" 2117 " cpusubtype CPU_SUBTYPE_PENTII_M3\n"); 2118 break; 2119 case CPU_SUBTYPE_PENTII_M5: 2120 printf(" cputype CPU_TYPE_I386\n" 2121 " cpusubtype CPU_SUBTYPE_PENTII_M5\n"); 2122 break; 2123 default: 2124 goto print_arch_unknown; 2125 } 2126 break; 2127 case CPU_TYPE_X86_64: 2128 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 2129 case CPU_SUBTYPE_X86_64_ALL: 2130 printf(" cputype CPU_TYPE_X86_64\n" 2131 " cpusubtype CPU_SUBTYPE_X86_64_ALL\n"); 2132 break; 2133 default: 2134 goto print_arch_unknown; 2135 } 2136 break; 2137 case CPU_TYPE_I860: 2138 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 2139 case CPU_SUBTYPE_I860_ALL: 2140 printf(" cputype CPU_TYPE_I860\n" 2141 " cpusubtype CPU_SUBTYPE_I860_ALL\n"); 2142 break; 2143 case CPU_SUBTYPE_I860_860: 2144 printf(" cputype CPU_TYPE_I860\n" 2145 " cpusubtype CPU_SUBTYPE_I860_860\n"); 2146 break; 2147 default: 2148 goto print_arch_unknown; 2149 } 2150 break; 2151 case CPU_TYPE_HPPA: 2152 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 2153 case CPU_SUBTYPE_HPPA_ALL: 2154 printf(" cputype CPU_TYPE_HPPA\n" 2155 " cpusubtype CPU_SUBTYPE_HPPA_ALL\n"); 2156 break; 2157 case CPU_SUBTYPE_HPPA_7100LC: 2158 printf(" cputype CPU_TYPE_HPPA\n" 2159 " cpusubtype CPU_SUBTYPE_HPPA_7100LC\n"); 2160 break; 2161 default: 2162 goto print_arch_unknown; 2163 } 2164 break; 2165 case CPU_TYPE_SPARC: 2166 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 2167 case CPU_SUBTYPE_SPARC_ALL: 2168 printf(" cputype CPU_TYPE_SPARC\n" 2169 " cpusubtype CPU_SUBTYPE_SPARC_ALL\n"); 2170 break; 2171 default: 2172 goto print_arch_unknown; 2173 } 2174 break; 2175 case CPU_TYPE_ARM: 2176 switch(cpusubtype){ 2177 case CPU_SUBTYPE_ARM_V4T: 2178 printf(" cputype CPU_TYPE_ARM\n" 2179 " cpusubtype CPU_SUBTYPE_ARM_V4T\n"); 2180 break; 2181 case CPU_SUBTYPE_ARM_V5TEJ: 2182 printf(" cputype CPU_TYPE_ARM\n" 2183 " cpusubtype CPU_SUBTYPE_ARM_V5TEJ\n"); 2184 break; 2185 case CPU_SUBTYPE_ARM_XSCALE: 2186 printf(" cputype CPU_TYPE_ARM\n" 2187 " cpusubtype CPU_SUBTYPE_ARM_XSCALE\n"); 2188 break; 2189 case CPU_SUBTYPE_ARM_V6: 2190 printf(" cputype CPU_TYPE_ARM\n" 2191 " cpusubtype CPU_SUBTYPE_ARM_V6\n"); 2192 break; 2193 case CPU_SUBTYPE_ARM_V6M: 2194 printf(" cputype CPU_TYPE_ARM\n" 2195 " cpusubtype CPU_SUBTYPE_ARM_V6M\n"); 2196 break; 2197 case CPU_SUBTYPE_ARM_V7: 2198 printf(" cputype CPU_TYPE_ARM\n" 2199 " cpusubtype CPU_SUBTYPE_ARM_V7\n"); 2200 break; 2201 case CPU_SUBTYPE_ARM_V7F: 2202 printf(" cputype CPU_TYPE_ARM\n" 2203 " cpusubtype CPU_SUBTYPE_ARM_V7F\n"); 2204 break; 2205 case CPU_SUBTYPE_ARM_V7S: 2206 printf(" cputype CPU_TYPE_ARM\n" 2207 " cpusubtype CPU_SUBTYPE_ARM_V7S\n"); 2208 break; 2209 case CPU_SUBTYPE_ARM_V7K: 2210 printf(" cputype CPU_TYPE_ARM\n" 2211 " cpusubtype CPU_SUBTYPE_ARM_V7K\n"); 2212 break; 2213 case CPU_SUBTYPE_ARM_V7M: 2214 printf(" cputype CPU_TYPE_ARM\n" 2215 " cpusubtype CPU_SUBTYPE_ARM_V7M\n"); 2216 break; 2217 case CPU_SUBTYPE_ARM_V7EM: 2218 printf(" cputype CPU_TYPE_ARM\n" 2219 " cpusubtype CPU_SUBTYPE_ARM_V7EM\n"); 2220 break; 2221 case CPU_SUBTYPE_ARM_ALL: 2222 printf(" cputype CPU_TYPE_ARM\n" 2223 " cpusubtype CPU_SUBTYPE_ARM_ALL\n"); 2224 break; 2225 default: 2226 goto print_arch_unknown; 2227 } 2228 break; 2229 case CPU_TYPE_ANY: 2230 switch(cpusubtype & ~CPU_SUBTYPE_MASK){ 2231 case CPU_SUBTYPE_MULTIPLE: 2232 printf(" cputype CPU_TYPE_ANY\n" 2233 " cpusubtype CPU_SUBTYPE_MULTIPLE\n"); 2234 break; 2235 case CPU_SUBTYPE_LITTLE_ENDIAN: 2236 printf(" cputype CPU_TYPE_ANY\n" 2237 " cpusubtype CPU_SUBTYPE_LITTLE_ENDIAN\n"); 2238 break; 2239 case CPU_SUBTYPE_BIG_ENDIAN: 2240 printf(" cputype CPU_TYPE_ANY\n" 2241 " cpusubtype CPU_SUBTYPE_BIG_ENDIAN\n"); 2242 break; 2243 default: 2244 goto print_arch_unknown; 2245 } 2246 break; 2247print_arch_unknown: 2248 default: 2249 printf(" cputype (%d)\n" 2250 " cpusubtype cpusubtype (%d)\n", cputype, 2251 cpusubtype & ~CPU_SUBTYPE_MASK); 2252 break; 2253 } 2254} 2255 2256/* 2257 * size_ar_name is used to return the size of the name of an archive member 2258 * for printing it without blanks (with printf string "%.*s"). 2259 */ 2260static 2261int 2262size_ar_name( 2263char *ar_name) 2264{ 2265 uint32_t j; 2266 struct ar_hdr ar_hdr; 2267 2268 for(j = 0; j < sizeof(ar_hdr.ar_name); j++){ 2269 if(ar_name[j] == ' ') 2270 break; 2271 } 2272 return(j); 2273} 2274 2275/* 2276 * Create a new input file struct, clear it and return it. 2277 */ 2278static 2279struct input_file * 2280new_input(void) 2281{ 2282 struct input_file *input; 2283 2284 input_files = reallocate(input_files, 2285 (ninput_files + 1) * sizeof(struct input_file)); 2286 input = input_files + ninput_files; 2287 ninput_files++; 2288 memset(input, '\0', sizeof(struct input_file)); 2289 return(input); 2290} 2291 2292/* 2293 * Create a new thin file struct, clear it and return it. 2294 */ 2295static 2296struct thin_file * 2297new_thin(void) 2298{ 2299 struct thin_file *thin; 2300 2301 thin_files = reallocate(thin_files, 2302 (nthin_files + 1) * sizeof(struct thin_file)); 2303 thin = thin_files + nthin_files; 2304 nthin_files++; 2305 memset(thin, '\0', sizeof(struct thin_file)); 2306 return(thin); 2307} 2308 2309/* 2310 * Create a new arch_flag struct on the specified list, clear it and return it. 2311 */ 2312static 2313struct arch_flag * 2314new_arch_flag( 2315struct arch_flag **arch_flags, 2316uint32_t *narch_flags) 2317{ 2318 struct arch_flag *arch_flag; 2319 2320 *arch_flags = reallocate(*arch_flags, 2321 (*narch_flags + 1) * sizeof(struct arch_flag)); 2322 arch_flag = *arch_flags + *narch_flags; 2323 *narch_flags = *narch_flags + 1; 2324 memset(arch_flag, '\0', sizeof(struct arch_flag)); 2325 return(arch_flag); 2326} 2327 2328/* 2329 * Create a new replace struct, clear it and return it. 2330 */ 2331static 2332struct replace * 2333new_replace(void) 2334{ 2335 struct replace *replace; 2336 2337 replaces = reallocate(replaces, 2338 (nreplaces + 1) * sizeof(struct replace)); 2339 replace = replaces + nreplaces; 2340 nreplaces++; 2341 memset(replace, '\0', sizeof(struct replace)); 2342 return(replace); 2343} 2344 2345/* 2346 * Create a new segalign struct, clear it and return it. 2347 */ 2348static 2349struct segalign * 2350new_segalign(void) 2351{ 2352 struct segalign *segalign; 2353 2354 segaligns = reallocate(segaligns, 2355 (nsegaligns + 1) * sizeof(struct segalign)); 2356 segalign = segaligns + nsegaligns; 2357 nsegaligns++; 2358 memset(segalign, '\0', sizeof(struct segalign)); 2359 return(segalign); 2360} 2361 2362/* 2363 * Function for qsort for comparing thin file's alignment 2364 */ 2365static 2366int 2367cmp_qsort( 2368const struct thin_file *thin1, 2369const struct thin_file *thin2) 2370{ 2371 return(thin1->fat_arch.align - thin2->fat_arch.align); 2372} 2373 2374/* 2375 * rnd() rounds v to a multiple of r. 2376 */ 2377static 2378uint32_t 2379rnd( 2380uint32_t v, 2381uint32_t r) 2382{ 2383 r--; 2384 v += r; 2385 v &= ~(int32_t)r; 2386 return(v); 2387} 2388 2389/* 2390 * ispoweroftwo() returns TRUE or FALSE depending if x is a power of two. 2391 */ 2392static 2393enum 2394bool 2395ispoweroftwo( 2396uint32_t x) 2397{ 2398 if(x == 0) 2399 return(TRUE); 2400 while((x & 0x1) != 0x1){ 2401 x >>= 1; 2402 } 2403 if((x & ~0x1) != 0) 2404 return(FALSE); 2405 else 2406 return(TRUE); 2407} 2408 2409/* 2410 * check_arch is called when an input file is specified with a -arch flag input 2411 * and that the architecture can be determined from the input to check that 2412 * both architectures match. 2413 */ 2414static 2415void 2416check_arch( 2417struct input_file *input, 2418struct thin_file *thin) 2419{ 2420 if(input->arch_flag.cputype != thin->fat_arch.cputype) 2421 fatal("specifed architecture type (%s) for file (%s) does " 2422 "not match its cputype (%d) and cpusubtype (%d) " 2423 "(should be cputype (%d) and cpusubtype (%d))", 2424 input->arch_flag.name, input->name, 2425 thin->fat_arch.cputype, thin->fat_arch.cpusubtype & 2426 ~CPU_SUBTYPE_MASK, input->arch_flag.cputype, 2427 input->arch_flag.cpusubtype & ~CPU_SUBTYPE_MASK); 2428} 2429 2430/* 2431 * Create a blank dylib. This is a stub dylib with no load commands. 2432 * It is a target page size block of bytes of zero except for the mach_header. 2433 */ 2434static 2435struct thin_file * 2436new_blank_dylib( 2437struct arch_flag *arch) 2438{ 2439 uint32_t target_page_size, align, onebit; 2440 struct thin_file *file; 2441 enum byte_sex host_byte_sex, target_byte_sex; 2442 struct mach_header *mh; 2443 struct mach_header_64 *mh64; 2444 2445 file = new_thin(); 2446 file->name = "blank dylib"; 2447 target_page_size = get_segalign_from_flag(arch); 2448 file->addr = allocate(target_page_size); 2449 memset(file->addr, '\0', target_page_size); 2450 file->fat_arch.cputype = arch->cputype; 2451 file->fat_arch.cpusubtype = arch->cpusubtype; 2452 file->fat_arch.offset = 0; 2453 file->fat_arch.size = target_page_size; 2454 onebit = 1; 2455 for(align = 1; (target_page_size & onebit) != onebit; align++) 2456 onebit = onebit << 1; 2457 file->fat_arch.align = align; 2458 2459 host_byte_sex = get_host_byte_sex(); 2460 target_byte_sex = get_byte_sex_from_flag(arch); 2461 2462 if((arch->cputype & CPU_ARCH_ABI64) == CPU_ARCH_ABI64){ 2463 mh64 = (struct mach_header_64 *)file->addr; 2464 mh64->magic = MH_MAGIC_64; 2465 mh64->cputype = arch->cputype; 2466 mh64->cpusubtype = arch->cpusubtype; 2467 mh64->filetype = MH_DYLIB_STUB; 2468 if(target_byte_sex != host_byte_sex) 2469 swap_mach_header_64(mh64, target_byte_sex); 2470 } 2471 else{ 2472 mh = (struct mach_header *)file->addr; 2473 mh->magic = MH_MAGIC; 2474 mh->cputype = arch->cputype; 2475 mh->cpusubtype = arch->cpusubtype; 2476 mh->filetype = MH_DYLIB_STUB; 2477 if(target_byte_sex != host_byte_sex) 2478 swap_mach_header(mh, target_byte_sex); 2479 } 2480 return(file); 2481} 2482 2483/* 2484 * Print the current usage line and exit (by calling fatal). 2485 */ 2486static 2487void 2488usage(void) 2489{ 2490 fatal("Usage: %s [input_file] ... [-arch <arch_type> input_file] ... " 2491 "[-info] [-detailed_info] [-output output_file] [-create] " 2492 "[-arch_blank <arch_type>] [-thin <arch_type>] " 2493 "[-remove <arch_type>] ... [-extract <arch_type>] ... " 2494 "[-extract_family <arch_type>] ... " 2495 "[-verify_arch <arch_type> ...] " 2496 "[-replace <arch_type> <file_name>] ...", progname); 2497} 2498