Alexandre Julliard : winecrt0: Reimplement __wine_rtl_unwind() as a proper asm function.

Alexandre Julliard julliard at winehq.org
Tue May 14 15:43:01 CDT 2019


Module: wine
Branch: master
Commit: 351bd3306914066dc8c9219353eeef585bb3bf41
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=351bd3306914066dc8c9219353eeef585bb3bf41

Author: Alexandre Julliard <julliard at 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 at 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,




More information about the wine-cvs mailing list