Alexandre Julliard : ntdll: Add support for dispatching exception from 32-bit code in Wow64 mode.
Alexandre Julliard
julliard at winehq.org
Wed Dec 1 15:23:48 CST 2021
Module: wine
Branch: master
Commit: e5e857c290352f41ce48935c3925aba68e87e873
URL: https://source.winehq.org/git/wine.git/?a=commit;h=e5e857c290352f41ce48935c3925aba68e87e873
Author: Alexandre Julliard <julliard at winehq.org>
Date: Wed Dec 1 11:27:51 2021 +0100
ntdll: Add support for dispatching exception from 32-bit code in Wow64 mode.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntdll/loader.c | 3 +++
dlls/ntdll/ntdll_misc.h | 1 +
dlls/ntdll/signal_x86_64.c | 25 ++++++++++++++++++++++++-
dlls/ntdll/unix/signal_x86_64.c | 1 +
4 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 3cc522af4d8..86aec79dbfc 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -3855,6 +3855,8 @@ static void load_global_options(void)
static void (WINAPI *pWow64LdrpInitialize)( CONTEXT *ctx );
+void (WINAPI *pWow64PrepareForException)( EXCEPTION_RECORD *rec, CONTEXT *context ) = NULL;
+
static void init_wow64( CONTEXT *context )
{
if (!imports_fixup_done)
@@ -3874,6 +3876,7 @@ static void init_wow64( CONTEXT *context )
if (!(p ## name = RtlFindExportedRoutineByName( wow64, #name ))) ERR( "failed to load %s\n", #name )
GET_PTR( Wow64LdrpInitialize );
+ GET_PTR( Wow64PrepareForException );
#undef GET_PTR
imports_fixup_done = TRUE;
}
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index 34af6b780cf..d7c5ade5bc1 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -52,6 +52,7 @@ extern void WINAPI LdrInitializeThunk(CONTEXT*,ULONG_PTR,ULONG_PTR,ULONG_PTR) DE
extern NTSTATUS WINAPI KiUserExceptionDispatcher(EXCEPTION_RECORD*,CONTEXT*) DECLSPEC_HIDDEN;
extern void WINAPI KiUserApcDispatcher(CONTEXT*,ULONG_PTR,ULONG_PTR,ULONG_PTR,PNTAPCFUNC) DECLSPEC_HIDDEN;
extern void WINAPI KiUserCallbackDispatcher(ULONG,void*,ULONG) DECLSPEC_HIDDEN;
+extern void (WINAPI *pWow64PrepareForException)( EXCEPTION_RECORD *rec, CONTEXT *context ) DECLSPEC_HIDDEN;
#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
extern RUNTIME_FUNCTION *lookup_function_info( ULONG_PTR pc, ULONG_PTR *base, LDR_DATA_TABLE_ENTRY **module ) DECLSPEC_HIDDEN;
diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c
index ef32eba68b7..e0372b111fd 100644
--- a/dlls/ntdll/signal_x86_64.c
+++ b/dlls/ntdll/signal_x86_64.c
@@ -566,12 +566,35 @@ NTSTATUS WINAPI dispatch_exception( EXCEPTION_RECORD *rec, CONTEXT *context )
}
+NTSTATUS WINAPI dispatch_wow_exception( EXCEPTION_RECORD *rec_ptr, CONTEXT *context_ptr )
+{
+ char buffer[sizeof(CONTEXT) + sizeof(CONTEXT_EX) + sizeof(XSTATE) + 128];
+ CONTEXT *context;
+ CONTEXT_EX *context_ex;
+ EXCEPTION_RECORD rec = *rec_ptr;
+
+ RtlInitializeExtendedContext( buffer, context_ptr->ContextFlags, &context_ex );
+ context = RtlLocateLegacyContext( context_ex, NULL );
+ RtlCopyContext( context, context_ptr->ContextFlags, context_ptr );
+ pWow64PrepareForException( &rec, context );
+ return dispatch_exception( &rec, context );
+}
+
+
/*******************************************************************
* KiUserExceptionDispatcher (NTDLL.@)
*/
__ASM_GLOBAL_FUNC( KiUserExceptionDispatcher,
"mov 0x98(%rsp),%rcx\n\t" /* context->Rsp */
- "mov 0xf8(%rsp),%rdx\n\t" /* context->Rip */
+ "movw %cs,%ax\n\t"
+ "cmpw %ax,0x38(%rsp)\n\t" /* context->SegCs */
+ "je 1f\n\t"
+ "mov %rsp,%rdx\n\t" /* context */
+ "lea 0x4f0(%rsp),%rcx\n\t" /* rec */
+ "movq %r14,%rsp\n\t" /* switch to 64-bit stack */
+ "call " __ASM_NAME("dispatch_wow_exception") "\n\t"
+ "int3\n"
+ "1:\tmov 0xf8(%rsp),%rdx\n\t" /* context->Rip */
"mov %rdx,-0x8(%rcx)\n\t"
"mov %rbp,-0x10(%rcx)\n\t"
"mov %rdi,-0x18(%rcx)\n\t"
diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c
index 0085bd42410..9972faf799c 100644
--- a/dlls/ntdll/unix/signal_x86_64.c
+++ b/dlls/ntdll/unix/signal_x86_64.c
@@ -2171,6 +2171,7 @@ static void setup_raise_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec
}
}
+ CS_sig(sigcontext) = cs64_sel;
RIP_sig(sigcontext) = (ULONG_PTR)pKiUserExceptionDispatcher;
RSP_sig(sigcontext) = (ULONG_PTR)stack;
/* clear single-step, direction, and align check flag */
More information about the wine-cvs
mailing list