Added canonical check for LIDT/LGDT instructions in 64-bit mode

This commit is contained in:
Stanislav Shwartsman 2008-04-24 19:34:01 +00:00
parent d24a274909
commit b504253645

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: protect_ctrl.cc,v 1.80 2008-04-22 22:05:38 sshwarts Exp $
// $Id: protect_ctrl.cc,v 1.81 2008-04-24 19:34:01 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -658,8 +658,8 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::SGDT_Ms(bxInstruction_c *i)
BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
write_virtual_word(i->seg(), RMAddr(i), limit_16);
write_virtual_dword(i->seg(), RMAddr(i)+2, base_32);
write_virtual_word(i->seg(), RMAddr(i), limit_16);
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::SIDT_Ms(bxInstruction_c *i)
@ -714,8 +714,8 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::LIDT_Ms(bxInstruction_c *i)
BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
Bit16u limit_16 = read_virtual_word(i->seg(), RMAddr(i));
Bit32u base_32 = read_virtual_dword(i->seg(), RMAddr(i) + 2);
Bit16u limit_16 = read_virtual_word(i->seg(), RMAddr(i));
if (i->os32L() == 0) base_32 &= 0x00ffffff; /* ignore upper 8 bits */
@ -727,29 +727,33 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::LIDT_Ms(bxInstruction_c *i)
void BX_CPP_AttrRegparmN(1) BX_CPU_C::SGDT64_Ms(bxInstruction_c *i)
{
BX_ASSERT(BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64);
Bit16u limit_16 = BX_CPU_THIS_PTR gdtr.limit;
Bit64u base_64 = BX_CPU_THIS_PTR gdtr.base;
BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
write_virtual_word (i->seg(), RMAddr(i), limit_16);
write_virtual_qword(i->seg(), RMAddr(i)+2, base_64);
write_virtual_word (i->seg(), RMAddr(i), limit_16);
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::SIDT64_Ms(bxInstruction_c *i)
{
BX_ASSERT(BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64);
Bit16u limit_16 = BX_CPU_THIS_PTR idtr.limit;
Bit64u base_64 = BX_CPU_THIS_PTR idtr.base;
BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
write_virtual_word(i->seg(), RMAddr(i), limit_16);
write_virtual_qword(i->seg(), RMAddr(i)+2, base_64);
write_virtual_word(i->seg(), RMAddr(i), limit_16);
}
void BX_CPP_AttrRegparmN(1) BX_CPU_C::LGDT64_Ms(bxInstruction_c *i)
{
BX_ASSERT(protected_mode());
BX_ASSERT(BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64);
if (CPL!=0) {
BX_ERROR(("LGDT64_Ms: CPL != 0 in long mode"));
@ -760,8 +764,12 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::LGDT64_Ms(bxInstruction_c *i)
BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
Bit16u limit_16 = read_virtual_word(i->seg(), RMAddr(i));
Bit64u base_64 = read_virtual_qword(i->seg(), RMAddr(i) + 2);
if (! IsCanonical(base_64)) {
BX_ERROR(("LGDT64_Ms: loaded base64 address is not in canonical form!"));
exception(BX_GP_EXCEPTION, 0, 0);
}
Bit16u limit_16 = read_virtual_word(i->seg(), RMAddr(i));
BX_CPU_THIS_PTR gdtr.limit = limit_16;
BX_CPU_THIS_PTR gdtr.base = base_64;
@ -769,7 +777,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::LGDT64_Ms(bxInstruction_c *i)
void BX_CPP_AttrRegparmN(1) BX_CPU_C::LIDT64_Ms(bxInstruction_c *i)
{
BX_ASSERT(protected_mode());
BX_ASSERT(BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64);
if (CPL != 0) {
BX_ERROR(("LIDT64_Ms: CPL != 0 in long mode"));
@ -780,8 +788,12 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::LIDT64_Ms(bxInstruction_c *i)
BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
Bit16u limit_16 = read_virtual_word(i->seg(), RMAddr(i));
Bit64u base_64 = read_virtual_qword(i->seg(), RMAddr(i) + 2);
if (! IsCanonical(base_64)) {
BX_ERROR(("LIDT64_Ms: loaded base64 address is not in canonical form!"));
exception(BX_GP_EXCEPTION, 0, 0);
}
Bit16u limit_16 = read_virtual_word(i->seg(), RMAddr(i));
BX_CPU_THIS_PTR idtr.limit = limit_16;
BX_CPU_THIS_PTR idtr.base = base_64;