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:
Gabe Black 2008-06-12 00:50:10 -04:00
parent 6bd9cf3594
commit fa7c81c6df
3 changed files with 48 additions and 2 deletions

View file

@ -81,6 +81,11 @@ let {{
for letter in ("C", "D", "E", "F", "G", "S"): for letter in ("C", "D", "E", "F", "G", "S"):
assembler.symbols["%ss" % letter.lower()] = "SEGMENT_REG_%sS" % letter 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"): for reg in ("TR", "IDTR"):
assembler.symbols[reg.lower()] = "SYS_SEGMENT_REG_%s" % reg assembler.symbols[reg.lower()] = "SYS_SEGMENT_REG_%s" % reg

View file

@ -231,6 +231,11 @@ output header {{
void void
divide(uint64_t dividend, uint64_t divisor, divide(uint64_t dividend, uint64_t divisor,
uint64_t &quotient, uint64_t &remainder); uint64_t &quotient, uint64_t &remainder);
enum SegmentSelectorCheck {
SegNoCheck, SegCSCheck, SegCallGateCheck,
SegSSCheck, SegIretCheck, SegIntCSCheck
};
}}; }};
output decoder {{ output decoder {{
@ -1018,11 +1023,46 @@ let {{
DestReg = SegSelSrc1; 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 = ''' code = '''
// The selector is in source 1 and can be at most 16 bits. // The selector is in source 1 and can be at most 16 bits.
SegSelector selector = psrc1; 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. // Compute the address of the descriptor and set DestReg to it.
if (selector.ti) { if (selector.ti) {
// A descriptor in the LDT // A descriptor in the LDT

View file

@ -149,6 +149,7 @@ def operands {{
'GDTRBase': ('ControlReg', 'uqw', 'MISCREG_TSG_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 205), 'GDTRBase': ('ControlReg', 'uqw', 'MISCREG_TSG_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 205),
'GDTRLimit': ('ControlReg', 'uqw', 'MISCREG_TSG_LIMIT', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 206), '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), '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) 'Mem': ('Mem', 'uqw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 300)
}}; }};