/* * 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); }
/* * The program cmpdylib. This compares an old and an new dynamic shared library * for compatiblity. Usage: * * cmpdylib old_dylib new_dylib * * It exits non-zero for incompatible libraries and prints why the libraries are * incompatible. It exit zero and prints nothing for compatible libraries. */ int main( int argc, char *argv[], char *envp[]) { progname = argv[0]; host_byte_sex = get_host_byte_sex(); if(argc != 3){ fprintf(stderr, "Usage: %s old_dylib new_dylib\n", progname); exit(EXIT_FAILURE); } old_dylib = argv[1]; new_dylib = argv[2]; ofile_process(old_dylib, NULL, 0, TRUE, TRUE, TRUE, FALSE, process_old, NULL); if(compatible == TRUE) return(EXIT_SUCCESS); else return(EXIT_FAILURE); }
int main( int argc, char **argv, char **envp) { int i; unsigned long j; struct arch_flag *arch_flags; unsigned long narch_flags; enum bool all_archs; char **files; progname = argv[0]; arch_flags = NULL; narch_flags = 0; all_archs = FALSE; output = stdout; cmd_flags.nfiles = 0; cmd_flags.c = FALSE; cmd_flags.x = FALSE; cmd_flags.ofile_name = NULL; cmd_flags.ofile_path = NULL; files = allocate(sizeof(char *) * argc); for(i = 1; i < argc; i++){ if(argv[i][0] == '-'){ if(argv[i][1] == '\0'){ for( ; i < argc; i++) files[cmd_flags.nfiles++] = argv[i]; break; } if(strcmp(argv[i], "-arch") == 0){ if(i + 1 == argc){ error("missing argument(s) to %s option", argv[i]); usage(); } if(strcmp("all", argv[i+1]) == 0){ all_archs = TRUE; } else{ arch_flags = reallocate(arch_flags, (narch_flags + 1) * sizeof(struct arch_flag)); if(get_arch_from_flag(argv[i+1], arch_flags + narch_flags) == 0){ error("unknown architecture specification flag: " "%s %s", argv[i], argv[i+1]); arch_usage(); usage(); } narch_flags++; } i++; } else{ for(j = 1; argv[i][j] != '\0'; j++){ switch(argv[i][j]){ case 'c': cmd_flags.c = TRUE; break; case 'x': cmd_flags.x = TRUE; break; case 'n': cmd_flags.n = TRUE; break; case 'o': cmd_flags.o = TRUE; break; default: error("invalid argument -%c", argv[i][j]); usage(); } } if(cmd_flags.n == TRUE && cmd_flags.ofile_name == NULL){ if(i + 1 == argc){ error("missing arguments to -n"); usage(); } cmd_flags.ofile_name = upper_string(argv[i+1]); i += 1; } if(cmd_flags.o == TRUE && cmd_flags.ofile_path == NULL){ if(i + 1 == argc){ error("missing arguments to -o"); usage(); } cmd_flags.ofile_path = argv[i+1]; i += 1; } } continue; } files[cmd_flags.nfiles++] = argv[i]; } if (cmd_flags.ofile_name == NULL) { if (cmd_flags.nfiles == 0) cmd_flags.ofile_name = upper_string("a.out"); else cmd_flags.ofile_name = upper_string(files[0]); } if (cmd_flags.o == TRUE) { output = fopen(cmd_flags.ofile_path, "w"); if (output == NULL) { error("couldn't open output file %s\n",cmd_flags.ofile_path); output = stdout; } } for(j = 0; j < cmd_flags.nfiles; j++) ofile_process(files[j], arch_flags, narch_flags, all_archs, FALSE, FALSE, TRUE, nm, &cmd_flags); if(cmd_flags.nfiles == 0) ofile_process("a.out", arch_flags, narch_flags, all_archs, FALSE, FALSE, TRUE, nm, &cmd_flags); if (cmd_flags.ofile_name != NULL) free(cmd_flags.ofile_name); if(errors == 0) return(EXIT_SUCCESS); else return(EXIT_FAILURE); }
int main( int argc, char **argv, char **envp) { int i; enum bool args_left; struct flags flag; struct arch_flag *arch_flags; unsigned long narch_flags; enum bool all_archs; progname = argv[0]; arch_flags = NULL; narch_flags = 0; all_archs = FALSE; flag.nfiles = 0; flag.m = FALSE; flag.l = FALSE; flag.x = FALSE; for(i = 1; i < argc; i++){ if(argv[i][0] == '-'){ if(argv[i][1] == '\0'){ flag.nfiles += argc - i - 1; break; } if(strcmp(argv[i], "-m") == 0){ flag.m = TRUE; continue; } if(strcmp(argv[i], "-l") == 0){ flag.l = TRUE; flag.m = TRUE; continue; } if(strcmp(argv[i], "-x") == 0){ flag.x = TRUE; flag.m = TRUE; continue; } if(strcmp(argv[i], "-arch") == 0){ if(i + 1 == argc){ error("missing argument(s) to %s option", argv[i]); usage(); } if(strcmp("all", argv[i+1]) == 0){ all_archs = TRUE; } else{ arch_flags = reallocate(arch_flags, (narch_flags + 1) * sizeof(struct arch_flag)); if(get_arch_from_flag(argv[i+1], arch_flags + narch_flags) == 0){ error("unknown architecture specification flag: " "%s %s", argv[i], argv[i+1]); arch_usage(); usage(); } narch_flags++; } i++; continue; } } flag.nfiles++; } if(flag.m == FALSE) printf("__TEXT\t__DATA\t__OBJC\tothers\tdec\thex\n"); args_left = TRUE; for (i = 1; i < argc; i++) { if(args_left == TRUE && argv[i][0] == '-'){ if(argv[i][1] == '\0'){ args_left = FALSE; continue; } if(strcmp(argv[i], "-m") == 0) continue; if(strcmp(argv[i], "-l") == 0) continue; if(strcmp(argv[i], "-x") == 0) continue; if(strcmp(argv[i], "-arch") == 0){ i++; continue; } } ofile_process(argv[i], arch_flags, narch_flags, all_archs, FALSE, TRUE, TRUE, size, &flag); } if(flag.nfiles == 0) ofile_process("a.out", arch_flags, narch_flags, all_archs, FALSE, TRUE, TRUE, size, &flag); if(errors == 0) return(EXIT_SUCCESS); else return(EXIT_FAILURE); }
int main( int argc, char **argv, char **envp) { struct flags flags; int i; uint32_t j, nfiles; char *endp; struct arch_flag *arch_flags; uint32_t narch_flags; enum bool all_archs, rest_args_files, use_member_syntax; struct stat stat_buf; progname = argv[0]; nfiles = 0; arch_flags = NULL; narch_flags = 0; all_archs = FALSE; flags.treat_as_data = FALSE; flags.print_offsets = FALSE; flags.offset_format = NULL; flags.all_sections = FALSE; flags.minimum_length = 4; rest_args_files = FALSE; for(i = 1; i < argc; i++){ if(rest_args_files == FALSE && argv[i][0] == '-'){ if(argv[i][1] == '\0') flags.treat_as_data = TRUE; else if(strcmp(argv[i], "--") == 0) rest_args_files = TRUE; else if(strcmp(argv[i], "-arch") == 0){ if(i + 1 == argc){ error("missing argument(s) to %s option", argv[i]); usage(); } if(strcmp("all", argv[i+1]) == 0){ all_archs = TRUE; } else{ arch_flags = reallocate(arch_flags, (narch_flags + 1) * sizeof(struct arch_flag)); if(get_arch_from_flag(argv[i+1], arch_flags + narch_flags) == 0){ error("unknown architecture specification flag: " "%s %s", argv[i], argv[i+1]); arch_usage(); usage(); } narch_flags++; } i++; } else if(strcmp(argv[i], "-n") == 0){ if(i + 1 == argc){ error("missing argument to %s option", argv[i]); usage(); } flags.minimum_length = strtoul(argv[i+1], &endp, 10); if(*endp != '\0'){ error("invalid decimal number in option: %s %s", argv[i], argv[i+1]); usage(); } i++; } else if(strcmp(argv[i], "-t") == 0){ if(i + 1 == argc){ error("missing argument to %s option", argv[i]); usage(); } if(argv[i+1][1] != '\0'){ error("invalid argument to option: %s %s", argv[i], argv[i+1]); usage(); } switch(argv[i+1][0]){ case 'd': flags.print_offsets = TRUE; flags.offset_format = "%d"; break; case 'o': flags.print_offsets = TRUE; flags.offset_format = "%o"; break; case 'x': flags.print_offsets = TRUE; flags.offset_format = "%x"; break; default: error("invalid argument to option: %s %s", argv[i], argv[i+1]); usage(); } i++; } else{ endp = NULL; for(j = 1; argv[i][j] != '\0' && endp == NULL; j++){ switch(argv[i][j]){ case 'o': flags.print_offsets = TRUE; flags.offset_format = "%7lu"; break; case 'a': flags.all_sections = TRUE; break; default: if(!isdigit(argv[i][j])){ error("unknown flag: %s", argv[i]); usage(); } flags.minimum_length = strtoul(argv[i]+j,&endp,10); if(*endp != '\0'){ error("invalid decimal number in flag: %s", argv[i]); usage(); } } } } } else{ nfiles++; } } /* * Process the file or stdin if there are no files. */ rest_args_files = FALSE; if(nfiles != 0){ for(i = 1; i < argc; i++){ if(argv[i][0] != '-' || rest_args_files == TRUE){ if(flags.treat_as_data == TRUE){ if(freopen(argv[i], "r", stdin) == NULL) system_error("can't open: %s", argv[i]); rewind(stdin); find(UINT_MAX, &flags); } else{ /* * If there's a filename that's an exact match then use * that, else fall back to the member syntax. */ if(stat(argv[i], &stat_buf) == 0) use_member_syntax = FALSE; else use_member_syntax = TRUE; ofile_process(argv[i], arch_flags, narch_flags, all_archs, TRUE, TRUE, use_member_syntax, ofile_processor,&flags); } } else if(strcmp(argv[i], "-arch") == 0 || strcmp(argv[i], "-n") == 0 || strcmp(argv[i], "-t") == 0) i++; else if(strcmp(argv[i], "--") == 0) rest_args_files = TRUE; } } else{ find(UINT_MAX, &flags); } if(errors == 0) return(EXIT_SUCCESS); else return(EXIT_FAILURE); }
/* * The check_dylib program. It takes a dynamic library file, an -install_name * argument, a -seg_addr_table argument and a -seg_addr_table_filename argument. * Then it preforms the following checks in the following order and if the * specific check fails it returns a specific error code: * * Check: * If the install_name of the dynamic library does not start with * @executable_path checks the install_name of the dynamic library file * against the specified -install_name argument and if it does not match it * Returns: 2 * * Check: * Checks the specified -seg_addr_table for the -seg_addr_table_filename * and if not found in the table it * Returns: 3 * * Check: * Checks that the specified address in the -seg_addr_table for the * -seg_addr_table_filename matches the dynamic library file. If not it * Returns: 4 * * Check: * Checks that the specified address in the -seg_addr_table for the * -seg_addr_table_filename and if it is zero then it * Returns: 5 * * If there is any other errors it returns 1 (EXIT_FAILURE). If all checks * pass then it returns 0 (EXIT_SUCCESS). */ int main( int argc, char **argv, char **envp) { int i; unsigned long table_size; char *install_name, *image_file_name, *seg_addr_table_name, *seg_addr_table_filename; struct check_block block; struct seg_addr_table *seg_addr_table, *entry; progname = argv[0]; install_name = NULL; image_file_name = NULL; seg_addr_table = NULL; seg_addr_table_filename = NULL; for(i = 1; i < argc; i++) { if(argv[i][0] == '-') { if(strcmp(argv[i], "-install_name") == 0) { if(i + 1 == argc) { error("missing argument(s) to %s option", argv[i]); usage(); } if(install_name != NULL) { error("more than one: %s option", argv[i]); usage(); } install_name = argv[i+1]; i++; } else if(strcmp(argv[i], "-seg_addr_table") == 0) { if(i + 1 == argc) { error("missing argument(s) to %s option", argv[i]); usage(); } if(seg_addr_table != NULL) { error("more than one: %s option", argv[i]); usage(); } seg_addr_table_name = argv[i+1]; seg_addr_table = parse_seg_addr_table(argv[i+1], argv[i], argv[i+1], &table_size); i++; } else if(strcmp(argv[i], "-seg_addr_table_filename") == 0) { if(i + 1 == argc) { error("missing argument(s) to %s option", argv[i]); usage(); } if(seg_addr_table_filename != NULL) { error("more than one: %s option", argv[i]); usage(); } seg_addr_table_filename = argv[i+1]; i++; } else { error("unknown option %s\n", argv[i]); usage(); } } else { if(image_file_name != NULL) { error("more than file name specified (%s and %s)", image_file_name, argv[i]); usage(); } image_file_name = argv[i]; } } if(image_file_name == NULL) { error("must specify a file name to be checked"); usage(); } if(install_name == NULL) { error("must specify the -install_name <install_name> option"); usage(); } if(seg_addr_table == NULL) { error("must specify the -seg_addr_table <table_name> option"); usage(); } if(seg_addr_table_filename == NULL) { error("must specify the -seg_addr_table_filename <pathname> " "option"); usage(); } /* * The first check to perform is checking the install name to match * the -install_name option. */ block.install_name = install_name; block.check_result = TRUE; ofile_process(image_file_name, NULL, 0, TRUE, TRUE, TRUE, FALSE, check_for_install_name, &block); if(block.check_result == FALSE) return(2); /* * The next check to perform is to see if the -seg_addr_table_filename * has an entry in the specified -seg_addr_table. */ entry = search_seg_addr_table(seg_addr_table, seg_addr_table_filename); if(entry == NULL) return(3); /* * The next check to perform is to see if the address in the * -seg_addr_table entry matches the dynamic library file. */ block.entry = entry; block.check_result = TRUE; ofile_process(image_file_name, NULL, 0, TRUE, TRUE, TRUE, FALSE, check_for_addresses, &block); if(block.check_result == FALSE) return(4); /* * The next check to perform is to see address in the -seg_addr_table * for the -seg_addr_table_filename is zero. */ if((entry->split == FALSE && entry->seg1addr == 0) || (entry->split == TRUE && (entry->segs_read_only_addr == 0 || entry->segs_read_write_addr == 0)) ) return(5); return(EXIT_SUCCESS); }
int main( int argc, char **argv, char **envp) { int i; struct cmd_flags cmd_flags; unsigned long j, table_size; struct arch_flag *arch_flags; unsigned long narch_flags; enum bool all_archs; char **files; progname = argv[0]; arch_flags = NULL; narch_flags = 0; all_archs = FALSE; cmd_flags.nfiles = 0; cmd_flags.rldtype = FALSE; cmd_flags.detail = FALSE; cmd_flags.verification = FALSE; cmd_flags.trey = FALSE; cmd_flags.check_dynamic_binary = TRUE; files = allocate(sizeof(char *) * argc); for(i = 1; i < argc; i++){ if(argv[i][0] == '-'){ if(argv[i][1] == '\0'){ for( ; i < argc; i++) files[cmd_flags.nfiles++] = argv[i]; break; } else if(strcmp(argv[i], "-arch") == 0){ if(i + 1 == argc){ error("missing argument(s) to %s option", argv[i]); usage(); } if(strcmp("all", argv[i+1]) == 0){ all_archs = TRUE; } else{ arch_flags = reallocate(arch_flags, (narch_flags + 1) * sizeof(struct arch_flag)); if(get_arch_from_flag(argv[i+1], arch_flags + narch_flags) == 0){ error("unknown architecture specification flag: " "%s %s", argv[i], argv[i+1]); arch_usage(); usage(); } narch_flags++; } i++; } else if(strcmp(argv[i], "-dylib_table") == 0){ if(i + 1 == argc){ error("missing argument(s) to %s option", argv[i]); usage(); } if(dylib_table_name != NULL){ error("more than one: %s option", argv[i]); usage(); } dylib_table_name = argv[i+1]; dylib_table = parse_dylib_table(argv[i+1], argv[i], argv[i+1]); i++; } else if(strcmp(argv[i], "-seg_addr_table") == 0){ if(i + 1 == argc){ error("missing argument(s) to %s option", argv[i]); usage(); } if(seg_addr_table_specified == TRUE){ error("more than one: %s option", argv[i]); usage(); } seg_addr_table_specified = TRUE; seg_addr_table_name = argv[i+1]; seg_addr_table = parse_seg_addr_table(argv[i+1], argv[i], argv[i+1], &table_size); i++; } else if(strcmp(argv[i], "-seg_addr_table_filename") == 0){ if(i + 1 == argc){ error("missing argument(s) to %s option", argv[i]); usage(); } if(seg_addr_table_filename != NULL){ error("more than one: %s option", argv[i]); usage(); } seg_addr_table_filename = argv[i+1]; i++; } else{ for(j = 1; argv[i][j] != '\0'; j++){ switch(argv[i][j]){ case 'r': cmd_flags.rldtype = TRUE; break; case 'd': cmd_flags.detail = TRUE; break; case 'v': cmd_flags.verification = TRUE; break; case 't': cmd_flags.trey = TRUE; break; case 'b': cmd_flags.check_dynamic_binary = TRUE; break; default: error("invalid argument -%c", argv[i][j]); usage(); } } } continue; } files[cmd_flags.nfiles++] = argv[i]; } if(arch_flags == NULL) all_archs = TRUE; if(cmd_flags.nfiles != 1) usage(); for(j = 0; j < cmd_flags.nfiles; j++) ofile_process(files[j], arch_flags, narch_flags, all_archs, TRUE, TRUE, FALSE, checksyms, &cmd_flags); if(errors == 0) return(exit_status); else return(EXIT_FAILURE); }