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/p... ============================================================================== --- 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=6... ============================================================================== --- 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
-