Commit 90e38659 authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: NtRaiseException doesn't need to be a register function.

Moved common code between NtRaiseException and RtlRaiseException to a separate raise_exception function.
parent 8b84808b
...@@ -77,6 +77,7 @@ static RTL_CRITICAL_SECTION vectored_handlers_section = { &critsect_debug, -1, 0 ...@@ -77,6 +77,7 @@ static RTL_CRITICAL_SECTION vectored_handlers_section = { &critsect_debug, -1, 0
# error You must define GET_IP for this CPU # error You must define GET_IP for this CPU
#endif #endif
extern void DECLSPEC_NORETURN __wine_call_from_32_restore_regs( const CONTEXT *context );
/******************************************************************* /*******************************************************************
* EXC_RaiseHandler * EXC_RaiseHandler
...@@ -241,65 +242,15 @@ static LONG call_vectored_handlers( EXCEPTION_RECORD *rec, CONTEXT *context ) ...@@ -241,65 +242,15 @@ static LONG call_vectored_handlers( EXCEPTION_RECORD *rec, CONTEXT *context )
} }
/******************************************************************* /**********************************************************************
* EXC_DefaultHandling * call_stack_handlers
* *
* Default handling for exceptions. Called when we didn't find a suitable handler. * Call the stack handlers chain.
*/
static void EXC_DefaultHandling( EXCEPTION_RECORD *rec, CONTEXT *context )
{
if (send_debug_event( rec, FALSE, context ) == DBG_CONTINUE) return; /* continue execution */
if (rec->ExceptionFlags & EH_STACK_INVALID)
ERR("Exception frame is not in stack limits => unable to dispatch exception.\n");
else if (rec->ExceptionCode == STATUS_NONCONTINUABLE_EXCEPTION)
ERR("Process attempted to continue execution after noncontinuable exception.\n");
else
ERR("Unhandled exception code %lx flags %lx addr %p\n",
rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress );
NtTerminateProcess( NtCurrentProcess(), 1 );
}
/***********************************************************************
* RtlRaiseException (NTDLL.@)
*/ */
void WINAPI __regs_RtlRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context ) static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *context )
{ {
EXCEPTION_REGISTRATION_RECORD *frame, *dispatch, *nested_frame; EXCEPTION_REGISTRATION_RECORD *frame, *dispatch, *nested_frame;
EXCEPTION_RECORD newrec; DWORD res;
DWORD res, c;
NTSTATUS status;
TRACE( "code=%lx flags=%lx addr=%p\n", rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress );
for (c=0; c<rec->NumberParameters; c++) TRACE(" info[%ld]=%08lx\n", c, rec->ExceptionInformation[c]);
if (rec->ExceptionCode == EXCEPTION_WINE_STUB)
{
if (HIWORD(rec->ExceptionInformation[1]))
MESSAGE( "wine: Call from %p to unimplemented function %s.%s, aborting\n",
rec->ExceptionAddress,
(char*)rec->ExceptionInformation[0], (char*)rec->ExceptionInformation[1] );
else
MESSAGE( "wine: Call from %p to unimplemented function %s.%ld, aborting\n",
rec->ExceptionAddress,
(char*)rec->ExceptionInformation[0], rec->ExceptionInformation[1] );
}
#ifdef __i386__
else
{
TRACE(" eax=%08lx ebx=%08lx ecx=%08lx edx=%08lx esi=%08lx edi=%08lx\n",
context->Eax, context->Ebx, context->Ecx,
context->Edx, context->Esi, context->Edi );
TRACE(" ebp=%08lx esp=%08lx cs=%04lx ds=%04lx es=%04lx fs=%04lx gs=%04lx flags=%08lx\n",
context->Ebp, context->Esp, context->SegCs, context->SegDs,
context->SegEs, context->SegFs, context->SegGs, context->EFlags );
}
#endif
status = send_debug_event( rec, TRUE, context );
if (status == DBG_CONTINUE || status == DBG_EXCEPTION_HANDLED) return; /* continue execution */
if (call_vectored_handlers( rec, context ) == EXCEPTION_CONTINUE_EXECUTION) return;
frame = NtCurrentTeb()->Tib.ExceptionList; frame = NtCurrentTeb()->Tib.ExceptionList;
nested_frame = NULL; nested_frame = NULL;
...@@ -326,13 +277,8 @@ void WINAPI __regs_RtlRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context ) ...@@ -326,13 +277,8 @@ void WINAPI __regs_RtlRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context )
switch(res) switch(res)
{ {
case ExceptionContinueExecution: case ExceptionContinueExecution:
if (!(rec->ExceptionFlags & EH_NONCONTINUABLE)) return; if (!(rec->ExceptionFlags & EH_NONCONTINUABLE)) return STATUS_SUCCESS;
newrec.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION; return STATUS_NONCONTINUABLE_EXCEPTION;
newrec.ExceptionFlags = EH_NONCONTINUABLE;
newrec.ExceptionRecord = rec;
newrec.NumberParameters = 0;
RtlRaiseException( &newrec ); /* never returns */
break;
case ExceptionContinueSearch: case ExceptionContinueSearch:
break; break;
case ExceptionNestedException: case ExceptionNestedException:
...@@ -340,16 +286,109 @@ void WINAPI __regs_RtlRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context ) ...@@ -340,16 +286,109 @@ void WINAPI __regs_RtlRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context )
rec->ExceptionFlags |= EH_NESTED_CALL; rec->ExceptionFlags |= EH_NESTED_CALL;
break; break;
default: default:
newrec.ExceptionCode = STATUS_INVALID_DISPOSITION; return STATUS_INVALID_DISPOSITION;
newrec.ExceptionFlags = EH_NONCONTINUABLE;
newrec.ExceptionRecord = rec;
newrec.NumberParameters = 0;
RtlRaiseException( &newrec ); /* never returns */
break;
} }
frame = frame->Prev; frame = frame->Prev;
} }
EXC_DefaultHandling( rec, context ); return STATUS_UNHANDLED_EXCEPTION;
}
/*******************************************************************
* raise_exception
*
* Implementation of NtRaiseException.
*/
static NTSTATUS raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_chance )
{
NTSTATUS status;
if (first_chance)
{
DWORD c;
TRACE( "code=%lx flags=%lx addr=%p\n",
rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress );
for (c = 0; c < rec->NumberParameters; c++)
TRACE( " info[%ld]=%08lx\n", c, rec->ExceptionInformation[c] );
if (rec->ExceptionCode == EXCEPTION_WINE_STUB)
{
if (rec->ExceptionInformation[1] >> 16)
MESSAGE( "wine: Call from %p to unimplemented function %s.%s, aborting\n",
rec->ExceptionAddress,
(char*)rec->ExceptionInformation[0], (char*)rec->ExceptionInformation[1] );
else
MESSAGE( "wine: Call from %p to unimplemented function %s.%ld, aborting\n",
rec->ExceptionAddress,
(char*)rec->ExceptionInformation[0], rec->ExceptionInformation[1] );
}
#ifdef __i386__
else
{
TRACE(" eax=%08lx ebx=%08lx ecx=%08lx edx=%08lx esi=%08lx edi=%08lx\n",
context->Eax, context->Ebx, context->Ecx,
context->Edx, context->Esi, context->Edi );
TRACE(" ebp=%08lx esp=%08lx cs=%04lx ds=%04lx es=%04lx fs=%04lx gs=%04lx flags=%08lx\n",
context->Ebp, context->Esp, context->SegCs, context->SegDs,
context->SegEs, context->SegFs, context->SegGs, context->EFlags );
}
#endif
status = send_debug_event( rec, TRUE, context );
if (status == DBG_CONTINUE || status == DBG_EXCEPTION_HANDLED)
return STATUS_SUCCESS;
if (call_vectored_handlers( rec, context ) == EXCEPTION_CONTINUE_EXECUTION)
return STATUS_SUCCESS;
if ((status = call_stack_handlers( rec, context )) != STATUS_UNHANDLED_EXCEPTION)
return status;
}
/* last chance exception */
status = send_debug_event( rec, FALSE, context );
if (status != DBG_CONTINUE)
{
if (rec->ExceptionFlags & EH_STACK_INVALID)
ERR("Exception frame is not in stack limits => unable to dispatch exception.\n");
else if (rec->ExceptionCode == STATUS_NONCONTINUABLE_EXCEPTION)
ERR("Process attempted to continue execution after noncontinuable exception.\n");
else
ERR("Unhandled exception code %lx flags %lx addr %p\n",
rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress );
NtTerminateProcess( NtCurrentProcess(), 1 );
}
return STATUS_SUCCESS;
}
/*******************************************************************
* NtRaiseException (NTDLL.@)
*/
NTSTATUS WINAPI NtRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_chance )
{
NTSTATUS status = raise_exception( rec, context, first_chance );
#ifdef DEFINE_REGS_ENTRYPOINT
if (status == STATUS_SUCCESS) __wine_call_from_32_restore_regs( context );
#endif
return status;
}
/***********************************************************************
* 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 */
}
} }
/**********************************************************************/ /**********************************************************************/
...@@ -454,28 +493,6 @@ void WINAPI RtlUnwind( PVOID pEndFrame, PVOID unusedEip, ...@@ -454,28 +493,6 @@ void WINAPI RtlUnwind( PVOID pEndFrame, PVOID unusedEip,
#endif #endif
/*******************************************************************
* NtRaiseException (NTDLL.@)
*/
void WINAPI __regs_NtRaiseException( EXCEPTION_RECORD *rec, CONTEXT *ctx,
BOOL first, CONTEXT *context )
{
__regs_RtlRaiseException( rec, ctx );
*context = *ctx;
}
#ifdef DEFINE_REGS_ENTRYPOINT
DEFINE_REGS_ENTRYPOINT( NtRaiseException, 12, 12 );
#else
void WINAPI NtRaiseException( EXCEPTION_RECORD *rec, CONTEXT *ctx, BOOL first )
{
CONTEXT context;
memset( &context, 0, sizeof(context) );
__regs_NtRaiseException( rec, ctx, first, &context );
}
#endif
/*********************************************************************** /***********************************************************************
* RtlRaiseStatus (NTDLL.@) * RtlRaiseStatus (NTDLL.@)
* *
......
...@@ -273,7 +273,7 @@ ...@@ -273,7 +273,7 @@
@ stdcall NtQueryVirtualMemory(long ptr long ptr long ptr) @ stdcall NtQueryVirtualMemory(long ptr long ptr long ptr)
@ stdcall NtQueryVolumeInformationFile(long ptr ptr long long) @ stdcall NtQueryVolumeInformationFile(long ptr ptr long long)
@ stdcall NtQueueApcThread(long ptr long long long) @ stdcall NtQueueApcThread(long ptr long long long)
@ stdcall -register NtRaiseException(ptr ptr long) @ stdcall NtRaiseException(ptr ptr long)
@ stub NtRaiseHardError @ stub NtRaiseHardError
@ stdcall NtReadFile(long long long long long long long long long) @ stdcall NtReadFile(long long long long long long long long long)
@ stub NtReadFileScatter @ stub NtReadFileScatter
......
...@@ -1841,7 +1841,7 @@ NTSTATUS WINAPI NtQueryTimerResolution(PULONG,PULONG,PULONG); ...@@ -1841,7 +1841,7 @@ NTSTATUS WINAPI NtQueryTimerResolution(PULONG,PULONG,PULONG);
NTSTATUS WINAPI NtQueryValueKey(HANDLE,const UNICODE_STRING *,KEY_VALUE_INFORMATION_CLASS,void *,DWORD,DWORD *); NTSTATUS WINAPI NtQueryValueKey(HANDLE,const UNICODE_STRING *,KEY_VALUE_INFORMATION_CLASS,void *,DWORD,DWORD *);
NTSTATUS WINAPI NtQueryVirtualMemory(HANDLE,LPCVOID,MEMORY_INFORMATION_CLASS,PVOID,SIZE_T,SIZE_T*); NTSTATUS WINAPI NtQueryVirtualMemory(HANDLE,LPCVOID,MEMORY_INFORMATION_CLASS,PVOID,SIZE_T,SIZE_T*);
NTSTATUS WINAPI NtQueryVolumeInformationFile(HANDLE,PIO_STATUS_BLOCK,PVOID,ULONG,FS_INFORMATION_CLASS); NTSTATUS WINAPI NtQueryVolumeInformationFile(HANDLE,PIO_STATUS_BLOCK,PVOID,ULONG,FS_INFORMATION_CLASS);
void WINAPI NtRaiseException(PEXCEPTION_RECORD,PCONTEXT,BOOL); NTSTATUS WINAPI NtRaiseException(PEXCEPTION_RECORD,PCONTEXT,BOOL);
NTSTATUS WINAPI NtRaiseHardError(NTSTATUS,ULONG,PUNICODE_STRING,PVOID*,HARDERROR_RESPONSE_OPTION,PHARDERROR_RESPONSE); NTSTATUS WINAPI NtRaiseHardError(NTSTATUS,ULONG,PUNICODE_STRING,PVOID*,HARDERROR_RESPONSE_OPTION,PHARDERROR_RESPONSE);
NTSTATUS WINAPI NtReadFile(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,PVOID,ULONG,PLARGE_INTEGER,PULONG); NTSTATUS WINAPI NtReadFile(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,PVOID,ULONG,PLARGE_INTEGER,PULONG);
NTSTATUS WINAPI NtReadFileScatter(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,FILE_SEGMENT_ELEMENT,ULONG,PLARGE_INTEGER,PULONG); NTSTATUS WINAPI NtReadFileScatter(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,FILE_SEGMENT_ELEMENT,ULONG,PLARGE_INTEGER,PULONG);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment