/* * process_old() is called once for each architecture in the old dynamic shared * library and then causes compare() to be called for the same architecture * in the new dynamic shared library. */ static void process_old( struct ofile *old_ofile, char *arch_name, void *cookie) { struct arch_flag arch_flag; /* check to make sure this is a dynamic shared library */ check_dylib(old_ofile, arch_name); /* fill in the architecure info */ arch_flag.name = (char *)get_arch_name_from_types( old_ofile->mh_cputype, old_ofile->mh_cpusubtype); arch_flag.cputype = old_ofile->mh_cputype; arch_flag.cpusubtype = old_ofile->mh_cpusubtype; arch_processed = FALSE; arch_name_being_processed = arch_name; ofile_process(new_dylib, &arch_flag, 1, FALSE, TRUE, TRUE, FALSE, compare, old_ofile); if(arch_processed == FALSE) fatal("new dynamic shared library: %s does not contain " "architecture %s\n", new_dylib, arch_flag.name); }
/* * get_lto_cputype() takes an arch_flag pointer and the target_triple string * returned from lto_module_get_target_triple() and sets the fields in the * arch_flag. If it can parse and knows the strings values it returns 1 and * the fields are set. Otherwise it returns 0 and the fields are not set. */ static int get_lto_cputype( struct arch_flag *arch_flag, char *target_triple) { char *p; size_t n; if(target_triple == NULL) return(0); p = index(target_triple, '-'); if(p == NULL) return(0); n = p - target_triple; if(strncmp(target_triple, "i686", n) == 0 || strncmp(target_triple, "i386", n) == 0){ arch_flag->cputype = CPU_TYPE_I386; arch_flag->cpusubtype = CPU_SUBTYPE_I386_ALL; } else if(strncmp(target_triple, "x86_64", n) == 0){ arch_flag->cputype = CPU_TYPE_X86_64; arch_flag->cpusubtype = CPU_SUBTYPE_X86_64_ALL; } else if(strncmp(target_triple, "x86_64h", n) == 0){ arch_flag->cputype = CPU_TYPE_X86_64; arch_flag->cpusubtype = CPU_SUBTYPE_X86_64_H; } else if(strncmp(target_triple, "powerpc", n) == 0){ arch_flag->cputype = CPU_TYPE_POWERPC; arch_flag->cpusubtype = CPU_SUBTYPE_POWERPC_ALL; } else if(strncmp(target_triple, "powerpc64", n) == 0){ arch_flag->cputype = CPU_TYPE_POWERPC64; arch_flag->cpusubtype = CPU_SUBTYPE_POWERPC_ALL; } else if(strncmp(target_triple, "arm", n) == 0){ arch_flag->cputype = CPU_TYPE_ARM; arch_flag->cpusubtype = CPU_SUBTYPE_ARM_V4T; } else if(strncmp(target_triple, "armv5", n) == 0 || strncmp(target_triple, "armv5e", n) == 0 || strncmp(target_triple, "thumbv5", n) == 0 || strncmp(target_triple, "thumbv5e", n) == 0){ arch_flag->cputype = CPU_TYPE_ARM; arch_flag->cpusubtype = CPU_SUBTYPE_ARM_V5TEJ; } else if(strncmp(target_triple, "armv6", n) == 0 || strncmp(target_triple, "thumbv6", n) == 0){ arch_flag->cputype = CPU_TYPE_ARM; arch_flag->cpusubtype = CPU_SUBTYPE_ARM_V6; } else if(strncmp(target_triple, "armv6m", n) == 0 || strncmp(target_triple, "thumbv6m", n) == 0){ arch_flag->cputype = CPU_TYPE_ARM; arch_flag->cpusubtype = CPU_SUBTYPE_ARM_V6M; } else if(strncmp(target_triple, "armv7", n) == 0 || strncmp(target_triple, "thumbv7", n) == 0){ arch_flag->cputype = CPU_TYPE_ARM; arch_flag->cpusubtype = CPU_SUBTYPE_ARM_V7; } else if(strncmp(target_triple, "armv7f", n) == 0 || strncmp(target_triple, "thumbv7f", n) == 0){ arch_flag->cputype = CPU_TYPE_ARM; arch_flag->cpusubtype = CPU_SUBTYPE_ARM_V7F; } else if(strncmp(target_triple, "armv7s", n) == 0 || strncmp(target_triple, "thumbv7s", n) == 0){ arch_flag->cputype = CPU_TYPE_ARM; arch_flag->cpusubtype = CPU_SUBTYPE_ARM_V7S; } else if(strncmp(target_triple, "armv7k", n) == 0 || strncmp(target_triple, "thumbv7k", n) == 0){ arch_flag->cputype = CPU_TYPE_ARM; arch_flag->cpusubtype = CPU_SUBTYPE_ARM_V7K; } else if(strncmp(target_triple, "armv7m", n) == 0 || strncmp(target_triple, "thumbv7m", n) == 0){ arch_flag->cputype = CPU_TYPE_ARM; arch_flag->cpusubtype = CPU_SUBTYPE_ARM_V7M; } else if(strncmp(target_triple, "armv7em", n) == 0 || strncmp(target_triple, "thumbv7em", n) == 0){ arch_flag->cputype = CPU_TYPE_ARM; arch_flag->cpusubtype = CPU_SUBTYPE_ARM_V7EM; } else if(strncmp(target_triple, "arm64", n) == 0){ arch_flag->cputype = CPU_TYPE_ARM64; arch_flag->cpusubtype = CPU_SUBTYPE_ARM64_ALL; } else{ return(0); } arch_flag->name = (char *)get_arch_name_from_types(arch_flag->cputype, arch_flag->cpusubtype); return(1); }
/* * The codesign_allocate(1) tool has the following usage: * * codesign_allocate -i oldfile -a arch size ... -o newfile * * Where the oldfile is a Mach-O file that is input for the dynamic linker * and it creates or adds an */ int main( int argc, char **argv, char **envp) { uint32_t i; char *input, *output, *endp; struct arch *archs; uint32_t narchs; progname = argv[0]; input = NULL; output = NULL; archs = NULL; narchs = 0; for(i = 1; i < argc; i++) { if(strcmp(argv[i], "-i") == 0) { if(i + 1 == argc) { error("missing argument to: %s option", argv[i]); usage(); } if(input != NULL) { error("more than one: %s option specified", argv[i]); usage(); } input = argv[i+1]; i++; } else if(strcmp(argv[i], "-o") == 0) { if(i + 1 == argc) { error("missing argument to: %s option", argv[i]); usage(); } if(output != NULL) { error("more than one: %s option specified", argv[i]); usage(); } output = argv[i+1]; i++; } else if(strcmp(argv[i], "-a") == 0) { if(i + 2 == argc) { error("missing argument(s) to: %s option", argv[i]); usage(); } else { arch_signs = reallocate(arch_signs, (narch_signs + 1) * sizeof(struct arch_sign)); if(get_arch_from_flag(argv[i+1], &(arch_signs[narch_signs].arch_flag)) == 0) { error("unknown architecture specification flag: " "%s %s %s", argv[i], argv[i+1], argv[i+2]); arch_usage(); usage(); } arch_signs[narch_signs].datasize = strtoul(argv[i+2], &endp, 0); if(*endp != '\0') fatal("size for '-a %s %s' not a proper number", argv[i+1], argv[i+2]); if((arch_signs[narch_signs].datasize % 16) != 0) fatal("size for '-a %s %s' not a multiple of 16", argv[i+1], argv[i+2]); arch_signs[narch_signs].found = FALSE; narch_signs++; i += 2; } } else if(strcmp(argv[i], "-A") == 0) { if(i + 3 == argc) { error("missing argument(s) to: %s option", argv[i]); usage(); } else { arch_signs = reallocate(arch_signs, (narch_signs + 1) * sizeof(struct arch_sign)); arch_signs[narch_signs].arch_flag.cputype = strtoul(argv[i+1], &endp, 0); if(*endp != '\0') fatal("cputype for '-A %s %s %s' not a proper number", argv[i+1], argv[i+2], argv[i+3]); arch_signs[narch_signs].arch_flag.cpusubtype = strtoul(argv[i+2], &endp, 0); if(*endp != '\0') fatal("cpusubtype for '-A %s %s %s' not a proper " "number", argv[i+1], argv[i+2], argv[i+3]); arch_signs[narch_signs].arch_flag.name = (char *) get_arch_name_from_types( arch_signs[narch_signs].arch_flag.cputype, arch_signs[narch_signs].arch_flag.cpusubtype); arch_signs[narch_signs].datasize = strtoul(argv[i+3], &endp, 0); if(*endp != '\0') fatal("size for '-A %s %s %s' not a proper number", argv[i+1], argv[i+2], argv[i+3]); if((arch_signs[narch_signs].datasize % 16) != 0) fatal("size for '-A %s %s %s' not a multiple of 16", argv[i+1], argv[i+2], argv[i+3]); arch_signs[narch_signs].found = FALSE; narch_signs++; i += 3; } } else { error("unknown flag: %s", argv[i]); usage(); } } if(input == NULL || output == NULL || narch_signs == 0) usage(); breakout(input, &archs, &narchs, FALSE); if(errors) exit(EXIT_FAILURE); checkout(archs, narchs); process(archs, narchs); for(i = 0; i < narch_signs; i++) { if(arch_signs[i].found == FALSE) fatal("input file: %s does not contain a matching architecture " "for specified '-a %s %u' option", input, arch_signs[i].arch_flag.name, arch_signs[i].datasize); } writeout(archs, narchs, output, 0777, TRUE, FALSE, FALSE, NULL); if(errors) return(EXIT_FAILURE); else return(EXIT_SUCCESS); }