/* * 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); }