ReactOS 0.4.15-dev-7953-g1f49173
ehandler.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS CRT library
3 * LICENSE: MIT (https://spdx.org/licenses/MIT)
4 * PURPOSE: C specific exception/unwind handler for AMD64
5 * COPYRIGHT: Copyright 2018-2021 Timo Kreuzer <timo.kreuzer@reactos.org>
6*/
7
8#include <precomp.h>
9#include <winnt.h>
10
11
16 struct _EXCEPTION_RECORD *ExceptionRecord,
17 void *EstablisherFrame,
18 struct _CONTEXT *ContextRecord,
20{
21 PSCOPE_TABLE ScopeTable;
22 ULONG i, BeginAddress, EndAddress, Handler;
23 ULONG64 ImageBase, JumpTarget, IpOffset, TargetIpOffset;
24 EXCEPTION_POINTERS ExceptionPointers;
25 PTERMINATION_HANDLER TerminationHandler;
26 PEXCEPTION_FILTER ExceptionFilter;
27 LONG FilterResult;
28
29 /* Set up the EXCEPTION_POINTERS */
30 ExceptionPointers.ExceptionRecord = ExceptionRecord;
31 ExceptionPointers.ContextRecord = ContextRecord;
32
33 /* Get the image base */
34 ImageBase = (ULONG64)DispatcherContext->ImageBase;
35
36 /* Get the image base relative instruction pointers */
37 IpOffset = DispatcherContext->ControlPc - ImageBase;
38 TargetIpOffset = DispatcherContext->TargetIp - ImageBase;
39
40 /* Get the scope table and current index */
41 ScopeTable = (PSCOPE_TABLE)DispatcherContext->HandlerData;
42
43 /* Loop while we have scope table entries */
44 while (DispatcherContext->ScopeIndex < ScopeTable->Count)
45 {
46 /* Use i as index and update the dispatcher context */
47 i = DispatcherContext->ScopeIndex++;
48
49 /* Get the start and end of the scrope */
50 BeginAddress = ScopeTable->ScopeRecord[i].BeginAddress;
51 EndAddress = ScopeTable->ScopeRecord[i].EndAddress;
52
53 /* Skip this scope if we are not within the bounds */
54 if ((IpOffset < BeginAddress) || (IpOffset >= EndAddress))
55 {
56 continue;
57 }
58
59 /* Check if this is an unwind */
60 if (ExceptionRecord->ExceptionFlags & EXCEPTION_UNWIND)
61 {
62 /* Check if this is a target unwind */
63 if (ExceptionRecord->ExceptionFlags & EXCEPTION_TARGET_UNWIND)
64 {
65 /* Check if the target is within the scope itself */
66 if ((TargetIpOffset >= BeginAddress) &&
67 (TargetIpOffset < EndAddress))
68 {
70 }
71 }
72
73 /* Check if this is a termination handler / finally function */
74 if (ScopeTable->ScopeRecord[i].JumpTarget == 0)
75 {
76 /* Call the handler */
77 Handler = ScopeTable->ScopeRecord[i].HandlerAddress;
78 TerminationHandler = (PTERMINATION_HANDLER)(ImageBase + Handler);
79 TerminationHandler(TRUE, EstablisherFrame);
80 }
81 else if (ScopeTable->ScopeRecord[i].JumpTarget == TargetIpOffset)
82 {
84 }
85 }
86 else
87 {
88 /* We are only unterested in exception handlers */
89 if (ScopeTable->ScopeRecord[i].JumpTarget == 0)
90 {
91 continue;
92 }
93
94 /* This is an exception filter, get the handler address */
95 Handler = ScopeTable->ScopeRecord[i].HandlerAddress;
96
97 /* Check for hardcoded EXCEPTION_EXECUTE_HANDLER */
99 {
100 /* This is our result */
101 FilterResult = EXCEPTION_EXECUTE_HANDLER;
102 }
103 else
104 {
105 /* Otherwise we need to call the handler */
106 ExceptionFilter = (PEXCEPTION_FILTER)(ImageBase + Handler);
107 FilterResult = ExceptionFilter(&ExceptionPointers, EstablisherFrame);
108 }
109
110 if (FilterResult < 0 /* EXCEPTION_CONTINUE_EXECUTION */)
111 {
113 }
114
115 if (FilterResult > 0 /* EXCEPTION_EXECUTE_HANDLER */)
116 {
117 JumpTarget = (ImageBase + ScopeTable->ScopeRecord[i].JumpTarget);
118
119 /* Unwind to the target address (This does not return) */
121 (PVOID)JumpTarget,
122 ExceptionRecord,
123 UlongToPtr(ExceptionRecord->ExceptionCode),
124 DispatcherContext->ContextRecord,
125 DispatcherContext->HistoryTable);
126
127 /* Should not get here */
128 __debugbreak();
129 }
130 }
131 }
132
133 /* Reached the end of the scope table */
135}
136
137void __cdecl _local_unwind(void* frame, void* target)
138{
139 RtlUnwind(frame, target, NULL, 0);
140}
#define __cdecl
Definition: accygwin.h:79
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn UINT32 *TableIdx UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER Handler
Definition: acpixf.h:672
void __cdecl _local_unwind(void *frame, void *target)
Definition: ehandler.c:137
_CRTIMP EXCEPTION_DISPOSITION __cdecl __C_specific_handler(struct _EXCEPTION_RECORD *ExceptionRecord, void *EstablisherFrame, struct _CONTEXT *ContextRecord, struct _DISPATCHER_CONTEXT *DispatcherContext)
Definition: ehandler.c:15
#define _CRTIMP
Definition: crtdefs.h:72
LONG ExceptionFilter(IN PEXCEPTION_POINTERS ExceptionInfo, ULONG ExceptionCode)
Definition: delayimp.cpp:307
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
@ ExceptionContinueSearch
Definition: compat.h:91
@ ExceptionContinueExecution
Definition: compat.h:90
enum _EXCEPTION_DISPOSITION EXCEPTION_DISPOSITION
#define UlongToPtr(u)
Definition: config.h:106
GLenum target
Definition: glext.h:7315
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
void __cdecl __debugbreak(void)
Definition: intrin_ppc.h:698
unsigned __int64 ULONG64
Definition: imports.h:198
NTSYSAPI VOID NTAPI RtlUnwind(_In_opt_ PVOID TargetFrame, _In_opt_ PVOID TargetIp, _In_opt_ PEXCEPTION_RECORD ExceptionRecord, _In_ PVOID ReturnValue)
Definition: unwind.c:912
_IRQL_requires_same_ _In_ PVOID EstablisherFrame
Definition: ntbasedef.h:653
_IRQL_requires_same_ _In_ PVOID _Inout_ struct _CONTEXT * ContextRecord
Definition: ntbasedef.h:654
_IRQL_requires_same_ _In_ PVOID _Inout_ struct _CONTEXT _In_ PVOID DispatcherContext
Definition: ntbasedef.h:655
long LONG
Definition: pedump.c:60
int const SEH3$_SCOPE_TABLE * ScopeTable
Definition: pseh3.h:127
PEXCEPTION_RECORD ExceptionRecord
Definition: rtltypes.h:200
PCONTEXT ContextRecord
Definition: rtltypes.h:201
DWORD ExceptionCode
Definition: compat.h:208
DWORD ExceptionFlags
Definition: compat.h:209
uint32_t ULONG
Definition: typedefs.h:59
VOID NTAPI RtlUnwindEx(_In_opt_ PVOID TargetFrame, _In_opt_ PVOID TargetIp, _In_opt_ PEXCEPTION_RECORD ExceptionRecord, _In_ PVOID ReturnValue, _In_ PCONTEXT ContextRecord, _In_opt_ struct _UNWIND_HISTORY_TABLE *HistoryTable)
Definition: unwind.c:869
#define EXCEPTION_TARGET_UNWIND
Definition: rtltypes.h:159
#define EXCEPTION_UNWIND
Definition: rtltypes.h:161