From: Piotr Caban Subject: msvcrt: Add i386 __CxxExceptionFilter implementation Message-Id: <560A6691.7070606@codeweavers.com> Date: Tue, 29 Sep 2015 12:23:13 +0200 Signed-off-by: Piotr Caban --- dlls/msvcr100/msvcr100.spec | 2 +- dlls/msvcr110/msvcr110.spec | 2 +- dlls/msvcr120/msvcr120.spec | 2 +- dlls/msvcr120_app/msvcr120_app.spec | 2 +- dlls/msvcr70/msvcr70.spec | 2 +- dlls/msvcr71/msvcr71.spec | 2 +- dlls/msvcr80/msvcr80.spec | 2 +- dlls/msvcr90/msvcr90.spec | 2 +- dlls/msvcrt/except_arm.c | 9 +++++ dlls/msvcrt/except_i386.c | 71 +++++++++++++++++++++++++++++++++---- dlls/msvcrt/except_x86_64.c | 9 +++++ dlls/msvcrt/msvcrt.spec | 2 +- dlls/ucrtbase/ucrtbase.spec | 2 +- 13 files changed, 92 insertions(+), 17 deletions(-) diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec index edff2c9..8ceecc9 100644 --- a/dlls/msvcr100/msvcr100.spec +++ b/dlls/msvcr100/msvcr100.spec @@ -548,7 +548,7 @@ @ stub __CxxCallUnwindStdDelDtor @ stub __CxxCallUnwindVecDtor @ cdecl -arch=i386,x86_64,arm __CxxDetectRethrow(ptr) -@ stub __CxxExceptionFilter +@ cdecl -arch=i386,x86_64,arm __CxxExceptionFilter(ptr ptr long ptr) @ cdecl -arch=i386,x86_64,arm -norelay __CxxFrameHandler(ptr ptr ptr ptr) @ cdecl -arch=i386,x86_64,arm -norelay __CxxFrameHandler2(ptr ptr ptr ptr) __CxxFrameHandler @ cdecl -arch=i386,x86_64,arm -norelay __CxxFrameHandler3(ptr ptr ptr ptr) __CxxFrameHandler diff --git a/dlls/msvcr110/msvcr110.spec b/dlls/msvcr110/msvcr110.spec index 9dda90a..e42ec11 100644 --- a/dlls/msvcr110/msvcr110.spec +++ b/dlls/msvcr110/msvcr110.spec @@ -875,7 +875,7 @@ @ stdcall -arch=x86_64 __C_specific_handler(ptr long ptr ptr) ntdll.__C_specific_handler @ cdecl -arch=i386,x86_64,arm __CppXcptFilter(long ptr) @ cdecl -arch=i386,x86_64,arm __CxxDetectRethrow(ptr) -@ stub __CxxExceptionFilter +@ cdecl -arch=i386,x86_64,arm __CxxExceptionFilter(ptr ptr long ptr) @ cdecl -arch=i386,x86_64,arm -norelay __CxxFrameHandler(ptr ptr ptr ptr) @ cdecl -arch=i386,x86_64,arm -norelay __CxxFrameHandler2(ptr ptr ptr ptr) __CxxFrameHandler @ cdecl -arch=i386,x86_64,arm -norelay __CxxFrameHandler3(ptr ptr ptr ptr) __CxxFrameHandler diff --git a/dlls/msvcr120/msvcr120.spec b/dlls/msvcr120/msvcr120.spec index 6e13eef..9f04cbf 100644 --- a/dlls/msvcr120/msvcr120.spec +++ b/dlls/msvcr120/msvcr120.spec @@ -859,7 +859,7 @@ @ stdcall -arch=x86_64 __C_specific_handler(ptr long ptr ptr) ntdll.__C_specific_handler @ cdecl -arch=i386,x86_64,arm __CppXcptFilter(long ptr) @ cdecl -arch=i386,x86_64,arm __CxxDetectRethrow(ptr) -@ stub __CxxExceptionFilter +@ cdecl -arch=i386,x86_64,arm __CxxExceptionFilter(ptr ptr long ptr) @ cdecl -arch=i386,x86_64,arm -norelay __CxxFrameHandler(ptr ptr ptr ptr) @ cdecl -arch=i386,x86_64,arm -norelay __CxxFrameHandler2(ptr ptr ptr ptr) __CxxFrameHandler @ cdecl -arch=i386,x86_64,arm -norelay __CxxFrameHandler3(ptr ptr ptr ptr) __CxxFrameHandler diff --git a/dlls/msvcr120_app/msvcr120_app.spec b/dlls/msvcr120_app/msvcr120_app.spec index bc4d63b..d3591c1 100644 --- a/dlls/msvcr120_app/msvcr120_app.spec +++ b/dlls/msvcr120_app/msvcr120_app.spec @@ -853,7 +853,7 @@ @ stdcall -arch=x86_64 __C_specific_handler(ptr long ptr ptr) msvcr120.__C_specific_handler @ cdecl -arch=i386,x86_64,arm __CppXcptFilter(long ptr) msvcr120.__CppXcptFilter @ cdecl -arch=i386,x86_64,arm __CxxDetectRethrow(ptr) msvcr120.__CxxDetectRethrow -@ stub __CxxExceptionFilter +@ cdecl -arch=i386,x86_64,arm __CxxExceptionFilter(ptr ptr long ptr) msvcr120.__CxxExceptionFilter @ cdecl -arch=i386,x86_64,arm -norelay __CxxFrameHandler(ptr ptr ptr ptr) msvcr120.__CxxFrameHandler @ cdecl -arch=i386,x86_64,arm -norelay __CxxFrameHandler2(ptr ptr ptr ptr) msvcr120.__CxxFrameHandler2 @ cdecl -arch=i386,x86_64,arm -norelay __CxxFrameHandler3(ptr ptr ptr ptr) msvcr120.__CxxFrameHandler3 diff --git a/dlls/msvcr70/msvcr70.spec b/dlls/msvcr70/msvcr70.spec index eb3464b..3382652 100644 --- a/dlls/msvcr70/msvcr70.spec +++ b/dlls/msvcr70/msvcr70.spec @@ -119,7 +119,7 @@ @ stub __CxxCallUnwindDtor @ stub __CxxCallUnwindVecDtor @ cdecl -arch=i386,x86_64,arm __CxxDetectRethrow(ptr) -@ stub __CxxExceptionFilter +@ cdecl -arch=i386,x86_64,arm __CxxExceptionFilter(ptr ptr long ptr) @ cdecl -arch=i386,x86_64,arm -norelay __CxxFrameHandler(ptr ptr ptr ptr) @ stdcall -arch=i386 __CxxLongjmpUnwind(ptr) @ cdecl -arch=i386,x86_64,arm __CxxQueryExceptionSize() diff --git a/dlls/msvcr71/msvcr71.spec b/dlls/msvcr71/msvcr71.spec index 92c71c3..fbdf839 100644 --- a/dlls/msvcr71/msvcr71.spec +++ b/dlls/msvcr71/msvcr71.spec @@ -114,7 +114,7 @@ @ stub __CxxCallUnwindDtor @ stub __CxxCallUnwindVecDtor @ cdecl -arch=i386,x86_64,arm __CxxDetectRethrow(ptr) -@ stub __CxxExceptionFilter +@ cdecl -arch=i386,x86_64,arm __CxxExceptionFilter(ptr ptr long ptr) @ cdecl -arch=i386,x86_64,arm -norelay __CxxFrameHandler(ptr ptr ptr ptr) @ stdcall -arch=i386 __CxxLongjmpUnwind(ptr) @ cdecl -arch=i386,x86_64,arm __CxxQueryExceptionSize() diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec index cc10014..e83e056 100644 --- a/dlls/msvcr80/msvcr80.spec +++ b/dlls/msvcr80/msvcr80.spec @@ -182,7 +182,7 @@ @ stub __CxxCallUnwindStdDelDtor @ stub __CxxCallUnwindVecDtor @ cdecl -arch=i386,x86_64,arm __CxxDetectRethrow(ptr) -@ stub __CxxExceptionFilter +@ cdecl -arch=i386,x86_64,arm __CxxExceptionFilter(ptr ptr long ptr) @ cdecl -arch=i386,x86_64,arm -norelay __CxxFrameHandler(ptr ptr ptr ptr) @ cdecl -arch=i386,x86_64,arm -norelay __CxxFrameHandler2(ptr ptr ptr ptr) __CxxFrameHandler @ cdecl -arch=i386,x86_64,arm -norelay __CxxFrameHandler3(ptr ptr ptr ptr) __CxxFrameHandler diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec index e5415c4..9aef185 100644 --- a/dlls/msvcr90/msvcr90.spec +++ b/dlls/msvcr90/msvcr90.spec @@ -173,7 +173,7 @@ @ stub __CxxCallUnwindStdDelDtor @ stub __CxxCallUnwindVecDtor @ cdecl -arch=i386,x86_64,arm __CxxDetectRethrow(ptr) -@ stub __CxxExceptionFilter +@ cdecl -arch=i386,x86_64,arm __CxxExceptionFilter(ptr ptr long ptr) @ cdecl -arch=i386,x86_64,arm -norelay __CxxFrameHandler(ptr ptr ptr ptr) @ cdecl -arch=i386,x86_64,arm -norelay __CxxFrameHandler2(ptr ptr ptr ptr) __CxxFrameHandler @ cdecl -arch=i386,x86_64,arm -norelay __CxxFrameHandler3(ptr ptr ptr ptr) __CxxFrameHandler diff --git a/dlls/msvcrt/except_arm.c b/dlls/msvcrt/except_arm.c index 465f310..62dadef 100644 --- a/dlls/msvcrt/except_arm.c +++ b/dlls/msvcrt/except_arm.c @@ -64,6 +64,15 @@ typedef struct _DISPATCHER_CONTEXT DWORD VirtualVfpHead; } DISPATCHER_CONTEXT; +/********************************************************************* + * __CxxExceptionFilter (MSVCRT.@) + */ +int CDECL __CxxExceptionFilter( PEXCEPTION_POINTERS ptrs, + const type_info *ti, int flags, void **copy ) +{ + FIXME( "%p %p %x %p: not implemented\n", ptrs, ti, flags, copy ); + return EXCEPTION_CONTINUE_SEARCH; +} /********************************************************************* * __CxxFrameHandler (MSVCRT.@) diff --git a/dlls/msvcrt/except_i386.c b/dlls/msvcrt/except_i386.c index 2a4ef9d..6cbb758 100644 --- a/dlls/msvcrt/except_i386.c +++ b/dlls/msvcrt/except_i386.c @@ -266,7 +266,7 @@ static void dump_function_descr( const cxx_function_descr *descr ) /* check if the exception type is caught by a given catch block, and return the type that matched */ static const cxx_type_info *find_caught_type( cxx_exception_type *exc_type, - const catchblock_info *catchblock ) + const type_info *catch_ti, UINT catch_flags ) { UINT i; @@ -274,16 +274,16 @@ static const cxx_type_info *find_caught_type( cxx_exception_type *exc_type, { const cxx_type_info *type = exc_type->type_info_table->info[i]; - if (!catchblock->type_info) return type; /* catch(...) matches any type */ - if (catchblock->type_info != type->type_info) + if (!catch_ti) return type; /* catch(...) matches any type */ + if (catch_ti != type->type_info) { - if (strcmp( catchblock->type_info->mangled, type->type_info->mangled )) continue; + if (strcmp( catch_ti->mangled, type->type_info->mangled )) continue; } /* type is the same, now check the flags */ if ((exc_type->flags & TYPE_FLAG_CONST) && - !(catchblock->flags & TYPE_FLAG_CONST)) continue; + !(catch_flags & TYPE_FLAG_CONST)) continue; if ((exc_type->flags & TYPE_FLAG_VOLATILE) && - !(catchblock->flags & TYPE_FLAG_VOLATILE)) continue; + !(catch_flags & TYPE_FLAG_VOLATILE)) continue; return type; /* it matched */ } return NULL; @@ -442,7 +442,8 @@ static inline void call_catch_block( PEXCEPTION_RECORD rec, cxx_exception_frame const catchblock_info *catchblock = &tryblock->catchblock[j]; if(info) { - const cxx_type_info *type = find_caught_type( info, catchblock ); + const cxx_type_info *type = find_caught_type( info, + catchblock->type_info, catchblock->flags ); if (!type) continue; TRACE( "matched type %p in tryblock %d catchblock %d\n", type, i, j ); @@ -491,6 +492,62 @@ static inline void call_catch_block( PEXCEPTION_RECORD rec, cxx_exception_frame } } +/********************************************************************* + * __CxxExceptionFilter (MSVCRT.@) + */ +int CDECL __CxxExceptionFilter( PEXCEPTION_POINTERS ptrs, + const type_info *ti, int flags, void **copy) +{ + const cxx_type_info *type; + PEXCEPTION_RECORD rec; + + TRACE( "%p %p %x %p\n", ptrs, ti, flags, copy ); + + if (!ptrs) return EXCEPTION_CONTINUE_SEARCH; + + /* handle catch(...) */ + if (!ti) return EXCEPTION_EXECUTE_HANDLER; + + rec = ptrs->ExceptionRecord; + if (rec->ExceptionCode != CXX_EXCEPTION || rec->NumberParameters != 3 || + rec->ExceptionInformation[0] < CXX_FRAME_MAGIC_VC6 || + rec->ExceptionInformation[0] > CXX_FRAME_MAGIC_VC8) + return EXCEPTION_CONTINUE_SEARCH; + + if (rec->ExceptionInformation[1] == 0 && rec->ExceptionInformation[2] == 0) + { + rec = msvcrt_get_thread_data()->exc_record; + if (!rec) return EXCEPTION_CONTINUE_SEARCH; + } + + type = find_caught_type( (cxx_exception_type*)rec->ExceptionInformation[2], ti, flags ); + if (!type) return EXCEPTION_CONTINUE_SEARCH; + + if (copy) + { + void *object = (void *)rec->ExceptionInformation[1]; + + if (flags & TYPE_FLAG_REFERENCE) + { + *copy = get_this_pointer( &type->offsets, object ); + } + else if (type->flags & CLASS_IS_SIMPLE_TYPE) + { + memmove( copy, object, type->size ); + /* if it is a pointer, adjust it */ + if (type->size == sizeof(void*)) *copy = get_this_pointer( &type->offsets, *copy ); + } + else /* copy the object */ + { + if (type->copy_ctor) + call_copy_ctor( type->copy_ctor, copy, get_this_pointer(&type->offsets,object), + (type->flags & CLASS_HAS_VIRTUAL_BASE_CLASS) ); + else + memmove( copy, get_this_pointer(&type->offsets,object), type->size ); + } + } + return EXCEPTION_EXECUTE_HANDLER; +} /********************************************************************* * cxx_frame_handler diff --git a/dlls/msvcrt/except_x86_64.c b/dlls/msvcrt/except_x86_64.c index e2d2402..27d0a15 100644 --- a/dlls/msvcrt/except_x86_64.c +++ b/dlls/msvcrt/except_x86_64.c @@ -61,6 +61,15 @@ typedef struct _DISPATCHER_CONTEXT ULONG ScopeIndex; } DISPATCHER_CONTEXT; +/********************************************************************* + * __CxxExceptionFilter (MSVCRT.@) + */ +int CDECL __CxxExceptionFilter( PEXCEPTION_POINTERS ptrs, + const type_info *ti, int flags, void **copy ) +{ + FIXME( "%p %p %x %p: not implemented\n", ptrs, ti, flags, copy ); + return EXCEPTION_CONTINUE_SEARCH; +} /********************************************************************* * __CxxFrameHandler (MSVCRT.@) diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index 3bd47d2..bd854a4 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -178,7 +178,7 @@ # stub __CxxCallUnwindDtor # stub __CxxCallUnwindVecDtor @ cdecl -arch=i386,x86_64,arm __CxxDetectRethrow(ptr) -# stub __CxxExceptionFilter +@ cdecl -arch=i386,x86_64,arm __CxxExceptionFilter(ptr ptr long ptr) @ cdecl -arch=i386,x86_64,arm -norelay __CxxFrameHandler(ptr ptr ptr ptr) @ cdecl -arch=i386,x86_64,arm -norelay __CxxFrameHandler2(ptr ptr ptr ptr) __CxxFrameHandler @ cdecl -arch=i386,x86_64,arm -norelay __CxxFrameHandler3(ptr ptr ptr ptr) __CxxFrameHandler diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec index 5623107..58c5ee3 100644 --- a/dlls/ucrtbase/ucrtbase.spec +++ b/dlls/ucrtbase/ucrtbase.spec @@ -50,7 +50,7 @@ @ stub __BuildCatchObjectHelper @ stdcall -arch=x86_64 __C_specific_handler(ptr long ptr ptr) ntdll.__C_specific_handler @ cdecl -arch=i386,x86_64,arm __CxxDetectRethrow(ptr) -@ stub __CxxExceptionFilter +@ cdecl -arch=i386,x86_64,arm __CxxExceptionFilter(ptr ptr long ptr) @ cdecl -arch=i386,x86_64,arm -norelay __CxxFrameHandler(ptr ptr ptr ptr) @ cdecl -arch=i386,x86_64,arm -norelay __CxxFrameHandler2(ptr ptr ptr ptr) __CxxFrameHandler @ cdecl -arch=i386,x86_64,arm -norelay __CxxFrameHandler3(ptr ptr ptr ptr) __CxxFrameHandler