From 9bbe34eb81e10360af9bb3423f6e0ce2401c37dc Mon Sep 17 00:00:00 2001 From: Casper Hornstrup Date: Sat, 26 Oct 2002 07:32:08 +0000 Subject: [PATCH] 2002-10-26 Casper S. Hornstrup * 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 --- reactos/ChangeLog | 8 + reactos/lib/msvcrt/except/seh.s | 36 +- reactos/lib/ntdll/rtl/i386/except.s | 83 +-- reactos/lib/ntdll/rtl/i386/exception.c | 854 ++++++++++++------------- reactos/ntoskrnl/rtl/i386/except.s | 83 +-- reactos/ntoskrnl/rtl/i386/seh.s | 36 +- 6 files changed, 555 insertions(+), 545 deletions(-) diff --git a/reactos/ChangeLog b/reactos/ChangeLog index 76389d834c6..87c9dfa1670 100644 --- a/reactos/ChangeLog +++ b/reactos/ChangeLog @@ -1,3 +1,11 @@ +2002-10-26 Casper S. Hornstrup + + * 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 * lib/msvcrt/Makefile (OBJECTS_EXCEPT): Add except/seh.o; Remove diff --git a/reactos/lib/msvcrt/except/seh.s b/reactos/lib/msvcrt/except/seh.s index 9b1999eda03..b0b5762f886 100755 --- a/reactos/lib/msvcrt/except/seh.s +++ b/reactos/lib/msvcrt/except/seh.s @@ -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 diff --git a/reactos/lib/ntdll/rtl/i386/except.s b/reactos/lib/ntdll/rtl/i386/except.s index 78b66b73ce3..c6d28abe856 100755 --- a/reactos/lib/ntdll/rtl/i386/except.s +++ b/reactos/lib/ntdll/rtl/i386/except.s @@ -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 diff --git a/reactos/lib/ntdll/rtl/i386/exception.c b/reactos/lib/ntdll/rtl/i386/exception.c index 8f6bba89f27..4886d4aa527 100755 --- a/reactos/lib/ntdll/rtl/i386/exception.c +++ b/reactos/lib/ntdll/rtl/i386/exception.c @@ -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 -#include -#include - -#define NDEBUG -#include - -/* 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 +#include +#include + +#define NDEBUG +#include + +/* 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 */ diff --git a/reactos/ntoskrnl/rtl/i386/except.s b/reactos/ntoskrnl/rtl/i386/except.s index 750c253274e..e5532888420 100755 --- a/reactos/ntoskrnl/rtl/i386/except.s +++ b/reactos/ntoskrnl/rtl/i386/except.s @@ -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 diff --git a/reactos/ntoskrnl/rtl/i386/seh.s b/reactos/ntoskrnl/rtl/i386/seh.s index 411f308e41d..9b0e2b2ec02 100755 --- a/reactos/ntoskrnl/rtl/i386/seh.s +++ b/reactos/ntoskrnl/rtl/i386/seh.s @@ -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