X86: Change what the microop chks does.
Instead of computing the segment descriptor address, this now checks if a selector value/descriptor are legal for a particular purpose.
This commit is contained in:
parent
6bd9cf3594
commit
fa7c81c6df
3 changed files with 48 additions and 2 deletions
|
@ -81,6 +81,11 @@ let {{
|
|||
for letter in ("C", "D", "E", "F", "G", "S"):
|
||||
assembler.symbols["%ss" % letter.lower()] = "SEGMENT_REG_%sS" % letter
|
||||
|
||||
# Add in symbols for the various checks of segment selectors.
|
||||
for check in ("NoCheck", "CSCheck", "CallGateCheck",
|
||||
"SSCheck", "IretCheck", "IntCSCheck"):
|
||||
assembler.symbols[check] = "Seg%s" % check
|
||||
|
||||
for reg in ("TR", "IDTR"):
|
||||
assembler.symbols[reg.lower()] = "SYS_SEGMENT_REG_%s" % reg
|
||||
|
||||
|
|
|
@ -231,6 +231,11 @@ output header {{
|
|||
void
|
||||
divide(uint64_t dividend, uint64_t divisor,
|
||||
uint64_t "ient, uint64_t &remainder);
|
||||
|
||||
enum SegmentSelectorCheck {
|
||||
SegNoCheck, SegCSCheck, SegCallGateCheck,
|
||||
SegSSCheck, SegIretCheck, SegIntCSCheck
|
||||
};
|
||||
}};
|
||||
|
||||
output decoder {{
|
||||
|
@ -1018,11 +1023,46 @@ let {{
|
|||
DestReg = SegSelSrc1;
|
||||
'''
|
||||
|
||||
class Chks(SegOp):
|
||||
class Chks(RegOp):
|
||||
def __init__(self, dest, src1, src2=0,
|
||||
flags=None, dataSize="env.dataSize"):
|
||||
super(Chks, self).__init__(dest,
|
||||
src1, src2, flags, dataSize)
|
||||
code = '''
|
||||
// The selector is in source 1 and can be at most 16 bits.
|
||||
SegSelector selector = psrc1;
|
||||
|
||||
switch (imm8)
|
||||
{
|
||||
case SegNoCheck:
|
||||
break;
|
||||
case SegCSCheck:
|
||||
panic("CS checks for far calls/jumps not implemented.\\n");
|
||||
break;
|
||||
case SegCallGateCheck:
|
||||
panic("CS checks for far calls/jumps through call gates"
|
||||
"not implemented.\\n");
|
||||
break;
|
||||
case SegSSCheck:
|
||||
panic("SS selector checks not implemented.\\n");
|
||||
break;
|
||||
case SegIretCheck:
|
||||
{
|
||||
SegAttr csAttr = CSAttr;
|
||||
if (!selector.si && !selector.ti)
|
||||
return new GeneralProtection(psrc1 & 0xFFFF);
|
||||
if (selector.rpl < csAttr.dpl)
|
||||
return new GeneralProtection(psrc1 & 0xFFFF);
|
||||
break;
|
||||
}
|
||||
case SegIntCSCheck:
|
||||
panic("CS selector checks for interrupts and exceptions"
|
||||
"not implemented.\\n");
|
||||
break;
|
||||
default:
|
||||
panic("Undefined segment check type.\\n");
|
||||
}
|
||||
|
||||
// Compute the address of the descriptor and set DestReg to it.
|
||||
if (selector.ti) {
|
||||
// A descriptor in the LDT
|
||||
|
|
|
@ -149,6 +149,7 @@ def operands {{
|
|||
'GDTRBase': ('ControlReg', 'uqw', 'MISCREG_TSG_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 205),
|
||||
'GDTRLimit': ('ControlReg', 'uqw', 'MISCREG_TSG_LIMIT', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 206),
|
||||
'CSBase': ('ControlReg', 'udw', 'MISCREG_CS_EFF_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 207),
|
||||
'TscOp': ('ControlReg', 'udw', 'MISCREG_TSC', (None, None, ['IsSerializeAfter', 'IsSerializing', 'IsNonSpeculative']), 208),
|
||||
'CSAttr': ('ControlReg', 'udw', 'MISCREG_CS_ATTR', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 208),
|
||||
'TscOp': ('ControlReg', 'udw', 'MISCREG_TSC', (None, None, ['IsSerializeAfter', 'IsSerializing', 'IsNonSpeculative']), 209),
|
||||
'Mem': ('Mem', 'uqw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 300)
|
||||
}};
|
||||
|
|
Loading…
Reference in a new issue