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.
20 #define __ImageBase __MINGW_LSYMBOL(_image_base__)
22 /* This symbol is defined by the linker. */
23 extern IMAGE_DOS_HEADER __ImageBase
;
27 typedef struct _UNWIND_INFO
{
30 BYTE CountOfUnwindCodes
;
31 BYTE FrameRegisterAndOffset
;
32 ULONG AddressOfExceptionHandler
;
33 } UNWIND_INFO
,*PUNWIND_INFO
;
36 PIMAGE_SECTION_HEADER
_FindPESectionByName (const char *);
37 PIMAGE_SECTION_HEADER
_FindPESectionExec (size_t);
38 PBYTE
_GetPEImageBase (void);
40 int __mingw_init_ehandler (void);
43 EXCEPTION_DISPOSITION
__mingw_SEH_error_handler(struct _EXCEPTION_RECORD
*, void *, struct _CONTEXT
*, void *);
45 #define MAX_PDATA_ENTRIES 32
46 static RUNTIME_FUNCTION emu_pdata
[MAX_PDATA_ENTRIES
];
47 static UNWIND_INFO emu_xdata
[MAX_PDATA_ENTRIES
];
50 __mingw_init_ehandler (void)
52 static int was_here
= 0;
54 PIMAGE_SECTION_HEADER pSec
;
55 PBYTE _ImageBase
= _GetPEImageBase ();
57 if (was_here
|| !_ImageBase
)
60 if (_FindPESectionByName (".pdata") != NULL
)
63 /* Allocate # of e tables and entries. */
64 memset (emu_pdata
, 0, sizeof (RUNTIME_FUNCTION
) * MAX_PDATA_ENTRIES
);
65 memset (emu_xdata
, 0, sizeof (UNWIND_INFO
) * MAX_PDATA_ENTRIES
);
68 /* Fill tables and entries. */
69 while (e
< MAX_PDATA_ENTRIES
&& (pSec
= _FindPESectionExec (e
)) != NULL
)
71 emu_xdata
[e
].VersionAndFlags
= 9; /* UNW_FLAG_EHANDLER | UNW_VERSION */
72 emu_xdata
[e
].AddressOfExceptionHandler
=
73 (DWORD
)(size_t) ((LPBYTE
)__mingw_SEH_error_handler
- _ImageBase
);
74 emu_pdata
[e
].BeginAddress
= pSec
->VirtualAddress
;
75 emu_pdata
[e
].EndAddress
= pSec
->VirtualAddress
+ pSec
->Misc
.VirtualSize
;
76 emu_pdata
[e
].UnwindData
=
77 (DWORD
)(size_t)((LPBYTE
)&emu_xdata
[e
] - _ImageBase
);
81 if (!e
|| e
> MAX_PDATA_ENTRIES
)
84 /* RtlAddFunctionTable. */
86 RtlAddFunctionTable (emu_pdata
, e
, (DWORD64
)_ImageBase
);
90 extern void _fpreset (void);
93 __mingw_SEH_error_handler (struct _EXCEPTION_RECORD
* ExceptionRecord
,
94 void *EstablisherFrame
__attribute__ ((unused
)),
95 struct _CONTEXT
* ContextRecord
__attribute__ ((unused
)),
96 void *DispatcherContext
__attribute__ ((unused
)))
98 EXCEPTION_DISPOSITION action
= EXCEPTION_CONTINUE_SEARCH
;
99 void (*old_handler
) (int);
102 switch (ExceptionRecord
->ExceptionCode
)
104 case EXCEPTION_ACCESS_VIOLATION
:
105 /* test if the user has set SIGSEGV */
106 old_handler
= signal (SIGSEGV
, SIG_DFL
);
107 if (old_handler
== SIG_IGN
)
109 /* this is undefined if the signal was raised by anything other
111 signal (SIGSEGV
, SIG_IGN
);
112 action
= EXCEPTION_CONTINUE_EXECUTION
;
114 else if (old_handler
!= SIG_DFL
)
116 /* This means 'old' is a user defined function. Call it */
117 (*old_handler
) (SIGSEGV
);
118 action
= EXCEPTION_CONTINUE_EXECUTION
;
121 action
= EXCEPTION_EXECUTE_HANDLER
;
123 case EXCEPTION_ILLEGAL_INSTRUCTION
:
124 case EXCEPTION_PRIV_INSTRUCTION
:
125 /* test if the user has set SIGILL */
126 old_handler
= signal (SIGILL
, SIG_DFL
);
127 if (old_handler
== SIG_IGN
)
129 /* this is undefined if the signal was raised by anything other
131 signal (SIGILL
, SIG_IGN
);
132 action
= EXCEPTION_CONTINUE_EXECUTION
;
134 else if (old_handler
!= SIG_DFL
)
136 /* This means 'old' is a user defined function. Call it */
137 (*old_handler
) (SIGILL
);
138 action
= EXCEPTION_CONTINUE_EXECUTION
;
141 action
= EXCEPTION_EXECUTE_HANDLER
;
143 case EXCEPTION_FLT_INVALID_OPERATION
:
144 case EXCEPTION_FLT_DIVIDE_BY_ZERO
:
145 case EXCEPTION_FLT_DENORMAL_OPERAND
:
146 case EXCEPTION_FLT_OVERFLOW
:
147 case EXCEPTION_FLT_UNDERFLOW
:
148 case EXCEPTION_FLT_INEXACT_RESULT
:
152 case EXCEPTION_INT_DIVIDE_BY_ZERO
:
153 /* test if the user has set SIGFPE */
154 old_handler
= signal (SIGFPE
, SIG_DFL
);
155 if (old_handler
== SIG_IGN
)
157 signal (SIGFPE
, SIG_IGN
);
160 action
= EXCEPTION_CONTINUE_EXECUTION
;
162 else if (old_handler
!= SIG_DFL
)
164 /* This means 'old' is a user defined function. Call it */
165 (*old_handler
) (SIGFPE
);
166 action
= EXCEPTION_CONTINUE_EXECUTION
;
169 case EXCEPTION_DATATYPE_MISALIGNMENT
:
170 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED
:
171 case EXCEPTION_FLT_STACK_CHECK
:
172 case EXCEPTION_INT_OVERFLOW
:
173 case EXCEPTION_INVALID_HANDLE
:
174 /*case EXCEPTION_POSSIBLE_DEADLOCK: */
175 action
= EXCEPTION_CONTINUE_EXECUTION
;