Ejemplo n.º 1
0
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");
}
Ejemplo n.º 2
0
/**
 *  エンコード関数
 *  @param const char *filename 開くファイル名
 *  @return int 成功
 */
int encode(const char *filename)
{
    count_symbols(filename);    // シンボル数のカウント
    Node *root = build_tree();  // 符号の木を作る
    traverse_tree(0, root);     // 符号を当てる
    
    return 1;
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
0
/*
 * 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);
}
Ejemplo n.º 5
0
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);
}
Ejemplo n.º 6
0
/**
 *  エンコード関数
 *  @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;
}
Ejemplo n.º 7
0
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);
}
Ejemplo n.º 8
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;
    }
}
Ejemplo n.º 9
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);
}