int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size, 

                     int *gen_code_size_ptr,

                     uint8_t *pc_start,  uint8_t *cs_base, int flags)

{

    DisasContext dc1, *dc = &dc1;

    uint8_t *pc_ptr;

    uint16_t *gen_opc_end;

    int gen_code_size;

    long ret;

#ifdef DEBUG_DISAS

    struct disassemble_info disasm_info;

#endif

    

    /* generate intermediate code */



    dc->code32 = (flags >> GEN_FLAG_CODE32_SHIFT) & 1;

    dc->ss32 = (flags >> GEN_FLAG_SS32_SHIFT) & 1;

    dc->addseg = (flags >> GEN_FLAG_ADDSEG_SHIFT) & 1;

    dc->f_st = (flags >> GEN_FLAG_ST_SHIFT) & 7;

    dc->cc_op = CC_OP_DYNAMIC;

    dc->cs_base = cs_base;



    gen_opc_ptr = gen_opc_buf;

    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;

    gen_opparam_ptr = gen_opparam_buf;



    dc->is_jmp = 0;

    pc_ptr = pc_start;

    do {

        ret = disas_insn(dc, pc_ptr);

        if (ret == -1) {

            /* we trigger an illegal instruction operation only if it

               is the first instruction. Otherwise, we simply stop

               generating the code just before it */

            if (pc_ptr == pc_start)

                return -1;

            else

                break;

        }

        pc_ptr = (void *)ret;

    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end);

    /* we must store the eflags state if it is not already done */

    if (dc->cc_op != CC_OP_DYNAMIC)

        gen_op_set_cc_op(dc->cc_op);

    if (dc->is_jmp != 1) {

        /* we add an additionnal jmp to update the simulated PC */

        gen_op_jmp_im(ret - (unsigned long)dc->cs_base);

    }

    *gen_opc_ptr = INDEX_op_end;



    /* optimize flag computations */

#ifdef DEBUG_DISAS

    if (loglevel) {

        uint8_t *pc;

        int count;



        INIT_DISASSEMBLE_INFO(disasm_info, logfile, fprintf);

#if 0        

        disasm_info.flavour = bfd_get_flavour (abfd);

        disasm_info.arch = bfd_get_arch (abfd);

        disasm_info.mach = bfd_get_mach (abfd);

#endif

        disasm_info.endian = BFD_ENDIAN_LITTLE;

        if (dc->code32)

            disasm_info.mach = bfd_mach_i386_i386;

        else

            disasm_info.mach = bfd_mach_i386_i8086;

        fprintf(logfile, "----------------\n");

        fprintf(logfile, "IN:\n");

        disasm_info.buffer = pc_start;

        disasm_info.buffer_vma = (unsigned long)pc_start;

        disasm_info.buffer_length = pc_ptr - pc_start;

        pc = pc_start;

        while (pc < pc_ptr) {

            fprintf(logfile, "0x%08lx:  ", (long)pc);

            count = print_insn_i386((unsigned long)pc, &disasm_info);

            fprintf(logfile, "\n");

            pc += count;

        }

        fprintf(logfile, "\n");

        

        fprintf(logfile, "OP:\n");

        dump_ops(gen_opc_buf);

        fprintf(logfile, "\n");

    }

#endif



    /* optimize flag computations */

    optimize_flags(gen_opc_buf, gen_opc_ptr - gen_opc_buf);



#ifdef DEBUG_DISAS

    if (loglevel) {

        fprintf(logfile, "AFTER FLAGS OPT:\n");

        dump_ops(gen_opc_buf);

        fprintf(logfile, "\n");

    }

#endif



    /* generate machine code */

    gen_code_size = dyngen_code(gen_code_buf, gen_opc_buf, gen_opparam_buf);

    flush_icache_range((unsigned long)gen_code_buf, (unsigned long)(gen_code_buf + gen_code_size));

    *gen_code_size_ptr = gen_code_size;



#ifdef DEBUG_DISAS

    if (loglevel) {

        uint8_t *pc;

        int count;



        INIT_DISASSEMBLE_INFO(disasm_info, logfile, fprintf);

#if 0        

        disasm_info.flavour = bfd_get_flavour (abfd);

        disasm_info.arch = bfd_get_arch (abfd);

        disasm_info.mach = bfd_get_mach (abfd);

#endif

#ifdef WORDS_BIGENDIAN

        disasm_info.endian = BFD_ENDIAN_BIG;

#else

        disasm_info.endian = BFD_ENDIAN_LITTLE;

#endif        

        disasm_info.mach = bfd_mach_i386_i386;



        pc = gen_code_buf;

        disasm_info.buffer = pc;

        disasm_info.buffer_vma = (unsigned long)pc;

        disasm_info.buffer_length = *gen_code_size_ptr;

        fprintf(logfile, "OUT: [size=%d]\n", *gen_code_size_ptr);

        while (pc < gen_code_buf + *gen_code_size_ptr) {

            fprintf(logfile, "0x%08lx:  ", (long)pc);

            count = print_insn_i386((unsigned long)pc, &disasm_info);

            fprintf(logfile, "\n");

            pc += count;

        }

        fprintf(logfile, "\n");

        fflush(logfile);

    }

#endif

    return 0;

}

