📄 translate-copy.c
字号:
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 + -