fixed push to new stack for long mode

This commit is contained in:
Stanislav Shwartsman 2007-10-19 12:40:19 +00:00
parent 0f3fdaf94b
commit 679110caa9
4 changed files with 21 additions and 20 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: access.cc,v 1.73 2007-10-19 10:14:33 sshwarts Exp $
// $Id: access.cc,v 1.74 2007-10-19 12:40:18 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -1395,15 +1395,14 @@ accessOK:
}
// assuming the write happens in 64-bit mode
void BX_CPU_C::write_new_stack_qword(bx_address offset, Bit64u data)
void BX_CPU_C::write_new_stack_qword(bx_address offset, bx_bool user, Bit64u data)
{
bx_address laddr = offset;
if (IsCanonical(offset)) {
unsigned pl = (CPL==3);
BX_INSTR_MEM_DATA(BX_CPU_ID, laddr, 8, BX_WRITE);
#if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK
if (pl && BX_CPU_THIS_PTR alignment_check) {
if (user && BX_CPU_THIS_PTR alignment_check) {
if (laddr & 7) {
BX_ERROR(("write_new_stack_qword(): misaligned access"));
exception(BX_AC_EXCEPTION, 0, 0);
@ -1411,13 +1410,13 @@ void BX_CPU_C::write_new_stack_qword(bx_address offset, Bit64u data)
}
#endif
#if BX_SupportGuest2HostTLB
Bit64u *hostAddr = v2h_write_qword(laddr, pl);
Bit64u *hostAddr = v2h_write_qword(laddr, user);
if (hostAddr) {
WriteHostQWordToLittleEndian(hostAddr, data);
return;
}
#endif
access_linear(laddr, 8, pl, BX_WRITE, (void *) &data);
access_linear(laddr, 8, user, BX_WRITE, (void *) &data);
}
else {
BX_ERROR(("write_new_stack_qword(): canonical failure 0x%08x:%08x", GET32H(laddr), GET32L(laddr)));

View File

@ -1,5 +1,5 @@
////////////////////////////////////////////////////////////////////////
// $Id: call_far.cc,v 1.19 2007-10-19 10:59:39 sshwarts Exp $
// $Id: call_far.cc,v 1.20 2007-10-19 12:40:18 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -537,13 +537,14 @@ BX_CPU_C::call_gate64(bx_selector_t *gate_selector)
Bit64u old_SS = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value;
Bit64u old_RSP = RSP;
bx_bool user = (cs_descriptor.dpl == 3);
// 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 - 8, user, old_SS);
write_new_stack_qword(RSP_for_cpl_x - 16, user, old_RSP);
// push long pointer to return address onto new stack
write_new_stack_qword(RSP_for_cpl_x - 24, old_CS);
write_new_stack_qword(RSP_for_cpl_x - 32, old_RIP);
write_new_stack_qword(RSP_for_cpl_x - 24, user, old_CS);
write_new_stack_qword(RSP_for_cpl_x - 32, user, old_RIP);
RSP_for_cpl_x -= 32;
// prepare new stack null SS selector

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.h,v 1.337 2007-10-19 10:14:33 sshwarts Exp $
// $Id: cpu.h,v 1.338 2007-10-19 12:40:18 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -2828,7 +2828,7 @@ public: // for now...
BX_SMF void write_new_stack_dword(bx_segment_reg_t *seg, bx_address offset, bx_bool user, Bit32u data);
// write of qword to new stack could happen only in 64-bit mode
// (so stack segment is not relavant)
BX_SMF void write_new_stack_qword(bx_address offset, Bit64u data);
BX_SMF void write_new_stack_qword(bx_address offset, bx_bool user, Bit64u data);
#if BX_SUPPORT_MISALIGNED_SSE

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: exception.cc,v 1.93 2007-10-19 10:59:39 sshwarts Exp $
// $Id: exception.cc,v 1.94 2007-10-19 12:40:19 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -189,19 +189,20 @@ void BX_CPU_C::long_mode_int(Bit8u vector, bx_bool is_INT, bx_bool is_error_code
Bit64u old_RIP = RIP;
Bit64u old_SS = BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value;
Bit64u old_RSP = RSP;
bx_bool user = (cs_descriptor.dpl == 3);
// 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());
write_new_stack_qword(RSP_for_cpl_x - 8, user, old_SS);
write_new_stack_qword(RSP_for_cpl_x - 16, user, old_RSP);
write_new_stack_qword(RSP_for_cpl_x - 24, user, 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);
write_new_stack_qword(RSP_for_cpl_x - 32, user, old_CS);
write_new_stack_qword(RSP_for_cpl_x - 40, user, 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);
write_new_stack_qword(RSP_for_cpl_x, user, error_code);
}
bx_selector_t ss_selector;