mirror of
https://github.com/reactos/reactos.git
synced 2024-07-13 16:15:05 +00:00
[PSEH3]
- Add AllocaFrame field to the exception registration record. It is required for Clang and C++ handlers. - Fix the way how "nested functions" are emulated on Clang and C++, respecting the fact that the compiler can and will use a temporary esp-based stack frame below any alloca-allocations for function invocation. This uses the AllocaFrame field to calculate and setup a new temp stack frame for the "nested functions". - Make use of the HandlerType field in the exception registration record to use different methods for invoking filters / finally functions. - Write @_SEH3$_CallRtlUnwind@4 in raw asm instead of inline, because Clang cannot deal with stdcall decorations in inline asm (see http://llvm.org/bugs/show_bug.cgi?id=19027) - Make sure ExceptionPointers are properly initialized in _SEH3$_except_handler svn path=/trunk/; revision=62466
This commit is contained in:
parent
1ff93cb52e
commit
7165a7c35b
|
@ -67,6 +67,8 @@ typedef struct _SEH3$_REGISTRATION_FRAME
|
|||
/* Registers that we need to save */
|
||||
unsigned long Esp;
|
||||
unsigned long Ebp;
|
||||
|
||||
char* AllocaFrame;
|
||||
#ifdef _SEH3$_FRAME_ALL_NONVOLATILES
|
||||
unsigned long Ebx;
|
||||
unsigned long Esi;
|
||||
|
@ -101,10 +103,12 @@ enum
|
|||
_SEH3$_TryLevel = 0,
|
||||
};
|
||||
|
||||
#ifndef __clang__
|
||||
/* These are global dummy definitions, that get overwritten in the local context of __finally / __except blocks */
|
||||
int __cdecl __attribute__((error ("Can only be used inside a __finally block."))) _abnormal_termination(void);
|
||||
unsigned long __cdecl __attribute__((error("Can only be used inside an exception filter or __except block."))) _exception_code(void);
|
||||
void * __cdecl __attribute__((error("Can only be used inside an exception filter."))) _exception_info(void);
|
||||
#endif
|
||||
|
||||
/* This attribute allows automatic cleanup of the registered frames */
|
||||
#define _SEH3$_AUTO_CLEANUP __attribute__((cleanup(_SEH3$_Unregister)))
|
||||
|
@ -119,15 +123,16 @@ void * __cdecl __attribute__((error("Can only be used inside an exception filter
|
|||
#define _SEH3$_ASM_GOTO(_Label, ...)
|
||||
|
||||
int
|
||||
__attribute__((regparm(2)))
|
||||
__attribute__((regparm(3)))
|
||||
__attribute__((returns_twice))
|
||||
_SEH3$_RegisterFrameWithNonVolatiles(
|
||||
volatile SEH3$_REGISTRATION_FRAME* RegistrationFrame,
|
||||
const SEH3$_SCOPE_TABLE* ScopeTable);
|
||||
const SEH3$_SCOPE_TABLE* ScopeTable,
|
||||
void* AllocaFrame);
|
||||
|
||||
#define _SEH3$_RegisterFrame_(_TrylevelFrame, _DataTable) \
|
||||
do { \
|
||||
int result = _SEH3$_RegisterFrameWithNonVolatiles(_TrylevelFrame, _DataTable); \
|
||||
int result = _SEH3$_RegisterFrameWithNonVolatiles(_TrylevelFrame, _DataTable, __builtin_alloca(0)); \
|
||||
if (__builtin_expect(result != 0, 0)) \
|
||||
{ \
|
||||
if (result == 1) goto _SEH3$_l_FilterOrFinally; \
|
||||
|
@ -137,15 +142,16 @@ _SEH3$_RegisterFrameWithNonVolatiles(
|
|||
} while(0)
|
||||
|
||||
int
|
||||
__attribute__((regparm(2)))
|
||||
__attribute__((regparm(3)))
|
||||
__attribute__((returns_twice))
|
||||
_SEH3$_RegisterTryLevelWithNonVolatiles(
|
||||
volatile SEH3$_REGISTRATION_FRAME* RegistrationFrame,
|
||||
const SEH3$_SCOPE_TABLE* ScopeTable);
|
||||
const SEH3$_SCOPE_TABLE* ScopeTable,
|
||||
void* AllocaFrame);
|
||||
|
||||
#define _SEH3$_RegisterTryLevel_(_TrylevelFrame, _DataTable) \
|
||||
do { \
|
||||
int result = _SEH3$_RegisterTryLevelWithNonVolatiles(_TrylevelFrame, _DataTable); \
|
||||
int result = _SEH3$_RegisterTryLevelWithNonVolatiles(_TrylevelFrame, _DataTable, __builtin_alloca(0)); \
|
||||
if (__builtin_expect(result != 0, 0)) \
|
||||
{ \
|
||||
if (result == 1) goto _SEH3$_l_FilterOrFinally; \
|
||||
|
@ -163,25 +169,34 @@ _SEH3$_RegisterTryLevelWithNonVolatiles(
|
|||
|
||||
#define _SEH3$_ASM_GOTO(_Label, ...) asm goto ("#\n" : : : "memory", ## __VA_ARGS__ : _Label)
|
||||
|
||||
/* This is an asm wrapper around _SEH3$_RegisterFrame */
|
||||
#define _SEH3$_RegisterFrame_(_TrylevelFrame, _DataTable) \
|
||||
#ifdef __cplusplus
|
||||
#define _SEH3$_CALL_WRAPPER(_Function, _TrylevelFrame, _DataTable) \
|
||||
asm goto ("leal %0, %%eax\n" \
|
||||
"leal %1, %%edx\n" \
|
||||
"call __SEH3$_RegisterFrame\n" \
|
||||
"call " #_Function "WithStackLayout\n" \
|
||||
: \
|
||||
: "m" (*(_TrylevelFrame)), "m" (*(_DataTable)), "c"(__builtin_alloca(0)) \
|
||||
: "eax", "edx", "memory" \
|
||||
: _SEH3$_l_HandlerTarget, _SEH3$_l_FilterOrFinally)
|
||||
|
||||
#else
|
||||
#define _SEH3$_CALL_WRAPPER(_Function, _TrylevelFrame, _DataTable) \
|
||||
asm goto ("leal %0, %%eax\n" \
|
||||
"leal %1, %%edx\n" \
|
||||
"call " #_Function "\n" \
|
||||
: \
|
||||
: "m" (*(_TrylevelFrame)), "m" (*(_DataTable)) \
|
||||
: "ecx", "edx", "memory" \
|
||||
: "eax", "edx", "ecx", "memory" \
|
||||
: _SEH3$_l_HandlerTarget)
|
||||
#endif
|
||||
|
||||
/* This is an asm wrapper around _SEH3$_RegisterFrame */
|
||||
#define _SEH3$_RegisterFrame_(_TrylevelFrame, _DataTable) \
|
||||
_SEH3$_CALL_WRAPPER(__SEH3$_RegisterFrame, _TrylevelFrame, _DataTable)
|
||||
|
||||
/* This is an asm wrapper around _SEH3$_RegisterTryLevel */
|
||||
#define _SEH3$_RegisterTryLevel_(_TrylevelFrame, _DataTable) \
|
||||
asm goto ("leal %0, %%eax\n" \
|
||||
"leal %1, %%edx\n" \
|
||||
"call __SEH3$_RegisterTryLevel\n" \
|
||||
: \
|
||||
: "m" (*(_TrylevelFrame)), "m" (*(_DataTable)) \
|
||||
: "ecx", "edx", "memory" \
|
||||
: _SEH3$_l_HandlerTarget)
|
||||
_SEH3$_CALL_WRAPPER(__SEH3$_RegisterTryLevel, _TrylevelFrame, _DataTable)
|
||||
|
||||
/* This construct scares GCC so much, that it will stop moving code
|
||||
around into places that are never executed. */
|
||||
|
@ -214,15 +229,17 @@ _SEH3$_Unregister(
|
|||
/* The "nested" functions are a piece of code with a ret instruction at the end */
|
||||
#define _SEH3$_NESTED_FUNC_OPEN() \
|
||||
{ \
|
||||
int SavedEsp, result = 0; \
|
||||
\
|
||||
/* Save esp */ \
|
||||
asm volatile ("movl %%esp, %[SavedEsp]\n" : : [SavedEsp]"m"(SavedEsp));
|
||||
int _SEH3$_Result = 0; \
|
||||
|
||||
/* On invocation, the AllocaFrame field is loaded with the return esp value */
|
||||
#define _SEH3$_NESTED_FUNC_RETURN() \
|
||||
/* Restore esp and return to the caller */ \
|
||||
asm volatile ("movl %[FixedEsp], %%esp\nret\n" \
|
||||
: : "a"(_SEH3$_Result), [FixedEsp]"m"(_SEH3$_TrylevelFrame.AllocaFrame) : "memory")
|
||||
|
||||
#define _SEH3$_NESTED_FUNC_CLOSE() \
|
||||
/* Restore esp and return to the caller */ \
|
||||
asm volatile ("movl %[SavedEsp], %%esp\nret\n" \
|
||||
: : "a"(result), [SavedEsp]"irm"(SavedEsp)); \
|
||||
/* Return to the caller */ \
|
||||
_SEH3$_NESTED_FUNC_RETURN(); \
|
||||
}
|
||||
|
||||
/* The filter function */
|
||||
|
@ -230,7 +247,7 @@ _SEH3$_Unregister(
|
|||
_SEH3$_NESTED_FUNC_OPEN() \
|
||||
{ \
|
||||
/* Evaluate the filter expression */ \
|
||||
result = (expression); \
|
||||
_SEH3$_Result = (expression); \
|
||||
} \
|
||||
_SEH3$_NESTED_FUNC_CLOSE()
|
||||
|
||||
|
@ -238,11 +255,10 @@ _SEH3$_Unregister(
|
|||
_SEH3$_NESTED_FUNC_OPEN() \
|
||||
/* This construct makes sure that the finally function returns */ \
|
||||
/* a proper value at the end */ \
|
||||
for (; ; (void)({asm volatile ("movl %[SavedEsp], %%esp\nret\n" \
|
||||
: : "a"(result), [SavedEsp]"irm"(SavedEsp)); 0;}))
|
||||
for (; ; (void)({_SEH3$_NESTED_FUNC_RETURN(); 0;}))
|
||||
|
||||
#define _SEH3$_FILTER(_Filter, _FilterExpression) (&&_SEH3$_l_FilterOrFinally)
|
||||
#define _SEH3$_FINALLY(_Finally) 0
|
||||
#define _SEH3$_FINALLY(_Finally) (&&_SEH3$_l_FilterOrFinally)
|
||||
|
||||
#define _SEH3$_DECLARE_EXCEPT_INTRINSICS()
|
||||
|
||||
|
@ -336,6 +352,7 @@ _SEH3$_Unregister(
|
|||
__label__ _SEH3$_l_OnException; \
|
||||
__label__ _SEH3$_l_BeforeFilterOrFinally; \
|
||||
__label__ _SEH3$_l_FilterOrFinally; \
|
||||
(void)&&_SEH3$_l_OnException; \
|
||||
(void)&&_SEH3$_l_BeforeFilterOrFinally; \
|
||||
(void)&&_SEH3$_l_FilterOrFinally; \
|
||||
\
|
||||
|
@ -419,7 +436,7 @@ _SEH3$_Unregister(
|
|||
_SEH3$_DECLARE_FILTER_FUNC(_SEH3$_FinallyFunction); \
|
||||
\
|
||||
/* Create a static data table that contains the finally function */ \
|
||||
static const SEH3$_SCOPE_TABLE _SEH3$_ScopeTable = { 0, _SEH3$_FINALLY(&_SEH3$_FinallyFunction) }; \
|
||||
static const SEH3$_SCOPE_TABLE _SEH3$_ScopeTable = { 0, _SEH3$_FINALLY(&_SEH3$_FinallyFunction), _SEH3$_TryLevel, _SEH3$_HANDLER_TYPE }; \
|
||||
\
|
||||
/* Register the registration record. */ \
|
||||
if (_SEH3$_TryLevel == 1) _SEH3$_RegisterFrame_(&_SEH3$_TrylevelFrame, &_SEH3$_ScopeTable); \
|
||||
|
@ -431,6 +448,7 @@ _SEH3$_Unregister(
|
|||
_SEH3$_EnforceFramePointer(); \
|
||||
\
|
||||
_SEH3$_l_BeforeFilterOrFinally: (void)0; \
|
||||
_SEH3$_EnforceFramePointer(); \
|
||||
_SEH3$_l_FilterOrFinally: (void)0; \
|
||||
_SEH3$_FINALLY_FUNC_OPEN(_SEH3$_FinallyFunction)
|
||||
|
||||
|
|
|
@ -63,8 +63,8 @@ _SEH3$_Unregister(
|
|||
|
||||
static inline
|
||||
LONG
|
||||
_SEH3$_InvokeFilter(
|
||||
PVOID Record,
|
||||
_SEH3$_InvokeNestedFunctionFilter(
|
||||
PSEH3$_REGISTRATION_FRAME RegistrationFrame,
|
||||
PVOID Filter)
|
||||
{
|
||||
LONG FilterResult;
|
||||
|
@ -78,18 +78,58 @@ _SEH3$_InvokeFilter(
|
|||
/* The result is the frame base address that we passed in (0) plus the
|
||||
offset to the registration record. */
|
||||
"negl %%eax\n\t"
|
||||
"addl %[Record], %%eax\n\t"
|
||||
"addl %[RegistrationFrame], %%eax\n\t"
|
||||
|
||||
/* Second call to get the filter result */
|
||||
"mov $1, %%ecx\n\t"
|
||||
"call *%[Filter]\n\t"
|
||||
: "=a"(FilterResult)
|
||||
: [Record] "m" (Record), [Filter] "m" (Filter)
|
||||
: [RegistrationFrame] "m" (RegistrationFrame), [Filter] "m" (Filter)
|
||||
: "ecx", "edx");
|
||||
|
||||
return FilterResult;
|
||||
}
|
||||
|
||||
long
|
||||
__attribute__((regparm(1)))
|
||||
_SEH3$_InvokeEmbeddedFilter(
|
||||
PSEH3$_REGISTRATION_FRAME RegistrationFrame);
|
||||
|
||||
long
|
||||
__attribute__((regparm(1)))
|
||||
_SEH3$_InvokeEmbeddedFilterFromRegistration(
|
||||
PSEH3$_REGISTRATION_FRAME RegistrationFrame);
|
||||
|
||||
static inline
|
||||
LONG
|
||||
_SEH3$_InvokeFilter(
|
||||
PSEH3$_REGISTRATION_FRAME RegistrationFrame,
|
||||
PVOID Filter)
|
||||
{
|
||||
LONG FilterResult;
|
||||
|
||||
if (RegistrationFrame->ScopeTable->HandlerType == _SEH3$_NESTED_HANDLER)
|
||||
{
|
||||
return _SEH3$_InvokeNestedFunctionFilter(RegistrationFrame, Filter);
|
||||
}
|
||||
else if (RegistrationFrame->ScopeTable->HandlerType == _SEH3$_CPP_HANDLER)
|
||||
{
|
||||
/* Call the embedded filter function */
|
||||
return _SEH3$_InvokeEmbeddedFilter(RegistrationFrame);
|
||||
}
|
||||
else if (RegistrationFrame->ScopeTable->HandlerType == _SEH3$_CLANG_HANDLER)
|
||||
{
|
||||
return _SEH3$_InvokeEmbeddedFilterFromRegistration(RegistrationFrame);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Should not happen! Skip this handler */
|
||||
FilterResult = EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
return FilterResult;
|
||||
}
|
||||
|
||||
static inline
|
||||
LONG
|
||||
_SEH3$_GetFilterResult(
|
||||
|
@ -136,45 +176,51 @@ void
|
|||
_SEH3$_JumpToTarget(
|
||||
PSEH3$_REGISTRATION_FRAME RegistrationFrame)
|
||||
{
|
||||
asm volatile (
|
||||
/* Load the registers */
|
||||
"movl 20(%%ecx), %%esp\n"
|
||||
"movl 24(%%ecx), %%ebp\n"
|
||||
if (RegistrationFrame->ScopeTable->HandlerType == _SEH3$_CLANG_HANDLER)
|
||||
{
|
||||
asm volatile (
|
||||
/* Load the registers */
|
||||
"movl 20(%%ecx), %%esp\n"
|
||||
"movl 24(%%ecx), %%ebp\n"
|
||||
|
||||
/* Stack pointer is 4 off from the call to __SEH3$_RegisterFrame */
|
||||
"addl $4, %%esp\n"
|
||||
/* Stack pointer is 4 off from the call to __SEH3$_RegisterFrame */
|
||||
"addl $4, %%esp\n"
|
||||
|
||||
/* Jump into the exception handler */
|
||||
"jmp *%[Target]\n"
|
||||
: :
|
||||
"c" (RegistrationFrame),
|
||||
"a" (RegistrationFrame->ScopeTable),
|
||||
[Target] "m" (RegistrationFrame->ScopeTable->Target)
|
||||
);
|
||||
/* Jump into the exception handler */
|
||||
"jmp *%[Target]\n"
|
||||
: :
|
||||
"c" (RegistrationFrame),
|
||||
"a" (RegistrationFrame->ScopeTable),
|
||||
[Target] "m" (RegistrationFrame->ScopeTable->Target)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
asm volatile (
|
||||
/* Load the registers */
|
||||
"movl 20(%%ecx), %%esp\n"
|
||||
"movl 24(%%ecx), %%ebp\n"
|
||||
|
||||
/* Stack pointer is 4 off from the call to __SEH3$_RegisterFrame */
|
||||
"addl $4, %%esp\n"
|
||||
|
||||
/* Jump into the exception handler */
|
||||
"jmp *%[Target]\n"
|
||||
: :
|
||||
"c" (RegistrationFrame),
|
||||
"a" (RegistrationFrame->ScopeTable),
|
||||
[Target] "m" (RegistrationFrame->ScopeTable->Target)
|
||||
);
|
||||
}
|
||||
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
static inline
|
||||
void
|
||||
__fastcall
|
||||
_SEH3$_CallRtlUnwind(
|
||||
PSEH3$_REGISTRATION_FRAME RegistrationFrame)
|
||||
{
|
||||
LONG ClobberedEax;
|
||||
PSEH3$_REGISTRATION_FRAME RegistrationFrame);
|
||||
|
||||
asm volatile(
|
||||
"push %%ebp\n"
|
||||
"push $0\n"
|
||||
"push $0\n"
|
||||
"push $0\n"
|
||||
"push %[TargetFrame]\n"
|
||||
"call _RtlUnwind@16\n"
|
||||
"pop %%ebp\n"
|
||||
: "=a" (ClobberedEax)
|
||||
: [TargetFrame] "a" (RegistrationFrame)
|
||||
: "ebx", "ecx", "edx", "esi",
|
||||
"edi", "flags", "memory");
|
||||
}
|
||||
|
||||
EXCEPTION_DISPOSITION
|
||||
__cdecl
|
||||
|
@ -192,6 +238,10 @@ _SEH3$_except_handler(
|
|||
/* Clear the direction flag. */
|
||||
asm volatile ("cld\n" : : : "memory");
|
||||
|
||||
/* Save the exception pointers on the stack */
|
||||
ExceptionPointers.ExceptionRecord = ExceptionRecord;
|
||||
ExceptionPointers.ContextRecord = ContextRecord;
|
||||
|
||||
/* Check if this is an unwind */
|
||||
if (ExceptionRecord->ExceptionFlags & EXCEPTION_UNWINDING)
|
||||
{
|
||||
|
@ -200,10 +250,6 @@ _SEH3$_except_handler(
|
|||
}
|
||||
else
|
||||
{
|
||||
/* Save the exception pointers on the stack */
|
||||
ExceptionPointers.ExceptionRecord = ExceptionRecord;
|
||||
ExceptionPointers.ContextRecord = ContextRecord;
|
||||
|
||||
/* Loop all frames for this registration */
|
||||
CurrentFrame = EstablisherFrame->EndOfChain;
|
||||
for (;;)
|
||||
|
|
|
@ -7,9 +7,10 @@
|
|||
#define SEH3_REGISTRATION_FRAME_ExceptionPointers 16
|
||||
#define SEH3_REGISTRATION_FRAME_Esp 20
|
||||
#define SEH3_REGISTRATION_FRAME_Ebp 24
|
||||
#define SEH3_REGISTRATION_FRAME_Ebx 28
|
||||
#define SEH3_REGISTRATION_FRAME_Esi 32
|
||||
#define SEH3_REGISTRATION_FRAME_Edi 36
|
||||
#define SEH3_REGISTRATION_FRAME_AllocaFrame 28
|
||||
#define SEH3_REGISTRATION_FRAME_Ebx 32
|
||||
#define SEH3_REGISTRATION_FRAME_Esi 36
|
||||
#define SEH3_REGISTRATION_FRAME_Edi 40
|
||||
|
||||
#define SEH3_SCOPE_TABLE_Target 0
|
||||
#define SEH3_SCOPE_TABLE_Filter 4
|
||||
|
|
|
@ -15,11 +15,12 @@
|
|||
|
||||
/*
|
||||
* void
|
||||
* __attribute__((regparm(2)))
|
||||
* __attribute__((regparm(3)))
|
||||
* __attribute__((returns_twice))
|
||||
* _SEH3$_RegisterFrame[WithNonVolatiles](
|
||||
* PSEH3$_REGISTRATION_FRAME RegistrationFrame<eax>,
|
||||
* PSEH3$_SCOPE_TABLE ScopeTable<edx>);
|
||||
* PSEH3$_SCOPE_TABLE ScopeTable<edx>,
|
||||
* PVOID AllocaFrame);
|
||||
*/
|
||||
.global __SEH3$_RegisterFrameWithNonVolatiles
|
||||
__SEH3$_RegisterFrameWithNonVolatiles:
|
||||
|
@ -29,6 +30,12 @@ __SEH3$_RegisterFrameWithNonVolatiles:
|
|||
mov [eax + SEH3_REGISTRATION_FRAME_Esi], esi
|
||||
mov [eax + SEH3_REGISTRATION_FRAME_Edi], edi
|
||||
|
||||
.global __SEH3$_RegisterFrameWithStackLayout
|
||||
__SEH3$_RegisterFrameWithStackLayout:
|
||||
|
||||
/* Save the pointer to the alloca frame */
|
||||
mov [eax + SEH3_REGISTRATION_FRAME_AllocaFrame], ecx
|
||||
|
||||
.global __SEH3$_RegisterFrame
|
||||
__SEH3$_RegisterFrame:
|
||||
|
||||
|
@ -57,11 +64,12 @@ __SEH3$_RegisterFrame:
|
|||
|
||||
/*
|
||||
* void
|
||||
* __attribute__((regparm(2)))
|
||||
* __attribute__((regparm(3)))
|
||||
* __attribute__((returns_twice))
|
||||
* _SEH3$_RegisterTryLevel[WithNonVolatiles](
|
||||
* PSEH3$_REGISTRATION_FRAME RegistrationFrame<edx>,
|
||||
* PSEH3$_SCOPE_TABLE ScopeTable<eax>);
|
||||
* PSEH3$_SCOPE_TABLE ScopeTable<eax>,
|
||||
* PVOID AllocaFrame);
|
||||
*/
|
||||
.global __SEH3$_RegisterTryLevelWithNonVolatiles
|
||||
__SEH3$_RegisterTryLevelWithNonVolatiles:
|
||||
|
@ -71,6 +79,12 @@ __SEH3$_RegisterTryLevelWithNonVolatiles:
|
|||
mov [eax + SEH3_REGISTRATION_FRAME_Esi], esi
|
||||
mov [eax + SEH3_REGISTRATION_FRAME_Edi], edi
|
||||
|
||||
.global __SEH3$_RegisterTryLevelWithStackLayout
|
||||
__SEH3$_RegisterTryLevelWithStackLayout:
|
||||
|
||||
/* Save the pointer to the alloca frame */
|
||||
mov [eax + SEH3_REGISTRATION_FRAME_AllocaFrame], ecx
|
||||
|
||||
.global __SEH3$_RegisterTryLevel
|
||||
__SEH3$_RegisterTryLevel:
|
||||
|
||||
|
@ -98,3 +112,105 @@ __SEH3$_RegisterTryLevel:
|
|||
xor eax, eax
|
||||
ret
|
||||
|
||||
|
||||
.global __SEH3$_InvokeEmbeddedFilterFromRegistration
|
||||
__SEH3$_InvokeEmbeddedFilterFromRegistration:
|
||||
|
||||
/* Safe the current non-volatiles */
|
||||
push ebp
|
||||
push ebx
|
||||
push esi
|
||||
push edi
|
||||
|
||||
/* Load the non-volatiles from the registration invocation */
|
||||
mov ebx, [eax + SEH3_REGISTRATION_FRAME_Ebx]
|
||||
mov esi, [eax + SEH3_REGISTRATION_FRAME_Esi]
|
||||
mov edi, [eax + SEH3_REGISTRATION_FRAME_Edi]
|
||||
mov ebp, [eax + SEH3_REGISTRATION_FRAME_Ebp]
|
||||
|
||||
/* Get the saved stack pointer */
|
||||
mov edx, [eax + SEH3_REGISTRATION_FRAME_Esp]
|
||||
|
||||
xor eax, eax
|
||||
inc eax
|
||||
call [edx]
|
||||
|
||||
/* Restore the current non-volatiles */
|
||||
pop edi
|
||||
pop esi
|
||||
pop ebx
|
||||
pop ebp
|
||||
|
||||
ret
|
||||
|
||||
|
||||
.global __SEH3$_InvokeEmbeddedFilter
|
||||
__SEH3$_InvokeEmbeddedFilter:
|
||||
|
||||
/* Safe the current non-volatiles */
|
||||
push ebp
|
||||
push ebx
|
||||
push esi
|
||||
push edi
|
||||
|
||||
/* Load ebp from the registration invocation */
|
||||
mov ebp, [eax + SEH3_REGISTRATION_FRAME_Ebp]
|
||||
|
||||
/* Calculate the size of the temp stack frame region */
|
||||
mov ecx, [eax + SEH3_REGISTRATION_FRAME_AllocaFrame]
|
||||
sub ecx, [eax + SEH3_REGISTRATION_FRAME_Esp]
|
||||
|
||||
/* Put the return address on the stack */
|
||||
push offset __SEH3$_InvokeEmbeddedFilterReturn
|
||||
|
||||
/* Save the current stack pointer in the AllocaFrame member */
|
||||
mov [eax + SEH3_REGISTRATION_FRAME_AllocaFrame], esp
|
||||
|
||||
/* Allocate enough temp stack space on the stack */
|
||||
sub esp, ecx
|
||||
|
||||
/* Get the scope table */
|
||||
mov edx, [eax + SEH3_REGISTRATION_FRAME_ScopeTable]
|
||||
|
||||
/* Jump into the filter or finally function */
|
||||
jmp [edx + SEH3_SCOPE_TABLE_Filter]
|
||||
|
||||
/* We return to this label with a cleaned up stack */
|
||||
__SEH3$_InvokeEmbeddedFilterReturn:
|
||||
|
||||
/* Restore the current non-volatiles */
|
||||
pop edi
|
||||
pop esi
|
||||
pop ebx
|
||||
pop ebp
|
||||
|
||||
ret
|
||||
|
||||
/*
|
||||
* void
|
||||
* __fastcall
|
||||
* _SEH3$_CallRtlUnwind(
|
||||
* PSEH3$_REGISTRATION_FRAME RegistrationFrame<ecx>)
|
||||
*/
|
||||
.global @_SEH3$_CallRtlUnwind@4
|
||||
@_SEH3$_CallRtlUnwind@4:
|
||||
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
|
||||
push edi
|
||||
push esi
|
||||
push ebx
|
||||
|
||||
push 0 /* ReturnValue */
|
||||
push 0 /* ExceptionRecord */
|
||||
push 0 /* TargetIp */
|
||||
push ecx /* TargetFrame */
|
||||
call _RtlUnwind@16
|
||||
|
||||
pop ebx
|
||||
pop esi
|
||||
pop edi
|
||||
pop ebp
|
||||
ret
|
||||
|
||||
|
|
Loading…
Reference in a new issue