From 8065ada31f6e7d9b7a58d2e2f06fac2fb1be9c82 Mon Sep 17 00:00:00 2001 From: Stanislav Shwartsman Date: Thu, 18 Oct 2007 21:27:56 +0000 Subject: [PATCH] Some EIP setting cleanups. OK, currently I see big mess with setting of CS/EIP and SS/ESP everywhere, I have to unify it and make it easier ! --- bochs/cpu/call_far.cc | 22 +++++++++++++++++++--- bochs/cpu/ctrl_xfer16.cc | 22 ++++++++++------------ bochs/cpu/ctrl_xfer32.cc | 31 ++++++++++++++++--------------- bochs/cpu/ctrl_xfer64.cc | 6 +----- bochs/cpu/ctrl_xfer_pro.cc | 4 ++-- bochs/cpu/exception.cc | 10 +++++++++- bochs/cpu/segment_ctrl_pro.cc | 6 +++++- 7 files changed, 62 insertions(+), 39 deletions(-) diff --git a/bochs/cpu/call_far.cc b/bochs/cpu/call_far.cc index 826b42c7e..06a8e7898 100755 --- a/bochs/cpu/call_far.cc +++ b/bochs/cpu/call_far.cc @@ -1,5 +1,5 @@ //////////////////////////////////////////////////////////////////////// -// $Id: call_far.cc,v 1.15 2007-02-03 21:36:40 sshwarts Exp $ +// $Id: call_far.cc,v 1.16 2007-10-18 21:27:56 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -366,7 +366,8 @@ BX_CPU_C::call_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address disp) } } - // Help for OS/2 + // The follwoing push instructions might have a page fault which cannot + // be detected at this stage BX_CPU_THIS_PTR except_chk = 1; BX_CPU_THIS_PTR except_cs = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS]; BX_CPU_THIS_PTR except_ss = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS]; @@ -540,12 +541,17 @@ BX_CPU_C::call_gate64(bx_selector_t *gate_selector) parse_selector(0, &ss_selector); parse_descriptor(0, 0, &ss_descriptor); + // The following push instructions might have a page fault which cannot + // be detected at this stage + BX_CPU_THIS_PTR except_chk = 1; + BX_CPU_THIS_PTR except_cs = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS]; + BX_CPU_THIS_PTR except_ss = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS]; + // load CS:RIP (guaranteed to be in 64 bit mode) branch_far64(&cs_selector, &cs_descriptor, new_RIP, cs_descriptor.dpl); // set up null SS descriptor load_ss(&ss_selector, &ss_descriptor, cs_descriptor.dpl); - RSP = RSP_for_cpl_x; // push old stack long pointer onto new stack @@ -554,6 +560,8 @@ BX_CPU_C::call_gate64(bx_selector_t *gate_selector) // push long pointer to return address onto new stack push_64(old_CS); push_64(old_RIP); + + BX_CPU_THIS_PTR except_chk = 0; } else { @@ -566,12 +574,20 @@ BX_CPU_C::call_gate64(bx_selector_t *gate_selector) exception(BX_GP_EXCEPTION, 0, 0); } + // The following push instructions might have a page fault which cannot + // be detected at this stage + BX_CPU_THIS_PTR except_chk = 1; + BX_CPU_THIS_PTR except_cs = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS]; + BX_CPU_THIS_PTR except_ss = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS]; + // load CS:RIP (guaranteed to be in 64 bit mode) branch_far64(&cs_selector, &cs_descriptor, new_RIP, CPL); // push return address onto stack push_64(old_CS); push_64(old_RIP); + + BX_CPU_THIS_PTR except_chk = 0; } } #endif diff --git a/bochs/cpu/ctrl_xfer16.cc b/bochs/cpu/ctrl_xfer16.cc index bd4f32a41..af2e29f9b 100644 --- a/bochs/cpu/ctrl_xfer16.cc +++ b/bochs/cpu/ctrl_xfer16.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: ctrl_xfer16.cc,v 1.37 2007-07-09 15:16:11 sshwarts Exp $ +// $Id: ctrl_xfer16.cc,v 1.38 2007-10-18 21:27:56 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -103,8 +103,8 @@ void BX_CPU_C::RETfar16_Iw(bxInstruction_c *i) pop_16(&ip); pop_16(&cs_raw); - EIP = (Bit32u) ip; load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw); + EIP = (Bit32u) ip; if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) ESP += imm16; @@ -135,8 +135,9 @@ void BX_CPU_C::RETfar16(bxInstruction_c *i) pop_16(&ip); pop_16(&cs_raw); - EIP = (Bit32u) ip; + load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw); + EIP = (Bit32u) ip; done: BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_RET, @@ -154,13 +155,11 @@ void BX_CPU_C::CALL_Aw(bxInstruction_c *i) new_EIP = EIP + (Bit32s) i->Id(); new_EIP &= 0x0000ffff; -#if BX_CPU_LEVEL >= 2 if (new_EIP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled) { BX_ERROR(("CALL_Aw: new_IP > BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].limit")); exception(BX_GP_EXCEPTION, 0, 0); } -#endif /* push 16 bit EA of next instruction */ push_16(IP); @@ -192,8 +191,9 @@ void BX_CPU_C::CALL16_Ap(bxInstruction_c *i) push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value); push_16((Bit16u) EIP); - EIP = (Bit32u) disp16; + load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw); + EIP = (Bit32u) disp16; done: BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_CALL, @@ -248,7 +248,7 @@ void BX_CPU_C::CALL16_Ep(bxInstruction_c *i) read_virtual_word(i->seg(), RMAddr(i), &op1_16); read_virtual_word(i->seg(), RMAddr(i)+2, &cs_raw); - if ( protected_mode() ) { + if (protected_mode()) { BX_CPU_THIS_PTR call_protected(i, cs_raw, op1_16); goto done; } @@ -256,8 +256,8 @@ void BX_CPU_C::CALL16_Ep(bxInstruction_c *i) push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value); push_16(IP); - EIP = op1_16; load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw); + EIP = op1_16; done: BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_CALL, @@ -382,8 +382,8 @@ void BX_CPU_C::JMP16_Ep(bxInstruction_c *i) } #endif - EIP = op1_16; load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw); + EIP = op1_16; done: BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_JMP, @@ -408,12 +408,10 @@ void BX_CPU_C::IRET16(bxInstruction_c *i) goto done; } -#if BX_CPU_LEVEL >= 2 - if (BX_CPU_THIS_PTR cr0.get_PE()) { + if (protected_mode()) { iret_protected(i); goto done; } -#endif if (! can_pop(6)) { BX_ERROR(("IRET: top 6 bytes of stack not within stack limits")); diff --git a/bochs/cpu/ctrl_xfer32.cc b/bochs/cpu/ctrl_xfer32.cc index fb7657251..b2318aead 100644 --- a/bochs/cpu/ctrl_xfer32.cc +++ b/bochs/cpu/ctrl_xfer32.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: ctrl_xfer32.cc,v 1.49 2006-06-09 22:29:06 sshwarts Exp $ +// $Id: ctrl_xfer32.cc,v 1.50 2007-10-18 21:27:56 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -85,8 +85,9 @@ void BX_CPU_C::RETfar32_Iw(bxInstruction_c *i) pop_32(&eip); pop_32(&ecs_raw); - EIP = eip; + load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], (Bit16u) ecs_raw); + EIP = eip; if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) ESP += imm16; @@ -115,8 +116,9 @@ void BX_CPU_C::RETfar32(bxInstruction_c *i) pop_32(&eip); pop_32(&ecs_raw); /* 32bit pop, MSW discarded */ - EIP = eip; + load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], (Bit16u) ecs_raw); + EIP = eip; done: BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_RET, @@ -164,8 +166,9 @@ void BX_CPU_C::CALL32_Ap(bxInstruction_c *i) push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value); push_32(EIP); - EIP = disp32; + load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw); + EIP = disp32; done: BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_CALL, @@ -326,13 +329,12 @@ void BX_CPU_C::JMP_Ap(bxInstruction_c *i) if (protected_mode()) { BX_CPU_THIS_PTR jump_protected(i, cs_raw, disp32); - goto done; + } + else { + load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw); + EIP = disp32; } - load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw); - EIP = disp32; - -done: BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_JMP, BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP); } @@ -374,15 +376,14 @@ void BX_CPU_C::JMP32_Ep(bxInstruction_c *i) read_virtual_dword(i->seg(), RMAddr(i), &op1_32); read_virtual_word(i->seg(), RMAddr(i)+4, &cs_raw); - if ( protected_mode() ) { + if (protected_mode()) { BX_CPU_THIS_PTR jump_protected(i, cs_raw, op1_32); - goto done; + } + else { + load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw); + EIP = op1_32; } - EIP = op1_32; - load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], cs_raw); - -done: BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_JMP, BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP); } diff --git a/bochs/cpu/ctrl_xfer64.cc b/bochs/cpu/ctrl_xfer64.cc index f157a7a7d..886184846 100644 --- a/bochs/cpu/ctrl_xfer64.cc +++ b/bochs/cpu/ctrl_xfer64.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: ctrl_xfer64.cc,v 1.48 2007-09-25 16:11:32 sshwarts Exp $ +// $Id: ctrl_xfer64.cc,v 1.49 2007-10-18 21:27:56 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -183,8 +183,6 @@ void BX_CPU_C::CALL64_Ep(bxInstruction_c *i) BX_ASSERT(protected_mode()); - BX_INFO(("CallFar64 instruction executed ...")); - BX_CPU_THIS_PTR call_protected(i, cs_raw, op1_32); BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_CALL, @@ -274,8 +272,6 @@ void BX_CPU_C::JMP64_Ep(bxInstruction_c *i) read_virtual_dword(i->seg(), RMAddr(i), &op1_32); read_virtual_word(i->seg(), RMAddr(i)+4, &cs_raw); - BX_INFO(("JmpFar64 instruction executed ...")); - BX_ASSERT(protected_mode()); BX_CPU_THIS_PTR jump_protected(i, cs_raw, op1_32); diff --git a/bochs/cpu/ctrl_xfer_pro.cc b/bochs/cpu/ctrl_xfer_pro.cc index 0b93a8a1f..172919585 100644 --- a/bochs/cpu/ctrl_xfer_pro.cc +++ b/bochs/cpu/ctrl_xfer_pro.cc @@ -1,5 +1,5 @@ //////////////////////////////////////////////////////////////////////// -// $Id: ctrl_xfer_pro.cc,v 1.58 2007-09-25 16:11:32 sshwarts Exp $ +// $Id: ctrl_xfer_pro.cc,v 1.59 2007-10-18 21:27:56 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -98,7 +98,7 @@ BX_CPU_C::load_cs(bx_selector_t *selector, bx_descriptor_t *descriptor, Bit8u cp /* caller may request different CPL then in selector */ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl = cpl; BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid = 1; - // Added cpl to the selector value. + // Add cpl to the selector value. BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value = (0xfffc & BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value) | cpl; diff --git a/bochs/cpu/exception.cc b/bochs/cpu/exception.cc index dec592100..f49350d84 100644 --- a/bochs/cpu/exception.cc +++ b/bochs/cpu/exception.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: exception.cc,v 1.90 2007-09-27 16:22:14 sshwarts Exp $ +// $Id: exception.cc,v 1.91 2007-10-18 21:27:56 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -197,6 +197,12 @@ void BX_CPU_C::long_mode_int(Bit8u vector, bx_bool is_INT, bx_bool is_error_code parse_selector(0, &ss_selector); parse_descriptor(0, 0, &ss_descriptor); + // The follwoing push instructions might have a page fault which cannot + // be detected at this stage + BX_CPU_THIS_PTR except_chk = 1; + BX_CPU_THIS_PTR except_cs = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS]; + BX_CPU_THIS_PTR except_ss = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS]; + // load CS:RIP (guaranteed to be in 64 bit mode) branch_far64(&cs_selector, &cs_descriptor, gate_dest_offset, cs_descriptor.dpl); @@ -217,6 +223,8 @@ void BX_CPU_C::long_mode_int(Bit8u vector, bx_bool is_INT, bx_bool is_error_code if (is_error_code) push_64(error_code); + BX_CPU_THIS_PTR except_chk = 0; + // if INTERRUPT GATE set IF to 0 if (!(gate_descriptor.type & 1)) // even is int-gate BX_CPU_THIS_PTR clear_IF(); diff --git a/bochs/cpu/segment_ctrl_pro.cc b/bochs/cpu/segment_ctrl_pro.cc index b3ba085d3..67df4fe0e 100644 --- a/bochs/cpu/segment_ctrl_pro.cc +++ b/bochs/cpu/segment_ctrl_pro.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: segment_ctrl_pro.cc,v 1.71 2007-09-25 16:11:32 sshwarts Exp $ +// $Id: segment_ctrl_pro.cc,v 1.72 2007-10-18 21:27:56 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -643,6 +643,10 @@ BX_CPU_C::load_ss(bx_selector_t *selector, bx_descriptor_t *descriptor, Bit8u cp BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache = *descriptor; BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.rpl = cpl; + // Add cpl to the selector value. + BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value = + (0xfffc & BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value) | cpl; + #if BX_SUPPORT_X86_64 if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) { loadSRegLMNominal(BX_SEG_REG_SS, selector->value, cpl);