Commit 5807b5e5 authored by Alexandre Julliard's avatar Alexandre Julliard

msvcrt: Add support for VC7 and VC8 extensions to the C++ exception handler.

parent 30097828
...@@ -118,8 +118,8 @@ ...@@ -118,8 +118,8 @@
@ cdecl __CxxDetectRethrow(ptr) msvcrt.__CxxDetectRethrow @ cdecl __CxxDetectRethrow(ptr) msvcrt.__CxxDetectRethrow
@ stub __CxxExceptionFilter @ stub __CxxExceptionFilter
@ cdecl -i386 -norelay __CxxFrameHandler(ptr ptr ptr ptr) msvcrt.__CxxFrameHandler @ cdecl -i386 -norelay __CxxFrameHandler(ptr ptr ptr ptr) msvcrt.__CxxFrameHandler
@ stub __CxxFrameHandler2 @ cdecl -i386 -norelay __CxxFrameHandler2(ptr ptr ptr ptr) msvcrt.__CxxFrameHandler
@ stub __CxxFrameHandler3 @ cdecl -i386 -norelay __CxxFrameHandler3(ptr ptr ptr ptr) msvcrt.__CxxFrameHandler
@ stdcall -i386 __CxxLongjmpUnwind(ptr) msvcrt.__CxxLongjmpUnwind @ stdcall -i386 __CxxLongjmpUnwind(ptr) msvcrt.__CxxLongjmpUnwind
@ cdecl __CxxQueryExceptionSize() msvcrt.__CxxQueryExceptionSize @ cdecl __CxxQueryExceptionSize() msvcrt.__CxxQueryExceptionSize
@ stub __CxxRegisterExceptionObject @ stub __CxxRegisterExceptionObject
......
...@@ -115,8 +115,8 @@ ...@@ -115,8 +115,8 @@
@ cdecl __CxxDetectRethrow(ptr) msvcrt.__CxxDetectRethrow @ cdecl __CxxDetectRethrow(ptr) msvcrt.__CxxDetectRethrow
@ stub __CxxExceptionFilter @ stub __CxxExceptionFilter
@ cdecl -i386 -norelay __CxxFrameHandler(ptr ptr ptr ptr) msvcrt.__CxxFrameHandler @ cdecl -i386 -norelay __CxxFrameHandler(ptr ptr ptr ptr) msvcrt.__CxxFrameHandler
@ stub __CxxFrameHandler2 @ cdecl -i386 -norelay __CxxFrameHandler2(ptr ptr ptr ptr) msvcrt.__CxxFrameHandler
@ stub __CxxFrameHandler3 @ cdecl -i386 -norelay __CxxFrameHandler3(ptr ptr ptr ptr) msvcrt.__CxxFrameHandler
@ stdcall -i386 __CxxLongjmpUnwind(ptr) msvcrt.__CxxLongjmpUnwind @ stdcall -i386 __CxxLongjmpUnwind(ptr) msvcrt.__CxxLongjmpUnwind
@ cdecl __CxxQueryExceptionSize() msvcrt.__CxxQueryExceptionSize @ cdecl __CxxQueryExceptionSize() msvcrt.__CxxQueryExceptionSize
@ stub __CxxRegisterExceptionObject @ stub __CxxRegisterExceptionObject
......
...@@ -138,6 +138,10 @@ static void dump_function_descr( const cxx_function_descr *descr ) ...@@ -138,6 +138,10 @@ static void dump_function_descr( const cxx_function_descr *descr )
ptr->type_info, dbgstr_type_info( ptr->type_info ) ); ptr->type_info, dbgstr_type_info( ptr->type_info ) );
} }
} }
if (descr->magic <= CXX_FRAME_MAGIC_VC6) return;
TRACE( "expect list: %p\n", descr->expect_list );
if (descr->magic <= CXX_FRAME_MAGIC_VC7) return;
TRACE( "flags: %08x\n", descr->flags );
} }
/* check if the exception type is caught by a given catch block, and return the type that matched */ /* check if the exception type is caught by a given catch block, and return the type that matched */
...@@ -363,11 +367,16 @@ DWORD CDECL cxx_frame_handler( PEXCEPTION_RECORD rec, cxx_exception_frame* frame ...@@ -363,11 +367,16 @@ DWORD CDECL cxx_frame_handler( PEXCEPTION_RECORD rec, cxx_exception_frame* frame
{ {
cxx_exception_type *exc_type; cxx_exception_type *exc_type;
if (descr->magic != CXX_FRAME_MAGIC) if (descr->magic < CXX_FRAME_MAGIC_VC6 || descr->magic > CXX_FRAME_MAGIC_VC8)
{ {
ERR( "invalid frame magic %x\n", descr->magic ); ERR( "invalid frame magic %x\n", descr->magic );
return ExceptionContinueSearch; return ExceptionContinueSearch;
} }
if (descr->magic >= CXX_FRAME_MAGIC_VC8 &&
(descr->flags & FUNC_DESCR_SYNCHRONOUS) &&
(rec->ExceptionCode != CXX_EXCEPTION))
return ExceptionContinueSearch; /* handle only c++ exceptions */
if (rec->ExceptionFlags & (EH_UNWINDING|EH_EXIT_UNWIND)) if (rec->ExceptionFlags & (EH_UNWINDING|EH_EXIT_UNWIND))
{ {
if (descr->unwind_count && !nested_trylevel) cxx_local_unwind( frame, descr, -1 ); if (descr->unwind_count && !nested_trylevel) cxx_local_unwind( frame, descr, -1 );
...@@ -379,7 +388,7 @@ DWORD CDECL cxx_frame_handler( PEXCEPTION_RECORD rec, cxx_exception_frame* frame ...@@ -379,7 +388,7 @@ DWORD CDECL cxx_frame_handler( PEXCEPTION_RECORD rec, cxx_exception_frame* frame
{ {
exc_type = (cxx_exception_type *)rec->ExceptionInformation[2]; exc_type = (cxx_exception_type *)rec->ExceptionInformation[2];
if (rec->ExceptionInformation[0] > CXX_FRAME_MAGIC && if (rec->ExceptionInformation[0] > CXX_FRAME_MAGIC_VC8 &&
exc_type->custom_handler) exc_type->custom_handler)
{ {
return exc_type->custom_handler( rec, frame, context, dispatch, return exc_type->custom_handler( rec, frame, context, dispatch,
...@@ -466,7 +475,7 @@ void CDECL _CxxThrowException( exception *object, const cxx_exception_type *type ...@@ -466,7 +475,7 @@ void CDECL _CxxThrowException( exception *object, const cxx_exception_type *type
{ {
ULONG_PTR args[3]; ULONG_PTR args[3];
args[0] = CXX_FRAME_MAGIC; args[0] = CXX_FRAME_MAGIC_VC6;
args[1] = (ULONG_PTR)object; args[1] = (ULONG_PTR)object;
args[2] = (ULONG_PTR)type; args[2] = (ULONG_PTR)type;
RaiseException( CXX_EXCEPTION, EH_NONCONTINUABLE, 3, args ); RaiseException( CXX_EXCEPTION, EH_NONCONTINUABLE, 3, args );
...@@ -486,7 +495,7 @@ BOOL CDECL __CxxDetectRethrow(PEXCEPTION_POINTERS ptrs) ...@@ -486,7 +495,7 @@ BOOL CDECL __CxxDetectRethrow(PEXCEPTION_POINTERS ptrs)
if (rec->ExceptionCode == CXX_EXCEPTION && if (rec->ExceptionCode == CXX_EXCEPTION &&
rec->NumberParameters == 3 && rec->NumberParameters == 3 &&
rec->ExceptionInformation[0] == CXX_FRAME_MAGIC && rec->ExceptionInformation[0] == CXX_FRAME_MAGIC_VC6 &&
rec->ExceptionInformation[2]) rec->ExceptionInformation[2])
{ {
ptrs->ExceptionRecord = msvcrt_get_thread_data()->exc_record; ptrs->ExceptionRecord = msvcrt_get_thread_data()->exc_record;
......
...@@ -21,8 +21,10 @@ ...@@ -21,8 +21,10 @@
#ifndef __MSVCRT_CPPEXCEPT_H #ifndef __MSVCRT_CPPEXCEPT_H
#define __MSVCRT_CPPEXCEPT_H #define __MSVCRT_CPPEXCEPT_H
#define CXX_FRAME_MAGIC 0x19930520 #define CXX_FRAME_MAGIC_VC6 0x19930520
#define CXX_EXCEPTION 0xe06d7363 #define CXX_FRAME_MAGIC_VC7 0x19930521
#define CXX_FRAME_MAGIC_VC8 0x19930522
#define CXX_EXCEPTION 0xe06d7363
typedef void (*vtable_ptr)(void); typedef void (*vtable_ptr)(void);
...@@ -87,9 +89,14 @@ typedef struct __cxx_function_descr ...@@ -87,9 +89,14 @@ typedef struct __cxx_function_descr
const unwind_info *unwind_table; /* array of unwind handlers */ const unwind_info *unwind_table; /* array of unwind handlers */
UINT tryblock_count; /* number of try blocks */ UINT tryblock_count; /* number of try blocks */
const tryblock_info *tryblock; /* array of try blocks */ const tryblock_info *tryblock; /* array of try blocks */
UINT unknown[3]; UINT ipmap_count;
const void *ipmap;
const void *expect_list; /* expected exceptions list when magic >= VC7 */
UINT flags; /* flags when magic >= VC8 */
} cxx_function_descr; } cxx_function_descr;
#define FUNC_DESCR_SYNCHRONOUS 1 /* synchronous exceptions only (built with /EHs) */
typedef void (*cxx_copy_ctor)(void); typedef void (*cxx_copy_ctor)(void);
/* offsets for computing the this pointer */ /* offsets for computing the this pointer */
......
...@@ -114,8 +114,8 @@ ...@@ -114,8 +114,8 @@
@ cdecl __CxxDetectRethrow(ptr) @ cdecl __CxxDetectRethrow(ptr)
# stub __CxxExceptionFilter # stub __CxxExceptionFilter
@ cdecl -i386 -norelay __CxxFrameHandler(ptr ptr ptr ptr) @ cdecl -i386 -norelay __CxxFrameHandler(ptr ptr ptr ptr)
# stub __CxxFrameHandler2 @ cdecl -i386 -norelay __CxxFrameHandler2(ptr ptr ptr ptr) __CxxFrameHandler
# stub __CxxFrameHandler3 @ cdecl -i386 -norelay __CxxFrameHandler3(ptr ptr ptr ptr) __CxxFrameHandler
@ stdcall -arch=x86_64 __C_specific_handler(ptr long ptr ptr) ntdll.__C_specific_handler @ stdcall -arch=x86_64 __C_specific_handler(ptr long ptr ptr) ntdll.__C_specific_handler
@ stdcall -i386 __CxxLongjmpUnwind(ptr) @ stdcall -i386 __CxxLongjmpUnwind(ptr)
@ cdecl __CxxQueryExceptionSize() @ cdecl __CxxQueryExceptionSize()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment