mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 16:43:04 +00:00
Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys.
This commit is contained in:
parent
b94e2d8ca0
commit
c2c66aff7d
24198 changed files with 0 additions and 37285 deletions
310
sdk/lib/pseh/i386/framebased-gcchack.c
Normal file
310
sdk/lib/pseh/i386/framebased-gcchack.c
Normal file
|
@ -0,0 +1,310 @@
|
|||
/*
|
||||
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
|
||||
#include <windef.h>
|
||||
#include <stdarg.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\t"
|
||||
"push $0\n\t"
|
||||
"push $0\n\t"
|
||||
"push $Return%=\n\t"
|
||||
"push %[target]\n\t"
|
||||
"call %c[RtlUnwind]\n"
|
||||
"Return%=:\n\t"
|
||||
"pop %%ebp" :
|
||||
:
|
||||
[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\t"
|
||||
"push %[frame]\n\t"
|
||||
"call *%[filter]\n\t"
|
||||
"pop %%edx\n\t"
|
||||
"pop %%edx" :
|
||||
[ret] "=a" (ret) :
|
||||
"c" (context), [filter] "r" (filter), [frame] "r" (frame), [ep] "r" (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" : : "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 */
|
Loading…
Add table
Add a link
Reference in a new issue