Module: wine Branch: master Commit: b0326bea747c4f789f0fb36cf317df1b98816f22 URL: http://source.winehq.org/git/wine.git/?a=commit;h=b0326bea747c4f789f0fb36cf3...
Author: Daniel Lehman dlehman@esri.com Date: Thu Apr 20 06:21:14 2017 -0700
msvcrt: Handle synchronous flag for x64 C++ exceptions.
Signed-off-by: Daniel Lehman dlehman@esri.com Signed-off-by: Piotr Caban piotr@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/msvcrt/cppexcept.h | 2 ++ dlls/msvcrt/except_i386.c | 2 -- dlls/msvcrt/except_x86_64.c | 16 ++++++++++++++-- 3 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/dlls/msvcrt/cppexcept.h b/dlls/msvcrt/cppexcept.h index 6ea5818..2091889 100644 --- a/dlls/msvcrt/cppexcept.h +++ b/dlls/msvcrt/cppexcept.h @@ -26,6 +26,8 @@ #define CXX_FRAME_MAGIC_VC8 0x19930522 #define CXX_EXCEPTION 0xe06d7363
+#define FUNC_DESCR_SYNCHRONOUS 1 /* synchronous exceptions only (built with /EHs and /EHsc) */ + typedef void (*vtable_ptr)(void);
/* type_info object, see cpp.c for implementation */ diff --git a/dlls/msvcrt/except_i386.c b/dlls/msvcrt/except_i386.c index d26a864..963bd58 100644 --- a/dlls/msvcrt/except_i386.c +++ b/dlls/msvcrt/except_i386.c @@ -96,8 +96,6 @@ typedef struct __cxx_function_descr UINT flags; /* flags when magic >= VC8 */ } cxx_function_descr;
-#define FUNC_DESCR_SYNCHRONOUS 1 /* synchronous exceptions only (built with /EHs) */ - typedef struct _SCOPETABLE { int previousTryLevel; diff --git a/dlls/msvcrt/except_x86_64.c b/dlls/msvcrt/except_x86_64.c index d299608..8210f7b 100644 --- a/dlls/msvcrt/except_x86_64.c +++ b/dlls/msvcrt/except_x86_64.c @@ -331,6 +331,12 @@ static inline void* WINAPI call_catch_block(EXCEPTION_RECORD *rec) return ret_addr; }
+static inline BOOL cxx_is_consolidate(const EXCEPTION_RECORD *rec) +{ + return rec->ExceptionCode==STATUS_UNWIND_CONSOLIDATE && rec->NumberParameters==6 && + rec->ExceptionInformation[0]==(ULONG_PTR)call_catch_block; +} + static inline void find_catch_block(EXCEPTION_RECORD *rec, ULONG64 frame, DISPATCHER_CONTEXT *dispatch, const cxx_function_descr *descr, @@ -442,6 +448,13 @@ static DWORD cxx_frame_handler(EXCEPTION_RECORD *rec, ULONG64 frame, return ExceptionContinueSearch; }
+ if (descr->magic >= CXX_FRAME_MAGIC_VC8 && + (descr->flags & FUNC_DESCR_SYNCHRONOUS) && + (rec->ExceptionCode != CXX_EXCEPTION && + !cxx_is_consolidate(rec) && + rec->ExceptionCode != STATUS_LONGJUMP)) + return ExceptionContinueSearch; /* handle only c++ exceptions */ + /* update orig_frame if it's a nested exception */ throw_func_off = RtlLookupFunctionEntry(dispatch->ControlPc, &throw_base, NULL)->BeginAddress; throw_func = rva_to_ptr(throw_func_off, throw_base); @@ -470,8 +483,7 @@ static DWORD cxx_frame_handler(EXCEPTION_RECORD *rec, ULONG64 frame,
if (rec->ExceptionFlags & (EH_UNWINDING|EH_EXIT_UNWIND)) { - if (rec->ExceptionCode==STATUS_UNWIND_CONSOLIDATE && rec->NumberParameters==6 && - rec->ExceptionInformation[0]==(ULONG_PTR)call_catch_block) + if (cxx_is_consolidate(rec)) { EXCEPTION_RECORD *new_rec = (void*)rec->ExceptionInformation[4]; thread_data_t *data = msvcrt_get_thread_data();