Module: wine Branch: master Commit: 89336772f810cf0ecc456d5a94ad766fb92e87e1 URL: https://gitlab.winehq.org/wine/wine/-/commit/89336772f810cf0ecc456d5a94ad766...
Author: Alexandre Julliard julliard@winehq.org Date: Tue Feb 27 16:20:55 2024 +0100
wow64: Use a .seh handler for the simulation loop.
---
dlls/wow64/syscall.c | 75 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 63 insertions(+), 12 deletions(-)
diff --git a/dlls/wow64/syscall.c b/dlls/wow64/syscall.c index 78338f7ef6a..9f1f324ce35 100644 --- a/dlls/wow64/syscall.c +++ b/dlls/wow64/syscall.c @@ -940,25 +940,75 @@ NTSTATUS WINAPI Wow64SystemServiceEx( UINT num, UINT *args )
/********************************************************************** - * simulate_filter + * cpu_simulate */ +#ifdef __aarch64__ +extern void DECLSPEC_NORETURN cpu_simulate( void (*func)(void) ); +__ASM_GLOBAL_FUNC( cpu_simulate, + "stp x29, x30, [sp, #-32]!\n\t" + ".seh_save_fplr_x 32\n\t" + ".seh_endprologue\n\t" + ".seh_handler cpu_simulate_handler, @except\n\t" + "str x0, [sp, #16]\n" + ".Lcpu_simulate_loop:\n\t" + "ldr x0, [sp, #16]\n\t" + "blr x0\n\t" + "b .Lcpu_simulate_loop" ) +__ASM_GLOBAL_FUNC( cpu_simulate_handler, + "stp x29, x30, [sp, #-32]!\n\t" + ".seh_save_fplr_x 32\n\t" + ".seh_endprologue\n\t" + "mov x19, x0\n\t" /* record */ + "mov x20, x1\n\t" /* frame */ + "stp x0, x2, [sp, #16]\n\t" /* record, context */ + "add x0, sp, #16\n\t" + "bl Wow64PassExceptionToGuest\n\t" + "mov x20, x0\n\t" /* frame */ + "adr x1, .Lcpu_simulate_loop\n\t" /* target */ + "mov x19, x2\n\t" /* record */ + "bl RtlUnwind\n\t" + "brk #1" ) + +#elif defined __WINE_PE_BUILD +extern void DECLSPEC_NORETURN cpu_simulate( void (*func)(void) ); +__ASM_GLOBAL_FUNC( cpu_simulate, + "subq $0x28, %rsp\n\t" + ".seh_stackalloc 0x28\n\t" + ".seh_endprologue\n\t" + ".seh_handler cpu_simulate_handler, @except\n\t" + "movq %rcx,0x20(%rsp)\n" + ".Lcpu_simulate_loop:\n\t" + "call *0x20(%rsp)\n\t" + "jmp .Lcpu_simulate_loop" ) +__ASM_GLOBAL_FUNC( cpu_simulate_handler, + "subq $0x38, %rsp\n\t" + ".seh_stackalloc 0x38\n\t" + ".seh_endprologue\n\t" + "movq %rcx,%rsi\n\t" /* record */ + "movq %rcx,0x20(%rsp)\n\t" + "movq %rdx,%rdi\n\t" /* frame */ + "movq %r8,0x28(%rsp)\n\t" /* context */ + "leaq 0x20(%rsp),%rcx\n\t" + "call Wow64PassExceptionToGuest\n\t" + "movq %rdi,%rcx\n\t" /* frame */ + "leaq .Lcpu_simulate_loop(%rip), %rdx\n\t" /* target */ + "movq %rsi,%r8\n\t" /* record */ + "call RtlUnwind\n\t" + "int3" ) +#else static LONG CALLBACK simulate_filter( EXCEPTION_POINTERS *ptrs ) { Wow64PassExceptionToGuest( ptrs ); return EXCEPTION_EXECUTE_HANDLER; }
- -/********************************************************************** - * cpu_simulate - */ -static void cpu_simulate(void) +static void cpu_simulate( void (*func)(void) ) { for (;;) { __TRY { - pBTCpuSimulate(); + func(); } __EXCEPT( simulate_filter ) { @@ -967,6 +1017,7 @@ static void cpu_simulate(void) __ENDTRY } } +#endif
/********************************************************************** @@ -1039,7 +1090,7 @@ void WINAPI Wow64ApcRoutine( ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, CON ctx.Eip = pLdrSystemDllInitBlock->pKiUserApcDispatcher; frame.wow_context = &stack->context; pBTCpuSetContext( GetCurrentThread(), GetCurrentProcess(), NULL, &ctx ); - cpu_simulate(); + cpu_simulate( pBTCpuSimulate ); } break;
@@ -1065,7 +1116,7 @@ void WINAPI Wow64ApcRoutine( ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, CON ctx.R3 = arg3; frame.wow_context = &stack->context; pBTCpuSetContext( GetCurrentThread(), GetCurrentProcess(), NULL, &ctx ); - cpu_simulate(); + cpu_simulate( pBTCpuSimulate ); } break; } @@ -1128,7 +1179,7 @@ NTSTATUS WINAPI Wow64KiUserCallbackDispatcher( ULONG id, void *args, ULONG len, pBTCpuSetContext( GetCurrentThread(), GetCurrentProcess(), NULL, &ctx );
if (!__wine_setjmpex( &frame.jmpbuf, NULL )) - cpu_simulate(); + cpu_simulate( pBTCpuSimulate ); else pBTCpuSetContext( GetCurrentThread(), GetCurrentProcess(), NULL, &orig_ctx ); } @@ -1153,7 +1204,7 @@ NTSTATUS WINAPI Wow64KiUserCallbackDispatcher( ULONG id, void *args, ULONG len, pBTCpuSetContext( GetCurrentThread(), GetCurrentProcess(), NULL, &ctx );
if (!__wine_setjmpex( &frame.jmpbuf, NULL )) - cpu_simulate(); + cpu_simulate( pBTCpuSimulate ); else pBTCpuSetContext( GetCurrentThread(), GetCurrentProcess(), NULL, &orig_ctx ); } @@ -1177,7 +1228,7 @@ void WINAPI Wow64LdrpInitialize( CONTEXT *context )
RtlRunOnceExecuteOnce( &init_done, process_init, NULL, NULL ); thread_init(); - cpu_simulate(); + cpu_simulate( pBTCpuSimulate ); }