https://git.reactos.org/?p=reactos.git;a=commitdiff;h=92db51883abd474f3c3fe3d788a4b5e4201f8515

commit 92db51883abd474f3c3fe3d788a4b5e4201f8515
Author:     Timo Kreuzer <timo.kreu...@reactos.org>
AuthorDate: Mon Jan 8 21:55:15 2024 +0200
Commit:     Timo Kreuzer <timo.kreu...@reactos.org>
CommitDate: Sat Jan 13 19:39:23 2024 +0200

    [MSVCRT] Add asm wrapper around RtlUnwind for Wine code
    
    This is needed, because Wine code expects RtlUnwind to restore the 
non-volatile registers, before returning, but ours / the native one doesn't do 
that.
    Should fix CORE-19392 and CORE-19397
---
 sdk/lib/crt/crt.cmake           |  1 +
 sdk/lib/crt/wine/msvcrt.h       | 13 ++++++++++++
 sdk/lib/crt/wine/rosglue_i386.s | 47 +++++++++++++++++++++++++++++++++++++++++
 sdk/lib/crt/wine/wine.cmake     |  3 +++
 4 files changed, 64 insertions(+)

diff --git a/sdk/lib/crt/crt.cmake b/sdk/lib/crt/crt.cmake
index 91f9d4a074e..f4868b27080 100644
--- a/sdk/lib/crt/crt.cmake
+++ b/sdk/lib/crt/crt.cmake
@@ -31,6 +31,7 @@ list(APPEND CRT_ASM_SOURCE
     ${CRT_SETJMP_ASM_SOURCE}
     ${CRT_STDLIB_ASM_SOURCE}
     ${CRT_STRING_ASM_SOURCE}
+    ${CRT_WINE_ASM_SOURCE}
 )
 
 set_source_files_properties(${CRT_ASM_SOURCE} PROPERTIES COMPILE_DEFINITIONS 
"__MINGW_IMPORT=extern;USE_MSVCRT_PREFIX;_MSVCRT_LIB_;_MSVCRT_;_MT;CRTDLL")
diff --git a/sdk/lib/crt/wine/msvcrt.h b/sdk/lib/crt/wine/msvcrt.h
index d5dc4cd5366..47199794248 100644
--- a/sdk/lib/crt/wine/msvcrt.h
+++ b/sdk/lib/crt/wine/msvcrt.h
@@ -1489,6 +1489,19 @@ typedef struct {
 #ifdef __REACTOS__
 #define __wine_longjmp longjmp
 #define __wine_jmp_buf _JBTYPE
+
+#ifdef _M_IX86
+// ASM wrapper for Wine code. See rosglue_i386.s for implementation.
+void
+WINAPI
+__wine__RtlUnwind(
+    struct _EXCEPTION_REGISTRATION_RECORD* pEndFrame,
+    PVOID targetIp,
+    struct _EXCEPTION_RECORD* pRecord,
+    PVOID retval);
+#define RtlUnwind __wine__RtlUnwind
+#endif /* _M_IX86 */
+
 #endif
 
 #endif /* __WINE_MSVCRT_H */
diff --git a/sdk/lib/crt/wine/rosglue_i386.s b/sdk/lib/crt/wine/rosglue_i386.s
new file mode 100644
index 00000000000..bc0b9b384fe
--- /dev/null
+++ b/sdk/lib/crt/wine/rosglue_i386.s
@@ -0,0 +1,47 @@
+
+#include <asm.inc>
+
+.code
+
+EXTERN _RtlUnwind@16:PROC
+
+// ASM wrapper for Wine code. This is needed, because Wine code expects
+// RtlUnwind to restore the non-volatile registers, before returning, but
+// ours / the native one does not do that.
+//
+// void
+// WINAPI
+// __wine__RtlUnwind(
+//     PVOID TargetFrame,
+//     PVOID TargetIp ,
+//     PEXCEPTION_RECORD ExceptionRecord ,
+//     PVOID ReturnValue);
+//
+PUBLIC ___wine__RtlUnwind@16
+___wine__RtlUnwind@16:
+
+    push ebp
+    mov ebp, esp
+
+    /* Save non-volatile registers */
+    push ebx
+    push esi
+    push edi
+
+    /* Call the native function */
+    push dword ptr [ebp + 20] // ReturnValue
+    push dword ptr [ebp + 16] // ExceptionRecord
+    push dword ptr [ebp + 12] // TargetIp
+    push dword ptr [ebp + 8]  // TargetFrame
+    call _RtlUnwind@16
+
+    /* Restore non-volatile registers */
+    pop edi
+    pop esi
+    pop ebx
+
+    mov esp, ebp
+    pop ebp
+    ret 16
+
+END
diff --git a/sdk/lib/crt/wine/wine.cmake b/sdk/lib/crt/wine/wine.cmake
index d16da073c31..f279fe8bc72 100644
--- a/sdk/lib/crt/wine/wine.cmake
+++ b/sdk/lib/crt/wine/wine.cmake
@@ -10,6 +10,9 @@ if(ARCH STREQUAL "i386")
     list(APPEND CRT_WINE_SOURCE
         wine/except_i386.c
     )
+    list(APPEND CRT_WINE_ASM_SOURCE
+        wine/rosglue_i386.s
+    )
 elseif(ARCH STREQUAL "amd64")
     list(APPEND CRT_WINE_SOURCE
         wine/except_x86_64.c

Reply via email to