Author: tkreuzer
Date: Sun Mar  2 19:36:50 2014
New Revision: 62383
URL: 
http://svn.reactos.org/svn/reactos?rev=62383&view=rev
Log:
[PSEH3]
- Switch the registration asm functions from a complete custom calling convention to
regparm(2), so that it can be used in "returns_twice" based algorithm (required
by CLANG, which doesn't support "asm goto" construct)
- Add support for saving all non-volatiles in the registration frame (also required by
CLANG, since without asm goto, we cannot give the compiler the required hints to save
these registers itself)
Modified:
    trunk/reactos/include/reactos/libs/pseh/pseh3.h
    trunk/reactos/lib/pseh/i386/pseh3.c
    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 Mar  2 19:36:50
2014
@@ -12,6 +12,11 @@
 #include "excpt.h"
+/* CLANG must safe non-volatiles, because it uses a return-twice algorithm */
+#if defined(__clang__) && !defined(_SEH3$_FRAME_ALL_NONVOLATILES)
+#define _SEH3$_FRAME_ALL_NONVOLATILES 1
+#endif
+
 typedef struct _SEH3$_SCOPE_TABLE
 {
     void *Target;
@@ -42,7 +47,11 @@
     /* Registers that we need to save */
     unsigned long Esp;
     unsigned long Ebp;
-
+#ifdef _SEH3$_FRAME_ALL_NONVOLATILES
+    unsigned long Ebx;
+    unsigned long Esi;
+    unsigned long Edi;
+#endif
 } SEH3$_REGISTRATION_FRAME ,*PSEH3$_REGISTRATION_FRAME;
 /* Prevent gcc from inlining functions that use SEH. */
@@ -95,7 +104,7 @@
 /* This is an asm wrapper around _SEH3$_RegisterFrame */
 #define _SEH3$_RegisterFrame(_TrylevelFrame, _DataTable, _Target) \
-    asm goto ("leal %0, %%ecx\n" \
+    asm goto ("leal %0, %%edx\n" \
               "call __SEH3$_RegisterFrame\n" \
               : \
               : "m" (*(_TrylevelFrame)), "a" (_DataTable) \
@@ -104,7 +113,7 @@
 /* This is an asm wrapper around _SEH3$_EnterTryLevel */
 #define _SEH3$_RegisterTryLevel(_TrylevelFrame, _DataTable, _Target) \
-    asm goto ("leal %0, %%ecx\n" \
+    asm goto ("leal %0, %%edx\n" \
               "call __SEH3$_RegisterTryLevel\n" \
               : \
               : "m" (*(_TrylevelFrame)), "a" (_DataTable) \
Modified: trunk/reactos/lib/pseh/i386/pseh3.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/pseh/i386/pseh3.c?rev=…
==============================================================================
--- trunk/reactos/lib/pseh/i386/pseh3.c [iso-8859-1] (original)
+++ trunk/reactos/lib/pseh/i386/pseh3.c [iso-8859-1] Sun Mar  2 19:36:50 2014
@@ -34,6 +34,8 @@
 #include <windef.h>
 #include <winnt.h>
+/* We need the full structure with all non-volatile */
+#define _SEH3$_FRAME_ALL_NONVOLATILES 1
 #include "pseh3.h"
 #include "pseh3_asmdef.h"
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 Mar  2 19:36:50 2014
@@ -7,6 +7,9 @@
 #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_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 Mar  2 19:36:50 2014
@@ -11,62 +11,90 @@
 .text
-
 .extern __SEH3$_except_handler
 /*
  *  void
- *  _SEH3$_RegisterFrame(
- *       PSEH_REGISTRATION_FRAME RegistrationRecord<ecx>,
- *       PSEH_DATA_TABLE DataTable<eax>);
+ *  __attribute__((regparm(2)))
+ *  __attribute__((returns_twice))
+ *  _SEH3$_RegisterFrame[WithNonVolatiles](
+ *       PSEH_DATA_TABLE DataTable<eax>,
+ *       PSEH_REGISTRATION_FRAME RegistrationRecord<edx>);
  */
+.global __SEH3$_RegisterFrameWithNonVolatiles
+__SEH3$_RegisterFrameWithNonVolatiles:
+
+    /* Save non-volatiles in the registration frame */
+    mov [edx + SEH3_REGISTRATION_FRAME_Ebx], ebx
+    mov [edx + SEH3_REGISTRATION_FRAME_Esi], esi
+    mov [edx + SEH3_REGISTRATION_FRAME_Edi], edi
+
 .global __SEH3$_RegisterFrame
 __SEH3$_RegisterFrame:
     /* Save the address of the static data table */
-    mov [ecx + SEH3_REGISTRATION_FRAME_ScopeTable], eax
+    mov [edx + SEH3_REGISTRATION_FRAME_ScopeTable], eax
     /* Set the handler address */
-    mov dword ptr [ecx + SEH3_REGISTRATION_FRAME_Handler], offset __SEH3$_except_handler
+    mov dword ptr [edx + SEH3_REGISTRATION_FRAME_Handler], offset __SEH3$_except_handler
     /* Set this as the end of the internal chain */
-    mov dword ptr [ecx + SEH3_REGISTRATION_FRAME_EndOfChain], ecx
+    mov dword ptr [edx + SEH3_REGISTRATION_FRAME_EndOfChain], edx
     /* Register the frame in the TEB */
     mov eax, dword ptr fs:[0]
-    mov [ecx + SEH3_REGISTRATION_FRAME_Next], eax
-    mov dword ptr fs:[0], ecx
+    mov [edx + SEH3_REGISTRATION_FRAME_Next], eax
+    mov dword ptr fs:[0], edx
-    /* Save the registers */
-    mov [ecx + SEH3_REGISTRATION_FRAME_Esp], esp
-    mov [ecx + SEH3_REGISTRATION_FRAME_Ebp], ebp
+    /* Save the stack registers */
+    mov [edx + SEH3_REGISTRATION_FRAME_Esp], esp
+    mov [edx + SEH3_REGISTRATION_FRAME_Ebp], ebp
+    /* Set eax to 0 to indicate 1st return */
+    xor eax, eax
     ret
+
+/*
+ *  void
+ *  __attribute__((regparm(2)))
+ *  __attribute__((returns_twice))
+ *  _SEH3$_RegisterTryLevel[WithNonVolatiles](
+ *       PSEH_DATA_TABLE DataTable<eax>,
+ *       PSEH_REGISTRATION_FRAME RegistrationRecord<edx>);
+ */
+.global __SEH3$_RegisterTryLevelWithNonVolatiles
+__SEH3$_RegisterTryLevelWithNonVolatiles:
+
+    /* Save non-volatiles in the registration frame */
+    mov [edx + SEH3_REGISTRATION_FRAME_Ebx], ebx
+    mov [edx + SEH3_REGISTRATION_FRAME_Esi], esi
+    mov [edx + SEH3_REGISTRATION_FRAME_Edi], edi
 .global __SEH3$_RegisterTryLevel
 __SEH3$_RegisterTryLevel:
     /* Save the address of the static data table */
-    mov [ecx + SEH3_REGISTRATION_FRAME_ScopeTable], eax
+    mov [edx + SEH3_REGISTRATION_FRAME_ScopeTable], eax
     /* Set the handler address to NULL as identification */
-    and dword ptr [ecx + SEH3_REGISTRATION_FRAME_Handler], 0
+    and dword ptr [edx + SEH3_REGISTRATION_FRAME_Handler], 0
     /* Get the current registered frame */
     mov eax, dword ptr fs:[0]
     /* Get the current end of the chain and set this as Next */
-    mov edx, [eax + SEH3_REGISTRATION_FRAME_EndOfChain]
-    mov [ecx + SEH3_REGISTRATION_FRAME_Next], edx
+    mov ecx, [eax + SEH3_REGISTRATION_FRAME_EndOfChain]
+    mov [edx + SEH3_REGISTRATION_FRAME_Next], ecx
     /* Set this as the end of the internal chain */
-    mov dword ptr [eax + SEH3_REGISTRATION_FRAME_EndOfChain], ecx
+    mov dword ptr [eax + SEH3_REGISTRATION_FRAME_EndOfChain], edx
-    /* Save the registers */
-    mov [ecx + SEH3_REGISTRATION_FRAME_Esp], esp
-    mov [ecx + SEH3_REGISTRATION_FRAME_Ebp], ebp
+    /* Save the stack registers */
+    mov [edx + SEH3_REGISTRATION_FRAME_Esp], esp
+    mov [edx + SEH3_REGISTRATION_FRAME_Ebp], ebp
+    /* Set eax to 0 to indicate 1st return */
+    xor eax, eax
     ret
-