diff --git a/target-i386/exec.h b/target-i386/exec.h index 3f6ddf1b4b0ebd346b8d49be43b1b81e2b014cda..63010f745dfacf4eb53ffd3bc85af2da966ad405 100644 --- a/target-i386/exec.h +++ b/target-i386/exec.h @@ -123,11 +123,11 @@ typedef struct CCTable { extern CCTable cc_table[]; void load_seg(int seg_reg, int selector); -void helper_ljmp_protected_T0_T1(void); +void helper_ljmp_protected_T0_T1(int next_eip); void helper_lcall_real_T0_T1(int shift, int next_eip); void helper_lcall_protected_T0_T1(int shift, int next_eip); void helper_iret_real(int shift); -void helper_iret_protected(int shift); +void helper_iret_protected(int shift, int next_eip); void helper_lret_protected(int shift, int addend); void helper_lldt_T0(void); void helper_ltr_T0(void); diff --git a/target-i386/helper.c b/target-i386/helper.c index 6239436315ceb0bd600358f71d699851c505e892..dbdabd82ee685ff3162b21eeebf3a47594d09420 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -1219,7 +1219,7 @@ void load_seg(int seg_reg, int selector) } /* protected mode jump */ -void helper_ljmp_protected_T0_T1(void) +void helper_ljmp_protected_T0_T1(int next_eip) { int new_cs, new_eip, gate_cs, type; uint32_t e1, e2, cpl, dpl, rpl, limit; @@ -1267,8 +1267,7 @@ void helper_ljmp_protected_T0_T1(void) case 5: /* task gate */ if (dpl < cpl || dpl < rpl) raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); - /* XXX: check if it is really the current EIP */ - switch_tss(new_cs, e1, e2, SWITCH_TSS_JMP, env->eip); + switch_tss(new_cs, e1, e2, SWITCH_TSS_JMP, next_eip); break; case 4: /* 286 call gate */ case 12: /* 386 call gate */ @@ -1732,7 +1731,7 @@ static inline void helper_ret_protected(int shift, int is_iret, int addend) ESP = new_esp; } -void helper_iret_protected(int shift) +void helper_iret_protected(int shift, int next_eip) { int tss_selector, type; uint32_t e1, e2; @@ -1748,8 +1747,7 @@ void helper_iret_protected(int shift) /* NOTE: we check both segment and busy TSS */ if (type != 3) raise_exception_err(EXCP0A_TSS, tss_selector & 0xfffc); - /* XXX: check if it is really the current EIP */ - switch_tss(tss_selector, e1, e2, SWITCH_TSS_IRET, env->eip); + switch_tss(tss_selector, e1, e2, SWITCH_TSS_IRET, next_eip); } else { helper_ret_protected(shift, 1, 0); } diff --git a/target-i386/op.c b/target-i386/op.c index f592b67a6af25ba316f027a0f0afac4cd1651082..1169f121adc2de71928dc34535d201b3a1ab42e4 100644 --- a/target-i386/op.c +++ b/target-i386/op.c @@ -918,7 +918,7 @@ void OPPROTO op_arpl_update(void) /* T0: segment, T1:eip */ void OPPROTO op_ljmp_protected_T0_T1(void) { - helper_ljmp_protected_T0_T1(); + helper_ljmp_protected_T0_T1(PARAM1); } void OPPROTO op_lcall_real_T0_T1(void) @@ -938,7 +938,7 @@ void OPPROTO op_iret_real(void) void OPPROTO op_iret_protected(void) { - helper_iret_protected(PARAM1); + helper_iret_protected(PARAM1, PARAM2); } void OPPROTO op_lret_protected(void) diff --git a/target-i386/translate.c b/target-i386/translate.c index 12a74435ff444f22b148f57205e2cb74446d40a2..4a1a2767a952bf8ed4a5b6093cf1a8d2a41e253c 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -2172,7 +2172,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) if (s->cc_op != CC_OP_DYNAMIC) gen_op_set_cc_op(s->cc_op); gen_op_jmp_im(pc_start - s->cs_base); - gen_op_ljmp_protected_T0_T1(); + gen_op_ljmp_protected_T0_T1(s->pc - s->cs_base); } else { gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS])); gen_op_movl_T0_T1(); @@ -3453,7 +3453,7 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) if (s->cc_op != CC_OP_DYNAMIC) gen_op_set_cc_op(s->cc_op); gen_op_jmp_im(pc_start - s->cs_base); - gen_op_iret_protected(s->dflag); + gen_op_iret_protected(s->dflag, s->pc - s->cs_base); s->cc_op = CC_OP_EFLAGS; } gen_eob(s);