[PSEH] Make structures more SEH3 compatible

This commit is contained in:
Timo Kreuzer 2025-07-04 20:06:19 +03:00
parent 6d2eb03402
commit d23ee5f365
4 changed files with 137 additions and 69 deletions

View file

@ -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);
}

View file

@ -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

View file

@ -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

View file

@ -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; \
\ \