ucrtbase: Add __current_exception_context() implementation.

Signed-off-by: Piotr Caban <piotr@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Piotr Caban 2018-03-20 15:36:43 +01:00 committed by Alexandre Julliard
parent a9cf391bed
commit f82af4d2bb
7 changed files with 43 additions and 23 deletions

View File

@ -34,7 +34,7 @@
@ cdecl __RTtypeid(ptr) ucrtbase.__RTtypeid @ cdecl __RTtypeid(ptr) ucrtbase.__RTtypeid
@ stub __TypeMatch @ stub __TypeMatch
@ cdecl __current_exception() ucrtbase.__current_exception @ cdecl __current_exception() ucrtbase.__current_exception
@ stub __current_exception_context @ cdecl __current_exception_context() ucrtbase.__current_exception_context
@ stub __dcrt_get_wide_environment_from_os @ stub __dcrt_get_wide_environment_from_os
@ stub __dcrt_initial_narrow_environment @ stub __dcrt_initial_narrow_environment
@ stub __intrinsic_abnormal_termination @ stub __intrinsic_abnormal_termination

View File

@ -432,23 +432,24 @@ void CDECL __DestructExceptionObject(EXCEPTION_RECORD *rec)
/********************************************************************* /*********************************************************************
* __CxxRegisterExceptionObject (MSVCRT.@) * __CxxRegisterExceptionObject (MSVCRT.@)
*/ */
BOOL CDECL __CxxRegisterExceptionObject(EXCEPTION_RECORD **rec, cxx_frame_info *frame_info) BOOL CDECL __CxxRegisterExceptionObject(EXCEPTION_POINTERS *ep, cxx_frame_info *frame_info)
{ {
thread_data_t *data = msvcrt_get_thread_data(); thread_data_t *data = msvcrt_get_thread_data();
TRACE("(%p, %p)\n", rec, frame_info); TRACE("(%p, %p)\n", ep, frame_info);
if (!rec || !*rec) if (!ep || !ep->ExceptionRecord)
{ {
frame_info->rec = (void*)-1; frame_info->rec = (void*)-1;
frame_info->unk = (void*)-1; frame_info->context = (void*)-1;
return TRUE; return TRUE;
} }
frame_info->rec = data->exc_record; frame_info->rec = data->exc_record;
frame_info->unk = 0; frame_info->context = data->ctx_record;
data->exc_record = *rec; data->exc_record = ep->ExceptionRecord;
_CreateFrameInfo(&frame_info->frame_info, (void*)(*rec)->ExceptionInformation[1]); data->ctx_record = ep->ContextRecord;
_CreateFrameInfo(&frame_info->frame_info, (void*)ep->ExceptionRecord->ExceptionInformation[1]);
return TRUE; return TRUE;
} }
@ -469,6 +470,7 @@ void CDECL __CxxUnregisterExceptionObject(cxx_frame_info *frame_info, BOOL in_us
&& _IsExceptionObjectToBeDestroyed((void*)data->exc_record->ExceptionInformation[1])) && _IsExceptionObjectToBeDestroyed((void*)data->exc_record->ExceptionInformation[1]))
__DestructExceptionObject(data->exc_record); __DestructExceptionObject(data->exc_record);
data->exc_record = frame_info->rec; data->exc_record = frame_info->rec;
data->ctx_record = frame_info->context;
} }
struct __std_exception_data { struct __std_exception_data {
@ -517,4 +519,13 @@ void** CDECL __current_exception(void)
return (void**)&msvcrt_get_thread_data()->exc_record; return (void**)&msvcrt_get_thread_data()->exc_record;
} }
/*********************************************************************
* __current_exception_context (UCRTBASE.@)
*/
void** CDECL __current_exception_context(void)
{
TRACE("()\n");
return (void**)&msvcrt_get_thread_data()->ctx_record;
}
#endif /* _MSVCR_VER>=140 */ #endif /* _MSVCR_VER>=140 */

View File

