Alexandre Julliard : ntdll: Unwind the syscall frame when calling KiRaiseUserExceptionDispatcher().

Alexandre Julliard julliard at winehq.org
Tue Aug 11 16:26:50 CDT 2020


Module: wine
Branch: master
Commit: 9b7f14f1b49e838f5edc74296fd53b7215a8b52d
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=9b7f14f1b49e838f5edc74296fd53b7215a8b52d

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Aug 11 15:25:55 2020 +0200

ntdll: Unwind the syscall frame when calling KiRaiseUserExceptionDispatcher().

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/exception.c          |  6 ++++--
 dlls/ntdll/unix/loader.c        |  2 +-
 dlls/ntdll/unix/server.c        |  2 +-
 dlls/ntdll/unix/signal_arm.c    |  8 ++++++++
 dlls/ntdll/unix/signal_arm64.c  |  8 ++++++++
 dlls/ntdll/unix/signal_i386.c   | 16 ++++++++++++++++
 dlls/ntdll/unix/signal_x86_64.c | 31 +++++++++++++++++++++++++++++++
 dlls/ntdll/unix/unix_private.h  |  3 ++-
 8 files changed, 71 insertions(+), 5 deletions(-)

diff --git a/dlls/ntdll/exception.c b/dlls/ntdll/exception.c
index b32665611f..f8aca6dfb7 100644
--- a/dlls/ntdll/exception.c
+++ b/dlls/ntdll/exception.c
@@ -179,10 +179,12 @@ void WINAPI RtlRaiseStatus( NTSTATUS status )
 /*******************************************************************
  *		KiRaiseUserExceptionDispatcher  (NTDLL.@)
  */
-void WINAPI KiRaiseUserExceptionDispatcher(void)
+NTSTATUS WINAPI KiRaiseUserExceptionDispatcher(void)
 {
-    EXCEPTION_RECORD rec = { NtCurrentTeb()->ExceptionCode };
+    DWORD code = NtCurrentTeb()->ExceptionCode;
+    EXCEPTION_RECORD rec = { code };
     RtlRaiseException( &rec );
+    return code;
 }
 
 
diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c
index 776a22321a..d621d4ef8e 100644
--- a/dlls/ntdll/unix/loader.c
+++ b/dlls/ntdll/unix/loader.c
@@ -95,7 +95,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(module);
 extern IMAGE_NT_HEADERS __wine_spec_nt_header;
 
 void     (WINAPI *pDbgUiRemoteBreakin)( void *arg ) = NULL;
-void     (WINAPI *pKiRaiseUserExceptionDispatcher)(void) = NULL;
+NTSTATUS (WINAPI *pKiRaiseUserExceptionDispatcher)(void) = NULL;
 void     (WINAPI *pKiUserApcDispatcher)(CONTEXT*,ULONG_PTR,ULONG_PTR,ULONG_PTR,PNTAPCFUNC) = NULL;
 NTSTATUS (WINAPI *pKiUserExceptionDispatcher)(EXCEPTION_RECORD*,CONTEXT*) = NULL;
 void     (WINAPI *pLdrInitializeThunk)(CONTEXT*,void**,ULONG_PTR,ULONG_PTR) = NULL;
diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c
index 3f68e87acb..d867a7fb46 100644
--- a/dlls/ntdll/unix/server.c
+++ b/dlls/ntdll/unix/server.c
@@ -1650,7 +1650,7 @@ NTSTATUS WINAPI NtClose( HANDLE handle )
     if (!NtQueryInformationProcess( NtCurrentProcess(), ProcessDebugPort, &port, sizeof(port), NULL) && port)
     {
         NtCurrentTeb()->ExceptionCode = ret;
-        pKiRaiseUserExceptionDispatcher();
+        call_raise_user_exception_dispatcher( pKiRaiseUserExceptionDispatcher );
     }
     return ret;
 }
