ARM64EC: Patch the call checker before calling any syscall exports

CEF on Windows patches these before FEX is even loaded, so this needs to
be setup as early as possible using some direct syscalls which skip any
such patches.
This commit is contained in:
Billy Laws committed 2024-09-10 16:05:37 +00:00
1 parent 360ea538b7
commit 7255850e9d
2 files changed
+56 -27

No files matched your search

+26 -16
View File
@@ -91,22 +91,32 @@ ret_sp_misaligned:
ldr lr, [lr, #:lo12:X64ReturnInstr]
br x17
// Calls NtContinue directly to allow continuing from a full native context, as the NTDLL NtContinue export takes in
// an x64 context with EC and the conversion to that loses the ARM64EC ABI-disallowed registers that FEX uses.
.global "#NtContinueNative"
"#NtContinueNative":
adrp x16, WineSyscallDispatcher
ldr x16, [x16, #:lo12:WineSyscallDispatcher]
cbz x16, direct_syscall
wine_syscall:
mov x9, x30
adrp x8, WineNtContinueSyscallId
ldr x8, [x8, #:lo12:WineNtContinueSyscallId]
blr x16
ret
direct_syscall:
svc #0x43
ret
// Makes a wrapper for calling a system call directly, skipping the usual ntdll thunks
#define HASH #
#define DIRECT_SYSCALL_WRAPPER(Name, WineIdName, WindowsId) \
.global Name; \
Name:; \
adrp x16, WineSyscallDispatcher; \
ldr x16, [x16, HASH:lo12:WineSyscallDispatcher]; \
cbz x16, 1f; \
mov x9, x30; \
adrp x8, WineIdName; \
ldr x8, [x8, HASH:lo12:WineIdName]; \
blr x16; \
ret; \
1:; \
svc HASH WindowsId; \
ret
// Allows for continuing from a full native context, as the NTDLL NtContinue export takes in an x64 context with EC and
// the conversion to that loses the ARM64EC ABI-disallowed registers that FEX uses.
DIRECT_SYSCALL_WRAPPER("#NtContinueNative", WineNtContinueSyscallId, 0x43)
// Both of these are wrapped as FEX needs them to setup its call checker at startup time and their NTDLL thunks could
// already be patched by then (and because the call checker isn't installed, their patched x86 versions would be invoked
// when called by FEX).
DIRECT_SYSCALL_WRAPPER("#NtAllocateVirtualMemoryNative", WineNtAllocateVirtualMemorySyscallId, 0x18)
DIRECT_SYSCALL_WRAPPER("#NtProtectVirtualMemoryNative", WineNtProtectVirtualMemorySyscallId, 0x50)
// A replacement for the standard ARM64EC call checker that ignores any FFS patches and always redirects to a function's
// native implementation. As the only library FEX calls into is NTDLL, this is done using a LUT generated at init time.