@ -400,7 +400,8 @@ static DWORD catch_function_nested_handler( EXCEPTION_RECORD *rec, EXCEPTION_REG
/* find and call the appropriate catch block for an exception */ /* find and call the appropriate catch block for an exception */
/* returns the address to continue execution to after the catch block was called */ /* returns the address to continue execution to after the catch block was called */
static inline void call_catch_block( PEXCEPTION_RECORD rec, cxx_exception_frame *frame, static inline void call_catch_block( PEXCEPTION_RECORD rec, CONTEXT *context,
cxx_exception_frame *frame,
const cxx_function_descr *descr, int nested_trylevel, const cxx_function_descr *descr, int nested_trylevel,
EXCEPTION_REGISTRATION_RECORD *catch_frame, EXCEPTION_REGISTRATION_RECORD *catch_frame,
cxx_exception_type *info ) cxx_exception_type *info )
@ -457,7 +458,9 @@ static inline void call_catch_block( PEXCEPTION_RECORD rec, cxx_exception_frame
data = msvcrt_get_thread_data(); data = msvcrt_get_thread_data();
nested_frame.frame_info.rec = data->exc_record; nested_frame.frame_info.rec = data->exc_record;
nested_frame.frame_info.context = data->ctx_record;
data->exc_record = rec; data->exc_record = rec;
data->ctx_record = context;
/* call the catch block */ /* call the catch block */
TRACE( "calling catch block %p addr %p ebp %p\n", TRACE( "calling catch block %p addr %p ebp %p\n",
@ -552,7 +555,7 @@ static LONG CALLBACK se_translation_filter( EXCEPTION_POINTERS *ep, void *c )
} }
exc_type = (cxx_exception_type *)rec->ExceptionInformation[2]; exc_type = (cxx_exception_type *)rec->ExceptionInformation[2];
call_catch_block( rec, ctx->frame, ctx->descr, call_catch_block( rec, ep->ContextRecord, ctx->frame, ctx->descr,
ctx->frame->trylevel, ctx->nested_frame, exc_type ); ctx->frame->trylevel, ctx->nested_frame, exc_type );
__DestructExceptionObject( rec ); __DestructExceptionObject( rec );
@ -649,7 +652,8 @@ DWORD CDECL cxx_frame_handler( PEXCEPTION_RECORD rec, cxx_exception_frame* frame
} }
} }
call_catch_block( rec, frame, descr, frame->trylevel, nested_frame, exc_type ); call_catch_block( rec, context, frame, descr,
frame->trylevel, nested_frame, exc_type );
return ExceptionContinueSearch; return ExceptionContinueSearch;
} }

View File

