Commit 08cea4ee authored by Fabrice Bellard's avatar Fabrice Bellard
Browse files

fixed ljmp and iret to TSS


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@682 c046a42c-6fe2-441c-8c8c-71466251a162
parent 883da8e2
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -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);
+4 −6
Original line number Diff line number Diff line
@@ -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);
    }
+2 −2
Original line number Diff line number Diff line
@@ -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)
+2 −2
Original line number Diff line number Diff line
@@ -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);