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"):
|
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
|
||||||
|
|
||||||
|
|
|
@ -231,6 +231,11 @@ output header {{
|
||||||
void
|
void
|
||||||
divide(uint64_t dividend, uint64_t divisor,
|
divide(uint64_t dividend, uint64_t divisor,
|
||||||
uint64_t "ient, uint64_t &remainder);
|
uint64_t "ient, 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
|
||||||
|
|
|
@ -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)
|
||||||
}};
|
}};
|
||||||
|
|
Loading…
Reference in a new issue