ReactOS  0.4.15-dev-1177-g6cb3b62
crt_handler.c
Go to the documentation of this file.
1 
7 #include <excpt.h>
8 #include <string.h>
9 #include <stdlib.h>
10 #include <malloc.h>
11 #include <memory.h>
12 #include <signal.h>
13 #include <stdio.h>
14 
15 #include <windef.h>
16 #include <winbase.h>
17 
18 #if defined (_WIN64) && defined (__ia64__)
19 #error FIXME: Unsupported __ImageBase implementation.
20 #else
21 #ifndef _MSC_VER
22 #define __ImageBase __MINGW_LSYMBOL(_image_base__)
23 #endif
24 /* This symbol is defined by the linker. */
26 #endif
27 
28 #pragma pack(push,1)
29 typedef struct _UNWIND_INFO {
36 #pragma pack(pop)
37 
40 PBYTE _GetPEImageBase (void);
41 
42 int __mingw_init_ehandler (void);
43 extern void __cdecl _fpreset (void);
44 
45 #if defined(_WIN64) && !defined(_MSC_VER)
46 EXCEPTION_DISPOSITION __mingw_SEH_error_handler(struct _EXCEPTION_RECORD *, void *, struct _CONTEXT *, void *);
47 
48 #define MAX_PDATA_ENTRIES 32
49 static RUNTIME_FUNCTION emu_pdata[MAX_PDATA_ENTRIES];
50 static UNWIND_INFO emu_xdata[MAX_PDATA_ENTRIES];
51 
52 int
54 {
55  static int was_here = 0;
56  size_t e = 0;
58  PBYTE _ImageBase = _GetPEImageBase ();
59 
60  if (was_here || !_ImageBase)
61  return was_here;
62  was_here = 1;
63  if (_FindPESectionByName (".pdata") != NULL)
64  return 1;
65 
66  /* Allocate # of e tables and entries. */
67  memset (emu_pdata, 0, sizeof (RUNTIME_FUNCTION) * MAX_PDATA_ENTRIES);
68  memset (emu_xdata, 0, sizeof (UNWIND_INFO) * MAX_PDATA_ENTRIES);
69 
70  e = 0;
71  /* Fill tables and entries. */
72  while (e < MAX_PDATA_ENTRIES && (pSec = _FindPESectionExec (e)) != NULL)
73  {
74  emu_xdata[e].VersionAndFlags = 9; /* UNW_FLAG_EHANDLER | UNW_VERSION */
75  emu_xdata[e].AddressOfExceptionHandler =
76  (DWORD)(size_t) ((LPBYTE)__mingw_SEH_error_handler - _ImageBase);
77  emu_pdata[e].BeginAddress = pSec->VirtualAddress;
78  emu_pdata[e].EndAddress = pSec->VirtualAddress + pSec->Misc.VirtualSize;
79  emu_pdata[e].UnwindData =
80  (DWORD)(size_t)((LPBYTE)&emu_xdata[e] - _ImageBase);
81  ++e;
82  }
83 #ifdef _DEBUG_CRT
84  if (!e || e > MAX_PDATA_ENTRIES)
85  abort ();
86 #endif
87  /* RtlAddFunctionTable. */
88  if (e != 0)
89  RtlAddFunctionTable (emu_pdata, e, (DWORD64)_ImageBase);
90  return 1;
91 }
92 
93 extern void __cdecl _fpreset (void);
94 
96 __mingw_SEH_error_handler (struct _EXCEPTION_RECORD* ExceptionRecord,
100 {
101  EXCEPTION_DISPOSITION action = ExceptionContinueSearch; /* EXCEPTION_CONTINUE_SEARCH; */
102  void (*old_handler) (int);
103  int reset_fpu = 0;
104 
105  switch (ExceptionRecord->ExceptionCode)
106  {
108  /* test if the user has set SIGSEGV */
109  old_handler = signal (SIGSEGV, SIG_DFL);
110  if (old_handler == SIG_IGN)
111  {
112  /* this is undefined if the signal was raised by anything other
113  than raise (). */
115  action = 0; //EXCEPTION_CONTINUE_EXECUTION;
116  }
117  else if (old_handler != SIG_DFL)
118  {
119  /* This means 'old' is a user defined function. Call it */
120  (*old_handler) (SIGSEGV);
121  action = 0; // EXCEPTION_CONTINUE_EXECUTION;
122  }
123  else
124  action = 4; /* EXCEPTION_EXECUTE_HANDLER; */
125  break;
128  /* test if the user has set SIGILL */
129  old_handler = signal (SIGILL, SIG_DFL);
130  if (old_handler == SIG_IGN)
131  {
132  /* this is undefined if the signal was raised by anything other
133  than raise (). */
134  signal (SIGILL, SIG_IGN);
135  action = 0; // EXCEPTION_CONTINUE_EXECUTION;
136  }
137  else if (old_handler != SIG_DFL)
138  {
139  /* This means 'old' is a user defined function. Call it */
140  (*old_handler) (SIGILL);
141  action = 0; // EXCEPTION_CONTINUE_EXECUTION;
142  }
143  else
144  action = 4; /* EXCEPTION_EXECUTE_HANDLER;*/
145  break;
152  reset_fpu = 1;
153  /* fall through. */
154 
156  /* test if the user has set SIGFPE */
157  old_handler = signal (SIGFPE, SIG_DFL);
158  if (old_handler == SIG_IGN)
159  {
160  signal (SIGFPE, SIG_IGN);
161  if (reset_fpu)
162  _fpreset ();
163  action = 0; // EXCEPTION_CONTINUE_EXECUTION;
164  }
165  else if (old_handler != SIG_DFL)
166  {
167  /* This means 'old' is a user defined function. Call it */
168  (*old_handler) (SIGFPE);
169  action = 0; // EXCEPTION_CONTINUE_EXECUTION;
170  }
171  break;
177  /*case EXCEPTION_POSSIBLE_DEADLOCK: */
178  action = 0; // EXCEPTION_CONTINUE_EXECUTION;
179  break;
180  default:
181  break;
182  }
183  return action;
184 }
185 
186 #endif
187 
189 
190 long CALLBACK
192 
193 #define GCC_MAGIC (('G' << 16) | ('C' << 8) | 'C' | (1U << 29))
194 
195 long CALLBACK
197 {
198  void (*old_handler) (int);
200  int reset_fpu = 0;
201 
202 #ifdef __SEH__
203  if ((exception_data->ExceptionRecord->ExceptionCode & 0x20ffffff) == GCC_MAGIC)
204  {
205  if ((exception_data->ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE) == 0)
207  }
208 #endif
209 
210  switch (exception_data->ExceptionRecord->ExceptionCode)
211  {
213  /* test if the user has set SIGSEGV */
214  old_handler = signal (SIGSEGV, SIG_DFL);
215  if (old_handler == SIG_IGN)
216  {
217  /* this is undefined if the signal was raised by anything other
218  than raise (). */
221  }
222  else if (old_handler != SIG_DFL)
223  {
224  /* This means 'old' is a user defined function. Call it */
225  (*old_handler) (SIGSEGV);
227  }
228  break;
229 
232  /* test if the user has set SIGILL */
233  old_handler = signal (SIGILL, SIG_DFL);
234  if (old_handler == SIG_IGN)
235  {
236  /* this is undefined if the signal was raised by anything other
237  than raise (). */
238  signal (SIGILL, SIG_IGN);
240  }
241  else if (old_handler != SIG_DFL)
242  {
243  /* This means 'old' is a user defined function. Call it */
244  (*old_handler) (SIGILL);
246  }
247  break;
248 
255  reset_fpu = 1;
256  /* fall through. */
257 
259  /* test if the user has set SIGFPE */
260  old_handler = signal (SIGFPE, SIG_DFL);
261  if (old_handler == SIG_IGN)
262  {
263  signal (SIGFPE, SIG_IGN);
264  if (reset_fpu)
265  _fpreset ();
267  }
268  else if (old_handler != SIG_DFL)
269  {
270  /* This means 'old' is a user defined function. Call it */
271  (*old_handler) (SIGFPE);
273  }
274  break;
275 #ifdef _WIN64
281  /*case EXCEPTION_POSSIBLE_DEADLOCK: */
283  break;
284 #endif
285  default:
286  break;
287  }
288 
290  action = (*__mingw_oldexcpt_handler)(exception_data);
291  return action;
292 }
struct _UNWIND_INFO UNWIND_INFO
#define EXCEPTION_FLT_UNDERFLOW
Definition: winbase.h:319
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
_IRQL_requires_same_ _In_ PVOID EstablisherFrame
Definition: ntbasedef.h:654
#define __cdecl
Definition: accygwin.h:79
ULONG AddressOfExceptionHandler
Definition: crt_handler.c:34
#define EXCEPTION_INT_DIVIDE_BY_ZERO
Definition: winbase.h:320
#define EXCEPTION_ACCESS_VIOLATION
Definition: winbase.h:308
#define CALLBACK
Definition: compat.h:35
PIMAGE_SECTION_HEADER _FindPESectionByName(const char *)
Definition: pesect.c:70
#define EXCEPTION_INVALID_HANDLE
Definition: winbase.h:329
#define EXCEPTION_INT_OVERFLOW
Definition: winbase.h:321
#define EXCEPTION_NONCONTINUABLE
Definition: rtltypes.h:154
#define SIGILL
Definition: signal.h:25
#define EXCEPTION_FLT_INVALID_OPERATION
Definition: winbase.h:316
long CALLBACK _gnu_exception_handler(EXCEPTION_POINTERS *exception_data)
Definition: crt_handler.c:196
#define SIG_DFL
Definition: signal.h:47
#define DWORD
Definition: nt_native.h:44
BYTE FrameRegisterAndOffset
Definition: crt_handler.c:33
DWORD ExceptionCode
Definition: compat.h:208
WORD unused[29]
Definition: crypt.c:1155
#define EXCEPTION_CONTINUE_SEARCH
Definition: excpt.h:86
int signal
Definition: except.c:82
PIMAGE_SECTION_HEADER _FindPESectionExec(size_t)
Definition: pesect.c:133
unsigned char * LPBYTE
Definition: typedefs.h:53
_IRQL_requires_same_ _In_ PVOID _Inout_ struct _CONTEXT _In_ PVOID DispatcherContext
Definition: ntbasedef.h:655
#define e
Definition: ke_i.h:82
LPTOP_LEVEL_EXCEPTION_FILTER __mingw_oldexcpt_handler
Definition: crt_handler.c:188
smooth NULL
Definition: ftsmooth.c:416
union _IMAGE_SECTION_HEADER::@1553 Misc
BOOLEAN NTAPI RtlAddFunctionTable(IN PRUNTIME_FUNCTION FunctionTable, IN DWORD EntryCount, IN DWORD64 BaseAddress)
Definition: unwind.c:164
BYTE PrologSize
Definition: crt_handler.c:31
#define EXCEPTION_FLT_DIVIDE_BY_ZERO
Definition: winbase.h:314
BYTE CountOfUnwindCodes
Definition: crt_handler.c:32
#define EXCEPTION_ARRAY_BOUNDS_EXCEEDED
Definition: winbase.h:312
#define SIGFPE
Definition: signal.h:30
_IRQL_requires_same_ _In_ PVOID _Inout_ struct _CONTEXT * ContextRecord
Definition: ntbasedef.h:655
#define EXCEPTION_DATATYPE_MISALIGNMENT
Definition: winbase.h:309
#define EXCEPTION_FLT_DENORMAL_OPERAND
Definition: winbase.h:313
PTOP_LEVEL_EXCEPTION_FILTER LPTOP_LEVEL_EXCEPTION_FILTER
Definition: winbase.h:1419
#define SIGSEGV
Definition: signal.h:33
unsigned char BYTE
Definition: xxhash.c:193
const WCHAR * action
Definition: action.c:7783
uint64_t DWORD64
Definition: typedefs.h:67
void __cdecl _fpreset(void)
Definition: fpreset.c:13
#define EXCEPTION_FLT_OVERFLOW
Definition: winbase.h:317
#define abort()
Definition: i386-dis.c:35
#define EXCEPTION_FLT_STACK_CHECK
Definition: winbase.h:318
#define GCC_MAGIC
Definition: crt_handler.c:193
struct _UNWIND_INFO * PUNWIND_INFO
#define EXCEPTION_ILLEGAL_INSTRUCTION
Definition: winbase.h:324
unsigned int ULONG
Definition: retypes.h:1
enum _EXCEPTION_DISPOSITION EXCEPTION_DISPOSITION
DWORD ExceptionFlags
Definition: compat.h:209
PEXCEPTION_RECORD ExceptionRecord
Definition: rtltypes.h:200
#define __ImageBase
Definition: crt_handler.c:22
#define SIG_IGN
Definition: signal.h:48
#define memset(x, y, z)
Definition: compat.h:39
PBYTE _GetPEImageBase(void)
Definition: pesect.c:163
BYTE * PBYTE
Definition: pedump.c:66
int __mingw_init_ehandler(void)
Definition: mscmain.c:27
#define EXCEPTION_PRIV_INSTRUCTION
Definition: winbase.h:322
#define EXCEPTION_FLT_INEXACT_RESULT
Definition: winbase.h:315
BYTE VersionAndFlags
Definition: crt_handler.c:30
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define EXCEPTION_CONTINUE_EXECUTION
Definition: excpt.h:87