SEH library

svn path=/trunk/; revision=9591
This commit is contained in:
KJK::Hyperion 2004-06-02 18:36:55 +00:00
parent 07320b09dd
commit a8943a8c91
6 changed files with 181 additions and 0 deletions

View file

@ -0,0 +1,2 @@
*.o
*.d

View file

@ -0,0 +1,103 @@
#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <pseh/framebased/internal.h>
#include <excpt.h>
/* Assembly helpers, see i386/framebased.asm */
extern void __cdecl _SEHCleanHandlerEnvironment(void);
extern void __cdecl _SEHRegisterFrame(_SEHRegistration_t *);
extern void __cdecl _SEHUnregisterFrame(const _SEHRegistration_t *);
extern void __cdecl _SEHUnwind(_SEHPortableFrame_t *);
__declspec(noreturn) void __cdecl _SEHCallHandler(_SEHPortableFrame_t * frame)
{
frame->SPF_Handling = 1;
_SEHUnwind(frame);
frame->SPF_Handlers->SH_Handler(frame);
}
int __cdecl _SEHFrameHandler
(
struct _EXCEPTION_RECORD * ExceptionRecord,
void * EstablisherFrame,
struct _CONTEXT * ContextRecord,
void * DispatcherContext
)
{
_SEHPortableFrame_t * frame;
_SEHCleanHandlerEnvironment();
frame = EstablisherFrame;
/* Unwinding */
if(ExceptionRecord->ExceptionFlags & (4 | 2))
{
if(frame->SPF_Handlers->SH_Finally && !frame->SPF_Handling)
frame->SPF_Handlers->SH_Finally(frame);
}
/* Handling */
else
{
if(ExceptionRecord->ExceptionCode)
frame->SPF_Code = ExceptionRecord->ExceptionCode;
else
frame->SPF_Code = 0xC0000001;
if(frame->SPF_Handlers->SH_Filter)
{
int ret;
switch((UINT_PTR)frame->SPF_Handlers->SH_Filter)
{
case EXCEPTION_EXECUTE_HANDLER + 1:
case EXCEPTION_CONTINUE_SEARCH + 1:
case EXCEPTION_CONTINUE_EXECUTION + 1:
{
ret = (int)((UINT_PTR)frame->SPF_Handlers->SH_Filter) - 1;
break;
}
default:
{
EXCEPTION_POINTERS ep;
ep.ExceptionRecord = ExceptionRecord;
ep.ContextRecord = ContextRecord;
ret = frame->SPF_Handlers->SH_Filter(&ep, frame);
break;
}
}
/* EXCEPTION_CONTINUE_EXECUTION */
if(ret < 0)
return ExceptionContinueExecution;
/* EXCEPTION_EXECUTE_HANDLER */
else if(ret > 0)
_SEHCallHandler(frame);
/* EXCEPTION_CONTINUE_SEARCH */
else
/* fall through */;
}
}
return ExceptionContinueSearch;
}
void __stdcall _SEHEnter(_SEHPortableFrame_t * frame)
{
frame->SPF_Registration.SER_Handler = _SEHFrameHandler;
frame->SPF_Code = 0;
frame->SPF_Handling = 0;
_SEHRegisterFrame(&frame->SPF_Registration);
}
void __stdcall _SEHLeave(_SEHPortableFrame_t * frame)
{
_SEHUnregisterFrame(&frame->SPF_Registration);
}
/* EOF */

View file

@ -0,0 +1,2 @@
*.o
*.d

View file

@ -0,0 +1,48 @@
cpu 486
segment .text use32
global __SEHCleanHandlerEnvironment
__SEHCleanHandlerEnvironment:
cld
ret
global __SEHRegisterFrame
__SEHRegisterFrame:
mov ecx, [esp+4]
mov eax, [fs:0]
mov [ecx+0], eax
mov [fs:0], ecx
ret
global __SEHUnregisterFrame
__SEHUnregisterFrame:
mov ecx, [esp+4]
mov ecx, [ecx]
mov [fs:0], ecx
ret
global __SEHUnwind
__SEHUnwind:
extern RtlUnwind
mov ecx, [esp+4]
; RtlUnwind clobbers all the "don't clobber" registers, so we save them
push esi
push edi
push ebx
push eax
push eax
push eax
push ecx
call RtlUnwind
pop ebx
pop edi
pop esi
ret
; EOF

21
reactos/lib/pseh/makefile Normal file
View file

@ -0,0 +1,21 @@
# $Id: makefile,v 1.1 2004/06/02 18:36:55 hyperion Exp $
PATH_TO_TOP = ../..
TARGET_TYPE = library
TARGET_NAME = pseh
TARGET_CFLAGS += -D_DISABLE_TIDENTS -Werror -Wall -D__USE_W32API
include $(PATH_TO_TOP)/config
include makefile.$(ARCH)
TARGET_OBJECTS = framebased.o $(TARGET_ARCH_OBJECTS)
DEP_OBJECTS = $(TARGET_OBJECTS)
include $(PATH_TO_TOP)/rules.mak
include $(TOOLS_PATH)/helper.mk
include $(TOOLS_PATH)/depend.mk
# EOF

View file

@ -0,0 +1,5 @@
# $Id: makefile.i386,v 1.1 2004/06/02 18:36:55 hyperion Exp $
TARGET_ARCH_OBJECTS = $(ARCH)/framebased.o
# EOF