1 /****************************************************************************
3 * GNAT COMPILER COMPONENTS *
7 * C Implementation File *
9 * Copyright (C) 1992-2008, 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, 51 Franklin Street, Fifth Floor, *
20 * Boston, MA 02110-1301, 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.
34 A major part of the functionality 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 catch the resulting signals that come
40 from these probes failing (i.e. touching protected pages). */
42 /* This file should be kept synchronized with 2sinit.ads, 2sinit.adb,
43 s-init-ae653-cert.adb and s-init-xi-sparc.adb. All these files implement
44 the required functionality for different targets. */
46 /* The following include is here to meet the published VxWorks requirement
47 that the __vxworks header appear before any other include. */
57 /* We don't have libiberty, so us malloc. */
58 #define xmalloc(S) malloc (S)
67 extern void __gnat_raise_program_error (const char *, int);
69 /* Addresses of exception data blocks for predefined exceptions. Tasking_Error
70 is not used in this unit, and the abort signal is only used on IRIX. */
71 extern struct Exception_Data constraint_error;
72 extern struct Exception_Data numeric_error;
73 extern struct Exception_Data program_error;
74 extern struct Exception_Data storage_error;
76 /* For the Cert run time we use the regular raise exception routine because
77 Raise_From_Signal_Handler is not available. */
79 #define Raise_From_Signal_Handler \
80 __gnat_raise_exception
81 extern void Raise_From_Signal_Handler (struct Exception_Data *, const char *);
83 #define Raise_From_Signal_Handler \
84 ada__exceptions__raise_from_signal_handler
85 extern void Raise_From_Signal_Handler (struct Exception_Data *, const char *);
88 /* Global values computed by the binder. */
89 int __gl_main_priority = -1;
90 int __gl_time_slice_val = -1;
91 char __gl_wc_encoding = 'n';
92 char __gl_locking_policy = ' ';
93 char __gl_queuing_policy = ' ';
94 char __gl_task_dispatching_policy = ' ';
95 char *__gl_priority_specific_dispatching = 0;
96 int __gl_num_specific_dispatching = 0;
97 char *__gl_interrupt_states = 0;
98 int __gl_num_interrupt_states = 0;
99 int __gl_unreserve_all_interrupts = 0;
100 int __gl_exception_tracebacks = 0;
101 int __gl_zero_cost_exceptions = 0;
102 int __gl_detect_blocking = 0;
103 int __gl_default_stack_size = -1;
104 int __gl_leap_seconds_support = 0;
106 /* Indication of whether synchronous signal handler has already been
107 installed by a previous call to adainit. */
108 int __gnat_handler_installed = 0;
111 int __gnat_inside_elab_final_code = 0;
112 /* ??? This variable is obsolete since 2001-08-29 but is kept to allow
113 bootstrap from old GNAT versions (< 3.15). */
116 /* HAVE_GNAT_INIT_FLOAT must be set on every targets where a __gnat_init_float
117 is defined. If this is not set then a void implementation will be defined
118 at the end of this unit. */
119 #undef HAVE_GNAT_INIT_FLOAT
121 /******************************/
122 /* __gnat_get_interrupt_state */
123 /******************************/
125 char __gnat_get_interrupt_state (int);
127 /* This routine is called from the runtime as needed to determine the state
128 of an interrupt, as set by an Interrupt_State pragma appearing anywhere
129 in the current partition. The input argument is the interrupt number,
130 and the result is one of the following:
132 'n' this interrupt not set by any Interrupt_State pragma
133 'u' Interrupt_State pragma set state to User
134 'r' Interrupt_State pragma set state to Runtime
135 's' Interrupt_State pragma set state to System */
138 __gnat_get_interrupt_state (int intrup)
140 if (intrup >= __gl_num_interrupt_states)
143 return __gl_interrupt_states [intrup];
146 /***********************************/
147 /* __gnat_get_specific_dispatching */
148 /***********************************/
150 char __gnat_get_specific_dispatching (int);
152 /* This routine is called from the runtime as needed to determine the
153 priority specific dispatching policy, as set by a
154 Priority_Specific_Dispatching pragma appearing anywhere in the current
155 partition. The input argument is the priority number, and the result
156 is the upper case first character of the policy name, e.g. 'F' for
157 FIFO_Within_Priorities. A space ' ' is returned if no
158 Priority_Specific_Dispatching pragma is used in the partition. */
161 __gnat_get_specific_dispatching (int priority)
163 if (__gl_num_specific_dispatching == 0)
165 else if (priority >= __gl_num_specific_dispatching)
168 return __gl_priority_specific_dispatching [priority];
173 /**********************/
174 /* __gnat_set_globals */
175 /**********************/
177 /* This routine is kept for bootstrapping purposes, since the binder generated
178 file now sets the __gl_* variables directly. */
181 __gnat_set_globals ()
194 #include <sys/time.h>
196 /* Some versions of AIX don't define SA_NODEFER. */
200 #endif /* SA_NODEFER */
202 /* Versions of AIX before 4.3 don't have nanosleep but provide
205 #ifndef _AIXVERSION_430
207 extern int nanosleep (struct timestruc_t *, struct timestruc_t *);
210 nanosleep (struct timestruc_t *Rqtp, struct timestruc_t *Rmtp)
212 return nsleep (Rqtp, Rmtp);
215 #endif /* _AIXVERSION_430 */
217 static void __gnat_error_handler (int sig, siginfo_t * si, void * uc);
219 /* __gnat_adjust_context_for_raise - see comments along with the default
220 version later in this file. */
223 __gnat_adjust_context_for_raise (int signo ATTRIBUTE_UNUSED, void *ucontext)
225 /* We need to adjust the "Instruction Address Register" value, part of a
226 'struct mstsave' wrapped as a jumpbuf in the mcontext field designated by
227 the signal data pointer we get. See sys/context.h + sys/mstsave.h */
229 mcontext_t *mcontext = &((ucontext_t *) ucontext)->uc_mcontext;
230 mcontext->jmp_context.iar++;
233 #define HAVE_GNAT_ADJUST_CONTEXT_FOR_RAISE
236 __gnat_error_handler (int sig, siginfo_t * si, void * uc)
238 struct Exception_Data *exception;
244 /* FIXME: we need to detect the case of a *real* SIGSEGV. */
245 exception = &storage_error;
246 msg = "stack overflow or erroneous memory access";
250 exception = &constraint_error;
255 exception = &constraint_error;
260 exception = &program_error;
261 msg = "unhandled signal";
264 __gnat_adjust_context_for_raise (sig, uc);
265 Raise_From_Signal_Handler (exception, msg);
269 __gnat_install_handler (void)
271 struct sigaction act;
273 /* Set up signal handler to map synchronous signals to appropriate
274 exceptions. Make sure that the handler isn't interrupted by another
275 signal that might cause a scheduling event! */
277 act.sa_flags = SA_NODEFER | SA_RESTART | SA_SIGINFO;
278 act.sa_sigaction = __gnat_error_handler;
279 sigemptyset (&act.sa_mask);
281 /* Do not install handlers if interrupt state is "System". */
282 if (__gnat_get_interrupt_state (SIGABRT) != 's')
283 sigaction (SIGABRT, &act, NULL);
284 if (__gnat_get_interrupt_state (SIGFPE) != 's')
285 sigaction (SIGFPE, &act, NULL);
286 if (__gnat_get_interrupt_state (SIGILL) != 's')
287 sigaction (SIGILL, &act, NULL);
288 if (__gnat_get_interrupt_state (SIGSEGV) != 's')
289 sigaction (SIGSEGV, &act, NULL);
290 if (__gnat_get_interrupt_state (SIGBUS) != 's')
291 sigaction (SIGBUS, &act, NULL);
293 __gnat_handler_installed = 1;
300 #elif defined(__alpha__) && defined(__osf__)
303 #include <sys/siginfo.h>
305 static void __gnat_error_handler (int, siginfo_t *, struct sigcontext *);
306 extern char *__gnat_get_code_loc (struct sigcontext *);
307 extern void __gnat_set_code_loc (struct sigcontext *, char *);
308 extern size_t __gnat_machine_state_length (void);
310 /* __gnat_adjust_context_for_raise - see comments along with the default
311 version later in this file. */
313 #define HAVE_GNAT_ADJUST_CONTEXT_FOR_RAISE
316 __gnat_adjust_context_for_raise (int signo, void *context)
318 struct sigcontext * sigcontext = (struct sigcontext *) context;
320 /* The fallback code fetches the faulting insn address from sc_pc, so
321 adjust that when need be. For SIGFPE, the required adjustment depends
322 on the trap shadow situation (see man ieee). */
325 /* ??? We never adjust here, considering that sc_pc always
326 designates the instruction following the one which trapped.
327 This is not necessarily true but corresponds to what we have
331 sigcontext->sc_pc ++;
336 (int sig, siginfo_t *sip, struct sigcontext *context)
338 struct Exception_Data *exception;
339 static int recurse = 0;
342 /* Adjusting is required for every fault context, so adjust for this one
343 now, before we possibly trigger a recursive fault below. */
344 __gnat_adjust_context_for_raise (sig, context);
346 /* If this was an explicit signal from a "kill", just resignal it. */
347 if (SI_FROMUSER (sip))
349 signal (sig, SIG_DFL);
350 kill (getpid(), sig);
353 /* Otherwise, treat it as something we handle. */
357 /* If the problem was permissions, this is a constraint error.
358 Likewise if the failing address isn't maximally aligned or if
361 ??? Using a static variable here isn't task-safe, but it's
362 much too hard to do anything else and we're just determining
363 which exception to raise. */
364 if (sip->si_code == SEGV_ACCERR
365 || (((long) sip->si_addr) & 3) != 0
368 exception = &constraint_error;
373 /* See if the page before the faulting page is accessible. Do that
374 by trying to access it. We'd like to simply try to access
375 4096 + the faulting address, but it's not guaranteed to be
376 the actual address, just to be on the same page. */
379 ((long) sip->si_addr & - getpagesize ()))[getpagesize ()];
380 msg = "stack overflow (or erroneous memory access)";
381 exception = &storage_error;
386 exception = &program_error;
391 exception = &constraint_error;
396 exception = &program_error;
397 msg = "unhandled signal";
401 Raise_From_Signal_Handler (exception, (char *) msg);
405 __gnat_install_handler (void)
407 struct sigaction act;
409 /* Setup signal handler to map synchronous signals to appropriate
410 exceptions. Make sure that the handler isn't interrupted by another
411 signal that might cause a scheduling event! */
413 act.sa_handler = (void (*) (int)) __gnat_error_handler;
414 act.sa_flags = SA_RESTART | SA_NODEFER | SA_SIGINFO;
415 sigemptyset (&act.sa_mask);
417 /* Do not install handlers if interrupt state is "System". */
418 if (__gnat_get_interrupt_state (SIGABRT) != 's')
419 sigaction (SIGABRT, &act, NULL);
420 if (__gnat_get_interrupt_state (SIGFPE) != 's')
421 sigaction (SIGFPE, &act, NULL);
422 if (__gnat_get_interrupt_state (SIGILL) != 's')
423 sigaction (SIGILL, &act, NULL);
424 if (__gnat_get_interrupt_state (SIGSEGV) != 's')
425 sigaction (SIGSEGV, &act, NULL);
426 if (__gnat_get_interrupt_state (SIGBUS) != 's')
427 sigaction (SIGBUS, &act, NULL);
429 __gnat_handler_installed = 1;
432 /* Routines called by s-mastop-tru64.adb. */
437 __gnat_get_code_loc (struct sigcontext *context)
439 return (char *) context->sc_pc;
443 __gnat_set_code_loc (struct sigcontext *context, char *pc)
445 context->sc_pc = (long) pc;
449 __gnat_machine_state_length (void)
451 return sizeof (struct sigcontext);
458 #elif defined (__hpux__)
461 #include <sys/ucontext.h>
464 __gnat_error_handler (int sig, siginfo_t *siginfo, void *ucontext);
466 #if defined (__hppa__)
468 /* __gnat_adjust_context_for_raise - see comments along with the default
469 version later in this file. */
471 #define HAVE_GNAT_ADJUST_CONTEXT_FOR_RAISE
474 __gnat_adjust_context_for_raise (int signo ATTRIBUTE_UNUSED, void *ucontext)
476 mcontext_t *mcontext = &((ucontext_t *) ucontext)->uc_mcontext;
478 if (UseWideRegs (mcontext))
479 mcontext->ss_wide.ss_32.ss_pcoq_head_lo ++;
481 mcontext->ss_narrow.ss_pcoq_head ++;
488 (int sig, siginfo_t *siginfo ATTRIBUTE_UNUSED, void *ucontext)
490 struct Exception_Data *exception;
496 /* FIXME: we need to detect the case of a *real* SIGSEGV. */
497 exception = &storage_error;
498 msg = "stack overflow or erroneous memory access";
502 exception = &constraint_error;
507 exception = &constraint_error;
512 exception = &program_error;
513 msg = "unhandled signal";
516 __gnat_adjust_context_for_raise (sig, ucontext);
518 Raise_From_Signal_Handler (exception, msg);
521 /* This must be in keeping with System.OS_Interface.Alternate_Stack_Size. */
522 #if defined (__hppa__)
523 char __gnat_alternate_stack[16 * 1024]; /* 2 * SIGSTKSZ */
525 char __gnat_alternate_stack[128 * 1024]; /* MINSIGSTKSZ */
529 __gnat_install_handler (void)
531 struct sigaction act;
533 /* Set up signal handler to map synchronous signals to appropriate
534 exceptions. Make sure that the handler isn't interrupted by another
535 signal that might cause a scheduling event! Also setup an alternate
536 stack region for the handler execution so that stack overflows can be
537 handled properly, avoiding a SEGV generation from stack usage by the
541 stack.ss_sp = __gnat_alternate_stack;
542 stack.ss_size = sizeof (__gnat_alternate_stack);
544 sigaltstack (&stack, NULL);
546 act.sa_sigaction = __gnat_error_handler;
547 act.sa_flags = SA_NODEFER | SA_RESTART | SA_SIGINFO;
548 sigemptyset (&act.sa_mask);
550 /* Do not install handlers if interrupt state is "System". */
551 if (__gnat_get_interrupt_state (SIGABRT) != 's')
552 sigaction (SIGABRT, &act, NULL);
553 if (__gnat_get_interrupt_state (SIGFPE) != 's')
554 sigaction (SIGFPE, &act, NULL);
555 if (__gnat_get_interrupt_state (SIGILL) != 's')
556 sigaction (SIGILL, &act, NULL);
557 if (__gnat_get_interrupt_state (SIGBUS) != 's')
558 sigaction (SIGBUS, &act, NULL);
559 act.sa_flags |= SA_ONSTACK;
560 if (__gnat_get_interrupt_state (SIGSEGV) != 's')
561 sigaction (SIGSEGV, &act, NULL);
563 __gnat_handler_installed = 1;
566 /*********************/
567 /* GNU/Linux Section */
568 /*********************/
570 #elif defined (linux) && (defined (i386) || defined (__x86_64__) \
571 || defined (__ia64__))
575 #define __USE_GNU 1 /* required to get REG_EIP/RIP from glibc's ucontext.h */
576 #include <sys/ucontext.h>
578 /* GNU/Linux, which uses glibc, does not define NULL in included
582 #define NULL ((void *) 0)
587 /* MaRTE OS provides its own version of sigaction, sigfillset, and
588 sigemptyset (overriding these symbol names). We want to make sure that
589 the versions provided by the underlying C library are used here (these
590 versions are renamed by MaRTE to linux_sigaction, fake_linux_sigfillset,
591 and fake_linux_sigemptyset, respectively). The MaRTE library will not
592 always be present (it will not be linked if no tasking constructs are
593 used), so we use the weak symbol mechanism to point always to the symbols
594 defined within the C library. */
596 #pragma weak linux_sigaction
597 int linux_sigaction (int signum, const struct sigaction *act,
598 struct sigaction *oldact) {
599 return sigaction (signum, act, oldact);
601 #define sigaction(signum, act, oldact) linux_sigaction (signum, act, oldact)
603 #pragma weak fake_linux_sigfillset
604 void fake_linux_sigfillset (sigset_t *set) {
607 #define sigfillset(set) fake_linux_sigfillset (set)
609 #pragma weak fake_linux_sigemptyset
610 void fake_linux_sigemptyset (sigset_t *set) {
613 #define sigemptyset(set) fake_linux_sigemptyset (set)
617 static void __gnat_error_handler (int, siginfo_t *siginfo, void *ucontext);
619 /* __gnat_adjust_context_for_raise - see comments along with the default
620 version later in this file. */
622 #define HAVE_GNAT_ADJUST_CONTEXT_FOR_RAISE
625 __gnat_adjust_context_for_raise (int signo ATTRIBUTE_UNUSED, void *ucontext)
627 mcontext_t *mcontext = &((ucontext_t *) ucontext)->uc_mcontext;
629 /* On the i386 and x86-64 architectures, stack checking is performed by
630 means of probes with moving stack pointer, that is to say the probed
631 address is always the value of the stack pointer. Upon hitting the
632 guard page, the stack pointer therefore points to an inaccessible
633 address and an alternate signal stack is needed to run the handler.
634 But there is an additional twist: on these architectures, the EH
635 return code writes the address of the handler at the target CFA's
636 value on the stack before doing the jump. As a consequence, if
637 there is an active handler in the frame whose stack has overflowed,
638 the stack pointer must nevertheless point to an accessible address
639 by the time the EH return is executed.
641 We therefore adjust the saved value of the stack pointer by the size
642 of one page, in order to make sure that it points to an accessible
643 address in case it's used as the target CFA. The stack checking code
644 guarantees that this page is unused by the time this happens. */
647 unsigned long pattern = *(unsigned long *)mcontext->gregs[REG_EIP];
648 /* The pattern is "orl $0x0,(%esp)" for a probe in 32-bit mode. */
649 if (signo == SIGSEGV && pattern == 0x00240c83)
650 mcontext->gregs[REG_ESP] += 4096;
651 mcontext->gregs[REG_EIP]++;
652 #elif defined (__x86_64__)
653 unsigned long pattern = *(unsigned long *)mcontext->gregs[REG_RIP];
654 /* The pattern is "orq $0x0,(%rsp)" for a probe in 64-bit mode. */
655 if (signo == SIGSEGV && (pattern & 0xffffffffff) == 0x00240c8348)
656 mcontext->gregs[REG_RSP] += 4096;
657 mcontext->gregs[REG_RIP]++;
658 #elif defined (__ia64__)
664 __gnat_error_handler (int sig,
665 siginfo_t *siginfo ATTRIBUTE_UNUSED,
668 struct Exception_Data *exception;
670 static int recurse = 0;
675 /* If the problem was permissions, this is a constraint error.
676 Likewise if the failing address isn't maximally aligned or if
679 ??? Using a static variable here isn't task-safe, but it's
680 much too hard to do anything else and we're just determining
681 which exception to raise. */
684 exception = &constraint_error;
689 /* Here we would like a discrimination test to see whether the
690 page before the faulting address is accessible. Unfortunately
691 Linux seems to have no way of giving us the faulting address.
693 In versions of a-init.c before 1.95, we had a test of the page
694 before the stack pointer using:
698 ((long) info->esp_at_signal & - getpagesize ()))[getpagesize ()];
700 but that's wrong, since it tests the stack pointer location, and
701 the current stack probe code does not move the stack pointer
702 until all probes succeed.
704 For now we simply do not attempt any discrimination at all. Note
705 that this is quite acceptable, since a "real" SIGSEGV can only
706 occur as the result of an erroneous program. */
708 msg = "stack overflow (or erroneous memory access)";
709 exception = &storage_error;
714 exception = &constraint_error;
719 exception = &constraint_error;
724 exception = &program_error;
725 msg = "unhandled signal";
729 /* We adjust the interrupted context here (and not in the
730 MD_FALLBACK_FRAME_STATE_FOR macro) because recent versions of the Native
731 POSIX Thread Library (NPTL) are compiled with DWARF-2 unwind information,
732 and hence the later macro is never executed for signal frames. */
734 __gnat_adjust_context_for_raise (sig, ucontext);
736 Raise_From_Signal_Handler (exception, msg);
739 #if defined (i386) || defined (__x86_64__)
740 /* This must be in keeping with System.OS_Interface.Alternate_Stack_Size. */
741 char __gnat_alternate_stack[16 * 1024]; /* 2 * SIGSTKSZ */
745 __gnat_install_handler (void)
747 struct sigaction act;
749 /* Set up signal handler to map synchronous signals to appropriate
750 exceptions. Make sure that the handler isn't interrupted by another
751 signal that might cause a scheduling event! Also setup an alternate
752 stack region for the handler execution so that stack overflows can be
753 handled properly, avoiding a SEGV generation from stack usage by the
756 #if defined (i386) || defined (__x86_64__)
758 stack.ss_sp = __gnat_alternate_stack;
759 stack.ss_size = sizeof (__gnat_alternate_stack);
761 sigaltstack (&stack, NULL);
764 act.sa_sigaction = __gnat_error_handler;
765 act.sa_flags = SA_NODEFER | SA_RESTART | SA_SIGINFO;
766 sigemptyset (&act.sa_mask);
768 /* Do not install handlers if interrupt state is "System". */
769 if (__gnat_get_interrupt_state (SIGABRT) != 's')
770 sigaction (SIGABRT, &act, NULL);
771 if (__gnat_get_interrupt_state (SIGFPE) != 's')
772 sigaction (SIGFPE, &act, NULL);
773 if (__gnat_get_interrupt_state (SIGILL) != 's')
774 sigaction (SIGILL, &act, NULL);
775 if (__gnat_get_interrupt_state (SIGBUS) != 's')
776 sigaction (SIGBUS, &act, NULL);
777 #if defined (i386) || defined (__x86_64__)
778 act.sa_flags |= SA_ONSTACK;
780 if (__gnat_get_interrupt_state (SIGSEGV) != 's')
781 sigaction (SIGSEGV, &act, NULL);
783 __gnat_handler_installed = 1;
799 #define SIGADAABORT 48
800 #define SIGNAL_STACK_SIZE 4096
801 #define SIGNAL_STACK_ALIGNMENT 64
803 #define Check_Abort_Status \
804 system__soft_links__check_abort_status
805 extern int (*Check_Abort_Status) (void);
807 extern struct Exception_Data _abort_signal;
809 static void __gnat_error_handler (int, int, sigcontext_t *);
811 /* We are not setting the SA_SIGINFO bit in the sigaction flags when
812 connecting that handler, with the effects described in the sigaction
816 If cleared and the signal is caught, the first argument is
817 also the signal number but the second argument is the signal
818 code identifying the cause of the signal. The third argument
819 points to a sigcontext_t structure containing the receiving
820 process's context when the signal was delivered. */
823 __gnat_error_handler (int sig, int code, sigcontext_t *sc ATTRIBUTE_UNUSED)
825 struct Exception_Data *exception;
833 exception = &program_error;
834 msg = "SIGSEGV: (Invalid virtual address)";
836 else if (code == ENXIO)
838 exception = &program_error;
839 msg = "SIGSEGV: (Read beyond mapped object)";
841 else if (code == ENOSPC)
843 exception = &program_error; /* ??? storage_error ??? */
844 msg = "SIGSEGV: (Autogrow for file failed)";
846 else if (code == EACCES || code == EEXIST)
848 /* ??? We handle stack overflows here, some of which do trigger
849 SIGSEGV + EEXIST on Irix 6.5 although EEXIST is not part of
850 the documented valid codes for SEGV in the signal(5) man
853 /* ??? Re-add smarts to further verify that we launched
854 the stack into a guard page, not an attempt to
855 write to .text or something. */
856 exception = &storage_error;
857 msg = "SIGSEGV: (stack overflow or erroneous memory access)";
861 /* Just in case the OS guys did it to us again. Sometimes
862 they fail to document all of the valid codes that are
863 passed to signal handlers, just in case someone depends
864 on knowing all the codes. */
865 exception = &program_error;
866 msg = "SIGSEGV: (Undocumented reason)";
871 /* Map all bus errors to Program_Error. */
872 exception = &program_error;
877 /* Map all fpe errors to Constraint_Error. */
878 exception = &constraint_error;
883 if ((*Check_Abort_Status) ())
885 exception = &_abort_signal;
894 /* Everything else is a Program_Error. */
895 exception = &program_error;
896 msg = "unhandled signal";
899 Raise_From_Signal_Handler (exception, msg);
903 __gnat_install_handler (void)
905 struct sigaction act;
907 /* Setup signal handler to map synchronous signals to appropriate
908 exceptions. Make sure that the handler isn't interrupted by another
909 signal that might cause a scheduling event! */
911 act.sa_handler = __gnat_error_handler;
912 act.sa_flags = SA_NODEFER + SA_RESTART;
913 sigfillset (&act.sa_mask);
914 sigemptyset (&act.sa_mask);
916 /* Do not install handlers if interrupt state is "System". */
917 if (__gnat_get_interrupt_state (SIGABRT) != 's')
918 sigaction (SIGABRT, &act, NULL);
919 if (__gnat_get_interrupt_state (SIGFPE) != 's')
920 sigaction (SIGFPE, &act, NULL);
921 if (__gnat_get_interrupt_state (SIGILL) != 's')
922 sigaction (SIGILL, &act, NULL);
923 if (__gnat_get_interrupt_state (SIGSEGV) != 's')
924 sigaction (SIGSEGV, &act, NULL);
925 if (__gnat_get_interrupt_state (SIGBUS) != 's')
926 sigaction (SIGBUS, &act, NULL);
927 if (__gnat_get_interrupt_state (SIGADAABORT) != 's')
928 sigaction (SIGADAABORT, &act, NULL);
930 __gnat_handler_installed = 1;
933 /*******************/
935 /*******************/
937 #elif defined (__Lynx__)
943 __gnat_error_handler (int sig)
945 struct Exception_Data *exception;
951 exception = &constraint_error;
955 exception = &constraint_error;
959 exception = &storage_error;
960 msg = "stack overflow or erroneous memory access";
963 exception = &constraint_error;
967 exception = &program_error;
968 msg = "unhandled signal";
971 Raise_From_Signal_Handler(exception, msg);
975 __gnat_install_handler(void)
977 struct sigaction act;
979 act.sa_handler = __gnat_error_handler;
981 sigemptyset (&act.sa_mask);
983 /* Do not install handlers if interrupt state is "System". */
984 if (__gnat_get_interrupt_state (SIGFPE) != 's')
985 sigaction (SIGFPE, &act, NULL);
986 if (__gnat_get_interrupt_state (SIGILL) != 's')
987 sigaction (SIGILL, &act, NULL);
988 if (__gnat_get_interrupt_state (SIGSEGV) != 's')
989 sigaction (SIGSEGV, &act, NULL);
990 if (__gnat_get_interrupt_state (SIGBUS) != 's')
991 sigaction (SIGBUS, &act, NULL);
993 __gnat_handler_installed = 1;
996 /*******************/
997 /* Solaris Section */
998 /*******************/
1000 #elif defined (sun) && defined (__SVR4) && !defined (__vxworks)
1003 #include <siginfo.h>
1004 #include <sys/ucontext.h>
1005 #include <sys/regset.h>
1007 /* The code below is common to SPARC and x86. Beware of the delay slot
1008 differences for signal context adjustments. */
1010 #if defined (__sparc)
1011 #define RETURN_ADDR_OFFSET 8
1013 #define RETURN_ADDR_OFFSET 0
1016 /* Likewise regarding how the "instruction pointer" register slot can
1017 be identified in signal machine contexts. We have either "REG_PC"
1018 or "PC" at hand, depending on the target CPU and Solaris version. */
1020 #if !defined (REG_PC)
1024 static void __gnat_error_handler (int, siginfo_t *, ucontext_t *);
1026 /* __gnat_adjust_context_for_raise - see comments along with the default
1027 version later in this file. */
1029 #define HAVE_GNAT_ADJUST_CONTEXT_FOR_RAISE
1032 __gnat_adjust_context_for_raise (int signo ATTRIBUTE_UNUSED,
1035 mcontext_t *mcontext = & ((ucontext_t *)ucontext)->uc_mcontext;
1036 mcontext->gregs[REG_PC] += (1 - RETURN_ADDR_OFFSET);
1040 __gnat_error_handler (int sig, siginfo_t *sip, ucontext_t *uctx)
1042 struct Exception_Data *exception;
1043 static int recurse = 0;
1046 /* Adjusting is required for every fault context, so adjust for this one
1047 now, before we possibly trigger a recursive fault below. */
1048 __gnat_adjust_context_for_raise (sig, (void *)uctx);
1050 /* If this was an explicit signal from a "kill", just resignal it. */
1051 if (SI_FROMUSER (sip))
1053 signal (sig, SIG_DFL);
1054 kill (getpid(), sig);
1057 /* Otherwise, treat it as something we handle. */
1061 /* If the problem was permissions, this is a constraint error.
1062 Likewise if the failing address isn't maximally aligned or if
1065 ??? Using a static variable here isn't task-safe, but it's
1066 much too hard to do anything else and we're just determining
1067 which exception to raise. */
1068 if (sip->si_code == SEGV_ACCERR
1069 || (((long) sip->si_addr) & 3) != 0
1072 exception = &constraint_error;
1077 /* See if the page before the faulting page is accessible. Do that
1078 by trying to access it. We'd like to simply try to access
1079 4096 + the faulting address, but it's not guaranteed to be
1080 the actual address, just to be on the same page. */
1083 ((long) sip->si_addr & - getpagesize ()))[getpagesize ()];
1084 exception = &storage_error;
1085 msg = "stack overflow (or erroneous memory access)";
1090 exception = &program_error;
1095 exception = &constraint_error;
1100 exception = &program_error;
1101 msg = "unhandled signal";
1106 Raise_From_Signal_Handler (exception, msg);
1110 __gnat_install_handler (void)
1112 struct sigaction act;
1114 /* Set up signal handler to map synchronous signals to appropriate
1115 exceptions. Make sure that the handler isn't interrupted by another
1116 signal that might cause a scheduling event! */
1118 act.sa_handler = __gnat_error_handler;
1119 act.sa_flags = SA_NODEFER | SA_RESTART | SA_SIGINFO;
1120 sigemptyset (&act.sa_mask);
1122 /* Do not install handlers if interrupt state is "System". */
1123 if (__gnat_get_interrupt_state (SIGABRT) != 's')
1124 sigaction (SIGABRT, &act, NULL);
1125 if (__gnat_get_interrupt_state (SIGFPE) != 's')
1126 sigaction (SIGFPE, &act, NULL);
1127 if (__gnat_get_interrupt_state (SIGSEGV) != 's')
1128 sigaction (SIGSEGV, &act, NULL);
1129 if (__gnat_get_interrupt_state (SIGBUS) != 's')
1130 sigaction (SIGBUS, &act, NULL);
1132 __gnat_handler_installed = 1;
1141 long __gnat_error_handler (int *, void *);
1144 #define lib_get_curr_invo_context LIB$I64_GET_CURR_INVO_CONTEXT
1145 #define lib_get_prev_invo_context LIB$I64_GET_PREV_INVO_CONTEXT
1146 #define lib_get_invo_handle LIB$I64_GET_INVO_HANDLE
1148 #define lib_get_curr_invo_context LIB$GET_CURR_INVO_CONTEXT
1149 #define lib_get_prev_invo_context LIB$GET_PREV_INVO_CONTEXT
1150 #define lib_get_invo_handle LIB$GET_INVO_HANDLE
1153 #if defined (IN_RTS) && !defined (__IA64)
1155 /* The prehandler actually gets control first on a condition. It swaps the
1156 stack pointer and calls the handler (__gnat_error_handler). */
1157 extern long __gnat_error_prehandler (void);
1159 extern char *__gnat_error_prehandler_stack; /* Alternate signal stack */
1162 /* Define macro symbols for the VMS conditions that become Ada exceptions.
1163 Most of these are also defined in the header file ssdef.h which has not
1164 yet been converted to be recognized by GNU C. */
1166 /* Defining these as macros, as opposed to external addresses, allows
1167 them to be used in a case statement below. */
1168 #define SS$_ACCVIO 12
1169 #define SS$_HPARITH 1284
1170 #define SS$_STKOVF 1364
1171 #define SS$_RESIGNAL 2328
1173 /* These codes are in standard message libraries. */
1174 extern int CMA$_EXIT_THREAD;
1175 extern int SS$_DEBUG;
1176 extern int SS$_INTDIV;
1177 extern int LIB$_KEYNOTFOU;
1178 extern int LIB$_ACTIMAGE;
1179 extern int MTH$_FLOOVEMAT; /* Some ACVC_21 CXA tests */
1181 /* These codes are non standard, which is to say the author is
1182 not sure if they are defined in the standard message libraries
1183 so keep them as macros for now. */
1184 #define RDB$_STREAM_EOF 20480426
1185 #define FDL$_UNPRIKW 11829410
1187 struct cond_except {
1189 const struct Exception_Data *except;
1192 struct descriptor_s {unsigned short len, mbz; __char_ptr32 adr; };
1194 /* Conditions that don't have an Ada exception counterpart must raise
1195 Non_Ada_Error. Since this is defined in s-auxdec, it should only be
1196 referenced by user programs, not the compiler or tools. Hence the
1201 #define Status_Error ada__io_exceptions__status_error
1202 extern struct Exception_Data Status_Error;
1204 #define Mode_Error ada__io_exceptions__mode_error
1205 extern struct Exception_Data Mode_Error;
1207 #define Name_Error ada__io_exceptions__name_error
1208 extern struct Exception_Data Name_Error;
1210 #define Use_Error ada__io_exceptions__use_error
1211 extern struct Exception_Data Use_Error;
1213 #define Device_Error ada__io_exceptions__device_error
1214 extern struct Exception_Data Device_Error;
1216 #define End_Error ada__io_exceptions__end_error
1217 extern struct Exception_Data End_Error;
1219 #define Data_Error ada__io_exceptions__data_error
1220 extern struct Exception_Data Data_Error;
1222 #define Layout_Error ada__io_exceptions__layout_error
1223 extern struct Exception_Data Layout_Error;
1225 #define Non_Ada_Error system__aux_dec__non_ada_error
1226 extern struct Exception_Data Non_Ada_Error;
1228 #define Coded_Exception system__vms_exception_table__coded_exception
1229 extern struct Exception_Data *Coded_Exception (Exception_Code);
1231 #define Base_Code_In system__vms_exception_table__base_code_in
1232 extern Exception_Code Base_Code_In (Exception_Code);
1234 /* DEC Ada exceptions are not defined in a header file, so they
1235 must be declared as external addresses. */
1237 extern int ADA$_PROGRAM_ERROR;
1238 extern int ADA$_LOCK_ERROR;
1239 extern int ADA$_EXISTENCE_ERROR;
1240 extern int ADA$_KEY_ERROR;
1241 extern int ADA$_KEYSIZERR;
1242 extern int ADA$_STAOVF;
1243 extern int ADA$_CONSTRAINT_ERRO;
1244 extern int ADA$_IOSYSFAILED;
1245 extern int ADA$_LAYOUT_ERROR;
1246 extern int ADA$_STORAGE_ERROR;
1247 extern int ADA$_DATA_ERROR;
1248 extern int ADA$_DEVICE_ERROR;
1249 extern int ADA$_END_ERROR;
1250 extern int ADA$_MODE_ERROR;
1251 extern int ADA$_NAME_ERROR;
1252 extern int ADA$_STATUS_ERROR;
1253 extern int ADA$_NOT_OPEN;
1254 extern int ADA$_ALREADY_OPEN;
1255 extern int ADA$_USE_ERROR;
1256 extern int ADA$_UNSUPPORTED;
1257 extern int ADA$_FAC_MODE_MISMAT;
1258 extern int ADA$_ORG_MISMATCH;
1259 extern int ADA$_RFM_MISMATCH;
1260 extern int ADA$_RAT_MISMATCH;
1261 extern int ADA$_MRS_MISMATCH;
1262 extern int ADA$_MRN_MISMATCH;
1263 extern int ADA$_KEY_MISMATCH;
1264 extern int ADA$_MAXLINEXC;
1265 extern int ADA$_LINEXCMRS;
1267 /* DEC Ada specific conditions. */
1268 static const struct cond_except dec_ada_cond_except_table [] = {
1269 {&ADA$_PROGRAM_ERROR, &program_error},
1270 {&ADA$_USE_ERROR, &Use_Error},
1271 {&ADA$_KEYSIZERR, &program_error},
1272 {&ADA$_STAOVF, &storage_error},
1273 {&ADA$_CONSTRAINT_ERRO, &constraint_error},
1274 {&ADA$_IOSYSFAILED, &Device_Error},
1275 {&ADA$_LAYOUT_ERROR, &Layout_Error},
1276 {&ADA$_STORAGE_ERROR, &storage_error},
1277 {&ADA$_DATA_ERROR, &Data_Error},
1278 {&ADA$_DEVICE_ERROR, &Device_Error},
1279 {&ADA$_END_ERROR, &End_Error},
1280 {&ADA$_MODE_ERROR, &Mode_Error},
1281 {&ADA$_NAME_ERROR, &Name_Error},
1282 {&ADA$_STATUS_ERROR, &Status_Error},
1283 {&ADA$_NOT_OPEN, &Use_Error},
1284 {&ADA$_ALREADY_OPEN, &Use_Error},
1285 {&ADA$_USE_ERROR, &Use_Error},
1286 {&ADA$_UNSUPPORTED, &Use_Error},
1287 {&ADA$_FAC_MODE_MISMAT, &Use_Error},
1288 {&ADA$_ORG_MISMATCH, &Use_Error},
1289 {&ADA$_RFM_MISMATCH, &Use_Error},
1290 {&ADA$_RAT_MISMATCH, &Use_Error},
1291 {&ADA$_MRS_MISMATCH, &Use_Error},
1292 {&ADA$_MRN_MISMATCH, &Use_Error},
1293 {&ADA$_KEY_MISMATCH, &Use_Error},
1294 {&ADA$_MAXLINEXC, &constraint_error},
1295 {&ADA$_LINEXCMRS, &constraint_error},
1300 /* Already handled by a pragma Import_Exception
1301 in Aux_IO_Exceptions */
1302 {&ADA$_LOCK_ERROR, &Lock_Error},
1303 {&ADA$_EXISTENCE_ERROR, &Existence_Error},
1304 {&ADA$_KEY_ERROR, &Key_Error},
1309 /* Non-DEC Ada specific conditions. We could probably also put
1310 SS$_HPARITH here and possibly SS$_ACCVIO, SS$_STKOVF. */
1311 static const struct cond_except cond_except_table [] = {
1312 {&MTH$_FLOOVEMAT, &constraint_error},
1313 {&SS$_INTDIV, &constraint_error},
1317 /* To deal with VMS conditions and their mapping to Ada exceptions,
1318 the __gnat_error_handler routine below is installed as an exception
1319 vector having precedence over DEC frame handlers. Some conditions
1320 still need to be handled by such handlers, however, in which case
1321 __gnat_error_handler needs to return SS$_RESIGNAL. Consider for
1322 instance the use of a third party library compiled with DECAda and
1323 performing its own exception handling internally.
1325 To allow some user-level flexibility, which conditions should be
1326 resignaled is controlled by a predicate function, provided with the
1327 condition value and returning a boolean indication stating whether
1328 this condition should be resignaled or not.
1330 That predicate function is called indirectly, via a function pointer,
1331 by __gnat_error_handler, and changing that pointer is allowed to the
1332 the user code by way of the __gnat_set_resignal_predicate interface.
1334 The user level function may then implement what it likes, including
1335 for instance the maintenance of a dynamic data structure if the set
1336 of to be resignalled conditions has to change over the program's
1339 ??? This is not a perfect solution to deal with the possible
1340 interactions between the GNAT and the DECAda exception handling
1341 models and better (more general) schemes are studied. This is so
1342 just provided as a convenient workaround in the meantime, and
1343 should be use with caution since the implementation has been kept
1347 resignal_predicate (int code);
1349 const int *cond_resignal_table [] = {
1354 (int *) RDB$_STREAM_EOF,
1355 (int *) FDL$_UNPRIKW,
1359 const int facility_resignal_table [] = {
1360 0x1380000, /* RDB */
1361 0x2220000, /* SQL */
1365 /* Default GNAT predicate for resignaling conditions. */
1368 __gnat_default_resignal_p (int code)
1372 for (i = 0; facility_resignal_table [i]; i++)
1373 if ((code & 0xfff0000) == facility_resignal_table [i])
1376 for (i = 0, iexcept = 0;
1377 cond_resignal_table [i] &&
1378 !(iexcept = LIB$MATCH_COND (&code, &cond_resignal_table [i]));
1384 /* Static pointer to predicate that the __gnat_error_handler exception
1385 vector invokes to determine if it should resignal a condition. */
1387 static resignal_predicate * __gnat_resignal_p = __gnat_default_resignal_p;
1389 /* User interface to change the predicate pointer to PREDICATE. Reset to
1390 the default if PREDICATE is null. */
1393 __gnat_set_resignal_predicate (resignal_predicate * predicate)
1396 __gnat_resignal_p = __gnat_default_resignal_p;
1398 __gnat_resignal_p = predicate;
1401 /* Should match System.Parameters.Default_Exception_Msg_Max_Length. */
1402 #define Default_Exception_Msg_Max_Length 512
1404 /* Action routine for SYS$PUTMSG. There may be multiple
1405 conditions, each with text to be appended to MESSAGE
1406 and separated by line termination. */
1409 copy_msg (msgdesc, message)
1410 struct descriptor_s *msgdesc;
1413 int len = strlen (message);
1416 /* Check for buffer overflow and skip. */
1417 if (len > 0 && len <= Default_Exception_Msg_Max_Length - 3)
1419 strcat (message, "\r\n");
1423 /* Check for buffer overflow and truncate if necessary. */
1424 copy_len = (len + msgdesc->len <= Default_Exception_Msg_Max_Length - 1 ?
1426 Default_Exception_Msg_Max_Length - 1 - len);
1427 strncpy (&message [len], msgdesc->adr, copy_len);
1428 message [len + copy_len] = 0;
1434 __gnat_handle_vms_condition (int *sigargs, void *mechargs)
1436 struct Exception_Data *exception = 0;
1437 Exception_Code base_code;
1438 struct descriptor_s gnat_facility = {4,0,"GNAT"};
1439 char message [Default_Exception_Msg_Max_Length];
1441 const char *msg = "";
1443 /* Check for conditions to resignal which aren't effected by pragma
1444 Import_Exception. */
1445 if (__gnat_resignal_p (sigargs [1]))
1446 return SS$_RESIGNAL;
1449 /* See if it's an imported exception. Beware that registered exceptions
1450 are bound to their base code, with the severity bits masked off. */
1451 base_code = Base_Code_In ((Exception_Code) sigargs [1]);
1452 exception = Coded_Exception (base_code);
1458 /* Subtract PC & PSL fields which messes with PUTMSG. */
1460 SYS$PUTMSG (sigargs, copy_msg, &gnat_facility, message);
1464 exception->Name_Length = 19;
1465 /* ??? The full name really should be get sys$getmsg returns. */
1466 exception->Full_Name = "IMPORTED_EXCEPTION";
1467 exception->Import_Code = base_code;
1470 /* Do not adjust the program counter as already points to the next
1471 instruction (just after the call to LIB$STOP). */
1472 Raise_From_Signal_Handler (exception, msg);
1481 if (sigargs[3] == 0)
1483 exception = &constraint_error;
1484 msg = "access zero";
1488 exception = &storage_error;
1489 msg = "stack overflow (or erroneous memory access)";
1491 __gnat_adjust_context_for_raise (0, (void *)mechargs);
1495 exception = &storage_error;
1496 msg = "stack overflow";
1497 __gnat_adjust_context_for_raise (0, (void *)mechargs);
1502 return SS$_RESIGNAL; /* toplev.c handles for compiler */
1504 exception = &constraint_error;
1505 msg = "arithmetic error";
1507 /* No need to adjust pc on Alpha: the pc is already on the instruction
1508 after the trapping one. */
1509 __gnat_adjust_context_for_raise (0, (void *)mechargs);
1519 /* Scan the DEC Ada exception condition table for a match and fetch
1520 the associated GNAT exception pointer. */
1522 dec_ada_cond_except_table [i].cond &&
1523 !LIB$MATCH_COND (&sigargs [1],
1524 &dec_ada_cond_except_table [i].cond);
1526 exception = (struct Exception_Data *)
1527 dec_ada_cond_except_table [i].except;
1531 /* Scan the VMS standard condition table for a match and fetch
1532 the associated GNAT exception pointer. */
1534 cond_except_table [i].cond &&
1535 !LIB$MATCH_COND (&sigargs [1], &cond_except_table [i].cond);
1537 exception = (struct Exception_Data *)
1538 cond_except_table [i].except;
1541 /* User programs expect Non_Ada_Error to be raised, reference
1542 DEC Ada test CXCONDHAN. */
1543 exception = &Non_Ada_Error;
1547 exception = &program_error;
1550 /* Subtract PC & PSL fields which messes with PUTMSG. */
1552 SYS$PUTMSG (sigargs, copy_msg, &gnat_facility, message);
1558 Raise_From_Signal_Handler (exception, msg);
1562 __gnat_error_handler (int *sigargs, void *mechargs)
1564 return __gnat_handle_vms_condition (sigargs, mechargs);
1568 __gnat_install_handler (void)
1570 long prvhnd ATTRIBUTE_UNUSED;
1572 #if !defined (IN_RTS)
1573 SYS$SETEXV (1, __gnat_error_handler, 3, &prvhnd);
1576 /* On alpha-vms, we avoid the global vector annoyance thanks to frame based
1577 handlers to turn conditions into exceptions since GCC 3.4. The global
1578 vector is still required for earlier GCC versions. We're resorting to
1579 the __gnat_error_prehandler assembly function in this case. */
1581 #if defined (IN_RTS) && defined (__alpha__)
1582 if ((__GNUC__ * 10 + __GNUC_MINOR__) < 34)
1584 char * c = (char *) xmalloc (2049);
1586 __gnat_error_prehandler_stack = &c[2048];
1587 SYS$SETEXV (1, __gnat_error_prehandler, 3, &prvhnd);
1591 __gnat_handler_installed = 1;
1594 /* __gnat_adjust_context_for_raise for Alpha - see comments along with the
1595 default version later in this file. */
1597 #if defined (IN_RTS) && defined (__alpha__)
1599 #include <vms/chfctxdef.h>
1600 #include <vms/chfdef.h>
1602 #define HAVE_GNAT_ADJUST_CONTEXT_FOR_RAISE
1605 __gnat_adjust_context_for_raise (int signo ATTRIBUTE_UNUSED, void *ucontext)
1607 /* Add one to the address of the instruction signaling the condition,
1608 located in the sigargs array. */
1610 CHF$MECH_ARRAY * mechargs = (CHF$MECH_ARRAY *) ucontext;
1611 CHF$SIGNAL_ARRAY * sigargs
1612 = (CHF$SIGNAL_ARRAY *) mechargs->chf$q_mch_sig_addr;
1614 int vcount = sigargs->chf$is_sig_args;
1615 int * pc_slot = & (&sigargs->chf$l_sig_name)[vcount-2];
1622 /* __gnat_adjust_context_for_raise for ia64. */
1624 #if defined (IN_RTS) && defined (__IA64)
1626 #include <vms/chfctxdef.h>
1627 #include <vms/chfdef.h>
1629 #define HAVE_GNAT_ADJUST_CONTEXT_FOR_RAISE
1631 typedef unsigned long long u64;
1634 __gnat_adjust_context_for_raise (int signo ATTRIBUTE_UNUSED, void *ucontext)
1636 /* Add one to the address of the instruction signaling the condition,
1637 located in the 64bits sigargs array. */
1639 CHF$MECH_ARRAY * mechargs = (CHF$MECH_ARRAY *) ucontext;
1641 CHF64$SIGNAL_ARRAY *chfsig64
1642 = (CHF64$SIGNAL_ARRAY *) mechargs->chf$ph_mch_sig64_addr;
1645 = (u64 *)chfsig64 + 1 + chfsig64->chf64$l_sig_args;
1647 u64 * ih_pc_loc = post_sigarray - 2;
1654 /*******************/
1655 /* FreeBSD Section */
1656 /*******************/
1658 #elif defined (__FreeBSD__)
1661 #include <sys/ucontext.h>
1664 static void __gnat_error_handler (int, siginfo_t *, ucontext_t *);
1665 void __gnat_adjust_context_for_raise (int, void*);
1667 /* __gnat_adjust_context_for_raise - see comments along with the default
1668 version later in this file. */
1670 #define HAVE_GNAT_ADJUST_CONTEXT_FOR_RAISE
1673 __gnat_adjust_context_for_raise (int signo ATTRIBUTE_UNUSED, void *ucontext)
1675 mcontext_t *mcontext = &((ucontext_t *) ucontext)->uc_mcontext;
1680 __gnat_error_handler (int sig, siginfo_t *info __attribute__ ((unused)),
1681 ucontext_t *ucontext)
1683 struct Exception_Data *exception;
1689 exception = &constraint_error;
1694 exception = &constraint_error;
1699 exception = &storage_error;
1700 msg = "stack overflow or erroneous memory access";
1704 exception = &constraint_error;
1709 exception = &program_error;
1710 msg = "unhandled signal";
1713 __gnat_adjust_context_for_raise (sig, ucontext);
1714 Raise_From_Signal_Handler (exception, msg);
1718 __gnat_install_handler ()
1720 struct sigaction act;
1722 /* Set up signal handler to map synchronous signals to appropriate
1723 exceptions. Make sure that the handler isn't interrupted by another
1724 signal that might cause a scheduling event! */
1727 = (void (*)(int, struct __siginfo *, void*)) __gnat_error_handler;
1728 act.sa_flags = SA_NODEFER | SA_RESTART | SA_SIGINFO;
1729 (void) sigemptyset (&act.sa_mask);
1731 (void) sigaction (SIGILL, &act, NULL);
1732 (void) sigaction (SIGFPE, &act, NULL);
1733 (void) sigaction (SIGSEGV, &act, NULL);
1734 (void) sigaction (SIGBUS, &act, NULL);
1736 __gnat_handler_installed = 1;
1739 /*******************/
1740 /* VxWorks Section */
1741 /*******************/
1743 #elif defined(__vxworks)
1746 #include <taskLib.h>
1754 #include "private/vThreadsP.h"
1757 void __gnat_error_handler (int, void *, struct sigcontext *);
1761 /* Directly vectored Interrupt routines are not supported when using RTPs. */
1763 extern int __gnat_inum_to_ivec (int);
1765 /* This is needed by the GNAT run time to handle Vxworks interrupts. */
1767 __gnat_inum_to_ivec (int num)
1769 return INUM_TO_IVEC (num);
1773 #if !defined(__alpha_vxworks) && (_WRS_VXWORKS_MAJOR != 6) && !defined(__RTP__)
1775 /* getpid is used by s-parint.adb, but is not defined by VxWorks, except
1776 on Alpha VxWorks and VxWorks 6.x (including RTPs). */
1778 extern long getpid (void);
1783 return taskIdSelf ();
1787 /* VxWorks expects the field excCnt to be zeroed when a signal is handled.
1788 The VxWorks version of longjmp does this; GCC's builtin_longjmp doesn't. */
1790 __gnat_clear_exception_count (void)
1793 WIND_TCB *currentTask = (WIND_TCB *) taskIdSelf();
1795 currentTask->vThreads.excCnt = 0;
1800 /* VxWorks context adjustment for targets that need/support it. */
1802 void __gnat_adjust_context_for_raise (int, void*);
1804 #if defined (_ARCH_PPC) && !defined (VTHREADS) && !defined (__RTP__)
1806 #define HAVE_GNAT_ADJUST_CONTEXT_FOR_RAISE
1808 /* We need the constant and structure definitions describing the machine
1809 state. Part of this is normally retrieved from the VxWorks "regs.h" but
1810 #including it here gets the GCC internals instance of this file instead.
1811 We need to #include the version we need directly here, and prevent the
1812 possibly indirect inclusion of the GCC one, as its contents is useless to
1813 us and it depends on several other headers that we don't have at hand. */
1814 #include <arch/ppc/regsPpc.h>
1819 __gnat_adjust_context_for_raise (int signo ATTRIBUTE_UNUSED, void *sigcontext)
1821 REG_SET * mcontext = ((struct sigcontext *) sigcontext)->sc_pregs;
1827 /* Handle different SIGnal to exception mappings in different VxWorks
1830 __gnat_map_signal (int sig)
1832 struct Exception_Data *exception;
1838 exception = &constraint_error;
1843 exception = &constraint_error;
1844 msg = "Floating point exception or SIGILL";
1847 exception = &storage_error;
1848 msg = "SIGSEGV: possible stack overflow";
1851 exception = &storage_error;
1852 msg = "SIGBUS: possible stack overflow";
1856 /* In RTP mode a SIGSEGV is most likely due to a stack overflow,
1857 since stack checking uses the probing mechanism. */
1859 exception = &constraint_error;
1863 exception = &storage_error;
1864 msg = "SIGSEGV: possible stack overflow";
1867 /* In kernel mode a SIGILL is most likely due to a stack overflow,
1868 since stack checking uses the stack limit mechanism. */
1870 exception = &storage_error;
1871 msg = "SIGILL: possible stack overflow";
1874 exception = &program_error;
1879 exception = &program_error;
1884 exception = &program_error;
1885 msg = "unhandled signal";
1888 __gnat_clear_exception_count ();
1889 Raise_From_Signal_Handler (exception, msg);
1892 /* Tasking and Non-tasking signal handler. Map SIGnal to Ada exception
1893 propagation after the required low level adjustments. */
1896 __gnat_error_handler (int sig, void * si ATTRIBUTE_UNUSED,
1897 struct sigcontext * sc)
1901 /* VxWorks will always mask out the signal during the signal handler and
1902 will reenable it on a longjmp. GNAT does not generate a longjmp to
1903 return from a signal handler so the signal will still be masked unless
1905 sigprocmask (SIG_SETMASK, NULL, &mask);
1906 sigdelset (&mask, sig);
1907 sigprocmask (SIG_SETMASK, &mask, NULL);
1909 __gnat_adjust_context_for_raise (sig, (void *)sc);
1910 __gnat_map_signal (sig);
1914 __gnat_install_handler (void)
1916 struct sigaction act;
1918 /* Setup signal handler to map synchronous signals to appropriate
1919 exceptions. Make sure that the handler isn't interrupted by another
1920 signal that might cause a scheduling event! */
1922 act.sa_handler = __gnat_error_handler;
1923 act.sa_flags = SA_SIGINFO | SA_ONSTACK;
1924 sigemptyset (&act.sa_mask);
1926 /* For VxWorks, install all signal handlers, since pragma Interrupt_State
1927 applies to vectored hardware interrupts, not signals. */
1928 sigaction (SIGFPE, &act, NULL);
1929 sigaction (SIGILL, &act, NULL);
1930 sigaction (SIGSEGV, &act, NULL);
1931 sigaction (SIGBUS, &act, NULL);
1933 __gnat_handler_installed = 1;
1936 #define HAVE_GNAT_INIT_FLOAT
1939 __gnat_init_float (void)
1941 /* Disable overflow/underflow exceptions on the PPC processor, needed
1942 to get correct Ada semantics. Note that for AE653 vThreads, the HW
1943 overflow settings are an OS configuration issue. The instructions
1944 below have no effect. */
1945 #if defined (_ARCH_PPC) && !defined (_SOFT_FLOAT) && !defined (VTHREADS)
1950 #if (defined (__i386__) || defined (i386)) && !defined (VTHREADS)
1951 /* This is used to properly initialize the FPU on an x86 for each
1956 /* Similarly for SPARC64. Achieved by masking bits in the Trap Enable Mask
1957 field of the Floating-point Status Register (see the SPARC Architecture
1958 Manual Version 9, p 48). */
1959 #if defined (sparc64)
1961 #define FSR_TEM_NVM (1 << 27) /* Invalid operand */
1962 #define FSR_TEM_OFM (1 << 26) /* Overflow */
1963 #define FSR_TEM_UFM (1 << 25) /* Underflow */
1964 #define FSR_TEM_DZM (1 << 24) /* Division by Zero */
1965 #define FSR_TEM_NXM (1 << 23) /* Inexact result */
1969 __asm__("st %%fsr, %0" : "=m" (fsr));
1970 fsr &= ~(FSR_TEM_OFM | FSR_TEM_UFM);
1971 __asm__("ld %0, %%fsr" : : "m" (fsr));
1976 /* This subprogram is called by System.Task_Primitives.Operations.Enter_Task
1977 (if not null) when a new task is created. It is initialized by
1978 System.Stack_Checking.Operations.Initialize_Stack_Limit.
1979 The use of a hook avoids to drag stack checking subprograms if stack
1980 checking is not used. */
1981 void (*__gnat_set_stack_limit_hook)(void) = (void (*)(void))0;
1984 /******************/
1985 /* NetBSD Section */
1986 /******************/
1988 #elif defined(__NetBSD__)
1994 __gnat_error_handler (int sig)
1996 struct Exception_Data *exception;
2002 exception = &constraint_error;
2006 exception = &constraint_error;
2010 exception = &storage_error;
2011 msg = "stack overflow or erroneous memory access";
2014 exception = &constraint_error;
2018 exception = &program_error;
2019 msg = "unhandled signal";
2022 Raise_From_Signal_Handler(exception, msg);
2026 __gnat_install_handler(void)
2028 struct sigaction act;
2030 act.sa_handler = __gnat_error_handler;
2031 act.sa_flags = SA_NODEFER | SA_RESTART;
2032 sigemptyset (&act.sa_mask);
2034 /* Do not install handlers if interrupt state is "System". */
2035 if (__gnat_get_interrupt_state (SIGFPE) != 's')
2036 sigaction (SIGFPE, &act, NULL);
2037 if (__gnat_get_interrupt_state (SIGILL) != 's')
2038 sigaction (SIGILL, &act, NULL);
2039 if (__gnat_get_interrupt_state (SIGSEGV) != 's')
2040 sigaction (SIGSEGV, &act, NULL);
2041 if (__gnat_get_interrupt_state (SIGBUS) != 's')
2042 sigaction (SIGBUS, &act, NULL);
2044 __gnat_handler_installed = 1;
2047 /*******************/
2048 /* OpenBSD Section */
2049 /*******************/
2051 #elif defined(__OpenBSD__)
2057 __gnat_error_handler (int sig)
2059 struct Exception_Data *exception;
2065 exception = &constraint_error;
2069 exception = &constraint_error;
2073 exception = &storage_error;
2074 msg = "stack overflow or erroneous memory access";
2077 exception = &constraint_error;
2081 exception = &program_error;
2082 msg = "unhandled signal";
2085 Raise_From_Signal_Handler(exception, msg);
2089 __gnat_install_handler(void)
2091 struct sigaction act;
2093 act.sa_handler = __gnat_error_handler;
2094 act.sa_flags = SA_NODEFER | SA_RESTART;
2095 sigemptyset (&act.sa_mask);
2097 /* Do not install handlers if interrupt state is "System" */
2098 if (__gnat_get_interrupt_state (SIGFPE) != 's')
2099 sigaction (SIGFPE, &act, NULL);
2100 if (__gnat_get_interrupt_state (SIGILL) != 's')
2101 sigaction (SIGILL, &act, NULL);
2102 if (__gnat_get_interrupt_state (SIGSEGV) != 's')
2103 sigaction (SIGSEGV, &act, NULL);
2104 if (__gnat_get_interrupt_state (SIGBUS) != 's')
2105 sigaction (SIGBUS, &act, NULL);
2107 __gnat_handler_installed = 1;
2112 /* For all other versions of GNAT, the handler does nothing. */
2114 /*******************/
2115 /* Default Section */
2116 /*******************/
2119 __gnat_install_handler (void)
2121 __gnat_handler_installed = 1;
2126 /*********************/
2127 /* __gnat_init_float */
2128 /*********************/
2130 /* This routine is called as each process thread is created, for possible
2131 initialization of the FP processor. This version is used under INTERIX,
2132 WIN32 and could be used under OS/2. */
2134 #if defined (_WIN32) || defined (__INTERIX) || defined (__EMX__) \
2135 || defined (__Lynx__) || defined(__NetBSD__) || defined(__FreeBSD__) \
2136 || defined (__OpenBSD__)
2138 #define HAVE_GNAT_INIT_FLOAT
2141 __gnat_init_float (void)
2143 #if defined (__i386__) || defined (i386)
2145 /* This is used to properly initialize the FPU on an x86 for each
2150 #endif /* Defined __i386__ */
2154 #ifndef HAVE_GNAT_INIT_FLOAT
2156 /* All targets without a specific __gnat_init_float will use an empty one. */
2158 __gnat_init_float (void)
2163 /***********************************/
2164 /* __gnat_adjust_context_for_raise */
2165 /***********************************/
2167 #ifndef HAVE_GNAT_ADJUST_CONTEXT_FOR_RAISE
2169 /* All targets without a specific version will use an empty one. */
2171 /* Given UCONTEXT a pointer to a context structure received by a signal
2172 handler for SIGNO, perform the necessary adjustments to let the handler
2173 raise an exception. Calls to this routine are not conditioned by the
2174 propagation scheme in use. */
2177 __gnat_adjust_context_for_raise (int signo ATTRIBUTE_UNUSED,
2178 void *ucontext ATTRIBUTE_UNUSED)
2180 /* Adjustments are currently required for the GCC ZCX propagation scheme
2181 only. These adjustments (described below) are harmless for the other
2182 schemes, so may be applied unconditionally. */
2184 /* Adjustments required for a GCC ZCX propagation scheme:
2185 ------------------------------------------------------
2187 The GCC unwinder expects to be dealing with call return addresses, since
2188 this is the "nominal" case of what we retrieve while unwinding a regular
2191 To evaluate if a handler applies at some point identified by a return
2192 address, the propagation engine needs to determine what region the
2193 corresponding call instruction pertains to. Because the return address
2194 may not be attached to the same region as the call, the unwinder always
2195 subtracts "some" amount from a return address to search the region
2196 tables, amount chosen to ensure that the resulting address is inside the
2199 When we raise an exception from a signal handler, e.g. to transform a
2200 SIGSEGV into Storage_Error, things need to appear as if the signal
2201 handler had been "called" by the instruction which triggered the signal,
2202 so that exception handlers that apply there are considered. What the
2203 unwinder will retrieve as the return address from the signal handler is
2204 what it will find as the faulting instruction address in the signal
2205 context pushed by the kernel. Leaving this address untouched looses, if
2206 the triggering instruction happens to be the very first of a region, as
2207 the later adjustments performed by the unwinder would yield an address
2208 outside that region. We need to compensate for the unwinder adjustments
2209 at some point, and this is what this routine is expected to do.
2211 signo is passed because on some targets for some signals the PC in
2212 context points to the instruction after the faulting one, in which case
2213 the unwinder adjustment is still desired.
2215 We used to perform the compensation in the GCC unwinding fallback macro.
2216 The thread at http://gcc.gnu.org/ml/gcc-patches/2004-05/msg00343.html
2217 describes a couple of issues with this approach. First, on some targets
2218 the adjustment to apply depends on the triggering signal, which is not
2219 easily accessible from the macro. Besides, other languages, e.g. Java,
2220 deal with this by performing the adjustment in the signal handler before
2221 the raise, so fallback adjustments just break those front-ends. */