diff --git a/dlls/ntdll/unix/signal_arm.c b/dlls/ntdll/unix/signal_arm.c
index 30a1f61969..e619dbd975 100644
--- a/dlls/ntdll/unix/signal_arm.c
+++ b/dlls/ntdll/unix/signal_arm.c
@@ -596,6 +596,14 @@ void WINAPI call_user_apc( CONTEXT *context_ptr, ULONG_PTR ctx, ULONG_PTR arg1,
 }
 
 
+/***********************************************************************
+ *           call_raise_user_exception_dispatcher
+ */
+__ASM_GLOBAL_FUNC( call_raise_user_exception_dispatcher,
+                   "mov r2, r0\n\t"  /* dispatcher */
+                   "b " __ASM_NAME("call_user_exception_dispatcher") )
+
+
 /***********************************************************************
  *           call_user_exception_dispatcher
  */
diff --git a/dlls/ntdll/unix/signal_arm64.c b/dlls/ntdll/unix/signal_arm64.c
index b36b75972c..d5ced2172a 100644
--- a/dlls/ntdll/unix/signal_arm64.c
+++ b/dlls/ntdll/unix/signal_arm64.c
@@ -597,6 +597,14 @@ void WINAPI call_user_apc( CONTEXT *context_ptr, ULONG_PTR ctx, ULONG_PTR arg1,
 }
 
 
+/***********************************************************************
+ *           call_raise_user_exception_dispatcher
+ */
+__ASM_GLOBAL_FUNC( call_raise_user_exception_dispatcher,
+                   "mov x2, x0\n\t"  /* dispatcher */
+                   "b " __ASM_NAME("call_user_exception_dispatcher") )
+
+
 /***********************************************************************
  *           call_user_exception_dispatcher
  */
diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c
index 00bb422c44..39c154ebbc 100644
--- a/dlls/ntdll/unix/signal_i386.c
+++ b/dlls/ntdll/unix/signal_i386.c
@@ -1555,6 +1555,22 @@ void WINAPI call_user_apc( CONTEXT *context_ptr, ULONG_PTR ctx, ULONG_PTR arg1,
 }
 
 
+/***********************************************************************
+ *           call_raise_user_exception_dispatcher
+ */
+__ASM_GLOBAL_FUNC( call_raise_user_exception_dispatcher,
+                   "movl %fs:0x1f8,%eax\n\t"  /* x86_thread_data()->syscall_frame */
+                   "pushl (%eax)\n\t"         /* frame->prev_frame */
+                   "popl %fs:0x1f8\n\t"
+                   "movl 4(%eax),%edi\n\t"    /* frame->edi */
+                   "movl 8(%eax),%esi\n\t"    /* frame->esi */
+                   "movl 12(%eax),%ebx\n\t"   /* frame->ebx */
+                   "movl 16(%eax),%ebp\n\t"   /* frame->ebp */
+                   "movl 4(%esp),%edx\n\t"    /* dispatcher */
+                   "leal 24(%eax),%esp\n\t"
+                   "jmp *%edx" )
+
+
 /***********************************************************************
  *           call_user_exception_dispatcher
  */
diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c
index a1de881845..a1918908fc 100644
--- a/dlls/ntdll/unix/signal_x86_64.c
+++ b/dlls/ntdll/unix/signal_x86_64.c
@@ -1907,6 +1907,37 @@ void WINAPI call_user_apc( CONTEXT *context_ptr, ULONG_PTR ctx, ULONG_PTR arg1,
 }
 
 
