x86-64: Implement IRET for wine

This commit is contained in:
Stefanos Kornilios Mitsis Poiitidis committed 2020-09-21 13:42:07 +03:00
1 parent 2cb8db0abb
commit 23a4e83ba2
3 files changed
+41 -1

No files matched your search

@@ -168,6 +168,44 @@ void OpDispatchBuilder::RETOp(OpcodeArgs) {
BlockSetRIP = true;
}
/*
stack contains:
RIP
CS
EFLAGS
RSP
SS
*/
void OpDispatchBuilder::IRETOp(OpcodeArgs) {
LogMan::Throw::A(CTX->Config.Is64BitMode == true, "IRET only implemented for x64");
uint8_t GPRSize = CTX->Config.Is64BitMode ? 8 : 4;
auto Constant = _Constant(GPRSize);
OrderedNode* SP = _LoadContext(GPRSize, offsetof(FEXCore::Core::CPUState, gregs[FEXCore::X86State::REG_RSP]), GPRClass);
// RIP (64 bits)
_StoreContext(GPRClass, GPRSize, offsetof(FEXCore::Core::CPUState, rip), _LoadMem(GPRClass, GPRSize, SP, GPRSize));
SP = _Add(SP, Constant);
//CS (lower 16 used)
_StoreContext(GPRClass, 2, offsetof(FEXCore::Core::CPUState, cs), _LoadMem(GPRClass, GPRSize, SP, GPRSize));
SP = _Add(SP, Constant);
//eflags (lower 16 used)
auto eflags = _LoadMem(GPRClass, GPRSize, SP, GPRSize);
SetPackedRFLAG(false, eflags);
SP = _Add(SP, Constant);
// RSP
_StoreContext(GPRClass, GPRSize, offsetof(FEXCore::Core::CPUState, gregs[FEXCore::X86State::REG_RSP]), _LoadMem(GPRClass, GPRSize, SP, GPRSize));
SP = _Add(SP, Constant);
//ss
_StoreContext(GPRClass, 2, offsetof(FEXCore::Core::CPUState, ss), _LoadMem(GPRClass, GPRSize, SP, GPRSize));
SP = _Add(SP, Constant);
_ExitFunction();
BlockSetRIP = true;
}
void OpDispatchBuilder::SIGRETOp(OpcodeArgs) {
// Store the new RIP
_SignalReturn();
@@ -7477,6 +7515,7 @@ void InstallOpcodeHandlers(Context::OperatingMode Mode) {
{0xC8, 1, &OpDispatchBuilder::EnterOp},
{0xC9, 1, &OpDispatchBuilder::LEAVEOp},
{0xCC, 2, &OpDispatchBuilder::INTOp},
{0xCF, 1, &OpDispatchBuilder::IRETOp},
{0xD7, 2, &OpDispatchBuilder::XLATOp},
{0xE0, 3, &OpDispatchBuilder::LoopOp},
{0xE3, 1, &OpDispatchBuilder::CondJUMPRCXOp},
@@ -106,6 +106,7 @@ public:
void LEAOp(OpcodeArgs);
void NOPOp(OpcodeArgs);
void RETOp(OpcodeArgs);
void IRETOp(OpcodeArgs);
void SIGRETOp(OpcodeArgs);
void CallbackReturnOp(OpcodeArgs);
void SecondaryALUOp(OpcodeArgs);
@@ -179,7 +179,7 @@ void InitializeBaseTables(Context::OperatingMode Mode) {
{0xCC, 1, X86InstInfo{"INT3", TYPE_INST, FLAGS_DEBUG, 0, nullptr}},
{0xCD, 1, X86InstInfo{"INT", TYPE_INST, FLAGS_DEBUG , 1, nullptr}},
{0xCE, 1, X86InstInfo{"[INV]", TYPE_INVALID, FLAGS_NONE, 0, nullptr}},
{0xCF, 1, X86InstInfo{"IRET", TYPE_PRIV, FLAGS_NONE, 0, nullptr}},
{0xCF, 1, X86InstInfo{"IRET", TYPE_INST, FLAGS_SETS_RIP | FLAGS_BLOCK_END, 0, nullptr}},
{0xD4, 3, X86InstInfo{"[INV]", TYPE_INVALID, FLAGS_NONE, 0, nullptr}},
{0xD7, 1, X86InstInfo{"XLAT", TYPE_INST, FLAGS_DEBUG_MEM_ACCESS, 0, nullptr}},