int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size, 

                     int *gen_code_size_ptr,

                     uint8_t *pc_start,  uint8_t *cs_base, int flags)

{

    DisasContext dc1, *dc = &dc1;

    uint8_t *pc_ptr;

    uint16_t *gen_opc_end;

    int gen_code_size;

    long ret;

#ifdef DEBUG_DISAS

    struct disassemble_info disasm_info;

#endif

    

    



    dc->code32 = (flags >> GEN_FLAG_CODE32_SHIFT) & 1;

    dc->ss32 = (flags >> GEN_FLAG_SS32_SHIFT) & 1;

    dc->addseg = (flags >> GEN_FLAG_ADDSEG_SHIFT) & 1;

    dc->f_st = (flags >> GEN_FLAG_ST_SHIFT) & 7;

    dc->cc_op = CC_OP_DYNAMIC;

    dc->cs_base = cs_base;



    gen_opc_ptr = gen_opc_buf;

    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;

    gen_opparam_ptr = gen_opparam_buf;



    dc->is_jmp = 0;

    pc_ptr = pc_start;

    do {

        ret = disas_insn(dc, pc_ptr);

        if (ret == -1) {

            





            if (pc_ptr == pc_start)

                return -1;

            else

                break;

        }

        pc_ptr = (void *)ret;

    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end);

    

    if (dc->cc_op != CC_OP_DYNAMIC)

        gen_op_set_cc_op(dc->cc_op);

    if (dc->is_jmp != 1) {

        

        gen_op_jmp_im(ret - (unsigned long)dc->cs_base);

    }

    *gen_opc_ptr = INDEX_op_end;



    

#ifdef DEBUG_DISAS

    if (loglevel) {

        uint8_t *pc;

        int count;



        INIT_DISASSEMBLE_INFO(disasm_info, logfile, fprintf);

#if 0        

        disasm_info.flavour = bfd_get_flavour (abfd);

        disasm_info.arch = bfd_get_arch (abfd);

        disasm_info.mach = bfd_get_mach (abfd);

#endif

        disasm_info.endian = BFD_ENDIAN_LITTLE;

        if (dc->code32)

            disasm_info.mach = bfd_mach_i386_i386;

        else

            disasm_info.mach = bfd_mach_i386_i8086;

        fprintf(logfile, "----------------\n");

        fprintf(logfile, "IN:\n");

        disasm_info.buffer = pc_start;

        disasm_info.buffer_vma = (unsigned long)pc_start;

        disasm_info.buffer_length = pc_ptr - pc_start;

        pc = pc_start;

        while (pc < pc_ptr) {

            fprintf(logfile, "0x%08lx:  ", (long)pc);

            count = print_insn_i386((unsigned long)pc, &disasm_info);

            fprintf(logfile, "\n");

            pc += count;

        }

        fprintf(logfile, "\n");

        

        fprintf(logfile, "OP:\n");

        dump_ops(gen_opc_buf);

        fprintf(logfile, "\n");

    }

#endif



    

    optimize_flags(gen_opc_buf, gen_opc_ptr - gen_opc_buf);



#ifdef DEBUG_DISAS

    if (loglevel) {

        fprintf(logfile, "AFTER FLAGS OPT:\n");

        dump_ops(gen_opc_buf);

        fprintf(logfile, "\n");

    }

#endif



    

    gen_code_size = dyngen_code(gen_code_buf, gen_opc_buf, gen_opparam_buf);

    flush_icache_range((unsigned long)gen_code_buf, (unsigned long)(gen_code_buf + gen_code_size));

    *gen_code_size_ptr = gen_code_size;



#ifdef DEBUG_DISAS

    if (loglevel) {

        uint8_t *pc;

        int count;



        INIT_DISASSEMBLE_INFO(disasm_info, logfile, fprintf);

#if 0        

        disasm_info.flavour = bfd_get_flavour (abfd);

        disasm_info.arch = bfd_get_arch (abfd);

        disasm_info.mach = bfd_get_mach (abfd);

#endif

#ifdef WORDS_BIGENDIAN

        disasm_info.endian = BFD_ENDIAN_BIG;

#else

        disasm_info.endian = BFD_ENDIAN_LITTLE;

#endif        

        disasm_info.mach = bfd_mach_i386_i386;



        pc = gen_code_buf;

        disasm_info.buffer = pc;

        disasm_info.buffer_vma = (unsigned long)pc;

        disasm_info.buffer_length = *gen_code_size_ptr;

        fprintf(logfile, "OUT: [size=%d]\n", *gen_code_size_ptr);

        while (pc < gen_code_buf + *gen_code_size_ptr) {

            fprintf(logfile, "0x%08lx:  ", (long)pc);

            count = print_insn_i386((unsigned long)pc, &disasm_info);

            fprintf(logfile, "\n");

            pc += count;

        }

        fprintf(logfile, "\n");

        fflush(logfile);

    }

#endif

    return 0;

}

