diff --git a/reactos/lib/pseh/i386/pseh3.c b/reactos/lib/pseh/i386/pseh3.c index 5d74d0ac059..2395dfe3a18 100644 --- a/reactos/lib/pseh/i386/pseh3.c +++ b/reactos/lib/pseh/i386/pseh3.c @@ -145,16 +145,17 @@ __attribute__((regparm(1))) _SEH3$_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); } - if (Frame->Handler) - _SEH3$_UnregisterFrame(Frame); - else - _SEH3$_UnregisterTryLevel(Frame); } static inline @@ -210,6 +211,10 @@ _SEH3$_JumpToTarget( "movl 24(%%ecx), %%esp\n\t" "movl 28(%%ecx), %%ebp\n\t" + "movl 36(%%ecx), %%ebx\n\t" + "movl 40(%%ecx), %%esi\n\t" + "movl 44(%%ecx), %%edi\n\t" + /* Stack pointer is 4 off from the call to __SEH3$_RegisterFrame */ "addl $4, %%esp\n\t" diff --git a/reactos/lib/pseh/i386/pseh3_i386.S b/reactos/lib/pseh/i386/pseh3_i386.S index 69f8b758f51..ad8da19180f 100644 --- a/reactos/lib/pseh/i386/pseh3_i386.S +++ b/reactos/lib/pseh/i386/pseh3_i386.S @@ -20,7 +20,7 @@ * _SEH3$_RegisterFrame[WithNonVolatiles]( * PSEH3$_REGISTRATION_FRAME RegistrationFrame, * PSEH3$_SCOPE_TABLE ScopeTable, - * PVOID AllocaFrame); + * PVOID AllocaFrame); */ .global __SEH3$_RegisterFrameWithNonVolatiles __SEH3$_RegisterFrameWithNonVolatiles: @@ -33,6 +33,7 @@ __SEH3$_RegisterFrameWithNonVolatiles: /* Safe the return address */ mov ebx, [esp] mov [eax + SEH3_REGISTRATION_FRAME_ReturnAddress], ebx + mov ebx, [eax + SEH3_REGISTRATION_FRAME_Ebx] .global __SEH3$_RegisterFrameWithStackLayout __SEH3$_RegisterFrameWithStackLayout: @@ -71,9 +72,9 @@ __SEH3$_RegisterFrame: * __attribute__((regparm(3))) * __attribute__((returns_twice)) * _SEH3$_RegisterTryLevel[WithNonVolatiles]( - * PSEH3$_REGISTRATION_FRAME RegistrationFrame, - * PSEH3$_SCOPE_TABLE ScopeTable, - * PVOID AllocaFrame); + * PSEH3$_REGISTRATION_FRAME RegistrationFrame, + * PSEH3$_SCOPE_TABLE ScopeTable, + * PVOID AllocaFrame); */ .global __SEH3$_RegisterTryLevelWithNonVolatiles __SEH3$_RegisterTryLevelWithNonVolatiles: @@ -130,6 +131,9 @@ __SEH3$_InvokeEmbeddedFilterFromRegistration: push esi push edi + /* Save the registration frame pointer */ + push eax + /* Load the non-volatiles from the registration invocation */ mov ebx, [eax + SEH3_REGISTRATION_FRAME_Ebx] mov esi, [eax + SEH3_REGISTRATION_FRAME_Esi] @@ -141,7 +145,7 @@ __SEH3$_InvokeEmbeddedFilterFromRegistration: sub ecx, [eax + SEH3_REGISTRATION_FRAME_Esp] /* Put the return address on the stack */ - push offset __SEH3$_InvokeEmbeddedFilterReturn + push offset __SEH3$_InvokeEmbeddedFilterReturnClang /* Save the current stack pointer in the AllocaFrame member */ mov [eax + SEH3_REGISTRATION_FRAME_AllocaFrame], esp @@ -157,6 +161,26 @@ __SEH3$_InvokeEmbeddedFilterFromRegistration: inc eax jmp edx + /* We return to this label with a cleaned up stack */ +__SEH3$_InvokeEmbeddedFilterReturnClang: + + /* Restore the registration frame pointer */ + pop ecx + + /* Save the non-volatiles back in the registration frame */ + mov [ecx + SEH3_REGISTRATION_FRAME_Ebx], ebx + mov [ecx + SEH3_REGISTRATION_FRAME_Esi], esi + mov [ecx + SEH3_REGISTRATION_FRAME_Edi], edi + mov [ecx + SEH3_REGISTRATION_FRAME_Ebp], ebp + + /* Restore the current non-volatiles */ + pop edi + pop esi + pop ebx + pop ebp + + ret + .global __SEH3$_InvokeEmbeddedFilter __SEH3$_InvokeEmbeddedFilter: