ReactOS  0.4.13-dev-551-gf37fb1f
pseh3.c File Reference
#include <stdarg.h>
#include <windef.h>
#include <winnt.h>
#include "pseh3.h"
#include "pseh3_asmdef.h"
Include dependency graph for pseh3.c:

Go to the source code of this file.

Macros

#define _SEH3   $_FRAME_ALL_NONVOLATILES 1
 

Functions

 C_ASSERT (SEH3_REGISTRATION_FRAME_Next==FIELD_OFFSET(SEH3 $_REGISTRATION_FRAME, Next))
 
 C_ASSERT (SEH3_REGISTRATION_FRAME_Handler==FIELD_OFFSET(SEH3 $_REGISTRATION_FRAME, Handler))
 
 C_ASSERT (SEH3_REGISTRATION_FRAME_EndOfChain==FIELD_OFFSET(SEH3 $_REGISTRATION_FRAME, EndOfChain))
 
 C_ASSERT (SEH3_REGISTRATION_FRAME_ScopeTable==FIELD_OFFSET(SEH3 $_REGISTRATION_FRAME, ScopeTable))
 
 C_ASSERT (SEH3_REGISTRATION_FRAME_ExceptionPointers==FIELD_OFFSET(SEH3 $_REGISTRATION_FRAME, ExceptionPointers))
 
 C_ASSERT (SEH3_REGISTRATION_FRAME_ExceptionCode==FIELD_OFFSET(SEH3 $_REGISTRATION_FRAME, ExceptionCode))
 
 C_ASSERT (SEH3_REGISTRATION_FRAME_Esp==FIELD_OFFSET(SEH3 $_REGISTRATION_FRAME, Esp))
 
 C_ASSERT (SEH3_REGISTRATION_FRAME_Ebp==FIELD_OFFSET(SEH3 $_REGISTRATION_FRAME, Ebp))
 
 C_ASSERT (SEH3_REGISTRATION_FRAME_AllocaFrame==FIELD_OFFSET(SEH3 $_REGISTRATION_FRAME, AllocaFrame))
 
 C_ASSERT (SEH3_REGISTRATION_FRAME_Ebx==FIELD_OFFSET(SEH3 $_REGISTRATION_FRAME, Ebx))
 
 C_ASSERT (SEH3_REGISTRATION_FRAME_Esi==FIELD_OFFSET(SEH3 $_REGISTRATION_FRAME, Esi))
 
 C_ASSERT (SEH3_REGISTRATION_FRAME_Edi==FIELD_OFFSET(SEH3 $_REGISTRATION_FRAME, Edi))
 
 C_ASSERT (SEH3_SCOPE_TABLE_Filter==FIELD_OFFSET(SEH3 $_SCOPE_TABLE, Filter))
 
 C_ASSERT (SEH3_SCOPE_TABLE_Target==FIELD_OFFSET(SEH3 $_SCOPE_TABLE, Target))
 
void __attribute__ ((regparm(1)))
 
static LONG _SEH3 $_InvokeNestedFunctionFilter (volatile SEH3 $_REGISTRATION_FRAME *RegistrationFrame, PVOID Filter)
 
static LONG _SEH3 $_GetFilterResult (PSEH3 $_REGISTRATION_FRAME Record)
 
static VOID _SEH3 $_CallFinally (PSEH3 $_REGISTRATION_FRAME Record)
 
 __attribute__ ((noreturn))
 
void __fastcall _SEH3 $_CallRtlUnwind (PSEH3 $_REGISTRATION_FRAME RegistrationFrame)
 
EXCEPTION_DISPOSITION __cdecl __attribute__ ((__target__("cld")))
 

Macro Definition Documentation

◆ _SEH3

#define _SEH3   $_FRAME_ALL_NONVOLATILES 1

Definition at line 38 of file pseh3.c.

Function Documentation

◆ $_CallFinally()

static VOID _SEH3 $_CallFinally ( PSEH3 $_REGISTRATION_FRAME  Record)
inlinestatic

Definition at line 195 of file pseh3.c.

197 {
198  _SEH3$_InvokeFilter(Record, Record->ScopeTable->Filter);
199 }
_In_ struct _KBUGCHECK_REASON_CALLBACK_RECORD * Record
Definition: ketypes.h:256
#define _SEH3
Definition: pseh3.c:38

Referenced by __attribute__().

◆ $_CallRtlUnwind()

void __fastcall _SEH3 $_CallRtlUnwind ( PSEH3 $_REGISTRATION_FRAME  RegistrationFrame)

Referenced by __attribute__().

◆ $_GetFilterResult()

static LONG _SEH3 $_GetFilterResult ( PSEH3 $_REGISTRATION_FRAME  Record)
inlinestatic

Definition at line 163 of file pseh3.c.

