Author: hyperion Date: Sat Dec 13 20:55:50 2008 New Revision: 38069
URL: http://svn.reactos.org/svn/reactos?rev=38069&view=rev Log: modified lib/pseh/framebased-gcchack.c modified lib/pseh/i386/framebased-gcchack.S Correctly chain exceptions raised during unwinding by "finally" blocks Sanitize direction flag before any C code is executed, just to be totally safe Clean up code
Modified: trunk/reactos/lib/pseh/framebased-gcchack.c trunk/reactos/lib/pseh/i386/framebased-gcchack.S
Modified: trunk/reactos/lib/pseh/framebased-gcchack.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/pseh/framebased-gcchack... ============================================================================== --- trunk/reactos/lib/pseh/framebased-gcchack.c [iso-8859-1] (original) +++ trunk/reactos/lib/pseh/framebased-gcchack.c [iso-8859-1] Sat Dec 13 20:55:50 2008 @@ -29,25 +29,28 @@
#include <excpt.h>
+#ifndef EXCEPTION_EXIT_UNWIND +#define EXCEPTION_EXIT_UNWIND 4 +#endif + +#ifndef EXCEPTION_UNWINDING +#define EXCEPTION_UNWINDING 2 +#endif + extern _SEH2Registration_t * __cdecl _SEH2CurrentRegistration(void); +extern void _SEH2GlobalUnwind(void *);
extern int __SEH2Except(void *, void *, void *); extern void __SEH2Finally(void *, void *); +extern DECLSPEC_NORETURN int __SEH2Handle(void *, void *, void *);
-extern -#if defined(__GNUC__) -__attribute__((noreturn)) -#elif defined(_MSC_VER) -__declspec(noreturn) -#endif -int __SEH2Handle(void *, void *, void *); +extern void __cdecl __SEH2EnterFrame(_SEH2Registration_t *); +extern void __cdecl __SEH2LeaveFrame(void);
-static -#if defined(__GNUC__) -__attribute__((always_inline)) -#elif defined(_MSC_VER) -__forceinline -#endif +extern int __cdecl __SEH2FrameHandler(struct _EXCEPTION_RECORD *, void *, struct _CONTEXT *, void *); +extern int __cdecl __SEH2NestedHandler(struct _EXCEPTION_RECORD *, void *, struct _CONTEXT *, void *); + +FORCEINLINE int _SEH2Except(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * trylevel, EXCEPTION_POINTERS * ep) { return __SEH2Except(trylevel->ST_Filter, trylevel->ST_FramePointer, ep); @@ -56,18 +59,36 @@ static #if defined(__GNUC__) __attribute__((noinline)) -#elif defined(_MSC_VER) -__declspec(noinline) #endif void _SEH2Finally(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * trylevel) { __SEH2Finally(trylevel->ST_Body, trylevel->ST_FramePointer); }
+extern +int __cdecl _SEH2NestedHandler +( + struct _EXCEPTION_RECORD * ExceptionRecord, + void * EstablisherFrame, + struct _CONTEXT * ContextRecord, + void * DispatcherContext +) +{ + if(ExceptionRecord->ExceptionFlags & (EXCEPTION_EXIT_UNWIND | EXCEPTION_UNWINDING)) + return ExceptionContinueSearch; + + *((void **)DispatcherContext) = EstablisherFrame; + return ExceptionCollidedUnwind; +} + static void _SEH2LocalUnwind(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * dsttrylevel) { volatile _SEH2TryLevel_t * trylevel; + _SEH2Registration_t nestedframe; + + nestedframe.SER_Handler = &__SEH2NestedHandler; + __SEH2EnterFrame(&nestedframe);
for(trylevel = frame->SF_TopTryLevel; trylevel && trylevel != dsttrylevel; trylevel = trylevel->ST_Next) { @@ -76,16 +97,11 @@ }
frame->SF_TopTryLevel = dsttrylevel; + + __SEH2LeaveFrame(); }
-extern void _SEH2GlobalUnwind(void *); - -static -#if defined(__GNUC__) -__attribute__((noreturn)) -#elif defined(_MSC_VER) -__declspec(noreturn) -#endif +static DECLSPEC_NORETURN void _SEH2Handle(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * trylevel) { _SEH2GlobalUnwind(frame); @@ -93,7 +109,7 @@ __SEH2Handle(trylevel->ST_Body, frame->SF_FramePointer, frame->SF_StackPointer); }
-static +extern int __cdecl _SEH2FrameHandler ( struct _EXCEPTION_RECORD * ExceptionRecord, @@ -104,16 +120,10 @@ { _SEH2Frame_t * frame;
-#if defined(__GNUC__) - __asm__ __volatile__("cld"); -#elif defined(_MSC_VER) - __asm cld -#endif - frame = EstablisherFrame;
/* Unwinding */ - if(ExceptionRecord->ExceptionFlags & (4 | 2)) + if(ExceptionRecord->ExceptionFlags & (EXCEPTION_EXIT_UNWIND | EXCEPTION_UNWINDING)) { _SEH2LocalUnwind(frame, NULL); } @@ -148,18 +158,12 @@ }
extern -void __cdecl __SEH2EnterFrame(_SEH2Frame_t *); - -extern void __cdecl _SEH2EnterFrame(_SEH2Frame_t * frame) { - frame->SF_Registration.SER_Handler = _SEH2FrameHandler; + frame->SF_Registration.SER_Handler = __SEH2FrameHandler; frame->SF_Code = 0; - __SEH2EnterFrame(frame); + __SEH2EnterFrame(&frame->SF_Registration); } - -extern -void __cdecl __SEH2LeaveFrame(void);
extern void __cdecl _SEH2LeaveFrame(void)
Modified: trunk/reactos/lib/pseh/i386/framebased-gcchack.S URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/pseh/i386/framebased-gc... ============================================================================== --- trunk/reactos/lib/pseh/i386/framebased-gcchack.S [iso-8859-1] (original) +++ trunk/reactos/lib/pseh/i386/framebased-gcchack.S [iso-8859-1] Sat Dec 13 20:55:50 2008 @@ -92,4 +92,20 @@
ret
+.globl ___SEH2FrameHandler +___SEH2FrameHandler: + +.extern __SEH2FrameHandler + + cld + jmp __SEH2FrameHandler + +.globl ___SEH2NestedHandler +___SEH2NestedHandler: + +.extern __SEH2NestedHandler + + cld + jmp __SEH2NestedHandler + // EOF