@ -352,15 +352,17 @@ static void* WINAPI call_catch_block(EXCEPTION_RECORD *rec)
const cxx_function_descr *descr = (void*)rec->ExceptionInformation[2]; const cxx_function_descr *descr = (void*)rec->ExceptionInformation[2];
EXCEPTION_RECORD *prev_rec = (void*)rec->ExceptionInformation[4]; EXCEPTION_RECORD *prev_rec = (void*)rec->ExceptionInformation[4];
EXCEPTION_RECORD *untrans_rec = (void*)rec->ExceptionInformation[6]; EXCEPTION_RECORD *untrans_rec = (void*)rec->ExceptionInformation[6];
CONTEXT *context = (void*)rec->ExceptionInformation[7];
void* (__cdecl *handler)(ULONG64 unk, ULONG64 rbp) = (void*)rec->ExceptionInformation[5]; void* (__cdecl *handler)(ULONG64 unk, ULONG64 rbp) = (void*)rec->ExceptionInformation[5];
int *unwind_help = rva_to_ptr(descr->unwind_help, frame); int *unwind_help = rva_to_ptr(descr->unwind_help, frame);
EXCEPTION_POINTERS ep = { prev_rec, context };
cxx_catch_ctx ctx; cxx_catch_ctx ctx;
void *ret_addr = NULL; void *ret_addr = NULL;
TRACE("calling handler %p\n", handler); TRACE("calling handler %p\n", handler);
ctx.rethrow = FALSE; ctx.rethrow = FALSE;
__CxxRegisterExceptionObject(&prev_rec, &ctx.frame_info); __CxxRegisterExceptionObject(&ep, &ctx.frame_info);
__TRY __TRY
{ {
__TRY __TRY
@ -395,11 +397,12 @@ static void* WINAPI call_catch_block(EXCEPTION_RECORD *rec)
static inline BOOL cxx_is_consolidate(const EXCEPTION_RECORD *rec) static inline BOOL cxx_is_consolidate(const EXCEPTION_RECORD *rec)
{ {
return rec->ExceptionCode==STATUS_UNWIND_CONSOLIDATE && rec->NumberParameters==7 && return rec->ExceptionCode==STATUS_UNWIND_CONSOLIDATE && rec->NumberParameters==8 &&
rec->ExceptionInformation[0]==(ULONG_PTR)call_catch_block; rec->ExceptionInformation[0]==(ULONG_PTR)call_catch_block;
} }
static inline void find_catch_block(EXCEPTION_RECORD *rec, EXCEPTION_RECORD *untrans_rec, static inline void find_catch_block(EXCEPTION_RECORD *rec, CONTEXT *context,
EXCEPTION_RECORD *untrans_rec,
ULONG64 frame, DISPATCHER_CONTEXT *dispatch, ULONG64 frame, DISPATCHER_CONTEXT *dispatch,
const cxx_function_descr *descr, const cxx_function_descr *descr,
cxx_exception_type *info, ULONG64 orig_frame) cxx_exception_type *info, ULONG64 orig_frame)
@ -409,7 +412,7 @@ static inline void find_catch_block(EXCEPTION_RECORD *rec, EXCEPTION_RECORD *unt
descr->ipmap_count, dispatch->ControlPc-dispatch->ImageBase); descr->ipmap_count, dispatch->ControlPc-dispatch->ImageBase);
const tryblock_info *in_catch; const tryblock_info *in_catch;
EXCEPTION_RECORD catch_record; EXCEPTION_RECORD catch_record;
CONTEXT context; CONTEXT ctx;
UINT i, j; UINT i, j;
INT *unwind_help; INT *unwind_help;
@ -476,7 +479,7 @@ static inline void find_catch_block(EXCEPTION_RECORD *rec, EXCEPTION_RECORD *unt
memset(&catch_record, 0, sizeof(catch_record)); memset(&catch_record, 0, sizeof(catch_record));
catch_record.ExceptionCode = STATUS_UNWIND_CONSOLIDATE; catch_record.ExceptionCode = STATUS_UNWIND_CONSOLIDATE;
catch_record.ExceptionFlags = EXCEPTION_NONCONTINUABLE; catch_record.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
catch_record.NumberParameters = 7; catch_record.NumberParameters = 8;
catch_record.ExceptionInformation[0] = (ULONG_PTR)call_catch_block; catch_record.ExceptionInformation[0] = (ULONG_PTR)call_catch_block;
catch_record.ExceptionInformation[1] = orig_frame; catch_record.ExceptionInformation[1] = orig_frame;
catch_record.ExceptionInformation[2] = (ULONG_PTR)descr; catch_record.ExceptionInformation[2] = (ULONG_PTR)descr;
@ -485,7 +488,8 @@ static inline void find_catch_block(EXCEPTION_RECORD *rec, EXCEPTION_RECORD *unt
catch_record.ExceptionInformation[5] = catch_record.ExceptionInformation[5] =
(ULONG_PTR)rva_to_ptr(catchblock->handler, dispatch->ImageBase); (ULONG_PTR)rva_to_ptr(catchblock->handler, dispatch->ImageBase);
catch_record.ExceptionInformation[6] = (ULONG_PTR)untrans_rec; catch_record.ExceptionInformation[6] = (ULONG_PTR)untrans_rec;
RtlUnwindEx((void*)frame, (void*)dispatch->ControlPc, &catch_record, NULL, &context, NULL); catch_record.ExceptionInformation[7] = (ULONG_PTR)context;
RtlUnwindEx((void*)frame, (void*)dispatch->ControlPc, &catch_record, NULL, &ctx, NULL);
} }
} }
@ -505,7 +509,7 @@ static LONG CALLBACK se_translation_filter(EXCEPTION_POINTERS *ep, void *c)
} }
exc_type = (cxx_exception_type *)rec->ExceptionInformation[2]; exc_type = (cxx_exception_type *)rec->ExceptionInformation[2];
find_catch_block(rec, ctx->seh_rec, ctx->dest_frame, ctx->dispatch, find_catch_block(rec, ep->ContextRecord, ctx->seh_rec, ctx->dest_frame, ctx->dispatch,
ctx->descr, exc_type, ctx->orig_frame); ctx->descr, exc_type, ctx->orig_frame);
__DestructExceptionObject(rec); __DestructExceptionObject(rec);
@ -618,7 +622,7 @@ static DWORD cxx_frame_handler(EXCEPTION_RECORD *rec, ULONG64 frame,
} }
} }
find_catch_block(rec, NULL, frame, dispatch, descr, exc_type, orig_frame); find_catch_block(rec, context, NULL, frame, dispatch, descr, exc_type, orig_frame);
return ExceptionContinueSearch; return ExceptionContinueSearch;
} }

