* Sync up to trunk HEAD (r62502).

svn path=/branches/shell-experiments/; revision=62503
This commit is contained in:
Amine Khaldi 2014-03-15 14:56:08 +00:00
commit f4388e723d
442 changed files with 16244 additions and 5506 deletions

View file

@ -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"
@ -48,8 +50,9 @@ C_ASSERT(SEH3_REGISTRATION_FRAME_Ebp == FIELD_OFFSET(SEH3$_REGISTRATION_FRAME, E
C_ASSERT(SEH3_SCOPE_TABLE_Filter == FIELD_OFFSET(SEH3$_SCOPE_TABLE, Filter));
C_ASSERT(SEH3_SCOPE_TABLE_Target == FIELD_OFFSET(SEH3$_SCOPE_TABLE, Target));
static inline
void _SEH3$_Unregister(
void
__attribute__((regparm(1)))
_SEH3$_Unregister(
volatile SEH3$_REGISTRATION_FRAME *Frame)
{
if (Frame->Handler)
@ -60,8 +63,8 @@ void _SEH3$_Unregister(
static inline
LONG
_SEH3$_InvokeFilter(
PVOID Record,
_SEH3$_InvokeNestedFunctionFilter(
PSEH3$_REGISTRATION_FRAME RegistrationFrame,
PVOID Filter)
{
LONG FilterResult;
@ -75,18 +78,58 @@ _SEH3$_InvokeFilter(
/* The result is the frame base address that we passed in (0) plus the
offset to the registration record. */
"negl %%eax\n\t"
"addl %[Record], %%eax\n\t"
"addl %[RegistrationFrame], %%eax\n\t"
/* Second call to get the filter result */
"mov $1, %%ecx\n\t"
"call *%[Filter]\n\t"
: "=a"(FilterResult)
: [Record] "m" (Record), [Filter] "m" (Filter)
: [RegistrationFrame] "m" (RegistrationFrame), [Filter] "m" (Filter)
: "ecx", "edx");
return FilterResult;
}
long
__attribute__((regparm(1)))
_SEH3$_InvokeEmbeddedFilter(
PSEH3$_REGISTRATION_FRAME RegistrationFrame);
long
__attribute__((regparm(1)))
_SEH3$_InvokeEmbeddedFilterFromRegistration(
PSEH3$_REGISTRATION_FRAME RegistrationFrame);
static inline
LONG
_SEH3$_InvokeFilter(
PSEH3$_REGISTRATION_FRAME RegistrationFrame,
PVOID Filter)
{
LONG FilterResult;
if (RegistrationFrame->ScopeTable->HandlerType == _SEH3$_NESTED_HANDLER)
{
return _SEH3$_InvokeNestedFunctionFilter(RegistrationFrame, Filter);
}
else if (RegistrationFrame->ScopeTable->HandlerType == _SEH3$_CPP_HANDLER)
{
/* Call the embedded filter function */
return _SEH3$_InvokeEmbeddedFilter(RegistrationFrame);
}
else if (RegistrationFrame->ScopeTable->HandlerType == _SEH3$_CLANG_HANDLER)
{
return _SEH3$_InvokeEmbeddedFilterFromRegistration(RegistrationFrame);
}
else
{
/* Should not happen! Skip this handler */
FilterResult = EXCEPTION_CONTINUE_SEARCH;
}
return FilterResult;
}
static inline
LONG
_SEH3$_GetFilterResult(
@ -133,45 +176,51 @@ void
_SEH3$_JumpToTarget(
PSEH3$_REGISTRATION_FRAME RegistrationFrame)
{
asm volatile (
/* Load the registers */
"movl 20(%%ecx), %%esp\n"
"movl 24(%%ecx), %%ebp\n"
if (RegistrationFrame->ScopeTable->HandlerType == _SEH3$_CLANG_HANDLER)
{
asm volatile (
/* Load the registers */
"movl 20(%%ecx), %%esp\n"
"movl 24(%%ecx), %%ebp\n"
/* Stack pointer is 4 off from the call to __SEH3$_RegisterFrame */
"addl $4, %%esp\n"
/* Stack pointer is 4 off from the call to __SEH3$_RegisterFrame */
"addl $4, %%esp\n"
/* Jump into the exception handler */
"jmp *%[Target]\n"
: :
"c" (RegistrationFrame),
"a" (RegistrationFrame->ScopeTable),
[Target] "m" (RegistrationFrame->ScopeTable->Target)
);
/* Jump into the exception handler */
"jmp *%[Target]\n"
: :
"c" (RegistrationFrame),
"a" (RegistrationFrame->ScopeTable),
[Target] "m" (RegistrationFrame->ScopeTable->Target)
);
}
else
{
asm volatile (
/* Load the registers */
"movl 20(%%ecx), %%esp\n"
"movl 24(%%ecx), %%ebp\n"
/* Stack pointer is 4 off from the call to __SEH3$_RegisterFrame */
"addl $4, %%esp\n"
/* Jump into the exception handler */
"jmp *%[Target]\n"
: :
"c" (RegistrationFrame),
"a" (RegistrationFrame->ScopeTable),
[Target] "m" (RegistrationFrame->ScopeTable->Target)
);
}
__builtin_unreachable();
}
static inline
void
__fastcall
_SEH3$_CallRtlUnwind(
PSEH3$_REGISTRATION_FRAME RegistrationFrame)
{
LONG ClobberedEax;
PSEH3$_REGISTRATION_FRAME RegistrationFrame);
asm volatile(
"push %%ebp\n"
"push $0\n"
"push $0\n"
"push $0\n"
"push %[TargetFrame]\n"
"call _RtlUnwind@16\n"
"pop %%ebp\n"
: "=a" (ClobberedEax)
: [TargetFrame] "a" (RegistrationFrame)
: "ebx", "ecx", "edx", "esi",
"edi", "flags", "memory");
}
EXCEPTION_DISPOSITION
__cdecl
@ -189,6 +238,10 @@ _SEH3$_except_handler(
/* Clear the direction flag. */
asm volatile ("cld\n" : : : "memory");
/* Save the exception pointers on the stack */
ExceptionPointers.ExceptionRecord = ExceptionRecord;
ExceptionPointers.ContextRecord = ContextRecord;
/* Check if this is an unwind */
if (ExceptionRecord->ExceptionFlags & EXCEPTION_UNWINDING)
{
@ -197,10 +250,6 @@ _SEH3$_except_handler(
}
else
{
/* Save the exception pointers on the stack */
ExceptionPointers.ExceptionRecord = ExceptionRecord;
ExceptionPointers.ContextRecord = ContextRecord;
/* Loop all frames for this registration */
CurrentFrame = EstablisherFrame->EndOfChain;
for (;;)

View file

@ -7,6 +7,10 @@
#define SEH3_REGISTRATION_FRAME_ExceptionPointers 16
#define SEH3_REGISTRATION_FRAME_Esp 20
#define SEH3_REGISTRATION_FRAME_Ebp 24
#define SEH3_REGISTRATION_FRAME_AllocaFrame 28
#define SEH3_REGISTRATION_FRAME_Ebx 32
#define SEH3_REGISTRATION_FRAME_Esi 36
#define SEH3_REGISTRATION_FRAME_Edi 40
#define SEH3_SCOPE_TABLE_Target 0
#define SEH3_SCOPE_TABLE_Filter 4

View file

@ -11,62 +11,206 @@
.text
.extern __SEH3$_except_handler
/*
* void
* _SEH3$_RegisterFrame(
* PSEH_REGISTRATION_FRAME RegistrationRecord<ecx>,
* PSEH_DATA_TABLE DataTable<eax>);
* __attribute__((regparm(3)))
* __attribute__((returns_twice))
* _SEH3$_RegisterFrame[WithNonVolatiles](
* PSEH3$_REGISTRATION_FRAME RegistrationFrame<eax>,
* PSEH3$_SCOPE_TABLE ScopeTable<edx>,
* PVOID AllocaFrame);
*/
.global __SEH3$_RegisterFrameWithNonVolatiles
__SEH3$_RegisterFrameWithNonVolatiles:
/* Save non-volatiles in the registration frame */
mov [eax + SEH3_REGISTRATION_FRAME_Ebx], ebx
mov [eax + SEH3_REGISTRATION_FRAME_Esi], esi
mov [eax + SEH3_REGISTRATION_FRAME_Edi], edi
.global __SEH3$_RegisterFrameWithStackLayout
__SEH3$_RegisterFrameWithStackLayout:
/* Save the pointer to the alloca frame */
mov [eax + SEH3_REGISTRATION_FRAME_AllocaFrame], ecx
.global __SEH3$_RegisterFrame
__SEH3$_RegisterFrame:
/* Save the address of the static data table */
mov [ecx + SEH3_REGISTRATION_FRAME_ScopeTable], eax
mov [eax + SEH3_REGISTRATION_FRAME_ScopeTable], edx
/* Set the handler address */
mov dword ptr [ecx + SEH3_REGISTRATION_FRAME_Handler], offset __SEH3$_except_handler
mov dword ptr [eax + 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 [eax + SEH3_REGISTRATION_FRAME_EndOfChain], eax
/* 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, dword ptr fs:[0]
mov [eax + SEH3_REGISTRATION_FRAME_Next], edx
mov dword ptr fs:[0], eax
/* Save the registers */
mov [ecx + SEH3_REGISTRATION_FRAME_Esp], esp
mov [ecx + SEH3_REGISTRATION_FRAME_Ebp], ebp
/* Save the stack registers */
mov [eax + SEH3_REGISTRATION_FRAME_Esp], esp
mov [eax + SEH3_REGISTRATION_FRAME_Ebp], ebp
/* Set eax to 0 to indicate 1st return */
xor eax, eax
ret
/*
* void
* __attribute__((regparm(3)))
* __attribute__((returns_twice))
* _SEH3$_RegisterTryLevel[WithNonVolatiles](
* PSEH3$_REGISTRATION_FRAME RegistrationFrame<edx>,
* PSEH3$_SCOPE_TABLE ScopeTable<eax>,
* PVOID AllocaFrame);
*/
.global __SEH3$_RegisterTryLevelWithNonVolatiles
__SEH3$_RegisterTryLevelWithNonVolatiles:
/* Save non-volatiles in the registration frame */
mov [eax + SEH3_REGISTRATION_FRAME_Ebx], ebx
mov [eax + SEH3_REGISTRATION_FRAME_Esi], esi
mov [eax + SEH3_REGISTRATION_FRAME_Edi], edi
.global __SEH3$_RegisterTryLevelWithStackLayout
__SEH3$_RegisterTryLevelWithStackLayout:
/* Save the pointer to the alloca frame */
mov [eax + SEH3_REGISTRATION_FRAME_AllocaFrame], ecx
.global __SEH3$_RegisterTryLevel
__SEH3$_RegisterTryLevel:
/* Save the address of the static data table */
mov [ecx + SEH3_REGISTRATION_FRAME_ScopeTable], eax
mov [eax + SEH3_REGISTRATION_FRAME_ScopeTable], edx
/* Set the handler address to NULL as identification */
and dword ptr [ecx + SEH3_REGISTRATION_FRAME_Handler], 0
and dword ptr [eax + SEH3_REGISTRATION_FRAME_Handler], 0
/* Get the current registered frame */
mov eax, dword ptr fs:[0]
mov edx, 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, [edx + SEH3_REGISTRATION_FRAME_EndOfChain]
mov [eax + 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 [edx + SEH3_REGISTRATION_FRAME_EndOfChain], eax
/* Save the registers */
mov [ecx + SEH3_REGISTRATION_FRAME_Esp], esp
mov [ecx + SEH3_REGISTRATION_FRAME_Ebp], ebp
/* Save the stack registers */
mov [eax + SEH3_REGISTRATION_FRAME_Esp], esp
mov [eax + SEH3_REGISTRATION_FRAME_Ebp], ebp
/* Set eax to 0 to indicate 1st return */
xor eax, eax
ret
.global __SEH3$_InvokeEmbeddedFilterFromRegistration
__SEH3$_InvokeEmbeddedFilterFromRegistration:
/* Safe the current non-volatiles */
push ebp
push ebx
push esi
push edi
/* Load the non-volatiles from the registration invocation */
mov ebx, [eax + SEH3_REGISTRATION_FRAME_Ebx]
mov esi, [eax + SEH3_REGISTRATION_FRAME_Esi]
mov edi, [eax + SEH3_REGISTRATION_FRAME_Edi]
mov ebp, [eax + SEH3_REGISTRATION_FRAME_Ebp]
/* Get the saved stack pointer */
mov edx, [eax + SEH3_REGISTRATION_FRAME_Esp]
xor eax, eax
inc eax
call [edx]
/* Restore the current non-volatiles */
pop edi
pop esi
pop ebx
pop ebp
ret
.global __SEH3$_InvokeEmbeddedFilter
__SEH3$_InvokeEmbeddedFilter:
/* Safe the current non-volatiles */
push ebp
push ebx
push esi
push edi
/* Load ebp from the registration invocation */
mov ebp, [eax + SEH3_REGISTRATION_FRAME_Ebp]
/* Calculate the size of the temp stack frame region */
mov ecx, [eax + SEH3_REGISTRATION_FRAME_AllocaFrame]
sub ecx, [eax + SEH3_REGISTRATION_FRAME_Esp]
/* Put the return address on the stack */
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 scope table */
mov edx, [eax + SEH3_REGISTRATION_FRAME_ScopeTable]
/* Jump into the filter or finally function */
jmp [edx + SEH3_SCOPE_TABLE_Filter]
/* We return to this label with a cleaned up stack */
__SEH3$_InvokeEmbeddedFilterReturn:
/* Restore the current non-volatiles */
pop edi
pop esi
pop ebx
pop ebp
ret
/*
* void
* __fastcall
* _SEH3$_CallRtlUnwind(
* PSEH3$_REGISTRATION_FRAME RegistrationFrame<ecx>)
*/
.global @_SEH3$_CallRtlUnwind@4
@_SEH3$_CallRtlUnwind@4:
push ebp
mov ebp, esp
push edi
push esi
push ebx
push 0 /* ReturnValue */
push 0 /* ExceptionRecord */
push 0 /* TargetIp */
push ecx /* TargetFrame */
call _RtlUnwind@16
pop ebx
pop esi
pop edi
pop ebp
ret