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
@ stub __TypeMatch
@ 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_initial_narrow_environment
@ stub __intrinsic_abnormal_termination

View File

@ -432,23 +432,24 @@ void CDECL __DestructExceptionObject(EXCEPTION_RECORD *rec)
/*********************************************************************
* __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();
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->unk = (void*)-1;
frame_info->context = (void*)-1;
return TRUE;
}
frame_info->rec = data->exc_record;
frame_info->unk = 0;
data->exc_record = *rec;
_CreateFrameInfo(&frame_info->frame_info, (void*)(*rec)->ExceptionInformation[1]);
frame_info->context = data->ctx_record;
data->exc_record = ep->ExceptionRecord;
data->ctx_record = ep->ContextRecord;
_CreateFrameInfo(&frame_info->frame_info, (void*)ep->ExceptionRecord->ExceptionInformation[1]);
return TRUE;
}
@ -469,6 +470,7 @@ void CDECL __CxxUnregisterExceptionObject(cxx_frame_info *frame_info, BOOL in_us
&& _IsExceptionObjectToBeDestroyed((void*)data->exc_record->ExceptionInformation[1]))
__DestructExceptionObject(data->exc_record);
data->exc_record = frame_info->rec;
data->ctx_record = frame_info->context;
}
struct __std_exception_data {
@ -517,4 +519,13 @@ void** CDECL __current_exception(void)
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 */

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 */
/* 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,
EXCEPTION_REGISTRATION_RECORD *catch_frame,
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();
nested_frame.frame_info.rec = data->exc_record;
nested_frame.frame_info.context = data->ctx_record;
data->exc_record = rec;
data->ctx_record = context;
/* call the catch block */
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];
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 );
__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;
}

View File

@ -352,15 +352,17 @@ static void* WINAPI call_catch_block(EXCEPTION_RECORD *rec)
const cxx_function_descr *descr = (void*)rec->ExceptionInformation[2];
EXCEPTION_RECORD *prev_rec = (void*)rec->ExceptionInformation[4];
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];
int *unwind_help = rva_to_ptr(descr->unwind_help, frame);
EXCEPTION_POINTERS ep = { prev_rec, context };
cxx_catch_ctx ctx;
void *ret_addr = NULL;
TRACE("calling handler %p\n", handler);
ctx.rethrow = FALSE;
__CxxRegisterExceptionObject(&prev_rec, &ctx.frame_info);
__CxxRegisterExceptionObject(&ep, &ctx.frame_info);
__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)
{
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;
}
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,
const cxx_function_descr *descr,
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);
const tryblock_info *in_catch;
EXCEPTION_RECORD catch_record;
CONTEXT context;
CONTEXT ctx;
UINT i, j;
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));
catch_record.ExceptionCode = STATUS_UNWIND_CONSOLIDATE;
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[1] = orig_frame;
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] =
(ULONG_PTR)rva_to_ptr(catchblock->handler, dispatch->ImageBase);
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];
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);
__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;
}

View File

@ -214,11 +214,11 @@ typedef struct
{
frame_info frame_info;
EXCEPTION_RECORD *rec;
void *unk;
CONTEXT *context;
} cxx_frame_info;
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 __DestructExceptionObject(EXCEPTION_RECORD*);
@ -259,6 +259,7 @@ struct __thread_data {
void *unk6[3];
int unk7;
EXCEPTION_RECORD *exc_record;
CONTEXT *ctx_record;
frame_info *frame_info_head;
void *unk8[6];
LCID cached_lcid;

View File

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

View File

@ -31,7 +31,7 @@
@ cdecl __RTtypeid(ptr) ucrtbase.__RTtypeid
@ stub __TypeMatch
@ 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=x86_64,arm64 -norelay __intrinsic_setjmpex(ptr ptr) ucrtbase.__intrinsic_setjmpex
@ stub __processing_throw