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 within this package.
16 #if defined (_WIN64) && defined (__ia64__)
17 #error FIXME: Unsupported __ImageBase implementation.
19 #define __ImageBase _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 case EXCEPTION_ILLEGAL_INSTRUCTION
:
120 case EXCEPTION_PRIV_INSTRUCTION
:
121 /* test if the user has set SIGILL */
122 old_handler
= signal (SIGILL
, SIG_DFL
);
123 if (old_handler
== SIG_IGN
)
125 /* this is undefined if the signal was raised by anything other
127 signal (SIGILL
, SIG_IGN
);
128 action
= EXCEPTION_CONTINUE_EXECUTION
;
130 else if (old_handler
!= SIG_DFL
)
132 /* This means 'old' is a user defined function. Call it */
133 (*old_handler
) (SIGILL
);
134 action
= EXCEPTION_CONTINUE_EXECUTION
;
137 case EXCEPTION_FLT_INVALID_OPERATION
:
138 case EXCEPTION_FLT_DIVIDE_BY_ZERO
:
139 case EXCEPTION_FLT_DENORMAL_OPERAND
:
140 case EXCEPTION_FLT_OVERFLOW
:
141 case EXCEPTION_FLT_UNDERFLOW
:
142 case EXCEPTION_FLT_INEXACT_RESULT
:
146 case EXCEPTION_INT_DIVIDE_BY_ZERO
:
147 /* test if the user has set SIGFPE */
148 old_handler
= signal (SIGFPE
, SIG_DFL
);
149 if (old_handler
== SIG_IGN
)
151 signal (SIGFPE
, SIG_IGN
);
154 action
= EXCEPTION_CONTINUE_EXECUTION
;
156 else if (old_handler
!= SIG_DFL
)
158 /* This means 'old' is a user defined function. Call it */
159 (*old_handler
) (SIGFPE
);
160 action
= EXCEPTION_CONTINUE_EXECUTION
;
163 case EXCEPTION_DATATYPE_MISALIGNMENT
:
164 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED
:
165 case EXCEPTION_FLT_STACK_CHECK
:
166 case EXCEPTION_INT_OVERFLOW
:
167 case EXCEPTION_INVALID_HANDLE
:
168 /*case EXCEPTION_POSSIBLE_DEADLOCK: */
169 action
= EXCEPTION_CONTINUE_EXECUTION
;