[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
This commit is contained in:
Timo Kreuzer 2024-01-08 21:55:15 +02:00
parent d52b70a73e
commit 92db51883a
4 changed files with 64 additions and 0 deletions

View file

@ -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")

View file

@ -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 */

View file

@ -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

View file

@ -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