- 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

svn path=/trunk/; revision=64078
This commit is contained in:
Timo Kreuzer 2014-09-07 21:40:07 +00:00
parent cc9ee2cf1b
commit 38d7031ac9
3 changed files with 29 additions and 13 deletions

View file

@ -77,6 +77,9 @@ typedef struct _SEH3$_REGISTRATION_FRAME
unsigned long Esi; unsigned long Esi;
unsigned long Edi; unsigned long Edi;
#endif #endif
#ifdef __clang__
void *ReturnAddress;
#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. */

View file

@ -12,6 +12,7 @@
#define SEH3_REGISTRATION_FRAME_Ebx 36 #define SEH3_REGISTRATION_FRAME_Ebx 36
#define SEH3_REGISTRATION_FRAME_Esi 40 #define SEH3_REGISTRATION_FRAME_Esi 40
#define SEH3_REGISTRATION_FRAME_Edi 44 #define SEH3_REGISTRATION_FRAME_Edi 44
#define SEH3_REGISTRATION_FRAME_ReturnAddress 48
#define SEH3_SCOPE_TABLE_Target 0 #define SEH3_SCOPE_TABLE_Target 0
#define SEH3_SCOPE_TABLE_Filter 4 #define SEH3_SCOPE_TABLE_Filter 4

View file

@ -30,6 +30,10 @@ __SEH3$_RegisterFrameWithNonVolatiles:
mov [eax + SEH3_REGISTRATION_FRAME_Esi], esi mov [eax + SEH3_REGISTRATION_FRAME_Esi], esi
mov [eax + SEH3_REGISTRATION_FRAME_Edi], edi mov [eax + SEH3_REGISTRATION_FRAME_Edi], edi
/* Safe the return address */
mov ebx, [esp]
mov [eax + SEH3_REGISTRATION_FRAME_ReturnAddress], ebx
.global __SEH3$_RegisterFrameWithStackLayout .global __SEH3$_RegisterFrameWithStackLayout
__SEH3$_RegisterFrameWithStackLayout: __SEH3$_RegisterFrameWithStackLayout:
@ -79,6 +83,10 @@ __SEH3$_RegisterTryLevelWithNonVolatiles:
mov [eax + SEH3_REGISTRATION_FRAME_Esi], esi mov [eax + SEH3_REGISTRATION_FRAME_Esi], esi
mov [eax + SEH3_REGISTRATION_FRAME_Edi], edi mov [eax + SEH3_REGISTRATION_FRAME_Edi], edi
/* Safe the return address */
mov ebx, [esp]
mov [eax + SEH3_REGISTRATION_FRAME_ReturnAddress], ebx
.global __SEH3$_RegisterTryLevelWithStackLayout .global __SEH3$_RegisterTryLevelWithStackLayout
__SEH3$_RegisterTryLevelWithStackLayout: __SEH3$_RegisterTryLevelWithStackLayout:
@ -128,22 +136,26 @@ __SEH3$_InvokeEmbeddedFilterFromRegistration:
mov edi, [eax + SEH3_REGISTRATION_FRAME_Edi] mov edi, [eax + SEH3_REGISTRATION_FRAME_Edi]
mov ebp, [eax + SEH3_REGISTRATION_FRAME_Ebp] mov ebp, [eax + SEH3_REGISTRATION_FRAME_Ebp]
jmp __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]
/* Get the saved stack pointer */ /* Put the return address on the stack */
mov edx, [eax + SEH3_REGISTRATION_FRAME_Esp] 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 xor eax, eax
inc eax inc eax
call [edx] jmp edx
/* Restore the current non-volatiles */
pop edi
pop esi
pop ebx
pop ebp
ret
.global __SEH3$_InvokeEmbeddedFilter .global __SEH3$_InvokeEmbeddedFilter
@ -157,7 +169,7 @@ __SEH3$_InvokeEmbeddedFilter:
/* Load ebp from the registration invocation */ /* Load ebp from the registration invocation */
mov ebp, [eax + SEH3_REGISTRATION_FRAME_Ebp] mov ebp, [eax + SEH3_REGISTRATION_FRAME_Ebp]
__SEH3$_InvokeEmbeddedFilter2:
/* Calculate the size of the temp stack frame region */ /* Calculate the size of the temp stack frame region */
mov ecx, [eax + SEH3_REGISTRATION_FRAME_AllocaFrame] mov ecx, [eax + SEH3_REGISTRATION_FRAME_AllocaFrame]
sub ecx, [eax + SEH3_REGISTRATION_FRAME_Esp] sub ecx, [eax + SEH3_REGISTRATION_FRAME_Esp]