mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-14 10:00:42 +02:00
ARM64EC: Support directly issuing the NtContinue syscall
This is required for handling SMC with the ResetToConsistentState arguments as used in Windows, as using the NTDLL exported NtContinue would wipe out any reserved registers in the ARM64EC ABI. For Windows the syscall numbers are somewhat stable, and the SVC instruction can be called directly. Since wine doesn't handle that on ARM64, hardcode the system call number and manually call into wine dispatcher. Once wine gains proper syscall thunks, those can be parsed to get the number and the hardcoding dropped.
This commit is contained in:
1 parent
e2583249c6
commit
4877bb3f19
2 files changed
+34
-1
No files matched your search
@@ -46,9 +46,17 @@ $end_info$
|
||||
#include <wine/debug.h>
|
||||
|
||||
class ECSyscallHandler;
|
||||
|
||||
extern "C" {
|
||||
void* X64ReturnInstr; // See Module.S
|
||||
extern void* ExitFunctionEC;
|
||||
|
||||
// Wine doesn't support issuing direct system calls with SVC, and unlike Windows it doesn't have a 'stable' syscall number for NtContinue
|
||||
void* WineSyscallDispatcher;
|
||||
// TODO: this really shouldn't be hardcoded, once wine gains proper syscall thunks this can be dropped.
|
||||
uint64_t WineNtContinueSyscallId = 0x1a;
|
||||
}
|
||||
|
||||
struct ThreadCPUArea {
|
||||
static constexpr size_t TEBCPUAreaOffset = 0x1788;
|
||||
CHPE_V2_CPU_AREA_INFO* Area;
|
||||
@@ -85,6 +93,9 @@ struct ThreadCPUArea {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
extern "C" NTSTATUS NtContinueNative(ARM64_NT_CONTEXT* NativeContext, BOOLEAN Alert);
|
||||
|
||||
namespace {
|
||||
fextl::unique_ptr<FEXCore::Context::Context> CTX;
|
||||
fextl::unique_ptr<FEX::DummyHandlers::DummySignalDelegator> SignalDelegator;
|
||||
@@ -437,7 +448,12 @@ void ProcessInit() {
|
||||
X64ReturnInstr = ::VirtualAlloc(nullptr, FEXCore::Utils::FEX_PAGE_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
*reinterpret_cast<uint8_t*>(X64ReturnInstr) = 0xc3;
|
||||
|
||||
Exception::KiUserExceptionDispatcher = GetRedirectedProcAddress(GetModuleHandle("ntdll.dll"), "KiUserExceptionDispatcher");
|
||||
const auto NtDll = GetModuleHandle("ntdll.dll");
|
||||
Exception::KiUserExceptionDispatcher = GetRedirectedProcAddress(NtDll, "KiUserExceptionDispatcher");
|
||||
const auto WineSyscallDispatcherPtr = reinterpret_cast<void**>(GetProcAddress(NtDll, "__wine_syscall_dispatcher"));
|
||||
if (WineSyscallDispatcherPtr) {
|
||||
WineSyscallDispatcher = *WineSyscallDispatcherPtr;
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessTerm() {}
|
||||
|
||||
Reference in new issue
Block a user