ReactOS 0.4.16-dev-725-g22577ae
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 34 of file pseh3.c.

Function Documentation

◆ __attribute__() [1/3]

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

Definition at line 261 of file pseh3.c.

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

◆ __attribute__() [2/3]

__attribute__ ( (noreturn)  )

Definition at line 202 of file pseh3.c.

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

◆ __attribute__() [3/3]

void __attribute__ ( (regparm(1))  )

Definition at line 65 of file pseh3.c.

68{
69 if (Frame->Handler)
70 _SEH3$_UnregisterFrame(Frame);
71 else
72 _SEH3$_UnregisterTryLevel(Frame);
73}

◆ _SEH3$_CallFinally()

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

Definition at line 196 of file pseh3.c.

198{
199 _SEH3$_InvokeFilter(Record, Record->ScopeTable->Filter);
200}
_In_ struct _KBUGCHECK_REASON_CALLBACK_RECORD * Record
Definition: ketypes.h:268

Referenced by __attribute__().

◆ _SEH3$_CallRtlUnwind()

void __fastcall _SEH3$_CallRtlUnwind ( PSEH3$_REGISTRATION_FRAME  RegistrationFrame)

Referenced by __attribute__().

◆ _SEH3$_GetFilterResult()

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

Definition at line 164 of file pseh3.c.

166{
167 PVOID Filter = Record->ScopeTable->Filter;
168 LONG Result;
169
170 /* Check for __finally frames */
171 if (Record->ScopeTable->Target == NULL)
172 {
174 }
175
176 /* Check if we have a constant filter */
177 if (((ULONG)Filter & 0xFFFFFF00) == 0)
178 {
179 /* Lowest 8 bit are sign extended to give the result */
181 }
182 else
183 {
184 /* Call the filter function */
185 Result = _SEH3$_InvokeFilter(Record, Filter);
186 }
187
188 /* Normalize the result */
189 if (Result < 0) return EXCEPTION_CONTINUE_EXECUTION;
190 else if (Result > 0) return EXCEPTION_EXECUTE_HANDLER;
191 else return EXCEPTION_CONTINUE_SEARCH;
192}
_Must_inspect_result_ _In_opt_ PFLT_FILTER Filter
Definition: fltkernel.h:1801
#define EXCEPTION_CONTINUE_SEARCH
Definition: excpt.h:91
uint32_t ULONG
Definition: typedefs.h:59
_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:409
char CHAR
Definition: xmlstorage.h:175

Referenced by __attribute__().

◆ _SEH3$_InvokeNestedFunctionFilter()

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

Definition at line 77 of file pseh3.c.

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

◆ C_ASSERT() [1/14]

◆ C_ASSERT() [2/14]

◆ C_ASSERT() [3/14]

◆ C_ASSERT() [4/14]

◆ C_ASSERT() [5/14]

◆ 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]