ntdll: Add a raise_status function and avoid exporting __regs_RtlRaiseException.

This commit is contained in:
Alexandre Julliard 2009-04-10 13:09:06 +02:00
parent c709adcf16
commit 48199d7074
6 changed files with 98 additions and 68 deletions

View File

@ -321,7 +321,7 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *context )
*
* Implementation of NtRaiseException.
*/
static NTSTATUS raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_chance )
NTSTATUS raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_chance )
{
NTSTATUS status;
@ -410,21 +410,30 @@ NTSTATUS WINAPI NtRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL
}
/*******************************************************************
* raise_status
*
* Implementation of RtlRaiseStatus with a specific exception record.
*/
void raise_status( NTSTATUS status, EXCEPTION_RECORD *rec )
{
EXCEPTION_RECORD ExceptionRec;
ExceptionRec.ExceptionCode = status;
ExceptionRec.ExceptionFlags = EH_NONCONTINUABLE;
ExceptionRec.ExceptionRecord = rec;
ExceptionRec.NumberParameters = 0;
for (;;) RtlRaiseException( &ExceptionRec ); /* never returns */
}
/***********************************************************************
* RtlRaiseException (NTDLL.@)
*/
void WINAPI __regs_RtlRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context )
{
NTSTATUS status = raise_exception( rec, context, TRUE );
if (status != STATUS_SUCCESS)
{
EXCEPTION_RECORD newrec;
newrec.ExceptionCode = status;
newrec.ExceptionFlags = EH_NONCONTINUABLE;
newrec.ExceptionRecord = rec;
newrec.NumberParameters = 0;
RtlRaiseException( &newrec ); /* never returns */
}
if (status != STATUS_SUCCESS) raise_status( status, rec );
}
/**********************************************************************/
@ -447,7 +456,7 @@ void WINAPI RtlRaiseException( EXCEPTION_RECORD *rec )
void WINAPI __regs_RtlUnwind( EXCEPTION_REGISTRATION_RECORD* pEndFrame, PVOID unusedEip,
PEXCEPTION_RECORD pRecord, PVOID returnEax, CONTEXT *context )
{
EXCEPTION_RECORD record, newrec;
EXCEPTION_RECORD record;
EXCEPTION_REGISTRATION_RECORD *frame, *dispatch;
DWORD res;
@ -476,23 +485,12 @@ void WINAPI __regs_RtlUnwind( EXCEPTION_REGISTRATION_RECORD* pEndFrame, PVOID un
{
/* Check frame address */
if (pEndFrame && (frame > pEndFrame))
{
newrec.ExceptionCode = STATUS_INVALID_UNWIND_TARGET;
newrec.ExceptionFlags = EH_NONCONTINUABLE;
newrec.ExceptionRecord = pRecord;
newrec.NumberParameters = 0;
RtlRaiseException( &newrec ); /* never returns */
}
raise_status( STATUS_INVALID_UNWIND_TARGET, pRecord );
if (((void*)frame < NtCurrentTeb()->Tib.StackLimit) ||
((void*)(frame+1) > NtCurrentTeb()->Tib.StackBase) ||
(UINT_PTR)frame & 3)
{
newrec.ExceptionCode = STATUS_BAD_STACK;
newrec.ExceptionFlags = EH_NONCONTINUABLE;
newrec.ExceptionRecord = pRecord;
newrec.NumberParameters = 0;
RtlRaiseException( &newrec ); /* never returns */
}
raise_status( STATUS_BAD_STACK, pRecord );
/* Call handler */
TRACE( "calling handler at %p code=%x flags=%x\n",
@ -508,11 +506,7 @@ void WINAPI __regs_RtlUnwind( EXCEPTION_REGISTRATION_RECORD* pEndFrame, PVOID un
frame = dispatch;
break;
default:
newrec.ExceptionCode = STATUS_INVALID_DISPOSITION;
newrec.ExceptionFlags = EH_NONCONTINUABLE;
newrec.ExceptionRecord = pRecord;
newrec.NumberParameters = 0;
RtlRaiseException( &newrec ); /* never returns */
raise_status( STATUS_INVALID_DISPOSITION, pRecord );
break;
}
frame = __wine_pop_frame( frame );
@ -541,13 +535,7 @@ void WINAPI RtlUnwind( PVOID pEndFrame, PVOID unusedEip,
*/
void WINAPI RtlRaiseStatus( NTSTATUS status )
{
EXCEPTION_RECORD ExceptionRec;
ExceptionRec.ExceptionCode = status;
ExceptionRec.ExceptionFlags = EH_NONCONTINUABLE;
ExceptionRec.ExceptionRecord = NULL;
ExceptionRec.NumberParameters = 0;
RtlRaiseException( &ExceptionRec );
raise_status( status, NULL );
}

View File

@ -41,7 +41,8 @@ struct drive_info
/* exceptions */
extern void wait_suspend( CONTEXT *context );
extern void WINAPI __regs_RtlRaiseException( PEXCEPTION_RECORD, PCONTEXT );
extern NTSTATUS raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_chance );
extern void raise_status( NTSTATUS status, EXCEPTION_RECORD *rec ) DECLSPEC_NORETURN;
extern void set_cpu_context( const CONTEXT *context );
extern void copy_context( CONTEXT *to, const CONTEXT *from, DWORD flags );
extern NTSTATUS context_to_server( context_t *to, const CONTEXT *from );

View File

@ -629,7 +629,7 @@ static void merge_vm86_pending_flags( EXCEPTION_RECORD *rec )
vcontext.EFlags &= ~VIP_FLAG;
get_vm86_teb_info()->vm86_pending = 0;
__regs_RtlRaiseException( rec, &vcontext );
raise_exception( rec, &vcontext, TRUE );
restore_vm86_context( &vcontext, vm86 );
check_pending = TRUE;
@ -1470,6 +1470,8 @@ static inline DWORD get_fpu_code( const CONTEXT *context )
*/
static void WINAPI raise_segv_exception( EXCEPTION_RECORD *rec, CONTEXT *context )
{
NTSTATUS status;
switch(rec->ExceptionCode)
{
case EXCEPTION_ACCESS_VIOLATION:
@ -1492,7 +1494,8 @@ static void WINAPI raise_segv_exception( EXCEPTION_RECORD *rec, CONTEXT *context
}
break;
}
__regs_RtlRaiseException( rec, context );
status = NtRaiseException( rec, context, TRUE );
if (status) raise_status( status, rec );
done:
NtSetContextThread( GetCurrentThread(), context );
}
@ -1503,6 +1506,8 @@ done:
*/
static void WINAPI raise_trap_exception( EXCEPTION_RECORD *rec, CONTEXT *context )
{
NTSTATUS status;
if (rec->ExceptionCode == EXCEPTION_SINGLE_STEP)
{
struct ntdll_thread_regs * const regs = ntdll_get_thread_regs();
@ -1522,20 +1527,22 @@ static void WINAPI raise_trap_exception( EXCEPTION_RECORD *rec, CONTEXT *context
context->EFlags &= ~0x100; /* clear single-step flag */
}
__regs_RtlRaiseException( rec, context );
NtSetContextThread( GetCurrentThread(), context );
status = NtRaiseException( rec, context, TRUE );
if (status) raise_status( status, rec );
}
/**********************************************************************
* raise_exception
* raise_generic_exception
*
* Generic raise function for exceptions that don't need special treatment.
*/
static void WINAPI raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context )
static void WINAPI raise_generic_exception( EXCEPTION_RECORD *rec, CONTEXT *context )
{
__regs_RtlRaiseException( rec, context );
NtSetContextThread( GetCurrentThread(), context );
NTSTATUS status;
status = NtRaiseException( rec, context, TRUE );
if (status) raise_status( status, rec );
}
@ -1564,7 +1571,7 @@ static void WINAPI raise_vm86_sti_exception( EXCEPTION_RECORD *rec, CONTEXT *con
{
/* Executing DPMI code and virtual interrupts are enabled. */
get_vm86_teb_info()->vm86_pending = 0;
__regs_RtlRaiseException( rec, context );
NtRaiseException( rec, context, TRUE );
}
done:
NtSetContextThread( GetCurrentThread(), context );
@ -1705,7 +1712,7 @@ static void fpe_handler( int signal, siginfo_t *siginfo, void *sigcontext )
{
CONTEXT *win_context;
SIGCONTEXT *context = sigcontext;
EXCEPTION_RECORD *rec = setup_exception( context, raise_exception );
EXCEPTION_RECORD *rec = setup_exception( context, raise_generic_exception );
win_context = get_exception_context( rec );
@ -1756,7 +1763,7 @@ static void int_handler( int signal, siginfo_t *siginfo, void *sigcontext )
init_handler( sigcontext, &fs, &gs );
if (!dispatch_signal(SIGINT))
{
EXCEPTION_RECORD *rec = setup_exception( sigcontext, raise_exception );
EXCEPTION_RECORD *rec = setup_exception( sigcontext, raise_generic_exception );
rec->ExceptionCode = CONTROL_C_EXIT;
}
}
@ -1768,7 +1775,7 @@ static void int_handler( int signal, siginfo_t *siginfo, void *sigcontext )
*/
static void abrt_handler( int signal, siginfo_t *siginfo, void *sigcontext )
{
EXCEPTION_RECORD *rec = setup_exception( sigcontext, raise_exception );
EXCEPTION_RECORD *rec = setup_exception( sigcontext, raise_generic_exception );
rec->ExceptionCode = EXCEPTION_WINE_ASSERTION;
rec->ExceptionFlags = EH_NONCONTINUABLE;
}
@ -1986,7 +1993,7 @@ void __wine_enter_vm86( CONTEXT *context )
WINE_ERR( "unhandled result from vm86 mode %x\n", res );
continue;
}
__regs_RtlRaiseException( &rec, context );
raise_exception( &rec, context, TRUE );
}
}

View File

@ -618,6 +618,7 @@ static inline DWORD get_fpu_code( const CONTEXT *context )
static void do_segv( CONTEXT *context, int trap, int err, int code, void * addr )
{
EXCEPTION_RECORD rec;
NTSTATUS status;
rec.ExceptionRecord = NULL;
rec.ExceptionFlags = EXCEPTION_CONTINUABLE;
@ -694,7 +695,8 @@ static void do_segv( CONTEXT *context, int trap, int err, int code, void * addr
}
break;
}
__regs_RtlRaiseException( &rec, context );
status = raise_exception( &rec, context, TRUE );
if (status) raise_status( status, &rec );
}
/**********************************************************************
@ -705,6 +707,7 @@ static void do_segv( CONTEXT *context, int trap, int err, int code, void * addr
static void do_trap( CONTEXT *context, int code, void * addr )
{
EXCEPTION_RECORD rec;
NTSTATUS status;
rec.ExceptionFlags = EXCEPTION_CONTINUABLE;
rec.ExceptionRecord = NULL;
@ -726,7 +729,8 @@ static void do_trap( CONTEXT *context, int code, void * addr )
default:FIXME("Unhandled SIGTRAP/%x\n", code);
break;
}
__regs_RtlRaiseException( &rec, context );
status = raise_exception( &rec, context, TRUE );
if (status) raise_status( status, &rec );
}
/**********************************************************************
@ -737,6 +741,7 @@ static void do_trap( CONTEXT *context, int code, void * addr )
static void do_fpe( CONTEXT *context, int code, void * addr )
{
EXCEPTION_RECORD rec;
NTSTATUS status;
switch ( code & 0xffff ) {
#ifdef FPE_FLTSUB
@ -785,7 +790,8 @@ static void do_fpe( CONTEXT *context, int code, void * addr )
rec.ExceptionRecord = NULL;
rec.ExceptionAddress = addr;
rec.NumberParameters = 0;
__regs_RtlRaiseException( &rec, context );
status = raise_exception( &rec, context, TRUE );
if (status) raise_status( status, &rec );
}
/**********************************************************************
@ -840,6 +846,7 @@ static HANDLER_DEF(int_handler)
{
EXCEPTION_RECORD rec;
CONTEXT context;
NTSTATUS status;
save_context( &context, HANDLER_CONTEXT );
rec.ExceptionCode = CONTROL_C_EXIT;
@ -847,7 +854,8 @@ static HANDLER_DEF(int_handler)
rec.ExceptionRecord = NULL;
rec.ExceptionAddress = (LPVOID)context.Iar;
rec.NumberParameters = 0;
__regs_RtlRaiseException( &rec, &context );
status = raise_exception( &rec, &context, TRUE );
if (status) raise_status( status, &rec );
restore_context( &context, HANDLER_CONTEXT );
}
}
@ -862,6 +870,7 @@ static HANDLER_DEF(abrt_handler)
{
EXCEPTION_RECORD rec;
CONTEXT context;
NTSTATUS status;
save_context( &context, HANDLER_CONTEXT );
rec.ExceptionCode = EXCEPTION_WINE_ASSERTION;
@ -869,7 +878,8 @@ static HANDLER_DEF(abrt_handler)
rec.ExceptionRecord = NULL;
rec.ExceptionAddress = (LPVOID)context.Iar;
rec.NumberParameters = 0;
__regs_RtlRaiseException( &rec, &context ); /* Should never return.. */
status = raise_exception( &rec, &context, TRUE );
if (status) raise_status( status, &rec );
restore_context( &context, HANDLER_CONTEXT );
}

