1 /****************************************************************************
3 * GNAT COMPILER COMPONENTS *
7 * C Implementation File *
9 * Copyright (C) 1992-2003 Free Software Foundation, Inc. *
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. *
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. *
28 * GNAT was originally developed by the GNAT team at New York University. *
29 * Extensive contributions were provided by Ada Core Technologies Inc. *
31 ****************************************************************************/
33 /* This unit contains initialization circuits that are system dependent. A
34 major part of the functionality involved involves stack overflow checking.
35 The GCC backend generates probe instructions to test for stack overflow.
36 For details on the exact approach used to generate these probes, see the
37 "Using and Porting GCC" manual, in particular the "Stack Checking" section
38 and the subsection "Specifying How Stack Checking is Done". The handlers
39 installed by this file are used to handle resulting signals that come
40 from these probes failing (i.e. touching protected pages) */
42 /* The following include is here to meet the published VxWorks requirement
43 that the __vxworks header appear before any other include. */
53 /* We don't have libiberty, so us malloc. */
54 #define xmalloc(S) malloc (S)
63 extern void __gnat_raise_program_error (const char *, int);
65 /* Addresses of exception data blocks for predefined exceptions. */
66 extern struct Exception_Data constraint_error
;
67 extern struct Exception_Data numeric_error
;
68 extern struct Exception_Data program_error
;
69 extern struct Exception_Data storage_error
;
70 extern struct Exception_Data tasking_error
;
71 extern struct Exception_Data _abort_signal
;
73 #define Lock_Task system__soft_links__lock_task
74 extern void (*Lock_Task
) (void);
76 #define Unlock_Task system__soft_links__unlock_task
77 extern void (*Unlock_Task
) (void);
79 #define Get_Machine_State_Addr \
80 system__soft_links__get_machine_state_addr
81 extern struct Machine_State
*(*Get_Machine_State_Addr
) (void);
83 #define Check_Abort_Status \
84 system__soft_links__check_abort_status
85 extern int (*Check_Abort_Status
) (void);
87 #define Raise_From_Signal_Handler \
88 ada__exceptions__raise_from_signal_handler
89 extern void Raise_From_Signal_Handler (struct Exception_Data
*, const char *);
91 #define Propagate_Signal_Exception \
92 __gnat_propagate_sig_exc
93 extern void Propagate_Signal_Exception (struct Machine_State
*,
94 struct Exception_Data
*,
97 /* Copies of global values computed by the binder */
98 int __gl_main_priority
= -1;
99 int __gl_time_slice_val
= -1;
100 char __gl_wc_encoding
= 'n';
101 char __gl_locking_policy
= ' ';
102 char __gl_queuing_policy
= ' ';
103 char __gl_task_dispatching_policy
= ' ';
104 char *__gl_restrictions
= 0;
105 char *__gl_interrupt_states
= 0;
106 int __gl_num_interrupt_states
= 0;
107 int __gl_unreserve_all_interrupts
= 0;
108 int __gl_exception_tracebacks
= 0;
109 int __gl_zero_cost_exceptions
= 0;
111 /* Indication of whether synchronous signal handler has already been
112 installed by a previous call to adainit */
113 int __gnat_handler_installed
= 0;
115 /* HAVE_GNAT_INIT_FLOAT must be set on every targets where a __gnat_init_float
116 is defined. If this is not set them a void implementation will be defined
117 at the end of this unit. */
118 #undef HAVE_GNAT_INIT_FLOAT
120 /******************************/
121 /* __gnat_get_interrupt_state */
122 /******************************/
124 char __gnat_get_interrupt_state (int);
126 /* This routine is called from the runtime as needed to determine the state
127 of an interrupt, as set by an Interrupt_State pragma appearing anywhere
128 in the current partition. The input argument is the interrupt number,
129 and the result is one of the following:
131 'n' this interrupt not set by any Interrupt_State pragma
132 'u' Interrupt_State pragma set state to User
133 'r' Interrupt_State pragma set state to Runtime
134 's' Interrupt_State pragma set state to System */
137 __gnat_get_interrupt_state (int intrup
)
139 if (intrup
>= __gl_num_interrupt_states
)
142 return __gl_interrupt_states
[intrup
];
145 /**********************/
146 /* __gnat_set_globals */
147 /**********************/
149 /* This routine is called from the binder generated main program. It copies
150 the values for global quantities computed by the binder into the following
151 global locations. The reason that we go through this copy, rather than just
152 define the global locations in the binder generated file, is that they are
153 referenced from the runtime, which may be in a shared library, and the
154 binder file is not in the shared library. Global references across library
155 boundaries like this are not handled correctly in all systems. */
158 __gnat_set_globals (int main_priority
,
163 char task_dispatching_policy
,
165 char *interrupt_states
,
166 int num_interrupt_states
,
167 int unreserve_all_interrupts
,
168 int exception_tracebacks
,
169 int zero_cost_exceptions
)
171 static int already_called
= 0;
173 /* If this procedure has been already called once, check that the
174 arguments in this call are consistent with the ones in the previous
175 calls. Otherwise, raise a Program_Error exception.
177 We do not check for consistency of the wide character encoding
178 method. This default affects only Wide_Text_IO where no explicit
179 coding method is given, and there is no particular reason to let
180 this default be affected by the source representation of a library
183 We do not check either for the consistency of exception tracebacks,
184 because exception tracebacks are not normally set in Stand-Alone
185 libraries. If a library or the main program set the exception
186 tracebacks, then they are never reset afterwards (see below).
188 The value of main_priority is meaningful only when we are invoked
189 from the main program elaboration routine of an Ada application.
190 Checking the consistency of this parameter should therefore not be
191 done. Since it is assured that the main program elaboration will
192 always invoke this procedure before any library elaboration
193 routine, only the value of main_priority during the first call
194 should be taken into account and all the subsequent ones should be
195 ignored. Note that the case where the main program is not written
196 in Ada is also properly handled, since the default value will then
197 be used for this parameter.
199 For identical reasons, the consistency of time_slice_val should not
204 if (__gl_locking_policy
!= locking_policy
205 || __gl_queuing_policy
!= queuing_policy
206 || __gl_task_dispatching_policy
!= task_dispatching_policy
207 || __gl_unreserve_all_interrupts
!= unreserve_all_interrupts
208 || __gl_zero_cost_exceptions
!= zero_cost_exceptions
)
209 __gnat_raise_program_error (__FILE__
, __LINE__
);
211 /* If either a library or the main program set the exception traceback
212 flag, it is never reset later */
214 if (exception_tracebacks
!= 0)
215 __gl_exception_tracebacks
= exception_tracebacks
;
221 __gl_main_priority
= main_priority
;
222 __gl_time_slice_val
= time_slice_val
;
223 __gl_wc_encoding
= wc_encoding
;
224 __gl_locking_policy
= locking_policy
;
225 __gl_queuing_policy
= queuing_policy
;
226 __gl_restrictions
= restrictions
;
227 __gl_interrupt_states
= interrupt_states
;
228 __gl_num_interrupt_states
= num_interrupt_states
;
229 __gl_task_dispatching_policy
= task_dispatching_policy
;
230 __gl_unreserve_all_interrupts
= unreserve_all_interrupts
;
231 __gl_exception_tracebacks
= exception_tracebacks
;
233 /* ??? __gl_zero_cost_exceptions is new in 3.15 and is referenced from
234 a-except.adb, which is also part of the compiler sources. Since the
235 compiler is built with an older release of GNAT, the call generated by
236 the old binder to this function does not provide any value for the
237 corresponding argument, so the global has to be initialized in some
238 reasonable other way. This could be removed as soon as the next major
242 __gl_zero_cost_exceptions
= zero_cost_exceptions
;
244 __gl_zero_cost_exceptions
= 0;
245 /* We never build the compiler to run in ZCX mode currently anyway. */
249 /*********************/
250 /* __gnat_initialize */
251 /*********************/
253 /* __gnat_initialize is called at the start of execution of an Ada program
254 (the call is generated by the binder). The standard routine does nothing
255 at all; the intention is that this be replaced by system specific
256 code where initialization is required. */
258 /***********************************/
259 /* __gnat_initialize (AIX Version) */
260 /***********************************/
265 #include <sys/time.h>
267 /* Some versions of AIX don't define SA_NODEFER. */
271 #endif /* SA_NODEFER */
273 /* Versions of AIX before 4.3 don't have nanosleep but provide
276 #ifndef _AIXVERSION_430
278 extern int nanosleep (struct timestruc_t
*, struct timestruc_t
*);
281 nanosleep (struct timestruc_t
*Rqtp
, struct timestruc_t
*Rmtp
)
283 return nsleep (Rqtp
, Rmtp
);
286 #endif /* _AIXVERSION_430 */
288 static void __gnat_error_handler (int);
291 __gnat_error_handler (int sig
)
293 struct Exception_Data
*exception
;
299 /* FIXME: we need to detect the case of a *real* SIGSEGV */
300 exception
= &storage_error
;
301 msg
= "stack overflow or erroneous memory access";
305 exception
= &constraint_error
;
310 exception
= &constraint_error
;
315 exception
= &program_error
;
316 msg
= "unhandled signal";
319 Raise_From_Signal_Handler (exception
, msg
);
323 __gnat_install_handler (void)
325 struct sigaction act
;
327 /* Set up signal handler to map synchronous signals to appropriate
328 exceptions. Make sure that the handler isn't interrupted by another
329 signal that might cause a scheduling event! */
331 act
.sa_handler
= __gnat_error_handler
;
332 act
.sa_flags
= SA_NODEFER
| SA_RESTART
;
333 sigemptyset (&act
.sa_mask
);
335 /* Do not install handlers if interrupt state is "System" */
336 if (__gnat_get_interrupt_state (SIGABRT
) != 's')
337 sigaction (SIGABRT
, &act
, NULL
);
338 if (__gnat_get_interrupt_state (SIGFPE
) != 's')
339 sigaction (SIGFPE
, &act
, NULL
);
340 if (__gnat_get_interrupt_state (SIGILL
) != 's')
341 sigaction (SIGILL
, &act
, NULL
);
342 if (__gnat_get_interrupt_state (SIGSEGV
) != 's')
343 sigaction (SIGSEGV
, &act
, NULL
);
344 if (__gnat_get_interrupt_state (SIGBUS
) != 's')
345 sigaction (SIGBUS
, &act
, NULL
);
347 __gnat_handler_installed
= 1;
351 __gnat_initialize (void)
355 /***************************************/
356 /* __gnat_initialize (RTEMS version) */
357 /***************************************/
359 #elif defined(__rtems__)
361 extern void __gnat_install_handler (void);
363 /* For RTEMS, each bsp will provide a custom __gnat_install_handler (). */
366 __gnat_initialize (void)
368 __gnat_install_handler ();
371 /****************************************/
372 /* __gnat_initialize (Dec Unix Version) */
373 /****************************************/
375 #elif defined(__alpha__) && defined(__osf__) && ! defined(__alpha_vxworks)
377 /* Note: it seems that __osf__ is defined for the Alpha VXWorks case. Not
378 clear that this is reasonable, but in any case we have to be sure to
379 exclude this case in the above test. */
382 #include <sys/siginfo.h>
384 static void __gnat_error_handler (int, siginfo_t
*, struct sigcontext
*);
385 extern char *__gnat_get_code_loc (struct sigcontext
*);
386 extern void __gnat_enter_handler (struct sigcontext
*, char *);
387 extern size_t __gnat_machine_state_length (void);
389 extern long exc_lookup_gp (char *);
390 extern void exc_resume (struct sigcontext
*);
393 __gnat_error_handler (int sig
, siginfo_t
*sip
, struct sigcontext
*context
)
395 struct Exception_Data
*exception
;
396 static int recurse
= 0;
397 struct sigcontext
*mstate
;
400 /* If this was an explicit signal from a "kill", just resignal it. */
401 if (SI_FROMUSER (sip
))
403 signal (sig
, SIG_DFL
);
404 kill (getpid(), sig
);
407 /* Otherwise, treat it as something we handle. */
411 /* If the problem was permissions, this is a constraint error.
412 Likewise if the failing address isn't maximally aligned or if
415 ??? Using a static variable here isn't task-safe, but it's
416 much too hard to do anything else and we're just determining
417 which exception to raise. */
418 if (sip
->si_code
== SEGV_ACCERR
419 || (((long) sip
->si_addr
) & 3) != 0
422 exception
= &constraint_error
;
427 /* See if the page before the faulting page is accessible. Do that
428 by trying to access it. We'd like to simply try to access
429 4096 + the faulting address, but it's not guaranteed to be
430 the actual address, just to be on the same page. */
433 ((long) sip
->si_addr
& - getpagesize ()))[getpagesize ()];
434 msg
= "stack overflow (or erroneous memory access)";
435 exception
= &storage_error
;
440 exception
= &program_error
;
445 exception
= &constraint_error
;
450 exception
= &program_error
;
451 msg
= "unhandled signal";
455 mstate
= (struct sigcontext
*) (*Get_Machine_State_Addr
) ();
459 Raise_From_Signal_Handler (exception
, (char *) msg
);
463 __gnat_install_handler (void)
465 struct sigaction act
;
467 /* Setup signal handler to map synchronous signals to appropriate
468 exceptions. Make sure that the handler isn't interrupted by another
469 signal that might cause a scheduling event! */
471 act
.sa_handler
= (void (*) (int)) __gnat_error_handler
;
472 act
.sa_flags
= SA_ONSTACK
| SA_RESTART
| SA_NODEFER
| SA_SIGINFO
;
473 sigemptyset (&act
.sa_mask
);
475 /* Do not install handlers if interrupt state is "System" */
476 if (__gnat_get_interrupt_state (SIGABRT
) != 's')
477 sigaction (SIGABRT
, &act
, NULL
);
478 if (__gnat_get_interrupt_state (SIGFPE
) != 's')
479 sigaction (SIGFPE
, &act
, NULL
);
480 if (__gnat_get_interrupt_state (SIGILL
) != 's')
481 sigaction (SIGILL
, &act
, NULL
);
482 if (__gnat_get_interrupt_state (SIGSEGV
) != 's')
483 sigaction (SIGSEGV
, &act
, NULL
);
484 if (__gnat_get_interrupt_state (SIGBUS
) != 's')
485 sigaction (SIGBUS
, &act
, NULL
);
487 __gnat_handler_installed
= 1;
491 __gnat_initialize (void)
495 /* Routines called by 5amastop.adb. */
500 __gnat_get_code_loc (struct sigcontext
*context
)
502 return (char *) context
->sc_pc
;
506 __gnat_enter_handler ( struct sigcontext
*context
, char *pc
)
508 context
->sc_pc
= (long) pc
;
509 context
->sc_regs
[SC_GP
] = exc_lookup_gp (pc
);
510 exc_resume (context
);
514 __gnat_machine_state_length (void)
516 return sizeof (struct sigcontext
);
519 /************************************/
520 /* __gnat_initialize (HPUX Version) */
521 /************************************/
527 static void __gnat_error_handler (int);
530 __gnat_error_handler (int sig
)
532 struct Exception_Data
*exception
;
538 /* FIXME: we need to detect the case of a *real* SIGSEGV */
539 exception
= &storage_error
;
540 msg
= "stack overflow or erroneous memory access";
544 exception
= &constraint_error
;
549 exception
= &constraint_error
;
554 exception
= &program_error
;
555 msg
= "unhandled signal";
558 Raise_From_Signal_Handler (exception
, msg
);
562 __gnat_install_handler (void)
564 struct sigaction act
;
566 /* Set up signal handler to map synchronous signals to appropriate
567 exceptions. Make sure that the handler isn't interrupted by another
568 signal that might cause a scheduling event! Also setup an alternate
569 stack region for the handler execution so that stack overflows can be
570 handled properly, avoiding a SEGV generation from stack usage by the
573 static char handler_stack
[SIGSTKSZ
*2];
574 /* SIGSTKSZ appeared to be "short" for the needs in some contexts
575 (e.g. experiments with GCC ZCX exceptions). */
579 stack
.ss_sp
= handler_stack
;
580 stack
.ss_size
= sizeof (handler_stack
);
583 sigaltstack (&stack
, NULL
);
585 act
.sa_handler
= __gnat_error_handler
;
586 act
.sa_flags
= SA_NODEFER
| SA_RESTART
| SA_ONSTACK
;
587 sigemptyset (&act
.sa_mask
);
589 /* Do not install handlers if interrupt state is "System" */
590 if (__gnat_get_interrupt_state (SIGABRT
) != 's')
591 sigaction (SIGABRT
, &act
, NULL
);
592 if (__gnat_get_interrupt_state (SIGFPE
) != 's')
593 sigaction (SIGFPE
, &act
, NULL
);
594 if (__gnat_get_interrupt_state (SIGILL
) != 's')
595 sigaction (SIGILL
, &act
, NULL
);
596 if (__gnat_get_interrupt_state (SIGSEGV
) != 's')
597 sigaction (SIGSEGV
, &act
, NULL
);
598 if (__gnat_get_interrupt_state (SIGBUS
) != 's')
599 sigaction (SIGBUS
, &act
, NULL
);
601 __gnat_handler_installed
= 1;
605 __gnat_initialize (void)
609 /*****************************************/
610 /* __gnat_initialize (GNU/Linux Version) */
611 /*****************************************/
613 #elif defined (linux) && defined (i386) && !defined (__RT__)
616 #include <asm/sigcontext.h>
618 /* GNU/Linux, which uses glibc, does not define NULL in included
622 #define NULL ((void *) 0)
635 static void __gnat_error_handler (int);
638 __gnat_error_handler (int sig
)
640 struct Exception_Data
*exception
;
642 static int recurse
= 0;
644 struct sigcontext
*info
645 = (struct sigcontext
*) (((char *) &sig
) + sizeof (int));
647 /* The Linux kernel does not document how to get the machine state in a
648 signal handler, but in fact the necessary data is in a sigcontext_struct
649 value that is on the stack immediately above the signal number
650 parameter, and the above messing accesses this value on the stack. */
652 struct Machine_State
*mstate
;
657 /* If the problem was permissions, this is a constraint error.
658 Likewise if the failing address isn't maximally aligned or if
661 ??? Using a static variable here isn't task-safe, but it's
662 much too hard to do anything else and we're just determining
663 which exception to raise. */
666 exception
= &constraint_error
;
671 /* Here we would like a discrimination test to see whether the
672 page before the faulting address is accessible. Unfortunately
673 Linux seems to have no way of giving us the faulting address.
675 In versions of a-init.c before 1.95, we had a test of the page
676 before the stack pointer using:
680 ((long) info->esp_at_signal & - getpagesize ()))[getpagesize ()];
682 but that's wrong, since it tests the stack pointer location, and
683 the current stack probe code does not move the stack pointer
684 until all probes succeed.
686 For now we simply do not attempt any discrimination at all. Note
687 that this is quite acceptable, since a "real" SIGSEGV can only
688 occur as the result of an erroneous program */
690 msg
= "stack overflow (or erroneous memory access)";
691 exception
= &storage_error
;
696 exception
= &constraint_error
;
701 exception
= &constraint_error
;
706 exception
= &program_error
;
707 msg
= "unhandled signal";
710 mstate
= (*Get_Machine_State_Addr
) ();
713 mstate
->eip
= info
->eip
;
714 mstate
->ebx
= info
->ebx
;
715 mstate
->esp
= info
->esp_at_signal
;
716 mstate
->ebp
= info
->ebp
;
717 mstate
->esi
= info
->esi
;
718 mstate
->edi
= info
->edi
;
722 Raise_From_Signal_Handler (exception
, msg
);
726 __gnat_install_handler (void)
728 struct sigaction act
;
730 /* Set up signal handler to map synchronous signals to appropriate
731 exceptions. Make sure that the handler isn't interrupted by another
732 signal that might cause a scheduling event! */
734 act
.sa_handler
= __gnat_error_handler
;
735 act
.sa_flags
= SA_NODEFER
| SA_RESTART
;
736 sigemptyset (&act
.sa_mask
);
738 /* Do not install handlers if interrupt state is "System" */
739 if (__gnat_get_interrupt_state (SIGABRT
) != 's')
740 sigaction (SIGABRT
, &act
, NULL
);
741 if (__gnat_get_interrupt_state (SIGFPE
) != 's')
742 sigaction (SIGFPE
, &act
, NULL
);
743 if (__gnat_get_interrupt_state (SIGILL
) != 's')
744 sigaction (SIGILL
, &act
, NULL
);
745 if (__gnat_get_interrupt_state (SIGSEGV
) != 's')
746 sigaction (SIGSEGV
, &act
, NULL
);
747 if (__gnat_get_interrupt_state (SIGBUS
) != 's')
748 sigaction (SIGBUS
, &act
, NULL
);
750 __gnat_handler_installed
= 1;
754 __gnat_initialize (void)
758 /******************************************/
759 /* __gnat_initialize (NT-mingw32 Version) */
760 /******************************************/
762 #elif defined (__MINGW32__)
765 static LONG WINAPI
__gnat_error_handler (PEXCEPTION_POINTERS
);
767 /* __gnat_initialize (mingw32). */
770 __gnat_error_handler (PEXCEPTION_POINTERS info
)
773 struct Exception_Data
*exception
;
776 switch (info
->ExceptionRecord
->ExceptionCode
)
778 case EXCEPTION_ACCESS_VIOLATION
:
779 /* If the failing address isn't maximally-aligned or if we've
780 recursed, this is a program error. */
781 if ((info
->ExceptionRecord
->ExceptionInformation
[1] & 3) != 0
784 exception
= &program_error
;
785 msg
= "EXCEPTION_ACCESS_VIOLATION";
789 /* See if the page before the faulting page is accessible. Do that
790 by trying to access it. */
792 * ((volatile char *) (info
->ExceptionRecord
->ExceptionInformation
[1]
794 exception
= &storage_error
;
795 msg
= "stack overflow (or erroneous memory access)";
799 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED
:
800 exception
= &constraint_error
;
801 msg
= "EXCEPTION_ARRAY_BOUNDS_EXCEEDED";
804 case EXCEPTION_DATATYPE_MISALIGNMENT
:
805 exception
= &constraint_error
;
806 msg
= "EXCEPTION_DATATYPE_MISALIGNMENT";
809 case EXCEPTION_FLT_DENORMAL_OPERAND
:
810 exception
= &constraint_error
;
811 msg
= "EXCEPTION_FLT_DENORMAL_OPERAND";
814 case EXCEPTION_FLT_DIVIDE_BY_ZERO
:
815 exception
= &constraint_error
;
816 msg
= "EXCEPTION_FLT_DENORMAL_OPERAND";
819 case EXCEPTION_FLT_INVALID_OPERATION
:
820 exception
= &constraint_error
;
821 msg
= "EXCEPTION_FLT_INVALID_OPERATION";
824 case EXCEPTION_FLT_OVERFLOW
:
825 exception
= &constraint_error
;
826 msg
= "EXCEPTION_FLT_OVERFLOW";
829 case EXCEPTION_FLT_STACK_CHECK
:
830 exception
= &program_error
;
831 msg
= "EXCEPTION_FLT_STACK_CHECK";
834 case EXCEPTION_FLT_UNDERFLOW
:
835 exception
= &constraint_error
;
836 msg
= "EXCEPTION_FLT_UNDERFLOW";
839 case EXCEPTION_INT_DIVIDE_BY_ZERO
:
840 exception
= &constraint_error
;
841 msg
= "EXCEPTION_INT_DIVIDE_BY_ZERO";
844 case EXCEPTION_INT_OVERFLOW
:
845 exception
= &constraint_error
;
846 msg
= "EXCEPTION_INT_OVERFLOW";
849 case EXCEPTION_INVALID_DISPOSITION
:
850 exception
= &program_error
;
851 msg
= "EXCEPTION_INVALID_DISPOSITION";
854 case EXCEPTION_NONCONTINUABLE_EXCEPTION
:
855 exception
= &program_error
;
856 msg
= "EXCEPTION_NONCONTINUABLE_EXCEPTION";
859 case EXCEPTION_PRIV_INSTRUCTION
:
860 exception
= &program_error
;
861 msg
= "EXCEPTION_PRIV_INSTRUCTION";
864 case EXCEPTION_SINGLE_STEP
:
865 exception
= &program_error
;
866 msg
= "EXCEPTION_SINGLE_STEP";
869 case EXCEPTION_STACK_OVERFLOW
:
870 exception
= &storage_error
;
871 msg
= "EXCEPTION_STACK_OVERFLOW";
875 exception
= &program_error
;
876 msg
= "unhandled signal";
880 Raise_From_Signal_Handler (exception
, msg
);
881 return 0; /* This is never reached, avoid compiler warning */
885 __gnat_install_handler (void)
887 SetUnhandledExceptionFilter (__gnat_error_handler
);
888 __gnat_handler_installed
= 1;
892 __gnat_initialize (void)
895 /* Initialize floating-point coprocessor. This call is needed because
896 the MS libraries default to 64-bit precision instead of 80-bit
897 precision, and we require the full precision for proper operation,
898 given that we have set Max_Digits etc with this in mind */
900 __gnat_init_float ();
902 /* initialize a lock for a process handle list - see a-adaint.c for the
903 implementation of __gnat_portable_no_block_spawn, __gnat_portable_wait */
907 /***************************************/
908 /* __gnat_initialize (Interix Version) */
909 /***************************************/
911 #elif defined (__INTERIX)
915 static void __gnat_error_handler (int);
918 __gnat_error_handler (int sig
)
920 struct Exception_Data
*exception
;
926 exception
= &storage_error
;
927 msg
= "stack overflow or erroneous memory access";
931 exception
= &constraint_error
;
936 exception
= &constraint_error
;
941 exception
= &program_error
;
942 msg
= "unhandled signal";
945 Raise_From_Signal_Handler (exception
, msg
);
949 __gnat_install_handler (void)
951 struct sigaction act
;
953 /* Set up signal handler to map synchronous signals to appropriate
954 exceptions. Make sure that the handler isn't interrupted by another
955 signal that might cause a scheduling event! */
957 act
.sa_handler
= __gnat_error_handler
;
959 sigemptyset (&act
.sa_mask
);
961 /* Handlers for signals besides SIGSEGV cause c974013 to hang */
962 /* sigaction (SIGILL, &act, NULL); */
963 /* sigaction (SIGABRT, &act, NULL); */
964 /* sigaction (SIGFPE, &act, NULL); */
965 /* sigaction (SIGBUS, &act, NULL); */
967 /* Do not install handlers if interrupt state is "System" */
968 if (__gnat_get_interrupt_state (SIGSEGV
) != 's')
969 sigaction (SIGSEGV
, &act
, NULL
);
971 __gnat_handler_installed
= 1;
975 __gnat_initialize (void)
977 __gnat_init_float ();
980 /**************************************/
981 /* __gnat_initialize (LynxOS Version) */
982 /**************************************/
984 #elif defined (__Lynx__)
987 __gnat_initialize (void)
989 __gnat_init_float ();
992 /*********************************/
993 /* __gnat_install_handler (Lynx) */
994 /*********************************/
997 __gnat_install_handler (void)
999 __gnat_handler_installed
= 1;
1002 /****************************/
1003 /* __gnat_initialize (OS/2) */
1004 /****************************/
1006 #elif defined (__EMX__) /* OS/2 dependent initialization */
1009 __gnat_initialize (void)
1013 /*********************************/
1014 /* __gnat_install_handler (OS/2) */
1015 /*********************************/
1018 __gnat_install_handler (void)
1020 __gnat_handler_installed
= 1;
1023 /***********************************/
1024 /* __gnat_initialize (SGI Version) */
1025 /***********************************/
1030 #include <siginfo.h>
1036 #define SIGADAABORT 48
1037 #define SIGNAL_STACK_SIZE 4096
1038 #define SIGNAL_STACK_ALIGNMENT 64
1040 struct Machine_State
1042 sigcontext_t context
;
1045 static void __gnat_error_handler (int, int, sigcontext_t
*);
1048 __gnat_error_handler (int sig
, int code
, sigcontext_t
*sc
)
1050 struct Machine_State
*mstate
;
1051 struct Exception_Data
*exception
;
1059 exception
= &program_error
;
1060 msg
= "SIGSEGV: (Invalid virtual address)";
1062 else if (code
== ENXIO
)
1064 exception
= &program_error
;
1065 msg
= "SIGSEGV: (Read beyond mapped object)";
1067 else if (code
== ENOSPC
)
1069 exception
= &program_error
; /* ??? storage_error ??? */
1070 msg
= "SIGSEGV: (Autogrow for file failed)";
1072 else if (code
== EACCES
)
1074 /* ??? Re-add smarts to further verify that we launched
1075 the stack into a guard page, not an attempt to
1076 write to .text or something */
1077 exception
= &storage_error
;
1078 msg
= "SIGSEGV: (stack overflow or erroneous memory access)";
1082 /* Just in case the OS guys did it to us again. Sometimes
1083 they fail to document all of the valid codes that are
1084 passed to signal handlers, just in case someone depends
1085 on knowing all the codes */
1086 exception
= &program_error
;
1087 msg
= "SIGSEGV: (Undocumented reason)";
1092 /* Map all bus errors to Program_Error. */
1093 exception
= &program_error
;
1098 /* Map all fpe errors to Constraint_Error. */
1099 exception
= &constraint_error
;
1104 if ((*Check_Abort_Status
) ())
1106 exception
= &_abort_signal
;
1115 /* Everything else is a Program_Error. */
1116 exception
= &program_error
;
1117 msg
= "unhandled signal";
1120 mstate
= (*Get_Machine_State_Addr
) ();
1122 memcpy ((void *) mstate
, (const void *) sc
, sizeof (sigcontext_t
));
1124 Raise_From_Signal_Handler (exception
, msg
);
1128 __gnat_install_handler (void)
1130 struct sigaction act
;
1132 /* Setup signal handler to map synchronous signals to appropriate
1133 exceptions. Make sure that the handler isn't interrupted by another
1134 signal that might cause a scheduling event! */
1136 act
.sa_handler
= __gnat_error_handler
;
1137 act
.sa_flags
= SA_NODEFER
+ SA_RESTART
;
1138 sigfillset (&act
.sa_mask
);
1139 sigemptyset (&act
.sa_mask
);
1141 /* Do not install handlers if interrupt state is "System" */
1142 if (__gnat_get_interrupt_state (SIGABRT
) != 's')
1143 sigaction (SIGABRT
, &act
, NULL
);
1144 if (__gnat_get_interrupt_state (SIGFPE
) != 's')
1145 sigaction (SIGFPE
, &act
, NULL
);
1146 if (__gnat_get_interrupt_state (SIGILL
) != 's')
1147 sigaction (SIGILL
, &act
, NULL
);
1148 if (__gnat_get_interrupt_state (SIGSEGV
) != 's')
1149 sigaction (SIGSEGV
, &act
, NULL
);
1150 if (__gnat_get_interrupt_state (SIGBUS
) != 's')
1151 sigaction (SIGBUS
, &act
, NULL
);
1152 if (__gnat_get_interrupt_state (SIGADAABORT
) != 's')
1153 sigaction (SIGADAABORT
, &act
, NULL
);
1155 __gnat_handler_installed
= 1;
1159 __gnat_initialize (void)
1163 /*************************************************/
1164 /* __gnat_initialize (Solaris and SunOS Version) */
1165 /*************************************************/
1167 #elif defined (sun) && defined (__SVR4) && !defined (__vxworks)
1170 #include <siginfo.h>
1172 static void __gnat_error_handler (int, siginfo_t
*);
1175 __gnat_error_handler (int sig
, siginfo_t
*sip
)
1177 struct Exception_Data
*exception
;
1178 static int recurse
= 0;
1181 /* If this was an explicit signal from a "kill", just resignal it. */
1182 if (SI_FROMUSER (sip
))
1184 signal (sig
, SIG_DFL
);
1185 kill (getpid(), sig
);
1188 /* Otherwise, treat it as something we handle. */
1192 /* If the problem was permissions, this is a constraint error.
1193 Likewise if the failing address isn't maximally aligned or if
1196 ??? Using a static variable here isn't task-safe, but it's
1197 much too hard to do anything else and we're just determining
1198 which exception to raise. */
1199 if (sip
->si_code
== SEGV_ACCERR
1200 || (((long) sip
->si_addr
) & 3) != 0
1203 exception
= &constraint_error
;
1208 /* See if the page before the faulting page is accessible. Do that
1209 by trying to access it. We'd like to simply try to access
1210 4096 + the faulting address, but it's not guaranteed to be
1211 the actual address, just to be on the same page. */
1214 ((long) sip
->si_addr
& - getpagesize ()))[getpagesize ()];
1215 exception
= &storage_error
;
1216 msg
= "stack overflow (or erroneous memory access)";
1221 exception
= &program_error
;
1226 exception
= &constraint_error
;
1231 exception
= &program_error
;
1232 msg
= "unhandled signal";
1237 Raise_From_Signal_Handler (exception
, msg
);
1241 __gnat_install_handler (void)
1243 struct sigaction act
;
1245 /* Set up signal handler to map synchronous signals to appropriate
1246 exceptions. Make sure that the handler isn't interrupted by another
1247 signal that might cause a scheduling event! */
1249 act
.sa_handler
= __gnat_error_handler
;
1250 act
.sa_flags
= SA_NODEFER
| SA_RESTART
| SA_SIGINFO
;
1251 sigemptyset (&act
.sa_mask
);
1253 /* Do not install handlers if interrupt state is "System" */
1254 if (__gnat_get_interrupt_state (SIGABRT
) != 's')
1255 sigaction (SIGABRT
, &act
, NULL
);
1256 if (__gnat_get_interrupt_state (SIGFPE
) != 's')
1257 sigaction (SIGFPE
, &act
, NULL
);
1258 if (__gnat_get_interrupt_state (SIGSEGV
) != 's')
1259 sigaction (SIGSEGV
, &act
, NULL
);
1260 if (__gnat_get_interrupt_state (SIGBUS
) != 's')
1261 sigaction (SIGBUS
, &act
, NULL
);
1263 __gnat_handler_installed
= 1;
1267 __gnat_initialize (void)
1271 /***********************************/
1272 /* __gnat_initialize (VMS Version) */
1273 /***********************************/
1277 /* The prehandler actually gets control first on a condition. It swaps the
1278 stack pointer and calls the handler (__gnat_error_handler). */
1279 extern long __gnat_error_prehandler (void);
1281 extern char *__gnat_error_prehandler_stack
; /* Alternate signal stack */
1283 /* Conditions that don't have an Ada exception counterpart must raise
1284 Non_Ada_Error. Since this is defined in s-auxdec, it should only be
1285 referenced by user programs, not the compiler or tools. Hence the
1289 #define Non_Ada_Error system__aux_dec__non_ada_error
1290 extern struct Exception_Data Non_Ada_Error
;
1292 #define Coded_Exception system__vms_exception_table__coded_exception
1293 extern struct Exception_Data
*Coded_Exception (int);
1296 /* Define macro symbols for the VMS conditions that become Ada exceptions.
1297 Most of these are also defined in the header file ssdef.h which has not
1298 yet been converted to be recoginized by Gnu C. Some, which couldn't be
1299 located, are assigned names based on the DEC test suite tests which
1302 #define SS$_ACCVIO 12
1303 #define SS$_DEBUG 1132
1304 #define SS$_INTDIV 1156
1305 #define SS$_HPARITH 1284
1306 #define SS$_STKOVF 1364
1307 #define SS$_RESIGNAL 2328
1308 #define MTH$_FLOOVEMAT 1475268 /* Some ACVC_21 CXA tests */
1309 #define SS$_CE24VRU 3253636 /* Write to unopened file */
1310 #define SS$_C980VTE 3246436 /* AST requests time slice */
1311 #define CMA$_EXIT_THREAD 4227492
1312 #define CMA$_EXCCOPLOS 4228108
1313 #define CMA$_ALERTED 4227460
1315 struct descriptor_s
{unsigned short len
, mbz
; char *adr
; };
1317 long __gnat_error_handler (int *, void *);
1320 __gnat_error_handler (int *sigargs
, void *mechargs
)
1322 struct Exception_Data
*exception
= 0;
1326 struct descriptor_s msgdesc
;
1327 int msg_flag
= 0x000f; /* 1 bit for each of the four message parts */
1328 unsigned short outlen
;
1330 long curr_invo_handle
;
1333 /* Resignaled condtions aren't effected by by pragma Import_Exception */
1338 case CMA$_EXIT_THREAD
:
1339 return SS$_RESIGNAL
;
1341 case SS$_DEBUG
: /* Gdb attach, resignal to merge activate gdbstub. */
1342 return SS$_RESIGNAL
;
1344 case 1409786: /* Nickerson bug #33 ??? */
1345 return SS$_RESIGNAL
;
1347 case 1381050: /* Nickerson bug #33 ??? */
1348 return SS$_RESIGNAL
;
1350 case 11829410: /* Resignalled as Use_Error for CE10VRC */
1351 return SS$_RESIGNAL
;
1356 /* See if it's an imported exception. Mask off severity bits. */
1357 exception
= Coded_Exception (sigargs
[1] & 0xfffffff8);
1362 msgdesc
.adr
= message
;
1363 SYS$
GETMSG (sigargs
[1], &outlen
, &msgdesc
, msg_flag
, 0);
1364 message
[outlen
] = 0;
1367 exception
->Name_Length
= 19;
1368 /* The full name really should be get sys$getmsg returns. ??? */
1369 exception
->Full_Name
= "IMPORTED_EXCEPTION";
1370 exception
->Import_Code
= sigargs
[1] & 0xfffffff8;
1378 if (sigargs
[3] == 0)
1380 exception
= &constraint_error
;
1381 msg
= "access zero";
1385 exception
= &storage_error
;
1386 msg
= "stack overflow (or erroneous memory access)";
1391 exception
= &storage_error
;
1392 msg
= "stack overflow";
1396 exception
= &constraint_error
;
1397 msg
= "division by zero";
1402 return SS$_RESIGNAL
; /* toplev.c handles for compiler */
1405 exception
= &constraint_error
;
1406 msg
= "arithmetic error";
1411 case MTH$_FLOOVEMAT
:
1412 exception
= &constraint_error
;
1413 msg
= "floating overflow in math library";
1417 exception
= &constraint_error
;
1422 exception
= &program_error
;
1428 exception
= &program_error
;
1430 /* User programs expect Non_Ada_Error to be raised, reference
1431 DEC Ada test CXCONDHAN. */
1432 exception
= &Non_Ada_Error
;
1436 msgdesc
.adr
= message
;
1437 SYS$
GETMSG (sigargs
[1], &outlen
, &msgdesc
, msg_flag
, 0);
1438 message
[outlen
] = 0;
1443 mstate
= (long *) (*Get_Machine_State_Addr
) ();
1446 LIB$
GET_CURR_INVO_CONTEXT (&curr_icb
);
1447 LIB$
GET_PREV_INVO_CONTEXT (&curr_icb
);
1448 LIB$
GET_PREV_INVO_CONTEXT (&curr_icb
);
1449 curr_invo_handle
= LIB$
GET_INVO_HANDLE (&curr_icb
);
1450 *mstate
= curr_invo_handle
;
1452 Raise_From_Signal_Handler (exception
, msg
);
1456 __gnat_install_handler (void)
1461 c
= (char *) xmalloc (2049);
1463 __gnat_error_prehandler_stack
= &c
[2048];
1465 /* __gnat_error_prehandler is an assembly function. */
1466 SYS$
SETEXV (1, __gnat_error_prehandler
, 3, &prvhnd
);
1467 __gnat_handler_installed
= 1;
1471 __gnat_initialize(void)
1475 /*************************************************/
1476 /* __gnat_initialize (FreeBSD version) */
1477 /*************************************************/
1479 #elif defined (__FreeBSD__)
1485 __gnat_error_handler (sig
, code
, sc
)
1488 struct sigcontext
*sc
;
1490 struct Exception_Data
*exception
;
1496 exception
= &constraint_error
;
1501 exception
= &constraint_error
;
1506 exception
= &storage_error
;
1507 msg
= "stack overflow or erroneous memory access";
1511 exception
= &constraint_error
;
1516 exception
= &program_error
;
1517 msg
= "unhandled signal";
1520 Raise_From_Signal_Handler (exception
, msg
);
1524 __gnat_install_handler ()
1526 struct sigaction act
;
1528 /* Set up signal handler to map synchronous signals to appropriate
1529 exceptions. Make sure that the handler isn't interrupted by another
1530 signal that might cause a scheduling event! */
1532 act
.sa_handler
= __gnat_error_handler
;
1533 act
.sa_flags
= SA_NODEFER
| SA_RESTART
;
1534 (void) sigemptyset (&act
.sa_mask
);
1536 (void) sigaction (SIGILL
, &act
, NULL
);
1537 (void) sigaction (SIGFPE
, &act
, NULL
);
1538 (void) sigaction (SIGSEGV
, &act
, NULL
);
1539 (void) sigaction (SIGBUS
, &act
, NULL
);
1542 void __gnat_init_float ();
1545 __gnat_initialize ()
1547 __gnat_install_handler ();
1549 /* XXX - Initialize floating-point coprocessor. This call is
1550 needed because FreeBSD defaults to 64-bit precision instead
1551 of 80-bit precision? We require the full precision for
1552 proper operation, given that we have set Max_Digits etc
1553 with this in mind */
1554 __gnat_init_float ();
1557 /***************************************/
1558 /* __gnat_initialize (VXWorks Version) */
1559 /***************************************/
1561 #elif defined(__vxworks)
1564 #include <taskLib.h>
1568 extern int __gnat_inum_to_ivec (int);
1569 static void __gnat_error_handler (int, int, struct sigcontext
*);
1570 void __gnat_map_signal (int);
1572 #ifndef __alpha_vxworks
1574 /* getpid is used by s-parint.adb, but is not defined by VxWorks, except
1577 extern long getpid (void);
1582 return taskIdSelf ();
1586 /* This is needed by the GNAT run time to handle Vxworks interrupts */
1588 __gnat_inum_to_ivec (int num
)
1590 return INUM_TO_IVEC (num
);
1593 /* Exported to 5zintman.adb in order to handle different signal
1594 to exception mappings in different VxWorks versions */
1596 __gnat_map_signal (int sig
)
1598 struct Exception_Data
*exception
;
1604 exception
= &constraint_error
;
1608 exception
= &constraint_error
;
1612 exception
= &program_error
;
1617 exception
= &storage_error
;
1618 msg
= "SIGBUS: possible stack overflow";
1620 exception
= &program_error
;
1625 exception
= &program_error
;
1626 msg
= "unhandled signal";
1629 Raise_From_Signal_Handler (exception
, msg
);
1633 __gnat_error_handler (int sig
, int code
, struct sigcontext
*sc
)
1638 /* VxWorks will always mask out the signal during the signal handler and
1639 will reenable it on a longjmp. GNAT does not generate a longjmp to
1640 return from a signal handler so the signal will still be masked unless
1642 sigprocmask (SIG_SETMASK
, NULL
, &mask
);
1643 sigdelset (&mask
, sig
);
1644 sigprocmask (SIG_SETMASK
, &mask
, NULL
);
1646 /* VxWorks will suspend the task when it gets a hardware exception. We
1647 take the liberty of resuming the task for the application. */
1648 if (taskIsSuspended (taskIdSelf ()) != 0)
1649 taskResume (taskIdSelf ());
1651 __gnat_map_signal (sig
);
1656 __gnat_install_handler (void)
1658 struct sigaction act
;
1660 /* Setup signal handler to map synchronous signals to appropriate
1661 exceptions. Make sure that the handler isn't interrupted by another
1662 signal that might cause a scheduling event! */
1664 act
.sa_handler
= __gnat_error_handler
;
1665 act
.sa_flags
= SA_SIGINFO
| SA_ONSTACK
;
1666 sigemptyset (&act
.sa_mask
);
1668 /* For VxWorks, install all signal handlers, since pragma Interrupt_State
1669 applies to vectored hardware interrupts, not signals */
1670 sigaction (SIGFPE
, &act
, NULL
);
1671 sigaction (SIGILL
, &act
, NULL
);
1672 sigaction (SIGSEGV
, &act
, NULL
);
1673 sigaction (SIGBUS
, &act
, NULL
);
1675 __gnat_handler_installed
= 1;
1678 #define HAVE_GNAT_INIT_FLOAT
1681 __gnat_init_float (void)
1683 /* Disable overflow/underflow exceptions on the PPC processor, this is needed
1684 to get correct Ada semantic. */
1685 #if defined (_ARCH_PPC) && !defined (_SOFT_FLOAT)
1690 /* Similarily for sparc64. Achieved by masking bits in the Trap Enable Mask
1691 field of the Floating-point Status Register (see the Sparc Architecture
1692 Manual Version 9, p 48). */
1693 #if defined (sparc64)
1695 #define FSR_TEM_NVM (1 << 27) /* Invalid operand */
1696 #define FSR_TEM_OFM (1 << 26) /* Overflow */
1697 #define FSR_TEM_UFM (1 << 25) /* Underflow */
1698 #define FSR_TEM_DZM (1 << 24) /* Division by Zero */
1699 #define FSR_TEM_NXM (1 << 23) /* Inexact result */
1703 __asm__("st %%fsr, %0" : "=m" (fsr
));
1704 fsr
&= ~(FSR_TEM_OFM
| FSR_TEM_UFM
);
1705 __asm__("ld %0, %%fsr" : : "m" (fsr
));
1711 __gnat_initialize (void)
1713 __gnat_init_float ();
1715 /* Assume an environment task stack size of 20kB.
1717 Using a constant is necessary because we do not want each Ada application
1718 to depend on the optional taskShow library,
1719 which is required to get the actual stack information.
1721 The consequence of this is that with -fstack-check
1722 the environment task must have an actual stack size
1723 of at least 20kB and the usable size will be about 14kB.
1726 __gnat_set_stack_size (14336);
1727 /* Allow some head room for the stack checking code, and for
1728 stack space consumed during initialization */
1731 /********************************/
1732 /* __gnat_initialize for NetBSD */
1733 /********************************/
1735 #elif defined(__NetBSD__)
1741 __gnat_error_handler (int sig
)
1743 struct Exception_Data
*exception
;
1749 exception
= &constraint_error
;
1753 exception
= &constraint_error
;
1757 exception
= &storage_error
;
1758 msg
= "stack overflow or erroneous memory access";
1761 exception
= &constraint_error
;
1765 exception
= &program_error
;
1766 msg
= "unhandled signal";
1769 Raise_From_Signal_Handler(exception
, msg
);
1773 __gnat_install_handler(void)
1775 struct sigaction act
;
1777 act
.sa_handler
= __gnat_error_handler
;
1778 act
.sa_flags
= SA_NODEFER
| SA_RESTART
;
1779 sigemptyset (&act
.sa_mask
);
1781 /* Do not install handlers if interrupt state is "System" */
1782 if (__gnat_get_interrupt_state (SIGFPE
) != 's')
1783 sigaction (SIGFPE
, &act
, NULL
);
1784 if (__gnat_get_interrupt_state (SIGILL
) != 's')
1785 sigaction (SIGILL
, &act
, NULL
);
1786 if (__gnat_get_interrupt_state (SIGSEGV
) != 's')
1787 sigaction (SIGSEGV
, &act
, NULL
);
1788 if (__gnat_get_interrupt_state (SIGBUS
) != 's')
1789 sigaction (SIGBUS
, &act
, NULL
);
1791 __gnat_handler_installed
= 1;
1795 __gnat_initialize (void)
1797 __gnat_install_handler ();
1798 __gnat_init_float ();
1803 /* For all other versions of GNAT, the initialize routine and handler
1804 installation do nothing */
1806 /***************************************/
1807 /* __gnat_initialize (Default Version) */
1808 /***************************************/
1811 __gnat_initialize (void)
1815 /********************************************/
1816 /* __gnat_install_handler (Default Version) */
1817 /********************************************/
1820 __gnat_install_handler (void)
1822 __gnat_handler_installed
= 1;
1827 /*********************/
1828 /* __gnat_init_float */
1829 /*********************/
1831 /* This routine is called as each process thread is created, for possible
1832 initialization of the FP processor. This version is used under INTERIX,
1833 WIN32 and could be used under OS/2 */
1835 #if defined (_WIN32) || defined (__INTERIX) || defined (__EMX__) \
1836 || defined (__Lynx__) || defined(__NetBSD__) || defined(__FreeBSD__)
1838 #define HAVE_GNAT_INIT_FLOAT
1841 __gnat_init_float (void)
1843 #if defined (__i386__) || defined (i386)
1845 /* This is used to properly initialize the FPU on an x86 for each
1850 #endif /* Defined __i386__ */
1854 #ifndef HAVE_GNAT_INIT_FLOAT
1856 /* All targets without a specific __gnat_init_float will use an empty one */
1858 __gnat_init_float (void)