msvcr80: Use Cxx(Un)RegisterExceptionObject helpers in i386 nested exception handler.
Signed-off-by: Piotr Caban <piotr@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
8348d4b40e
commit
2296261600
|
@ -4,7 +4,7 @@
|
||||||
@ cdecl _FindAndUnlinkFrame(ptr) ucrtbase._FindAndUnlinkFrame
|
@ cdecl _FindAndUnlinkFrame(ptr) ucrtbase._FindAndUnlinkFrame
|
||||||
@ stub _GetImageBase
|
@ stub _GetImageBase
|
||||||
@ stub _GetThrowImageBase
|
@ stub _GetThrowImageBase
|
||||||
@ cdecl -arch=i386,x86_64,arm _IsExceptionObjectToBeDestroyed(ptr) ucrtbase._IsExceptionObjectToBeDestroyed
|
@ cdecl _IsExceptionObjectToBeDestroyed(ptr) ucrtbase._IsExceptionObjectToBeDestroyed
|
||||||
@ stub _NLG_Dispatch2
|
@ stub _NLG_Dispatch2
|
||||||
@ stub _NLG_Return
|
@ stub _NLG_Return
|
||||||
@ stub _NLG_Return2
|
@ stub _NLG_Return2
|
||||||
|
|
|
@ -530,7 +530,7 @@
|
||||||
@ cdecl _Getmonths()
|
@ cdecl _Getmonths()
|
||||||
@ cdecl _Gettnames()
|
@ cdecl _Gettnames()
|
||||||
@ extern _HUGE MSVCRT__HUGE
|
@ extern _HUGE MSVCRT__HUGE
|
||||||
@ cdecl -arch=i386,x86_64,arm _IsExceptionObjectToBeDestroyed(ptr)
|
@ cdecl _IsExceptionObjectToBeDestroyed(ptr)
|
||||||
@ stub _NLG_Dispatch2
|
@ stub _NLG_Dispatch2
|
||||||
@ stub _NLG_Return
|
@ stub _NLG_Return
|
||||||
@ stub _NLG_Return2
|
@ stub _NLG_Return2
|
||||||
|
|
|
@ -853,7 +853,7 @@
|
||||||
@ cdecl _Getmonths()
|
@ cdecl _Getmonths()
|
||||||
@ cdecl _Gettnames()
|
@ cdecl _Gettnames()
|
||||||
@ extern _HUGE MSVCRT__HUGE
|
@ extern _HUGE MSVCRT__HUGE
|
||||||
@ cdecl -arch=i386,x86_64,arm _IsExceptionObjectToBeDestroyed(ptr)
|
@ cdecl _IsExceptionObjectToBeDestroyed(ptr)
|
||||||
@ stub _Lock_shared_ptr_spin_lock
|
@ stub _Lock_shared_ptr_spin_lock
|
||||||
@ stub -arch=i386 _NLG_Dispatch2
|
@ stub -arch=i386 _NLG_Dispatch2
|
||||||
@ stub -arch=arm,win64 __NLG_Dispatch2
|
@ stub -arch=arm,win64 __NLG_Dispatch2
|
||||||
|
|
|
@ -837,7 +837,7 @@
|
||||||
@ cdecl _Getmonths()
|
@ cdecl _Getmonths()
|
||||||
@ cdecl _Gettnames()
|
@ cdecl _Gettnames()
|
||||||
@ extern _HUGE MSVCRT__HUGE
|
@ extern _HUGE MSVCRT__HUGE
|
||||||
@ cdecl -arch=i386,x86_64,arm _IsExceptionObjectToBeDestroyed(ptr)
|
@ cdecl _IsExceptionObjectToBeDestroyed(ptr)
|
||||||
@ stub _LCbuild
|
@ stub _LCbuild
|
||||||
@ stub -arch=i386 _NLG_Dispatch2
|
@ stub -arch=i386 _NLG_Dispatch2
|
||||||
@ stub -arch=arm,win64 __NLG_Dispatch2
|
@ stub -arch=arm,win64 __NLG_Dispatch2
|
||||||
|
|
|
@ -831,7 +831,7 @@
|
||||||
@ cdecl _Getmonths() msvcr120._Getmonths
|
@ cdecl _Getmonths() msvcr120._Getmonths
|
||||||
@ cdecl _Gettnames() msvcr120._Gettnames
|
@ cdecl _Gettnames() msvcr120._Gettnames
|
||||||
@ extern _HUGE msvcr120._HUGE
|
@ extern _HUGE msvcr120._HUGE
|
||||||
@ cdecl -arch=i386,x86_64,arm _IsExceptionObjectToBeDestroyed(ptr) msvcr120._IsExceptionObjectToBeDestroyed
|
@ cdecl _IsExceptionObjectToBeDestroyed(ptr) msvcr120._IsExceptionObjectToBeDestroyed
|
||||||
@ stub _LCbuild
|
@ stub _LCbuild
|
||||||
@ stub -arch=i386 _NLG_Dispatch2
|
@ stub -arch=i386 _NLG_Dispatch2
|
||||||
@ stub -arch=arm,win64 __NLG_Dispatch2
|
@ stub -arch=arm,win64 __NLG_Dispatch2
|
||||||
|
|
|
@ -162,7 +162,7 @@
|
||||||
@ cdecl _Getmonths()
|
@ cdecl _Getmonths()
|
||||||
@ cdecl _Gettnames()
|
@ cdecl _Gettnames()
|
||||||
@ extern _HUGE MSVCRT__HUGE
|
@ extern _HUGE MSVCRT__HUGE
|
||||||
@ cdecl -arch=i386,x86_64,arm _IsExceptionObjectToBeDestroyed(ptr)
|
@ cdecl _IsExceptionObjectToBeDestroyed(ptr)
|
||||||
@ stub -arch=i386 _NLG_Dispatch2
|
@ stub -arch=i386 _NLG_Dispatch2
|
||||||
@ stub -arch=arm,win64 __NLG_Dispatch2
|
@ stub -arch=arm,win64 __NLG_Dispatch2
|
||||||
@ stub -arch=i386 _NLG_Return
|
@ stub -arch=i386 _NLG_Return
|
||||||
|
|
|
@ -157,7 +157,7 @@
|
||||||
@ cdecl _Getmonths()
|
@ cdecl _Getmonths()
|
||||||
@ cdecl _Gettnames()
|
@ cdecl _Gettnames()
|
||||||
@ extern _HUGE MSVCRT__HUGE
|
@ extern _HUGE MSVCRT__HUGE
|
||||||
@ cdecl -arch=i386,x86_64,arm _IsExceptionObjectToBeDestroyed(ptr)
|
@ cdecl _IsExceptionObjectToBeDestroyed(ptr)
|
||||||
@ stub _NLG_Dispatch2
|
@ stub _NLG_Dispatch2
|
||||||
@ stub _NLG_Return
|
@ stub _NLG_Return
|
||||||
@ stub _NLG_Return2
|
@ stub _NLG_Return2
|
||||||
|
|
|
@ -372,6 +372,24 @@ void CDECL _FindAndUnlinkFrame(frame_info *fi)
|
||||||
ERR("frame not found, native crashes in this case\n");
|
ERR("frame not found, native crashes in this case\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* _IsExceptionObjectToBeDestroyed (MSVCR80.@)
|
||||||
|
*/
|
||||||
|
BOOL __cdecl _IsExceptionObjectToBeDestroyed(const void *obj)
|
||||||
|
{
|
||||||
|
frame_info *cur;
|
||||||
|
|
||||||
|
TRACE( "%p\n", obj );
|
||||||
|
|
||||||
|
for (cur = msvcrt_get_thread_data()->frame_info_head; cur; cur = cur->next)
|
||||||
|
{
|
||||||
|
if (cur->object == obj)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* __DestructExceptionObject (MSVCRT.@)
|
* __DestructExceptionObject (MSVCRT.@)
|
||||||
*/
|
*/
|
||||||
|
@ -424,13 +442,14 @@ void CDECL __CxxUnregisterExceptionObject(cxx_frame_info *frame_info, BOOL in_us
|
||||||
{
|
{
|
||||||
thread_data_t *data = msvcrt_get_thread_data();
|
thread_data_t *data = msvcrt_get_thread_data();
|
||||||
|
|
||||||
FIXME("(%p) semi-stub\n", frame_info);
|
TRACE("(%p)\n", frame_info);
|
||||||
|
|
||||||
if(frame_info->rec == (void*)-1)
|
if(frame_info->rec == (void*)-1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_FindAndUnlinkFrame(&frame_info->frame_info);
|
_FindAndUnlinkFrame(&frame_info->frame_info);
|
||||||
if(data->exc_record->ExceptionCode == CXX_EXCEPTION && !in_use) /* FIXME: use _IsExceptionObjectToBeDestroyed here */
|
if(data->exc_record->ExceptionCode == CXX_EXCEPTION && !in_use
|
||||||
|
&& _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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,15 +74,6 @@ int CDECL __CxxExceptionFilter( PEXCEPTION_POINTERS ptrs,
|
||||||
return EXCEPTION_CONTINUE_SEARCH;
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* _IsExceptionObjectToBeDestroyed (MSVCR80.@)
|
|
||||||
*/
|
|
||||||
BOOL __cdecl _IsExceptionObjectToBeDestroyed(const void *obj)
|
|
||||||
{
|
|
||||||
FIXME("%p not implemented\n", obj);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* __CxxFrameHandler (MSVCRT.@)
|
* __CxxFrameHandler (MSVCRT.@)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -131,7 +131,6 @@ DWORD CDECL cxx_frame_handler( PEXCEPTION_RECORD rec, cxx_exception_frame* frame
|
||||||
PCONTEXT context, EXCEPTION_REGISTRATION_RECORD** dispatch,
|
PCONTEXT context, EXCEPTION_REGISTRATION_RECORD** dispatch,
|
||||||
const cxx_function_descr *descr,
|
const cxx_function_descr *descr,
|
||||||
EXCEPTION_REGISTRATION_RECORD* nested_frame, int nested_trylevel );
|
EXCEPTION_REGISTRATION_RECORD* nested_frame, int nested_trylevel );
|
||||||
BOOL __cdecl _IsExceptionObjectToBeDestroyed(const void*);
|
|
||||||
|
|
||||||
/* call a function with a given ebp */
|
/* call a function with a given ebp */
|
||||||
static inline void *call_ebp_func( void *func, void *ebp )
|
static inline void *call_ebp_func( void *func, void *ebp )
|
||||||
|
@ -350,11 +349,10 @@ static void cxx_local_unwind( cxx_exception_frame* frame, const cxx_function_des
|
||||||
struct catch_func_nested_frame
|
struct catch_func_nested_frame
|
||||||
{
|
{
|
||||||
EXCEPTION_REGISTRATION_RECORD frame; /* standard exception frame */
|
EXCEPTION_REGISTRATION_RECORD frame; /* standard exception frame */
|
||||||
EXCEPTION_RECORD *prev_rec; /* previous record to restore in thread data */
|
|
||||||
cxx_exception_frame *cxx_frame; /* frame of parent exception */
|
cxx_exception_frame *cxx_frame; /* frame of parent exception */
|
||||||
const cxx_function_descr *descr; /* descriptor of parent exception */
|
const cxx_function_descr *descr; /* descriptor of parent exception */
|
||||||
int trylevel; /* current try level */
|
int trylevel; /* current try level */
|
||||||
EXCEPTION_RECORD *rec; /* rec associated with frame */
|
cxx_frame_info frame_info;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* handler for exceptions happening while calling a catch function */
|
/* handler for exceptions happening while calling a catch function */
|
||||||
|
@ -362,19 +360,10 @@ static DWORD catch_function_nested_handler( EXCEPTION_RECORD *rec, EXCEPTION_REG
|
||||||
CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **dispatcher )
|
CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **dispatcher )
|
||||||
{
|
{
|
||||||
struct catch_func_nested_frame *nested_frame = (struct catch_func_nested_frame *)frame;
|
struct catch_func_nested_frame *nested_frame = (struct catch_func_nested_frame *)frame;
|
||||||
PEXCEPTION_RECORD prev_rec = nested_frame->rec;
|
|
||||||
|
|
||||||
if (rec->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND))
|
if (rec->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND))
|
||||||
{
|
{
|
||||||
if (prev_rec->ExceptionCode == CXX_EXCEPTION)
|
__CxxUnregisterExceptionObject(&nested_frame->frame_info, FALSE);
|
||||||
{
|
|
||||||
void *object = (void*)prev_rec->ExceptionInformation[1];
|
|
||||||
cxx_exception_type *info = (cxx_exception_type*) prev_rec->ExceptionInformation[2];
|
|
||||||
if (info && info->destructor && _IsExceptionObjectToBeDestroyed(object))
|
|
||||||
call_dtor( info->destructor, object);
|
|
||||||
}
|
|
||||||
|
|
||||||
msvcrt_get_thread_data()->exc_record = nested_frame->prev_rec;
|
|
||||||
return ExceptionContinueSearch;
|
return ExceptionContinueSearch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,6 +371,8 @@ static DWORD catch_function_nested_handler( EXCEPTION_RECORD *rec, EXCEPTION_REG
|
||||||
|
|
||||||
if(rec->ExceptionCode == CXX_EXCEPTION)
|
if(rec->ExceptionCode == CXX_EXCEPTION)
|
||||||
{
|
{
|
||||||
|
PEXCEPTION_RECORD prev_rec = msvcrt_get_thread_data()->exc_record;
|
||||||
|
|
||||||
if((rec->ExceptionInformation[1] == 0 && rec->ExceptionInformation[2] == 0) ||
|
if((rec->ExceptionInformation[1] == 0 && rec->ExceptionInformation[2] == 0) ||
|
||||||
(prev_rec->ExceptionCode == CXX_EXCEPTION &&
|
(prev_rec->ExceptionCode == CXX_EXCEPTION &&
|
||||||
rec->ExceptionInformation[1] == prev_rec->ExceptionInformation[1] &&
|
rec->ExceptionInformation[1] == prev_rec->ExceptionInformation[1] &&
|
||||||
|
@ -408,40 +399,6 @@ static DWORD catch_function_nested_handler( EXCEPTION_RECORD *rec, EXCEPTION_REG
|
||||||
nested_frame->trylevel );
|
nested_frame->trylevel );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* _IsExceptionObjectToBeDestroyed (MSVCR80.@)
|
|
||||||
*/
|
|
||||||
BOOL __cdecl _IsExceptionObjectToBeDestroyed(const void *obj)
|
|
||||||
{
|
|
||||||
EXCEPTION_REGISTRATION_RECORD *reg = NtCurrentTeb()->Tib.ExceptionList;
|
|
||||||
frame_info *cur;
|
|
||||||
|
|
||||||
TRACE( "%p\n", obj );
|
|
||||||
|
|
||||||
while (reg != (EXCEPTION_REGISTRATION_RECORD*)-1)
|
|
||||||
{
|
|
||||||
if (reg->Handler == catch_function_nested_handler)
|
|
||||||
{
|
|
||||||
EXCEPTION_RECORD *rec = ((struct catch_func_nested_frame*)reg)->rec;
|
|
||||||
|
|
||||||
if(!(rec->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND))
|
|
||||||
&& rec->ExceptionCode == CXX_EXCEPTION && rec->NumberParameters == 3
|
|
||||||
&& rec->ExceptionInformation[1] == (LONG_PTR)obj)
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
reg = reg->Prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (cur = msvcrt_get_thread_data()->frame_info_head; cur; cur = cur->next)
|
|
||||||
{
|
|
||||||
if (cur->object == obj)
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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, cxx_exception_frame *frame,
|
||||||
|
@ -454,7 +411,6 @@ static inline void call_catch_block( PEXCEPTION_RECORD rec, cxx_exception_frame
|
||||||
void *addr, *object = (void *)rec->ExceptionInformation[1];
|
void *addr, *object = (void *)rec->ExceptionInformation[1];
|
||||||
struct catch_func_nested_frame nested_frame;
|
struct catch_func_nested_frame nested_frame;
|
||||||
int trylevel = frame->trylevel;
|
int trylevel = frame->trylevel;
|
||||||
thread_data_t *thread_data = msvcrt_get_thread_data();
|
|
||||||
DWORD save_esp = ((DWORD*)frame)[-1];
|
DWORD save_esp = ((DWORD*)frame)[-1];
|
||||||
|
|
||||||
for (i = 0; i < descr->tryblock_count; i++)
|
for (i = 0; i < descr->tryblock_count; i++)
|
||||||
|
@ -502,21 +458,17 @@ static inline void call_catch_block( PEXCEPTION_RECORD rec, cxx_exception_frame
|
||||||
/* setup an exception block for nested exceptions */
|
/* setup an exception block for nested exceptions */
|
||||||
|
|
||||||
nested_frame.frame.Handler = catch_function_nested_handler;
|
nested_frame.frame.Handler = catch_function_nested_handler;
|
||||||
nested_frame.prev_rec = thread_data->exc_record;
|
|
||||||
nested_frame.cxx_frame = frame;
|
nested_frame.cxx_frame = frame;
|
||||||
nested_frame.descr = descr;
|
nested_frame.descr = descr;
|
||||||
nested_frame.trylevel = nested_trylevel + 1;
|
nested_frame.trylevel = nested_trylevel + 1;
|
||||||
nested_frame.rec = rec;
|
__CxxRegisterExceptionObject(&rec, &nested_frame.frame_info);
|
||||||
|
|
||||||
__wine_push_frame( &nested_frame.frame );
|
__wine_push_frame( &nested_frame.frame );
|
||||||
thread_data->exc_record = rec;
|
|
||||||
addr = call_ebp_func( catchblock->handler, &frame->ebp );
|
addr = call_ebp_func( catchblock->handler, &frame->ebp );
|
||||||
thread_data->exc_record = nested_frame.prev_rec;
|
|
||||||
__wine_pop_frame( &nested_frame.frame );
|
__wine_pop_frame( &nested_frame.frame );
|
||||||
|
|
||||||
((DWORD*)frame)[-1] = save_esp;
|
((DWORD*)frame)[-1] = save_esp;
|
||||||
if (info && info->destructor && _IsExceptionObjectToBeDestroyed(object))
|
__CxxUnregisterExceptionObject(&nested_frame.frame_info, FALSE);
|
||||||
call_dtor( info->destructor, object );
|
|
||||||
TRACE( "done, continuing at %p\n", addr );
|
TRACE( "done, continuing at %p\n", addr );
|
||||||
|
|
||||||
continue_after_catch( frame, addr );
|
continue_after_catch( frame, addr );
|
||||||
|
|
|
@ -71,15 +71,6 @@ int CDECL __CxxExceptionFilter( PEXCEPTION_POINTERS ptrs,
|
||||||
return EXCEPTION_CONTINUE_SEARCH;
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
|
||||||
* _IsExceptionObjectToBeDestroyed (MSVCR80.@)
|
|
||||||
*/
|
|
||||||
BOOL __cdecl _IsExceptionObjectToBeDestroyed(const void *obj)
|
|
||||||
{
|
|
||||||
FIXME ( "%p not implemented\n", obj );
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* __CxxFrameHandler (MSVCRT.@)
|
* __CxxFrameHandler (MSVCRT.@)
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -217,6 +217,9 @@ typedef struct
|
||||||
void *unk;
|
void *unk;
|
||||||
} cxx_frame_info;
|
} cxx_frame_info;
|
||||||
|
|
||||||
|
BOOL __cdecl __CxxRegisterExceptionObject(EXCEPTION_RECORD**, cxx_frame_info*);
|
||||||
|
void __cdecl __CxxUnregisterExceptionObject(cxx_frame_info*, BOOL);
|
||||||
|
|
||||||
/* TLS data */
|
/* TLS data */
|
||||||
extern DWORD msvcrt_tls_index DECLSPEC_HIDDEN;
|
extern DWORD msvcrt_tls_index DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
@ cdecl _Getdays()
|
@ cdecl _Getdays()
|
||||||
@ cdecl _Getmonths()
|
@ cdecl _Getmonths()
|
||||||
@ cdecl _Gettnames()
|
@ cdecl _Gettnames()
|
||||||
@ cdecl -arch=i386,x86_64,arm _IsExceptionObjectToBeDestroyed(ptr)
|
@ cdecl _IsExceptionObjectToBeDestroyed(ptr)
|
||||||
@ stub _LCbuild
|
@ stub _LCbuild
|
||||||
@ stub _LCmulcc
|
@ stub _LCmulcc
|
||||||
@ stub _LCmulcr
|
@ stub _LCmulcr
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
@ stdcall _CxxThrowException(long long) ucrtbase._CxxThrowException
|
@ stdcall _CxxThrowException(long long) ucrtbase._CxxThrowException
|
||||||
@ cdecl -arch=i386 -norelay _EH_prolog() ucrtbase._EH_prolog
|
@ cdecl -arch=i386 -norelay _EH_prolog() ucrtbase._EH_prolog
|
||||||
@ cdecl _FindAndUnlinkFrame(ptr) ucrtbase._FindAndUnlinkFrame
|
@ cdecl _FindAndUnlinkFrame(ptr) ucrtbase._FindAndUnlinkFrame
|
||||||
@ cdecl -arch=i386,x86_64,arm _IsExceptionObjectToBeDestroyed(ptr) ucrtbase._IsExceptionObjectToBeDestroyed
|
@ cdecl _IsExceptionObjectToBeDestroyed(ptr) ucrtbase._IsExceptionObjectToBeDestroyed
|
||||||
@ stub _NLG_Dispatch2
|
@ stub _NLG_Dispatch2
|
||||||
@ stub _NLG_Return
|
@ stub _NLG_Return
|
||||||
@ stub _NLG_Return2
|
@ stub _NLG_Return2
|
||||||
|
|
Loading…
Reference in New Issue