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 @@
#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 */
......
......@@ -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;
......
......@@ -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();
......
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