mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-06 02:28:19 +00:00
include: Move the exception handling support functions to winecrt0 instead of having them inline.
This commit is contained in:
parent
5d2b8e77d2
commit
655292ae00
|
@ -9,6 +9,7 @@ C_SRCS = \
|
|||
dll_entry.c \
|
||||
dll_main.c \
|
||||
drv_entry.c \
|
||||
exception.c \
|
||||
exe16_entry.c \
|
||||
exe_entry.c \
|
||||
exe_main.c \
|
||||
|
|
127
dlls/winecrt0/exception.c
Normal file
127
dlls/winecrt0/exception.c
Normal file
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* Support functions for Wine exception handling
|
||||
*
|
||||
* Copyright (c) 1999, 2010 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 <stdarg.h>
|
||||
#include "winternl.h"
|
||||
#include "wine/exception.h"
|
||||
|
||||
/* 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" );
|
||||
#else
|
||||
RtlUnwind( frame, target, record, 0 );
|
||||
#endif
|
||||
for (;;) target();
|
||||
}
|
||||
|
||||
static void DECLSPEC_NORETURN unwind_target(void)
|
||||
{
|
||||
__WINE_FRAME *wine_frame = (__WINE_FRAME *)__wine_get_frame();
|
||||
__wine_pop_frame( &wine_frame->frame );
|
||||
siglongjmp( wine_frame->jmp, 1 );
|
||||
}
|
||||
|
||||
static void DECLSPEC_NORETURN unwind_frame( EXCEPTION_RECORD *record,
|
||||
EXCEPTION_REGISTRATION_RECORD *frame )
|
||||
{
|
||||
__WINE_FRAME *wine_frame = (__WINE_FRAME *)frame;
|
||||
|
||||
/* hack to make GetExceptionCode() work in handler */
|
||||
wine_frame->ExceptionCode = record->ExceptionCode;
|
||||
wine_frame->ExceptionRecord = wine_frame;
|
||||
|
||||
__wine_rtl_unwind( frame, record, unwind_target );
|
||||
}
|
||||
|
||||
DWORD __wine_exception_handler( EXCEPTION_RECORD *record,
|
||||
EXCEPTION_REGISTRATION_RECORD *frame,
|
||||
CONTEXT *context,
|
||||
EXCEPTION_REGISTRATION_RECORD **pdispatcher )
|
||||
{
|
||||
__WINE_FRAME *wine_frame = (__WINE_FRAME *)frame;
|
||||
EXCEPTION_POINTERS ptrs;
|
||||
|
||||
if (record->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND | EH_NESTED_CALL))
|
||||
return ExceptionContinueSearch;
|
||||
|
||||
ptrs.ExceptionRecord = record;
|
||||
ptrs.ContextRecord = context;
|
||||
switch(wine_frame->u.filter( &ptrs ))
|
||||
{
|
||||
case EXCEPTION_CONTINUE_SEARCH:
|
||||
return ExceptionContinueSearch;
|
||||
case EXCEPTION_CONTINUE_EXECUTION:
|
||||
return ExceptionContinueExecution;
|
||||
case EXCEPTION_EXECUTE_HANDLER:
|
||||
break;
|
||||
}
|
||||
unwind_frame( record, frame );
|
||||
}
|
||||
|
||||
DWORD __wine_exception_handler_page_fault( EXCEPTION_RECORD *record,
|
||||
EXCEPTION_REGISTRATION_RECORD *frame,
|
||||
CONTEXT *context,
|
||||
EXCEPTION_REGISTRATION_RECORD **pdispatcher )
|
||||
{
|
||||
if (record->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND | EH_NESTED_CALL))
|
||||
return ExceptionContinueSearch;
|
||||
if (record->ExceptionCode != STATUS_ACCESS_VIOLATION)
|
||||
return ExceptionContinueSearch;
|
||||
unwind_frame( record, frame );
|
||||
}
|
||||
|
||||
DWORD __wine_exception_handler_all( EXCEPTION_RECORD *record,
|
||||
EXCEPTION_REGISTRATION_RECORD *frame,
|
||||
CONTEXT *context,
|
||||
EXCEPTION_REGISTRATION_RECORD **pdispatcher )
|
||||
{
|
||||
if (record->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND | EH_NESTED_CALL))
|
||||
return ExceptionContinueSearch;
|
||||
unwind_frame( record, frame );
|
||||
}
|
||||
|
||||
DWORD __wine_finally_handler( EXCEPTION_RECORD *record,
|
||||
EXCEPTION_REGISTRATION_RECORD *frame,
|
||||
CONTEXT *context,
|
||||
EXCEPTION_REGISTRATION_RECORD **pdispatcher )
|
||||
{
|
||||
if (record->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND))
|
||||
{
|
||||
__WINE_FRAME *wine_frame = (__WINE_FRAME *)frame;
|
||||
wine_frame->u.finally_func( FALSE );
|
||||
}
|
||||
return ExceptionContinueSearch;
|
||||
}
|
|
@ -94,6 +94,25 @@ extern "C" {
|
|||
#define siglongjmp(buf,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 DWORD __wine_exception_handler( EXCEPTION_RECORD *record,
|
||||
EXCEPTION_REGISTRATION_RECORD *frame,
|
||||
CONTEXT *context,
|
||||
EXCEPTION_REGISTRATION_RECORD **pdispatcher ) DECLSPEC_HIDDEN;
|
||||
extern DWORD __wine_exception_handler_page_fault( EXCEPTION_RECORD *record,
|
||||
EXCEPTION_REGISTRATION_RECORD *frame,
|
||||
CONTEXT *context,
|
||||
EXCEPTION_REGISTRATION_RECORD **pdispatcher ) DECLSPEC_HIDDEN;
|
||||
extern DWORD __wine_exception_handler_all( EXCEPTION_RECORD *record,
|
||||
EXCEPTION_REGISTRATION_RECORD *frame,
|
||||
CONTEXT *context,
|
||||
EXCEPTION_REGISTRATION_RECORD **pdispatcher ) DECLSPEC_HIDDEN;
|
||||
extern DWORD __wine_finally_handler( EXCEPTION_RECORD *record,
|
||||
EXCEPTION_REGISTRATION_RECORD *frame,
|
||||
CONTEXT *context,
|
||||
EXCEPTION_REGISTRATION_RECORD **pdispatcher ) DECLSPEC_HIDDEN;
|
||||
|
||||
#define __TRY \
|
||||
do { __WINE_FRAME __f; \
|
||||
int __first = 1; \
|
||||
|
@ -246,116 +265,6 @@ static inline EXCEPTION_REGISTRATION_RECORD *__wine_get_frame(void)
|
|||
|
||||
extern void __wine_enter_vm86( CONTEXT *context );
|
||||
|
||||
#ifndef USE_COMPILER_EXCEPTIONS
|
||||
|
||||
NTSYSAPI void WINAPI RtlUnwind(PVOID,PVOID,PEXCEPTION_RECORD,PVOID);
|
||||
|
||||
static inline void DECLSPEC_NORETURN __wine_unwind_target(void)
|
||||
{
|
||||
__WINE_FRAME *wine_frame = (__WINE_FRAME *)__wine_get_frame();
|
||||
__wine_pop_frame( &wine_frame->frame );
|
||||
siglongjmp( wine_frame->jmp, 1 );
|
||||
}
|
||||
|
||||
/* wrapper for RtlUnwind since it clobbers registers on Windows */
|
||||
static inline void DECLSPEC_NORETURN __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" );
|
||||
#else
|
||||
RtlUnwind( frame, target, record, 0 );
|
||||
#endif
|
||||
for (;;) target();
|
||||
}
|
||||
|
||||
static inline void DECLSPEC_NORETURN __wine_unwind_frame( EXCEPTION_RECORD *record,
|
||||
EXCEPTION_REGISTRATION_RECORD *frame )
|
||||
{
|
||||
__WINE_FRAME *wine_frame = (__WINE_FRAME *)frame;
|
||||
|
||||
/* hack to make GetExceptionCode() work in handler */
|
||||
wine_frame->ExceptionCode = record->ExceptionCode;
|
||||
wine_frame->ExceptionRecord = wine_frame;
|
||||
|
||||
__wine_rtl_unwind( frame, record, __wine_unwind_target );
|
||||
}
|
||||
|
||||
static inline DWORD __wine_exception_handler( EXCEPTION_RECORD *record,
|
||||
EXCEPTION_REGISTRATION_RECORD *frame,
|
||||
CONTEXT *context,
|
||||
EXCEPTION_REGISTRATION_RECORD **pdispatcher )
|
||||
{
|
||||
__WINE_FRAME *wine_frame = (__WINE_FRAME *)frame;
|
||||
EXCEPTION_POINTERS ptrs;
|
||||
|
||||
if (record->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND | EH_NESTED_CALL))
|
||||
return ExceptionContinueSearch;
|
||||
|
||||
ptrs.ExceptionRecord = record;
|
||||
ptrs.ContextRecord = context;
|
||||
switch(wine_frame->u.filter( &ptrs ))
|
||||
{
|
||||
case EXCEPTION_CONTINUE_SEARCH:
|
||||
return ExceptionContinueSearch;
|
||||
case EXCEPTION_CONTINUE_EXECUTION:
|
||||
return ExceptionContinueExecution;
|
||||
case EXCEPTION_EXECUTE_HANDLER:
|
||||
break;
|
||||
}
|
||||
__wine_unwind_frame( record, frame );
|
||||
}
|
||||
|
||||
static inline DWORD __wine_exception_handler_page_fault( EXCEPTION_RECORD *record,
|
||||
EXCEPTION_REGISTRATION_RECORD *frame,
|
||||
CONTEXT *context,
|
||||
EXCEPTION_REGISTRATION_RECORD **pdispatcher )
|
||||
{
|
||||
if (record->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND | EH_NESTED_CALL))
|
||||
return ExceptionContinueSearch;
|
||||
if (record->ExceptionCode != STATUS_ACCESS_VIOLATION)
|
||||
return ExceptionContinueSearch;
|
||||
__wine_unwind_frame( record, frame );
|
||||
}
|
||||
|
||||
static inline DWORD __wine_exception_handler_all( EXCEPTION_RECORD *record,
|
||||
EXCEPTION_REGISTRATION_RECORD *frame,
|
||||
CONTEXT *context,
|
||||
EXCEPTION_REGISTRATION_RECORD **pdispatcher )
|
||||
{
|
||||
if (record->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND | EH_NESTED_CALL))
|
||||
return ExceptionContinueSearch;
|
||||
__wine_unwind_frame( record, frame );
|
||||
}
|
||||
|
||||
static inline DWORD __wine_finally_handler( EXCEPTION_RECORD *record,
|
||||
EXCEPTION_REGISTRATION_RECORD *frame,
|
||||
CONTEXT *context,
|
||||
EXCEPTION_REGISTRATION_RECORD **pdispatcher )
|
||||
{
|
||||
if (record->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND))
|
||||
{
|
||||
__WINE_FRAME *wine_frame = (__WINE_FRAME *)frame;
|
||||
wine_frame->u.finally_func( FALSE );
|
||||
}
|
||||
return ExceptionContinueSearch;
|
||||
}
|
||||
|
||||
#endif /* USE_COMPILER_EXCEPTIONS */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue