From 0f3fdaf94b59af5500f42af3276624726548c84f Mon Sep 17 00:00:00 2001 From: Stanislav Shwartsman Date: Fri, 19 Oct 2007 10:59:39 +0000 Subject: [PATCH] exception was suffering from the same issue - fixed with new_stack push functtions --- bochs/cpu/call_far.cc | 6 +- bochs/cpu/exception.cc | 152 ++++++++++++++++++++++++----------------- 2 files changed, 93 insertions(+), 65 deletions(-) diff --git a/bochs/cpu/call_far.cc b/bochs/cpu/call_far.cc index 999ea2f08..b55c21969 100755 --- a/bochs/cpu/call_far.cc +++ b/bochs/cpu/call_far.cc @@ -1,5 +1,5 @@ //////////////////////////////////////////////////////////////////////// -// $Id: call_far.cc,v 1.18 2007-10-19 10:14:33 sshwarts Exp $ +// $Id: call_far.cc,v 1.19 2007-10-19 10:59:39 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -372,7 +372,7 @@ BX_CPU_C::call_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address disp) bx_segment_reg_t new_stack; new_stack.selector = ss_selector; new_stack.cache = ss_descriptor; - new_stack.selector.rpl = ss_descriptor.dpl; + new_stack.selector.rpl = cs_descriptor.dpl; // add cpl to the selector value new_stack.selector.value = (0xfffc & new_stack.selector.value) | new_stack.selector.rpl; @@ -415,7 +415,7 @@ BX_CPU_C::call_protected(bxInstruction_c *i, Bit16u cs_raw, bx_address disp) /* load new SS:SP value from TSS */ /* load SS descriptor */ - load_ss(&ss_selector, &ss_descriptor, ss_descriptor.dpl); + load_ss(&ss_selector, &ss_descriptor, cs_descriptor.dpl); if (ss_descriptor.u.segment.d_b) ESP = temp_ESP; else diff --git a/bochs/cpu/exception.cc b/bochs/cpu/exception.cc index 94e093bda..130e8983c 100644 --- a/bochs/cpu/exception.cc +++ b/bochs/cpu/exception.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: exception.cc,v 1.92 2007-10-19 10:14:33 sshwarts Exp $ +// $Id: exception.cc,v 1.93 2007-10-19 10:59:39 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -185,11 +185,25 @@ void BX_CPU_C::long_mode_int(Bit8u vector, bx_bool is_INT, bx_bool is_error_code exception(BX_GP_EXCEPTION, 0, 0); } - Bit16u old_CS = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value; + Bit64u old_CS = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value; Bit64u old_RIP = RIP; - Bit16u old_SS = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value; + Bit64u old_SS = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value; Bit64u old_RSP = RSP; + // push old stack long pointer onto new stack + write_new_stack_qword(RSP_for_cpl_x - 8, old_SS); + write_new_stack_qword(RSP_for_cpl_x - 16, old_RSP); + write_new_stack_qword(RSP_for_cpl_x - 24, read_eflags()); + // push long pointer to return address onto new stack + write_new_stack_qword(RSP_for_cpl_x - 32, old_CS); + write_new_stack_qword(RSP_for_cpl_x - 40, old_RIP); + RSP_for_cpl_x -= 40; + + if (is_error_code) { + RSP_for_cpl_x -= 8; + write_new_stack_qword(RSP_for_cpl_x, error_code); + } + bx_selector_t ss_selector; bx_descriptor_t ss_descriptor; @@ -204,16 +218,6 @@ void BX_CPU_C::long_mode_int(Bit8u vector, bx_bool is_INT, bx_bool is_error_code load_ss(&ss_selector, &ss_descriptor, cs_descriptor.dpl); RSP = RSP_for_cpl_x; - // push old stack long pointer onto new stack - push_64(old_SS); - push_64(old_RSP); - push_64(read_eflags()); - // push long pointer to return address onto new stack - push_64(old_CS); - push_64(old_RIP); - if (is_error_code) - push_64(error_code); - // if INTERRUPT GATE set IF to 0 if (!(gate_descriptor.type & 1)) // even is int-gate BX_CPU_THIS_PTR clear_IF(); @@ -286,6 +290,7 @@ void BX_CPU_C::protected_mode_int(Bit8u vector, bx_bool is_INT, bx_bool is_error Bit16u gate_dest_selector; Bit32u gate_dest_offset; + Bit32u temp_ESP; // interrupt vector must be within IDT table limits, // else #GP(vector number*8 + 2 + EXT) @@ -544,13 +549,83 @@ void BX_CPU_C::protected_mode_int(Bit8u vector, bx_bool is_INT, bx_bool is_error old_EIP = EIP; old_CS = BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value; + // Prepare new stack segment + bx_segment_reg_t new_stack; + new_stack.selector = ss_selector; + new_stack.cache = ss_descriptor; + new_stack.selector.rpl = cs_descriptor.dpl; + // add cpl to the selector value + new_stack.selector.value = (0xfffc & new_stack.selector.value) | + new_stack.selector.rpl; + bx_bool user = (cs_descriptor.dpl == 3); + + if (ss_descriptor.u.segment.d_b) + temp_ESP = ESP_for_cpl_x; + else + temp_ESP = (Bit16u) ESP_for_cpl_x; + + if (is_v8086_mode) + { + if (gate_descriptor.type>=14) { // 386 int/trap gate + write_new_stack_dword(&new_stack, temp_ESP-4, user, + BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value); + write_new_stack_dword(&new_stack, temp_ESP-8, user, + BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value); + write_new_stack_dword(&new_stack, temp_ESP-12, user, + BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value); + write_new_stack_dword(&new_stack, temp_ESP-16, user, + BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value); + temp_ESP -= 16; + } + else { + write_new_stack_word(&new_stack, temp_ESP-2, user, + BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value); + write_new_stack_word(&new_stack, temp_ESP-4, user, + BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value); + write_new_stack_word(&new_stack, temp_ESP-6, user, + BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value); + write_new_stack_word(&new_stack, temp_ESP-8, user, + BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value); + temp_ESP -= 8; + } + } + + if (gate_descriptor.type>=14) { // 386 int/trap gate + // push long pointer to old stack onto new stack + write_new_stack_dword(&new_stack, temp_ESP-4, user, old_SS); + write_new_stack_dword(&new_stack, temp_ESP-8, user, old_ESP); + write_new_stack_dword(&new_stack, temp_ESP-12, user, read_eflags()); + write_new_stack_dword(&new_stack, temp_ESP-16, user, old_CS); + write_new_stack_dword(&new_stack, temp_ESP-20, user, old_EIP); + temp_ESP -= 20; + + if (is_error_code) { + temp_ESP -= 4; + write_new_stack_dword(&new_stack, temp_ESP, user, error_code); + } + } + else { // 286 int/trap gate + // push long pointer to old stack onto new stack + write_new_stack_word(&new_stack, temp_ESP-2, user, old_SS); + write_new_stack_word(&new_stack, temp_ESP-4, user, (Bit16u) old_ESP); + write_new_stack_word(&new_stack, temp_ESP-6, user, read_flags()); + write_new_stack_word(&new_stack, temp_ESP-8, user, old_CS); + write_new_stack_word(&new_stack, temp_ESP-10, user, (Bit16u) old_EIP); + temp_ESP -= 10; + + if (is_error_code) { + temp_ESP -= 2; + write_new_stack_word(&new_stack, temp_ESP, user, error_code); + } + } + // load new SS:SP values from TSS load_ss(&ss_selector, &ss_descriptor, cs_descriptor.dpl); if (ss_descriptor.u.segment.d_b) - ESP = ESP_for_cpl_x; + ESP = temp_ESP; else - SP = ESP_for_cpl_x; // leave upper 16bits + SP = (Bit16u) temp_ESP; // load new CS:IP values from gate // set CPL to new code segment DPL @@ -558,8 +633,6 @@ void BX_CPU_C::protected_mode_int(Bit8u vector, bx_bool is_INT, bx_bool is_error load_cs(&cs_selector, &cs_descriptor, cs_descriptor.dpl); EIP = gate_dest_offset; - Bit32u eflags = read_eflags(); - // if INTERRUPT GATE set IF to 0 if (!(gate_descriptor.type & 1)) // even is int-gate BX_CPU_THIS_PTR clear_IF(); @@ -570,19 +643,6 @@ void BX_CPU_C::protected_mode_int(Bit8u vector, bx_bool is_INT, bx_bool is_error if (is_v8086_mode) { - if (gate_descriptor.type>=14) { // 386 int/trap gate - push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value); - push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value); - push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value); - push_32(BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value); - } - else { - push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value); - push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value); - push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value); - push_16(BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value); - } - BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.valid = 0; BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value = 0; BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.valid = 0; @@ -593,37 +653,6 @@ void BX_CPU_C::protected_mode_int(Bit8u vector, bx_bool is_INT, bx_bool is_error BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value = 0; } - if (gate_descriptor.type>=14) { // 386 int/trap gate - // push long pointer to old stack onto new stack - push_32(old_SS); - push_32(old_ESP); - - // push EFLAGS - push_32(eflags); - - // push long pointer to return address onto new stack - push_32(old_CS); - push_32(old_EIP); - - if (is_error_code) - push_32(error_code); - } - else { // 286 int/trap gate - // push long pointer to old stack onto new stack - push_16(old_SS); - push_16(old_ESP); // ignores upper 16bits - - // push FLAGS - push_16(eflags); // ignores upper 16bits - - // push return address onto new stack - push_16(old_CS); - push_16(old_EIP); // ignores upper 16bits - - if (is_error_code) - push_16(error_code); - } - return; } @@ -638,7 +667,6 @@ void BX_CPU_C::protected_mode_int(Bit8u vector, bx_bool is_INT, bx_bool is_error if (IS_CODE_SEGMENT_CONFORMING(cs_descriptor.type) || cs_descriptor.dpl==CPL) { int bytes; - Bit32u temp_ESP; if (BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.u.segment.d_b) temp_ESP = ESP;