OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [ada/] [seh_init.c] - Blame information for rev 720

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 706 jeremybenn
/****************************************************************************
2
 *                                                                          *
3
 *                         GNAT COMPILER COMPONENTS                         *
4
 *                                                                          *
5
 *                              S E H - I N I T                             *
6
 *                                                                          *
7
 *                          C Implementation File                           *
8
 *                                                                          *
9
 *           Copyright (C) 2005-2011, 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 3,  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.                                     *
17
 *                                                                          *
18
 * As a special exception under Section 7 of GPL version 3, you are granted *
19
 * additional permissions described in the GCC Runtime Library Exception,   *
20
 * version 3.1, as published by the Free Software Foundation.               *
21
 *                                                                          *
22
 * You should have received a copy of the GNU General Public License and    *
23
 * a copy of the GCC Runtime Library Exception along with this program;     *
24
 * see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    *
25
 * <http://www.gnu.org/licenses/>.                                          *
26
 *                                                                          *
27
 * GNAT was originally developed  by the GNAT team at  New York University. *
28
 * Extensive contributions were provided by Ada Core Technologies Inc.      *
29
 *                                                                          *
30
 ****************************************************************************/
31
 
32
/*  This unit contains support for SEH (Structured Exception Handling).
33
    Right now the only implementation is for Win32.  */
34
 
