static void print_trans_maindata(const char *filename) { fprintf(OUT, "struct trans_maindata trans_%s_maindata = {\n", filename); /* シンボルの個数(0番anonymousも数える) */ fprintf(OUT, " %d, /*count of symbol*/\n", count_symbols()); /* シンボルの配列 */ fprintf(OUT, " trans_%s_maindata_symbols, /*symboltable*/\n", filename); /* ファンクタの個数 */ fprintf(OUT, " %d, /*count of functor*/\n", lmn_functor_table.next_id); /* ファンクタの配列 */ fprintf(OUT, " trans_%s_maindata_functors, /*functortable*/\n", filename); /* ルールセットの個数 */ fprintf(OUT, " %d, /*count of ruleset*/\n", count_rulesets()); /* ルールセットオブジェクトへのポインタの配列 */ fprintf(OUT, " trans_%s_maindata_rulesets, /*rulesettable*/\n", filename); /* モジュールの個数 */ fprintf(OUT, " %d, /*count of module*/\n", count_modules()); /* モジュールの配列 */ fprintf(OUT, " trans_%s_maindata_modules, /*moduletable*/\n", filename); /* シンボルid変換テーブル */ fprintf(OUT, " trans_%s_maindata_symbolexchange, /*symbol id exchange table*/\n", filename); /* ファンクタid変換テーブル */ fprintf(OUT, " trans_%s_maindata_functorexchange, /*functor id exchange table*/\n", filename); /* ルールセットid変換テーブル */ fprintf(OUT, " trans_%s_maindata_rulesetexchange /*ruleset id exchange table*/\n", filename); fprintf(OUT, "};\n\n"); }
/** * エンコード関数 * @param const char *filename 開くファイル名 * @return int 成功 */ int encode(const char *filename) { count_symbols(filename); // シンボル数のカウント Node *root = build_tree(); // 符号の木を作る traverse_tree(0, root); // 符号を当てる return 1; }
static void print_trans_symbols(const char *filename) { int i; int count = count_symbols(); fprintf(OUT, "const char *trans_%s_maindata_symbols[%d] = {\n", filename, count); for(i=0; i<count; ++i){ fprintf(OUT, " \"%s\"", lmn_id_to_name(i)); if(i != count-1) fprintf(OUT, ","); fprintf(OUT, "\n"); } fprintf(OUT, "};\n"); fprintf(OUT, "int trans_%s_maindata_symbolexchange[%d];\n\n", filename, count); }
/* * Finish building grammar */ void grammar_complete(struct grammar *grammar) { resolve_symbols(grammar); determine_start(grammar); add_sentinel_rule(grammar); count_symbols(grammar); /* At this point we have complete symbol graph */ if (print_opt(P_GRAMMAR)) dump_grammar(grammar); if (print_opt(P_SYMBOLS)) dump_symbols(grammar); nullable_find(grammar); if (print_opt(P_NULLABLE)) nullable_dump(grammar); }
static void collect_global_symbols() { uint32_t count = count_symbols(); GlobalSymbol* all_symbols = safe_malloc(sizeof(GlobalSymbol)*count); GlobalSymbolSet* set; GlobalSymbolSet* next; uint32_t i; count = 0; for (set = global_symbol_sets; set; set = next) { for (i = 0; i < set->num_symbols; ++i) { GlobalSymbol* g = &all_symbols[count + i]; CH_DbgGlobalSymbol* sym = &set->symbols[i]; g->name = sym->name; g->kind = sym->kind; g->is_partial = sym->is_partial; g->defining_object = set->defining_object - debug_objects; g->defining_object_offset = set->symbols[i].defining_object_offset; g->address = sym->address; } count += set->num_symbols; next = set->next; safe_free(set->symbols); safe_free(set); } qsort(all_symbols, count, sizeof(GlobalSymbol), compare_global_symbols); count = remove_duplicates(count, all_symbols); all_symbols = safe_realloc(all_symbols, count*sizeof(GlobalSymbol)); pthread_mutex_lock(&global_symbol_mutex); global_symbols = all_symbols; global_symbol_count = count; pthread_cond_broadcast(&global_symbol_condition); pthread_mutex_unlock(&global_symbol_mutex); }
/** * エンコード関数 * @param const char *filename 開くファイル名 * @return int 成功 */ int encode(const char *filename) { FILE *fp; char *mapfile; count_symbols(filename); // シンボル数のカウント Node *root = build_tree(); // 符号の木を作る mapfile = change_extention(filename, ".maps"); if ((fp = fopen(mapfile, "w")) == NULL) { fprintf(stderr, "Cannot Open Mapping File\n"); exit(1); } free(mapfile); fprintf(fp, "%s\n", filename); // ファイル名を入れておく traverse_tree(0, root, fp); // 符号を当てる fclose(fp); compress(root, filename); // 圧縮 printf("finished\n"); return 1; }
int main(int argc, char * argv[]) { KXKextManagerError err; int fd; const char * output_name = NULL; uint32_t i, zero = 0, num_files = 0; uint32_t filenum; uint32_t strx, strtabsize, strtabpad; struct symbol * import_symbols; struct symbol * export_symbols; uint32_t num_import_syms, num_export_syms, num_removed_syms; uint32_t import_idx, export_idx; const NXArchInfo * host_arch; const NXArchInfo * target_arch; boolean_t require_imports = true; boolean_t diff = false; struct { struct mach_header hdr; struct symtab_command symcmd; } load_cmds; struct file { vm_offset_t mapped; vm_size_t mapped_size; uint32_t nsyms; boolean_t import; const char * path; }; struct file files[64]; host_arch = NXGetLocalArchInfo(); target_arch = host_arch; for( i = 1; i < argc; i += 2) { boolean_t import; if (!strcmp("-sect", argv[i])) { require_imports = false; i--; continue; } if (!strcmp("-diff", argv[i])) { require_imports = false; diff = true; i--; continue; } if (i == (argc - 1)) { fprintf(stderr, "bad arguments: %s\n", argv[i]); exit(1); } if (!strcmp("-arch", argv[i])) { target_arch = NXGetArchInfoFromName(argv[i + 1]); if (!target_arch) { fprintf(stderr, "unknown architecture name: %s\n", argv[i+1]); exit(1); } continue; } if (!strcmp("-output", argv[i])) { output_name = argv[i+1]; continue; } if (!strcmp("-import", argv[i])) import = true; else if (!strcmp("-export", argv[i])) import = false; else { fprintf(stderr, "unknown option: %s\n", argv[i]); exit(1); } err = readFile(argv[i+1], &files[num_files].mapped, &files[num_files].mapped_size); if (kKXKextManagerErrorNone != err) exit(1); if (files[num_files].mapped && files[num_files].mapped_size) { files[num_files].import = import; files[num_files].path = argv[i+1]; num_files++; } } if (!output_name) { fprintf(stderr, "no output file\n"); exit(1); } num_import_syms = 0; num_export_syms = 0; for (filenum = 0; filenum < num_files; filenum++) { files[filenum].nsyms = count_symbols((char *) files[filenum].mapped); if (files[filenum].import) num_import_syms += files[filenum].nsyms; else num_export_syms += files[filenum].nsyms; } if (!num_export_syms) { fprintf(stderr, "no export names\n"); exit(1); } import_symbols = calloc(num_import_syms, sizeof(struct symbol)); export_symbols = calloc(num_export_syms, sizeof(struct symbol)); strtabsize = 4; import_idx = 0; export_idx = 0; for (filenum = 0; filenum < num_files; filenum++) { if (files[filenum].import) { store_symbols((char *) files[filenum].mapped, import_symbols, import_idx, num_import_syms); import_idx += files[filenum].nsyms; } else { strtabsize += store_symbols((char *) files[filenum].mapped, export_symbols, export_idx, num_export_syms); export_idx += files[filenum].nsyms; } if (!files[filenum].nsyms) { fprintf(stderr, "warning: file %s contains no names\n", files[filenum].path); } } qsort(import_symbols, num_import_syms, sizeof(struct symbol), &qsort_cmp); qsort(export_symbols, num_export_syms, sizeof(struct symbol), &qsort_cmp); num_removed_syms = 0; if (num_import_syms) { for (export_idx = 0; export_idx < num_export_syms; export_idx++) { boolean_t found = true; if (!bsearch(export_symbols[export_idx].name, import_symbols, num_import_syms, sizeof(struct symbol), &bsearch_cmp)) { if (require_imports) fprintf(stderr, "exported name not in import list: %s\n", export_symbols[export_idx].name); found = false; } if (export_symbols[export_idx].indirect) { if (!bsearch(export_symbols[export_idx].indirect, import_symbols, num_import_syms, sizeof(struct symbol), &bsearch_cmp)) { if (require_imports) fprintf(stderr, "exported name not in import list: %s\n", export_symbols[export_idx].indirect); found = false; } } if (found && !diff) continue; if (!found && diff) continue; num_removed_syms++; strtabsize -= (export_symbols[export_idx].name_len + export_symbols[export_idx].indirect_len); export_symbols[export_idx].name = 0; } } if (require_imports && num_removed_syms) { err = kKXKextManagerErrorUnspecified; goto finish; } fd = open(output_name, O_WRONLY|O_CREAT|O_TRUNC, 0755); if (-1 == fd) { perror("couldn't write output"); err = kKXKextManagerErrorFileAccess; goto finish; } strtabpad = (strtabsize + 3) & ~3; load_cmds.hdr.magic = MH_MAGIC; load_cmds.hdr.cputype = target_arch->cputype; load_cmds.hdr.cpusubtype = target_arch->cpusubtype; load_cmds.hdr.filetype = MH_OBJECT; load_cmds.hdr.ncmds = 1; load_cmds.hdr.sizeofcmds = sizeof(load_cmds.symcmd); load_cmds.hdr.flags = MH_INCRLINK; load_cmds.symcmd.cmd = LC_SYMTAB; load_cmds.symcmd.cmdsize = sizeof(load_cmds.symcmd); load_cmds.symcmd.symoff = sizeof(load_cmds); load_cmds.symcmd.nsyms = (num_export_syms - num_removed_syms); load_cmds.symcmd.stroff = (num_export_syms - num_removed_syms) * sizeof(struct nlist) + load_cmds.symcmd.symoff; load_cmds.symcmd.strsize = strtabpad; if (target_arch->byteorder != host_arch->byteorder) { swap_mach_header(&load_cmds.hdr, target_arch->byteorder); swap_symtab_command(&load_cmds.symcmd, target_arch->byteorder); } err = writeFile(fd, &load_cmds, sizeof(load_cmds)); if (kKXKextManagerErrorNone != err) goto finish; strx = 4; for (export_idx = 0; export_idx < num_export_syms; export_idx++) { struct nlist nl; if (!export_symbols[export_idx].name) continue; nl.n_sect = 0; nl.n_desc = 0; nl.n_un.n_strx = strx; strx += export_symbols[export_idx].name_len; if (export_symbols[export_idx].indirect) { nl.n_type = N_INDR | N_EXT; nl.n_value = strx; strx += export_symbols[export_idx].indirect_len; } else { nl.n_type = N_UNDF | N_EXT; nl.n_value = 0; } if (target_arch->byteorder != host_arch->byteorder) swap_nlist(&nl, 1, target_arch->byteorder); err = writeFile(fd, &nl, sizeof(nl)); if (kKXKextManagerErrorNone != err) goto finish; } strx = sizeof(uint32_t); err = writeFile(fd, &zero, strx); if (kKXKextManagerErrorNone != err) goto finish; for (export_idx = 0; export_idx < num_export_syms; export_idx++) { if (!export_symbols[export_idx].name) continue; err = writeFile(fd, export_symbols[export_idx].name, export_symbols[export_idx].name_len + export_symbols[export_idx].indirect_len); if (kKXKextManagerErrorNone != err) goto finish; } err = writeFile(fd, &zero, strtabpad - strtabsize); if (kKXKextManagerErrorNone != err) goto finish; close(fd); finish: if (kKXKextManagerErrorNone != err) { if (output_name) unlink(output_name); exit(1); } else exit(0); return(0); }
// fill out al and info for a given mate // this does *not* fill in mapq, as that requires knowledge of which mate is the anchor as well as second-best scores void DebugOutput::process_one_mate(DbgAlignment& al, DbgInfo& info, const AlignmentData& alignment, const AlignmentData& mate, const uint32 mapq) { // output read_id as CRC of read name al.read_id = crcCalc(alignment.read_name, strlen(alignment.read_name)); al.read_len = alignment.read_len; if (alignment.best->is_aligned()) { // setup alignment information const io::BNTAnn* ann = std::upper_bound( bnt.data.anns, bnt.data.anns + bnt.info.n_seqs, alignment.cigar_pos, SeqFinder() ) - 1u; al.alignment_pos = alignment.cigar_pos - int32(ann->offset) + 1u; info.flag = (alignment.best->mate() ? DbgInfo::READ_2 : DbgInfo::READ_1) | (alignment.best->is_rc() ? DbgInfo::REVERSE : 0u); if (alignment_type == PAIRED_END) { if (alignment.best->is_paired()) // FIXME: this should be other_mate.is_concordant() { info.flag |= DbgInfo::PROPER_PAIR; } if (mate.best->is_aligned() == false) { info.flag |= DbgInfo::MATE_UNMAPPED; } } const uint32 ref_cigar_len = reference_cigar_length(alignment.cigar, alignment.cigar_len); if (alignment.cigar_pos + ref_cigar_len > ann->offset + ann->len) { // flag UNMAPPED as this alignment bridges two adjacent reference sequences info.flag |= DbgInfo::UNMAPPED; } uint32 n_mm; uint32 n_gapo; uint32 n_gape; analyze_md_string(alignment.mds_vec, n_mm, n_gapo, n_gape); info.ref_id = uint32(ann - bnt.data.anns); info.mate = alignment.best->mate(); info.score = alignment.best->score(); info.mapQ = mapq; info.ed = alignment.best->ed(); info.subs = count_symbols(Cigar::SUBSTITUTION, alignment.cigar, alignment.cigar_len); info.ins = count_symbols(Cigar::INSERTION, alignment.cigar, alignment.cigar_len); info.dels = count_symbols(Cigar::DELETION, alignment.cigar, alignment.cigar_len); info.mms = n_mm; info.gapo = n_gapo; info.gape = n_gape; info.sec_score = alignment.second_best->score(); if (info.sec_score == alignment.second_best->is_aligned()) { info.sec_score = alignment.second_best->score(); info.has_second = 1; } else { info.sec_score = Field_traits<int16>::min(); info.has_second = 0; } info.pad = 0x69; } else { // unmapped alignment al.alignment_pos = 0; } }
int main(int argc, char * argv[]) { ToolError err; int i, fd; const char * output_name = NULL; uint32_t zero = 0, num_files = 0; uint32_t filenum; uint32_t strx, strtabsize, strtabpad; struct symbol * import_symbols; struct symbol * export_symbols; uint32_t num_import_syms, num_export_syms; uint32_t result_count, num_removed_syms; uint32_t import_idx, export_idx; const NXArchInfo * host_arch; const NXArchInfo * target_arch; boolean_t require_imports = true; boolean_t diff = false; struct file { vm_offset_t mapped; vm_size_t mapped_size; uint32_t nsyms; boolean_t import; const char * path; }; struct file files[64]; host_arch = NXGetLocalArchInfo(); target_arch = host_arch; for( i = 1; i < argc; i += 2) { boolean_t import; if (!strcmp("-sect", argv[i])) { require_imports = false; i--; continue; } if (!strcmp("-diff", argv[i])) { require_imports = false; diff = true; i--; continue; } if (i == (argc - 1)) { fprintf(stderr, "bad arguments: %s\n", argv[i]); exit(1); } if (!strcmp("-arch", argv[i])) { target_arch = DL_NXGetArchInfoFromName(argv[i + 1]); if (!target_arch) { fprintf(stderr, "unknown architecture name: %s\n", argv[i+1]); exit(1); } continue; } if (!strcmp("-output", argv[i])) { output_name = argv[i+1]; continue; } if (!strcmp("-import", argv[i])) import = true; else if (!strcmp("-export", argv[i])) import = false; else { fprintf(stderr, "unknown option: %s\n", argv[i]); exit(1); } err = readFile(argv[i+1], &files[num_files].mapped, &files[num_files].mapped_size); if (kErrorNone != err) exit(1); if (files[num_files].mapped && files[num_files].mapped_size) { files[num_files].import = import; files[num_files].path = argv[i+1]; num_files++; } } if (!output_name) { fprintf(stderr, "no output file\n"); exit(1); } num_import_syms = 0; num_export_syms = 0; for (filenum = 0; filenum < num_files; filenum++) { files[filenum].nsyms = count_symbols((char *) files[filenum].mapped, files[filenum].mapped_size); if (files[filenum].import) num_import_syms += files[filenum].nsyms; else num_export_syms += files[filenum].nsyms; } if (!num_export_syms) { fprintf(stderr, "no export names\n"); exit(1); } import_symbols = calloc(num_import_syms, sizeof(struct symbol)); export_symbols = calloc(num_export_syms, sizeof(struct symbol)); import_idx = 0; export_idx = 0; for (filenum = 0; filenum < num_files; filenum++) { if (files[filenum].import) { store_symbols((char *) files[filenum].mapped, files[filenum].mapped_size, import_symbols, import_idx, num_import_syms); import_idx += files[filenum].nsyms; } else { store_symbols((char *) files[filenum].mapped, files[filenum].mapped_size, export_symbols, export_idx, num_export_syms); export_idx += files[filenum].nsyms; } if (false && !files[filenum].nsyms) { fprintf(stderr, "warning: file %s contains no names\n", files[filenum].path); } } qsort(import_symbols, num_import_syms, sizeof(struct symbol), &qsort_cmp); qsort(export_symbols, num_export_syms, sizeof(struct symbol), &qsort_cmp); result_count = 0; num_removed_syms = 0; strtabsize = 4; if (num_import_syms) { for (export_idx = 0; export_idx < num_export_syms; export_idx++) { struct symbol * result; char * name; size_t len; boolean_t wild; name = export_symbols[export_idx].indirect; len = export_symbols[export_idx].indirect_len; if (!name) { name = export_symbols[export_idx].name; len = export_symbols[export_idx].name_len; } wild = ((len > 2) && ('*' == name[len-=2])); if (wild) { struct bsearch_key key; key.name = name; key.name_len = len; result = bsearch(&key, import_symbols, num_import_syms, sizeof(struct symbol), &bsearch_cmp_prefix); if (result) { struct symbol * first; struct symbol * last; strtabsize += (result->name_len + result->indirect_len); first = result; while (--first >= &import_symbols[0]) { if (bsearch_cmp_prefix(&key, first)) break; strtabsize += (first->name_len + first->indirect_len); } first++; last = result; while (++last < (&import_symbols[0] + num_import_syms)) { if (bsearch_cmp_prefix(&key, last)) break; strtabsize += (last->name_len + last->indirect_len); } result_count += last - first; result = first; export_symbols[export_idx].list = first; export_symbols[export_idx].list_count = last - first; export_symbols[export_idx].flags |= kExported; } } else result = bsearch(name, import_symbols, num_import_syms, sizeof(struct symbol), &bsearch_cmp); if (!result && require_imports) { int status; char * demangled_result = __cxa_demangle(export_symbols[export_idx].name + 1, NULL, NULL, &status); fprintf(stderr, "exported name not in import list: %s\n", demangled_result ? demangled_result : export_symbols[export_idx].name); // fprintf(stderr, " : %s\n", export_symbols[export_idx].name); if (demangled_result) { free(demangled_result); } num_removed_syms++; } if (diff) { if (!result) result = &export_symbols[export_idx]; else result = NULL; } if (result && !wild) { export_symbols[export_idx].flags |= kExported; strtabsize += (export_symbols[export_idx].name_len + export_symbols[export_idx].indirect_len); result_count++; export_symbols[export_idx].list = &export_symbols[export_idx]; export_symbols[export_idx].list_count = 1; } } } strtabpad = (strtabsize + 3) & ~3; if (require_imports && num_removed_syms) { err = kError; goto finish; } fd = open(output_name, O_WRONLY|O_CREAT|O_TRUNC, 0755); if (-1 == fd) { perror("couldn't write output"); err = kErrorFileAccess; goto finish; } struct symtab_command symcmd; struct uuid_command uuidcmd; symcmd.cmd = LC_SYMTAB; symcmd.cmdsize = sizeof(symcmd); symcmd.symoff = sizeof(symcmd) + sizeof(uuidcmd); symcmd.nsyms = result_count; symcmd.strsize = strtabpad; uuidcmd.cmd = LC_UUID; uuidcmd.cmdsize = sizeof(uuidcmd); uuid_generate(uuidcmd.uuid); if (CPU_ARCH_ABI64 & target_arch->cputype) { struct mach_header_64 hdr; hdr.magic = MH_MAGIC_64; hdr.cputype = target_arch->cputype; hdr.cpusubtype = target_arch->cpusubtype; hdr.filetype = MH_KEXT_BUNDLE; hdr.ncmds = 2; hdr.sizeofcmds = sizeof(symcmd) + sizeof(uuidcmd); hdr.flags = MH_INCRLINK; symcmd.symoff += sizeof(hdr); symcmd.stroff = result_count * sizeof(struct nlist_64) + symcmd.symoff; if (target_arch->byteorder != host_arch->byteorder) swap_mach_header_64(&hdr, target_arch->byteorder); err = writeFile(fd, &hdr, sizeof(hdr)); } else { struct mach_header hdr; hdr.magic = MH_MAGIC; hdr.cputype = target_arch->cputype; hdr.cpusubtype = target_arch->cpusubtype; hdr.filetype = (target_arch->cputype == CPU_TYPE_I386) ? MH_OBJECT : MH_KEXT_BUNDLE; hdr.ncmds = 2; hdr.sizeofcmds = sizeof(symcmd) + sizeof(uuidcmd); hdr.flags = MH_INCRLINK; symcmd.symoff += sizeof(hdr); symcmd.stroff = result_count * sizeof(struct nlist) + symcmd.symoff; if (target_arch->byteorder != host_arch->byteorder) swap_mach_header(&hdr, target_arch->byteorder); err = writeFile(fd, &hdr, sizeof(hdr)); } if (kErrorNone != err) goto finish; if (target_arch->byteorder != host_arch->byteorder) { swap_symtab_command(&symcmd, target_arch->byteorder); swap_uuid_command(&uuidcmd, target_arch->byteorder); } err = writeFile(fd, &symcmd, sizeof(symcmd)); if (kErrorNone != err) goto finish; err = writeFile(fd, &uuidcmd, sizeof(uuidcmd)); if (kErrorNone != err) goto finish; strx = 4; for (export_idx = 0; export_idx < num_export_syms; export_idx++) { if (!export_symbols[export_idx].name) continue; if (!(kExported & export_symbols[export_idx].flags)) continue; if (export_idx && export_symbols[export_idx - 1].name && !strcmp(export_symbols[export_idx - 1].name, export_symbols[export_idx].name)) { fprintf(stderr, "duplicate export: %s\n", export_symbols[export_idx - 1].name); err = kErrorDuplicate; goto finish; } for (import_idx = 0; import_idx < export_symbols[export_idx].list_count; import_idx++) { if (export_symbols[export_idx].list != &export_symbols[export_idx]) { printf("wild: %s, %s\n", export_symbols[export_idx].name, export_symbols[export_idx].list[import_idx].name); } if (CPU_ARCH_ABI64 & target_arch->cputype) { struct nlist_64 nl; nl.n_sect = 0; nl.n_desc = 0; nl.n_un.n_strx = strx; strx += export_symbols[export_idx].list[import_idx].name_len; if (export_symbols[export_idx].flags & kObsolete) { nl.n_desc |= N_DESC_DISCARDED; } if (export_symbols[export_idx].list[import_idx].indirect) { nl.n_type = N_INDR | N_EXT; nl.n_value = strx; strx += export_symbols[export_idx].list[import_idx].indirect_len; } else { nl.n_type = N_UNDF | N_EXT; nl.n_value = 0; } if (target_arch->byteorder != host_arch->byteorder) swap_nlist_64(&nl, 1, target_arch->byteorder); err = writeFile(fd, &nl, sizeof(nl)); } else { struct nlist nl; nl.n_sect = 0; nl.n_desc = 0; nl.n_un.n_strx = strx; strx += export_symbols[export_idx].list[import_idx].name_len; if (export_symbols[export_idx].flags & kObsolete) { nl.n_desc |= N_DESC_DISCARDED; } if (export_symbols[export_idx].list[import_idx].indirect) { nl.n_type = N_INDR | N_EXT; nl.n_value = strx; strx += export_symbols[export_idx].list[import_idx].indirect_len; } else { nl.n_type = N_UNDF | N_EXT; nl.n_value = 0; } if (target_arch->byteorder != host_arch->byteorder) swap_nlist(&nl, 1, target_arch->byteorder); err = writeFile(fd, &nl, sizeof(nl)); } } if (kErrorNone != err) goto finish; } strx = sizeof(uint32_t); err = writeFile(fd, &zero, strx); if (kErrorNone != err) goto finish; for (export_idx = 0; export_idx < num_export_syms; export_idx++) { if (!export_symbols[export_idx].name) continue; for (import_idx = 0; import_idx < export_symbols[export_idx].list_count; import_idx++) { err = writeFile(fd, export_symbols[export_idx].list[import_idx].name, export_symbols[export_idx].list[import_idx].name_len); if (kErrorNone != err) goto finish; if (export_symbols[export_idx].list[import_idx].indirect) { err = writeFile(fd, export_symbols[export_idx].list[import_idx].indirect, export_symbols[export_idx].list[import_idx].indirect_len); if (kErrorNone != err) goto finish; } } } err = writeFile(fd, &zero, strtabpad - strtabsize); if (kErrorNone != err) goto finish; close(fd); finish: for (filenum = 0; filenum < num_files; filenum++) { // unmap file if (files[filenum].mapped_size) { munmap((caddr_t)files[filenum].mapped, files[filenum].mapped_size); files[filenum].mapped = 0; files[filenum].mapped_size = 0; } } if (kErrorNone != err) { if (output_name) unlink(output_name); exit(1); } else exit(0); return(0); }