diff --git a/reactos/include/reactos/libs/pseh/pseh2.h b/reactos/include/reactos/libs/pseh/pseh2.h index 74676fe7706..4e46d43f9d7 100644 --- a/reactos/include/reactos/libs/pseh/pseh2.h +++ b/reactos/include/reactos/libs/pseh/pseh2.h @@ -46,7 +46,6 @@ typedef struct __SEH2Frame { _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 @@ void * _SEHClosureFromTrampoline(_SEHTrampoline_t * trampoline_) #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_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_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_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 (int)(R_) +#define __SEH_RETURN_EXCEPT(R_) return (long)(R_) #define __SEH_RETURN_FINALLY() return #define __SEH_BEGIN_TRY \ @@ -175,9 +182,9 @@ void * _SEHClosureFromTrampoline(_SEHTrampoline_t * trampoline_) #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 @@ void * _SEHClosureFromTrampoline(_SEHTrampoline_t * trampoline_) \ _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; \ - _SEHTryLevel.ST_Body = &&_SEHBeginExcept; \ - __SEH_USE_LABEL(_SEHBeginExcept); \ - } \ - else if((__VA_ARGS__) < 0) \ - { \ - _SEHTryLevel.ST_Filter = (void *)-1; \ - _SEHTryLevel.ST_Body = NULL; \ + 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 \ { \ - _SEHTryLevel.ST_Filter = (void *)0; \ - _SEHTryLevel.ST_Body = NULL; \ - } \ - } \ - else \ - { \ - __SEH_DEFINE_EXCEPT(_SEHExcept) \ - { \ - __SEH_RETURN_EXCEPT((__VA_ARGS__)); \ - } \ + __SEH_DEFINE_EXCEPT(_SEHExcept) \ + { \ + __SEH_RETURN_EXCEPT((__VA_ARGS__)); \ + } \ \ - _SEHTryLevel.ST_Filter = &_SEHExcept; \ - _SEHTryLevel.ST_Body = &&_SEHBeginExcept; \ - __SEH_USE_LABEL(_SEHBeginExcept); \ + _SEHTryLevel.ST_Filter = &_SEHExcept; \ + _SEHTryLevel.ST_Body = &&_SEHBeginExcept; \ + __SEH_USE_LABEL(_SEHBeginExcept); \ + } \ } \ \ __SEH_BARRIER; \ @@ -347,8 +358,6 @@ void * _SEHClosureFromTrampoline(_SEHTrampoline_t * trampoline_) _SEHBeginExcept:; \ { \ { \ - _SEH2Frame_t * const _SEH2FrameP = _SEHTopTryLevel ? &_SEHFrame : _SEHCurFrameP; \ - (void)_SEH2FrameP; \ __SEH_BARRIER; #define _SEH2_END \ @@ -360,7 +369,7 @@ void * _SEHClosureFromTrampoline(_SEHTrampoline_t * trampoline_) } \ __SEH_END_SCOPE; -#define _SEH2_GetExceptionInformation() ((_SEH2FrameP)->SF_ExceptionInformation) +#define _SEH2_GetExceptionInformation() (_SEHExceptionInformation) #define _SEH2_GetExceptionCode() ((_SEH2FrameP)->SF_Code) #define _SEH2_AbnormalTermination() (_SEHAbnormalTermination) diff --git a/reactos/lib/pseh/framebased-gcchack.c b/reactos/lib/pseh/framebased-gcchack.c index efb9cbb27f7..d69f7884f91 100644 --- a/reactos/lib/pseh/framebased-gcchack.c +++ b/reactos/lib/pseh/framebased-gcchack.c @@ -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 #include - #include +#include #ifndef EXCEPTION_EXIT_UNWIND #define EXCEPTION_EXIT_UNWIND 4 @@ -37,18 +38,29 @@ #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 @@ void _SEH2GlobalUnwind(void * target) ); } -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 @@ int _SEH2Except(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * trylevel) filter = _SEHFunctionFromTrampoline((_SEHTrampoline_t *)filter); } - return __SEH2Except(filter, context); + __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; } -FORCEINLINE +static void _SEH2Finally(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * trylevel) { if(trylevel->ST_Filter == NULL && trylevel->ST_Body != NULL) @@ -105,7 +130,7 @@ void _SEH2Finally(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * trylevel) 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 @@ int __cdecl _SEH2FrameHandler 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; diff --git a/reactos/lib/pseh/i386/framebased-gcchack.S b/reactos/lib/pseh/i386/framebased-gcchack.S index 191921fd8f4..d60f6cf7ccb 100644 --- a/reactos/lib/pseh/i386/framebased-gcchack.S +++ b/reactos/lib/pseh/i386/framebased-gcchack.S @@ -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: @@ -56,28 +30,6 @@ ___SEH2Handle: 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 .globl ___SEH2FrameHandler ___SEH2FrameHandler: