https://git.reactos.org/?p=reactos.git;a=commitdiff;h=92db51883abd474f3c3fe…
commit 92db51883abd474f3c3fe3d788a4b5e4201f8515
Author: Timo Kreuzer <timo.kreuzer(a)reactos.org>
AuthorDate: Mon Jan 8 21:55:15 2024 +0200
Commit: Timo Kreuzer <timo.kreuzer(a)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