Module: wine Branch: master Commit: ae21ddb0240fbe917473cc92669ac09e356197e9 URL: https://source.winehq.org/git/wine.git/?a=commit;h=ae21ddb0240fbe917473cc926...
Author: Alexandre Julliard julliard@winehq.org Date: Wed Aug 4 12:25:52 2021 +0200
wow64: Add support for jumping to 32-bit code in Wow64LdrpInitialize().
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/wow64/process.c | 15 ++++++++++++ dlls/wow64/sync.c | 9 ++++++++ dlls/wow64/syscall.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++------ dlls/wow64/syscall.h | 2 ++ 4 files changed, 83 insertions(+), 7 deletions(-)
diff --git a/dlls/wow64/process.c b/dlls/wow64/process.c index 44380535d9c..764a2ba46ca 100644 --- a/dlls/wow64/process.c +++ b/dlls/wow64/process.c @@ -309,6 +309,21 @@ NTSTATUS WINAPI wow64_NtAssignProcessToJobObject( UINT *args ) }
+/********************************************************************** + * wow64_NtContinue + */ +NTSTATUS WINAPI wow64_NtContinue( UINT *args ) +{ + void *context = get_ptr( &args ); + BOOLEAN alertable = get_ulong( &args ); + + NtSetInformationThread( GetCurrentThread(), ThreadWow64Context, + context, get_machine_context_size( current_machine )); + if (alertable) NtTestAlert(); + return STATUS_SUCCESS; +} + + /********************************************************************** * wow64_NtCreateThread */ diff --git a/dlls/wow64/sync.c b/dlls/wow64/sync.c index 1b4c3c864c3..400deeb8422 100644 --- a/dlls/wow64/sync.c +++ b/dlls/wow64/sync.c @@ -1461,6 +1461,15 @@ NTSTATUS WINAPI wow64_NtTerminateJobObject( UINT *args ) }
+/********************************************************************** + * wow64_NtTestAlert + */ +NTSTATUS WINAPI wow64_NtTestAlert( UINT *args ) +{ + return NtTestAlert(); +} + + /********************************************************************** * wow64_NtWaitForDebugEvent */ diff --git a/dlls/wow64/syscall.c b/dlls/wow64/syscall.c index e120ed022cd..6f443557e16 100644 --- a/dlls/wow64/syscall.c +++ b/dlls/wow64/syscall.c @@ -393,7 +393,7 @@ static HMODULE load_cpu_dll(void) /********************************************************************** * process_init */ -static void process_init(void) +static DWORD WINAPI process_init( RTL_RUN_ONCE *once, void *param, void **context ) { HMODULE module; UNICODE_STRING str; @@ -421,11 +421,63 @@ static void process_init(void) *pWow64Transition = *p__wine_syscall_dispatcher = pBTCpuGetBopCode();
init_file_redirects(); + return TRUE;
#undef GET_PTR }
+/********************************************************************** + * thread_init + */ +static void thread_init(void) +{ + /* update initial context to jump to 32-bit LdrInitializeThunk (cf. 32-bit call_init_thunk) */ + switch (current_machine) + { + case IMAGE_FILE_MACHINE_I386: + { + I386_CONTEXT *ctx_ptr, ctx = { CONTEXT_I386_ALL }; + ULONG *stack; + + NtQueryInformationThread( GetCurrentThread(), ThreadWow64Context, &ctx, sizeof(ctx), NULL ); + ctx_ptr = (I386_CONTEXT *)ULongToPtr( ctx.Esp ) - 1; + *ctx_ptr = ctx; + + stack = (ULONG *)ctx_ptr; + *(--stack) = 0; + *(--stack) = 0; + *(--stack) = 0; + *(--stack) = PtrToUlong( ctx_ptr ); + *(--stack) = 0xdeadbabe; + ctx.Esp = PtrToUlong( stack ); + ctx.Eip = pLdrSystemDllInitBlock->pLdrInitializeThunk; + NtSetInformationThread( GetCurrentThread(), ThreadWow64Context, &ctx, sizeof(ctx) ); + } + break; + + case IMAGE_FILE_MACHINE_ARMNT: + { + ARM_CONTEXT *ctx_ptr, ctx = { CONTEXT_ARM_ALL }; + + NtQueryInformationThread( GetCurrentThread(), ThreadWow64Context, &ctx, sizeof(ctx), NULL ); + ctx_ptr = (ARM_CONTEXT *)ULongToPtr( ctx.Sp & ~15 ) - 1; + *ctx_ptr = ctx; + + ctx.R0 = PtrToUlong( ctx_ptr ); + ctx.Sp = PtrToUlong( ctx_ptr ); + ctx.Pc = pLdrSystemDllInitBlock->pLdrInitializeThunk; + NtSetInformationThread( GetCurrentThread(), ThreadWow64Context, &ctx, sizeof(ctx) ); + } + break; + + default: + ERR( "not supported machine %x\n", current_machine ); + NtTerminateProcess( GetCurrentProcess(), STATUS_INVALID_IMAGE_FORMAT ); + } +} + + /********************************************************************** * free_temp_data */ @@ -500,11 +552,9 @@ void WINAPI Wow64ApcRoutine( ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3, CON */ void WINAPI Wow64LdrpInitialize( CONTEXT *context ) { - static BOOL init_done; + static RTL_RUN_ONCE init_done;
- if (!init_done) - { - init_done = TRUE; - process_init(); - } + RtlRunOnceExecuteOnce( &init_done, process_init, NULL, NULL ); + thread_init(); + pBTCpuSimulate(); } diff --git a/dlls/wow64/syscall.h b/dlls/wow64/syscall.h index 782a7a78c18..f794d35cee4 100644 --- a/dlls/wow64/syscall.h +++ b/dlls/wow64/syscall.h @@ -43,6 +43,7 @@ SYSCALL_ENTRY( NtClose ) \ SYSCALL_ENTRY( NtCompleteConnectPort ) \ SYSCALL_ENTRY( NtConnectPort ) \ + SYSCALL_ENTRY( NtContinue ) \ SYSCALL_ENTRY( NtCreateDebugObject ) \ SYSCALL_ENTRY( NtCreateDirectoryObject ) \ SYSCALL_ENTRY( NtCreateEvent ) \ @@ -217,6 +218,7 @@ SYSCALL_ENTRY( NtTerminateJobObject ) \ SYSCALL_ENTRY( NtTerminateProcess ) \ SYSCALL_ENTRY( NtTerminateThread ) \ + SYSCALL_ENTRY( NtTestAlert ) \ SYSCALL_ENTRY( NtUnloadDriver ) \ SYSCALL_ENTRY( NtUnloadKey ) \ SYSCALL_ENTRY( NtUnlockFile ) \