Module: wine Branch: master Commit: 351bd3306914066dc8c9219353eeef585bb3bf41 URL: https://source.winehq.org/git/wine.git/?a=commit;h=351bd3306914066dc8c921935...
Author: Alexandre Julliard julliard@winehq.org Date: Tue May 14 13:27:38 2019 +0200
winecrt0: Reimplement __wine_rtl_unwind() as a proper asm function.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/winecrt0/exception.c | 64 ++++++++++++++++++++++++++++------------------- include/wine/exception.h | 4 +-- 2 files changed, 40 insertions(+), 28 deletions(-)
diff --git a/dlls/winecrt0/exception.c b/dlls/winecrt0/exception.c index 98132fa..d141d28 100644 --- a/dlls/winecrt0/exception.c +++ b/dlls/winecrt0/exception.c @@ -23,38 +23,50 @@ #include "wine/exception.h" #include "wine/asm.h"
-#ifdef __x86_64__ -extern void __wine_unwind_trampoline(void); -/* we need an extra call to make sure the stack is correctly aligned */ -__ASM_GLOBAL_FUNC( __wine_unwind_trampoline, "callq *%rax" ); -#endif - -/* wrapper for RtlUnwind since it clobbers registers on Windows */ -void __wine_rtl_unwind( EXCEPTION_REGISTRATION_RECORD* frame, EXCEPTION_RECORD *record, - void (*target)(void) ) -{ #if defined(__GNUC__) && defined(__i386__) - int dummy1, dummy2, dummy3, dummy4; - __asm__ __volatile__("pushl %%ebp\n\t" - "pushl %%ebx\n\t" - "pushl $0\n\t" - "pushl %3\n\t" - "pushl %2\n\t" - "pushl %1\n\t" - "call *%0\n\t" - "popl %%ebx\n\t" - "popl %%ebp" - : "=a" (dummy1), "=S" (dummy2), "=D" (dummy3), "=c" (dummy4) - : "0" (RtlUnwind), "1" (frame), "2" (target), "3" (record) - : "edx", "memory" ); -#elif defined(__x86_64__) - RtlUnwind( frame, __wine_unwind_trampoline, record, target ); + +__ASM_GLOBAL_FUNC( __wine_rtl_unwind, + "pushl %ebp\n\t" + __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") + __ASM_CFI(".cfi_rel_offset %ebp,0\n\t") + "movl %esp,%ebp\n\t" + __ASM_CFI(".cfi_def_cfa_register %ebp\n\t") + "subl $8,%esp\n\t" + "pushl $0\n\t" /* retval */ + "pushl 12(%ebp)\n\t" /* record */ + "pushl 16(%ebp)\n\t" /* target */ + "pushl 8(%ebp)\n\t" /* frame */ + "call " __ASM_NAME("RtlUnwind") __ASM_STDCALL(16) "\n\t" + "call *16(%ebp)" ) + +#elif defined(__GNUC__) && defined(__x86_64__) + +__ASM_GLOBAL_FUNC( __wine_rtl_unwind, + "pushq %rbp\n\t" + __ASM_CFI(".cfi_adjust_cfa_offset 8\n\t") + __ASM_CFI(".cfi_rel_offset %rbp,0\n\t") + "movq %rsp,%rbp\n\t" + __ASM_CFI(".cfi_def_cfa_register %rbp\n\t") + "subq $0x20,%rsp\n\t" + "movq %r8,%r9\n\t" /* retval = final target */ + "movq %rdx,%r8\n\t" /* record */ + "leaq __wine_unwind_trampoline(%rip),%rdx\n\t" /* target = trampoline */ + "call " __ASM_NAME("RtlUnwind") "\n" + "__wine_unwind_trampoline:\n\t" + /* we need an extra call to make sure the stack is correctly aligned */ + "callq *%rax" ) + #else + +void __cdecl __wine_rtl_unwind( EXCEPTION_REGISTRATION_RECORD* frame, EXCEPTION_RECORD *record, + void (*target)(void) ) +{ RtlUnwind( frame, target, record, 0 ); -#endif for (;;) target(); }
+#endif + static void DECLSPEC_NORETURN unwind_target(void) { __WINE_FRAME *wine_frame = (__WINE_FRAME *)__wine_get_frame(); diff --git a/include/wine/exception.h b/include/wine/exception.h index f30807e..f4e9166 100644 --- a/include/wine/exception.h +++ b/include/wine/exception.h @@ -98,8 +98,8 @@ static inline int sigsetjmp( sigjmp_buf buf, int sigs ) { return setjmp( buf ); static inline void siglongjmp( sigjmp_buf buf, int val ) { longjmp( buf, val ); } #endif
-extern void __wine_rtl_unwind( EXCEPTION_REGISTRATION_RECORD* frame, EXCEPTION_RECORD *record, - void (*target)(void) ) DECLSPEC_HIDDEN DECLSPEC_NORETURN; +extern void __cdecl __wine_rtl_unwind( EXCEPTION_REGISTRATION_RECORD* frame, EXCEPTION_RECORD *record, + void (*target)(void) ) DECLSPEC_HIDDEN DECLSPEC_NORETURN; extern DWORD __wine_exception_handler( EXCEPTION_RECORD *record, EXCEPTION_REGISTRATION_RECORD *frame, CONTEXT *context,