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
|
||||
@ stub _GetImageBase
|
||||
@ stub _GetThrowImageBase
|
||||
@ cdecl -arch=i386,x86_64,arm _IsExceptionObjectToBeDestroyed(ptr) ucrtbase._IsExceptionObjectToBeDestroyed
|
||||
@ cdecl _IsExceptionObjectToBeDestroyed(ptr) ucrtbase._IsExceptionObjectToBeDestroyed
|
||||
@ stub _NLG_Dispatch2
|
||||
@ stub _NLG_Return
|
||||
@ stub _NLG_Return2
|
||||
|
|
|
@ -530,7 +530,7 @@
|
|||
@ cdecl _Getmonths()
|
||||
@ cdecl _Gettnames()
|
||||
@ extern _HUGE MSVCRT__HUGE
|
||||
@ cdecl -arch=i386,x86_64,arm _IsExceptionObjectToBeDestroyed(ptr)
|
||||
@ cdecl _IsExceptionObjectToBeDestroyed(ptr)
|
||||
@ stub _NLG_Dispatch2
|
||||
@ stub _NLG_Return
|
||||
@ stub _NLG_Return2
|
||||
|
|
|
@ -853,7 +853,7 @@
|
|||
@ cdecl _Getmonths()
|
||||
@ cdecl _Gettnames()
|
||||
@ extern _HUGE MSVCRT__HUGE
|
||||
@ cdecl -arch=i386,x86_64,arm _IsExceptionObjectToBeDestroyed(ptr)
|
||||
@ cdecl _IsExceptionObjectToBeDestroyed(ptr)
|
||||
@ stub _Lock_shared_ptr_spin_lock
|
||||
@ stub -arch=i386 _NLG_Dispatch2
|
||||
@ stub -arch=arm,win64 __NLG_Dispatch2
|
||||
|
|
|
@ -837,7 +837,7 @@
|
|||
@ cdecl _Getmonths()
|
||||
@ cdecl _Gettnames()
|
||||
@ extern _HUGE MSVCRT__HUGE
|
||||
@ cdecl -arch=i386,x86_64,arm _IsExceptionObjectToBeDestroyed(ptr)
|
||||
@ cdecl _IsExceptionObjectToBeDestroyed(ptr)
|
||||
@ stub _LCbuild
|
||||
@ stub -arch=i386 _NLG_Dispatch2
|
||||
@ stub -arch=arm,win64 __NLG_Dispatch2
|
||||
|
|
|
@ -831,7 +831,7 @@
|
|||
@ cdecl _Getmonths() msvcr120._Getmonths
|
||||
@ cdecl _Gettnames() msvcr120._Gettnames
|
||||
@ extern _HUGE msvcr120._HUGE
|
||||
@ cdecl -arch=i386,x86_64,arm _IsExceptionObjectToBeDestroyed(ptr) msvcr120._IsExceptionObjectToBeDestroyed
|
||||
@ cdecl _IsExceptionObjectToBeDestroyed(ptr) msvcr120._IsExceptionObjectToBeDestroyed
|
||||
@ stub _LCbuild
|
||||
@ stub -arch=i386 _NLG_Dispatch2
|
||||
@ stub -arch=arm,win64 __NLG_Dispatch2
|
||||
|
|
|
@ -162,7 +162,7 @@
|
|||
@ cdecl _Getmonths()
|
||||
@ cdecl _Gettnames()
|
||||
@ extern _HUGE MSVCRT__HUGE
|
||||
@ cdecl -arch=i386,x86_64,arm _IsExceptionObjectToBeDestroyed(ptr)
|
||||
@ cdecl _IsExceptionObjectToBeDestroyed(ptr)
|
||||
@ stub -arch=i386 _NLG_Dispatch2
|
||||
@ stub -arch=arm,win64 __NLG_Dispatch2
|
||||
@ stub -arch=i386 _NLG_Return
|
||||
|
|
|
@ -157,7 +157,7 @@
|
|||
@ cdecl _Getmonths()
|
||||
@ cdecl _Gettnames()
|
||||
@ extern _HUGE MSVCRT__HUGE
|
||||
@ cdecl -arch=i386,x86_64,arm _IsExceptionObjectToBeDestroyed(ptr)
|
||||
@ cdecl _IsExceptionObjectToBeDestroyed(ptr)
|
||||
@ stub _NLG_Dispatch2
|
||||
@ stub _NLG_Return
|
||||
@ stub _NLG_Return2
|
||||
|
|
|
@ -372,6 +372,24 @@ void CDECL _FindAndUnlinkFrame(frame_info *fi)
|
|||
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.@)
|
||||
*/
|
||||
|
@ -424,13 +442,14 @@ void CDECL __CxxUnregisterExceptionObject(cxx_frame_info *frame_info, BOOL in_us
|
|||
{
|
||||
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)
|
||||
return;
|
||||
|
||||
_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);
|
||||
data->exc_record = frame_info->rec;
|
||||
}
|
||||
|
|
|
@ -74,15 +74,6 @@ int CDECL __CxxExceptionFilter( PEXCEPTION_POINTERS ptrs,
|
|||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* _IsExceptionObjectToBeDestroyed (MSVCR80.@)
|
||||
*/
|
||||
BOOL __cdecl _IsExceptionObjectToBeDestroyed(const void *obj)
|
||||
{
|
||||
FIXME("%p not implemented\n", obj);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* __CxxFrameHandler (MSVCRT.@)
|
||||
*/
|
||||
|
|
|
@ -131,7 +131,6 @@ DWORD CDECL cxx_frame_handler( PEXCEPTION_RECORD rec, cxx_exception_frame* frame
|
|||
PCONTEXT context, EXCEPTION_REGISTRATION_RECORD** dispatch,
|
||||
const cxx_function_descr *descr,
|
||||
EXCEPTION_REGISTRATION_RECORD* nested_frame, int nested_trylevel );
|
||||
BOOL __cdecl _IsExceptionObjectToBeDestroyed(const void*);
|
||||
|
||||
/* call a function with a given 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
|
||||
{
|
||||
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 */
|
||||
const cxx_function_descr *descr; /* descriptor of parent exception */
|
||||
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 */
|
||||
|
@ -362,19 +360,10 @@ static DWORD catch_function_nested_handler( EXCEPTION_RECORD *rec, EXCEPTION_REG
|
|||
CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **dispatcher )
|
||||
{
|
||||
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 (prev_rec->ExceptionCode == CXX_EXCEPTION)
|
||||
{
|
||||
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;
|
||||
__CxxUnregisterExceptionObject(&nested_frame->frame_info, FALSE);
|
||||
return ExceptionContinueSearch;
|
||||
}
|
||||
|
||||
|
@ -382,6 +371,8 @@ static DWORD catch_function_nested_handler( EXCEPTION_RECORD *rec, EXCEPTION_REG
|
|||
|
||||
if(rec->ExceptionCode == CXX_EXCEPTION)
|
||||
{
|
||||
PEXCEPTION_RECORD prev_rec = msvcrt_get_thread_data()->exc_record;
|
||||
|
||||
if((rec->ExceptionInformation[1] == 0 && rec->ExceptionInformation[2] == 0) ||
|
||||
(prev_rec->ExceptionCode == CXX_EXCEPTION &&
|
||||
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 );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* _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 */
|
||||
/* 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,
|
||||
|
@ -454,7 +411,6 @@ static inline void call_catch_block( PEXCEPTION_RECORD rec, cxx_exception_frame
|
|||
void *addr, *object = (void *)rec->ExceptionInformation[1];
|
||||
struct catch_func_nested_frame nested_frame;
|
||||
int trylevel = frame->trylevel;
|
||||
thread_data_t *thread_data = msvcrt_get_thread_data();
|
||||
DWORD save_esp = ((DWORD*)frame)[-1];
|
||||
|
||||
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 */
|
||||
|
||||
nested_frame.frame.Handler = catch_function_nested_handler;
|
||||
nested_frame.prev_rec = thread_data->exc_record;
|
||||
nested_frame.cxx_frame = frame;
|
||||
nested_frame.descr = descr;
|
||||
nested_frame.trylevel = nested_trylevel + 1;
|
||||
nested_frame.rec = rec;
|
||||
__CxxRegisterExceptionObject(&rec, &nested_frame.frame_info);
|
||||
|
||||
__wine_push_frame( &nested_frame.frame );
|
||||
thread_data->exc_record = rec;
|
||||
addr = call_ebp_func( catchblock->handler, &frame->ebp );
|
||||
thread_data->exc_record = nested_frame.prev_rec;
|
||||
__wine_pop_frame( &nested_frame.frame );
|
||||
|
||||
((DWORD*)frame)[-1] = save_esp;
|
||||
if (info && info->destructor && _IsExceptionObjectToBeDestroyed(object))
|
||||
call_dtor( info->destructor, object );
|
||||
__CxxUnregisterExceptionObject(&nested_frame.frame_info, FALSE);
|
||||
TRACE( "done, continuing at %p\n", addr );
|
||||
|
||||
continue_after_catch( frame, addr );
|
||||
|
|
|
@ -71,15 +71,6 @@ int CDECL __CxxExceptionFilter( PEXCEPTION_POINTERS ptrs,
|
|||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* _IsExceptionObjectToBeDestroyed (MSVCR80.@)
|
||||
*/
|
||||
BOOL __cdecl _IsExceptionObjectToBeDestroyed(const void *obj)
|
||||
{
|
||||
FIXME ( "%p not implemented\n", obj );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* __CxxFrameHandler (MSVCRT.@)
|
||||
*/
|
||||
|
|
|
@ -217,6 +217,9 @@ typedef struct
|
|||
void *unk;
|
||||
} cxx_frame_info;
|
||||
|
||||
BOOL __cdecl __CxxRegisterExceptionObject(EXCEPTION_RECORD**, cxx_frame_info*);
|
||||
void __cdecl __CxxUnregisterExceptionObject(cxx_frame_info*, BOOL);
|
||||
|
||||
/* TLS data */
|
||||
extern DWORD msvcrt_tls_index DECLSPEC_HIDDEN;
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
@ cdecl _Getdays()
|
||||
@ cdecl _Getmonths()
|
||||
@ cdecl _Gettnames()
|
||||
@ cdecl -arch=i386,x86_64,arm _IsExceptionObjectToBeDestroyed(ptr)
|
||||
@ cdecl _IsExceptionObjectToBeDestroyed(ptr)
|
||||
@ stub _LCbuild
|
||||
@ stub _LCmulcc
|
||||
@ stub _LCmulcr
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
@ stdcall _CxxThrowException(long long) ucrtbase._CxxThrowException
|
||||
@ cdecl -arch=i386 -norelay _EH_prolog() ucrtbase._EH_prolog
|
||||
@ 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_Return
|
||||
@ stub _NLG_Return2
|
||||
|
|
Loading…
Reference in New Issue