int FUNC_0(uint8_t *VAR_0, int VAR_1, 

                     int *VAR_2,

                     uint8_t *VAR_3,  uint8_t *VAR_4, int VAR_5)

{

    DisasContext dc1, *dc = &dc1;

    uint8_t *pc_ptr;

    uint16_t *gen_opc_end;

    int VAR_6;

    long VAR_7;

#ifdef DEBUG_DISAS

    struct disassemble_info disasm_info;

#endif

    

    



    dc->code32 = (VAR_5 >> GEN_FLAG_CODE32_SHIFT) & 1;

    dc->ss32 = (VAR_5 >> GEN_FLAG_SS32_SHIFT) & 1;

    dc->addseg = (VAR_5 >> GEN_FLAG_ADDSEG_SHIFT) & 1;

    dc->f_st = (VAR_5 >> GEN_FLAG_ST_SHIFT) & 7;

    dc->cc_op = CC_OP_DYNAMIC;

    dc->VAR_4 = VAR_4;



    gen_opc_ptr = gen_opc_buf;

    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;

    gen_opparam_ptr = gen_opparam_buf;



    dc->is_jmp = 0;

    pc_ptr = VAR_3;

    do {

        VAR_7 = disas_insn(dc, pc_ptr);

        if (VAR_7 == -1) {

            





            if (pc_ptr == VAR_3)

                return -1;

            else

                break;

        }

        pc_ptr = (void *)VAR_7;

    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end);

    

    if (dc->cc_op != CC_OP_DYNAMIC)

        gen_op_set_cc_op(dc->cc_op);

    if (dc->is_jmp != 1) {

        

        gen_op_jmp_im(VAR_7 - (unsigned long)dc->VAR_4);

    }

    *gen_opc_ptr = INDEX_op_end;



    

#ifdef DEBUG_DISAS

    if (loglevel) {

        uint8_t *pc;

        int count;



        INIT_DISASSEMBLE_INFO(disasm_info, logfile, fprintf);

#if 0        

        disasm_info.flavour = bfd_get_flavour (abfd);

        disasm_info.arch = bfd_get_arch (abfd);

        disasm_info.mach = bfd_get_mach (abfd);

#endif

        disasm_info.endian = BFD_ENDIAN_LITTLE;

        if (dc->code32)

            disasm_info.mach = bfd_mach_i386_i386;

        else

            disasm_info.mach = bfd_mach_i386_i8086;

        fprintf(logfile, "----------------\n");

        fprintf(logfile, "IN:\n");

        disasm_info.buffer = VAR_3;

        disasm_info.buffer_vma = (unsigned long)VAR_3;

        disasm_info.buffer_length = pc_ptr - VAR_3;

        pc = VAR_3;

        while (pc < pc_ptr) {

            fprintf(logfile, "0x%08lx:  ", (long)pc);

            count = print_insn_i386((unsigned long)pc, &disasm_info);

            fprintf(logfile, "\n");

            pc += count;

        }

        fprintf(logfile, "\n");

        

        fprintf(logfile, "OP:\n");

        dump_ops(gen_opc_buf);

        fprintf(logfile, "\n");

    }

#endif



    

    optimize_flags(gen_opc_buf, gen_opc_ptr - gen_opc_buf);



#ifdef DEBUG_DISAS

    if (loglevel) {

        fprintf(logfile, "AFTER FLAGS OPT:\n");

        dump_ops(gen_opc_buf);

        fprintf(logfile, "\n");

    }

#endif



    

    VAR_6 = dyngen_code(VAR_0, gen_opc_buf, gen_opparam_buf);

    flush_icache_range((unsigned long)VAR_0, (unsigned long)(VAR_0 + VAR_6));

    *VAR_2 = VAR_6;



#ifdef DEBUG_DISAS

    if (loglevel) {

        uint8_t *pc;

        int count;



        INIT_DISASSEMBLE_INFO(disasm_info, logfile, fprintf);

#if 0        

        disasm_info.flavour = bfd_get_flavour (abfd);

        disasm_info.arch = bfd_get_arch (abfd);

        disasm_info.mach = bfd_get_mach (abfd);

#endif

#ifdef WORDS_BIGENDIAN

        disasm_info.endian = BFD_ENDIAN_BIG;

#else

        disasm_info.endian = BFD_ENDIAN_LITTLE;

#endif        

        disasm_info.mach = bfd_mach_i386_i386;



        pc = VAR_0;

        disasm_info.buffer = pc;

        disasm_info.buffer_vma = (unsigned long)pc;

        disasm_info.buffer_length = *VAR_2;

        fprintf(logfile, "OUT: [size=%d]\n", *VAR_2);

        while (pc < VAR_0 + *VAR_2) {

            fprintf(logfile, "0x%08lx:  ", (long)pc);

            count = print_insn_i386((unsigned long)pc, &disasm_info);

            fprintf(logfile, "\n");

            pc += count;

        }

        fprintf(logfile, "\n");

        fflush(logfile);

    }

#endif

    return 0;

}