165 {
166  PVOID Filter = Record->ScopeTable->Filter;
167  LONG Result;
168 
169  /* Check for __finally frames */
170  if (Record->ScopeTable->Target == NULL)
171  {
173  }
174 
175  /* Check if we have a constant filter */
176  if (((ULONG)Filter & 0xFFFFFF00) == 0)
177  {
178  /* Lowest 8 bit are sign extended to give the result */
179  Result = (LONG)(CHAR)(ULONG)Filter;
180  }
181  else
182  {
183  /* Call the filter function */
184  Result = _SEH3$_InvokeFilter(Record, Filter);
185  }
186 
187  /* Normalize the result */
188  if (Result < 0) return EXCEPTION_CONTINUE_EXECUTION;
189  else if (Result > 0) return EXCEPTION_EXECUTE_HANDLER;
190  else return EXCEPTION_CONTINUE_SEARCH;
191 }
char CHAR
Definition: xmlstorage.h:175
_In_ struct _KBUGCHECK_REASON_CALLBACK_RECORD * Record
Definition: ketypes.h:256
#define EXCEPTION_CONTINUE_SEARCH
Definition: excpt.h:86
long LONG
Definition: pedump.c:60
_Must_inspect_result_ _In_opt_ PFLT_FILTER Filter
Definition: fltkernel.h:1802
#define _SEH3
Definition: pseh3.c:38
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:416
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
unsigned int ULONG
Definition: retypes.h:1
#define EXCEPTION_CONTINUE_EXECUTION
Definition: excpt.h:87

Referenced by __attribute__().

◆ $_InvokeNestedFunctionFilter()

static LONG _SEH3 $_InvokeNestedFunctionFilter ( volatile SEH3 $_REGISTRATION_FRAME RegistrationFrame,
PVOID  Filter 
)
inlinestatic

Definition at line 76 of file pseh3.c.

79 {
80  LONG FilterResult;
81 
82  asm volatile (
83  /* First call with param = 0 to get the frame layout */
84  "xorl %%ecx, %%ecx\n\t"
85  "xorl %%eax, %%eax\n\t"
86  "call *%[Filter]\n\t"
87 
88  /* The result is the frame base address that we passed in (0) plus the
89  offset to the registration record. */
90  "negl %%eax\n\t"
91  "addl %[RegistrationFrame], %%eax\n\t"
92 
93  /* Second call to get the filter result */
94  "mov $1, %%ecx\n\t"
95  "call *%[Filter]"
96  : "=a" (FilterResult)
97  : [RegistrationFrame] "m" (RegistrationFrame), [Filter] "m" (Filter)
98  : "ecx", "edx");
99 
100  return FilterResult;
101 }
long LONG
Definition: pedump.c:60
_Must_inspect_result_ _In_opt_ PFLT_FILTER Filter
Definition: fltkernel.h:1802

◆ __attribute__() [1/3]

void __attribute__ ( (regparm(1))  )

Definition at line 64 of file pseh3.c.

67 {
68  if (Frame->Handler)
69  _SEH3$_UnregisterFrame(Frame);
70  else
71  _SEH3$_UnregisterTryLevel(Frame);
72 }
#define _SEH3
Definition: pseh3.c:38

◆ __attribute__() [2/3]

__attribute__ ( (noreturn)  )

Definition at line 201 of file pseh3.c.

206 {
207  if (RegistrationFrame->ScopeTable->HandlerType == _SEH3$_CLANG_HANDLER)
208  {
209  asm volatile (
210  /* Load the registers */
211  "movl 24(%%ecx), %%esp\n\t"
212  "movl 28(%%ecx), %%ebp\n\t"
213 
214  "movl 36(%%ecx), %%ebx\n\t"
215  "movl 40(%%ecx), %%esi\n\t"
216  "movl 44(%%ecx), %%edi\n\t"
217 
218  /* Stack pointer is 4 off from the call to __SEH3$_RegisterFrame */
219  "addl $4, %%esp\n\t"
220 
221  /* Jump into the exception handler */
222  "jmp *%[Target]"
223  : :
224  "c" (RegistrationFrame),
225  "a" (RegistrationFrame->ScopeTable),
226  [Target] "m" (RegistrationFrame->ScopeTable->Target)
227  );
228  }
229  else
230  {
231  asm volatile (
232  /* Load the registers */
233  "movl 24(%%ecx), %%esp\n\t"
234  "movl 28(%%ecx), %%ebp\n\t"
235 
236  /* Stack pointer is 4 off from the call to __SEH3$_RegisterFrame */
237  "addl $4, %%esp\n\t"
238 
239  /* Jump into the exception handler */
240  "jmp *%[Target]"
241  : :
242  "c" (RegistrationFrame),
243  "a" (RegistrationFrame->ScopeTable),
244  [Target] "m" (RegistrationFrame->ScopeTable->Target)
245  );
246  }
247 
248  __builtin_unreachable();
249 }
#define _SEH3
Definition: pseh3.c:38
_Must_inspect_result_ typedef _In_ ULONG _In_ BOOLEAN Target
Definition: iotypes.h:1067

◆ __attribute__() [3/3]

EXCEPTION_DISPOSITION __cdecl __attribute__ ( (__target__("cld"))  )

Definition at line 260 of file pseh3.c.

