| 429 | } |
| 430 | |
| 431 | static uint64_t HandleSyscallImpl(FEXCore::Core::CpuStateFrame* Frame, FEXCore::HLE::SyscallArguments* Args) { |
| 432 | const uint64_t ReturnRIP = *(uint32_t*)(Frame->State.gregs[FEXCore::X86State::REG_RSP]); // Return address from the stack |
| 433 | uint64_t ReturnRSP = Frame->State.gregs[FEXCore::X86State::REG_RSP] + 4; // Stack pointer after popping return address |
| 434 | uint64_t ReturnRAX = 0; |
| 435 | |
| 436 | if (Frame->State.rip == (uint64_t)BridgeInstrs::UnixCall) { |
| 437 | struct StackLayout { |
| 438 | unixlib_handle_t Handle; |
| 439 | UINT32 ID; |
| 440 | ULONG32 Args; |
| 441 | }* StackArgs = reinterpret_cast<StackLayout*>(ReturnRSP); |
| 442 | |
| 443 | ReturnRSP += sizeof(StackLayout); |
| 444 | |
| 445 | Context::UnlockJITContext(); |
| 446 | ReturnRAX = static_cast<uint64_t>(WineUnixCall(StackArgs->Handle, StackArgs->ID, ULongToPtr(StackArgs->Args))); |
| 447 | Context::LockJITContext(); |
| 448 | } else if (Frame->State.rip == (uint64_t)BridgeInstrs::Syscall) { |
| 449 | const uint64_t EntryRAX = Frame->State.gregs[FEXCore::X86State::REG_RAX]; |
| 450 | |
| 451 | Context::UnlockJITContext(); |
| 452 | Wow64ProcessPendingCrossProcessItems(); |
| 453 | ReturnRAX = static_cast<uint64_t>(Wow64SystemServiceEx(static_cast<UINT>(EntryRAX), reinterpret_cast<UINT*>(ReturnRSP + 4))); |
| 454 | Context::LockJITContext(); |
| 455 | } |
| 456 | // If a new context has been set, use it directly and don't return to the syscall caller |
| 457 | if (Frame->State.rip == (uint64_t)BridgeInstrs::Syscall || Frame->State.rip == (uint64_t)BridgeInstrs::UnixCall) { |
| 458 | Frame->State.gregs[FEXCore::X86State::REG_RAX] = ReturnRAX; |
| 459 | Frame->State.gregs[FEXCore::X86State::REG_RSP] = ReturnRSP; |
| 460 | Frame->State.rip = ReturnRIP; |
| 461 | } |
| 462 | |
| 463 | // NORETURNEDRESULT causes this result to be ignored since we restore all registers back from memory after a syscall anyway |
| 464 | return 0; |
| 465 | } |
| 466 | |
| 467 | uint64_t HandleSyscall(FEXCore::Core::CpuStateFrame* Frame, FEXCore::HLE::SyscallArguments* Args) override { |
| 468 | // Stash the the context pointer on the stack, as Simulate can be called from this syscall handler which would overwrite it |
nothing calls this directly
no test coverage detected