mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 21:45:41 +00:00
[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) svn path=/trunk/; revision=62383
This commit is contained in:
parent
e46cb53319
commit
62dc9b0d32
4 changed files with 66 additions and 24 deletions
|
@ -12,6 +12,11 @@
|
||||||
|
|
||||||
#include "excpt.h"
|
#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
|
typedef struct _SEH3$_SCOPE_TABLE
|
||||||
{
|
{
|
||||||
void *Target;
|
void *Target;
|
||||||
|
@ -42,7 +47,11 @@ typedef struct _SEH3$_REGISTRATION_FRAME
|
||||||
/* Registers that we need to save */
|
/* Registers that we need to save */
|
||||||
unsigned long Esp;
|
unsigned long Esp;
|
||||||
unsigned long Ebp;
|
unsigned long Ebp;
|
||||||
|
#ifdef _SEH3$_FRAME_ALL_NONVOLATILES
|
||||||
|
unsigned long Ebx;
|
||||||
|
unsigned long Esi;
|
||||||
|
unsigned long Edi;
|
||||||
|
#endif
|
||||||
} SEH3$_REGISTRATION_FRAME ,*PSEH3$_REGISTRATION_FRAME;
|
} SEH3$_REGISTRATION_FRAME ,*PSEH3$_REGISTRATION_FRAME;
|
||||||
|
|
||||||
/* Prevent gcc from inlining functions that use SEH. */
|
/* Prevent gcc from inlining functions that use SEH. */
|
||||||
|
@ -95,7 +104,7 @@ void * __cdecl __attribute__((error("Can only be used inside an exception filter
|
||||||
|
|
||||||
/* This is an asm wrapper around _SEH3$_RegisterFrame */
|
/* This is an asm wrapper around _SEH3$_RegisterFrame */
|
||||||
#define _SEH3$_RegisterFrame(_TrylevelFrame, _DataTable, _Target) \
|
#define _SEH3$_RegisterFrame(_TrylevelFrame, _DataTable, _Target) \
|
||||||
asm goto ("leal %0, %%ecx\n" \
|
asm goto ("leal %0, %%edx\n" \
|
||||||
"call __SEH3$_RegisterFrame\n" \
|
"call __SEH3$_RegisterFrame\n" \
|
||||||
: \
|
: \
|
||||||
: "m" (*(_TrylevelFrame)), "a" (_DataTable) \
|
: "m" (*(_TrylevelFrame)), "a" (_DataTable) \
|
||||||
|
@ -104,7 +113,7 @@ void * __cdecl __attribute__((error("Can only be used inside an exception filter
|
||||||
|
|
||||||
/* This is an asm wrapper around _SEH3$_EnterTryLevel */
|
/* This is an asm wrapper around _SEH3$_EnterTryLevel */
|
||||||
#define _SEH3$_RegisterTryLevel(_TrylevelFrame, _DataTable, _Target) \
|
#define _SEH3$_RegisterTryLevel(_TrylevelFrame, _DataTable, _Target) \
|
||||||
asm goto ("leal %0, %%ecx\n" \
|
asm goto ("leal %0, %%edx\n" \
|
||||||
"call __SEH3$_RegisterTryLevel\n" \
|
"call __SEH3$_RegisterTryLevel\n" \
|
||||||
: \
|
: \
|
||||||
: "m" (*(_TrylevelFrame)), "a" (_DataTable) \
|
: "m" (*(_TrylevelFrame)), "a" (_DataTable) \
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
#include <windef.h>
|
#include <windef.h>
|
||||||
#include <winnt.h>
|
#include <winnt.h>
|
||||||
|
|
||||||
|
/* We need the full structure with all non-volatile */
|
||||||
|
#define _SEH3$_FRAME_ALL_NONVOLATILES 1
|
||||||
#include "pseh3.h"
|
#include "pseh3.h"
|
||||||
#include "pseh3_asmdef.h"
|
#include "pseh3_asmdef.h"
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,9 @@
|
||||||
#define SEH3_REGISTRATION_FRAME_ExceptionPointers 16
|
#define SEH3_REGISTRATION_FRAME_ExceptionPointers 16
|
||||||
#define SEH3_REGISTRATION_FRAME_Esp 20
|
#define SEH3_REGISTRATION_FRAME_Esp 20
|
||||||
#define SEH3_REGISTRATION_FRAME_Ebp 24
|
#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_Target 0
|
||||||
#define SEH3_SCOPE_TABLE_Filter 4
|
#define SEH3_SCOPE_TABLE_Filter 4
|
||||||
|
|
|
@ -11,62 +11,90 @@
|
||||||
|
|
||||||
.text
|
.text
|
||||||
|
|
||||||
|
|
||||||
.extern __SEH3$_except_handler
|
.extern __SEH3$_except_handler
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* void
|
* void
|
||||||
* _SEH3$_RegisterFrame(
|
* __attribute__((regparm(2)))
|
||||||
* PSEH_REGISTRATION_FRAME RegistrationRecord<ecx>,
|
* __attribute__((returns_twice))
|
||||||
* PSEH_DATA_TABLE DataTable<eax>);
|
* _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
|
.global __SEH3$_RegisterFrame
|
||||||
__SEH3$_RegisterFrame:
|
__SEH3$_RegisterFrame:
|
||||||
|
|
||||||
/* Save the address of the static data table */
|
/* 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 */
|
/* 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 */
|
/* 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 */
|
/* Register the frame in the TEB */
|
||||||
mov eax, dword ptr fs:[0]
|
mov eax, dword ptr fs:[0]
|
||||||
mov [ecx + SEH3_REGISTRATION_FRAME_Next], eax
|
mov [edx + SEH3_REGISTRATION_FRAME_Next], eax
|
||||||
mov dword ptr fs:[0], ecx
|
mov dword ptr fs:[0], edx
|
||||||
|
|
||||||
/* Save the registers */
|
/* Save the stack registers */
|
||||||
mov [ecx + SEH3_REGISTRATION_FRAME_Esp], esp
|
mov [edx + SEH3_REGISTRATION_FRAME_Esp], esp
|
||||||
mov [ecx + SEH3_REGISTRATION_FRAME_Ebp], ebp
|
mov [edx + SEH3_REGISTRATION_FRAME_Ebp], ebp
|
||||||
|
|
||||||
|
/* Set eax to 0 to indicate 1st return */
|
||||||
|
xor eax, eax
|
||||||
ret
|
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
|
.global __SEH3$_RegisterTryLevel
|
||||||
__SEH3$_RegisterTryLevel:
|
__SEH3$_RegisterTryLevel:
|
||||||
|
|
||||||
/* Save the address of the static data table */
|
/* 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 */
|
/* 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 */
|
/* Get the current registered frame */
|
||||||
mov eax, dword ptr fs:[0]
|
mov eax, dword ptr fs:[0]
|
||||||
|
|
||||||
/* Get the current end of the chain and set this as Next */
|
/* Get the current end of the chain and set this as Next */
|
||||||
mov edx, [eax + SEH3_REGISTRATION_FRAME_EndOfChain]
|
mov ecx, [eax + SEH3_REGISTRATION_FRAME_EndOfChain]
|
||||||
mov [ecx + SEH3_REGISTRATION_FRAME_Next], edx
|
mov [edx + SEH3_REGISTRATION_FRAME_Next], ecx
|
||||||
|
|
||||||
/* Set this as the end of the internal chain */
|
/* 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 */
|
/* Save the stack registers */
|
||||||
mov [ecx + SEH3_REGISTRATION_FRAME_Esp], esp
|
mov [edx + SEH3_REGISTRATION_FRAME_Esp], esp
|
||||||
mov [ecx + SEH3_REGISTRATION_FRAME_Ebp], ebp
|
mov [edx + SEH3_REGISTRATION_FRAME_Ebp], ebp
|
||||||
|
|
||||||
|
/* Set eax to 0 to indicate 1st return */
|
||||||
|
xor eax, eax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue