Create a branch for cmake bringup.

svn path=/branches/cmake-bringup/; revision=48236
This commit is contained in:
Amine Khaldi 2010-07-24 18:52:44 +00:00
parent a28e798006
commit c424146e2c
20602 changed files with 0 additions and 1140137 deletions

View file

@ -0,0 +1,25 @@
.text
.intel_syntax noprefix
.globl _SEHCleanHandlerEnvironment
_SEHCleanHandlerEnvironment:
ret
.globl _SEHCurrentRegistration
_SEHCurrentRegistration:
ret
.globl _SEHRegisterFrame
_SEHRegisterFrame:
ret
.globl _SEHUnregisterFrame
_SEHUnregisterFrame:
ret
.globl _SEHGlobalUnwind
_SEHGlobalUnwind:
ret
// EOF

503
lib/pseh/framebased.c Normal file
View file

@ -0,0 +1,503 @@
/*
Copyright (c) 2004/2005 KJK::Hyperion
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#define _NTSYSTEM_
#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <pseh/pseh.h>
#include <pseh/framebased/internal.h>
#include <pseh/excpt.h>
#include <pseh/framebased.h>
#include <excpt.h>
/* Tracing */
#ifdef _SEH_ENABLE_TRACE
extern unsigned long __cdecl DbgPrint(const char * format, ...);
#define _SEH_TRACE_HEADER_(FRAME_) \
DbgPrint("[PSEH:%p]%s:%d:", FRAME_, __FILE__, __LINE__);
#define _SEH_TRACE_TRAILER_ \
DbgPrint("\n");
#define _SEH_FILTER_RET_STRING_(RET_) \
(((int)(RET_) < 0) ? "_SEH_CONTINUE_EXECUTION" : (((int)(RET_) > 0) ? "_SEH_EXECUTE_HANDLER" : "_SEH_CONTINUE_SEARCH"))
#define _SEH_TRACE_LINE_(FRAME_, ARGS_) \
{ \
_SEH_TRACE_HEADER_(FRAME_); \
DbgPrint ARGS_; \
_SEH_TRACE_TRAILER_; \
}
#define _SEH_TRACE_ENTER(FRAME_, FUNCNAME_, ARGS_) \
{ \
if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_ENTER_LEAVE) \
{ \
_SEH_TRACE_HEADER_(FRAME_); \
DbgPrint(">>> %s(", (FUNCNAME_)); \
DbgPrint ARGS_; \
DbgPrint(")"); \
_SEH_TRACE_TRAILER_; \
} \
}
#define _SEH_TRACE_LEAVE(FRAME_, FUNCNAME_, ARGS_) \
{ \
if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_ENTER_LEAVE) \
{ \
_SEH_TRACE_HEADER_(FRAME_); \
DbgPrint("<<< %s => ", (FUNCNAME_)); \
DbgPrint ARGS_; \
_SEH_TRACE_TRAILER_; \
} \
}
#define _SEH_TRACE_EXCEPTION_RECORD(FRAME_, ER_) \
{ \
if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_EXCEPTION_RECORD) \
{ \
_SEH_TRACE_LINE_ \
( \
(FRAME_), \
( \
"ExceptionRecord %p = { ExceptionCode : %08X, ExceptionFlags : %08X, ExceptionRecord : %p, ExceptionAddress : %p }", \
(ER_), \
(ER_)->ExceptionCode, \
(ER_)->ExceptionFlags, \
(ER_)->ExceptionRecord, \
(ER_)->ExceptionAddress \
) \
); \
} \
}
#ifdef _X86_
#define _SEH_TRACE_CONTEXT(FRAME_, CONTEXT_) \
{ \
if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_CONTEXT) \
{ \
if(((CONTEXT_)->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER) \
{ \
_SEH_TRACE_LINE_ \
( \
(FRAME_), \
( \
"eax=%08X ebx=%08X ecx=%08X edx=%08X esi=%08X edi=%08X", \
(CONTEXT_)->Eax, \
(CONTEXT_)->Ebx, \
(CONTEXT_)->Ecx, \
(CONTEXT_)->Edx, \
(CONTEXT_)->Esi, \
(CONTEXT_)->Edi \
) \
); \
} \
\
if(((CONTEXT_)->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL) \
{ \
_SEH_TRACE_LINE_ \
( \
(FRAME_), \
( \
"eip=%08X esp=%08X ebp=%08X efl=%08X cs=%08X ss=%08X", \
(CONTEXT_)->Eip, \
(CONTEXT_)->Esp, \
(CONTEXT_)->Ebp, \
(CONTEXT_)->EFlags, \
(CONTEXT_)->SegCs, \
(CONTEXT_)->SegSs \
) \
); \
} \
\
if(((CONTEXT_)->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS) \
{ \
_SEH_TRACE_LINE_ \
( \
(FRAME_), \
( \
"ds=%08X es=%08X fs=%08X gs=%08X", \
(CONTEXT_)->SegDs, \
(CONTEXT_)->SegEs, \
(CONTEXT_)->SegFs, \
(CONTEXT_)->SegGs \
) \
); \
} \
} \
}
#else
#define _SEH_TRACE_CONTEXT(FRAME_, CONTEXT_)
#endif
#define _SEH_TRACE_UNWIND(FRAME_, ARGS_) \
{ \
if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_UNWIND) \
{ \
_SEH_TRACE_LINE_((FRAME_), ARGS_); \
} \
}
#define _SEH_TRACE_TRYLEVEL(FRAME_, TRYLEVEL_) \
{ \
if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_TRYLEVEL) \
{ \
_SEH_TRACE_LINE_((FRAME_), ("trylevel %p, filter %p", (TRYLEVEL_), (TRYLEVEL_)->SPT_Handlers.SH_Filter)); \
} \
}
#define _SEH_TRACE_ENTER_CALL_FILTER(FRAME_, TRYLEVEL_, ER_) \
{ \
if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_CALL_FILTER) \
{ \
_SEH_TRACE_LINE_ \
( \
(FRAME_), \
( \
"trylevel %p, calling filter %p, ExceptionCode %08X", \
(TRYLEVEL_), \
(TRYLEVEL_)->SPT_Handlers.SH_Filter, \
(ER_)->ExceptionCode \
) \
); \
} \
}
#define _SEH_TRACE_LEAVE_CALL_FILTER(FRAME_, TRYLEVEL_, RET_) \
{ \
if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_CALL_FILTER) \
{ \
_SEH_TRACE_LINE_ \
( \
(FRAME_), \
( \
"trylevel %p, filter %p => %s", \
(TRYLEVEL_), \
(TRYLEVEL_)->SPT_Handlers.SH_Filter, \
_SEH_FILTER_RET_STRING_(RET_) \
) \
); \
} \
}
#define _SEH_TRACE_FILTER(FRAME_, TRYLEVEL_, RET_) \
{ \
if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_FILTER) \
{ \
_SEH_TRACE_LINE_ \
( \
(FRAME_), \
( \
"trylevel %p => %s", \
(TRYLEVEL_), \
_SEH_FILTER_RET_STRING_(RET_) \
) \
); \
} \
}
#define _SEH_TRACE_ENTER_CALL_HANDLER(FRAME_, TRYLEVEL_) \
{ \
if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_CALL_HANDLER) \
{ \
_SEH_TRACE_LINE_((FRAME_), ("trylevel %p, handling", (TRYLEVEL_))); \
} \
}
#define _SEH_TRACE_ENTER_CALL_FINALLY(FRAME_, TRYLEVEL_) \
{ \
if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_CALL_FINALLY) \
{ \
_SEH_TRACE_LINE_ \
( \
(FRAME_), \
( \
"trylevel %p, calling exit routine %p", \
(TRYLEVEL_), \
(TRYLEVEL_)->SPT_Handlers.SH_Finally \
) \
); \
} \
}
#define _SEH_TRACE_LEAVE_CALL_FINALLY(FRAME_, TRYLEVEL_) \
{ \
if((FRAME_)->SPF_Tracing & _SEH_DO_TRACE_CALL_FINALLY) \
{ \
_SEH_TRACE_LINE_ \
( \
(FRAME_), \
( \
"trylevel %p, exit routine %p returned", \
(TRYLEVEL_), \
(TRYLEVEL_)->SPT_Handlers.SH_Finally \
) \
); \
} \
}
#else
#define _SEH_TRACE_ENTER(FRAME_, FUNCNAME_, ARGS_)
#define _SEH_TRACE_LEAVE(FRAME_, FUNCNAME_, ARGS_)
#define _SEH_TRACE_EXCEPTION_RECORD(FRAME_, ER_)
#define _SEH_TRACE_CONTEXT(FRAME_, CONTEXT_)
#define _SEH_TRACE_UNWIND(FRAME_, ARGS_)
#define _SEH_TRACE_TRYLEVEL(FRAME_, TRYLEVEL_)
#define _SEH_TRACE_ENTER_CALL_FILTER(FRAME_, TRYLEVEL_, ER_)
#define _SEH_TRACE_LEAVE_CALL_FILTER(FRAME_, TRYLEVEL_, RET_)
#define _SEH_TRACE_FILTER(FRAME_, TRYLEVEL_, RET_)
#define _SEH_TRACE_ENTER_CALL_HANDLER(FRAME_, TRYLEVEL_)
#define _SEH_TRACE_ENTER_CALL_FINALLY(FRAME_, TRYLEVEL_)
#define _SEH_TRACE_LEAVE_CALL_FINALLY(FRAME_, TRYLEVEL_)
#endif
/* Assembly helpers, see i386/framebased.asm */
extern void __cdecl _SEHCleanHandlerEnvironment(void);
extern struct __SEHRegistration * __cdecl _SEHRegisterFrame(_SEHRegistration_t *);
extern void __cdecl _SEHUnregisterFrame(void);
extern void __cdecl _SEHGlobalUnwind(_SEHPortableFrame_t *);
extern _SEHRegistration_t * __cdecl _SEHCurrentRegistration(void);
/* Borland C++ uses a different decoration (i.e. none) for stdcall functions */
extern void __stdcall RtlUnwind(void *, void *, PEXCEPTION_RECORD, void *);
void const * _SEHRtlUnwind = RtlUnwind;
static void __stdcall _SEHLocalUnwind
(
_SEHPortableFrame_t * frame,
_SEHPortableTryLevel_t * dsttrylevel
)
{
_SEHPortableTryLevel_t * trylevel;
_SEH_TRACE_UNWIND(frame, ("enter local unwind from %p to %p", frame->SPF_TopTryLevel, dsttrylevel));
for
(
trylevel = frame->SPF_TopTryLevel;
trylevel != dsttrylevel;
trylevel = trylevel->SPT_Next
)
{
_SEHFinally_t pfnFinally;
/* ASSERT(trylevel); */
pfnFinally = trylevel->SPT_Handlers.SH_Finally;
if(pfnFinally)
{
_SEH_TRACE_ENTER_CALL_FINALLY(frame, trylevel);
pfnFinally(frame);
_SEH_TRACE_LEAVE_CALL_FINALLY(frame, trylevel);
}
}
_SEH_TRACE_UNWIND(frame, ("leave local unwind from %p to %p", frame->SPF_TopTryLevel, dsttrylevel));
}
static void __cdecl _SEHCallHandler
(
_SEHPortableFrame_t * frame,
_SEHPortableTryLevel_t * trylevel
)
{
_SEHGlobalUnwind(frame);
_SEHLocalUnwind(frame, trylevel);
_SEH_TRACE_ENTER_CALL_HANDLER(frame, trylevel);
frame->SPF_Handler(trylevel);
/* ASSERT(0); */
}
static int __cdecl _SEHFrameHandler
(
struct _EXCEPTION_RECORD * ExceptionRecord,
void * EstablisherFrame,
struct _CONTEXT * ContextRecord,
void * DispatcherContext
)
{
_SEHPortableFrame_t * frame;
_SEHCleanHandlerEnvironment();
frame = EstablisherFrame;
_SEH_TRACE_ENTER
(
frame,
"_SEHFrameHandler",
(
"%p, %p, %p, %p",
ExceptionRecord,
EstablisherFrame,
ContextRecord,
DispatcherContext
)
);
_SEH_TRACE_EXCEPTION_RECORD(frame, ExceptionRecord);
_SEH_TRACE_CONTEXT(frame, ContextRecord);
/* Unwinding */
if(ExceptionRecord->ExceptionFlags & (4 | 2))
{
_SEH_TRACE_UNWIND(frame, ("enter forced unwind"));
_SEHLocalUnwind(frame, NULL);
_SEH_TRACE_UNWIND(frame, ("leave forced unwind"));
}
/* Handling */
else
{
int ret;
_SEHPortableTryLevel_t * trylevel;
if(ExceptionRecord->ExceptionCode)
frame->SPF_Code = ExceptionRecord->ExceptionCode;
else
frame->SPF_Code = 0xC0000001;
for
(
trylevel = frame->SPF_TopTryLevel;
trylevel != NULL;
trylevel = trylevel->SPT_Next
)
{
_SEHFilter_t pfnFilter = trylevel->SPT_Handlers.SH_Filter;
_SEH_TRACE_TRYLEVEL(frame, trylevel);
switch((UINT_PTR)pfnFilter)
{
case (UINT_PTR)_SEH_STATIC_FILTER(_SEH_EXECUTE_HANDLER):
case (UINT_PTR)_SEH_STATIC_FILTER(_SEH_CONTINUE_SEARCH):
case (UINT_PTR)_SEH_STATIC_FILTER(_SEH_CONTINUE_EXECUTION):
{
ret = (int)((UINT_PTR)pfnFilter) - 2;
break;
}
default:
{
if(trylevel->SPT_Handlers.SH_Filter)
{
EXCEPTION_POINTERS ep;
ep.ExceptionRecord = ExceptionRecord;
ep.ContextRecord = ContextRecord;
_SEH_TRACE_ENTER_CALL_FILTER(frame, trylevel, ExceptionRecord);
ret = pfnFilter(&ep, frame);
_SEH_TRACE_LEAVE_CALL_FILTER(frame, trylevel, ret);
}
else
ret = _SEH_CONTINUE_SEARCH;
break;
}
}
_SEH_TRACE_FILTER(frame, trylevel, ret);
/* _SEH_CONTINUE_EXECUTION */
if(ret < 0)
{
_SEH_TRACE_LEAVE(frame, "_SEHFrameHandler", ("ExceptionContinueExecution"));
return ExceptionContinueExecution;
}
/* _SEH_EXECUTE_HANDLER */
else if(ret > 0)
_SEHCallHandler(frame, trylevel);
/* _SEH_CONTINUE_SEARCH */
else
continue;
}
/* FALLTHROUGH */
}
_SEH_TRACE_LEAVE(frame, "_SEHFrameHandler", ("ExceptionContinueSearch"));
return ExceptionContinueSearch;
}
void __stdcall _SEHEnterFrame_s(_SEHPortableFrame_t * frame)
{
_SEHEnterFrame_f(frame);
}
void __stdcall _SEHLeaveFrame_s(void)
{
_SEHLeaveFrame_f();
}
void __stdcall _SEHReturn_s(void)
{
_SEHReturn_f();
}
void _SEH_FASTCALL _SEHEnterFrame_f(_SEHPortableFrame_t * frame)
{
/* ASSERT(frame); */
/* ASSERT(trylevel); */
frame->SPF_Registration.SER_Handler = _SEHFrameHandler;
frame->SPF_Code = 0;
_SEHRegisterFrame(&frame->SPF_Registration);
}
void _SEH_FASTCALL _SEHLeaveFrame_f(void)
{
_SEHPortableFrame_t * frame;
frame = _SEH_CONTAINING_RECORD
(
_SEHCurrentRegistration(),
_SEHPortableFrame_t,
SPF_Registration
);
/* ASSERT(frame); */
/* ASSERT(frame->SPF_TopTryLevel == NULL) */
_SEHUnregisterFrame();
}
void _SEH_FASTCALL _SEHReturn_f(void)
{
_SEHPortableFrame_t * frame;
frame = _SEH_CONTAINING_RECORD
(
_SEHCurrentRegistration(),
_SEHPortableFrame_t,
SPF_Registration
);
_SEHLocalUnwind(frame, NULL);
_SEHUnregisterFrame();
}
/* EOF */

