modified lib/pseh/framebased-gcchack.c

modified   lib/pseh/i386/framebased-gcchack.S
   Correctly handle exceptions thrown during unwinding
   Renamed some internal routines to more appropriate names

svn path=/trunk/; revision=38460
This commit is contained in:
KJK::Hyperion 2008-12-30 04:00:45 +00:00
parent d3c81b34be
commit 26d5b48792
2 changed files with 33 additions and 15 deletions

View file

@ -40,7 +40,7 @@
extern DECLSPEC_NORETURN int __SEH2Handle(void *, void *, void *);
extern int __cdecl __SEH2FrameHandler(struct _EXCEPTION_RECORD *, void *, struct _CONTEXT *, void *);
extern int __cdecl __SEH2NestedHandler(struct _EXCEPTION_RECORD *, void *, struct _CONTEXT *, void *);
extern int __cdecl __SEH2UnwindHandler(struct _EXCEPTION_RECORD *, void *, struct _CONTEXT *, void *);
FORCEINLINE
_SEH2Registration_t * __cdecl _SEH2CurrentRegistration(void)
@ -134,8 +134,18 @@ void _SEH2Finally(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * trylevel)
}
}
typedef struct __SEH2UnwindFrame
{
_SEH2Registration_t SUF_Registration;
_SEH2Frame_t * SUF_Frame;
volatile _SEH2TryLevel_t * SUF_TargetTryLevel;
}
_SEH2UnwindFrame_t;
static void _SEH2LocalUnwind(_SEH2Frame_t *, volatile _SEH2TryLevel_t *);
extern
int __cdecl _SEH2NestedHandler
int __cdecl _SEH2UnwindHandler
(
struct _EXCEPTION_RECORD * ExceptionRecord,
void * EstablisherFrame,
@ -144,25 +154,33 @@ int __cdecl _SEH2NestedHandler
)
{
if(ExceptionRecord->ExceptionFlags & (EXCEPTION_EXIT_UNWIND | EXCEPTION_UNWINDING))
return ExceptionContinueSearch;
{
_SEH2UnwindFrame_t * unwindframe = CONTAINING_RECORD(EstablisherFrame, _SEH2UnwindFrame_t, SUF_Registration);
_SEH2LocalUnwind(unwindframe->SUF_Frame, unwindframe->SUF_TargetTryLevel);
*((void **)DispatcherContext) = EstablisherFrame;
return ExceptionCollidedUnwind;
}
*((void **)DispatcherContext) = EstablisherFrame;
return ExceptionCollidedUnwind;
return ExceptionContinueSearch;
}
static
void _SEH2LocalUnwind(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * dsttrylevel)
{
volatile _SEH2TryLevel_t * trylevel;
_SEH2Registration_t nestedframe;
_SEH2UnwindFrame_t unwindframe;
nestedframe.SER_Handler = &__SEH2NestedHandler;
__SEH2EnterFrame(&nestedframe);
unwindframe.SUF_Frame = frame;
unwindframe.SUF_TargetTryLevel = dsttrylevel;
unwindframe.SUF_Registration.SER_Handler = &__SEH2UnwindHandler;
__SEH2EnterFrame(&unwindframe.SUF_Registration);
for(trylevel = frame->SF_TopTryLevel; trylevel && trylevel != dsttrylevel; trylevel = trylevel->ST_Next)
{
frame->SF_TopTryLevel = trylevel->ST_Next;
_SEH2Finally(frame, trylevel);
frame->SF_TopTryLevel = dsttrylevel;
}
__SEH2LeaveFrame();
}

View file

@ -40,14 +40,14 @@ ___SEH2FrameHandler:
jmp __SEH2FrameHandler
.endfunc
.func __SEH2NestedHandler
.globl ___SEH2NestedHandler
___SEH2NestedHandler:
.func __SEH2UnwindHandler
.globl ___SEH2UnwindHandler
___SEH2UnwindHandler:
.extern __SEH2NestedHandler
.extern __SEH2UnwindHandler
cld
jmp __SEH2NestedHandler
jmp __SEH2UnwindHandler
.endfunc
// EOF