Author: tkreuzer Date: Sat Mar 8 11:51:51 2014 New Revision: 62458
URL: http://svn.reactos.org/svn/reactos?rev=62458&view=rev Log: [PSEH3] Enforce the use of a frame pointer in all functions that use PSEH, even when -fomit-frame-pointer option was specified. This way we don't need to explicitly tell PSEH with a global define, whether we have a frame pointer or not, which would also probably not have worked together with alloca().
Modified: trunk/reactos/include/reactos/libs/pseh/pseh3.h
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] Sat Mar 8 11:51:51 2014 @@ -93,6 +93,9 @@
/* CLANG specific definitions! */ #ifdef __clang__ + +/* CLANG thinks it is smart and optimizes the alloca away if it is 0 and with it the use of a frame register */ +#define _SEH3$_EnforceFramePointer() asm volatile ("#\n" : : "m"(*(char*)__builtin_alloca(4)) : "%esp", "memory")
/* CLANG doesn't have asm goto! */ #define _SEH3$_ASM_GOTO(_Label, ...) @@ -137,34 +140,30 @@
#else /* !__clang__ */
+/* This will make GCC use ebp, even if it was disabled by -fomit-frame-pointer */ +#define _SEH3$_EnforceFramePointer() asm volatile ("#\n" : : "m"(*(char*)__builtin_alloca(0)) : "%esp", "memory") + #define _SEH3$_ASM_GOTO(_Label, ...) asm goto ("#\n" : : : "memory", ## __VA_ARGS__ : _Label)
/* This is an asm wrapper around _SEH3$_RegisterFrame */ #define _SEH3$_RegisterFrame_(_TrylevelFrame, _DataTable) \ - asm goto ("leal %1, %%edx\n" \ + asm goto ("leal %0, %%eax\n" \ + "leal %1, %%edx\n" \ "call __SEH3$_RegisterFrame\n" \ : \ - : "a" (_TrylevelFrame), "m" (*(_DataTable)) \ + : "m" (*(_TrylevelFrame)), "m" (*(_DataTable)) \ : "ecx", "edx", "memory" \ : _SEH3$_l_HandlerTarget)
/* This is an asm wrapper around _SEH3$_RegisterTryLevel */ #define _SEH3$_RegisterTryLevel_(_TrylevelFrame, _DataTable) \ - asm goto ("leal %1, %%edx\n" \ + asm goto ("leal %0, %%eax\n" \ + "leal %1, %%edx\n" \ "call __SEH3$_RegisterTryLevel\n" \ : \ - : "a" (_TrylevelFrame), "m" (*(_DataTable)) \ + : "m" (*(_TrylevelFrame)), "m" (*(_DataTable)) \ : "ecx", "edx", "memory" \ : _SEH3$_l_HandlerTarget) - -/* Define the registers that get clobbered, when reaching the __except block. - We specify ebp on optimized builds without frame pointer, since it will be - used by GCC as a general purpose register then. */ -#if defined(__OPTIMIZE__) && defined(_ALLOW_OMIT_FRAME_POINTER) -#define _SEH3$_CLOBBER_ON_EXCEPTION "ebp", "ebx", "ecx", "edx", "esi", "edi", "flags", "memory" -#else -#define _SEH3$_CLOBBER_ON_EXCEPTION "ebx", "ecx", "edx", "esi", "edi", "flags", "memory" -#endif
/* This construct scares GCC so much, that it will stop moving code around into places that are never executed. */ @@ -174,7 +173,7 @@ _SEH3$_ASM_GOTO(_SEH3$_l_HandlerTarget); \ _SEH3$_ASM_GOTO(_SEH3$_l_OnException); \ asm volatile ("#" : "=a"(plabel) : "p"(&&_SEH3$_l_BeforeTry), "p"(&&_SEH3$_l_HandlerTarget), "p"(&&_SEH3$_l_OnException) \ - : _SEH3$_CLOBBER_ON_EXCEPTION ); \ + : "ebx", "ecx", "edx", "esi", "edi", "flags", "memory" ); \ goto _SEH3$_l_OnException;
#endif /* __clang__ */ @@ -317,11 +316,12 @@ _SEH3$_DEFINE_DUMMY_FINALLY(_SEH3$_FinallyFunction) \ \ /* Allow intrinsics for __except to be used */ \ - _SEH3$_DECLARE_EXCEPT_INTRINSICS() \ + _SEH3$_DECLARE_EXCEPT_INTRINSICS(); \ \ goto _SEH3$_l_DoTry; \ \ _SEH3$_l_HandlerTarget: (void)0; \ + _SEH3$_EnforceFramePointer(); \ \ if (1) \ { \ @@ -355,6 +355,7 @@ goto _SEH3$_l_DoTry; \ \ _SEH3$_l_HandlerTarget: (void)0; \ + _SEH3$_EnforceFramePointer(); \ \ _SEH3$_FINALLY_FUNC_OPEN(_SEH3$_FinallyFunction) \ /* This construct makes sure that the finally function returns */ \