Author: tkreuzer
Date: Sun Sep 7 21:40:07 2014
New Revision: 64078
URL: http://svn.reactos.org/svn/reactos?rev=64078&view=rev
Log:
[PSEH]
- On clang builds we need to do the return twice trick, since we don't have asm goto, which would allow us to specify labels in the code where we can branch to on an exception. So we return back to from where we called the registration function and decide how to proceed from there nasedon the return value. For this we need to save the return address in the registration record and use it in __SEH3$_InvokeEmbeddedFilterFromRegistration
Modified:
trunk/reactos/include/reactos/libs/pseh/pseh3.h
trunk/reactos/lib/pseh/i386/pseh3_asmdef.h
trunk/reactos/lib/pseh/i386/pseh3_i386.S
Modified: trunk/reactos/include/reactos/libs/pseh/pseh3.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/libs/pseh/…
==============================================================================
--- trunk/reactos/include/reactos/libs/pseh/pseh3.h [iso-8859-1] (original)
+++ trunk/reactos/include/reactos/libs/pseh/pseh3.h [iso-8859-1] Sun Sep 7 21:40:07 2014
@@ -76,6 +76,9 @@
unsigned long Ebx;
unsigned long Esi;
unsigned long Edi;
+#endif
+#ifdef __clang__
+ void *ReturnAddress;
#endif
} SEH3$_REGISTRATION_FRAME ,*PSEH3$_REGISTRATION_FRAME;
Modified: trunk/reactos/lib/pseh/i386/pseh3_asmdef.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/pseh/i386/pseh3_asmdef…
==============================================================================
--- trunk/reactos/lib/pseh/i386/pseh3_asmdef.h [iso-8859-1] (original)
+++ trunk/reactos/lib/pseh/i386/pseh3_asmdef.h [iso-8859-1] Sun Sep 7 21:40:07 2014
@@ -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
Modified: trunk/reactos/lib/pseh/i386/pseh3_i386.S
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/pseh/i386/pseh3_i386.S…
==============================================================================
--- trunk/reactos/lib/pseh/i386/pseh3_i386.S [iso-8859-1] (original)
+++ trunk/reactos/lib/pseh/i386/pseh3_i386.S [iso-8859-1] Sun Sep 7 21:40:07 2014
@@ -30,6 +30,10 @@
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 @@
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,14 +136,61 @@
mov edi, [eax + SEH3_REGISTRATION_FRAME_Edi]
mov ebp, [eax + SEH3_REGISTRATION_FRAME_Ebp]
- jmp __SEH3$_InvokeEmbeddedFilter2
-
- /* Get the saved stack pointer */
- mov edx, [eax + SEH3_REGISTRATION_FRAME_Esp]
-
+ /* 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 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]
+ jmp edx
+
+
+.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
@@ -145,49 +200,6 @@
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]
-__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]
-
- /* 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