2002-10-26 Casper S. Hornstrup <chorns@users.sourceforge.net>

* lib/msvcrt/except/seh.s: Fix end-of-line formatting.
	* lib/ntdll/rtl/i386/exception.c: Ditto.
	* lib/ntdll/rtl/i386/except.s: Ditto.
	* ntoskrnl/rtl/i386/except.s: Ditto.
	* ntoskrnl/rtl/i386/seh.s: Ditto.

svn path=/trunk/; revision=3659
This commit is contained in:
Casper Hornstrup 2002-10-26 07:32:08 +00:00
parent b824c3ef39
commit 9bbe34eb81
6 changed files with 555 additions and 545 deletions

View file

@ -1,3 +1,11 @@
2002-10-26 Casper S. Hornstrup <chorns@users.sourceforge.net>
* lib/msvcrt/except/seh.s: Fix end-of-line formatting.
* lib/ntdll/rtl/i386/exception.c: Ditto.
* lib/ntdll/rtl/i386/except.s: Ditto.
* ntoskrnl/rtl/i386/except.s: Ditto.
* ntoskrnl/rtl/i386/seh.s: Ditto.
2002-10-26 Casper S. Hornstrup <chorns@users.sourceforge.net>
* lib/msvcrt/Makefile (OBJECTS_EXCEPT): Add except/seh.o; Remove

View file

@ -1,13 +1,13 @@
/* $Id: seh.s,v 1.1 2002/10/26 00:32:17 chorns Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS MSVCRT Runtime Library
* PURPOSE: Runtime library exception support for IA-32
* FILE: lib/msvcrt/except/seh.s
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
* NOTES: This file is shared with ntoskrnl/rtl/i386/seh.s.
* Please keep them in sync.
*/
/* $Id: seh.s,v 1.2 2002/10/26 07:32:08 chorns Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS MSVCRT Runtime Library
* PURPOSE: Runtime library exception support for IA-32
* FILE: lib/msvcrt/except/seh.s
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
* NOTES: This file is shared with ntoskrnl/rtl/i386/seh.s.
* Please keep them in sync.
*/
#define ExceptionContinueExecution 0
#define ExceptionContinueSearch 1
@ -49,11 +49,11 @@
#define ST_TRYLEVEL 0x00
#define ST_FILTER 0x04
#define ST_HANDLER 0x08
#define CONTEXT_EDI 0x9C
#define CONTEXT_EBX 0xA4
#define CONTEXT_EIP 0xB8
.globl __local_unwind2
.globl __except_handler3
@ -67,12 +67,12 @@ _do_debug:
#define LU2_TRYLEVEL 0x08
#define LU2_REGFRAME 0x04
//
// void
// _local_unwind2(PEXCEPTION_REGISTRATION RegistrationFrame,
// LONG TryLevel)
//
//
// void
// _local_unwind2(PEXCEPTION_REGISTRATION RegistrationFrame,
// LONG TryLevel)
//
// Parameters:
// [EDX+08h] - PEXCEPTION_REGISTRATION RegistrationFrame
// [EDX+04h] - LONG TryLevel

View file

@ -1,17 +1,17 @@
/* $Id: except.s,v 1.1 2002/10/26 00:32:18 chorns Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: User-mode exception support for IA-32
* FILE: lib/ntdll/rtl/i386/except.s
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
* NOTES: This file is shared with ntoskrnl/rtl/i386/except.s.
* Please keep them in sync.
*/
#define EXCEPTION_UNWINDING 0x02
/* $Id: except.s,v 1.2 2002/10/26 07:32:08 chorns Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: User-mode exception support for IA-32
* FILE: lib/ntdll/rtl/i386/except.s
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
* NOTES: This file is shared with ntoskrnl/rtl/i386/except.s.
* Please keep them in sync.
*/
#define EREC_FLAGS 0x04
#define EXCEPTION_UNWINDING 0x02
#define EREC_FLAGS 0x04
#define ExceptionContinueExecution 0
#define ExceptionContinueSearch 1
@ -125,9 +125,9 @@ _RtlpCaptureContext:
#define REH_ERECORD 0x08
#define REH_RFRAME 0x0C
#define REH_CONTEXT 0x10
#define REH_DCONTEXT 0x14
#define REH_EROUTINE 0x18
#define REH_CONTEXT 0x10
#define REH_DCONTEXT 0x14
#define REH_EROUTINE 0x18
// Parameters:
// None
@ -141,8 +141,8 @@ _RtlpCaptureContext:
// Returns:
// EXCEPTION_DISPOSITION
// Notes:
// Setup the protecting exception handler and call the exception
// handler in the right context.
// Setup the protecting exception handler and call the exception
// handler in the right context.
_RtlpExecuteHandler:
pushl %ebp
movl %esp, %ebp
@ -161,21 +161,21 @@ _RtlpExecuteHandler:
// Now call the exception handler
movl REH_EROUTINE(%ebp), %eax
call *%eax
cmpl $-1, %fs:0x0
jne .reh_stack_looks_ok
// This should not happen
pushl 0
pushl 0
pushl 0
pushl 0
call _RtlAssert@16
.reh_loop:
jmp .reh_loop
.reh_stack_looks_ok:
cmpl $-1, %fs:0x0
jne .reh_stack_looks_ok
// This should not happen
pushl 0
pushl 0
pushl 0
pushl 0
call _RtlAssert@16
.reh_loop:
jmp .reh_loop
.reh_stack_looks_ok:
movl %fs:0x0, %esp
// Return to the 'front-end' for this function
@ -201,18 +201,19 @@ _RtlpExecuteHandler:
// EXCEPTION_DISPOSITION
// Notes:
// This exception handler protects the exception handling
// mechanism by detecting nested exceptions.
// mechanism by detecting nested exceptions.
_RtlpExceptionProtector:
movl $ExceptionContinueSearch, %eax
movl REP_ERECORD(%esp), %ecx
movl REP_ERECORD(%esp), %ecx
testl $EXCEPTION_UNWINDING, EREC_FLAGS(%ecx)
jnz .rep_end
// Unwinding is not taking place, so return ExceptionNestedException
// Set DispatcherContext field to the exception registration for the
// exception handler that executed when a nested exception occurred
movl REP_DCONTEXT(%esp), %ecx movl REP_RFRAME(%esp), %eax
// Set DispatcherContext field to the exception registration for the
// exception handler that executed when a nested exception occurred
movl REP_DCONTEXT(%esp), %ecx
movl REP_RFRAME(%esp), %eax
movl %eax, (%ecx)
movl $ExceptionNestedException, %eax
@ -273,8 +274,8 @@ _RtlpUnwindProtector:
.rup_end:
ret
// Parameters:
// [ESP+04h] - PEXCEPTION_RECORD ExceptionRecord
// [ESP+08h] - PEXCEPTION_REGISTRATION RegistrationFrame