View file

@ -0,0 +1,89 @@
// Copyright (c) 2008 KJK::Hyperion
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to dos so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
.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+12]
mov ebx, [esp+16]
mov esi, [esp+20]
mov edi, [esp+24]
mov esp, [esp+8]
jmp eax
.endfunc
.func __SEH2FrameHandler
.globl ___SEH2FrameHandler
___SEH2FrameHandler:
.extern __SEH2FrameHandler
cld
jmp __SEH2FrameHandler
.endfunc
.func __SEH2UnwindHandler
.globl ___SEH2UnwindHandler
___SEH2UnwindHandler:
.extern __SEH2UnwindHandler
cld
jmp __SEH2UnwindHandler
.endfunc
// EOF

View file

@ -0,0 +1,309 @@
/*
Copyright (c) 2008 KJK::Hyperion
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#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
#endif
#ifndef EXCEPTION_UNWINDING
#define EXCEPTION_UNWINDING 2
#endif
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 *);
typedef struct __SEHTrampoline
{
unsigned char STR_MovEcx;
unsigned char * STR_Closure;
unsigned char STR_Jmp;
unsigned char * STR_Function;
}
__attribute__((packed))
_SEHTrampoline_t;
FORCEINLINE
int _SEHIsTrampoline(_SEHTrampoline_t * trampoline_)
{
return trampoline_->STR_MovEcx == 0xb9 && trampoline_->STR_Jmp == 0xe9;
}
FORCEINLINE
void * _SEHFunctionFromTrampoline(_SEHTrampoline_t * trampoline_)
{
return (int)(trampoline_ + 1) + trampoline_->STR_Function;
}
FORCEINLINE
void * _SEHClosureFromTrampoline(_SEHTrampoline_t * trampoline_)
{
return trampoline_->STR_Closure;
}
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)
{
__asm__ __volatile__
(
"push %%ebp\n"
"push $0\n"
"push $0\n"
"push $Return%=\n"
"push %[target]\n"
"call %c[RtlUnwind]\n"
"Return%=: pop %%ebp\n" :
:
[target] "g" (target), [RtlUnwind] "g" (&RtlUnwind) :
"eax", "ebx", "ecx", "edx", "esi", "edi", "flags", "memory"
);
}
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;
if(filter == (void *)1)
return 1;
if(filter == (void *)-1)
return -1;
if(_SEHIsTrampoline((_SEHTrampoline_t *)filter))
{
context = _SEHClosureFromTrampoline((_SEHTrampoline_t *)filter);
filter = _SEHFunctionFromTrampoline((_SEHTrampoline_t *)filter);
}
__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)
{
void * body = trylevel->ST_Body;
void * context = NULL;
if(_SEHIsTrampoline((_SEHTrampoline_t *)body))
{
context = _SEHClosureFromTrampoline((_SEHTrampoline_t *)body);
body = _SEHFunctionFromTrampoline((_SEHTrampoline_t *)body);
}
__asm__ __volatile__("call *%1\n" : : "c" (context), "r" (body) : "eax", "edx", "flags", "memory");
}
}
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 _SEH2UnwindHandler
(
struct _EXCEPTION_RECORD * ExceptionRecord,
void * EstablisherFrame,
struct _CONTEXT * ContextRecord,
void * DispatcherContext
)
{
if(ExceptionRecord->ExceptionFlags & (EXCEPTION_EXIT_UNWIND | EXCEPTION_UNWINDING))
{
_SEH2UnwindFrame_t * unwindframe = CONTAINING_RECORD(EstablisherFrame, _SEH2UnwindFrame_t, SUF_Registration);
_SEH2LocalUnwind(unwindframe->SUF_Frame, unwindframe->SUF_TargetTryLevel);
*((void **)DispatcherContext) = EstablisherFrame;
return ExceptionCollidedUnwind;
}
return ExceptionContinueSearch;
}
static
void _SEH2LocalUnwind(_SEH2Frame_t * frame, volatile _SEH2TryLevel_t * dsttrylevel)
{
volatile _SEH2TryLevel_t * trylevel;
_SEH2UnwindFrame_t unwindframe;
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);
}
__SEH2LeaveFrame();
}
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, &fulltrylevel->SHT_Common);
frame->SF_TopTryLevel = fulltrylevel->SHT_Common.ST_Next;
__SEH2Handle
(
fulltrylevel->SHT_Common.ST_Body,
fulltrylevel->SHT_Esp,
fulltrylevel->SHT_Ebp,
fulltrylevel->SHT_Ebx,
fulltrylevel->SHT_Esi,
fulltrylevel->SHT_Edi
);
}
extern
int __cdecl _SEH2FrameHandler
(
struct _EXCEPTION_RECORD * ExceptionRecord,
void * EstablisherFrame,
struct _CONTEXT * ContextRecord,
void * DispatcherContext
)
{
_SEH2Frame_t * frame;
frame = EstablisherFrame;
/* Unwinding */
if(ExceptionRecord->ExceptionFlags & (EXCEPTION_EXIT_UNWIND | EXCEPTION_UNWINDING))
{
_SEH2LocalUnwind(frame, NULL);
}
/* Handling */
else
{
int ret = 0;
volatile _SEH2TryLevel_t * trylevel;
EXCEPTION_POINTERS ep;
ep.ExceptionRecord = ExceptionRecord;
ep.ContextRecord = ContextRecord;
frame->SF_Code = ExceptionRecord->ExceptionCode;
for(trylevel = frame->SF_TopTryLevel; trylevel != NULL; trylevel = trylevel->ST_Next)
{
ret = _SEH2Except(frame, trylevel, &ep);
if(ret < 0)
return ExceptionContinueExecution;
else if(ret > 0)
_SEH2Handle(frame, trylevel);
}
}
return ExceptionContinueSearch;
}
extern
void __cdecl _SEH2EnterFrame(_SEH2Frame_t * frame)
{
frame->SF_Registration.SER_Handler = __SEH2FrameHandler;
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)
{
__SEH2LeaveFrame();
}
extern
void __cdecl _SEH2Return(void)
{
_SEH2LocalUnwind(CONTAINING_RECORD(_SEH2CurrentRegistration(), _SEH2Frame_t, SF_Registration), NULL);
_SEH2LeaveFrame();
}
/* EOF */