35
#ifdef __cplusplus
36
extern "C" {
37
#endif
38
 
39
#ifdef IN_RTS
40
#include "tconfig.h"
41
#include "tsystem.h"
42
 
43
/* We don't have libiberty, so use malloc.  */
44
#define xmalloc(S) malloc (S)
45
 
46
#else
47
#include "config.h"
48
#include "system.h"
49
#endif
50
 
51
#include "raise.h"
52
 
53
/* Addresses of exception data blocks for predefined exceptions. */
54
extern struct Exception_Data constraint_error;
55
extern struct Exception_Data numeric_error;
56
extern struct Exception_Data program_error;
57
extern struct Exception_Data storage_error;
58
extern struct Exception_Data tasking_error;
59
extern struct Exception_Data _abort_signal;
60
 
61
#define Raise_From_Signal_Handler \
62
                      ada__exceptions__raise_from_signal_handler
63
extern void Raise_From_Signal_Handler (struct Exception_Data *, const char *);
64
 
65
 
66
#if defined (_WIN32)
67
 
68
#include <windows.h>
69
#include <excpt.h>
70
 
71
extern void _global_unwind2 (void *);
72
 
73
EXCEPTION_DISPOSITION __gnat_SEH_error_handler
74
(struct _EXCEPTION_RECORD*, void*, struct _CONTEXT*, void*);
75
 
76
EXCEPTION_DISPOSITION
77
__gnat_SEH_error_handler (struct _EXCEPTION_RECORD* ExceptionRecord,
78
                          void *EstablisherFrame,
79
                          struct _CONTEXT* ContextRecord ATTRIBUTE_UNUSED,
80
                          void *DispatcherContext ATTRIBUTE_UNUSED)
81
{
82
  struct Exception_Data *exception;
83
  const char *msg;
84
 
85
  switch (ExceptionRecord->ExceptionCode)
86
    {
87
    case EXCEPTION_ACCESS_VIOLATION:
88
      /* If the failing address isn't maximally-aligned or if the page
89
         before the faulting page is not accessible, this is a program error.
90
      */
91
      if ((ExceptionRecord->ExceptionInformation[1] & 3) != 0
92
          || IsBadCodePtr
93
          ((void *)(ExceptionRecord->ExceptionInformation[1] + 4096)))
94
        {
95
          exception = &program_error;
96
          msg = "EXCEPTION_ACCESS_VIOLATION";
97
        }
98
      else
99
        {
100
          /* otherwise it is a stack overflow  */
101
          exception = &storage_error;
102
          msg = "stack overflow or erroneous memory access";
103
        }
104
      break;
105
 
106
    case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
107
      exception = &constraint_error;
108
      msg = "EXCEPTION_ARRAY_BOUNDS_EXCEEDED";
109
      break;
110
 
111
    case EXCEPTION_DATATYPE_MISALIGNMENT:
112
      exception = &constraint_error;
113
      msg = "EXCEPTION_DATATYPE_MISALIGNMENT";
114
      break;
115
 
116
    case EXCEPTION_FLT_DENORMAL_OPERAND:
117
      exception = &constraint_error;
118
      msg = "EXCEPTION_FLT_DENORMAL_OPERAND";
119
      break;
120
 
121
    case EXCEPTION_FLT_DIVIDE_BY_ZERO:
122
      exception = &constraint_error;
123
      msg = "EXCEPTION_FLT_DENORMAL_OPERAND";
124
      break;
125
 
126
    case EXCEPTION_FLT_INVALID_OPERATION:
127
      exception = &constraint_error;
128
      msg = "EXCEPTION_FLT_INVALID_OPERATION";
129
      break;
130
 
131
    case EXCEPTION_FLT_OVERFLOW:
132
      exception = &constraint_error;
133
      msg = "EXCEPTION_FLT_OVERFLOW";
134
      break;
135
 
136
    case EXCEPTION_FLT_STACK_CHECK:
137
      exception = &program_error;
138
      msg = "EXCEPTION_FLT_STACK_CHECK";
139
      break;
140
 
141
    case EXCEPTION_FLT_UNDERFLOW:
142
      exception = &constraint_error;
143
      msg = "EXCEPTION_FLT_UNDERFLOW";
144
      break;
145
 
146
    case EXCEPTION_INT_DIVIDE_BY_ZERO:
147
      exception = &constraint_error;
148
      msg = "EXCEPTION_INT_DIVIDE_BY_ZERO";
149
      break;
150
 
151
    case EXCEPTION_INT_OVERFLOW:
152
      exception = &constraint_error;
153
      msg = "EXCEPTION_INT_OVERFLOW";
154
      break;
155
 
156
    case EXCEPTION_INVALID_DISPOSITION:
157
      exception = &program_error;
158
      msg = "EXCEPTION_INVALID_DISPOSITION";
159
      break;
160
 
161
    case EXCEPTION_NONCONTINUABLE_EXCEPTION:
162
      exception = &program_error;
163
      msg = "EXCEPTION_NONCONTINUABLE_EXCEPTION";
164
      break;
165
 
166
    case EXCEPTION_PRIV_INSTRUCTION:
167
      exception = &program_error;
168
      msg = "EXCEPTION_PRIV_INSTRUCTION";
169
      break;
170
 
171
    case EXCEPTION_SINGLE_STEP:
172
      exception = &program_error;
173
      msg = "EXCEPTION_SINGLE_STEP";
174
      break;
175
 
176
    case EXCEPTION_STACK_OVERFLOW:
177
      exception = &storage_error;
178
      msg = "EXCEPTION_STACK_OVERFLOW";
179
      break;
180
 
181
   default:
182
      exception = &program_error;
183
      msg = "unhandled signal";
184
    }
185
 
186
#if ! defined (_WIN64)
187
  /* This call is important as it avoids locking the second time we catch a
188
     signal. Note that this routine is documented as internal to Windows and
189
     should not be used.  */
190
 
191
  _global_unwind2 (EstablisherFrame);
192
  /* Call equivalent to RtlUnwind (EstablisherFrame, NULL, NULL, 0); */
193
#endif
194
 
195
  Raise_From_Signal_Handler (exception, msg);
196
  return 0; /* This is never reached, avoid compiler warning  */
197
}
198
 
199
#if defined (_WIN64)
200
/*  On x86_64 windows exception mechanism is no more based on a chained list
201
    of handlers addresses on the stack. Instead unwinding information is used
202
    to retrieve the exception handler (similar to ZCX GCC mechanism). So in
203
    order to register an exception handler we need to put in the final
204
    executable some unwinding information. This information might be present
205
    statically in the image file inside the .pdata section or registered
206
    through RtlAddFunctionTable API. Currently the GCC toolchain does not
207
    generate the .pdata information for each function. As we don't need to
208
    handle SEH exceptions except for signal handling we are registering a
209
    "fake" unwinding data that associate a SEH exception handler to the
210
    complete .text section. As we never return from the handler, the system
211
    does not try to do the final unwinding using the pdata information. The
212
    unwinding is handled by the runtime using either the GNAT SJLJ mechanism
213
    or the ZCX GCC mechanism.
214
 
215
    Solutions based on SetUnhandledExceptionFilter have been discarded as this
216
    function is mostly disabled on last Windows versions.
217
    Using AddVectoredExceptionHandler should also be discarded as it overrides
218
    all SEH exception handlers that might be present in the program itself and
219
    the loaded DLL (for example it results in unexpected behaviors in the
220
    Win32 subsystem.  */
221
 
222
asm
223
(
224
 " .section .rdata, \"dr\"\n"
225
 " .align 4\n"
226
 "unwind_info:\n"
227
 " .byte 9\n" /* UNW_FLAG_EHANDLER | UNW_VERSION */
228
 " .byte 0\n" /* Prologue size.  */
229
 " .byte 0\n" /* Count of unwind code.  */
230
 " .byte 0\n" /* Frame register and offset.  */
231
 " .rva __gnat_SEH_error_handler\n"
232
 "\n"
233
 " .section .pdata, \"dr\"\n"
234
 " .align 4\n"
235
 " .long 0\n" /* ImageBase */
236
 " .rva etext\n"
237
 " .rva unwind_info\n"
238
 "\n"
239
 " .text\n"
240
);
241
 
242
void __gnat_install_SEH_handler (void *eh ATTRIBUTE_UNUSED)
243
{
244
  /* Nothing to do, the handler is statically installed by the asm statement
245
     just above.  */
246
}
247
 
248
#else /* defined (_WIN64) */
249
/*  Install the Win32 SEH exception handler. Note that the caller must have
250
    allocated 8 bytes on the stack and pass the pointer to this stack
251
    space. This is needed as the SEH exception handler must be on the stack of
252
    the thread.
253
 
254
       int buf[2];
255
 
256
       __gnat_install_SEH_handler ((void*)buf);
257
 
258
       main();
259
 
260
   This call must be done before calling the main procedure or the thread
261
   entry. The stack space must exists during all the main run.  */
262
 
263
void
264
__gnat_install_SEH_handler (void *ER)
265
{
266
  int *ptr;
267
 
268
  /* put current handler in ptr */
269
 
270
  asm ("mov %%fs:(0),%0" : "=r" (ptr));
271
 
272
  ((int *)ER)[0] = (int)ptr;                       /* previous handler */
273
  ((int *)ER)[1] = (int)__gnat_SEH_error_handler;  /* new handler */
274
 
275
  /* ER is the new handler, set fs:(0) with this value */
276
 
277
  asm volatile ("mov %0,%%fs:(0)": : "r" (ER));
278
}
279
#endif
280
 
281
#else /* defined (_WIN32) */
282
/* For all non Windows targets we provide a dummy SEH install handler.  */
283
void __gnat_install_SEH_handler (void *eh ATTRIBUTE_UNUSED)
284
{
285
}
286
#endif
287
 
288
#ifdef __cplusplus
289
}
290
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.