Author: hyperion Date: Mon Dec 22 20:45:25 2008 New Revision: 38295
URL: http://svn.reactos.org/svn/reactos?rev=38295&view=rev Log: modified include/reactos/libs/pseh/pseh2.h modified lib/pseh/framebased-gcchack.c modified lib/pseh/i386/framebased-gcchack.S (Re)added arguments to _SEH2_EXCEPT nested routines, so that using _SEH2_GetExceptionCode and _SEH2_GetExceptionInformation in exception filters doesn't force the creation of function trampolines (and related horrid inline code) Reimplemented some internal library routines in C
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] Mon Dec 22 20:45:25 2008 @@ -46,7 +46,6 @@ { _SEH2Registration_t SF_Registration; volatile struct __SEH2TryLevel * volatile SF_TopTryLevel; - struct _EXCEPTION_POINTERS * volatile SF_ExceptionInformation; volatile unsigned long SF_Code; } _SEH2Frame_t; @@ -140,15 +139,23 @@ #define __SEH_FORCE_NEST \ __asm__ __volatile__("#%0" : : "r" (&_SEHFrame))
-#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) - -#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_EXCEPT_RET long +#define __SEH_EXCEPT_ARGS __attribute__((unused)) _SEH2Frame_t * _SEH2FrameP, __attribute__((unused)) struct _EXCEPTION_POINTERS * _SEHExceptionInformation +#define __SEH_EXCEPT_ARGS_ , __SEH_EXCEPT_ARGS +#define __SEH_EXCEPT_PFN __SEH_DECLARE_EXCEPT_PFN +#define __SEH_DECLARE_EXCEPT_PFN(NAME_) __SEH_EXCEPT_RET (__cdecl * NAME_)(__SEH_EXCEPT_ARGS) +#define __SEH_DECLARE_EXCEPT(NAME_) __SEH_EXCEPT_RET __cdecl NAME_(__SEH_EXCEPT_ARGS) +#define __SEH_DEFINE_EXCEPT(NAME_) __SEH_EXCEPT_RET __cdecl NAME_(__SEH_EXCEPT_ARGS) + +#define __SEH_FINALLY_RET void +#define __SEH_FINALLY_ARGS void +#define __SEH_FINALLY_ARGS_ +#define __SEH_FINALLY_PFN __SEH_DECLARE_FINALLY_PFN +#define __SEH_DECLARE_FINALLY_PFN(NAME_) __SEH_FINALLY_RET (__cdecl * NAME_)(__SEH_FINALLY_ARGS) +#define __SEH_DECLARE_FINALLY(NAME_) __SEH_FINALLY_RET __cdecl NAME_(__SEH_FINALLY_ARGS) +#define __SEH_DEFINE_FINALLY(NAME_) __SEH_FINALLY_RET __cdecl NAME_(__SEH_FINALLY_ARGS) + +#define __SEH_RETURN_EXCEPT(R_) return (long)(R_) #define __SEH_RETURN_FINALLY() return
#define __SEH_BEGIN_TRY \ @@ -175,9 +182,9 @@ #define __SEH_LEAVE_TRYLEVEL() __SEH_SET_TRYLEVEL(_SEHPrevTryLevelP)
#define __SEH_END_SCOPE_CHAIN \ - static const int _SEH2ScopeKind = 1; \ - static _SEH2Frame_t * const _SEH2FrameP = 0; \ - static _SEH2TryLevel_t * const _SEH2TryLevelP = 0; + static __attribute__((unused)) const int _SEH2ScopeKind = 1; \ + static __attribute__((unused)) _SEH2Frame_t * const _SEH2FrameP = 0; \ + static __attribute__((unused)) _SEH2TryLevel_t * const _SEH2TryLevelP = 0;
#define __SEH_BEGIN_SCOPE \ for(;;) \ @@ -287,35 +294,39 @@ \ _SEHBeforeTry:; \ \ - if(__builtin_constant_p((__VA_ARGS__))) \ - { \ - if((__VA_ARGS__) > 0) \ + { \ + __attribute__((unused)) struct _EXCEPTION_POINTERS * volatile _SEHExceptionInformation; \ + \ + if(__builtin_constant_p((__VA_ARGS__))) \ { \ - _SEHTryLevel.ST_Filter = (void *)1; \ + if((__VA_ARGS__) > 0) \ + { \ + _SEHTryLevel.ST_Filter = (void *)1; \ + _SEHTryLevel.ST_Body = &&_SEHBeginExcept; \ + __SEH_USE_LABEL(_SEHBeginExcept); \ + } \ + else if((__VA_ARGS__) < 0) \ + { \ + _SEHTryLevel.ST_Filter = (void *)-1; \ + _SEHTryLevel.ST_Body = NULL; \ + } \ + else \ + { \ + _SEHTryLevel.ST_Filter = (void *)0; \ + _SEHTryLevel.ST_Body = NULL; \ + } \ + } \ + else \ + { \ + __SEH_DEFINE_EXCEPT(_SEHExcept) \ + { \ + __SEH_RETURN_EXCEPT((__VA_ARGS__)); \ + } \ + \ + _SEHTryLevel.ST_Filter = &_SEHExcept; \ _SEHTryLevel.ST_Body = &&_SEHBeginExcept; \ __SEH_USE_LABEL(_SEHBeginExcept); \ } \ - else if((__VA_ARGS__) < 0) \ - { \ - _SEHTryLevel.ST_Filter = (void *)-1; \ - _SEHTryLevel.ST_Body = NULL; \ - } \ - else \ - { \ - _SEHTryLevel.ST_Filter = (void *)0; \ - _SEHTryLevel.ST_Body = NULL; \ - } \ - } \ - else \ - { \ - __SEH_DEFINE_EXCEPT(_SEHExcept) \ - { \ - __SEH_RETURN_EXCEPT((__VA_ARGS__)); \ - } \ - \ - _SEHTryLevel.ST_Filter = &_SEHExcept; \ - _SEHTryLevel.ST_Body = &&_SEHBeginExcept; \ - __SEH_USE_LABEL(_SEHBeginExcept); \ } \ \ __SEH_BARRIER; \ @@ -347,8 +358,6 @@ _SEHBeginExcept:; \ { \ { \ - _SEH2Frame_t * const _SEH2FrameP = _SEHTopTryLevel ? &_SEHFrame : _SEHCurFrameP; \ - (void)_SEH2FrameP; \ __SEH_BARRIER;
#define _SEH2_END \ @@ -360,7 +369,7 @@ } \ __SEH_END_SCOPE;
-#define _SEH2_GetExceptionInformation() ((_SEH2FrameP)->SF_ExceptionInformation) +#define _SEH2_GetExceptionInformation() (_SEHExceptionInformation) #define _SEH2_GetExceptionCode() ((_SEH2FrameP)->SF_Code) #define _SEH2_AbnormalTermination() (_SEHAbnormalTermination)
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] Mon Dec 22 20:45:25 2008 @@ -20,14 +20,15 @@ DEALINGS IN THE SOFTWARE. */
-#define _NTSYSTEM_ +#define _NTSYSTEM_ /* removes dllimport attribute from RtlUnwind */ + #define STRICT #define WIN32_LEAN_AND_MEAN #include <windows.h>
#include <pseh/pseh2.h> - #include <excpt.h> +#include <intrin.h>
#ifndef EXCEPTION_EXIT_UNWIND #define EXCEPTION_EXIT_UNWIND 4 @@ -37,17 +38,28 @@ #define EXCEPTION_UNWINDING 2 #endif
-extern _SEH2Registration_t * __cdecl _SEH2CurrentRegistration(void); - -extern int __SEH2Except(void *, void *); -extern void __SEH2Finally(void *, void *); extern DECLSPEC_NORETURN int __SEH2Handle(void *, void *, void *); - -extern void __cdecl __SEH2EnterFrame(_SEH2Registration_t *); -extern void __cdecl __SEH2LeaveFrame(void); - extern int __cdecl __SEH2FrameHandler(struct _EXCEPTION_RECORD *, void *, struct _CONTEXT *, void *); extern int __cdecl __SEH2NestedHandler(struct _EXCEPTION_RECORD *, void *, struct _CONTEXT *, void *); + +FORCEINLINE +_SEH2Registration_t * __cdecl _SEH2CurrentRegistration(void) +{ + return (_SEH2Registration_t *)__readfsdword(0); +} + +FORCEINLINE +void __cdecl __SEH2EnterFrame(_SEH2Registration_t * frame) +{ + frame->SER_Prev = _SEH2CurrentRegistration(); + __writefsdword(0, (unsigned long)frame); +} + +FORCEINLINE +void __cdecl __SEH2LeaveFrame(void) +{ + __writefsdword(0, (unsigned long)_SEH2CurrentRegistration()->SER_Prev); +}
FORCEINLINE void _SEH2GlobalUnwind(void * target) @@ -67,11 +79,12 @@ ); }
-FORCEINLINE -int _SEH2Except(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * trylevel) +static +__SEH_EXCEPT_RET _SEH2Except(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * trylevel, struct _EXCEPTION_POINTERS * ep) { void * filter = trylevel->ST_Filter; void * context = NULL; + __SEH_EXCEPT_RET ret;
if(filter == (void *)0) return 0; @@ -88,10 +101,22 @@ filter = _SEHFunctionFromTrampoline((_SEHTrampoline_t *)filter); }
- return __SEH2Except(filter, context); -} - -FORCEINLINE + __asm__ __volatile__ + ( + "push %[ep]\n" + "push %[frame]\n" + "call *%[filter]\n" + "pop %%edx\n" + "pop %%edx\n" : + [ret] "=a" (ret) : + "c" (context), [filter] "r" (filter), [frame] "g" (frame), [ep] "g" (ep) : + "edx", "flags", "memory" + ); + + return ret; +} + +static void _SEH2Finally(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * trylevel) { if(trylevel->ST_Filter == NULL && trylevel->ST_Body != NULL) @@ -105,7 +130,7 @@ body = _SEHFunctionFromTrampoline((_SEHTrampoline_t *)body); }
- __SEH2Finally(body, context); + __asm__ __volatile__("call *%1\n" : : "c" (context), "r" (body) : "eax", "edx", "flags", "memory"); } }
@@ -179,11 +204,10 @@ ep.ContextRecord = ContextRecord;
frame->SF_Code = ExceptionRecord->ExceptionCode; - frame->SF_ExceptionInformation = &ep;
for(trylevel = frame->SF_TopTryLevel; trylevel != NULL; trylevel = trylevel->ST_Next) { - ret = _SEH2Except(frame, trylevel); + ret = _SEH2Except(frame, trylevel, &ep);
if(ret < 0) return ExceptionContinueExecution;
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] Mon Dec 22 20:45:25 2008 @@ -21,32 +21,6 @@ .text .intel_syntax noprefix
-.func _SEH2CurrentRegistration -.globl __SEH2CurrentRegistration -__SEH2CurrentRegistration: - mov eax, [fs:0] - ret -.endfunc - -.func __SEH2EnterFrame -.globl ___SEH2EnterFrame -___SEH2EnterFrame: - mov eax, [esp+4] - mov ecx, [fs:0] - mov [eax], ecx - mov [fs:0], eax - ret -.endfunc - -.func __SEH2LeaveFrame -.globl ___SEH2LeaveFrame -___SEH2LeaveFrame: - mov eax, [fs:0] - mov eax, [eax] - mov [fs:0], eax - ret -.endfunc - .func __SEH2Handle .globl ___SEH2Handle ___SEH2Handle: @@ -54,28 +28,6 @@ mov ebp, [esp+8] mov esp, [esp+12] jmp eax -.endfunc - -.func __SEH2Except -.globl ___SEH2Except -___SEH2Except: - mov eax, [esp+4] - mov ecx, [esp+8] - - call eax - - ret -.endfunc - -.func __SEH2Finally -.globl ___SEH2Finally -___SEH2Finally: - mov eax, [esp+4] - mov ecx, [esp+8] - - call eax - - ret .endfunc
.func __SEH2FrameHandler