ReactOS  0.4.15-dev-3439-g2693a26
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 
12 _CRTIMP
14 __cdecl
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 == EXCEPTION_CONTINUE_EXECUTION)
111  {
113  }
114 
115  if (FilterResult == 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 
137 void __cdecl _local_unwind(void* frame, void* target)
138 {
139  RtlUnwind(frame, target, NULL, 0);
140 }
int const SEH3 $_SCOPE_TABLE * ScopeTable
Definition: pseh3.h:127
_IRQL_requires_same_ _In_ PVOID EstablisherFrame
Definition: ntbasedef.h:653
#define __cdecl
Definition: accygwin.h:79
#define TRUE
Definition: types.h:120
#define _CRTIMP
Definition: crtdefs.h:72
NTSYSAPI VOID NTAPI RtlUnwind(_In_opt_ PVOID TargetFrame, _In_opt_ PVOID TargetIp, _In_opt_ PEXCEPTION_RECORD ExceptionRecord, _In_ PVOID ReturnValue)
Definition: except.c:47
void __cdecl __debugbreak(void)
Definition: intrin_ppc.h:698
#define EXCEPTION_CONTINUE_EXECUTION
Definition: excpt.h:87
LONG ExceptionFilter(IN PEXCEPTION_POINTERS ExceptionInfo, ULONG ExceptionCode)
Definition: delayimp.cpp:307
DWORD ExceptionCode
Definition: compat.h:208
_IRQL_requires_same_ _In_ PVOID _Inout_ struct _CONTEXT _In_ PVOID DispatcherContext
Definition: ntbasedef.h:654
long LONG
Definition: pedump.c:60
#define EXCEPTION_TARGET_UNWIND
Definition: rtltypes.h:159
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:885
#define UlongToPtr(u)
Definition: config.h:106
PCONTEXT ContextRecord
Definition: rtltypes.h:201
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define EXCEPTION_UNWIND
Definition: rtltypes.h:161
_IRQL_requires_same_ _In_ PVOID _Inout_ struct _CONTEXT * ContextRecord
Definition: ntbasedef.h:654
unsigned __int64 ULONG64
Definition: imports.h:198
void __cdecl _local_unwind(void *frame, void *target)
Definition: ehandler.c:137
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical 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:668
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 NULL
Definition: types.h:112
_CRTIMP EXCEPTION_DISPOSITION __cdecl __C_specific_handler(struct _EXCEPTION_RECORD *ExceptionRecord, void *EstablisherFrame, struct _CONTEXT *ContextRecord, struct _DISPATCHER_CONTEXT *DispatcherContext)
Definition: ehandler.c:15
unsigned int ULONG
Definition: retypes.h:1
GLenum target
Definition: glext.h:7315
enum _EXCEPTION_DISPOSITION EXCEPTION_DISPOSITION
DWORD ExceptionFlags
Definition: compat.h:209
PEXCEPTION_RECORD ExceptionRecord
Definition: rtltypes.h:200