View file

@ -0,0 +1,73 @@
// Copyright (c) 2004/2005 KJK::Hyperion
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to dos so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
.text
.intel_syntax noprefix
.globl __SEHCleanHandlerEnvironment
__SEHCleanHandlerEnvironment:
cld
ret
.globl __SEHCurrentRegistration
__SEHCurrentRegistration:
mov eax, [fs:0]
ret
.globl __SEHRegisterFrame
__SEHRegisterFrame:
mov ecx, [esp+4]
mov eax, [fs:0]
mov [ecx+0], eax
mov [fs:0], ecx
ret
.globl __SEHUnregisterFrame
__SEHUnregisterFrame:
mov ecx, [fs:0]
mov ecx, [ecx+0]
mov [fs:0], ecx
ret
.globl __SEHGlobalUnwind
__SEHGlobalUnwind:
.extern __SEHRtlUnwind
// RtlUnwind clobbers all the "don't clobber" registers, so we save them
push ebx
mov ebx, [esp+8]
push esi
push edi
push 0 // ReturnValue
push 0 // ExceptionRecord
push .RestoreRegisters // TargetIp
push ebx // TargetFrame
call [__SEHRtlUnwind]
.RestoreRegisters:
pop edi
pop esi
pop ebx
ret
// EOF

View file

