mirror of
https://github.com/reactos/reactos.git
synced 2025-08-07 08:23:00 +00:00
[PSEH] Make structures more SEH3 compatible
This commit is contained in:
parent
6d2eb03402
commit
d23ee5f365
4 changed files with 137 additions and 69 deletions
|
@ -45,8 +45,9 @@
|
||||||
/* Make sure the asm definitions match the structures */
|
/* Make sure the asm definitions match the structures */
|
||||||
C_ASSERT(SEH3_REGISTRATION_FRAME_Next == FIELD_OFFSET(SEH3$_REGISTRATION_FRAME, Next));
|
C_ASSERT(SEH3_REGISTRATION_FRAME_Next == FIELD_OFFSET(SEH3$_REGISTRATION_FRAME, Next));
|
||||||
C_ASSERT(SEH3_REGISTRATION_FRAME_Handler == FIELD_OFFSET(SEH3$_REGISTRATION_FRAME, Handler));
|
C_ASSERT(SEH3_REGISTRATION_FRAME_Handler == FIELD_OFFSET(SEH3$_REGISTRATION_FRAME, Handler));
|
||||||
C_ASSERT(SEH3_REGISTRATION_FRAME_EndOfChain == FIELD_OFFSET(SEH3$_REGISTRATION_FRAME, EndOfChain));
|
|
||||||
C_ASSERT(SEH3_REGISTRATION_FRAME_ScopeTable == FIELD_OFFSET(SEH3$_REGISTRATION_FRAME, ScopeTable));
|
C_ASSERT(SEH3_REGISTRATION_FRAME_ScopeTable == FIELD_OFFSET(SEH3$_REGISTRATION_FRAME, ScopeTable));
|
||||||
|
C_ASSERT(SEH3_REGISTRATION_FRAME_TryLevel == FIELD_OFFSET(SEH3$_REGISTRATION_FRAME, TryLevel));
|
||||||
|
C_ASSERT(SEH3_REGISTRATION_FRAME_EndOfChain == FIELD_OFFSET(SEH3$_REGISTRATION_FRAME, EndOfChain));
|
||||||
C_ASSERT(SEH3_REGISTRATION_FRAME_ExceptionPointers == FIELD_OFFSET(SEH3$_REGISTRATION_FRAME, ExceptionPointers));
|
C_ASSERT(SEH3_REGISTRATION_FRAME_ExceptionPointers == FIELD_OFFSET(SEH3$_REGISTRATION_FRAME, ExceptionPointers));
|
||||||
C_ASSERT(SEH3_REGISTRATION_FRAME_ExceptionCode == FIELD_OFFSET(SEH3$_REGISTRATION_FRAME, ExceptionCode));
|
C_ASSERT(SEH3_REGISTRATION_FRAME_ExceptionCode == FIELD_OFFSET(SEH3$_REGISTRATION_FRAME, ExceptionCode));
|
||||||
C_ASSERT(SEH3_REGISTRATION_FRAME_Esp == FIELD_OFFSET(SEH3$_REGISTRATION_FRAME, Esp));
|
C_ASSERT(SEH3_REGISTRATION_FRAME_Esp == FIELD_OFFSET(SEH3$_REGISTRATION_FRAME, Esp));
|
||||||
|
@ -63,6 +64,13 @@ C_ASSERT(SEH3_REGISTRATION_FRAME_ReturnAddress == FIELD_OFFSET(SEH3$_REGISTRATIO
|
||||||
C_ASSERT(SEH3_SCOPE_TABLE_Filter == FIELD_OFFSET(SEH3$_SCOPE_TABLE, Filter));
|
C_ASSERT(SEH3_SCOPE_TABLE_Filter == FIELD_OFFSET(SEH3$_SCOPE_TABLE, Filter));
|
||||||
C_ASSERT(SEH3_SCOPE_TABLE_Target == FIELD_OFFSET(SEH3$_SCOPE_TABLE, Target));
|
C_ASSERT(SEH3_SCOPE_TABLE_Target == FIELD_OFFSET(SEH3$_SCOPE_TABLE, Target));
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
_SEH3$_NESTED_HANDLER = 0,
|
||||||
|
_SEH3$_CPP_HANDLER = 1,
|
||||||
|
_SEH3$_CLANG_HANDLER = 2,
|
||||||
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
__attribute__((regparm(1)))
|
__attribute__((regparm(1)))
|
||||||
_SEH3$_Unregister(
|
_SEH3$_Unregister(
|
||||||
|
@ -76,7 +84,7 @@ _SEH3$_Unregister(
|
||||||
/* There shouldn't be any more nested try-level frames */
|
/* There shouldn't be any more nested try-level frames */
|
||||||
ASSERT(Frame->EndOfChain == Frame);
|
ASSERT(Frame->EndOfChain == Frame);
|
||||||
|
|
||||||
/* During unwinding on Windows ExecuteHandler2 installs it's own EH frame,
|
/* During unwinding on Windows ExecuteHandler2 installs its own EH frame,
|
||||||
so there can be one or even multiple frames before our own one and we
|
so there can be one or even multiple frames before our own one and we
|
||||||
need to search for the link that points to our head frame. */
|
need to search for the link that points to our head frame. */
|
||||||
CurrentFrame = (SEH3$_REGISTRATION_FRAME*)__readfsdword(0);
|
CurrentFrame = (SEH3$_REGISTRATION_FRAME*)__readfsdword(0);
|
||||||
|
@ -156,20 +164,21 @@ static inline
|
||||||
LONG
|
LONG
|
||||||
_SEH3$_InvokeFilter(
|
_SEH3$_InvokeFilter(
|
||||||
volatile SEH3$_REGISTRATION_FRAME *RegistrationFrame,
|
volatile SEH3$_REGISTRATION_FRAME *RegistrationFrame,
|
||||||
PVOID Filter)
|
PVOID Filter,
|
||||||
|
int HandlerType)
|
||||||
{
|
{
|
||||||
LONG FilterResult;
|
LONG FilterResult;
|
||||||
|
|
||||||
if (RegistrationFrame->ScopeTable->HandlerType == _SEH3$_NESTED_HANDLER)
|
if (HandlerType == _SEH3$_NESTED_HANDLER)
|
||||||
{
|
{
|
||||||
return _SEH3$_InvokeNestedFunctionFilter(RegistrationFrame, Filter);
|
return _SEH3$_InvokeNestedFunctionFilter(RegistrationFrame, Filter);
|
||||||
}
|
}
|
||||||
else if (RegistrationFrame->ScopeTable->HandlerType == _SEH3$_CPP_HANDLER)
|
else if (HandlerType == _SEH3$_CPP_HANDLER)
|
||||||
{
|
{
|
||||||
/* Call the embedded filter function */
|
/* Call the embedded filter function */
|
||||||
return _SEH3$_InvokeEmbeddedFilter(RegistrationFrame);
|
return _SEH3$_InvokeEmbeddedFilter(RegistrationFrame);
|
||||||
}
|
}
|
||||||
else if (RegistrationFrame->ScopeTable->HandlerType == _SEH3$_CLANG_HANDLER)
|
else if (HandlerType == _SEH3$_CLANG_HANDLER)
|
||||||
{
|
{
|
||||||
return _SEH3$_InvokeEmbeddedFilterFromRegistration(RegistrationFrame);
|
return _SEH3$_InvokeEmbeddedFilterFromRegistration(RegistrationFrame);
|
||||||
}
|
}
|
||||||
|
@ -184,7 +193,7 @@ _SEH3$_InvokeFilter(
|
||||||
|
|
||||||
void
|
void
|
||||||
__attribute__((regparm(1)))
|
__attribute__((regparm(1)))
|
||||||
_SEH3$_AutoCleanup(
|
_SEH3$_C_AutoCleanup(
|
||||||
volatile SEH3$_REGISTRATION_FRAME *Frame)
|
volatile SEH3$_REGISTRATION_FRAME *Frame)
|
||||||
{
|
{
|
||||||
_SEH3$_Unregister(Frame);
|
_SEH3$_Unregister(Frame);
|
||||||
|
@ -192,15 +201,37 @@ _SEH3$_AutoCleanup(
|
||||||
/* Check for __finally frames */
|
/* Check for __finally frames */
|
||||||
if (Frame->ScopeTable->Target == NULL)
|
if (Frame->ScopeTable->Target == NULL)
|
||||||
{
|
{
|
||||||
_SEH3$_InvokeFilter(Frame, Frame->ScopeTable->Filter);
|
#ifdef __clang__
|
||||||
|
_SEH3$_InvokeFilter(Frame, Frame->ScopeTable->Filter, _SEH3$_CLANG_HANDLER);
|
||||||
|
#else
|
||||||
|
_SEH3$_InvokeFilter(Frame, Frame->ScopeTable->Filter, _SEH3$_NESTED_HANDLER);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
__attribute__((regparm(1)))
|
||||||
|
_SEH3$_CPP_AutoCleanup(
|
||||||
|
volatile SEH3$_REGISTRATION_FRAME *Frame)
|
||||||
|
{
|
||||||
|
if (Frame->Handler)
|
||||||
|
_SEH3$_UnregisterFrame(Frame);
|
||||||
|
else
|
||||||
|
_SEH3$_UnregisterTryLevel(Frame);
|
||||||
|
|
||||||
|
/* Check for __finally frames */
|
||||||
|
if (Frame->ScopeTable->Target == NULL)
|
||||||
|
{
|
||||||
|
_SEH3$_InvokeFilter(Frame, Frame->ScopeTable->Filter, _SEH3$_CPP_HANDLER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
LONG
|
LONG
|
||||||
_SEH3$_GetFilterResult(
|
_SEH3$_GetFilterResult(
|
||||||
PSEH3$_REGISTRATION_FRAME Record)
|
PSEH3$_REGISTRATION_FRAME Record,
|
||||||
|
int HandlerType)
|
||||||
{
|
{
|
||||||
PVOID Filter = Record->ScopeTable->Filter;
|
PVOID Filter = Record->ScopeTable->Filter;
|
||||||
LONG Result;
|
LONG Result;
|
||||||
|
@ -214,7 +245,7 @@ _SEH3$_GetFilterResult(
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Call the filter function */
|
/* Call the filter function */
|
||||||
Result = _SEH3$_InvokeFilter(Record, Filter);
|
Result = _SEH3$_InvokeFilter(Record, Filter, HandlerType);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Normalize the result */
|
/* Normalize the result */
|
||||||
|
@ -226,9 +257,10 @@ _SEH3$_GetFilterResult(
|
||||||
static inline
|
static inline
|
||||||
VOID
|
VOID
|
||||||
_SEH3$_CallFinally(
|
_SEH3$_CallFinally(
|
||||||
PSEH3$_REGISTRATION_FRAME Record)
|
PSEH3$_REGISTRATION_FRAME Record,
|
||||||
|
int HandlerType)
|
||||||
{
|
{
|
||||||
_SEH3$_InvokeFilter(Record, Record->ScopeTable->Filter);
|
_SEH3$_InvokeFilter(Record, Record->ScopeTable->Filter, HandlerType);
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((noreturn))
|
__attribute__((noreturn))
|
||||||
|
@ -237,8 +269,7 @@ void
|
||||||
_SEH3$_JumpToTarget(
|
_SEH3$_JumpToTarget(
|
||||||
PSEH3$_REGISTRATION_FRAME RegistrationFrame)
|
PSEH3$_REGISTRATION_FRAME RegistrationFrame)
|
||||||
{
|
{
|
||||||
if (RegistrationFrame->ScopeTable->HandlerType == _SEH3$_CLANG_HANDLER)
|
#ifdef __clang__
|
||||||
{
|
|
||||||
asm volatile (
|
asm volatile (
|
||||||
/* Load the registers */
|
/* Load the registers */
|
||||||
"movl 24(%%ecx), %%esp\n\t"
|
"movl 24(%%ecx), %%esp\n\t"
|
||||||
|
@ -258,9 +289,7 @@ _SEH3$_JumpToTarget(
|
||||||
"a" (RegistrationFrame->ScopeTable),
|
"a" (RegistrationFrame->ScopeTable),
|
||||||
[Target] "m" (RegistrationFrame->ScopeTable->Target)
|
[Target] "m" (RegistrationFrame->ScopeTable->Target)
|
||||||
);
|
);
|
||||||
}
|
#else
|
||||||
else
|
|
||||||
{
|
|
||||||
asm volatile (
|
asm volatile (
|
||||||
/* Load the registers */
|
/* Load the registers */
|
||||||
"movl 24(%%ecx), %%esp\n\t"
|
"movl 24(%%ecx), %%esp\n\t"
|
||||||
|
@ -276,7 +305,7 @@ _SEH3$_JumpToTarget(
|
||||||
"a" (RegistrationFrame->ScopeTable),
|
"a" (RegistrationFrame->ScopeTable),
|
||||||
[Target] "m" (RegistrationFrame->ScopeTable->Target)
|
[Target] "m" (RegistrationFrame->ScopeTable->Target)
|
||||||
);
|
);
|
||||||
}
|
#endif
|
||||||
|
|
||||||
__builtin_unreachable();
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
|
@ -287,16 +316,17 @@ _SEH3$_CallRtlUnwind(
|
||||||
PSEH3$_REGISTRATION_FRAME RegistrationFrame);
|
PSEH3$_REGISTRATION_FRAME RegistrationFrame);
|
||||||
|
|
||||||
|
|
||||||
EXCEPTION_DISPOSITION
|
int // EXCEPTION_DISPOSITION
|
||||||
__cdecl
|
__cdecl
|
||||||
#ifndef __clang__
|
#ifndef __clang__
|
||||||
__attribute__ ((__target__ ("cld")))
|
__attribute__ ((__target__ ("cld")))
|
||||||
#endif
|
#endif
|
||||||
_SEH3$_except_handler(
|
_SEH3$_common_except_handler(
|
||||||
struct _EXCEPTION_RECORD * ExceptionRecord,
|
struct _EXCEPTION_RECORD * ExceptionRecord,
|
||||||
PSEH3$_REGISTRATION_FRAME EstablisherFrame,
|
PSEH3$_REGISTRATION_FRAME EstablisherFrame,
|
||||||
struct _CONTEXT * ContextRecord,
|
struct _CONTEXT * ContextRecord,
|
||||||
void * DispatcherContext)
|
void * DispatcherContext,
|
||||||
|
int HandlerType)
|
||||||
{
|
{
|
||||||
PSEH3$_REGISTRATION_FRAME CurrentFrame, TargetFrame;
|
PSEH3$_REGISTRATION_FRAME CurrentFrame, TargetFrame;
|
||||||
SEH3$_EXCEPTION_POINTERS ExceptionPointers;
|
SEH3$_EXCEPTION_POINTERS ExceptionPointers;
|
||||||
|
@ -329,7 +359,7 @@ _SEH3$_except_handler(
|
||||||
CurrentFrame->ExceptionCode = ExceptionRecord->ExceptionCode;
|
CurrentFrame->ExceptionCode = ExceptionRecord->ExceptionCode;
|
||||||
|
|
||||||
/* Get the filter result */
|
/* Get the filter result */
|
||||||
FilterResult = _SEH3$_GetFilterResult(CurrentFrame);
|
FilterResult = _SEH3$_GetFilterResult(CurrentFrame, HandlerType);
|
||||||
|
|
||||||
/* Check, if continuuing is requested */
|
/* Check, if continuuing is requested */
|
||||||
if (FilterResult == EXCEPTION_CONTINUE_EXECUTION)
|
if (FilterResult == EXCEPTION_CONTINUE_EXECUTION)
|
||||||
|
@ -372,7 +402,7 @@ _SEH3$_except_handler(
|
||||||
CurrentFrame->ExceptionCode = ExceptionRecord->ExceptionCode;
|
CurrentFrame->ExceptionCode = ExceptionRecord->ExceptionCode;
|
||||||
|
|
||||||
/* Call the finally function */
|
/* Call the finally function */
|
||||||
_SEH3$_CallFinally(CurrentFrame);
|
_SEH3$_CallFinally(CurrentFrame, HandlerType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -392,3 +422,28 @@ _SEH3$_except_handler(
|
||||||
_SEH3$_JumpToTarget(CurrentFrame);
|
_SEH3$_JumpToTarget(CurrentFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int // EXCEPTION_DISPOSITION
|
||||||
|
__cdecl
|
||||||
|
_SEH3$_C_except_handler(
|
||||||
|
struct _EXCEPTION_RECORD* ExceptionRecord,
|
||||||
|
PSEH3$_REGISTRATION_FRAME EstablisherFrame,
|
||||||
|
struct _CONTEXT* ContextRecord,
|
||||||
|
void* DispatcherContext)
|
||||||
|
{
|
||||||
|
#ifdef __clang__
|
||||||
|
return _SEH3$_common_except_handler(ExceptionRecord, EstablisherFrame, ContextRecord, DispatcherContext, _SEH3$_CLANG_HANDLER);
|
||||||
|
#else
|
||||||
|
return _SEH3$_common_except_handler(ExceptionRecord, EstablisherFrame, ContextRecord, DispatcherContext, _SEH3$_NESTED_HANDLER);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int // EXCEPTION_DISPOSITION
|
||||||
|
__cdecl
|
||||||
|
_SEH3$_CPP_except_handler(
|
||||||
|
struct _EXCEPTION_RECORD* ExceptionRecord,
|
||||||
|
PSEH3$_REGISTRATION_FRAME EstablisherFrame,
|
||||||
|
struct _CONTEXT* ContextRecord,
|
||||||
|
void* DispatcherContext)
|
||||||
|
{
|
||||||
|
return _SEH3$_common_except_handler(ExceptionRecord, EstablisherFrame, ContextRecord, DispatcherContext, _SEH3$_CPP_HANDLER);
|
||||||
|
}
|
||||||
|
|
|
@ -2,17 +2,19 @@
|
||||||
|
|
||||||
#define SEH3_REGISTRATION_FRAME_Next 0
|
#define SEH3_REGISTRATION_FRAME_Next 0
|
||||||
#define SEH3_REGISTRATION_FRAME_Handler 4
|
#define SEH3_REGISTRATION_FRAME_Handler 4
|
||||||
#define SEH3_REGISTRATION_FRAME_EndOfChain 8
|
#define SEH3_REGISTRATION_FRAME_ScopeTable 8
|
||||||
#define SEH3_REGISTRATION_FRAME_ScopeTable 12
|
#define SEH3_REGISTRATION_FRAME_TryLevel 12
|
||||||
#define SEH3_REGISTRATION_FRAME_ExceptionPointers 16
|
#define SEH3_REGISTRATION_FRAME_EndOfChain 16
|
||||||
#define SEH3_REGISTRATION_FRAME_ExceptionCode 20
|
#define SEH3_REGISTRATION_FRAME_ExceptionPointers 20
|
||||||
#define SEH3_REGISTRATION_FRAME_Esp 24
|
#define SEH3_REGISTRATION_FRAME_Esp 24
|
||||||
#define SEH3_REGISTRATION_FRAME_Ebp 28
|
#define SEH3_REGISTRATION_FRAME_Ebp 28
|
||||||
#define SEH3_REGISTRATION_FRAME_AllocaFrame 32
|
#define SEH3_REGISTRATION_FRAME_ExceptionCode 32
|
||||||
#define SEH3_REGISTRATION_FRAME_Ebx 36
|
#define SEH3_REGISTRATION_FRAME_AllocaFrame 36
|
||||||
#define SEH3_REGISTRATION_FRAME_Esi 40
|
#define SEH3_REGISTRATION_FRAME_Ebx 40
|
||||||
#define SEH3_REGISTRATION_FRAME_Edi 44
|
#define SEH3_REGISTRATION_FRAME_Esi 44
|
||||||
#define SEH3_REGISTRATION_FRAME_ReturnAddress 48
|
#define SEH3_REGISTRATION_FRAME_Edi 48
|
||||||
|
#define SEH3_REGISTRATION_FRAME_ReturnAddress 52
|
||||||
|
|
||||||
#define SEH3_SCOPE_TABLE_Target 0
|
#define SEH3_SCOPE_TABLE_EnclosingLevel 0
|
||||||
#define SEH3_SCOPE_TABLE_Filter 4
|
#define SEH3_SCOPE_TABLE_Filter 4
|
||||||
|
#define SEH3_SCOPE_TABLE_Target 8
|
||||||
|
|
|
@ -47,9 +47,6 @@ __SEH3$_RegisterFrame:
|
||||||
/* Save the address of the static data table */
|
/* Save the address of the static data table */
|
||||||
mov [eax + SEH3_REGISTRATION_FRAME_ScopeTable], edx
|
mov [eax + SEH3_REGISTRATION_FRAME_ScopeTable], edx
|
||||||
|
|
||||||
/* Set the handler address */
|
|
||||||
mov dword ptr [eax + SEH3_REGISTRATION_FRAME_Handler], offset __SEH3$_except_handler
|
|
||||||
|
|
||||||
/* Set this as the end of the internal chain */
|
/* Set this as the end of the internal chain */
|
||||||
mov dword ptr [eax + SEH3_REGISTRATION_FRAME_EndOfChain], eax
|
mov dword ptr [eax + SEH3_REGISTRATION_FRAME_EndOfChain], eax
|
||||||
|
|
||||||
|
|
|
@ -21,26 +21,11 @@ extern "C" {
|
||||||
#define _SEH3$_FRAME_ALL_NONVOLATILES 1
|
#define _SEH3$_FRAME_ALL_NONVOLATILES 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
_SEH3$_NESTED_HANDLER = 0,
|
|
||||||
_SEH3$_CPP_HANDLER = 1,
|
|
||||||
_SEH3$_CLANG_HANDLER = 2,
|
|
||||||
#ifdef __clang__
|
|
||||||
_SEH3$_HANDLER_TYPE = _SEH3$_CLANG_HANDLER,
|
|
||||||
#elif defined(__cplusplus)
|
|
||||||
_SEH3$_HANDLER_TYPE = _SEH3$_CPP_HANDLER,
|
|
||||||
#else
|
|
||||||
_SEH3$_HANDLER_TYPE = _SEH3$_NESTED_HANDLER,
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct _SEH3$_SCOPE_TABLE
|
typedef struct _SEH3$_SCOPE_TABLE
|
||||||
{
|
{
|
||||||
void *Target;
|
unsigned long EnclosingLevel;
|
||||||
void *Filter;
|
void *Filter;
|
||||||
unsigned char TryLevel;
|
void *Target;
|
||||||
unsigned char HandlerType;
|
|
||||||
} SEH3$_SCOPE_TABLE, *PSEH3$_SCOPE_TABLE;
|
} SEH3$_SCOPE_TABLE, *PSEH3$_SCOPE_TABLE;
|
||||||
|
|
||||||
typedef struct _SEH3$_EXCEPTION_POINTERS
|
typedef struct _SEH3$_EXCEPTION_POINTERS
|
||||||
|
@ -55,22 +40,25 @@ typedef struct _SEH3$_REGISTRATION_FRAME
|
||||||
struct _SEH3$_REGISTRATION_FRAME *Next;
|
struct _SEH3$_REGISTRATION_FRAME *Next;
|
||||||
void *Handler;
|
void *Handler;
|
||||||
|
|
||||||
/* Points to the end of the internal registration chain */
|
|
||||||
struct _SEH3$_REGISTRATION_FRAME *EndOfChain;
|
|
||||||
|
|
||||||
/* Pointer to the static scope table */
|
/* Pointer to the static scope table */
|
||||||
PSEH3$_SCOPE_TABLE ScopeTable;
|
PSEH3$_SCOPE_TABLE ScopeTable;
|
||||||
|
|
||||||
|
/* Index into ScopeTable array */
|
||||||
|
unsigned long TryLevel;
|
||||||
|
|
||||||
|
/* Points to the end of the internal registration chain */
|
||||||
|
struct _SEH3$_REGISTRATION_FRAME *EndOfChain;
|
||||||
|
|
||||||
/* Except handler stores pointer to exception pointers here */
|
/* Except handler stores pointer to exception pointers here */
|
||||||
PSEH3$_EXCEPTION_POINTERS volatile ExceptionPointers;
|
PSEH3$_EXCEPTION_POINTERS volatile ExceptionPointers;
|
||||||
|
|
||||||
/* Except handler stores the exception code here */
|
|
||||||
unsigned long ExceptionCode;
|
|
||||||
|
|
||||||
/* Registers that we need to save */
|
/* Registers that we need to save */
|
||||||
unsigned long Esp;
|
unsigned long Esp;
|
||||||
unsigned long Ebp;
|
unsigned long Ebp;
|
||||||
|
|
||||||
|
/* Except handler stores the exception code here */
|
||||||
|
unsigned long ExceptionCode;
|
||||||
|
|
||||||
char* AllocaFrame;
|
char* AllocaFrame;
|
||||||
#ifdef _SEH3$_FRAME_ALL_NONVOLATILES
|
#ifdef _SEH3$_FRAME_ALL_NONVOLATILES
|
||||||
unsigned long Ebx;
|
unsigned long Ebx;
|
||||||
|
@ -82,6 +70,22 @@ typedef struct _SEH3$_REGISTRATION_FRAME
|
||||||
#endif
|
#endif
|
||||||
} SEH3$_REGISTRATION_FRAME ,*PSEH3$_REGISTRATION_FRAME;
|
} SEH3$_REGISTRATION_FRAME ,*PSEH3$_REGISTRATION_FRAME;
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
#define _SEH3$_except_handler _SEH3$_CPP_except_handler
|
||||||
|
#define _SEH3$_AutoCleanup _SEH3$_CPP_AutoCleanup
|
||||||
|
#else
|
||||||
|
#define _SEH3$_except_handler _SEH3$_C_except_handler
|
||||||
|
#define _SEH3$_AutoCleanup _SEH3$_C_AutoCleanup
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int
|
||||||
|
__cdecl
|
||||||
|
_SEH3$_except_handler(
|
||||||
|
struct _EXCEPTION_RECORD * ExceptionRecord,
|
||||||
|
PSEH3$_REGISTRATION_FRAME EstablisherFrame,
|
||||||
|
struct _CONTEXT * ContextRecord,
|
||||||
|
void * DispatcherContext);
|
||||||
|
|
||||||
/* Prevent gcc from inlining functions that use SEH. */
|
/* Prevent gcc from inlining functions that use SEH. */
|
||||||
static inline __attribute__((always_inline)) __attribute__((returns_twice)) void _SEH3$_PreventInlining() {}
|
static inline __attribute__((always_inline)) __attribute__((returns_twice)) void _SEH3$_PreventInlining() {}
|
||||||
|
|
||||||
|
@ -106,7 +110,7 @@ void _SEH3$_UnregisterTryLevel(
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
_SEH3$_TryLevel = 0,
|
_SEH3$_TryLevel = -1,
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef __clang__
|
#ifndef __clang__
|
||||||
|
@ -146,6 +150,8 @@ _SEH3$_RegisterTryLevelWithNonVolatiles(
|
||||||
|
|
||||||
#define _SEH3$_RegisterFrame_(_TrylevelFrame, _DataTable) \
|
#define _SEH3$_RegisterFrame_(_TrylevelFrame, _DataTable) \
|
||||||
do { \
|
do { \
|
||||||
|
(_TrylevelFrame)->Handler = (void*)_SEH3$_except_handler; \
|
||||||
|
(_TrylevelFrame)->TryLevel = 0; \
|
||||||
int result = _SEH3$_RegisterFrameWithNonVolatiles(_TrylevelFrame, _DataTable, __builtin_alloca(0)); \
|
int result = _SEH3$_RegisterFrameWithNonVolatiles(_TrylevelFrame, _DataTable, __builtin_alloca(0)); \
|
||||||
if (__builtin_expect(result != 0, 0)) \
|
if (__builtin_expect(result != 0, 0)) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -157,6 +163,7 @@ _SEH3$_RegisterTryLevelWithNonVolatiles(
|
||||||
|
|
||||||
#define _SEH3$_RegisterTryLevel_(_TrylevelFrame, _DataTable) \
|
#define _SEH3$_RegisterTryLevel_(_TrylevelFrame, _DataTable) \
|
||||||
do { \
|
do { \
|
||||||
|
(_TrylevelFrame)->TryLevel = _SEH3$_TryLevel; \
|
||||||
int result = _SEH3$_RegisterTryLevelWithNonVolatiles(_TrylevelFrame, _DataTable, __builtin_alloca(0)); \
|
int result = _SEH3$_RegisterTryLevelWithNonVolatiles(_TrylevelFrame, _DataTable, __builtin_alloca(0)); \
|
||||||
if (__builtin_expect(result != 0, 0)) \
|
if (__builtin_expect(result != 0, 0)) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -198,11 +205,18 @@ _SEH3$_RegisterTryLevelWithNonVolatiles(
|
||||||
|
|
||||||
/* This is an asm wrapper around _SEH3$_RegisterFrame */
|
/* This is an asm wrapper around _SEH3$_RegisterFrame */
|
||||||
#define _SEH3$_RegisterFrame_(_TrylevelFrame, _DataTable) \
|
#define _SEH3$_RegisterFrame_(_TrylevelFrame, _DataTable) \
|
||||||
_SEH3$_CALL_WRAPPER(__SEH3$_RegisterFrame, _TrylevelFrame, _DataTable)
|
do { \
|
||||||
|
(_TrylevelFrame)->Handler = (void*)_SEH3$_except_handler; \
|
||||||
|
(_TrylevelFrame)->TryLevel = 0; \
|
||||||
|
_SEH3$_CALL_WRAPPER(__SEH3$_RegisterFrame, _TrylevelFrame, _DataTable); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/* This is an asm wrapper around _SEH3$_RegisterTryLevel */
|
/* This is an asm wrapper around _SEH3$_RegisterTryLevel */
|
||||||
#define _SEH3$_RegisterTryLevel_(_TrylevelFrame, _DataTable) \
|
#define _SEH3$_RegisterTryLevel_(_TrylevelFrame, _DataTable) \
|
||||||
_SEH3$_CALL_WRAPPER(__SEH3$_RegisterTryLevel, _TrylevelFrame, _DataTable)
|
do { \
|
||||||
|
(_TrylevelFrame)->TryLevel = _SEH3$_TryLevel; \
|
||||||
|
_SEH3$_CALL_WRAPPER(__SEH3$_RegisterTryLevel, _TrylevelFrame, _DataTable); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/* This construct scares GCC so much, that it will stop moving code
|
/* This construct scares GCC so much, that it will stop moving code
|
||||||
around into places that are never executed. */
|
around into places that are never executed. */
|
||||||
|
@ -330,7 +344,7 @@ _Pragma("GCC diagnostic pop") \
|
||||||
{ \
|
{ \
|
||||||
(void)p; \
|
(void)p; \
|
||||||
/* Unregister the frame */ \
|
/* Unregister the frame */ \
|
||||||
if (_SEH3$_TryLevel == 1) _SEH3$_UnregisterFrame(&_SEH3$_TrylevelFrame); \
|
if (_SEH3$_TryLevel == 0) _SEH3$_UnregisterFrame(&_SEH3$_TrylevelFrame); \
|
||||||
else _SEH3$_UnregisterTryLevel(&_SEH3$_TrylevelFrame); \
|
else _SEH3$_UnregisterTryLevel(&_SEH3$_TrylevelFrame); \
|
||||||
\
|
\
|
||||||
/* Invoke the finally function (an inline dummy in the __except case) */ \
|
/* Invoke the finally function (an inline dummy in the __except case) */ \
|
||||||
|
@ -358,7 +372,7 @@ _Pragma("GCC diagnostic pop") \
|
||||||
(void)&&_SEH3$_l_BeforeFilterOrFinally; \
|
(void)&&_SEH3$_l_BeforeFilterOrFinally; \
|
||||||
(void)&&_SEH3$_l_FilterOrFinally; \
|
(void)&&_SEH3$_l_FilterOrFinally; \
|
||||||
\
|
\
|
||||||
/* Count the try level. Outside of any __try, _SEH3$_TryLevel is 0 */ \
|
/* Count the try level. Outside of any __try, _SEH3$_TryLevel is -1 */ \
|
||||||
enum { \
|
enum { \
|
||||||
_SEH3$_PreviousTryLevel = _SEH3$_TryLevel, \
|
_SEH3$_PreviousTryLevel = _SEH3$_TryLevel, \
|
||||||
_SEH3$_TryLevel = _SEH3$_PreviousTryLevel + 1, \
|
_SEH3$_TryLevel = _SEH3$_PreviousTryLevel + 1, \
|
||||||
|
@ -394,10 +408,10 @@ _Pragma("GCC diagnostic pop") \
|
||||||
_SEH3$_DECLARE_FILTER_FUNC(_SEH3$_FilterFunction); \
|
_SEH3$_DECLARE_FILTER_FUNC(_SEH3$_FilterFunction); \
|
||||||
\
|
\
|
||||||
/* Create a static data table that contains the jump target and filter function */ \
|
/* Create a static data table that contains the jump target and filter function */ \
|
||||||
static const SEH3$_SCOPE_TABLE _SEH3$_ScopeTable = { &&_SEH3$_l_HandlerTarget, _SEH3$_FILTER(&_SEH3$_FilterFunction, (__VA_ARGS__)), _SEH3$_TryLevel, _SEH3$_HANDLER_TYPE }; \
|
static const SEH3$_SCOPE_TABLE __attribute__((section(".xdata$x"))) _SEH3$_ScopeTable = { (unsigned)(_SEH3$_TryLevel - 1), _SEH3$_FILTER(&_SEH3$_FilterFunction, (__VA_ARGS__)), &&_SEH3$_l_HandlerTarget }; \
|
||||||
\
|
\
|
||||||
/* Register the registration record. */ \
|
/* Register the registration record. */ \
|
||||||
if (_SEH3$_TryLevel == 1) _SEH3$_RegisterFrame_(&_SEH3$_TrylevelFrame, &_SEH3$_ScopeTable); \
|
if (_SEH3$_TryLevel == 0) _SEH3$_RegisterFrame_(&_SEH3$_TrylevelFrame, &_SEH3$_ScopeTable); \
|
||||||
else _SEH3$_RegisterTryLevel_(&_SEH3$_TrylevelFrame, &_SEH3$_ScopeTable); \
|
else _SEH3$_RegisterTryLevel_(&_SEH3$_TrylevelFrame, &_SEH3$_ScopeTable); \
|
||||||
\
|
\
|
||||||
/* Define an empty inline finally function */ \
|
/* Define an empty inline finally function */ \
|
||||||
|
@ -442,10 +456,10 @@ _Pragma("GCC diagnostic pop") \
|
||||||
_SEH3$_DECLARE_FILTER_FUNC(_SEH3$_FinallyFunction); \
|
_SEH3$_DECLARE_FILTER_FUNC(_SEH3$_FinallyFunction); \
|
||||||
\
|
\
|
||||||
/* Create a static data table that contains the finally function */ \
|
/* Create a static data table that contains the finally function */ \
|
||||||
static const SEH3$_SCOPE_TABLE _SEH3$_ScopeTable = { 0, _SEH3$_FINALLY(&_SEH3$_FinallyFunction), _SEH3$_TryLevel, _SEH3$_HANDLER_TYPE }; \
|
static const SEH3$_SCOPE_TABLE __attribute__((section(".xdata$x"))) _SEH3$_ScopeTable = { (unsigned)(_SEH3$_TryLevel - 1), _SEH3$_FINALLY(&_SEH3$_FinallyFunction), 0 }; \
|
||||||
\
|
\
|
||||||
/* Register the registration record. */ \
|
/* Register the registration record. */ \
|
||||||
if (_SEH3$_TryLevel == 1) _SEH3$_RegisterFrame_(&_SEH3$_TrylevelFrame, &_SEH3$_ScopeTable); \
|
if (_SEH3$_TryLevel == 0) _SEH3$_RegisterFrame_(&_SEH3$_TrylevelFrame, &_SEH3$_ScopeTable); \
|
||||||
else _SEH3$_RegisterTryLevel_(&_SEH3$_TrylevelFrame, &_SEH3$_ScopeTable); \
|
else _SEH3$_RegisterTryLevel_(&_SEH3$_TrylevelFrame, &_SEH3$_ScopeTable); \
|
||||||
_SEH3$_TrylevelFrame.ExceptionPointers = (PSEH3$_EXCEPTION_POINTERS)1; \
|
_SEH3$_TrylevelFrame.ExceptionPointers = (PSEH3$_EXCEPTION_POINTERS)1; \
|
||||||
\
|
\
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue