i386: RPL must be not be greater than DPL in LSL and LAR (nw)

i286: Conforming code segments are always permitted in LSL and LAR (nw)
This commit is contained in:
cracyc 2013-04-05 19:59:17 +00:00
parent 889162a4f3
commit 6b38d5156b
3 changed files with 10 additions and 6 deletions

View File

@ -3494,7 +3494,8 @@ static void I386OP(lar_r16_rm16)(i386_state *cpustate) // Opcode 0x0f 0x02
SetZF(0);
return;
}
if((((seg.flags >> 5) & 3) < cpustate->CPL) && ((seg.flags & 0x1c) != 0x1c))
UINT8 DPL = (seg.flags >> 5) & 3;
if(((DPL < cpustate->CPL) || (DPL < (seg.selector & 3))) && ((seg.flags & 0x1c) != 0x1c))
{
SetZF(0);
return;
@ -3558,7 +3559,8 @@ static void I386OP(lsl_r16_rm16)(i386_state *cpustate) // Opcode 0x0f 0x03
SetZF(0);
return;
}
if((((seg.flags >> 5) & 3) < cpustate->CPL) && ((seg.flags & 0x1c) != 0x1c))
UINT8 DPL = (seg.flags >> 5) & 3;
if(((DPL < cpustate->CPL) || (DPL < (seg.selector & 3))) && ((seg.flags & 0x1c) != 0x1c))
{
SetZF(0);
return;

View File

@ -3298,7 +3298,8 @@ static void I386OP(lar_r32_rm32)(i386_state *cpustate) // Opcode 0x0f 0x02
SetZF(0);
return;
}
if((((seg.flags >> 5) & 3) < cpustate->CPL) && ((seg.flags & 0x1c) != 0x1c))
UINT8 DPL = (seg.flags >> 5) & 3;
if((DPL < cpustate->CPL) && (DPL < (seg.selector & 3)) && ((seg.flags & 0x1c) != 0x1c))
{
SetZF(0);
return;
@ -3362,7 +3363,8 @@ static void I386OP(lsl_r32_rm32)(i386_state *cpustate) // Opcode 0x0f 0x03
SetZF(0);
return;
}
if((((seg.flags >> 5) & 3) < cpustate->CPL) && ((seg.flags & 0x1c) != 0x1c))
UINT8 DPL = (seg.flags >> 5) & 3;
if((DPL < cpustate->CPL) && (DPL < (seg.selector & 3)) && ((seg.flags & 0x1c) != 0x1c))
{
SetZF(0);
return;

View File

@ -618,7 +618,7 @@ static void PREFIX286(_0fpre)(i8086_state *cpustate)
else {
desc[2] = ReadWord(addr+4);
r = RIGHTS(desc);
if (DPL(r)>=PMAX(RPL(tmp),CPL)) {
if (DPL(r)>=PMAX(RPL(tmp),CPL) || (SEGDESC(r) && CODE(r) && CONF(r))) {
cpustate->ZeroVal = 0;
// rights are expected to be in upper byte
RegWord(ModRM) = r << 8;
@ -636,7 +636,7 @@ static void PREFIX286(_0fpre)(i8086_state *cpustate)
desc[2] = ReadWord(addr+4);
r = RIGHTS(desc);
if (!SEGDESC(r) && (GATE(r) >= CALLGATE)) cpustate->ZeroVal = 1; // not valid for gates
else if (DPL(r)>=PMAX(RPL(tmp),CPL)) {
else if (DPL(r)>=PMAX(RPL(tmp),CPL) || (SEGDESC(r) && CODE(r) && CONF(r))) {
cpustate->ZeroVal = 0;
RegWord(ModRM) = ReadWord(addr);
}