X86: Implement the longmode versions of the syscall instruction.
This commit is contained in:
parent
dadc30b0a4
commit
6325245e3e
2 changed files with 111 additions and 4 deletions
|
@ -254,7 +254,13 @@
|
|||
}
|
||||
}
|
||||
#if FULL_SYSTEM
|
||||
0x05: syscall();
|
||||
0x05: decode MODE_MODE {
|
||||
0x0: decode MODE_SUBMODE {
|
||||
0x0: Inst::SYSCALL_64();
|
||||
0x1: Inst::SYSCALL_COMPAT();
|
||||
}
|
||||
0x1: Inst::SYSCALL_LEGACY();
|
||||
}
|
||||
#else
|
||||
0x05: SyscallInst::syscall('xc->syscall(Rax)', IsSyscall);
|
||||
#endif
|
||||
|
|
|
@ -53,14 +53,115 @@
|
|||
#
|
||||
# Authors: Gabe Black
|
||||
|
||||
microcode = ""
|
||||
microcode = '''
|
||||
def macroop SYSCALL_64
|
||||
{
|
||||
# All 1s.
|
||||
limm t1, "(uint64_t)(-1)"
|
||||
|
||||
# Save the next RIP.
|
||||
rdip rcx
|
||||
|
||||
# Stick rflags with RF masked into r11.
|
||||
rflags t2
|
||||
limm t3, "~RFBit"
|
||||
andi r11, t2, t3, dataSize=8
|
||||
|
||||
rdval t3, star
|
||||
srli t3, t3, 32, dataSize=8
|
||||
andi t3, t3, 0xFC, dataSize=1
|
||||
|
||||
# Set up CS.
|
||||
wrsel cs, t3
|
||||
wrbase cs, t0, dataSize=8
|
||||
wrlimit cs, t1, dataSize=4
|
||||
# Not writable, read/execute-able, not expandDown,
|
||||
# dpl=0, defaultSize=0, long mode
|
||||
limm t4, ((0 << 0) | (1 << 1) | (0 << 2) | \
|
||||
(0 << 3) | (0 << 5) | (1 << 6))
|
||||
wrattr cs, t4
|
||||
|
||||
# Set up SS.
|
||||
addi t3, t3, 8
|
||||
wrsel ss, t3
|
||||
wrbase ss, t0, dataSize=8
|
||||
wrlimit ss, t1, dataSize=4
|
||||
# Writable, readable, not expandDown,
|
||||
# dpl=0, defaultSize=0, not long mode
|
||||
limm t4, ((1 << 0) | (1 << 1) | (0 << 2) | \
|
||||
(0 << 3) | (0 << 5) | (0 << 6))
|
||||
wrattr ss, t4
|
||||
|
||||
# Set the new rip.
|
||||
rdval t7, lstar
|
||||
wrip t0, t7
|
||||
|
||||
# Mask the flags against sf_mask and leave RF turned off.
|
||||
rdval t3, sf_mask, dataSize=8
|
||||
xor t3, t3, t1, dataSize=8
|
||||
and t3, t3, r11, dataSize=8
|
||||
wrflags t3, t0
|
||||
};
|
||||
|
||||
def macroop SYSCALL_COMPAT
|
||||
{
|
||||
# All 1s.
|
||||
limm t1, "(uint64_t)(-1)"
|
||||
|
||||
# Save the next RIP.
|
||||
rdip rcx
|
||||
|
||||
# Stick rflags with RF masked into r11.
|
||||
rflags t2
|
||||
limm t3, "~RFBit"
|
||||
andi r11, t2, t3, dataSize=8
|
||||
|
||||
rdval t3, star
|
||||
srli t3, t3, 32, dataSize=8
|
||||
andi t3, t3, 0xFC, dataSize=1
|
||||
|
||||
# Set up CS.
|
||||
wrsel cs, t3
|
||||
wrbase cs, t0, dataSize=8
|
||||
wrlimit cs, t1, dataSize=4
|
||||
# Not writable, read/execute-able, not expandDown,
|
||||
# dpl=0, defaultSize=0, long mode
|
||||
limm t4, ((0 << 0) | (1 << 1) | (0 << 2) | \
|
||||
(0 << 3) | (0 << 5) | (1 << 6))
|
||||
wrattr cs, t4
|
||||
|
||||
# Set up SS.
|
||||
addi t3, t3, 8
|
||||
wrsel ss, t3
|
||||
wrbase ss, t0, dataSize=8
|
||||
wrlimit ss, t1, dataSize=4
|
||||
# Writable, readable, not expandDown,
|
||||
# dpl=0, defaultSize=0, not long mode
|
||||
limm t4, ((1 << 0) | (1 << 1) | (0 << 2) | \
|
||||
(0 << 3) | (0 << 5) | (0 << 6))
|
||||
wrattr ss, t4
|
||||
|
||||
# Set the new rip.
|
||||
rdval t7, cstar
|
||||
wrip t0, t7
|
||||
|
||||
# Mask the flags against sf_mask and leave RF turned off.
|
||||
rdval t3, sf_mask, dataSize=8
|
||||
xor t3, t3, t1, dataSize=8
|
||||
and t3, t3, r11, dataSize=8
|
||||
wrflags t3, t0
|
||||
};
|
||||
|
||||
def macroop SYSCALL_LEGACY
|
||||
{
|
||||
panic "The syscall instruction isn't implemented in legacy mode."
|
||||
};
|
||||
'''
|
||||
#let {{
|
||||
# class SYSENTER(Inst):
|
||||
# "GenFault ${new UnimpInstFault}"
|
||||
# class SYSEXIT(Inst):
|
||||
# "GenFault ${new UnimpInstFault}"
|
||||
# class SYSCALL(Inst):
|
||||
# "GenFault ${new UnimpInstFault}"
|
||||
# class SYSRET(Inst):
|
||||
# "GenFault ${new UnimpInstFault}"
|
||||
#}};
|
||||
|
|
Loading…
Reference in a new issue