@ -0,0 +1,69 @@
// Copyright (c) 2004/2005 KJK::Hyperion
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to dos so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
.text
.globl _SEHCleanHandlerEnvironment
_SEHCleanHandlerEnvironment:
blr
.globl _SEHCurrentRegistration
_SEHCurrentRegistration:
lwz 3,0(13)
blr
// R3: Frame to store in
.globl _SEHRegisterFrame
_SEHRegisterFrame:
lwz 4,0(13)
stw 3,0(13)
stw 4,0(3)
blr
.globl _SEHUnregisterFrame
_SEHUnregisterFrame:
lwz 3,0(13)
lwz 3,0(3)
stw 3,0(13)
blr
.globl _SEHGlobalUnwind
_SEHGlobalUnwind:
.extern _SEHRtlUnwind
// RtlUnwind clobbers all the "don't clobber" registers, so we save them
lwz 3,4(1)
stwu 1,-132(1)
stmw 2,-128(1)
xor 6,6,6
xor 5,5,5
lis 4,.RestoreRegisters@ha
addi 4,4,.RestoreRegisters@l # Where to jump back to
# We already have r3
bl _SEHRtlUnwind
.RestoreRegisters:
lmw 2,-128(1)
addi 1,1,132
blr
// EOF

25
lib/pseh/pseh.rbuild Normal file
View file

@ -0,0 +1,25 @@
<?xml version="1.0"?>
<!DOCTYPE module SYSTEM "../../tools/rbuild/project.dtd">
<module name="pseh" type="staticlibrary">
<if property="ARCH" value="i386">
<directory name="i386">
<file>framebased.S</file>
<group compilerset="gcc">
<file>framebased-gcchack.c</file>
<file>framebased-gcchack-asm.S</file>
</group>
</directory>
</if>
<if property="ARCH" value="powerpc">
<directory name="powerpc">
<file>framebased.S</file>
</directory>
</if>
<if property="ARCH" value="amd64">
<directory name="amd64">
<file>framebased.S</file>
</directory>
</if>
<file>framebased.c</file>
</module>