View file

@ -1,433 +1,433 @@
/* $Id: exception.c,v 1.1 2002/10/26 00:32:18 chorns Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: User-mode exception support for IA-32
* FILE: lib/ntdll/rtl/i386/exception.c
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <windows.h>
#include <string.h>
#define NDEBUG
#include <debug.h>
/* FUNCTIONS ***************************************************************/
/* Implemented in except.s */
/* $Id: exception.c,v 1.2 2002/10/26 07:32:08 chorns Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: User-mode exception support for IA-32
* FILE: lib/ntdll/rtl/i386/exception.c
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <windows.h>
#include <string.h>
#define NDEBUG
#include <debug.h>
/* FUNCTIONS ***************************************************************/
/* Implemented in except.s */
VOID
RtlpCaptureContext(PCONTEXT pContext);
/* Macros that will help streamline the SEH implementations for
kernel mode and user mode */
#define SehpGetStackLimits(StackBase, StackLimit) \
{ \
(*(StackBase)) = NtCurrentTeb()->Tib->StackBase; \
(*(StackLimit)) = NtCurrentTeb()->Tib->StackLimit; \
}
#define SehpGetExceptionList() \
(PEXCEPTION_REGISTRATION)(NtCurrentTeb()->Tib.ExceptionList)
#define SehpSetExceptionList(NewExceptionList) \
NtCurrentTeb()->Tib.ExceptionList = (PVOID)(NewExceptionList)
/* Macros that will help streamline the SEH implementations for
kernel mode and user mode */
#define SehpGetStackLimits(StackBase, StackLimit) \
{ \
(*(StackBase)) = NtCurrentTeb()->Tib->StackBase; \
(*(StackLimit)) = NtCurrentTeb()->Tib->StackLimit; \
}
#define SehpGetExceptionList() \
(PEXCEPTION_REGISTRATION)(NtCurrentTeb()->Tib.ExceptionList)
#define SehpSetExceptionList(NewExceptionList) \
NtCurrentTeb()->Tib.ExceptionList = (PVOID)(NewExceptionList)
#define SehpCaptureContext(Context) \
{ \
RtlpCaptureContext(Context); \
}
/*** Code below this line is shared with ntoskrnl/rtl/i386/exception.c - please keep in sync ***/
VOID STDCALL
AsmDebug(ULONG Value)
{
DbgPrint("Value 0x%.08x\n", Value);
}
/* Declare a few prototypes for the functions in except.s */
EXCEPTION_DISPOSITION
RtlpExecuteHandlerForException(
PEXCEPTION_RECORD ExceptionRecord,
PEXCEPTION_REGISTRATION RegistrationFrame,
PCONTEXT Context,
PVOID DispatcherContext,
PEXCEPTION_HANDLER ExceptionHandler);
EXCEPTION_DISPOSITION
RtlpExecuteHandlerForUnwind(
PEXCEPTION_RECORD ExceptionRecord,
PEXCEPTION_REGISTRATION RegistrationFrame,
PCONTEXT Context,
PVOID DispatcherContext,
PEXCEPTION_HANDLER ExceptionHandler);
#ifndef NDEBUG
VOID RtlpDumpExceptionRegistrations(VOID)
{
PEXCEPTION_REGISTRATION Current;
DbgPrint("Dumping exception registrations:\n");
Current = SehpGetExceptionList();
if ((ULONG_PTR)Current != -1)
{
while ((ULONG_PTR)Current != -1)
{
DbgPrint(" (0x%08X) HANDLER (0x%08X)\n", Current, Current->handler);
Current = Current->prev;
}
DbgPrint(" End-Of-List\n");
} else {
DbgPrint(" No exception registrations exists.\n");
}
}
#endif /* NDEBUG */
ULONG
RtlpDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
IN PCONTEXT Context)
{
PEXCEPTION_REGISTRATION RegistrationFrame;
DWORD DispatcherContext;
DWORD ReturnValue;
DPRINT("RtlpDispatchException()\n");
#ifndef NDEBUG
RtlpDumpExceptionRegistrations();
#endif /* NDEBUG */
RegistrationFrame = SehpGetExceptionList();
DPRINT("RegistrationFrame is 0x%X\n", RegistrationFrame);
while ((ULONG_PTR)RegistrationFrame != -1)
{
EXCEPTION_RECORD ExceptionRecord2;
DWORD Temp = 0;
//PVOID RegistrationFrameEnd = (PVOID)RegistrationFrame + 8;
// Make sure the registration frame is located within the stack
DPRINT("Error checking\n");
#if 0
if (Teb->Tib.StackBase > RegistrationFrameEnd)
{
DPRINT("Teb->Tib.StackBase (0x%.08x) > RegistrationFrameEnd (0x%.08x)\n",
Teb->Tib.StackBase, RegistrationFrameEnd);
ExceptionRecord->ExceptionFlags |= EXCEPTION_STACK_INVALID;
return ExceptionContinueExecution;
}
// FIXME: Stack top, correct?
if (Teb->Tib.StackLimit < RegistrationFrameEnd)
{
DPRINT("Teb->Tib.StackLimit (0x%.08x) > RegistrationFrameEnd (0x%.08x)\n",
Teb->Tib.StackLimit, RegistrationFrameEnd);
ExceptionRecord->ExceptionFlags |= EXCEPTION_STACK_INVALID;
return ExceptionContinueExecution;
}
// Make sure stack is DWORD aligned
if ((ULONG_PTR)RegistrationFrame & 3)
{
DPRINT("RegistrationFrameEnd (0x%.08x) is not DWORD aligned.\n",
RegistrationFrameEnd);
ExceptionRecord->ExceptionFlags |= EXCEPTION_STACK_INVALID;
return ExceptionContinueExecution;
}
#endif
#if 0
/* FIXME: */
if (someFlag)
RtlpLogLastExceptionDisposition( hLog, retValue );
#endif
DPRINT("Calling handler at 0x%X\n", RegistrationFrame->handler);
DPRINT("ExceptionRecord 0x%X\n", ExceptionRecord);
DPRINT("RegistrationFrame 0x%X\n", RegistrationFrame);
DPRINT("Context 0x%X\n", Context);
DPRINT("&DispatcherContext 0x%X\n", &DispatcherContext);
ReturnValue = RtlpExecuteHandlerForException(
ExceptionRecord,
RegistrationFrame,
Context,
&DispatcherContext,
RegistrationFrame->handler);
DPRINT("Exception handler said 0x%X\n", ReturnValue);
DPRINT("RegistrationFrame == 0x%.08x\n", RegistrationFrame);
{
PULONG sp = (PULONG)((PVOID)RegistrationFrame - 0x08);
DPRINT("StandardESP == 0x%.08x\n", sp[0]);
DPRINT("Exception Pointers == 0x%.08x\n", sp[1]);
DPRINT("PrevFrame == 0x%.08x\n", sp[2]);
DPRINT("Handler == 0x%.08x\n", sp[3]);
DPRINT("ScopeTable == 0x%.08x\n", sp[4]);
DPRINT("TryLevel == 0x%.08x\n", sp[5]);
DPRINT("EBP == 0x%.08x\n", sp[6]);
}
if (RegistrationFrame == NULL)
{
ExceptionRecord->ExceptionFlags &= ~EXCEPTION_NESTED_CALL; // Turn off flag
}
if (ReturnValue == ExceptionContinueExecution)
{
DPRINT("ReturnValue == ExceptionContinueExecution\n");
if (ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE)
{
DPRINT("(ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE) == TRUE\n");
ExceptionRecord2.ExceptionRecord = ExceptionRecord;
ExceptionRecord2.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION;
ExceptionRecord2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
ExceptionRecord2.NumberParameters = 0;
RtlRaiseException(&ExceptionRecord2);
}
else
{
/* Copy the (possibly changed) context back to the trap frame and return */
NtContinue(Context, FALSE);
return ExceptionContinueExecution;
}
}
else if (ReturnValue == ExceptionContinueSearch)
{
DPRINT("ReturnValue == ExceptionContinueSearch\n");
/* Nothing to do here */
}
else if (ReturnValue == ExceptionNestedException)
{
DPRINT("ReturnValue == ExceptionNestedException\n");
ExceptionRecord->ExceptionFlags |= EXCEPTION_EXIT_UNWIND;
if (DispatcherContext > Temp)
{
Temp = DispatcherContext;
}
}
else /* if (ReturnValue == ExceptionCollidedUnwind) */
{
DPRINT("ReturnValue == ExceptionCollidedUnwind or unknown\n");
ExceptionRecord2.ExceptionRecord = ExceptionRecord;
ExceptionRecord2.ExceptionCode = STATUS_INVALID_DISPOSITION;
ExceptionRecord2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
ExceptionRecord2.NumberParameters = 0;
RtlRaiseException(&ExceptionRecord2);
}
RegistrationFrame = RegistrationFrame->prev; // Go to previous frame
}
/* No exception handler will handle this exception */
DPRINT("RtlpDispatchException(): Return ExceptionContinueExecution\n");
return ExceptionContinueExecution;
}
VOID STDCALL
RtlRaiseStatus(NTSTATUS Status)
{
EXCEPTION_RECORD ExceptionRecord;
DPRINT("RtlRaiseStatus(Status 0x%.08x)\n", Status);
ExceptionRecord.ExceptionCode = Status;
ExceptionRecord.ExceptionRecord = NULL;
ExceptionRecord.NumberParameters = 0;
ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
RtlRaiseException (& ExceptionRecord);
}
VOID STDCALL
RtlUnwind(PEXCEPTION_REGISTRATION RegistrationFrame,
PVOID ReturnAddress,
PEXCEPTION_RECORD ExceptionRecord,
DWORD EaxValue)
{
PEXCEPTION_REGISTRATION ERHead;
PEXCEPTION_RECORD pExceptRec;
EXCEPTION_RECORD TempER;
CONTEXT Context;
DPRINT("RtlUnwind(). RegistrationFrame 0x%X\n", RegistrationFrame);
#ifndef NDEBUG
RtlpDumpExceptionRegistrations();
#endif /* NDEBUG */
ERHead = SehpGetExceptionList();
DPRINT("ERHead is 0x%X\n", ERHead);
if (ExceptionRecord == NULL) // The normal case
{
DPRINT("ExceptionRecord == NULL (normal)\n");
pExceptRec = &TempER;
pExceptRec->ExceptionFlags = 0;
pExceptRec->ExceptionCode = STATUS_UNWIND;
pExceptRec->ExceptionRecord = NULL;
pExceptRec->ExceptionAddress = ReturnAddress;
pExceptRec->ExceptionInformation[0] = 0;
}
if (RegistrationFrame)
pExceptRec->ExceptionFlags |= EXCEPTION_UNWINDING;
else
pExceptRec->ExceptionFlags |= (EXCEPTION_UNWINDING|EXCEPTION_EXIT_UNWIND);
#ifndef NDEBUG
DPRINT("ExceptionFlags == 0x%x:\n", pExceptRec->ExceptionFlags);
if (pExceptRec->ExceptionFlags & EXCEPTION_UNWINDING)
{
DPRINT(" * EXCEPTION_UNWINDING (0x%x)\n", EXCEPTION_UNWINDING);
}
if (pExceptRec->ExceptionFlags & EXCEPTION_EXIT_UNWIND)
{
DPRINT(" * EXCEPTION_EXIT_UNWIND (0x%x)\n", EXCEPTION_EXIT_UNWIND);
}
#endif /* NDEBUG */
Context.ContextFlags =
(CONTEXT_i386 | CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS);
SehpCaptureContext(&Context);
DPRINT("Context.Eip = 0x%.08x\n", Context.Eip);
DPRINT("Context.Ebp = 0x%.08x\n", Context.Ebp);
DPRINT("Context.Esp = 0x%.08x\n", Context.Esp);
Context.Esp += 0x10;
Context.Eax = EaxValue;
// Begin traversing the list of EXCEPTION_REGISTRATION
while ((ULONG_PTR)ERHead != -1)
{
EXCEPTION_RECORD er2;
DPRINT("ERHead 0x%X\n", ERHead);
if (ERHead == RegistrationFrame)
{
DPRINT("Continueing execution\n");
NtContinue(&Context, FALSE);
return;
}
else
{
// If there's an exception frame, but it's lower on the stack
// than the head of the exception list, something's wrong!
if (RegistrationFrame && (RegistrationFrame <= ERHead))
{
DPRINT("The exception frame is bad\n");
// Generate an exception to bail out
er2.ExceptionRecord = pExceptRec;
er2.NumberParameters = 0;
er2.ExceptionCode = STATUS_INVALID_UNWIND_TARGET;
er2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
RtlRaiseException(&er2);
}
}
#if 0
Stack = ERHead + sizeof(EXCEPTION_REGISTRATION);
if ( (Teb->Tib.StackBase <= (PVOID)ERHead ) // Make sure that ERHead
&& (Teb->Tib.->StackLimit >= (PVOID)Stack ) // is in range, and a multiple
&& (0 == ((ULONG_PTR)ERHead & 3)) ) // of 4 (i.e., sane)
{
#else
if (1) {
#endif
PEXCEPTION_REGISTRATION NewERHead;
PEXCEPTION_REGISTRATION pCurrExceptReg;
EXCEPTION_DISPOSITION ReturnValue;
DPRINT("Executing handler at 0x%X for unwind\n", ERHead->handler);
ReturnValue = RtlpExecuteHandlerForUnwind(
pExceptRec,
ERHead,
&Context,
&NewERHead,
ERHead->handler);
DPRINT("Handler at 0x%X returned 0x%X\n", ERHead->handler, ReturnValue);
if (ReturnValue != ExceptionContinueSearch)
{
if (ReturnValue != ExceptionCollidedUnwind)
{
DPRINT("Bad return value\n");
er2.ExceptionRecord = pExceptRec;
er2.NumberParameters = 0;
er2.ExceptionCode = STATUS_INVALID_DISPOSITION;
er2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
RtlRaiseException(&er2);
}
else
{
ERHead = NewERHead;
}
}
pCurrExceptReg = ERHead;
ERHead = ERHead->prev;
DPRINT("New ERHead is 0x%X\n", ERHead);
DPRINT("Setting exception registration at 0x%X as current\n",
RegistrationFrame->prev);
// Unlink the exception handler
SehpSetExceptionList(RegistrationFrame->prev);
}
else // The stack looks goofy! Raise an exception to bail out
{
DPRINT("Bad stack\n");
er2.ExceptionRecord = pExceptRec;
er2.NumberParameters = 0;
er2.ExceptionCode = STATUS_BAD_STACK;
er2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
RtlRaiseException(&er2);
}
}
// If we get here, we reached the end of the EXCEPTION_REGISTRATION list.
// This shouldn't happen normally.
DPRINT("Ran out of exception registrations. RegistrationFrame is (0x%X)\n",
RegistrationFrame);
if ((ULONG_PTR)RegistrationFrame == -1)
NtContinue(&Context, FALSE);
else
NtRaiseException(pExceptRec, &Context, 0);
}
/* EOF */
/*** Code below this line is shared with ntoskrnl/rtl/i386/exception.c - please keep in sync ***/
VOID STDCALL
AsmDebug(ULONG Value)
{
DbgPrint("Value 0x%.08x\n", Value);
}
/* Declare a few prototypes for the functions in except.s */
EXCEPTION_DISPOSITION
RtlpExecuteHandlerForException(
PEXCEPTION_RECORD ExceptionRecord,
PEXCEPTION_REGISTRATION RegistrationFrame,
PCONTEXT Context,
PVOID DispatcherContext,
PEXCEPTION_HANDLER ExceptionHandler);
EXCEPTION_DISPOSITION
RtlpExecuteHandlerForUnwind(
PEXCEPTION_RECORD ExceptionRecord,
PEXCEPTION_REGISTRATION RegistrationFrame,
PCONTEXT Context,
PVOID DispatcherContext,
PEXCEPTION_HANDLER ExceptionHandler);
#ifndef NDEBUG
VOID RtlpDumpExceptionRegistrations(VOID)
{
PEXCEPTION_REGISTRATION Current;
DbgPrint("Dumping exception registrations:\n");
Current = SehpGetExceptionList();
if ((ULONG_PTR)Current != -1)
{
while ((ULONG_PTR)Current != -1)
{
DbgPrint(" (0x%08X) HANDLER (0x%08X)\n", Current, Current->handler);
Current = Current->prev;
}
DbgPrint(" End-Of-List\n");
} else {
DbgPrint(" No exception registrations exists.\n");
}
}
#endif /* NDEBUG */
ULONG
RtlpDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
IN PCONTEXT Context)
{
PEXCEPTION_REGISTRATION RegistrationFrame;
DWORD DispatcherContext;
DWORD ReturnValue;
DPRINT("RtlpDispatchException()\n");
#ifndef NDEBUG
RtlpDumpExceptionRegistrations();
#endif /* NDEBUG */
RegistrationFrame = SehpGetExceptionList();
DPRINT("RegistrationFrame is 0x%X\n", RegistrationFrame);
while ((ULONG_PTR)RegistrationFrame != -1)
{
EXCEPTION_RECORD ExceptionRecord2;
DWORD Temp = 0;
//PVOID RegistrationFrameEnd = (PVOID)RegistrationFrame + 8;
// Make sure the registration frame is located within the stack
DPRINT("Error checking\n");
#if 0
if (Teb->Tib.StackBase > RegistrationFrameEnd)
{
DPRINT("Teb->Tib.StackBase (0x%.08x) > RegistrationFrameEnd (0x%.08x)\n",
Teb->Tib.StackBase, RegistrationFrameEnd);
ExceptionRecord->ExceptionFlags |= EXCEPTION_STACK_INVALID;
return ExceptionContinueExecution;
}
// FIXME: Stack top, correct?
if (Teb->Tib.StackLimit < RegistrationFrameEnd)
{
DPRINT("Teb->Tib.StackLimit (0x%.08x) > RegistrationFrameEnd (0x%.08x)\n",
Teb->Tib.StackLimit, RegistrationFrameEnd);
ExceptionRecord->ExceptionFlags |= EXCEPTION_STACK_INVALID;
return ExceptionContinueExecution;
}
// Make sure stack is DWORD aligned
if ((ULONG_PTR)RegistrationFrame & 3)
{
DPRINT("RegistrationFrameEnd (0x%.08x) is not DWORD aligned.\n",
RegistrationFrameEnd);
ExceptionRecord->ExceptionFlags |= EXCEPTION_STACK_INVALID;
return ExceptionContinueExecution;
}
#endif
#if 0
/* FIXME: */
if (someFlag)
RtlpLogLastExceptionDisposition( hLog, retValue );
#endif
DPRINT("Calling handler at 0x%X\n", RegistrationFrame->handler);
DPRINT("ExceptionRecord 0x%X\n", ExceptionRecord);
DPRINT("RegistrationFrame 0x%X\n", RegistrationFrame);
DPRINT("Context 0x%X\n", Context);
DPRINT("&DispatcherContext 0x%X\n", &DispatcherContext);
ReturnValue = RtlpExecuteHandlerForException(
ExceptionRecord,
RegistrationFrame,
Context,
&DispatcherContext,
RegistrationFrame->handler);
DPRINT("Exception handler said 0x%X\n", ReturnValue);
DPRINT("RegistrationFrame == 0x%.08x\n", RegistrationFrame);
{
PULONG sp = (PULONG)((PVOID)RegistrationFrame - 0x08);
DPRINT("StandardESP == 0x%.08x\n", sp[0]);
DPRINT("Exception Pointers == 0x%.08x\n", sp[1]);
DPRINT("PrevFrame == 0x%.08x\n", sp[2]);
DPRINT("Handler == 0x%.08x\n", sp[3]);
DPRINT("ScopeTable == 0x%.08x\n", sp[4]);
DPRINT("TryLevel == 0x%.08x\n", sp[5]);
DPRINT("EBP == 0x%.08x\n", sp[6]);
}
if (RegistrationFrame == NULL)
{
ExceptionRecord->ExceptionFlags &= ~EXCEPTION_NESTED_CALL; // Turn off flag
}
if (ReturnValue == ExceptionContinueExecution)
{
DPRINT("ReturnValue == ExceptionContinueExecution\n");
if (ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE)
{
DPRINT("(ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE) == TRUE\n");
ExceptionRecord2.ExceptionRecord = ExceptionRecord;
ExceptionRecord2.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION;
ExceptionRecord2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
ExceptionRecord2.NumberParameters = 0;
RtlRaiseException(&ExceptionRecord2);
}
else
{
/* Copy the (possibly changed) context back to the trap frame and return */
NtContinue(Context, FALSE);
return ExceptionContinueExecution;
}
}
else if (ReturnValue == ExceptionContinueSearch)
{
DPRINT("ReturnValue == ExceptionContinueSearch\n");
/* Nothing to do here */
}
else if (ReturnValue == ExceptionNestedException)
{
DPRINT("ReturnValue == ExceptionNestedException\n");
ExceptionRecord->ExceptionFlags |= EXCEPTION_EXIT_UNWIND;
if (DispatcherContext > Temp)
{
Temp = DispatcherContext;
}
}
else /* if (ReturnValue == ExceptionCollidedUnwind) */
{
DPRINT("ReturnValue == ExceptionCollidedUnwind or unknown\n");
ExceptionRecord2.ExceptionRecord = ExceptionRecord;
ExceptionRecord2.ExceptionCode = STATUS_INVALID_DISPOSITION;
ExceptionRecord2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
ExceptionRecord2.NumberParameters = 0;
RtlRaiseException(&ExceptionRecord2);
}
RegistrationFrame = RegistrationFrame->prev; // Go to previous frame
}
/* No exception handler will handle this exception */
DPRINT("RtlpDispatchException(): Return ExceptionContinueExecution\n");
return ExceptionContinueExecution;
}
VOID STDCALL
RtlRaiseStatus(NTSTATUS Status)
{
EXCEPTION_RECORD ExceptionRecord;
DPRINT("RtlRaiseStatus(Status 0x%.08x)\n", Status);
ExceptionRecord.ExceptionCode = Status;
ExceptionRecord.ExceptionRecord = NULL;
ExceptionRecord.NumberParameters = 0;
ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
RtlRaiseException (& ExceptionRecord);
}
VOID STDCALL
RtlUnwind(PEXCEPTION_REGISTRATION RegistrationFrame,
PVOID ReturnAddress,
PEXCEPTION_RECORD ExceptionRecord,
DWORD EaxValue)
{
PEXCEPTION_REGISTRATION ERHead;
PEXCEPTION_RECORD pExceptRec;
EXCEPTION_RECORD TempER;
CONTEXT Context;
DPRINT("RtlUnwind(). RegistrationFrame 0x%X\n", RegistrationFrame);
#ifndef NDEBUG
RtlpDumpExceptionRegistrations();
#endif /* NDEBUG */
ERHead = SehpGetExceptionList();
DPRINT("ERHead is 0x%X\n", ERHead);
if (ExceptionRecord == NULL) // The normal case
{
DPRINT("ExceptionRecord == NULL (normal)\n");
pExceptRec = &TempER;
pExceptRec->ExceptionFlags = 0;
pExceptRec->ExceptionCode = STATUS_UNWIND;
pExceptRec->ExceptionRecord = NULL;
pExceptRec->ExceptionAddress = ReturnAddress;
pExceptRec->ExceptionInformation[0] = 0;
}
if (RegistrationFrame)
pExceptRec->ExceptionFlags |= EXCEPTION_UNWINDING;
else
pExceptRec->ExceptionFlags |= (EXCEPTION_UNWINDING|EXCEPTION_EXIT_UNWIND);
#ifndef NDEBUG
DPRINT("ExceptionFlags == 0x%x:\n", pExceptRec->ExceptionFlags);
if (pExceptRec->ExceptionFlags & EXCEPTION_UNWINDING)
{
DPRINT(" * EXCEPTION_UNWINDING (0x%x)\n", EXCEPTION_UNWINDING);
}
if (pExceptRec->ExceptionFlags & EXCEPTION_EXIT_UNWIND)
{
DPRINT(" * EXCEPTION_EXIT_UNWIND (0x%x)\n", EXCEPTION_EXIT_UNWIND);
}
#endif /* NDEBUG */
Context.ContextFlags =
(CONTEXT_i386 | CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS);
SehpCaptureContext(&Context);
DPRINT("Context.Eip = 0x%.08x\n", Context.Eip);
DPRINT("Context.Ebp = 0x%.08x\n", Context.Ebp);
DPRINT("Context.Esp = 0x%.08x\n", Context.Esp);
Context.Esp += 0x10;
Context.Eax = EaxValue;
// Begin traversing the list of EXCEPTION_REGISTRATION
while ((ULONG_PTR)ERHead != -1)
{
EXCEPTION_RECORD er2;
DPRINT("ERHead 0x%X\n", ERHead);
if (ERHead == RegistrationFrame)
{
DPRINT("Continueing execution\n");
NtContinue(&Context, FALSE);
return;
}
else
{
// If there's an exception frame, but it's lower on the stack
// than the head of the exception list, something's wrong!
if (RegistrationFrame && (RegistrationFrame <= ERHead))
{
DPRINT("The exception frame is bad\n");
// Generate an exception to bail out
er2.ExceptionRecord = pExceptRec;
er2.NumberParameters = 0;
er2.ExceptionCode = STATUS_INVALID_UNWIND_TARGET;
er2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
RtlRaiseException(&er2);
}
}
#if 0
Stack = ERHead + sizeof(EXCEPTION_REGISTRATION);
if ( (Teb->Tib.StackBase <= (PVOID)ERHead ) // Make sure that ERHead
&& (Teb->Tib.->StackLimit >= (PVOID)Stack ) // is in range, and a multiple
&& (0 == ((ULONG_PTR)ERHead & 3)) ) // of 4 (i.e., sane)
{
#else
if (1) {
#endif
PEXCEPTION_REGISTRATION NewERHead;
PEXCEPTION_REGISTRATION pCurrExceptReg;
EXCEPTION_DISPOSITION ReturnValue;
DPRINT("Executing handler at 0x%X for unwind\n", ERHead->handler);
ReturnValue = RtlpExecuteHandlerForUnwind(
pExceptRec,
ERHead,
&Context,
&NewERHead,
ERHead->handler);
DPRINT("Handler at 0x%X returned 0x%X\n", ERHead->handler, ReturnValue);
if (ReturnValue != ExceptionContinueSearch)
{
if (ReturnValue != ExceptionCollidedUnwind)
{
DPRINT("Bad return value\n");
er2.ExceptionRecord = pExceptRec;
er2.NumberParameters = 0;
er2.ExceptionCode = STATUS_INVALID_DISPOSITION;
er2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
RtlRaiseException(&er2);
}
else
{
ERHead = NewERHead;
}
}
pCurrExceptReg = ERHead;
ERHead = ERHead->prev;
DPRINT("New ERHead is 0x%X\n", ERHead);
DPRINT("Setting exception registration at 0x%X as current\n",
RegistrationFrame->prev);
// Unlink the exception handler
SehpSetExceptionList(RegistrationFrame->prev);
}
else // The stack looks goofy! Raise an exception to bail out
{
DPRINT("Bad stack\n");
er2.ExceptionRecord = pExceptRec;
er2.NumberParameters = 0;
er2.ExceptionCode = STATUS_BAD_STACK;
er2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
RtlRaiseException(&er2);
}
}
// If we get here, we reached the end of the EXCEPTION_REGISTRATION list.
// This shouldn't happen normally.
DPRINT("Ran out of exception registrations. RegistrationFrame is (0x%X)\n",
RegistrationFrame);
if ((ULONG_PTR)RegistrationFrame == -1)
NtContinue(&Context, FALSE);
else
NtRaiseException(pExceptRec, &Context, 0);
}
/* EOF */

View file

@ -1,17 +1,17 @@
/* $Id: except.s,v 1.1 2002/10/26 00:36:54 chorns Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: Kernel-mode exception support for IA-32
* FILE: ntoskrnl/rtl/i386/except.s
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
* NOTES: This file is shared with lib/ntdll/rtl/i386/except.s.
* Please keep them in sync.
*/
#define EXCEPTION_UNWINDING 0x02
/* $Id: except.s,v 1.2 2002/10/26 07:32:08 chorns Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: Kernel-mode exception support for IA-32
* FILE: ntoskrnl/rtl/i386/except.s
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
* NOTES: This file is shared with lib/ntdll/rtl/i386/except.s.
* Please keep them in sync.
*/
#define EREC_FLAGS 0x04
#define EXCEPTION_UNWINDING 0x02
#define EREC_FLAGS 0x04
#define ExceptionContinueExecution 0
#define ExceptionContinueSearch 1
@ -125,9 +125,9 @@ _RtlpCaptureContext:
#define REH_ERECORD 0x08
#define REH_RFRAME 0x0C
#define REH_CONTEXT 0x10
#define REH_DCONTEXT 0x14
#define REH_EROUTINE 0x18
#define REH_CONTEXT 0x10
#define REH_DCONTEXT 0x14
#define REH_EROUTINE 0x18
// Parameters:
// None
@ -141,8 +141,8 @@ _RtlpCaptureContext:
// Returns:
// EXCEPTION_DISPOSITION
// Notes:
// Setup the protecting exception handler and call the exception
// handler in the right context.
// Setup the protecting exception handler and call the exception
// handler in the right context.
_RtlpExecuteHandler:
pushl %ebp
movl %esp, %ebp
@ -161,21 +161,21 @@ _RtlpExecuteHandler:
// Now call the exception handler
movl REH_EROUTINE(%ebp), %eax
call *%eax
cmpl $-1, %fs:0x0
jne .reh_stack_looks_ok
// This should not happen
pushl 0
pushl 0
pushl 0
pushl 0
call _RtlAssert@16
.reh_loop:
jmp .reh_loop
.reh_stack_looks_ok:
cmpl $-1, %fs:0x0
jne .reh_stack_looks_ok
// This should not happen
pushl 0
pushl 0
pushl 0
pushl 0
call _RtlAssert@16
.reh_loop:
jmp .reh_loop
.reh_stack_looks_ok:
movl %fs:0x0, %esp
// Return to the 'front-end' for this function
@ -201,18 +201,19 @@ _RtlpExecuteHandler:
// EXCEPTION_DISPOSITION
// Notes:
// This exception handler protects the exception handling
// mechanism by detecting nested exceptions.
// mechanism by detecting nested exceptions.
_RtlpExceptionProtector:
movl $ExceptionContinueSearch, %eax
movl REP_ERECORD(%esp), %ecx
movl REP_ERECORD(%esp), %ecx
testl $EXCEPTION_UNWINDING, EREC_FLAGS(%ecx)
jnz .rep_end
// Unwinding is not taking place, so return ExceptionNestedException
// Set DispatcherContext field to the exception registration for the
// exception handler that executed when a nested exception occurred
movl REP_DCONTEXT(%esp), %ecx movl REP_RFRAME(%esp), %eax
// Set DispatcherContext field to the exception registration for the
// exception handler that executed when a nested exception occurred
movl REP_DCONTEXT(%esp), %ecx
movl REP_RFRAME(%esp), %eax
movl %eax, (%ecx)
movl $ExceptionNestedException, %eax
@ -273,8 +274,8 @@ _RtlpUnwindProtector:
.rup_end:
ret
// Parameters:
// [ESP+04h] - PEXCEPTION_RECORD ExceptionRecord
// [ESP+08h] - PEXCEPTION_REGISTRATION RegistrationFrame

View file

@ -1,13 +1,13 @@
/* $Id: seh.s,v 1.1 2002/10/26 00:38:01 chorns Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: Runtime library exception support for IA-32
* FILE: ntoskrnl/rtl/i386/seh.s
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
* NOTES: This file is shared with lib/msvcrt/except/seh.s.
* Please keep them in sync.
*/
/* $Id: seh.s,v 1.2 2002/10/26 07:32:08 chorns Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: Runtime library exception support for IA-32
* FILE: ntoskrnl/rtl/i386/seh.s
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
* NOTES: This file is shared with lib/msvcrt/except/seh.s.
* Please keep them in sync.
*/
#define ExceptionContinueExecution 0
#define ExceptionContinueSearch 1
@ -49,11 +49,11 @@
#define ST_TRYLEVEL 0x00
#define ST_FILTER 0x04
#define ST_HANDLER 0x08
#define CONTEXT_EDI 0x9C
#define CONTEXT_EBX 0xA4
#define CONTEXT_EIP 0xB8
.globl __local_unwind2
.globl __except_handler3
@ -67,12 +67,12 @@ _do_debug:
#define LU2_TRYLEVEL 0x08
#define LU2_REGFRAME 0x04
//
// void
// _local_unwind2(PEXCEPTION_REGISTRATION RegistrationFrame,
// LONG TryLevel)
//
//
// void
// _local_unwind2(PEXCEPTION_REGISTRATION RegistrationFrame,
// LONG TryLevel)
//
// Parameters:
// [EDX+08h] - PEXCEPTION_REGISTRATION RegistrationFrame
// [EDX+04h] - LONG TryLevel