This commit was manufactured by cvs2svn to create branch
[official-gcc.git] / gcc / ada / seh_init.c
blob15cda4fdbf457f2fa87773cd83355b2be6c23af3
1 /****************************************************************************
2 * *
3 * GNAT COMPILER COMPONENTS *
4 * *
5 * S E H - I N I T *
6 * *
7 * C Implementation File *
8 * *
9 * Copyright (C) 2005, Free Software Foundation, Inc. *
10 * *
11 * GNAT is free software; you can redistribute it and/or modify it under *
12 * terms of the GNU General Public License as published by the Free Soft- *
13 * ware Foundation; either version 2, or (at your option) any later ver- *
14 * sion. GNAT is distributed in the hope that it will be useful, but WITH- *
15 * OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
16 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
17 * for more details. You should have received a copy of the GNU General *
18 * Public License distributed with GNAT; see file COPYING. If not, write *
19 * to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, *
20 * MA 02111-1307, USA. *
21 * *
22 * As a special exception, if you link this file with other files to *
23 * produce an executable, this file does not by itself cause the resulting *
24 * executable to be covered by the GNU General Public License. This except- *
25 * ion does not however invalidate any other reasons why the executable *
26 * file might be covered by the GNU Public License. *
27 * *
28 * GNAT was originally developed by the GNAT team at New York University. *
29 * Extensive contributions were provided by Ada Core Technologies Inc. *
30 * *
31 ****************************************************************************/
33 /* This unit contains support for SEH (Structured Exception Handling).
34 Right now the only implementation is for Win32. */
36 #ifdef IN_RTS
37 #include "tconfig.h"
38 #include "tsystem.h"
39 #include <sys/stat.h>
41 /* We don't have libiberty, so us malloc. */
42 #define xmalloc(S) malloc (S)
44 #else
45 #include "config.h"
46 #include "system.h"
47 #endif
49 #include "raise.h"
51 /* Addresses of exception data blocks for predefined exceptions. */
52 extern struct Exception_Data constraint_error;
53 extern struct Exception_Data numeric_error;
54 extern struct Exception_Data program_error;
55 extern struct Exception_Data storage_error;
56 extern struct Exception_Data tasking_error;
57 extern struct Exception_Data _abort_signal;
59 #define Raise_From_Signal_Handler \
60 ada__exceptions__raise_from_signal_handler
61 extern void Raise_From_Signal_Handler (struct Exception_Data *, const char *);
64 #ifdef _WIN32
66 #include <windows.h>
67 #include <excpt.h>
69 extern void _global_unwind2 (void *);
71 EXCEPTION_DISPOSITION __gnat_SEH_error_handler
72 (struct _EXCEPTION_RECORD*, void*, struct _CONTEXT*, void*);
74 EXCEPTION_DISPOSITION
75 __gnat_SEH_error_handler (struct _EXCEPTION_RECORD* ExceptionRecord,
76 void *EstablisherFrame,
77 struct _CONTEXT* ContextRecord ATTRIBUTE_UNUSED,
78 void *DispatcherContext ATTRIBUTE_UNUSED)
80 struct Exception_Data *exception;
81 const char *msg;
83 switch (ExceptionRecord->ExceptionCode)
85 case EXCEPTION_ACCESS_VIOLATION:
86 /* If the failing address isn't maximally-aligned or if the page
87 before the faulting page is not accessible, this is a program error.
89 if ((ExceptionRecord->ExceptionInformation[1] & 3) != 0
90 || IsBadCodePtr
91 ((void *)(ExceptionRecord->ExceptionInformation[1] + 4096)))
93 exception = &program_error;
94 msg = "EXCEPTION_ACCESS_VIOLATION";
96 else
98 /* otherwise it is a stack overflow */
99 exception = &storage_error;
100 msg = "stack overflow (or erroneous memory access)";
102 break;
104 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
105 exception = &constraint_error;
106 msg = "EXCEPTION_ARRAY_BOUNDS_EXCEEDED";
107 break;
109 case EXCEPTION_DATATYPE_MISALIGNMENT:
110 exception = &constraint_error;
111 msg = "EXCEPTION_DATATYPE_MISALIGNMENT";
112 break;
114 case EXCEPTION_FLT_DENORMAL_OPERAND:
115 exception = &constraint_error;
116 msg = "EXCEPTION_FLT_DENORMAL_OPERAND";
117 break;
119 case EXCEPTION_FLT_DIVIDE_BY_ZERO:
120 exception = &constraint_error;
121 msg = "EXCEPTION_FLT_DENORMAL_OPERAND";
122 break;
124 case EXCEPTION_FLT_INVALID_OPERATION:
125 exception = &constraint_error;
126 msg = "EXCEPTION_FLT_INVALID_OPERATION";
127 break;
129 case EXCEPTION_FLT_OVERFLOW:
130 exception = &constraint_error;
131 msg = "EXCEPTION_FLT_OVERFLOW";
132 break;
134 case EXCEPTION_FLT_STACK_CHECK:
135 exception = &program_error;
136 msg = "EXCEPTION_FLT_STACK_CHECK";
137 break;
139 case EXCEPTION_FLT_UNDERFLOW:
140 exception = &constraint_error;
141 msg = "EXCEPTION_FLT_UNDERFLOW";
142 break;
144 case EXCEPTION_INT_DIVIDE_BY_ZERO:
145 exception = &constraint_error;
146 msg = "EXCEPTION_INT_DIVIDE_BY_ZERO";
147 break;
149 case EXCEPTION_INT_OVERFLOW:
150 exception = &constraint_error;
151 msg = "EXCEPTION_INT_OVERFLOW";
152 break;
154 case EXCEPTION_INVALID_DISPOSITION:
155 exception = &program_error;
156 msg = "EXCEPTION_INVALID_DISPOSITION";
157 break;
159 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
160 exception = &program_error;
161 msg = "EXCEPTION_NONCONTINUABLE_EXCEPTION";
162 break;
164 case EXCEPTION_PRIV_INSTRUCTION:
165 exception = &program_error;
166 msg = "EXCEPTION_PRIV_INSTRUCTION";
167 break;
169 case EXCEPTION_SINGLE_STEP:
170 exception = &program_error;
171 msg = "EXCEPTION_SINGLE_STEP";
172 break;
174 case EXCEPTION_STACK_OVERFLOW:
175 exception = &storage_error;
176 msg = "EXCEPTION_STACK_OVERFLOW";
177 break;
179 default:
180 exception = &program_error;
181 msg = "unhandled signal";
184 /* This call is important as it avoids locking the second time we catch a
185 signal. Note that this routine is documented as internal to Windows and
186 should not be used. */
188 _global_unwind2 (EstablisherFrame);
189 /* Call equivalent to RtlUnwind (EstablisherFrame, NULL, NULL, 0); */
191 Raise_From_Signal_Handler (exception, msg);
192 return 0; /* This is never reached, avoid compiler warning */
195 /* Install the Win32 SEH exception handler. Note that the caller must have
196 allocated 8 bytes on the stack and pass the pointer to this stack
197 space. This is needed as the SEH exception handler must be on the stack of
198 the thread.
200 int buf[2];
202 __gnat_install_SEH_handler ((void*)buf);
204 main();
206 This call must be done before calling the main procedure or the thread
207 entry. The stack space must exists during all the main run. */
209 void
210 __gnat_install_SEH_handler (void *ER)
212 int *ptr;
214 /* put current handler in ptr */
216 asm ("mov %%fs:(0),%%ecx" : : : "%ecx");
217 asm ("mov %%ecx,%0" : "=m" (ptr));
219 ((int *)ER)[0] = (int)ptr; /* previous handler */
220 ((int *)ER)[1] = (int)__gnat_SEH_error_handler; /* new handler */
222 /* ptr is the new handler, set fs:(0) with this value */
224 ptr = (int *)ER;
225 asm ("mov %0,%%ecx" : : "m" (ptr) : "%ecx");
226 asm ("mov %ecx,%fs:(0)");
229 #else /* _WIN32 */
230 /* For all non Windows targets we provide a dummy SEH install handler. */
231 void __gnat_install_SEH_handler (void *eh ATTRIBUTE_UNUSED)
234 #endif