View File

@ -371,6 +371,7 @@ static void segv_handler( int signal, siginfo_t *info, ucontext_t *ucontext )
{
EXCEPTION_RECORD rec;
CONTEXT context;
NTSTATUS status;
rec.ExceptionCode = EXCEPTION_ACCESS_VIOLATION;
@ -386,7 +387,8 @@ static void segv_handler( int signal, siginfo_t *info, ucontext_t *ucontext )
rec.ExceptionInformation[0] = 0; /* FIXME: read/write access ? */
rec.ExceptionInformation[1] = (ULONG_PTR)info->si_addr;
__regs_RtlRaiseException( &rec, &context );
status = raise_exception( &rec, &context, TRUE );
if (status) raise_status( status, &rec );
restore_context( &context, ucontext );
}
@ -399,6 +401,7 @@ static void bus_handler( int signal, siginfo_t *info, ucontext_t *ucontext )
{
EXCEPTION_RECORD rec;
CONTEXT context;
NTSTATUS status;
save_context( &context, ucontext );
rec.ExceptionRecord = NULL;
@ -411,7 +414,8 @@ static void bus_handler( int signal, siginfo_t *info, ucontext_t *ucontext )
else
rec.ExceptionCode = EXCEPTION_ACCESS_VIOLATION;
__regs_RtlRaiseException( &rec, &context );
status = raise_exception( &rec, &context, TRUE );
if (status) raise_status( status, &rec );
restore_context( &context, ucontext );
}
@ -424,6 +428,7 @@ static void ill_handler( int signal, siginfo_t *info, ucontext_t *ucontext )
{
EXCEPTION_RECORD rec;
CONTEXT context;
NTSTATUS status;
switch ( info->si_code )
{
@ -450,7 +455,8 @@ static void ill_handler( int signal, siginfo_t *info, ucontext_t *ucontext )
rec.ExceptionFlags = EXCEPTION_CONTINUABLE;
rec.ExceptionAddress = (LPVOID)context.pc;
rec.NumberParameters = 0;
__regs_RtlRaiseException( &rec, &context );
status = raise_exception( &rec, &context, TRUE );
if (status) raise_status( status, &rec );
restore_context( &context, ucontext );
}
@ -464,6 +470,7 @@ static void trap_handler( int signal, siginfo_t *info, ucontext_t *ucontext )
{
EXCEPTION_RECORD rec;
CONTEXT context;
NTSTATUS status;
switch ( info->si_code )
{
@ -481,7 +488,8 @@ static void trap_handler( int signal, siginfo_t *info, ucontext_t *ucontext )
rec.ExceptionRecord = NULL;
rec.ExceptionAddress = (LPVOID)context.pc;
rec.NumberParameters = 0;
__regs_RtlRaiseException( &rec, &context );
status = raise_exception( &rec, &context, TRUE );
if (status) raise_status( status, &rec );
restore_context( &context, ucontext );
}
@ -495,6 +503,7 @@ static void fpe_handler( int signal, siginfo_t *info, ucontext_t *ucontext )
{
EXCEPTION_RECORD rec;
CONTEXT context;
NTSTATUS status;
switch ( info->si_code )
{
@ -531,7 +540,8 @@ static void fpe_handler( int signal, siginfo_t *info, ucontext_t *ucontext )
rec.ExceptionRecord = NULL;
rec.ExceptionAddress = (LPVOID)context.pc;
rec.NumberParameters = 0;
__regs_RtlRaiseException( &rec, &context );
status = raise_exception( &rec, &context, TRUE );
if (status) raise_status( status, &rec );
restore_context( &context, ucontext );
restore_fpu( &context, ucontext );
}
@ -548,6 +558,7 @@ static void int_handler( int signal, siginfo_t *info, ucontext_t *ucontext )
{
EXCEPTION_RECORD rec;
CONTEXT context;
NTSTATUS status;
save_context( &context, ucontext );
rec.ExceptionCode = CONTROL_C_EXIT;
@ -555,7 +566,8 @@ static void int_handler( int signal, siginfo_t *info, ucontext_t *ucontext )
rec.ExceptionRecord = NULL;
rec.ExceptionAddress = (LPVOID)context.pc;
rec.NumberParameters = 0;
__regs_RtlRaiseException( &rec, &context );
status = raise_exception( &rec, &context, TRUE );
if (status) raise_status( status, &rec );
restore_context( &context, ucontext );
}
}
@ -569,6 +581,7 @@ static HANDLER_DEF(abrt_handler)
{
EXCEPTION_RECORD rec;
CONTEXT context;
NTSTATUS status;
save_context( &context, HANDLER_CONTEXT );
rec.ExceptionCode = EXCEPTION_WINE_ASSERTION;
@ -576,7 +589,8 @@ static HANDLER_DEF(abrt_handler)
rec.ExceptionRecord = NULL;
rec.ExceptionAddress = (LPVOID)context.pc;
rec.NumberParameters = 0;
__regs_RtlRaiseException( &rec, &context ); /* Should never return.. */
status = raise_exception( &rec, &context, TRUE );
if (status) raise_status( status, &rec );
restore_context( &context, HANDLER_CONTEXT );
}

View File

@ -478,6 +478,7 @@ static HANDLER_DEF(segv_handler)
{
EXCEPTION_RECORD rec;
CONTEXT context;
NTSTATUS status;
save_context( &context, HANDLER_CONTEXT );
@ -532,7 +533,8 @@ static HANDLER_DEF(segv_handler)
break;
}
__regs_RtlRaiseException( &rec, &context );
status = raise_exception( &rec, &context, TRUE );
if (status) raise_status( status, &rec );
done:
restore_context( &context, HANDLER_CONTEXT );
}
@ -546,6 +548,7 @@ static HANDLER_DEF(trap_handler)
{
EXCEPTION_RECORD rec;
CONTEXT context;
NTSTATUS status;
save_context( &context, HANDLER_CONTEXT );
rec.ExceptionFlags = EXCEPTION_CONTINUABLE;
@ -567,7 +570,8 @@ static HANDLER_DEF(trap_handler)
break;
}
__regs_RtlRaiseException( &rec, &context );
status = raise_exception( &rec, &context, TRUE );
if (status) raise_status( status, &rec );
restore_context( &context, HANDLER_CONTEXT );
}
@ -580,6 +584,7 @@ static HANDLER_DEF(fpe_handler)
{
EXCEPTION_RECORD rec;
CONTEXT context;
NTSTATUS status;
save_context( &context, HANDLER_CONTEXT );
rec.ExceptionFlags = EXCEPTION_CONTINUABLE;
@ -616,7 +621,8 @@ static HANDLER_DEF(fpe_handler)
break;
}
__regs_RtlRaiseException( &rec, &context );
status = raise_exception( &rec, &context, TRUE );
if (status) raise_status( status, &rec );
restore_context( &context, HANDLER_CONTEXT );
}
@ -631,6 +637,7 @@ static HANDLER_DEF(int_handler)
{
EXCEPTION_RECORD rec;
CONTEXT context;
NTSTATUS status;
save_context( &context, HANDLER_CONTEXT );
rec.ExceptionCode = CONTROL_C_EXIT;
@ -638,7 +645,8 @@ static HANDLER_DEF(int_handler)
rec.ExceptionRecord = NULL;
rec.ExceptionAddress = (LPVOID)context.Rip;
rec.NumberParameters = 0;
__regs_RtlRaiseException( &rec, &context );
status = raise_exception( &rec, &context, TRUE );
if (status) raise_status( status, &rec );
restore_context( &context, HANDLER_CONTEXT );
}
}
@ -653,6 +661,7 @@ static HANDLER_DEF(abrt_handler)
{
EXCEPTION_RECORD rec;
CONTEXT context;
NTSTATUS status;
save_context( &context, HANDLER_CONTEXT );
rec.ExceptionCode = EXCEPTION_WINE_ASSERTION;
@ -660,7 +669,8 @@ static HANDLER_DEF(abrt_handler)
rec.ExceptionRecord = NULL;
rec.ExceptionAddress = (LPVOID)context.Rip;
rec.NumberParameters = 0;
__regs_RtlRaiseException( &rec, &context ); /* Should never return.. */
status = raise_exception( &rec, &context, TRUE );
if (status) raise_status( status, &rec );
restore_context( &context, HANDLER_CONTEXT );
}