diff --git a/dlls/msvcrt/Makefile.in b/dlls/msvcrt/Makefile.in index ba8cdbbbba1..99310401f0a 100644 --- a/dlls/msvcrt/Makefile.in +++ b/dlls/msvcrt/Makefile.in @@ -13,6 +13,7 @@ C_SRCS = \ errno.c \ except.c \ except_i386.c \ + except_x86_64.c \ exit.c \ file.c \ heap.c \ diff --git a/dlls/msvcrt/except.c b/dlls/msvcrt/except.c index 0a172c2f67f..80004c91d2d 100644 --- a/dlls/msvcrt/except.c +++ b/dlls/msvcrt/except.c @@ -41,103 +41,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(seh); static MSVCRT_security_error_handler security_error_handler; -#ifdef __x86_64__ - -/******************************************************************* - * _setjmp (MSVCRT.@) - */ -__ASM_GLOBAL_FUNC( MSVCRT__setjmp, - "xorq %rdx,%rdx\n\t" /* frame */ - "jmp " __ASM_NAME("MSVCRT__setjmpex") ); - -/******************************************************************* - * _setjmpex (MSVCRT.@) - */ -__ASM_GLOBAL_FUNC( MSVCRT__setjmpex, - "movq %rdx,(%rcx)\n\t" /* jmp_buf->Frame */ - "movq %rbx,0x8(%rcx)\n\t" /* jmp_buf->Rbx */ - "leaq 0x8(%rsp),%rax\n\t" - "movq %rax,0x10(%rcx)\n\t" /* jmp_buf->Rsp */ - "movq %rbp,0x18(%rcx)\n\t" /* jmp_buf->Rbp */ - "movq %rsi,0x20(%rcx)\n\t" /* jmp_buf->Rsi */ - "movq %rdi,0x28(%rcx)\n\t" /* jmp_buf->Rdi */ - "movq %r12,0x30(%rcx)\n\t" /* jmp_buf->R12 */ - "movq %r13,0x38(%rcx)\n\t" /* jmp_buf->R13 */ - "movq %r14,0x40(%rcx)\n\t" /* jmp_buf->R14 */ - "movq %r15,0x48(%rcx)\n\t" /* jmp_buf->R15 */ - "movq (%rsp),%rax\n\t" - "movq %rax,0x50(%rcx)\n\t" /* jmp_buf->Rip */ - "movdqa %xmm6,0x60(%rcx)\n\t" /* jmp_buf->Xmm6 */ - "movdqa %xmm7,0x70(%rcx)\n\t" /* jmp_buf->Xmm7 */ - "movdqa %xmm8,0x80(%rcx)\n\t" /* jmp_buf->Xmm8 */ - "movdqa %xmm9,0x90(%rcx)\n\t" /* jmp_buf->Xmm9 */ - "movdqa %xmm10,0xa0(%rcx)\n\t" /* jmp_buf->Xmm10 */ - "movdqa %xmm11,0xb0(%rcx)\n\t" /* jmp_buf->Xmm11 */ - "movdqa %xmm12,0xc0(%rcx)\n\t" /* jmp_buf->Xmm12 */ - "movdqa %xmm13,0xd0(%rcx)\n\t" /* jmp_buf->Xmm13 */ - "movdqa %xmm14,0xe0(%rcx)\n\t" /* jmp_buf->Xmm14 */ - "movdqa %xmm15,0xf0(%rcx)\n\t" /* jmp_buf->Xmm15 */ - "xorq %rax,%rax\n\t" - "retq" ); - - -extern void DECLSPEC_NORETURN CDECL longjmp_set_regs( struct MSVCRT___JUMP_BUFFER *jmp, int retval ); -__ASM_GLOBAL_FUNC( longjmp_set_regs, - "movq %rdx,%rax\n\t" /* retval */ - "movq 0x8(%rcx),%rbx\n\t" /* jmp_buf->Rbx */ - "movq 0x18(%rcx),%rbp\n\t" /* jmp_buf->Rbp */ - "movq 0x20(%rcx),%rsi\n\t" /* jmp_buf->Rsi */ - "movq 0x28(%rcx),%rdi\n\t" /* jmp_buf->Rdi */ - "movq 0x30(%rcx),%r12\n\t" /* jmp_buf->R12 */ - "movq 0x38(%rcx),%r13\n\t" /* jmp_buf->R13 */ - "movq 0x40(%rcx),%r14\n\t" /* jmp_buf->R14 */ - "movq 0x48(%rcx),%r15\n\t" /* jmp_buf->R15 */ - "movdqa 0x60(%rcx),%xmm6\n\t" /* jmp_buf->Xmm6 */ - "movdqa 0x70(%rcx),%xmm7\n\t" /* jmp_buf->Xmm7 */ - "movdqa 0x80(%rcx),%xmm8\n\t" /* jmp_buf->Xmm8 */ - "movdqa 0x90(%rcx),%xmm9\n\t" /* jmp_buf->Xmm9 */ - "movdqa 0xa0(%rcx),%xmm10\n\t" /* jmp_buf->Xmm10 */ - "movdqa 0xb0(%rcx),%xmm11\n\t" /* jmp_buf->Xmm11 */ - "movdqa 0xc0(%rcx),%xmm12\n\t" /* jmp_buf->Xmm12 */ - "movdqa 0xd0(%rcx),%xmm13\n\t" /* jmp_buf->Xmm13 */ - "movdqa 0xe0(%rcx),%xmm14\n\t" /* jmp_buf->Xmm14 */ - "movdqa 0xf0(%rcx),%xmm15\n\t" /* jmp_buf->Xmm15 */ - "movq 0x50(%rcx),%rdx\n\t" /* jmp_buf->Rip */ - "movq 0x10(%rcx),%rsp\n\t" /* jmp_buf->Rsp */ - "jmp *%rdx" ); - -/******************************************************************* - * longjmp (MSVCRT.@) - */ -void __cdecl MSVCRT_longjmp( struct MSVCRT___JUMP_BUFFER *jmp, int retval ) -{ - EXCEPTION_RECORD rec; - - if (!retval) retval = 1; - if (jmp->Frame) - { - rec.ExceptionCode = STATUS_LONGJUMP; - rec.ExceptionFlags = 0; - rec.ExceptionRecord = NULL; - rec.ExceptionAddress = NULL; - rec.NumberParameters = 1; - rec.ExceptionInformation[0] = (DWORD_PTR)jmp; - RtlUnwind( (void *)jmp->Frame, (void *)jmp->Rip, &rec, IntToPtr(retval) ); - } - longjmp_set_regs( jmp, retval ); -} - -/******************************************************************* - * _local_unwind (MSVCRT.@) - */ -void __cdecl _local_unwind( void *frame, void *target ) -{ - CONTEXT context; - RtlUnwindEx( frame, target, NULL, 0, &context, NULL ); -} - -#endif /* __x86_64__ */ - static MSVCRT___sighandler_t sighandlers[MSVCRT_NSIG] = { MSVCRT_SIG_DFL }; static BOOL WINAPI msvcrt_console_handler(DWORD ctrlType) diff --git a/dlls/msvcrt/except_x86_64.c b/dlls/msvcrt/except_x86_64.c new file mode 100644 index 00000000000..dc09726d3df --- /dev/null +++ b/dlls/msvcrt/except_x86_64.c @@ -0,0 +1,135 @@ +/* + * msvcrt C++ exception handling + * + * Copyright 2011 Alexandre Julliard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include "wine/port.h" + +#ifdef __x86_64__ + +#include + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "winternl.h" +#include "msvcrt.h" +#include "wine/exception.h" +#include "excpt.h" +#include "wine/debug.h" + +#include "cppexcept.h" + +WINE_DEFAULT_DEBUG_CHANNEL(seh); + + +/******************************************************************* + * _setjmp (MSVCRT.@) + */ +__ASM_GLOBAL_FUNC( MSVCRT__setjmp, + "xorq %rdx,%rdx\n\t" /* frame */ + "jmp " __ASM_NAME("MSVCRT__setjmpex") ); + +/******************************************************************* + * _setjmpex (MSVCRT.@) + */ +__ASM_GLOBAL_FUNC( MSVCRT__setjmpex, + "movq %rdx,(%rcx)\n\t" /* jmp_buf->Frame */ + "movq %rbx,0x8(%rcx)\n\t" /* jmp_buf->Rbx */ + "leaq 0x8(%rsp),%rax\n\t" + "movq %rax,0x10(%rcx)\n\t" /* jmp_buf->Rsp */ + "movq %rbp,0x18(%rcx)\n\t" /* jmp_buf->Rbp */ + "movq %rsi,0x20(%rcx)\n\t" /* jmp_buf->Rsi */ + "movq %rdi,0x28(%rcx)\n\t" /* jmp_buf->Rdi */ + "movq %r12,0x30(%rcx)\n\t" /* jmp_buf->R12 */ + "movq %r13,0x38(%rcx)\n\t" /* jmp_buf->R13 */ + "movq %r14,0x40(%rcx)\n\t" /* jmp_buf->R14 */ + "movq %r15,0x48(%rcx)\n\t" /* jmp_buf->R15 */ + "movq (%rsp),%rax\n\t" + "movq %rax,0x50(%rcx)\n\t" /* jmp_buf->Rip */ + "movdqa %xmm6,0x60(%rcx)\n\t" /* jmp_buf->Xmm6 */ + "movdqa %xmm7,0x70(%rcx)\n\t" /* jmp_buf->Xmm7 */ + "movdqa %xmm8,0x80(%rcx)\n\t" /* jmp_buf->Xmm8 */ + "movdqa %xmm9,0x90(%rcx)\n\t" /* jmp_buf->Xmm9 */ + "movdqa %xmm10,0xa0(%rcx)\n\t" /* jmp_buf->Xmm10 */ + "movdqa %xmm11,0xb0(%rcx)\n\t" /* jmp_buf->Xmm11 */ + "movdqa %xmm12,0xc0(%rcx)\n\t" /* jmp_buf->Xmm12 */ + "movdqa %xmm13,0xd0(%rcx)\n\t" /* jmp_buf->Xmm13 */ + "movdqa %xmm14,0xe0(%rcx)\n\t" /* jmp_buf->Xmm14 */ + "movdqa %xmm15,0xf0(%rcx)\n\t" /* jmp_buf->Xmm15 */ + "xorq %rax,%rax\n\t" + "retq" ); + + +extern void DECLSPEC_NORETURN CDECL longjmp_set_regs( struct MSVCRT___JUMP_BUFFER *jmp, int retval ); +__ASM_GLOBAL_FUNC( longjmp_set_regs, + "movq %rdx,%rax\n\t" /* retval */ + "movq 0x8(%rcx),%rbx\n\t" /* jmp_buf->Rbx */ + "movq 0x18(%rcx),%rbp\n\t" /* jmp_buf->Rbp */ + "movq 0x20(%rcx),%rsi\n\t" /* jmp_buf->Rsi */ + "movq 0x28(%rcx),%rdi\n\t" /* jmp_buf->Rdi */ + "movq 0x30(%rcx),%r12\n\t" /* jmp_buf->R12 */ + "movq 0x38(%rcx),%r13\n\t" /* jmp_buf->R13 */ + "movq 0x40(%rcx),%r14\n\t" /* jmp_buf->R14 */ + "movq 0x48(%rcx),%r15\n\t" /* jmp_buf->R15 */ + "movdqa 0x60(%rcx),%xmm6\n\t" /* jmp_buf->Xmm6 */ + "movdqa 0x70(%rcx),%xmm7\n\t" /* jmp_buf->Xmm7 */ + "movdqa 0x80(%rcx),%xmm8\n\t" /* jmp_buf->Xmm8 */ + "movdqa 0x90(%rcx),%xmm9\n\t" /* jmp_buf->Xmm9 */ + "movdqa 0xa0(%rcx),%xmm10\n\t" /* jmp_buf->Xmm10 */ + "movdqa 0xb0(%rcx),%xmm11\n\t" /* jmp_buf->Xmm11 */ + "movdqa 0xc0(%rcx),%xmm12\n\t" /* jmp_buf->Xmm12 */ + "movdqa 0xd0(%rcx),%xmm13\n\t" /* jmp_buf->Xmm13 */ + "movdqa 0xe0(%rcx),%xmm14\n\t" /* jmp_buf->Xmm14 */ + "movdqa 0xf0(%rcx),%xmm15\n\t" /* jmp_buf->Xmm15 */ + "movq 0x50(%rcx),%rdx\n\t" /* jmp_buf->Rip */ + "movq 0x10(%rcx),%rsp\n\t" /* jmp_buf->Rsp */ + "jmp *%rdx" ); + +/******************************************************************* + * longjmp (MSVCRT.@) + */ +void __cdecl MSVCRT_longjmp( struct MSVCRT___JUMP_BUFFER *jmp, int retval ) +{ + EXCEPTION_RECORD rec; + + if (!retval) retval = 1; + if (jmp->Frame) + { + rec.ExceptionCode = STATUS_LONGJUMP; + rec.ExceptionFlags = 0; + rec.ExceptionRecord = NULL; + rec.ExceptionAddress = NULL; + rec.NumberParameters = 1; + rec.ExceptionInformation[0] = (DWORD_PTR)jmp; + RtlUnwind( (void *)jmp->Frame, (void *)jmp->Rip, &rec, IntToPtr(retval) ); + } + longjmp_set_regs( jmp, retval ); +} + +/******************************************************************* + * _local_unwind (MSVCRT.@) + */ +void __cdecl _local_unwind( void *frame, void *target ) +{ + RtlUnwind( frame, target, NULL, 0 ); +} + +#endif /* __x86_64__ */