+/***********************************************************************
+ *           call_raise_user_exception_dispatcher
+ */
+__ASM_GLOBAL_FUNC( call_raise_user_exception_dispatcher,
+                   "movq %gs:0x30,%rdx\n\t"
+                   "movq 0x328(%rdx),%rax\n\t"    /* amd64_thread_data()->syscall_frame */
+                   "pushq (%rax)\n\t"             /* frame->prev_frame */
+                   "popq 0x328(%rdx)\n\t"
+                   "movdqu 0x10(%rax),%xmm6\n\t"  /* frame->xmm[0..19 */
+                   "movdqu 0x20(%rax),%xmm7\n\t"
+                   "movdqu 0x30(%rax),%xmm8\n\t"
+                   "movdqu 0x40(%rax),%xmm9\n\t"
+                   "movdqu 0x50(%rax),%xmm10\n\t"
+                   "movdqu 0x60(%rax),%xmm11\n\t"
+                   "movdqu 0x70(%rax),%xmm12\n\t"
+                   "movdqu 0x80(%rax),%xmm13\n\t"
+                   "movdqu 0x90(%rax),%xmm14\n\t"
+                   "movdqu 0xa0(%rax),%xmm15\n\t"
+                   "ldmxcsr 0xb0(%rax)\n\t"       /* frame->mxcsr */
+                   "movq 0xb8(%rax),%r12\n\t"     /* frame->r12 */
+                   "movq 0xc0(%rax),%r13\n\t"     /* frame->r13 */
+                   "movq 0xc8(%rax),%r14\n\t"     /* frame->r14 */
+                   "movq 0xd0(%rax),%r15\n\t"     /* frame->r15 */
+                   "movq 0xd8(%rax),%rdi\n\t"     /* frame->rdi */
+                   "movq 0xe0(%rax),%rsi\n\t"     /* frame->rsi */
+                   "movq 0xe8(%rax),%rbx\n\t"     /* frame->rbx */
+                   "movq 0xf0(%rax),%rbp\n\t"     /* frame->rbp */
+                   "leaq 0x100(%rax),%rsp\n\t"
+                   "jmpq *%rcx" )
+
+
 /***********************************************************************
  *           call_user_exception_dispatcher
  */
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
index 7a6bb3c64a..397211957b 100644
--- a/dlls/ntdll/unix/unix_private.h
+++ b/dlls/ntdll/unix/unix_private.h
@@ -84,7 +84,7 @@ static const SIZE_T signal_stack_size = 0x10000 - 0x3000;
 
 /* callbacks to PE ntdll from the Unix side */
 extern void     (WINAPI *pDbgUiRemoteBreakin)( void *arg ) DECLSPEC_HIDDEN;
-extern void     (WINAPI *pKiRaiseUserExceptionDispatcher)(void) DECLSPEC_HIDDEN;
+extern NTSTATUS (WINAPI *pKiRaiseUserExceptionDispatcher)(void) DECLSPEC_HIDDEN;
 extern void     (WINAPI *pKiUserApcDispatcher)(CONTEXT*,ULONG_PTR,ULONG_PTR,ULONG_PTR,PNTAPCFUNC) DECLSPEC_HIDDEN;
 extern NTSTATUS (WINAPI *pKiUserExceptionDispatcher)(EXCEPTION_RECORD*,CONTEXT*) DECLSPEC_HIDDEN;
 extern void     (WINAPI *pLdrInitializeThunk)(CONTEXT*,void**,ULONG_PTR,ULONG_PTR) DECLSPEC_HIDDEN;
@@ -262,6 +262,7 @@ extern void WINAPI call_user_apc( CONTEXT *context_ptr, ULONG_PTR ctx, ULONG_PTR
                                   ULONG_PTR arg2, PNTAPCFUNC func ) DECLSPEC_HIDDEN;
 extern void WINAPI DECLSPEC_NORETURN call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context,
                                                                      NTSTATUS (WINAPI *dispatcher)(EXCEPTION_RECORD*,CONTEXT*) ) DECLSPEC_HIDDEN;
+extern void WINAPI DECLSPEC_NORETURN call_raise_user_exception_dispatcher( NTSTATUS (WINAPI *dispatcher)(void) ) DECLSPEC_HIDDEN;
 
 #define TICKSPERSEC 10000000
 #define SECS_1601_TO_1970  ((369 * 365 + 89) * (ULONGLONG)86400)




More information about the wine-cvs mailing list