int FUNC_0(uint8_t *VAR_0, int VAR_1,
int *VAR_2,
uint8_t *VAR_3,  uint8_t *VAR_4, int VAR_5)
{ DisasContext dc1, *dc = &dc1; uint8_t *pc_ptr; uint16_t *gen_opc_end; int VAR_6; long VAR_7; #ifdef DEBUG_DISAS
struct disassemble_info disasm_info; #endif
dc->code32 = (VAR_5 >> GEN_FLAG_CODE32_SHIFT) & 1; dc->ss32 = (VAR_5 >> GEN_FLAG_SS32_SHIFT) & 1; dc->addseg = (VAR_5 >> GEN_FLAG_ADDSEG_SHIFT) & 1; dc->f_st = (VAR_5 >> GEN_FLAG_ST_SHIFT) & 7; dc->cc_op = CC_OP_DYNAMIC; dc->VAR_4 = VAR_4; gen_opc_ptr = gen_opc_buf; gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; gen_opparam_ptr = gen_opparam_buf; dc->is_jmp = 0; pc_ptr = VAR_3; do { VAR_7 = disas_insn(dc, pc_ptr); if (VAR_7 == -1) { if (pc_ptr == VAR_3)
return -1; else
break; } pc_ptr = (void *)VAR_7; } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end); if (dc->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(dc->cc_op); if (dc->is_jmp != 1) { gen_op_jmp_im(VAR_7 - (unsigned long)dc->VAR_4); } *gen_opc_ptr = INDEX_op_end; #ifdef DEBUG_DISAS
if (loglevel) { uint8_t *pc; int count; INIT_DISASSEMBLE_INFO(disasm_info, logfile, fprintf); #if 0
disasm_info.flavour = bfd_get_flavour (abfd); disasm_info.arch = bfd_get_arch (abfd); disasm_info.mach = bfd_get_mach (abfd); #endif
disasm_info.endian = BFD_ENDIAN_LITTLE; if (dc->code32)
disasm_info.mach = bfd_mach_i386_i386; else
disasm_info.mach = bfd_mach_i386_i8086; fprintf(logfile, "----------------\n"); fprintf(logfile, "IN:\n"); disasm_info.buffer = VAR_3; disasm_info.buffer_vma = (unsigned long)VAR_3; disasm_info.buffer_length = pc_ptr - VAR_3; pc = VAR_3; while (pc < pc_ptr) { fprintf(logfile, "0x%08lx:  ", (long)pc); count = print_insn_i386((unsigned long)pc, &disasm_info); fprintf(logfile, "\n"); pc += count; } fprintf(logfile, "\n"); fprintf(logfile, "OP:\n"); dump_ops(gen_opc_buf); fprintf(logfile, "\n"); } #endif
optimize_flags(gen_opc_buf, gen_opc_ptr - gen_opc_buf); #ifdef DEBUG_DISAS
if (loglevel) { fprintf(logfile, "AFTER FLAGS OPT:\n"); dump_ops(gen_opc_buf); fprintf(logfile, "\n"); } #endif
VAR_6 = dyngen_code(VAR_0, gen_opc_buf, gen_opparam_buf); flush_icache_range((unsigned long)VAR_0, (unsigned long)(VAR_0 + VAR_6)); *VAR_2 = VAR_6; #ifdef DEBUG_DISAS
if (loglevel) { uint8_t *pc; int count; INIT_DISASSEMBLE_INFO(disasm_info, logfile, fprintf); #if 0
disasm_info.flavour = bfd_get_flavour (abfd); disasm_info.arch = bfd_get_arch (abfd); disasm_info.mach = bfd_get_mach (abfd); #endif
#ifdef WORDS_BIGENDIAN
disasm_info.endian = BFD_ENDIAN_BIG; #else
disasm_info.endian = BFD_ENDIAN_LITTLE; #endif
disasm_info.mach = bfd_mach_i386_i386; pc = VAR_0; disasm_info.buffer = pc; disasm_info.buffer_vma = (unsigned long)pc; disasm_info.buffer_length = *VAR_2; fprintf(logfile, "OUT: [size=%d]\n", *VAR_2); while (pc < VAR_0 + *VAR_2) { fprintf(logfile, "0x%08lx:  ", (long)pc); count = print_insn_i386((unsigned long)pc, &disasm_info); fprintf(logfile, "\n"); pc += count; } fprintf(logfile, "\n"); fflush(logfile); } #endif
return 0; }