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