winecrt0: Reimplement __wine_rtl_unwind() as a proper asm function.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
9177a75acc
commit
351bd33069
|
@ -23,38 +23,50 @@
|
||||||
#include "wine/exception.h"
|
#include "wine/exception.h"
|
||||||
#include "wine/asm.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__)
|
#if defined(__GNUC__) && defined(__i386__)
|
||||||
int dummy1, dummy2, dummy3, dummy4;
|
|
||||||
__asm__ __volatile__("pushl %%ebp\n\t"
|
__ASM_GLOBAL_FUNC( __wine_rtl_unwind,
|
||||||
"pushl %%ebx\n\t"
|
"pushl %ebp\n\t"
|
||||||
"pushl $0\n\t"
|
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
|
||||||
"pushl %3\n\t"
|
__ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
|
||||||
"pushl %2\n\t"
|
"movl %esp,%ebp\n\t"
|
||||||
"pushl %1\n\t"
|
__ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
|
||||||
"call *%0\n\t"
|
"subl $8,%esp\n\t"
|
||||||
"popl %%ebx\n\t"
|
"pushl $0\n\t" /* retval */
|
||||||
"popl %%ebp"
|
"pushl 12(%ebp)\n\t" /* record */
|
||||||
: "=a" (dummy1), "=S" (dummy2), "=D" (dummy3), "=c" (dummy4)
|
"pushl 16(%ebp)\n\t" /* target */
|
||||||
: "0" (RtlUnwind), "1" (frame), "2" (target), "3" (record)
|
"pushl 8(%ebp)\n\t" /* frame */
|
||||||
: "edx", "memory" );
|
"call " __ASM_NAME("RtlUnwind") __ASM_STDCALL(16) "\n\t"
|
||||||
#elif defined(__x86_64__)
|
"call *16(%ebp)" )
|
||||||
RtlUnwind( frame, __wine_unwind_trampoline, record, target );
|
|
||||||
|
#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
|
#else
|
||||||
|
|
||||||
|
void __cdecl __wine_rtl_unwind( EXCEPTION_REGISTRATION_RECORD* frame, EXCEPTION_RECORD *record,
|
||||||
|
void (*target)(void) )
|
||||||
|
{
|
||||||
RtlUnwind( frame, target, record, 0 );
|
RtlUnwind( frame, target, record, 0 );
|
||||||
#endif
|
|
||||||
for (;;) target();
|
for (;;) target();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
static void DECLSPEC_NORETURN unwind_target(void)
|
static void DECLSPEC_NORETURN unwind_target(void)
|
||||||
{
|
{
|
||||||
__WINE_FRAME *wine_frame = (__WINE_FRAME *)__wine_get_frame();
|
__WINE_FRAME *wine_frame = (__WINE_FRAME *)__wine_get_frame();
|
||||||
|
|
|
@ -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 ); }
|
static inline void siglongjmp( sigjmp_buf buf, int val ) { longjmp( buf, val ); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern void __wine_rtl_unwind( EXCEPTION_REGISTRATION_RECORD* frame, EXCEPTION_RECORD *record,
|
extern void __cdecl __wine_rtl_unwind( EXCEPTION_REGISTRATION_RECORD* frame, EXCEPTION_RECORD *record,
|
||||||
void (*target)(void) ) DECLSPEC_HIDDEN DECLSPEC_NORETURN;
|
void (*target)(void) ) DECLSPEC_HIDDEN DECLSPEC_NORETURN;
|
||||||
extern DWORD __wine_exception_handler( EXCEPTION_RECORD *record,
|
extern DWORD __wine_exception_handler( EXCEPTION_RECORD *record,
|
||||||
EXCEPTION_REGISTRATION_RECORD *frame,
|
EXCEPTION_REGISTRATION_RECORD *frame,
|
||||||
CONTEXT *context,
|
CONTEXT *context,
|
||||||
|
|
Loading…
Reference in New Issue