Alexandre Julliard : wow64: Add support for jumping to 32-bit code in Wow64LdrpInitialize().
Alexandre Julliard
julliard at winehq.org
Wed Aug 4 16:41:37 CDT 2021
Module: wine
Branch: master
Commit: ae21ddb0240fbe917473cc92669ac09e356197e9
URL: https://source.winehq.org/git/wine.git/?a=commit;h=ae21ddb0240fbe917473cc92669ac09e356197e9
Author: Alexandre Julliard <julliard at 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 at 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 ) \
More information about the wine-cvs
mailing list