X86: Implement the sysret instruction in long mode.
This commit is contained in:
parent
6325245e3e
commit
eec3f49a57
2 changed files with 79 additions and 5 deletions
|
@ -265,9 +265,15 @@
|
||||||
0x05: SyscallInst::syscall('xc->syscall(Rax)', IsSyscall);
|
0x05: SyscallInst::syscall('xc->syscall(Rax)', IsSyscall);
|
||||||
#endif
|
#endif
|
||||||
0x06: clts();
|
0x06: clts();
|
||||||
//sandpile.org says (AMD) after sysret, so I might want to check
|
0x07: decode MODE_SUBMODE {
|
||||||
//if that means amd64 or AMD machines
|
0x0: decode OPSIZE {
|
||||||
0x07: loadall_or_sysret();
|
// Return to 64 bit mode.
|
||||||
|
0x8: Inst::SYSRET_TO_64();
|
||||||
|
// Return to compatibility mode.
|
||||||
|
default: Inst::SYSRET_TO_COMPAT();
|
||||||
|
}
|
||||||
|
default: Inst::SYSRET_NON_64();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
0x01: decode OPCODE_OP_BOTTOM3 {
|
0x01: decode OPCODE_OP_BOTTOM3 {
|
||||||
0x0: invd();
|
0x0: invd();
|
||||||
|
|
|
@ -156,12 +156,80 @@ def macroop SYSCALL_LEGACY
|
||||||
{
|
{
|
||||||
panic "The syscall instruction isn't implemented in legacy mode."
|
panic "The syscall instruction isn't implemented in legacy mode."
|
||||||
};
|
};
|
||||||
|
|
||||||
|
def macroop SYSRET_TO_64
|
||||||
|
{
|
||||||
|
# All 1s.
|
||||||
|
limm t1, "(uint64_t)(-1)"
|
||||||
|
|
||||||
|
rdval t3, star
|
||||||
|
srli t3, t3, 48, dataSize=8
|
||||||
|
ori t3, t3, 3, dataSize=1
|
||||||
|
|
||||||
|
# Set rflags to r11 with RF and VM cleared.
|
||||||
|
limm t4, "~(RFBit | VMBit)"
|
||||||
|
and t4, t4, r11, dataSize=8
|
||||||
|
wrflags t4, t0
|
||||||
|
|
||||||
|
# Set up CS.
|
||||||
|
addi t4, t3, 16, dataSize=8
|
||||||
|
wrsel cs, t4
|
||||||
|
wrbase cs, t0, dataSize=8
|
||||||
|
wrlimit cs, t1, dataSize=4
|
||||||
|
# Not writable, read/execute-able, not expandDown,
|
||||||
|
# dpl=3, defaultSize=0, long mode
|
||||||
|
limm t4, ((0 << 0) | (1 << 1) | (0 << 2) | \
|
||||||
|
(3 << 3) | (0 << 5) | (1 << 6))
|
||||||
|
wrattr cs, t4
|
||||||
|
|
||||||
|
# Only the selector is changed for SS.
|
||||||
|
addi t4, t3, 8, dataSize=8
|
||||||
|
wrsel ss, t4
|
||||||
|
|
||||||
|
# Set the RIP back.
|
||||||
|
wrip rcx, t0, dataSize=8
|
||||||
|
};
|
||||||
|
|
||||||
|
def macroop SYSRET_TO_COMPAT
|
||||||
|
{
|
||||||
|
# All 1s.
|
||||||
|
limm t1, "(uint64_t)(-1)"
|
||||||
|
|
||||||
|
rdval t3, star
|
||||||
|
srli t3, t3, 48, dataSize=8
|
||||||
|
ori t3, t3, 3, dataSize=1
|
||||||
|
|
||||||
|
# Set rflags to r11 with RF and VM cleared.
|
||||||
|
limm t4, "~(RFBit | VMBit)"
|
||||||
|
and t4, t4, r11, dataSize=8
|
||||||
|
wrflags t4, t0
|
||||||
|
|
||||||
|
# Set up CS.
|
||||||
|
wrsel cs, t3
|
||||||
|
wrbase cs, t0, dataSize=8
|
||||||
|
wrlimit cs, t1, dataSize=4
|
||||||
|
# Not writable, read/execute-able, not expandDown,
|
||||||
|
# dpl=3, defaultSize=1, not long mode
|
||||||
|
limm t4, ((0 << 0) | (1 << 1) | (0 << 2) | \
|
||||||
|
(3 << 3) | (1 << 5) | (0 << 6))
|
||||||
|
wrattr cs, t4
|
||||||
|
|
||||||
|
# Only the selector is changed for SS.
|
||||||
|
addi t4, t3, 8, dataSize=8
|
||||||
|
wrsel ss, t4
|
||||||
|
|
||||||
|
# Set the RIP back.
|
||||||
|
wrip rcx, t0, dataSize=8
|
||||||
|
};
|
||||||
|
|
||||||
|
def macroop SYSRET_NON_64
|
||||||
|
{
|
||||||
|
panic "The sysret instruction isn't implemented in legacy mode."
|
||||||
|
};
|
||||||
'''
|
'''
|
||||||
#let {{
|
#let {{
|
||||||
# class SYSENTER(Inst):
|
# class SYSENTER(Inst):
|
||||||
# "GenFault ${new UnimpInstFault}"
|
# "GenFault ${new UnimpInstFault}"
|
||||||
# class SYSEXIT(Inst):
|
# class SYSEXIT(Inst):
|
||||||
# "GenFault ${new UnimpInstFault}"
|
# "GenFault ${new UnimpInstFault}"
|
||||||
# class SYSRET(Inst):
|
|
||||||
# "GenFault ${new UnimpInstFault}"
|
|
||||||
#}};
|
#}};
|
||||||
|
|
Loading…
Reference in a new issue