View File

@ -214,11 +214,11 @@ typedef struct
{ {
frame_info frame_info; frame_info frame_info;
EXCEPTION_RECORD *rec; EXCEPTION_RECORD *rec;
void *unk; CONTEXT *context;
} cxx_frame_info; } cxx_frame_info;
frame_info* __cdecl _CreateFrameInfo(frame_info *fi, void *obj); frame_info* __cdecl _CreateFrameInfo(frame_info *fi, void *obj);
BOOL __cdecl __CxxRegisterExceptionObject(EXCEPTION_RECORD**, cxx_frame_info*); BOOL __cdecl __CxxRegisterExceptionObject(EXCEPTION_POINTERS*, cxx_frame_info*);
void __cdecl __CxxUnregisterExceptionObject(cxx_frame_info*, BOOL); void __cdecl __CxxUnregisterExceptionObject(cxx_frame_info*, BOOL);
void CDECL __DestructExceptionObject(EXCEPTION_RECORD*); void CDECL __DestructExceptionObject(EXCEPTION_RECORD*);
@ -259,6 +259,7 @@ struct __thread_data {
void *unk6[3]; void *unk6[3];
int unk7; int unk7;
EXCEPTION_RECORD *exc_record; EXCEPTION_RECORD *exc_record;
CONTEXT *ctx_record;
frame_info *frame_info_head; frame_info *frame_info_head;
void *unk8[6]; void *unk8[6];
LCID cached_lcid; LCID cached_lcid;

View File

@ -83,7 +83,7 @@
@ stub __conio_common_vcwscanf @ stub __conio_common_vcwscanf
@ cdecl -arch=i386 __control87_2(long long ptr ptr) @ cdecl -arch=i386 __control87_2(long long ptr ptr)
@ cdecl __current_exception() @ cdecl __current_exception()
@ stub __current_exception_context @ cdecl __current_exception_context()
@ cdecl __daylight() MSVCRT___p__daylight @ cdecl __daylight() MSVCRT___p__daylight
@ stub __dcrt_get_wide_environment_from_os @ stub __dcrt_get_wide_environment_from_os
@ stub __dcrt_initial_narrow_environment @ stub __dcrt_initial_narrow_environment

View File

@ -31,7 +31,7 @@
@ cdecl __RTtypeid(ptr) ucrtbase.__RTtypeid @ cdecl __RTtypeid(ptr) ucrtbase.__RTtypeid
@ stub __TypeMatch @ stub __TypeMatch
@ cdecl __current_exception() ucrtbase.__current_exception @ cdecl __current_exception() ucrtbase.__current_exception
@ stub __current_exception_context @ cdecl __current_exception_context() ucrtbase.__current_exception_context
@ cdecl -arch=i386,x86_64,arm,arm64 -norelay __intrinsic_setjmp(ptr) ucrtbase.__intrinsic_setjmp @ cdecl -arch=i386,x86_64,arm,arm64 -norelay __intrinsic_setjmp(ptr) ucrtbase.__intrinsic_setjmp
@ cdecl -arch=x86_64,arm64 -norelay __intrinsic_setjmpex(ptr ptr) ucrtbase.__intrinsic_setjmpex @ cdecl -arch=x86_64,arm64 -norelay __intrinsic_setjmpex(ptr ptr) ucrtbase.__intrinsic_setjmpex
@ stub __processing_throw @ stub __processing_throw