msvcrt: Add support for VC7 and VC8 extensions to the C++ exception handler.
authorAlexandre Julliard <julliard@winehq.org>
Tue, 13 Apr 2010 15:21:06 +0000 (17:21 +0200)
committerAlexandre Julliard <julliard@winehq.org>
Tue, 13 Apr 2010 15:21:06 +0000 (17:21 +0200)
dlls/msvcr80/msvcr80.spec
dlls/msvcr90/msvcr90.spec
dlls/msvcrt/cppexcept.c
dlls/msvcrt/cppexcept.h
dlls/msvcrt/msvcrt.spec

index ec80a7f166d828b444ac571ff2a31d9ee0a71cba..3540296f2e558384dca384cd9f702bafdc55c4ea 100644 (file)
 @ cdecl __CxxDetectRethrow(ptr) msvcrt.__CxxDetectRethrow
 @ stub __CxxExceptionFilter
 @ cdecl -i386 -norelay __CxxFrameHandler(ptr ptr ptr ptr) msvcrt.__CxxFrameHandler
-@ stub __CxxFrameHandler2
-@ stub __CxxFrameHandler3
+@ cdecl -i386 -norelay __CxxFrameHandler2(ptr ptr ptr ptr) msvcrt.__CxxFrameHandler
+@ cdecl -i386 -norelay __CxxFrameHandler3(ptr ptr ptr ptr) msvcrt.__CxxFrameHandler
 @ stdcall -i386 __CxxLongjmpUnwind(ptr) msvcrt.__CxxLongjmpUnwind
 @ cdecl __CxxQueryExceptionSize() msvcrt.__CxxQueryExceptionSize
 @ stub __CxxRegisterExceptionObject
index 5854663a8f65c5ded6908ede7118ae5ca9524719..218ae788576305de9043299fc90dfabf3401a048 100644 (file)
 @ cdecl __CxxDetectRethrow(ptr) msvcrt.__CxxDetectRethrow
 @ stub __CxxExceptionFilter
 @ cdecl -i386 -norelay __CxxFrameHandler(ptr ptr ptr ptr) msvcrt.__CxxFrameHandler
-@ stub __CxxFrameHandler2
-@ stub __CxxFrameHandler3
+@ cdecl -i386 -norelay __CxxFrameHandler2(ptr ptr ptr ptr) msvcrt.__CxxFrameHandler
+@ cdecl -i386 -norelay __CxxFrameHandler3(ptr ptr ptr ptr) msvcrt.__CxxFrameHandler
 @ stdcall -i386 __CxxLongjmpUnwind(ptr) msvcrt.__CxxLongjmpUnwind
 @ cdecl __CxxQueryExceptionSize() msvcrt.__CxxQueryExceptionSize
 @ stub __CxxRegisterExceptionObject
index 4bdd59c0ba625833c5f9efa43fee09c502e06f23..a07d544ab6ad86e6458e59cb6d29044b309c78b6 100644 (file)
@@ -138,6 +138,10 @@ static void dump_function_descr( const cxx_function_descr *descr )
                      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 */
@@ -363,11 +367,16 @@ DWORD CDECL cxx_frame_handler( PEXCEPTION_RECORD rec, cxx_exception_frame* frame
 {
     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 );
         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 (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
     {
         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)
         {
             return exc_type->custom_handler( rec, frame, context, dispatch,
@@ -466,7 +475,7 @@ void CDECL _CxxThrowException( exception *object, const cxx_exception_type *type
 {
     ULONG_PTR args[3];
 
-    args[0] = CXX_FRAME_MAGIC;
+    args[0] = CXX_FRAME_MAGIC_VC6;
     args[1] = (ULONG_PTR)object;
     args[2] = (ULONG_PTR)type;
     RaiseException( CXX_EXCEPTION, EH_NONCONTINUABLE, 3, args );
@@ -486,7 +495,7 @@ BOOL CDECL __CxxDetectRethrow(PEXCEPTION_POINTERS ptrs)
 
   if (rec->ExceptionCode == CXX_EXCEPTION &&
       rec->NumberParameters == 3 &&
-      rec->ExceptionInformation[0] == CXX_FRAME_MAGIC &&
+      rec->ExceptionInformation[0] == CXX_FRAME_MAGIC_VC6 &&
       rec->ExceptionInformation[2])
   {
     ptrs->ExceptionRecord = msvcrt_get_thread_data()->exc_record;
index 7afb078881d17e2d0c5b4cf4f1bd35d92ee011e2..a46f222e34d78288a6f82da0ef5633b202428102 100644 (file)
 #ifndef __MSVCRT_CPPEXCEPT_H
 #define __MSVCRT_CPPEXCEPT_H
 
-#define CXX_FRAME_MAGIC    0x19930520
-#define CXX_EXCEPTION      0xe06d7363
+#define CXX_FRAME_MAGIC_VC6 0x19930520
+#define CXX_FRAME_MAGIC_VC7 0x19930521
+#define CXX_FRAME_MAGIC_VC8 0x19930522
+#define CXX_EXCEPTION       0xe06d7363
 
 typedef void (*vtable_ptr)(void);
 
@@ -87,9 +89,14 @@ typedef struct __cxx_function_descr
     const unwind_info   *unwind_table;   /* array of unwind handlers */
     UINT                 tryblock_count; /* number 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;
 
+#define FUNC_DESCR_SYNCHRONOUS  1        /* synchronous exceptions only (built with /EHs) */
+
 typedef void (*cxx_copy_ctor)(void);
 
 /* offsets for computing the this pointer */
index c90110f7bb016311bf2ba2326dec11f800c5d7f1..84828633ba629bbac880a1eb0d1e929aa98b3d61 100644 (file)
 @ cdecl __CxxDetectRethrow(ptr)
 # stub __CxxExceptionFilter
 @ cdecl -i386 -norelay __CxxFrameHandler(ptr ptr ptr ptr)
-# stub __CxxFrameHandler2
-# stub __CxxFrameHandler3
+@ cdecl -i386 -norelay __CxxFrameHandler2(ptr ptr ptr ptr) __CxxFrameHandler
+@ 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 -i386 __CxxLongjmpUnwind(ptr)
 @ cdecl __CxxQueryExceptionSize()