diff --git a/reactos/include/reactos/libs/pseh/pseh3.h b/reactos/include/reactos/libs/pseh/pseh3.h index 6fbedc248ea..76eea6589f6 100644 --- a/reactos/include/reactos/libs/pseh/pseh3.h +++ b/reactos/include/reactos/libs/pseh/pseh3.h @@ -77,6 +77,9 @@ typedef struct _SEH3$_REGISTRATION_FRAME unsigned long Esi; unsigned long Edi; #endif +#ifdef __clang__ + void *ReturnAddress; +#endif } SEH3$_REGISTRATION_FRAME ,*PSEH3$_REGISTRATION_FRAME; /* Prevent gcc from inlining functions that use SEH. */ diff --git a/reactos/lib/pseh/i386/pseh3_asmdef.h b/reactos/lib/pseh/i386/pseh3_asmdef.h index 74f7c83ff9a..0650155ee3a 100644 --- a/reactos/lib/pseh/i386/pseh3_asmdef.h +++ b/reactos/lib/pseh/i386/pseh3_asmdef.h @@ -12,6 +12,7 @@ #define SEH3_REGISTRATION_FRAME_Ebx 36 #define SEH3_REGISTRATION_FRAME_Esi 40 #define SEH3_REGISTRATION_FRAME_Edi 44 +#define SEH3_REGISTRATION_FRAME_ReturnAddress 48 #define SEH3_SCOPE_TABLE_Target 0 #define SEH3_SCOPE_TABLE_Filter 4 diff --git a/reactos/lib/pseh/i386/pseh3_i386.S b/reactos/lib/pseh/i386/pseh3_i386.S index adab89cec46..69f8b758f51 100644 --- a/reactos/lib/pseh/i386/pseh3_i386.S +++ b/reactos/lib/pseh/i386/pseh3_i386.S @@ -30,6 +30,10 @@ __SEH3$_RegisterFrameWithNonVolatiles: mov [eax + SEH3_REGISTRATION_FRAME_Esi], esi mov [eax + SEH3_REGISTRATION_FRAME_Edi], edi + /* Safe the return address */ + mov ebx, [esp] + mov [eax + SEH3_REGISTRATION_FRAME_ReturnAddress], ebx + .global __SEH3$_RegisterFrameWithStackLayout __SEH3$_RegisterFrameWithStackLayout: @@ -79,6 +83,10 @@ __SEH3$_RegisterTryLevelWithNonVolatiles: mov [eax + SEH3_REGISTRATION_FRAME_Esi], esi mov [eax + SEH3_REGISTRATION_FRAME_Edi], edi + /* Safe the return address */ + mov ebx, [esp] + mov [eax + SEH3_REGISTRATION_FRAME_ReturnAddress], ebx + .global __SEH3$_RegisterTryLevelWithStackLayout __SEH3$_RegisterTryLevelWithStackLayout: @@ -128,22 +136,26 @@ __SEH3$_InvokeEmbeddedFilterFromRegistration: mov edi, [eax + SEH3_REGISTRATION_FRAME_Edi] mov ebp, [eax + SEH3_REGISTRATION_FRAME_Ebp] - jmp __SEH3$_InvokeEmbeddedFilter2 + /* Calculate the size of the temp stack frame region */ + mov ecx, [eax + SEH3_REGISTRATION_FRAME_AllocaFrame] + sub ecx, [eax + SEH3_REGISTRATION_FRAME_Esp] - /* Get the saved stack pointer */ - mov edx, [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 return address that was saved when registering the frame */ + mov edx, [eax + SEH3_REGISTRATION_FRAME_ReturnAddress] + + /* Jump into the filter or finally function */ xor eax, eax inc eax - call [edx] - - /* Restore the current non-volatiles */ - pop edi - pop esi - pop ebx - pop ebp - - ret + jmp edx .global __SEH3$_InvokeEmbeddedFilter @@ -157,7 +169,7 @@ __SEH3$_InvokeEmbeddedFilter: /* Load ebp from the registration invocation */ mov ebp, [eax + SEH3_REGISTRATION_FRAME_Ebp] -__SEH3$_InvokeEmbeddedFilter2: + /* Calculate the size of the temp stack frame region */ mov ecx, [eax + SEH3_REGISTRATION_FRAME_AllocaFrame] sub ecx, [eax + SEH3_REGISTRATION_FRAME_Esp]