267 {
268  PSEH3$_REGISTRATION_FRAME CurrentFrame, TargetFrame;
269  SEH3$_EXCEPTION_POINTERS ExceptionPointers;
270  LONG FilterResult;
271 
272  /* Clear the direction flag. */
273  asm volatile ("cld" : : : "memory");
274 
275  /* Save the exception pointers on the stack */
276  ExceptionPointers.ExceptionRecord = ExceptionRecord;
277  ExceptionPointers.ContextRecord = ContextRecord;
278 
279  /* Check if this is an unwind */
280  if (ExceptionRecord->ExceptionFlags & EXCEPTION_UNWINDING)
281  {
282  /* Unwind all local frames */
283  TargetFrame = EstablisherFrame->Next;
284  }
285  else
286  {
287  /* Loop all frames for this registration */
288  CurrentFrame = EstablisherFrame->EndOfChain;
289  for (;;)
290  {
291  /* Check if we have an exception handler */
292  if (CurrentFrame->ScopeTable->Target != NULL)
293  {
294  /* Set exception pointers and code for this frame */
295  CurrentFrame->ExceptionPointers = &ExceptionPointers;
296  CurrentFrame->ExceptionCode = ExceptionRecord->ExceptionCode;
297 
298  /* Get the filter result */
299  FilterResult = _SEH3$_GetFilterResult(CurrentFrame);
300 
301  /* Check, if continuuing is requested */
302  if (FilterResult == EXCEPTION_CONTINUE_EXECUTION)
303  {
305  }
306 
307  /* Check if the except handler shall be executed */
308  if (FilterResult == EXCEPTION_EXECUTE_HANDLER) break;
309  }
310 
311  /* Bail out if this is the last handler */
312  if (CurrentFrame == EstablisherFrame)
314 
315  /* Go to the next frame */
316  CurrentFrame = CurrentFrame->Next;
317  }
318 
319  /* Call RtlUnwind to unwind the frames below this one */
321 
322  /* Do a local unwind up to this frame */
323  TargetFrame = CurrentFrame;
324  }
325 
326  /* Loop frames up to the target frame */
327  for (CurrentFrame = EstablisherFrame->EndOfChain;
328  CurrentFrame != TargetFrame;
329  CurrentFrame = CurrentFrame->Next)
330  {
331  /* Manually unregister the frame */
332  _SEH3$_Unregister(CurrentFrame);
333 
334  /* Check if this is an unwind frame */
335  if (CurrentFrame->ScopeTable->Target == NULL)
336  {
337  /* Set exception pointers and code for this frame */
338  CurrentFrame->ExceptionPointers = &ExceptionPointers;
339  CurrentFrame->ExceptionCode = ExceptionRecord->ExceptionCode;
340 
341  /* Call the finally function */
342  _SEH3$_CallFinally(CurrentFrame);
343  }
344  }
345 
346  /* Check if this was an unwind */
347  if (ExceptionRecord->ExceptionFlags & EXCEPTION_UNWINDING)
348  {
350  }
351 
352  /* Unregister the frame. It will be unregistered again at the end of the
353  __except block, due to auto cleanup, but that doesn't hurt.
354  All we do is set either fs:[0] or EstablisherFrame->EndOfChain to
355  CurrentFrame->Next, which will not change it's value. */
356  _SEH3$_Unregister(CurrentFrame);
357 
358  /* Jump to the __except block (does not return) */
359  _SEH3$_JumpToTarget(CurrentFrame);
360 }
_IRQL_requires_same_ _In_ PVOID EstablisherFrame
Definition: ntbasedef.h:660
#define EXCEPTION_UNWINDING
Definition: rtltypes.h:151
static LONG _SEH3 $_GetFilterResult(PSEH3 $_REGISTRATION_FRAME Record)
Definition: pseh3.c:163
void __fastcall _SEH3 $_CallRtlUnwind(PSEH3 $_REGISTRATION_FRAME RegistrationFrame)
long LONG
Definition: pedump.c:60
#define _SEH3
Definition: pseh3.c:38
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:416
static VOID _SEH3 $_CallFinally(PSEH3 $_REGISTRATION_FRAME Record)
Definition: pseh3.c:195
_IRQL_requires_same_ _In_ PVOID _Inout_ struct _CONTEXT * ContextRecord
Definition: ntbasedef.h:661
struct _EXCEPTION_RECORD * ExceptionRecord
Definition: pseh3.h:54
#define EXCEPTION_CONTINUE_EXECUTION
Definition: excpt.h:87

◆ C_ASSERT() [1/14]

◆ C_ASSERT() [2/14]

◆ C_ASSERT() [3/14]

◆ C_ASSERT() [4/14]

◆ C_ASSERT() [5/14]

C_ASSERT ( SEH3_REGISTRATION_FRAME_ExceptionPointers  = =FIELD_OFFSET(SEH3 $_REGISTRATION_FRAME, ExceptionPointers))

◆ C_ASSERT() [6/14]

◆ C_ASSERT() [7/14]

◆ C_ASSERT() [8/14]

◆ C_ASSERT() [9/14]

◆ C_ASSERT() [10/14]

◆ C_ASSERT() [11/14]

◆ C_ASSERT() [12/14]

◆ C_ASSERT() [13/14]

◆ C_ASSERT() [14/14]