Author: hyperion Date: Wed Nov 26 10:03:12 2008 New Revision: 37663
URL: http://svn.reactos.org/svn/reactos?rev=37663&view=rev Log: modified include/reactos/libs/pseh/pseh2.h If the compiler is not GCC, assume native SEH support
modified lib/pseh/framebased-gcchack.c modified lib/pseh/i386/framebased-gcchack.S Allow pseh to be compiled with Visual C++ without warnings
Modified: trunk/reactos/include/reactos/libs/pseh/pseh2.h trunk/reactos/lib/pseh/framebased-gcchack.c trunk/reactos/lib/pseh/i386/framebased-gcchack.S
Modified: trunk/reactos/include/reactos/libs/pseh/pseh2.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/libs/pseh/p... ============================================================================== --- trunk/reactos/include/reactos/libs/pseh/pseh2.h [iso-8859-1] (original) +++ trunk/reactos/include/reactos/libs/pseh/pseh2.h [iso-8859-1] Wed Nov 26 10:03:12 2008 @@ -23,10 +23,6 @@ #ifndef KJK_PSEH2_H_ #define KJK_PSEH2_H_
-#ifndef __GNUC__ -#error TODO -#endif - struct _EXCEPTION_RECORD; struct _EXCEPTION_POINTERS; struct _CONTEXT; @@ -39,90 +35,12 @@ void * );
-#if defined(__i386__) -typedef struct __SEHTrampoline -{ - unsigned char STR_MovEcx; - unsigned char STR_Closure[4]; - unsigned char STR_Jmp; - unsigned char STR_Function[4]; -} -_SEHTrampoline_t; - -static -__inline__ -__attribute__((always_inline)) -int _SEHIsTrampoline(_SEHTrampoline_t * trampoline_) -{ - return trampoline_->STR_MovEcx == 0xb9 && trampoline_->STR_Jmp == 0xe9; -} - -static -__inline__ -__attribute__((always_inline)) -void * _SEHFunctionFromTrampoline(_SEHTrampoline_t * trampoline_) -{ - return (void *)(*(int *)(&trampoline_->STR_Function[0]) + (int)(trampoline_ + 1)); -} - -static -__inline__ -__attribute__((always_inline)) -void * _SEHClosureFromTrampoline(_SEHTrampoline_t * trampoline_) -{ - return (void *)*(int *)(&trampoline_->STR_Closure[0]); -} -#else -#error TODO -#endif - -/* A no-op side effect that scares GCC */ -#define __SEH_SIDE_EFFECT __asm__ __volatile__("#") - -/* A no-op without any real side effects, but silences warnings */ -#define __SEH_PRETEND_SIDE_EFFECT (void)0 - -/* Forces GCC to consider the specified label reachable */ -#define __SEH_USE_LABEL(L_) __asm__ __volatile__("# %0\n" : : "i" (&&L_)) - -/* Makes GCC pretend the specified label is reachable, to silence warnings */ -#define __SEH_PRETEND_USE_LABEL(L_) (void)(&&L_) - -/* Forces GCC to emit the specified nested function as a function */ -#define __SEH_USE_NESTED_FUNCTION(F_) (void)(&F_) /* __attribute__((noinline)) seems to do the trick */ - -/* Soft memory barrier */ -#define __SEH_BARRIER __asm__ __volatile__("#":::"memory") - -/* GCC doesn't know that this equals zero */ -#define __SEH_ZERO ({ int zero = 0; __asm__ __volatile__("#" : "+g" (zero)); zero; }) - -#define __SEH_FALSE __builtin_expect(__SEH_ZERO, 0) -#define __SEH_TRUE __builtin_expect(!__SEH_ZERO, 1) - typedef struct __SEH2Registration { struct __SEH2Registration * SER_Prev; _SEH2FrameHandler_t SER_Handler; } _SEH2Registration_t; - -#define __SEH_FORCE_NEST \ - __asm__ __volatile__("#%0" : : "r" (&_SEHFrame)) - -#define __SEH_NESTED_PROLOG \ - __SEH_FORCE_NEST; - -#define __SEH_DECLARE_EXCEPT_PFN(NAME_) int (__cdecl * NAME_)(void *) -#define __SEH_DECLARE_EXCEPT(NAME_) int __cdecl NAME_(void *) -#define __SEH_DEFINE_EXCEPT(NAME_) int __cdecl NAME_(void * _SEHExceptionPointers) - -#define __SEH_DECLARE_FINALLY_PFN(NAME_) void (__cdecl * NAME_)(void) -#define __SEH_DECLARE_FINALLY(NAME_) void __cdecl NAME_(void) -#define __SEH_DEFINE_FINALLY(NAME_) void __cdecl NAME_(void) - -#define __SEH_RETURN_EXCEPT(R_) return (int)(R_) -#define __SEH_RETURN_FINALLY() return
typedef struct __SEH2Frame { @@ -142,6 +60,99 @@ void * ST_Body; } _SEH2TryLevel_t; + +#ifdef __cplusplus +extern "C" +{ +#endif + +extern void __cdecl _SEH2EnterFrame(_SEH2Frame_t *); +extern void __cdecl _SEH2LeaveFrame(void); +extern void __cdecl _SEH2Return(void); + +#ifdef __cplusplus +} +#endif + +#if defined(__GNUC__) + +#if defined(__i386__) +typedef struct __SEHTrampoline +{ + unsigned char STR_MovEcx; + unsigned char STR_Closure[4]; + unsigned char STR_Jmp; + unsigned char STR_Function[4]; +} +_SEHTrampoline_t; + +static +__inline__ +__attribute__((always_inline)) +int _SEHIsTrampoline(_SEHTrampoline_t * trampoline_) +{ + return trampoline_->STR_MovEcx == 0xb9 && trampoline_->STR_Jmp == 0xe9; +} + +static +__inline__ +__attribute__((always_inline)) +void * _SEHFunctionFromTrampoline(_SEHTrampoline_t * trampoline_) +{ + return (void *)(*(int *)(&trampoline_->STR_Function[0]) + (int)(trampoline_ + 1)); +} + +static +__inline__ +__attribute__((always_inline)) +void * _SEHClosureFromTrampoline(_SEHTrampoline_t * trampoline_) +{ + return (void *)*(int *)(&trampoline_->STR_Closure[0]); +} +#else +#error TODO +#endif + +/* A no-op side effect that scares GCC */ +#define __SEH_SIDE_EFFECT __asm__ __volatile__("#") + +/* A no-op without any real side effects, but silences warnings */ +#define __SEH_PRETEND_SIDE_EFFECT (void)0 + +/* Forces GCC to consider the specified label reachable */ +#define __SEH_USE_LABEL(L_) __asm__ __volatile__("# %0\n" : : "i" (&&L_)) + +/* Makes GCC pretend the specified label is reachable, to silence warnings */ +#define __SEH_PRETEND_USE_LABEL(L_) (void)(&&L_) + +/* Forces GCC to emit the specified nested function as a function */ +#define __SEH_USE_NESTED_FUNCTION(F_) (void)(&F_) /* __attribute__((noinline)) seems to do the trick */ + +/* Soft memory barrier */ +#define __SEH_BARRIER __asm__ __volatile__("#":::"memory") + +/* GCC doesn't know that this equals zero */ +#define __SEH_ZERO ({ int zero = 0; __asm__ __volatile__("#" : "+g" (zero)); zero; }) + +#define __SEH_FALSE __builtin_expect(__SEH_ZERO, 0) +#define __SEH_TRUE __builtin_expect(!__SEH_ZERO, 1) + +#define __SEH_FORCE_NEST \ + __asm__ __volatile__("#%0" : : "r" (&_SEHFrame)) + +#define __SEH_NESTED_PROLOG \ + __SEH_FORCE_NEST; + +#define __SEH_DECLARE_EXCEPT_PFN(NAME_) int (__cdecl * NAME_)(void *) +#define __SEH_DECLARE_EXCEPT(NAME_) int __cdecl NAME_(void *) +#define __SEH_DEFINE_EXCEPT(NAME_) int __cdecl NAME_(void * _SEHExceptionPointers) + +#define __SEH_DECLARE_FINALLY_PFN(NAME_) void (__cdecl * NAME_)(void) +#define __SEH_DECLARE_FINALLY(NAME_) void __cdecl NAME_(void) +#define __SEH_DEFINE_FINALLY(NAME_) void __cdecl NAME_(void) + +#define __SEH_RETURN_EXCEPT(R_) return (int)(R_) +#define __SEH_RETURN_FINALLY() return
#define __SEH_BEGIN_TRY \ { \ @@ -347,6 +358,7 @@
#define _SEH2_GetExceptionInformation() ((struct _EXCEPTION_POINTERS *)_SEHExceptionPointers) #define _SEH2_GetExceptionCode() ((_SEH2FrameP)->SF_Code) +#define _SEH2_AbnormalTermination() (!!_SEH2_GetExceptionCode())
#define _SEH2_YIELD(STMT_) \ for(;;) \ @@ -361,17 +373,22 @@
__SEH_END_SCOPE_CHAIN;
-#ifdef __cplusplus -extern "C" -{ -#endif - -extern void __cdecl _SEH2EnterFrame(_SEH2Frame_t *); -extern void __cdecl _SEH2LeaveFrame(void); -extern void __cdecl _SEH2Return(void); - -#ifdef __cplusplus -} +#else + +#include <excpt.h> + +#define _SEH2_TRY __try +#define _SEH2_FINALLY __finally +#define _SEH2_EXCEPT(E_) __except((E_)) +#define _SEH2_END + +#define _SEH2_GetExceptionInformation() (GetExceptionInformation()) +#define _SEH2_GetExceptionCode() (GetExceptionCode()) +#define _SEH2_AbnormalTermination() (AbnormalTermination()) + +#define _SEH2_YIELD(STMT_) STMT_ +#define _SEH2_LEAVE __leave + #endif
#endif
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] Wed Nov 26 10:03:12 2008 @@ -34,15 +34,31 @@ extern int __SEH2Except(void *, void *, void *); extern void __SEH2Finally(void *, void *);
+extern +#if defined(__GNUC__) +__attribute__((noreturn)) +#elif defined(_MSC_VER) +__declspec(noreturn) +#endif +int __SEH2Handle(void *, void *, void *); + static +#if defined(__GNUC__) __attribute__((always_inline)) +#elif defined(_MSC_VER) +__forceinline +#endif int _SEH2Except(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * trylevel, EXCEPTION_POINTERS * ep) { return __SEH2Except(trylevel->ST_Filter, trylevel->ST_FramePointer, ep); }
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); @@ -65,22 +81,16 @@ extern void _SEH2GlobalUnwind(void *);
static +#if defined(__GNUC__) __attribute__((noreturn)) +#elif defined(_MSC_VER) +__declspec(noreturn) +#endif void _SEH2Handle(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * trylevel) { _SEH2GlobalUnwind(frame); _SEH2LocalUnwind(frame, trylevel); - - __asm__ __volatile__ - ( - "mov %[frame], %%ebp\n" - "mov %[stack], %%esp\n" - "jmp *%[handler]\n" : - : - [frame] "m" (frame->SF_FramePointer), [stack] "m" (frame->SF_StackPointer), [handler] "r" (trylevel->ST_Body) - ); - - for(;;); + __SEH2Handle(trylevel->ST_Body, frame->SF_FramePointer, frame->SF_StackPointer); }
static @@ -94,7 +104,11 @@ { _SEH2Frame_t * frame;
+#if defined(__GNUC__) __asm__ __volatile__("cld"); +#elif defined(_MSC_VER) + __asm cld +#endif
frame = EstablisherFrame;
@@ -134,28 +148,23 @@ }
extern +void __cdecl __SEH2EnterFrame(_SEH2Frame_t *); + +extern void __cdecl _SEH2EnterFrame(_SEH2Frame_t * frame) { frame->SF_Registration.SER_Handler = _SEH2FrameHandler; frame->SF_Code = 0; - __asm__ __volatile__("movl %%fs:0, %k0\n" : "=q" (frame->SF_Registration.SER_Prev)); - - __SEH_BARRIER; - __asm__ __volatile__("movl %k0, %%fs:0\n" : : "q" (&frame->SF_Registration)); + __SEH2EnterFrame(frame); }
extern -void __cdecl _SEH2LeaveFrame() +void __cdecl __SEH2LeaveFrame(void); + +extern +void __cdecl _SEH2LeaveFrame(void) { - __asm__ __volatile__ - ( - "movl %%fs:0, %%edx\n" - "movl 0(%%edx), %%edx\n" - "movl %%edx, %%fs:0\n" : - : - : - "edx" - ); + __SEH2LeaveFrame(); }
extern
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] Wed Nov 26 10:03:12 2008 @@ -25,6 +25,28 @@ __SEH2CurrentRegistration: mov eax, [fs:0] ret + +.globl ___SEH2EnterFrame +___SEH2EnterFrame: + mov eax, [esp+4] + mov ecx, [fs:0] + mov [eax], ecx + mov [fs:0], eax + ret + +.globl __SEH2LeaveFrame +__SEH2LeaveFrame: + mov eax, [fs:0] + mov eax, [eax] + mov [fs:0], eax + ret + +.globl ___SEH2Handle +___SEH2Handle: + mov eax, [esp+4] + mov ebp, [esp+8] + mov esp, [esp+12] + jmp eax
.globl ___SEH2Except ___SEH2Except: