Commit b0326bea authored by Daniel Lehman's avatar Daniel Lehman Committed by Alexandre Julliard

msvcrt: Handle synchronous flag for x64 C++ exceptions.

parent dad06728
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
#define CXX_FRAME_MAGIC_VC8 0x19930522 #define CXX_FRAME_MAGIC_VC8 0x19930522
#define CXX_EXCEPTION 0xe06d7363 #define CXX_EXCEPTION 0xe06d7363
#define FUNC_DESCR_SYNCHRONOUS 1 /* synchronous exceptions only (built with /EHs and /EHsc) */
typedef void (*vtable_ptr)(void); typedef void (*vtable_ptr)(void);
/* type_info object, see cpp.c for implementation */ /* type_info object, see cpp.c for implementation */
......
...@@ -96,8 +96,6 @@ typedef struct __cxx_function_descr ...@@ -96,8 +96,6 @@ typedef struct __cxx_function_descr
UINT flags; /* flags when magic >= VC8 */ UINT flags; /* flags when magic >= VC8 */
} cxx_function_descr; } cxx_function_descr;
#define FUNC_DESCR_SYNCHRONOUS 1 /* synchronous exceptions only (built with /EHs) */
typedef struct _SCOPETABLE typedef struct _SCOPETABLE
{ {
int previousTryLevel; int previousTryLevel;
......
...@@ -331,6 +331,12 @@ static inline void* WINAPI call_catch_block(EXCEPTION_RECORD *rec) ...@@ -331,6 +331,12 @@ static inline void* WINAPI call_catch_block(EXCEPTION_RECORD *rec)
return ret_addr; 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, static inline void find_catch_block(EXCEPTION_RECORD *rec, ULONG64 frame,
DISPATCHER_CONTEXT *dispatch, DISPATCHER_CONTEXT *dispatch,
const cxx_function_descr *descr, const cxx_function_descr *descr,
...@@ -442,6 +448,13 @@ static DWORD cxx_frame_handler(EXCEPTION_RECORD *rec, ULONG64 frame, ...@@ -442,6 +448,13 @@ static DWORD cxx_frame_handler(EXCEPTION_RECORD *rec, ULONG64 frame,
return ExceptionContinueSearch; 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 */ /* update orig_frame if it's a nested exception */
throw_func_off = RtlLookupFunctionEntry(dispatch->ControlPc, &throw_base, NULL)->BeginAddress; throw_func_off = RtlLookupFunctionEntry(dispatch->ControlPc, &throw_base, NULL)->BeginAddress;
throw_func = rva_to_ptr(throw_func_off, throw_base); throw_func = rva_to_ptr(throw_func_off, throw_base);
...@@ -470,8 +483,7 @@ static DWORD cxx_frame_handler(EXCEPTION_RECORD *rec, ULONG64 frame, ...@@ -470,8 +483,7 @@ static DWORD cxx_frame_handler(EXCEPTION_RECORD *rec, ULONG64 frame,
if (rec->ExceptionFlags & (EH_UNWINDING|EH_EXIT_UNWIND)) if (rec->ExceptionFlags & (EH_UNWINDING|EH_EXIT_UNWIND))
{ {
if (rec->ExceptionCode==STATUS_UNWIND_CONSOLIDATE && rec->NumberParameters==6 && if (cxx_is_consolidate(rec))
rec->ExceptionInformation[0]==(ULONG_PTR)call_catch_block)
{ {
EXCEPTION_RECORD *new_rec = (void*)rec->ExceptionInformation[4]; EXCEPTION_RECORD *new_rec = (void*)rec->ExceptionInformation[4];
thread_data_t *data = msvcrt_get_thread_data(); thread_data_t *data = msvcrt_get_thread_data();
......
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