mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 23:42:57 +00:00
* Sync up to trunk HEAD (r62502).
svn path=/branches/shell-experiments/; revision=62503
This commit is contained in:
commit
f4388e723d
442 changed files with 16244 additions and 5506 deletions
|
@ -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 (;;)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue