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:
parent
a9cf391bed
commit
f82af4d2bb
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue