mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 16:36:33 +00:00
modified include/reactos/libs/pseh/pseh2.h
modified lib/pseh/framebased-gcchack.c modified lib/pseh/i386/framebased-gcchack.S Don't save just ESP and EBP, save all volatile registers because we might catch an exception thrown by another frame and end up clobbering all volatile registers (thanks to Dmitry Gorbachev for bug report and test case) Conversely, save volatile registers for _SEH2_EXCEPT scopes only Specialized frame setup routines, to reduce the amount of inline code and only de-optimize when strictly necessary svn path=/trunk/; revision=38668
This commit is contained in:
parent
92d6cc1154
commit
d728ecb2ca
3 changed files with 124 additions and 61 deletions
|
@ -56,17 +56,28 @@ typedef struct __SEH2TryLevel
|
|||
volatile struct __SEH2TryLevel * ST_Next;
|
||||
void * ST_Filter;
|
||||
void * ST_Body;
|
||||
void * volatile ST_Ebp;
|
||||
void * volatile ST_Esp;
|
||||
}
|
||||
_SEH2TryLevel_t;
|
||||
|
||||
typedef struct __SEH2HandleTryLevel
|
||||
{
|
||||
_SEH2TryLevel_t SHT_Common;
|
||||
void * volatile SHT_Esp;
|
||||
void * volatile SHT_Ebp;
|
||||
void * volatile SHT_Ebx;
|
||||
void * volatile SHT_Esi;
|
||||
void * volatile SHT_Edi;
|
||||
}
|
||||
_SEH2HandleTryLevel_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
extern __attribute__((returns_twice)) void __cdecl _SEH2EnterFrame(_SEH2Frame_t *);
|
||||
extern int __cdecl _SEH2EnterFrameAndTrylevel(_SEH2Frame_t *, volatile _SEH2TryLevel_t *);
|
||||
extern __attribute__((returns_twice)) int __cdecl _SEH2EnterFrameAndHandleTrylevel(_SEH2Frame_t *, volatile _SEH2HandleTryLevel_t *, void *);
|
||||
extern __attribute__((returns_twice)) int __cdecl _SEH2EnterHandleTrylevel(_SEH2Frame_t *, volatile _SEH2HandleTryLevel_t *, void *);
|
||||
extern void __cdecl _SEH2LeaveFrame(void);
|
||||
extern void __cdecl _SEH2Return(void);
|
||||
|
||||
|
@ -174,8 +185,25 @@ void * _SEHClosureFromTrampoline(_SEHTrampoline_t * trampoline_)
|
|||
__SEH_BARRIER; _SEH2FrameP->SF_TopTryLevel = (TRYLEVEL_); __SEH_BARRIER; \
|
||||
}
|
||||
|
||||
#define __SEH_ENTER_TRYLEVEL() __SEH_SET_TRYLEVEL(&_SEHTryLevel)
|
||||
#define __SEH_LEAVE_TRYLEVEL() __SEH_SET_TRYLEVEL(_SEHPrevTryLevelP)
|
||||
#define __SEH_ENTER_FRAME_AND_TRYLEVEL(TRYLEVEL_) (_SEH2EnterFrameAndTrylevel(_SEH2FrameP, (TRYLEVEL_)))
|
||||
#define __SEH_ENTER_TRYLEVEL(TRYLEVEL_) ((__SEH_SET_TRYLEVEL((TRYLEVEL_))), 0)
|
||||
|
||||
#define __SEH_ENTER_FRAME_AND_HANDLE_TRYLEVEL(TRYLEVEL_, HANDLE_) _SEH2EnterFrameAndHandleTrylevel(_SEH2FrameP, (TRYLEVEL_), (HANDLE_))
|
||||
#define __SEH_ENTER_HANDLE_TRYLEVEL(TRYLEVEL_, HANDLE_) _SEH2EnterHandleTrylevel(_SEH2FrameP, (TRYLEVEL_), (HANDLE_))
|
||||
|
||||
#define __SEH_ENTER_SCOPE(TRYLEVEL_) (_SEHTopTryLevel ? __SEH_ENTER_FRAME_AND_TRYLEVEL(TRYLEVEL_) : __SEH_ENTER_TRYLEVEL(TRYLEVEL_))
|
||||
#define __SEH_ENTER_HANDLE_SCOPE(TRYLEVEL_, HANDLE_) (({ __SEH_BARRIER; __asm__ __volatile__("mov %%esp, %0" : "=m" ((TRYLEVEL_)->SHT_Esp)); __SEH_BARRIER; }), (_SEHTopTryLevel ? __SEH_ENTER_FRAME_AND_HANDLE_TRYLEVEL((TRYLEVEL_), (HANDLE_)) : __SEH_ENTER_HANDLE_TRYLEVEL((TRYLEVEL_), (HANDLE_))))
|
||||
|
||||
#define __SEH_LEAVE_SCOPE() \
|
||||
if(_SEHTopTryLevel) \
|
||||
{ \
|
||||
_SEH2LeaveFrame(); \
|
||||
__asm__ __volatile__("mov %0, %%esp" : : "g" (_SEHStackPointer)); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
__SEH_SET_TRYLEVEL(_SEHPrevTryLevelP); \
|
||||
} \
|
||||
|
||||
#define __SEH_END_SCOPE_CHAIN \
|
||||
static __attribute__((unused)) const int _SEH2ScopeKind = 1; \
|
||||
|
@ -200,27 +228,23 @@ void * _SEHClosureFromTrampoline(_SEHTrampoline_t * trampoline_)
|
|||
__label__ _SEHAfterTry; \
|
||||
static const int _SEH2ScopeKind = 0; \
|
||||
volatile _SEH2TryLevel_t _SEHTryLevel; \
|
||||
volatile _SEH2HandleTryLevel_t _SEHHandleTryLevel; \
|
||||
void * _SEHStackPointer; \
|
||||
volatile _SEH2TryLevel_t * const _SEH2TryLevelP = &_SEHTryLevel; \
|
||||
volatile _SEH2TryLevel_t * _SEH2TryLevelP; \
|
||||
_SEH2Frame_t * const _SEH2FrameP = _SEHTopTryLevel ? \
|
||||
({ __asm__ __volatile__("mov %%esp, %0" : "=g" (_SEHStackPointer)); __builtin_alloca(sizeof(_SEH2Frame_t)); }) : \
|
||||
_SEHCurFrameP; \
|
||||
\
|
||||
(void)_SEH2ScopeKind; \
|
||||
(void)_SEHTryLevel; \
|
||||
(void)_SEHHandleTryLevel; \
|
||||
(void)_SEHStackPointer; \
|
||||
(void)_SEH2FrameP; \
|
||||
(void)_SEH2TryLevelP; \
|
||||
\
|
||||
if(_SEHTopTryLevel) \
|
||||
_SEH2EnterFrame(_SEH2FrameP); \
|
||||
\
|
||||
_SEHTryLevel.ST_Next = _SEHPrevTryLevelP; \
|
||||
goto _SEHBeforeTry; \
|
||||
\
|
||||
_SEHDoTry:; \
|
||||
\
|
||||
__SEH_ENTER_TRYLEVEL();
|
||||
_SEHDoTry:;
|
||||
|
||||
#define __SEH_END_SCOPE \
|
||||
} \
|
||||
|
@ -254,6 +278,9 @@ void * _SEHClosureFromTrampoline(_SEHTrampoline_t * trampoline_)
|
|||
\
|
||||
_SEHTryLevel.ST_Filter = 0; \
|
||||
_SEHTryLevel.ST_Body = &_SEHFinally; \
|
||||
_SEHTryLevel.ST_Next = _SEHPrevTryLevelP; \
|
||||
__SEH_ENTER_SCOPE(&_SEHTryLevel); \
|
||||
_SEH2TryLevelP = &_SEHTryLevel; \
|
||||
\
|
||||
_SEHAbnormalTermination = 1; \
|
||||
\
|
||||
|
@ -262,12 +289,7 @@ void * _SEHClosureFromTrampoline(_SEHTrampoline_t * trampoline_)
|
|||
\
|
||||
_SEHAbnormalTermination = 0; \
|
||||
\
|
||||
if(_SEHTopTryLevel) \
|
||||
_SEH2LeaveFrame(); \
|
||||
else \
|
||||
{ \
|
||||
__SEH_LEAVE_TRYLEVEL(); \
|
||||
} \
|
||||
__SEH_LEAVE_SCOPE(); \
|
||||
\
|
||||
_SEHFinally(); \
|
||||
goto _SEHEndExcept; \
|
||||
|
@ -296,64 +318,51 @@ void * _SEHClosureFromTrampoline(_SEHTrampoline_t * trampoline_)
|
|||
{ \
|
||||
__attribute__((unused)) struct _EXCEPTION_POINTERS * volatile _SEHExceptionInformation; \
|
||||
\
|
||||
if(__builtin_constant_p((__VA_ARGS__))) \
|
||||
if(__builtin_constant_p((__VA_ARGS__)) && (__VA_ARGS__) <= 0) \
|
||||
{ \
|
||||
if((__VA_ARGS__) > 0) \
|
||||
{ \
|
||||
_SEHTryLevel.ST_Filter = (void *)1; \
|
||||
_SEHTryLevel.ST_Body = &&_SEHBeginExcept; \
|
||||
__SEH_USE_LABEL(_SEHBeginExcept); \
|
||||
} \
|
||||
else if((__VA_ARGS__) < 0) \
|
||||
if((__VA_ARGS__) < 0) \
|
||||
{ \
|
||||
_SEHTryLevel.ST_Filter = (void *)-1; \
|
||||
_SEHTryLevel.ST_Body = NULL; \
|
||||
_SEHTryLevel.ST_Body = 0; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
_SEHTryLevel.ST_Filter = (void *)0; \
|
||||
_SEHTryLevel.ST_Body = NULL; \
|
||||
_SEHTryLevel.ST_Body = 0; \
|
||||
} \
|
||||
\
|
||||
_SEHTryLevel.ST_Next = _SEHPrevTryLevelP; \
|
||||
__SEH_ENTER_SCOPE(&_SEHTryLevel); \
|
||||
_SEH2TryLevelP = &_SEHTryLevel; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
__SEH_DEFINE_EXCEPT(_SEHExcept) \
|
||||
if(__builtin_constant_p((__VA_ARGS__)) && (__VA_ARGS__) > 0) \
|
||||
_SEHHandleTryLevel.SHT_Common.ST_Filter = (void *)1; \
|
||||
else \
|
||||
{ \
|
||||
__SEH_RETURN_EXCEPT((__VA_ARGS__)); \
|
||||
__SEH_DEFINE_EXCEPT(_SEHExcept) \
|
||||
{ \
|
||||
__SEH_RETURN_EXCEPT((__VA_ARGS__)); \
|
||||
} \
|
||||
\
|
||||
_SEHHandleTryLevel.SHT_Common.ST_Filter = &_SEHExcept; \
|
||||
} \
|
||||
\
|
||||
_SEHTryLevel.ST_Filter = &_SEHExcept; \
|
||||
_SEHTryLevel.ST_Body = &&_SEHBeginExcept; \
|
||||
__SEH_USE_LABEL(_SEHBeginExcept); \
|
||||
_SEHHandleTryLevel.SHT_Common.ST_Next = _SEHPrevTryLevelP; \
|
||||
_SEH2TryLevelP = &_SEHHandleTryLevel.SHT_Common; \
|
||||
\
|
||||
if(__builtin_expect(__SEH_ENTER_HANDLE_SCOPE(&_SEHHandleTryLevel, &&_SEHBeginExcept), 0)) \
|
||||
goto _SEHBeginExcept; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
__SEH_BARRIER; \
|
||||
\
|
||||
__asm__ __volatile__ \
|
||||
( \
|
||||
"mov %%ebp, %0\n" \
|
||||
"mov %%esp, %1" : \
|
||||
"=m" (_SEHTryLevel.ST_Ebp), \
|
||||
"=m" (_SEHTryLevel.ST_Esp) \
|
||||
); \
|
||||
\
|
||||
__SEH_BARRIER; \
|
||||
\
|
||||
goto _SEHDoTry; \
|
||||
\
|
||||
__attribute__((unused)) __SEH_DEFINE_FINALLY(_SEHFinally) { __SEH_RETURN_FINALLY(); } \
|
||||
\
|
||||
_SEHAfterTry:; \
|
||||
if(_SEHTopTryLevel) \
|
||||
{ \
|
||||
_SEH2LeaveFrame(); \
|
||||
__asm__ __volatile__("mov %0, %%esp" : : "g" (_SEHStackPointer)); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
__SEH_LEAVE_TRYLEVEL(); \
|
||||
} \
|
||||
__SEH_LEAVE_SCOPE(); \
|
||||
\
|
||||
goto _SEHEndExcept; \
|
||||
\
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
#define EXCEPTION_UNWINDING 2
|
||||
#endif
|
||||
|
||||
extern DECLSPEC_NORETURN int __SEH2Handle(void *, void *, void *);
|
||||
extern DECLSPEC_NORETURN int __SEH2Handle(void *, void *, void *, void *, void *, void *);
|
||||
extern int __cdecl __SEH2FrameHandler(struct _EXCEPTION_RECORD *, void *, struct _CONTEXT *, void *);
|
||||
extern int __cdecl __SEH2UnwindHandler(struct _EXCEPTION_RECORD *, void *, struct _CONTEXT *, void *);
|
||||
|
||||
|
@ -188,9 +188,20 @@ void _SEH2LocalUnwind(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * dsttrylev
|
|||
static DECLSPEC_NORETURN
|
||||
void _SEH2Handle(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * trylevel)
|
||||
{
|
||||
volatile _SEH2HandleTryLevel_t * fulltrylevel = CONTAINING_RECORD(trylevel, _SEH2HandleTryLevel_t, SHT_Common);
|
||||
|
||||
_SEH2GlobalUnwind(frame);
|
||||
_SEH2LocalUnwind(frame, trylevel);
|
||||
__SEH2Handle(trylevel->ST_Body, trylevel->ST_Ebp, trylevel->ST_Esp);
|
||||
_SEH2LocalUnwind(frame, &fulltrylevel->SHT_Common);
|
||||
|
||||
__SEH2Handle
|
||||
(
|
||||
fulltrylevel->SHT_Common.ST_Body,
|
||||
fulltrylevel->SHT_Esp,
|
||||
fulltrylevel->SHT_Ebp,
|
||||
fulltrylevel->SHT_Ebx,
|
||||
fulltrylevel->SHT_Esi,
|
||||
fulltrylevel->SHT_Edi
|
||||
);
|
||||
}
|
||||
|
||||
extern
|
||||
|
@ -241,11 +252,18 @@ extern
|
|||
void __cdecl _SEH2EnterFrame(_SEH2Frame_t * frame)
|
||||
{
|
||||
frame->SF_Registration.SER_Handler = __SEH2FrameHandler;
|
||||
frame->SF_TopTryLevel = 0;
|
||||
frame->SF_Code = 0;
|
||||
__SEH2EnterFrame(&frame->SF_Registration);
|
||||
}
|
||||
|
||||
extern
|
||||
int __cdecl _SEH2EnterFrameAndTrylevel(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * trylevel)
|
||||
{
|
||||
frame->SF_TopTryLevel = trylevel;
|
||||
_SEH2EnterFrame(frame);
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern
|
||||
void __cdecl _SEH2LeaveFrame(void)
|
||||
{
|
||||
|
|
|
@ -21,12 +21,48 @@
|
|||
.text
|
||||
.intel_syntax noprefix
|
||||
|
||||
.func _SEH2EnterHandleTrylevel
|
||||
.globl __SEH2EnterHandleTrylevel
|
||||
__SEH2EnterHandleTrylevel:
|
||||
mov eax, [esp+8]
|
||||
mov ecx, [esp+12]
|
||||
mov [eax+8], ecx
|
||||
mov [eax+16], ebp
|
||||
mov [eax+20], ebx
|
||||
mov [eax+24], esi
|
||||
mov [eax+28], edi
|
||||
|
||||
mov edx, [esp+4]
|
||||
mov [edx+8], eax
|
||||
|
||||
xor eax, eax
|
||||
ret
|
||||
.endfunc
|
||||
|
||||
.func _SEH2EnterFrameAndHandleTrylevel
|
||||
.globl __SEH2EnterFrameAndHandleTrylevel
|
||||
__SEH2EnterFrameAndHandleTrylevel:
|
||||
mov eax, [esp+8]
|
||||
mov ecx, [esp+12]
|
||||
mov [eax+8], ecx
|
||||
mov [eax+16], ebp
|
||||
mov [eax+20], ebx
|
||||
mov [eax+24], esi
|
||||
mov [eax+28], edi
|
||||
|
||||
.extern __SEH2EnterFrameAndTrylevel
|
||||
jmp __SEH2EnterFrameAndTrylevel
|
||||
.endfunc
|
||||
|
||||
.func __SEH2Handle
|
||||
.globl ___SEH2Handle
|
||||
___SEH2Handle:
|
||||
mov eax, [esp+4]
|
||||
mov ebp, [esp+8]
|
||||
mov esp, [esp+12]
|
||||
mov ebp, [esp+12]
|
||||
mov ebx, [esp+16]
|
||||
mov esi, [esp+20]
|
||||
mov edi, [esp+24]
|
||||
mov esp, [esp+8]
|
||||
jmp eax
|
||||
.endfunc
|
||||
|
||||
|
|
Loading…
Reference in a new issue