⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 translate-copy.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    case 0x1a4: /* shld imm */    case 0x1ac: /* shrd imm */        modrm = ldub_code(s->pc++);        parse_modrm(s, modrm);        ldub_code(s->pc++);        break;                /************************/        /* string ops */    case 0xa4: /* movsS */    case 0xa5:        break;            case 0xaa: /* stosS */    case 0xab:        break;    case 0xac: /* lodsS */    case 0xad:        break;    case 0xae: /* scasS */    case 0xaf:        break;    case 0xa6: /* cmpsS */    case 0xa7:        break;    case 0x6c: /* insS */    case 0x6d:        goto unsupported_op;    case 0x6e: /* outsS */    case 0x6f:        goto unsupported_op;        /************************/        /* port I/O */    case 0xe4:    case 0xe5:        goto unsupported_op;    case 0xe6:    case 0xe7:        goto unsupported_op;    case 0xec:    case 0xed:        goto unsupported_op;    case 0xee:    case 0xef:        goto unsupported_op;        /************************/        /* control */#if 0    case 0xc2: /* ret im */        val = ldsw_code(s->pc);        s->pc += 2;        gen_pop_T0(s);        gen_stack_update(s, val + (2 << s->dflag));        if (s->dflag == 0)            gen_op_andl_T0_ffff();        gen_op_jmp_T0();        gen_eob(s);        break;#endif    case 0xc3: /* ret */        gb(s, CPU_SEG);        if (!s->dflag)              gb(s, 0x66); /* d16 */        gb(s, 0x8f); /* pop addr */        gb(s, 0x05);        gl(s, CPU_FIELD_OFFSET(eip));        if (!s->dflag) {            /* reset high bits of EIP */            gen_movw_addr_im(s, CPU_FIELD_OFFSET(eip) + 2, 0);        }        gen_eob(s);        goto no_copy;    case 0xca: /* lret im */    case 0xcb: /* lret */    case 0xcf: /* iret */    case 0x9a: /* lcall im */    case 0xea: /* ljmp im */        goto unsupported_op;    case 0xe8: /* call im */        ot = dflag ? OT_LONG : OT_WORD;        val = insn_get(s, ot);        next_eip = s->pc - s->cs_base;        val += next_eip;        if (s->dflag) {            gb(s, 0x68); /* pushl imm */            gl(s, next_eip);        } else {            gb(s, 0x66); /* pushw imm */            gb(s, 0x68);            gw(s, next_eip);            val &= 0xffff;        }        gen_jmp(s, val);        goto no_copy;    case 0xe9: /* jmp */        ot = dflag ? OT_LONG : OT_WORD;        val = insn_get(s, ot);        val += s->pc - s->cs_base;        if (s->dflag == 0)            val = val & 0xffff;        gen_jmp(s, val);        goto no_copy;    case 0xeb: /* jmp Jb */        val = (int8_t)insn_get(s, OT_BYTE);        val += s->pc - s->cs_base;        if (s->dflag == 0)            val = val & 0xffff;        gen_jmp(s, val);        goto no_copy;    case 0x70 ... 0x7f: /* jcc Jb */        val = (int8_t)insn_get(s, OT_BYTE);        goto do_jcc;    case 0x180 ... 0x18f: /* jcc Jv */        if (dflag) {            val = insn_get(s, OT_LONG);        } else {            val = (int16_t)insn_get(s, OT_WORD);         }    do_jcc:        next_eip = s->pc - s->cs_base;        val += next_eip;        if (s->dflag == 0)            val &= 0xffff;        gen_jcc(s, b & 0xf, val, next_eip);        goto no_copy;        /************************/        /* flags */    case 0x9c: /* pushf */        /* XXX: put specific code ? */        goto unsupported_op;    case 0x9d: /* popf */        goto unsupported_op;    case 0x9e: /* sahf */    case 0x9f: /* lahf */    case 0xf5: /* cmc */    case 0xf8: /* clc */    case 0xf9: /* stc */    case 0xfc: /* cld */    case 0xfd: /* std */        break;        /************************/        /* bit operations */    case 0x1ba: /* bt/bts/btr/btc Gv, im */        ot = dflag ? OT_LONG : OT_WORD;        modrm = ldub_code(s->pc++);        op = (modrm >> 3) & 7;        parse_modrm(s, modrm);        /* load shift */        ldub_code(s->pc++);        if (op < 4)            goto illegal_op;        break;        /************************/        /* bcd */    case 0x27: /* daa */        break;    case 0x2f: /* das */        break;    case 0x37: /* aaa */        break;    case 0x3f: /* aas */        break;    case 0xd4: /* aam */        ldub_code(s->pc++);        break;    case 0xd5: /* aad */        ldub_code(s->pc++);        break;        /************************/        /* misc */    case 0x90: /* nop */        break;    case 0x9b: /* fwait */        if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==             (HF_MP_MASK | HF_TS_MASK)) {            goto unsupported_op;        }        break;    case 0xcc: /* int3 */        goto unsupported_op;    case 0xcd: /* int N */        goto unsupported_op;    case 0xce: /* into */        goto unsupported_op;    case 0xf1: /* icebp (undocumented, exits to external debugger) */        goto unsupported_op;    case 0xfa: /* cli */        goto unsupported_op;    case 0xfb: /* sti */        goto unsupported_op;    case 0x62: /* bound */        modrm = ldub_code(s->pc++);        mod = (modrm >> 6) & 3;        if (mod == 3)            goto illegal_op;        parse_modrm(s, modrm);        break;    case 0x1c8 ... 0x1cf: /* bswap reg */        break;    case 0xd6: /* salc */        break;    case 0xe0: /* loopnz */    case 0xe1: /* loopz */    case 0xe2: /* loop */    case 0xe3: /* jecxz */        goto unsupported_op;    case 0x130: /* wrmsr */    case 0x132: /* rdmsr */        goto unsupported_op;    case 0x131: /* rdtsc */        goto unsupported_op;    case 0x1a2: /* cpuid */        goto unsupported_op;    case 0xf4: /* hlt */        goto unsupported_op;    case 0x100:        goto unsupported_op;    case 0x101:        goto unsupported_op;    case 0x108: /* invd */    case 0x109: /* wbinvd */        goto unsupported_op;    case 0x63: /* arpl */        goto unsupported_op;    case 0x102: /* lar */    case 0x103: /* lsl */        goto unsupported_op;    case 0x118:        goto unsupported_op;    case 0x120: /* mov reg, crN */    case 0x122: /* mov crN, reg */        goto unsupported_op;    case 0x121: /* mov reg, drN */    case 0x123: /* mov drN, reg */        goto unsupported_op;    case 0x106: /* clts */        goto unsupported_op;    default:        goto illegal_op;    }    /* just copy the code */    /* no override yet */    if (!s->dflag)        gb(s, 0x66);    if (!s->aflag)        gb(s, 0x67);    if (prefixes & PREFIX_REPZ)        gb(s, 0xf3);    else if (prefixes & PREFIX_REPNZ)        gb(s, 0xf2);    {        int len, i;        len = s->pc - pc_start_insn;        for(i = 0; i < len; i++) {            *s->gen_code_ptr++ = ldub_code(pc_start_insn + i);        }    } no_copy:    return 0; illegal_op: unsupported_op:    /* fall back to slower code gen necessary */    s->pc = pc_start;    return -1;}#define GEN_CODE_MAX_SIZE      8192#define GEN_CODE_MAX_INSN_SIZE 512static inline int gen_intermediate_code_internal(CPUState *env,                                                 TranslationBlock *tb,                                                  uint8_t *gen_code_ptr,                                                 int *gen_code_size_ptr,                                                 int search_pc,                                                 uint8_t *tc_ptr){    DisasContext dc1, *dc = &dc1;    target_ulong pc_insn, pc_start, cs_base;    uint8_t *gen_code_end;    int flags, ret;    if (env->nb_breakpoints > 0 ||        env->singlestep_enabled)        return -1;    flags = tb->flags;    if (flags & (HF_TF_MASK | HF_ADDSEG_MASK |                  HF_SOFTMMU_MASK | HF_INHIBIT_IRQ_MASK))        return -1;    if (!(flags & HF_SS32_MASK))        return -1;    if (tb->cflags & CF_SINGLE_INSN)        return -1;    gen_code_end = gen_code_ptr +         GEN_CODE_MAX_SIZE - GEN_CODE_MAX_INSN_SIZE;    dc->gen_code_ptr = gen_code_ptr;    dc->gen_code_start = gen_code_ptr;    /* generate intermediate code */    pc_start = tb->pc;    cs_base = tb->cs_base;    dc->pc = pc_start;    dc->cs_base = cs_base;    dc->pe = (flags >> HF_PE_SHIFT) & 1;    dc->code32 = (flags >> HF_CS32_SHIFT) & 1;    dc->f_st = 0;    dc->vm86 = (flags >> VM_SHIFT) & 1;    dc->cpl = (flags >> HF_CPL_SHIFT) & 3;    dc->iopl = (flags >> IOPL_SHIFT) & 3;    dc->tb = tb;    dc->flags = flags;    dc->is_jmp = 0;    for(;;) {        pc_insn = dc->pc;        ret = disas_insn(dc);        if (ret < 0) {            /* unsupported insn */            if (dc->pc == pc_start) {                /* if first instruction, signal that no copying was done */                return -1;            } else {                gen_jmp(dc, dc->pc - dc->cs_base);                dc->is_jmp = 1;            }        }        if (search_pc) {            /* search pc mode */            if (tc_ptr < dc->gen_code_ptr) {                env->eip = pc_insn - cs_base;                return 0;            }        }        /* stop translation if indicated */        if (dc->is_jmp)            break;        /* if too long translation, stop generation */        if (dc->gen_code_ptr >= gen_code_end ||            (dc->pc - pc_start) >= (TARGET_PAGE_SIZE - 32)) {            gen_jmp(dc, dc->pc - dc->cs_base);            break;        }    }    #ifdef DEBUG_DISAS    if (loglevel & CPU_LOG_TB_IN_ASM) {        fprintf(logfile, "----------------\n");        fprintf(logfile, "IN: COPY: %s fpu=%d\n",                 lookup_symbol(pc_start),                tb->cflags & CF_TB_FP_USED ? 1 : 0);	target_disas(logfile, pc_start, dc->pc - pc_start, !dc->code32);        fprintf(logfile, "\n");    }#endif    if (!search_pc) {        *gen_code_size_ptr = dc->gen_code_ptr - dc->gen_code_start;        tb->size = dc->pc - pc_start;        tb->cflags |= CF_CODE_COPY;        return 0;    } else {        return -1;    }}/* generate code by just copying data. Return -1 if cannot generate   any code. Return 0 if code was generated */int cpu_gen_code_copy(CPUState *env, TranslationBlock *tb,                      int max_code_size, int *gen_code_size_ptr){    /* generate machine code */    tb->tb_next_offset[0] = 0xffff;    tb->tb_next_offset[1] = 0xffff;#ifdef USE_DIRECT_JUMP    /* the following two entries are optional (only used for string ops) */    tb->tb_jmp_offset[2] = 0xffff;    tb->tb_jmp_offset[3] = 0xffff;#endif    return gen_intermediate_code_internal(env, tb,                                           tb->tc_ptr, gen_code_size_ptr,                                          0, NULL);}static uint8_t dummy_gen_code_buf[GEN_CODE_MAX_SIZE];int cpu_restore_state_copy(TranslationBlock *tb,                            CPUState *env, unsigned long searched_pc,                           void *puc){    struct ucontext *uc = puc;    int ret, eflags;    /* find opc index corresponding to search_pc */    if (searched_pc < (unsigned long)tb->tc_ptr)        return -1;    searched_pc = searched_pc - (long)tb->tc_ptr + (long)dummy_gen_code_buf;    ret = gen_intermediate_code_internal(env, tb,                                          dummy_gen_code_buf, NULL,                                         1, (uint8_t *)searched_pc);    if (ret < 0)        return ret;    /* restore all the CPU state from the CPU context from the       signal. The FPU context stays in the host CPU. */        env->regs[R_EAX] = uc->uc_mcontext.gregs[REG_EAX];    env->regs[R_ECX] = uc->uc_mcontext.gregs[REG_ECX];    env->regs[R_EDX] = uc->uc_mcontext.gregs[REG_EDX];    env->regs[R_EBX] = uc->uc_mcontext.gregs[REG_EBX];    env->regs[R_ESP] = uc->uc_mcontext.gregs[REG_ESP];    env->regs[R_EBP] = uc->uc_mcontext.gregs[REG_EBP];    env->regs[R_ESI] = uc->uc_mcontext.gregs[REG_ESI];    env->regs[R_EDI] = uc->uc_mcontext.gregs[REG_EDI];    eflags = uc->uc_mcontext.gregs[REG_EFL];    env->df = 1 - (2 * ((eflags >> 10) & 1));    env->cc_src = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);    env->cc_op = CC_OP_EFLAGS;    return 0;}#endif /* USE_CODE_COPY */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -