diff options
author | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2004-04-25 17:57:43 +0000 |
---|---|---|
committer | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2004-04-25 17:57:43 +0000 |
commit | d720b93d0bcfe1beb729245b9ed1e5f071a24bd5 (patch) | |
tree | 4f9d65b82b9eb8bd65681cfde6bb18e7b6bd2eae /target-i386 | |
parent | eeab3a558f89e30ee93ef628bcbd6a3f64b9b8a6 (diff) |
precise self modifying code support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@745 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-i386')
-rw-r--r-- | target-i386/cpu.h | 18 | ||||
-rw-r--r-- | target-i386/translate-copy.c | 2 | ||||
-rw-r--r-- | target-i386/translate.c | 6 |
3 files changed, 22 insertions, 4 deletions
diff --git a/target-i386/cpu.h b/target-i386/cpu.h index daa2133f8e..6b2a89bb9a 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -22,6 +22,12 @@ #define TARGET_LONG_BITS 32 +/* target supports implicit self modifying code */ +#define TARGET_HAS_SMC +/* support for self modifying code even if the modified instruction is + close to the modifying instruction */ +#define TARGET_HAS_PRECISE_SMC + #include "cpu-defs.h" #if defined(__i386__) && !defined(CONFIG_SOFTMMU) @@ -331,8 +337,16 @@ typedef struct CPUX86State { int interrupt_request; int user_mode_only; /* user mode only simulation */ - /* soft mmu support */ uint32_t a20_mask; + + /* soft mmu support */ + /* in order to avoid passing too many arguments to the memory + write helpers, we store some rarely used information in the CPU + context) */ + unsigned long mem_write_pc; /* host pc at which the memory was + written */ + unsigned long mem_write_vaddr; /* target virtual addr at which the + memory was written */ /* 0 = kernel, 1 = user */ CPUTLBEntry tlb_read[2][CPU_TLB_SIZE]; CPUTLBEntry tlb_write[2][CPU_TLB_SIZE]; @@ -358,7 +372,7 @@ int cpu_x86_inl(CPUX86State *env, int addr); CPUX86State *cpu_x86_init(void); int cpu_x86_exec(CPUX86State *s); void cpu_x86_close(CPUX86State *s); -int cpu_x86_get_pic_interrupt(CPUX86State *s); +int cpu_get_pic_interrupt(CPUX86State *s); /* this function must always be used to load data in the segment cache: it synchronizes the hflags with the segment cache values */ diff --git a/target-i386/translate-copy.c b/target-i386/translate-copy.c index 500475a74a..e6f9198abc 100644 --- a/target-i386/translate-copy.c +++ b/target-i386/translate-copy.c @@ -1189,6 +1189,8 @@ static inline int gen_intermediate_code_internal(CPUState *env, 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; diff --git a/target-i386/translate.c b/target-i386/translate.c index 4bddba56a3..a1a4c633dc 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -4491,7 +4491,7 @@ static inline int gen_intermediate_code_internal(CPUState *env, DisasContext dc1, *dc = &dc1; uint8_t *pc_ptr; uint16_t *gen_opc_end; - int flags, j, lj; + int flags, j, lj, cflags; uint8_t *pc_start; uint8_t *cs_base; @@ -4499,6 +4499,7 @@ static inline int gen_intermediate_code_internal(CPUState *env, pc_start = (uint8_t *)tb->pc; cs_base = (uint8_t *)tb->cs_base; flags = tb->flags; + cflags = tb->cflags; dc->pe = (flags >> HF_PE_SHIFT) & 1; dc->code32 = (flags >> HF_CS32_SHIFT) & 1; @@ -4573,7 +4574,8 @@ static inline int gen_intermediate_code_internal(CPUState *env, the flag and abort the translation to give the irqs a change to be happen */ if (dc->tf || dc->singlestep_enabled || - (flags & HF_INHIBIT_IRQ_MASK)) { + (flags & HF_INHIBIT_IRQ_MASK) || + (cflags & CF_SINGLE_INSN)) { gen_op_jmp_im(pc_ptr - dc->cs_base); gen_eob(dc); break; |