Module: wine Branch: master Commit: 577c327a44025fb05fa9dbb12990e2c0e2be06d9 URL: https://gitlab.winehq.org/wine/wine/-/commit/577c327a44025fb05fa9dbb12990e2c...
Author: Alexandre Julliard julliard@winehq.org Date: Fri Mar 1 14:27:32 2024 +0100
kernelbase: Implement RaiseException on ARM64EC.
---
dlls/kernelbase/debug.c | 33 ++++++++++++++++++++++++++++++--- dlls/ntdll/tests/exception.c | 3 ++- 2 files changed, 32 insertions(+), 4 deletions(-)
diff --git a/dlls/kernelbase/debug.c b/dlls/kernelbase/debug.c index 8eb5094dbef..b7df4a7c766 100644 --- a/dlls/kernelbase/debug.c +++ b/dlls/kernelbase/debug.c @@ -313,7 +313,34 @@ void WINAPI DECLSPEC_HOTPATCH OutputDebugStringW( LPCWSTR str ) /******************************************************************* * RaiseException (kernelbase.@) */ -#if defined(__x86_64__) +#ifdef __x86_64__ +#ifdef __arm64ec__ +void __attribute__((naked)) RaiseException( DWORD code, DWORD flags, DWORD count, const ULONG_PTR *args ) +{ + asm( ".seh_proc RaiseException\n\t" + "stp x29, x30, [sp, #-0xb0]!\n\t" + ".seh_save_fplr_x 0xb0\n\t" + ".seh_endprologue\n\t" + "and w1, w1, #0x01\n\t" /* EXCEPTION_NONCONTINUABLE */ + "stp w0, w1, [sp, #0x10]\n\t" /* ExceptionCode, ExceptionFlags */ + "adr x4, RaiseException\n\t" + "stp xzr, x4, [sp, #0x18]\n\t" /* ExceptionRecord, ExceptionAddress */ + "mov w5, #0x0f\n\t" /* EXCEPTION_MAXIMUM_PARAMETERS */ + "cmp w2, w5\n\t" + "csel w2, w2, w5, lo\n\t" + "str x2, [sp, #0x28]\n\t" /* NumberParameters */ + "cbz x3, 1f\n\t" + "lsl w2, w2, #3\n\t" + "add x0, sp, #0x30\n\t" /* ExceptionInformation */ + "mov x1, x3\n\t" /* args */ + "bl "#memcpy"\n" + "1:\tadd x0, sp, #0x10\n\t" /* rec */ + "bl "#RtlRaiseException"\n\t" + "ldp x29, x30, [sp], #0xb0\n\t" + "ret\n\t" + ".seh_endproc" ); +} +#else /* Some DRMs depend on RaiseException not altering non-volatile registers. */ __ASM_GLOBAL_FUNC( RaiseException, ".byte 0x48,0x8d,0xa4,0x24,0x00,0x00,0x00,0x00\n\t" /* hotpatch prolog */ @@ -350,14 +377,14 @@ __ASM_GLOBAL_FUNC( RaiseException, "add $0xc8,%rsp\n\t" __ASM_CFI(".cfi_adjust_cfa_offset -0xc8\n\t") "ret" ) - +#endif /* __arm64ec__ */ C_ASSERT( offsetof(EXCEPTION_RECORD, ExceptionCode) == 0 ); C_ASSERT( offsetof(EXCEPTION_RECORD, ExceptionFlags) == 4 ); C_ASSERT( offsetof(EXCEPTION_RECORD, ExceptionRecord) == 8 ); C_ASSERT( offsetof(EXCEPTION_RECORD, ExceptionAddress) == 0x10 ); C_ASSERT( offsetof(EXCEPTION_RECORD, NumberParameters) == 0x18 ); C_ASSERT( offsetof(EXCEPTION_RECORD, ExceptionInformation) == 0x20 ); -#else +#else /* __x86_64__ */ void WINAPI DECLSPEC_HOTPATCH RaiseException( DWORD code, DWORD flags, DWORD count, const ULONG_PTR *args ) { EXCEPTION_RECORD record; diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c index b0b76f37813..eed151cdb1f 100644 --- a/dlls/ntdll/tests/exception.c +++ b/dlls/ntdll/tests/exception.c @@ -5183,7 +5183,8 @@ static void test_raiseexception_regs(void) ++expected; ok(test_raiseexception_regs_context.Rdi == expected, "got %#I64x.\n", test_raiseexception_regs_context.Rdi); ++expected; - ok(test_raiseexception_regs_context.Rbp == expected, "got %#I64x.\n", test_raiseexception_regs_context.Rbp); + ok(test_raiseexception_regs_context.Rbp == expected || is_arm64ec /* x29 modified by entry thunk */, + "got %#I64x.\n", test_raiseexception_regs_context.Rbp); ++expected; ok(test_raiseexception_regs_context.R12 == expected, "got %#I64x.\n", test_raiseexception_regs_context.R12); ++expected;