2
* This file has no copyright assigned and is placed in the Public Domain.
3
* This file is part of the w64 mingw-runtime package.
4
* No warranty is given; refer to the file DISCLAIMER.PD within this package.
16
#if defined (_WIN64) && defined (__ia64__)
17
#error FIXME: Unsupported __ImageBase implementation.
19
#define __ImageBase __MINGW_LSYMBOL(_image_base__)
20
/* This symbol is defined by the linker. */
21
extern IMAGE_DOS_HEADER __ImageBase;
25
typedef struct _UNWIND_INFO {
28
BYTE CountOfUnwindCodes;
29
BYTE FrameRegisterAndOffset;
30
ULONG AddressOfExceptionHandler;
31
} UNWIND_INFO,*PUNWIND_INFO;
34
PIMAGE_SECTION_HEADER _FindPESectionByName (const char *);
35
PIMAGE_SECTION_HEADER _FindPESectionExec (size_t);
36
PBYTE _GetPEImageBase (void);
38
int __mingw_init_ehandler (void);
41
EXCEPTION_DISPOSITION __mingw_SEH_error_handler(struct _EXCEPTION_RECORD *, void *, struct _CONTEXT *, void *);
43
#define MAX_PDATA_ENTRIES 32
44
static RUNTIME_FUNCTION emu_pdata[MAX_PDATA_ENTRIES];
45
static UNWIND_INFO emu_xdata[MAX_PDATA_ENTRIES];
48
__mingw_init_ehandler (void)
50
static int was_here = 0;
52
PIMAGE_SECTION_HEADER pSec;
53
PBYTE _ImageBase = _GetPEImageBase ();
55
if (was_here || !_ImageBase)
58
if (_FindPESectionByName (".pdata") != NULL)
61
/* Allocate # of e tables and entries. */
62
memset (emu_pdata, 0, sizeof (RUNTIME_FUNCTION) * MAX_PDATA_ENTRIES);
63
memset (emu_xdata, 0, sizeof (UNWIND_INFO) * MAX_PDATA_ENTRIES);
66
/* Fill tables and entries. */
67
while (e < MAX_PDATA_ENTRIES && (pSec = _FindPESectionExec (e)) != NULL)
69
emu_xdata[e].VersionAndFlags = 9; /* UNW_FLAG_EHANDLER | UNW_VERSION */
70
emu_xdata[e].AddressOfExceptionHandler =
71
(DWORD)(size_t) ((LPBYTE)__mingw_SEH_error_handler - _ImageBase);
72
emu_pdata[e].BeginAddress = pSec->VirtualAddress;
73
emu_pdata[e].EndAddress = pSec->VirtualAddress + pSec->Misc.VirtualSize;
74
emu_pdata[e].UnwindData =
75
(DWORD)(size_t)((LPBYTE)&emu_xdata[e] - _ImageBase);
79
if (!e || e > MAX_PDATA_ENTRIES)
82
/* RtlAddFunctionTable. */
84
RtlAddFunctionTable (emu_pdata, e, (DWORD64)_ImageBase);
88
extern void _fpreset (void);
91
__mingw_SEH_error_handler (struct _EXCEPTION_RECORD* ExceptionRecord,
92
void *EstablisherFrame __attribute__ ((unused)),
93
struct _CONTEXT* ContextRecord __attribute__ ((unused)),
94
void *DispatcherContext __attribute__ ((unused)))
96
EXCEPTION_DISPOSITION action = EXCEPTION_CONTINUE_SEARCH;
97
void (*old_handler) (int);
100
switch (ExceptionRecord->ExceptionCode)
102
case EXCEPTION_ACCESS_VIOLATION:
103
/* test if the user has set SIGSEGV */
104
old_handler = signal (SIGSEGV, SIG_DFL);
105
if (old_handler == SIG_IGN)
107
/* this is undefined if the signal was raised by anything other
109
signal (SIGSEGV, SIG_IGN);
110
action = EXCEPTION_CONTINUE_EXECUTION;
112
else if (old_handler != SIG_DFL)
114
/* This means 'old' is a user defined function. Call it */
115
(*old_handler) (SIGSEGV);
116
action = EXCEPTION_CONTINUE_EXECUTION;
119
action = EXCEPTION_EXECUTE_HANDLER;
121
case EXCEPTION_ILLEGAL_INSTRUCTION:
122
case EXCEPTION_PRIV_INSTRUCTION:
123
/* test if the user has set SIGILL */
124
old_handler = signal (SIGILL, SIG_DFL);
125
if (old_handler == SIG_IGN)
127
/* this is undefined if the signal was raised by anything other
129
signal (SIGILL, SIG_IGN);
130
action = EXCEPTION_CONTINUE_EXECUTION;
132
else if (old_handler != SIG_DFL)
134
/* This means 'old' is a user defined function. Call it */
135
(*old_handler) (SIGILL);
136
action = EXCEPTION_CONTINUE_EXECUTION;
139
action = EXCEPTION_EXECUTE_HANDLER;
141
case EXCEPTION_FLT_INVALID_OPERATION:
142
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
143
case EXCEPTION_FLT_DENORMAL_OPERAND:
144
case EXCEPTION_FLT_OVERFLOW:
145
case EXCEPTION_FLT_UNDERFLOW:
146
case EXCEPTION_FLT_INEXACT_RESULT:
150
case EXCEPTION_INT_DIVIDE_BY_ZERO:
151
/* test if the user has set SIGFPE */
152
old_handler = signal (SIGFPE, SIG_DFL);
153
if (old_handler == SIG_IGN)
155
signal (SIGFPE, SIG_IGN);
158
action = EXCEPTION_CONTINUE_EXECUTION;
160
else if (old_handler != SIG_DFL)
162
/* This means 'old' is a user defined function. Call it */
163
(*old_handler) (SIGFPE);
164
action = EXCEPTION_CONTINUE_EXECUTION;
167
case EXCEPTION_DATATYPE_MISALIGNMENT:
168
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
169
case EXCEPTION_FLT_STACK_CHECK:
170
case EXCEPTION_INT_OVERFLOW:
171
case EXCEPTION_INVALID_HANDLE:
172
/*case EXCEPTION_POSSIBLE_DEADLOCK: */
173
action = EXCEPTION_CONTINUE_EXECUTION;