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);
}
/* 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;
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 */
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;
/* 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);
}
/* 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)
void OPPROTO op_iret_protected(void)
{
- helper_iret_protected(PARAM1);
+ helper_iret_protected(PARAM1, PARAM2);
}
void OPPROTO op_lret_protected(void)
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();
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);