Revision 08cea4ee
b/target-i386/exec.h | ||
---|---|---|
123 | 123 |
extern CCTable cc_table[]; |
124 | 124 |
|
125 | 125 |
void load_seg(int seg_reg, int selector); |
126 |
void helper_ljmp_protected_T0_T1(void);
|
|
126 |
void helper_ljmp_protected_T0_T1(int next_eip);
|
|
127 | 127 |
void helper_lcall_real_T0_T1(int shift, int next_eip); |
128 | 128 |
void helper_lcall_protected_T0_T1(int shift, int next_eip); |
129 | 129 |
void helper_iret_real(int shift); |
130 |
void helper_iret_protected(int shift); |
|
130 |
void helper_iret_protected(int shift, int next_eip);
|
|
131 | 131 |
void helper_lret_protected(int shift, int addend); |
132 | 132 |
void helper_lldt_T0(void); |
133 | 133 |
void helper_ltr_T0(void); |
b/target-i386/helper.c | ||
---|---|---|
1219 | 1219 |
} |
1220 | 1220 |
|
1221 | 1221 |
/* protected mode jump */ |
1222 |
void helper_ljmp_protected_T0_T1(void)
|
|
1222 |
void helper_ljmp_protected_T0_T1(int next_eip)
|
|
1223 | 1223 |
{ |
1224 | 1224 |
int new_cs, new_eip, gate_cs, type; |
1225 | 1225 |
uint32_t e1, e2, cpl, dpl, rpl, limit; |
... | ... | |
1267 | 1267 |
case 5: /* task gate */ |
1268 | 1268 |
if (dpl < cpl || dpl < rpl) |
1269 | 1269 |
raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc); |
1270 |
/* XXX: check if it is really the current EIP */ |
|
1271 |
switch_tss(new_cs, e1, e2, SWITCH_TSS_JMP, env->eip); |
|
1270 |
switch_tss(new_cs, e1, e2, SWITCH_TSS_JMP, next_eip); |
|
1272 | 1271 |
break; |
1273 | 1272 |
case 4: /* 286 call gate */ |
1274 | 1273 |
case 12: /* 386 call gate */ |
... | ... | |
1732 | 1731 |
ESP = new_esp; |
1733 | 1732 |
} |
1734 | 1733 |
|
1735 |
void helper_iret_protected(int shift) |
|
1734 |
void helper_iret_protected(int shift, int next_eip)
|
|
1736 | 1735 |
{ |
1737 | 1736 |
int tss_selector, type; |
1738 | 1737 |
uint32_t e1, e2; |
... | ... | |
1748 | 1747 |
/* NOTE: we check both segment and busy TSS */ |
1749 | 1748 |
if (type != 3) |
1750 | 1749 |
raise_exception_err(EXCP0A_TSS, tss_selector & 0xfffc); |
1751 |
/* XXX: check if it is really the current EIP */ |
|
1752 |
switch_tss(tss_selector, e1, e2, SWITCH_TSS_IRET, env->eip); |
|
1750 |
switch_tss(tss_selector, e1, e2, SWITCH_TSS_IRET, next_eip); |
|
1753 | 1751 |
} else { |
1754 | 1752 |
helper_ret_protected(shift, 1, 0); |
1755 | 1753 |
} |
b/target-i386/op.c | ||
---|---|---|
918 | 918 |
/* T0: segment, T1:eip */ |
919 | 919 |
void OPPROTO op_ljmp_protected_T0_T1(void) |
920 | 920 |
{ |
921 |
helper_ljmp_protected_T0_T1(); |
|
921 |
helper_ljmp_protected_T0_T1(PARAM1);
|
|
922 | 922 |
} |
923 | 923 |
|
924 | 924 |
void OPPROTO op_lcall_real_T0_T1(void) |
... | ... | |
938 | 938 |
|
939 | 939 |
void OPPROTO op_iret_protected(void) |
940 | 940 |
{ |
941 |
helper_iret_protected(PARAM1); |
|
941 |
helper_iret_protected(PARAM1, PARAM2);
|
|
942 | 942 |
} |
943 | 943 |
|
944 | 944 |
void OPPROTO op_lret_protected(void) |
b/target-i386/translate.c | ||
---|---|---|
2172 | 2172 |
if (s->cc_op != CC_OP_DYNAMIC) |
2173 | 2173 |
gen_op_set_cc_op(s->cc_op); |
2174 | 2174 |
gen_op_jmp_im(pc_start - s->cs_base); |
2175 |
gen_op_ljmp_protected_T0_T1(); |
|
2175 |
gen_op_ljmp_protected_T0_T1(s->pc - s->cs_base);
|
|
2176 | 2176 |
} else { |
2177 | 2177 |
gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS])); |
2178 | 2178 |
gen_op_movl_T0_T1(); |
... | ... | |
3453 | 3453 |
if (s->cc_op != CC_OP_DYNAMIC) |
3454 | 3454 |
gen_op_set_cc_op(s->cc_op); |
3455 | 3455 |
gen_op_jmp_im(pc_start - s->cs_base); |
3456 |
gen_op_iret_protected(s->dflag); |
|
3456 |
gen_op_iret_protected(s->dflag, s->pc - s->cs_base);
|
|
3457 | 3457 |
s->cc_op = CC_OP_EFLAGS; |
3458 | 3458 |
} |
3459 | 3459 |
gen_eob(s); |
Also available in: Unified diff