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;
105 int __gl_canonical_streams = 0;
107 /* Indication of whether synchronous signal handler has already been
108 installed by a previous call to adainit. */
109 int __gnat_handler_installed = 0;
112 int __gnat_inside_elab_final_code = 0;
113 /* ??? This variable is obsolete since 2001-08-29 but is kept to allow
114 bootstrap from old GNAT versions (< 3.15). */
117 /* HAVE_GNAT_INIT_FLOAT must be set on every targets where a __gnat_init_float
118 is defined. If this is not set then a void implementation will be defined
119 at the end of this unit. */
120 #undef HAVE_GNAT_INIT_FLOAT
122 /******************************/
123 /* __gnat_get_interrupt_state */
124 /******************************/
126 char __gnat_get_interrupt_state (int);
128 /* This routine is called from the runtime as needed to determine the state
129 of an interrupt, as set by an Interrupt_State pragma appearing anywhere
130 in the current partition. The input argument is the interrupt number,
131 and the result is one of the following:
133 'n' this interrupt not set by any Interrupt_State pragma
134 'u' Interrupt_State pragma set state to User
135 'r' Interrupt_State pragma set state to Runtime
136 's' Interrupt_State pragma set state to System */
139 __gnat_get_interrupt_state (int intrup)
141 if (intrup >= __gl_num_interrupt_states)
144 return __gl_interrupt_states [intrup];
147 /***********************************/
148 /* __gnat_get_specific_dispatching */
149 /***********************************/
151 char __gnat_get_specific_dispatching (int);
153 /* This routine is called from the runtime as needed to determine the
154 priority specific dispatching policy, as set by a
155 Priority_Specific_Dispatching pragma appearing anywhere in the current
156 partition. The input argument is the priority number, and the result
157 is the upper case first character of the policy name, e.g. 'F' for
158 FIFO_Within_Priorities. A space ' ' is returned if no
159 Priority_Specific_Dispatching pragma is used in the partition. */
162 __gnat_get_specific_dispatching (int priority)
164 if (__gl_num_specific_dispatching == 0)
166 else if (priority >= __gl_num_specific_dispatching)
169 return __gl_priority_specific_dispatching [priority];
174 /**********************/
175 /* __gnat_set_globals */
176 /**********************/
178 /* This routine is kept for bootstrapping purposes, since the binder generated
179 file now sets the __gl_* variables directly. */
182 __gnat_set_globals ()
195 #include <sys/time.h>
197 /* Some versions of AIX don't define SA_NODEFER. */
201 #endif /* SA_NODEFER */
203 /* Versions of AIX before 4.3 don't have nanosleep but provide
206 #ifndef _AIXVERSION_430
208 extern int nanosleep (struct timestruc_t *, struct timestruc_t *);
211 nanosleep (struct timestruc_t *Rqtp, struct timestruc_t *Rmtp)
213 return nsleep (Rqtp, Rmtp);
216 #endif /* _AIXVERSION_430 */
218 static void __gnat_error_handler (int sig, siginfo_t * si, void * uc);
220 /* __gnat_adjust_context_for_raise - see comments along with the default
221 version later in this file. */
224 __gnat_adjust_context_for_raise (int signo ATTRIBUTE_UNUSED, void *ucontext)
226 /* We need to adjust the "Instruction Address Register" value, part of a
227 'struct mstsave' wrapped as a jumpbuf in the mcontext field designated by
228 the signal data pointer we get. See sys/context.h + sys/mstsave.h */
230 mcontext_t *mcontext = &((ucontext_t *) ucontext)->uc_mcontext;
231 mcontext->jmp_context.iar++;
234 #define HAVE_GNAT_ADJUST_CONTEXT_FOR_RAISE
237 __gnat_error_handler (int sig, siginfo_t * si, void * uc)
239 struct Exception_Data *exception;
245 /* FIXME: we need to detect the case of a *real* SIGSEGV. */
246 exception = &storage_error;
247 msg = "stack overflow or erroneous memory access";
251 exception = &constraint_error;
256 exception = &constraint_error;
261 exception = &program_error;
262 msg = "unhandled signal";
265 __gnat_adjust_context_for_raise (sig, uc);
266 Raise_From_Signal_Handler (exception, msg);
270 __gnat_install_handler (void)
272 struct sigaction act;
274 /* Set up signal handler to map synchronous signals to appropriate
275 exceptions. Make sure that the handler isn't interrupted by another
276 signal that might cause a scheduling event! */
278 act.sa_flags = SA_NODEFER | SA_RESTART | SA_SIGINFO;
279 act.sa_sigaction = __gnat_error_handler;
280 sigemptyset (&act.sa_mask);
282 /* Do not install handlers if interrupt state is "System". */
283 if (__gnat_get_interrupt_state (SIGABRT) != 's')
284 sigaction (SIGABRT, &act, NULL);
285 if (__gnat_get_interrupt_state (SIGFPE) != 's')
286 sigaction (SIGFPE, &act, NULL);
287 if (__gnat_get_interrupt_state (SIGILL) != 's')
288 sigaction (SIGILL, &act, NULL);
289 if (__gnat_get_interrupt_state (SIGSEGV) != 's')
290 sigaction (SIGSEGV, &act, NULL);
291 if (__gnat_get_interrupt_state (SIGBUS) != 's')
292 sigaction (SIGBUS, &act, NULL);
294 __gnat_handler_installed = 1;
301 #elif defined(__alpha__) && defined(__osf__)
304 #include <sys/siginfo.h>
306 static void __gnat_error_handler (int, siginfo_t *, struct sigcontext *);
307 extern char *__gnat_get_code_loc (struct sigcontext *);
308 extern void __gnat_set_code_loc (struct sigcontext *, char *);
309 extern size_t __gnat_machine_state_length (void);
311 /* __gnat_adjust_context_for_raise - see comments along with the default
312 version later in this file. */
314 #define HAVE_GNAT_ADJUST_CONTEXT_FOR_RAISE
317 __gnat_adjust_context_for_raise (int signo, void *context)
319 struct sigcontext * sigcontext = (struct sigcontext *) context;
321 /* The fallback code fetches the faulting insn address from sc_pc, so
322 adjust that when need be. For SIGFPE, the required adjustment depends
323 on the trap shadow situation (see man ieee). */
326 /* ??? We never adjust here, considering that sc_pc always
327 designates the instruction following the one which trapped.
328 This is not necessarily true but corresponds to what we have
332 sigcontext->sc_pc ++;
337 (int sig, siginfo_t *sip, struct sigcontext *context)
339 struct Exception_Data *exception;
340 static int recurse = 0;
343 /* Adjusting is required for every fault context, so adjust for this one
344 now, before we possibly trigger a recursive fault below. */
345 __gnat_adjust_context_for_raise (sig, context);
347 /* If this was an explicit signal from a "kill", just resignal it. */
348 if (SI_FROMUSER (sip))
350 signal (sig, SIG_DFL);
351 kill (getpid(), sig);
354 /* Otherwise, treat it as something we handle. */
358 /* If the problem was permissions, this is a constraint error.
359 Likewise if the failing address isn't maximally aligned or if
362 ??? Using a static variable here isn't task-safe, but it's
363 much too hard to do anything else and we're just determining
364 which exception to raise. */
365 if (sip->si_code == SEGV_ACCERR
366 || (((long) sip->si_addr) & 3) != 0
369 exception = &constraint_error;
374 /* See if the page before the faulting page is accessible. Do that
375 by trying to access it. We'd like to simply try to access
376 4096 + the faulting address, but it's not guaranteed to be
377 the actual address, just to be on the same page. */
380 ((long) sip->si_addr & - getpagesize ()))[getpagesize ()];
381 msg = "stack overflow (or erroneous memory access)";
382 exception = &storage_error;
387 exception = &program_error;
392 exception = &constraint_error;
397 exception = &program_error;
398 msg = "unhandled signal";
402 Raise_From_Signal_Handler (exception, (char *) msg);
406 __gnat_install_handler (void)
408 struct sigaction act;
410 /* Setup signal handler to map synchronous signals to appropriate
411 exceptions. Make sure that the handler isn't interrupted by another
412 signal that might cause a scheduling event! */
414 act.sa_handler = (void (*) (int)) __gnat_error_handler;
415 act.sa_flags = SA_RESTART | SA_NODEFER | SA_SIGINFO;
416 sigemptyset (&act.sa_mask);
418 /* Do not install handlers if interrupt state is "System". */
419 if (__gnat_get_interrupt_state (SIGABRT) != 's')
420 sigaction (SIGABRT, &act, NULL);
421 if (__gnat_get_interrupt_state (SIGFPE) != 's')
422 sigaction (SIGFPE, &act, NULL);
423 if (__gnat_get_interrupt_state (SIGILL) != 's')
424 sigaction (SIGILL, &act, NULL);
425 if (__gnat_get_interrupt_state (SIGSEGV) != 's')
426 sigaction (SIGSEGV, &act, NULL);
427 if (__gnat_get_interrupt_state (SIGBUS) != 's')
428 sigaction (SIGBUS, &act, NULL);
430 __gnat_handler_installed = 1;
433 /* Routines called by s-mastop-tru64.adb. */
438 __gnat_get_code_loc (struct sigcontext *context)
440 return (char *) context->sc_pc;
444 __gnat_set_code_loc (struct sigcontext *context, char *pc)
446 context->sc_pc = (long) pc;
450 __gnat_machine_state_length (void)
452 return sizeof (struct sigcontext);
459 #elif defined (__hpux__)
462 #include <sys/ucontext.h>
465 __gnat_error_handler (int sig, siginfo_t *siginfo, void *ucontext);
467 #if defined (__hppa__)
469 /* __gnat_adjust_context_for_raise - see comments along with the default
470 version later in this file. */
472 #define HAVE_GNAT_ADJUST_CONTEXT_FOR_RAISE
475 __gnat_adjust_context_for_raise (int signo ATTRIBUTE_UNUSED, void *ucontext)
477 mcontext_t *mcontext = &((ucontext_t *) ucontext)->uc_mcontext;
479 if (UseWideRegs (mcontext))
480 mcontext->ss_wide.ss_32.ss_pcoq_head_lo ++;
482 mcontext->ss_narrow.ss_pcoq_head ++;
489 (int sig, siginfo_t *siginfo ATTRIBUTE_UNUSED, void *ucontext)
491 struct Exception_Data *exception;
497 /* FIXME: we need to detect the case of a *real* SIGSEGV. */
498 exception = &storage_error;
499 msg = "stack overflow or erroneous memory access";
503 exception = &constraint_error;
508 exception = &constraint_error;
513 exception = &program_error;
514 msg = "unhandled signal";
517 __gnat_adjust_context_for_raise (sig, ucontext);
519 Raise_From_Signal_Handler (exception, msg);
522 /* This must be in keeping with System.OS_Interface.Alternate_Stack_Size. */
523 #if defined (__hppa__)
524 char __gnat_alternate_stack[16 * 1024]; /* 2 * SIGSTKSZ */
526 char __gnat_alternate_stack[128 * 1024]; /* MINSIGSTKSZ */
530 __gnat_install_handler (void)
532 struct sigaction act;
534 /* Set up signal handler to map synchronous signals to appropriate
535 exceptions. Make sure that the handler isn't interrupted by another
536 signal that might cause a scheduling event! Also setup an alternate
537 stack region for the handler execution so that stack overflows can be
538 handled properly, avoiding a SEGV generation from stack usage by the
542 stack.ss_sp = __gnat_alternate_stack;
543 stack.ss_size = sizeof (__gnat_alternate_stack);
545 sigaltstack (&stack, NULL);
547 act.sa_sigaction = __gnat_error_handler;
548 act.sa_flags = SA_NODEFER | SA_RESTART | SA_SIGINFO;
549 sigemptyset (&act.sa_mask);
551 /* Do not install handlers if interrupt state is "System". */
552 if (__gnat_get_interrupt_state (SIGABRT) != 's')
553 sigaction (SIGABRT, &act, NULL);
554 if (__gnat_get_interrupt_state (SIGFPE) != 's')
555 sigaction (SIGFPE, &act, NULL);
556 if (__gnat_get_interrupt_state (SIGILL) != 's')
557 sigaction (SIGILL, &act, NULL);
558 if (__gnat_get_interrupt_state (SIGBUS) != 's')
559 sigaction (SIGBUS, &act, NULL);
560 act.sa_flags |= SA_ONSTACK;
561 if (__gnat_get_interrupt_state (SIGSEGV) != 's')
562 sigaction (SIGSEGV, &act, NULL);
564 __gnat_handler_installed = 1;
567 /*********************/
568 /* GNU/Linux Section */
569 /*********************/
571 #elif defined (linux) && (defined (i386) || defined (__x86_64__) \
572 || defined (__ia64__) || defined (__powerpc__))
576 #define __USE_GNU 1 /* required to get REG_EIP/RIP from glibc's ucontext.h */
577 #include <sys/ucontext.h>
579 /* GNU/Linux, which uses glibc, does not define NULL in included
583 #define NULL ((void *) 0)
588 /* MaRTE OS provides its own version of sigaction, sigfillset, and
589 sigemptyset (overriding these symbol names). We want to make sure that
590 the versions provided by the underlying C library are used here (these
591 versions are renamed by MaRTE to linux_sigaction, fake_linux_sigfillset,
592 and fake_linux_sigemptyset, respectively). The MaRTE library will not
593 always be present (it will not be linked if no tasking constructs are
594 used), so we use the weak symbol mechanism to point always to the symbols
595 defined within the C library. */
597 #pragma weak linux_sigaction
598 int linux_sigaction (int signum, const struct sigaction *act,
599 struct sigaction *oldact) {
600 return sigaction (signum, act, oldact);
602 #define sigaction(signum, act, oldact) linux_sigaction (signum, act, oldact)
604 #pragma weak fake_linux_sigfillset
605 void fake_linux_sigfillset (sigset_t *set) {
608 #define sigfillset(set) fake_linux_sigfillset (set)
610 #pragma weak fake_linux_sigemptyset
611 void fake_linux_sigemptyset (sigset_t *set) {
614 #define sigemptyset(set) fake_linux_sigemptyset (set)
618 static void __gnat_error_handler (int, siginfo_t *siginfo, void *ucontext);
620 /* __gnat_adjust_context_for_raise - see comments along with the default
621 version later in this file. */
623 #define HAVE_GNAT_ADJUST_CONTEXT_FOR_RAISE
626 __gnat_adjust_context_for_raise (int signo ATTRIBUTE_UNUSED, void *ucontext)
629 mcontext_t *mcontext = &((ucontext_t *) ucontext)->uc_mcontext;
632 /* On the i386 and x86-64 architectures, stack checking is performed by
633 means of probes with moving stack pointer, that is to say the probed
634 address is always the value of the stack pointer. Upon hitting the
635 guard page, the stack pointer therefore points to an inaccessible
636 address and an alternate signal stack is needed to run the handler.
637 But there is an additional twist: on these architectures, the EH
638 return code writes the address of the handler at the target CFA's
639 value on the stack before doing the jump. As a consequence, if
640 there is an active handler in the frame whose stack has overflowed,
641 the stack pointer must nevertheless point to an accessible address
642 by the time the EH return is executed.
644 We therefore adjust the saved value of the stack pointer by the size
645 of one page, in order to make sure that it points to an accessible
646 address in case it's used as the target CFA. The stack checking code
647 guarantees that this page is unused by the time this happens. */
650 unsigned long pattern = *(unsigned long *)mcontext->gregs[REG_EIP];
651 /* The pattern is "orl $0x0,(%esp)" for a probe in 32-bit mode. */
652 if (signo == SIGSEGV && pattern == 0x00240c83)
653 mcontext->gregs[REG_ESP] += 4096;
654 mcontext->gregs[REG_EIP]++;
655 #elif defined (__x86_64__)
656 unsigned long pattern = *(unsigned long *)mcontext->gregs[REG_RIP];
657 /* The pattern is "orq $0x0,(%rsp)" for a probe in 64-bit mode. */
658 if (signo == SIGSEGV && (pattern & 0xffffffffff) == 0x00240c8348)
659 mcontext->gregs[REG_RSP] += 4096;
660 mcontext->gregs[REG_RIP]++;
661 #elif defined (__ia64__)
663 #elif defined (__powerpc__)
664 ((ucontext_t *) ucontext)->uc_mcontext.regs->nip++;
669 __gnat_error_handler (int sig,
670 siginfo_t *siginfo ATTRIBUTE_UNUSED,
673 struct Exception_Data *exception;
675 static int recurse = 0;
680 /* If the problem was permissions, this is a constraint error.
681 Likewise if the failing address isn't maximally aligned or if
684 ??? Using a static variable here isn't task-safe, but it's
685 much too hard to do anything else and we're just determining
686 which exception to raise. */
689 exception = &constraint_error;
694 /* Here we would like a discrimination test to see whether the
695 page before the faulting address is accessible. Unfortunately
696 Linux seems to have no way of giving us the faulting address.
698 In versions of a-init.c before 1.95, we had a test of the page
699 before the stack pointer using:
703 ((long) info->esp_at_signal & - getpagesize ()))[getpagesize ()];
705 but that's wrong, since it tests the stack pointer location, and
706 the current stack probe code does not move the stack pointer
707 until all probes succeed.
709 For now we simply do not attempt any discrimination at all. Note
710 that this is quite acceptable, since a "real" SIGSEGV can only
711 occur as the result of an erroneous program. */
713 msg = "stack overflow (or erroneous memory access)";
714 exception = &storage_error;
719 exception = &constraint_error;
724 exception = &constraint_error;
729 exception = &program_error;
730 msg = "unhandled signal";
734 /* We adjust the interrupted context here (and not in the
735 MD_FALLBACK_FRAME_STATE_FOR macro) because recent versions of the Native
736 POSIX Thread Library (NPTL) are compiled with DWARF-2 unwind information,
737 and hence the later macro is never executed for signal frames. */
739 __gnat_adjust_context_for_raise (sig, ucontext);
741 Raise_From_Signal_Handler (exception, msg);
744 #if defined (i386) || defined (__x86_64__)
745 /* This must be in keeping with System.OS_Interface.Alternate_Stack_Size. */
746 char __gnat_alternate_stack[16 * 1024]; /* 2 * SIGSTKSZ */
750 __gnat_install_handler (void)
752 struct sigaction act;
754 /* Set up signal handler to map synchronous signals to appropriate
755 exceptions. Make sure that the handler isn't interrupted by another
756 signal that might cause a scheduling event! Also setup an alternate
757 stack region for the handler execution so that stack overflows can be
758 handled properly, avoiding a SEGV generation from stack usage by the
761 #if defined (i386) || defined (__x86_64__)
763 stack.ss_sp = __gnat_alternate_stack;
764 stack.ss_size = sizeof (__gnat_alternate_stack);
766 sigaltstack (&stack, NULL);
769 act.sa_sigaction = __gnat_error_handler;
770 act.sa_flags = SA_NODEFER | SA_RESTART | SA_SIGINFO;
771 sigemptyset (&act.sa_mask);
773 /* Do not install handlers if interrupt state is "System". */
774 if (__gnat_get_interrupt_state (SIGABRT) != 's')
775 sigaction (SIGABRT, &act, NULL);
776 if (__gnat_get_interrupt_state (SIGFPE) != 's')
777 sigaction (SIGFPE, &act, NULL);
778 if (__gnat_get_interrupt_state (SIGILL) != 's')
779 sigaction (SIGILL, &act, NULL);
780 if (__gnat_get_interrupt_state (SIGBUS) != 's')
781 sigaction (SIGBUS, &act, NULL);
782 #if defined (i386) || defined (__x86_64__)
783 act.sa_flags |= SA_ONSTACK;
785 if (__gnat_get_interrupt_state (SIGSEGV) != 's')
786 sigaction (SIGSEGV, &act, NULL);
788 __gnat_handler_installed = 1;
804 #define SIGADAABORT 48
805 #define SIGNAL_STACK_SIZE 4096
806 #define SIGNAL_STACK_ALIGNMENT 64
808 #define Check_Abort_Status \
809 system__soft_links__check_abort_status
810 extern int (*Check_Abort_Status) (void);
812 extern struct Exception_Data _abort_signal;
814 static void __gnat_error_handler (int, int, sigcontext_t *);
816 /* We are not setting the SA_SIGINFO bit in the sigaction flags when
817 connecting that handler, with the effects described in the sigaction
821 If cleared and the signal is caught, the first argument is
822 also the signal number but the second argument is the signal
823 code identifying the cause of the signal. The third argument
824 points to a sigcontext_t structure containing the receiving
825 process's context when the signal was delivered. */
828 __gnat_error_handler (int sig, int code, sigcontext_t *sc ATTRIBUTE_UNUSED)
830 struct Exception_Data *exception;
838 exception = &program_error;
839 msg = "SIGSEGV: (Invalid virtual address)";
841 else if (code == ENXIO)
843 exception = &program_error;
844 msg = "SIGSEGV: (Read beyond mapped object)";
846 else if (code == ENOSPC)
848 exception = &program_error; /* ??? storage_error ??? */
849 msg = "SIGSEGV: (Autogrow for file failed)";
851 else if (code == EACCES || code == EEXIST)
853 /* ??? We handle stack overflows here, some of which do trigger
854 SIGSEGV + EEXIST on Irix 6.5 although EEXIST is not part of
855 the documented valid codes for SEGV in the signal(5) man
858 /* ??? Re-add smarts to further verify that we launched
859 the stack into a guard page, not an attempt to
860 write to .text or something. */
861 exception = &storage_error;
862 msg = "SIGSEGV: (stack overflow or erroneous memory access)";
866 /* Just in case the OS guys did it to us again. Sometimes
867 they fail to document all of the valid codes that are
868 passed to signal handlers, just in case someone depends
869 on knowing all the codes. */
870 exception = &program_error;
871 msg = "SIGSEGV: (Undocumented reason)";
876 /* Map all bus errors to Program_Error. */
877 exception = &program_error;
882 /* Map all fpe errors to Constraint_Error. */
883 exception = &constraint_error;
888 if ((*Check_Abort_Status) ())
890 exception = &_abort_signal;
899 /* Everything else is a Program_Error. */
900 exception = &program_error;
901 msg = "unhandled signal";
904 Raise_From_Signal_Handler (exception, msg);
908 __gnat_install_handler (void)
910 struct sigaction act;
912 /* Setup signal handler to map synchronous signals to appropriate
913 exceptions. Make sure that the handler isn't interrupted by another
914 signal that might cause a scheduling event! */
916 act.sa_handler = __gnat_error_handler;
917 act.sa_flags = SA_NODEFER + SA_RESTART;
918 sigfillset (&act.sa_mask);
919 sigemptyset (&act.sa_mask);
921 /* Do not install handlers if interrupt state is "System". */
922 if (__gnat_get_interrupt_state (SIGABRT) != 's')
923 sigaction (SIGABRT, &act, NULL);
924 if (__gnat_get_interrupt_state (SIGFPE) != 's')
925 sigaction (SIGFPE, &act, NULL);
926 if (__gnat_get_interrupt_state (SIGILL) != 's')
927 sigaction (SIGILL, &act, NULL);
928 if (__gnat_get_interrupt_state (SIGSEGV) != 's')
929 sigaction (SIGSEGV, &act, NULL);
930 if (__gnat_get_interrupt_state (SIGBUS) != 's')
931 sigaction (SIGBUS, &act, NULL);
932 if (__gnat_get_interrupt_state (SIGADAABORT) != 's')
933 sigaction (SIGADAABORT, &act, NULL);
935 __gnat_handler_installed = 1;
938 /*******************/
940 /*******************/
942 #elif defined (__Lynx__)
948 __gnat_error_handler (int sig)
950 struct Exception_Data *exception;
956 exception = &constraint_error;
960 exception = &constraint_error;
964 exception = &storage_error;
965 msg = "stack overflow or erroneous memory access";
968 exception = &constraint_error;
972 exception = &program_error;
973 msg = "unhandled signal";
976 Raise_From_Signal_Handler(exception, msg);
980 __gnat_install_handler(void)
982 struct sigaction act;
984 act.sa_handler = __gnat_error_handler;
986 sigemptyset (&act.sa_mask);
988 /* Do not install handlers if interrupt state is "System". */
989 if (__gnat_get_interrupt_state (SIGFPE) != 's')
990 sigaction (SIGFPE, &act, NULL);
991 if (__gnat_get_interrupt_state (SIGILL) != 's')
992 sigaction (SIGILL, &act, NULL);
993 if (__gnat_get_interrupt_state (SIGSEGV) != 's')
994 sigaction (SIGSEGV, &act, NULL);
995 if (__gnat_get_interrupt_state (SIGBUS) != 's')
996 sigaction (SIGBUS, &act, NULL);
998 __gnat_handler_installed = 1;
1001 /*******************/
1002 /* Solaris Section */
1003 /*******************/
1005 #elif defined (sun) && defined (__SVR4) && !defined (__vxworks)
1008 #include <siginfo.h>
1009 #include <sys/ucontext.h>
1010 #include <sys/regset.h>
1012 /* The code below is common to SPARC and x86. Beware of the delay slot
1013 differences for signal context adjustments. */
1015 #if defined (__sparc)
1016 #define RETURN_ADDR_OFFSET 8
1018 #define RETURN_ADDR_OFFSET 0
1021 /* Likewise regarding how the "instruction pointer" register slot can
1022 be identified in signal machine contexts. We have either "REG_PC"
1023 or "PC" at hand, depending on the target CPU and Solaris version. */
1025 #if !defined (REG_PC)
1029 static void __gnat_error_handler (int, siginfo_t *, ucontext_t *);
1031 /* __gnat_adjust_context_for_raise - see comments along with the default
1032 version later in this file. */
1034 #define HAVE_GNAT_ADJUST_CONTEXT_FOR_RAISE
1037 __gnat_adjust_context_for_raise (int signo ATTRIBUTE_UNUSED,
1040 mcontext_t *mcontext = & ((ucontext_t *)ucontext)->uc_mcontext;
1041 mcontext->gregs[REG_PC] += (1 - RETURN_ADDR_OFFSET);
1045 __gnat_error_handler (int sig, siginfo_t *sip, ucontext_t *uctx)
1047 struct Exception_Data *exception;
1048 static int recurse = 0;
1051 /* Adjusting is required for every fault context, so adjust for this one
1052 now, before we possibly trigger a recursive fault below. */
1053 __gnat_adjust_context_for_raise (sig, (void *)uctx);
1055 /* If this was an explicit signal from a "kill", just resignal it. */
1056 if (SI_FROMUSER (sip))
1058 signal (sig, SIG_DFL);
1059 kill (getpid(), sig);
1062 /* Otherwise, treat it as something we handle. */
1066 /* If the problem was permissions, this is a constraint error.
1067 Likewise if the failing address isn't maximally aligned or if
1070 ??? Using a static variable here isn't task-safe, but it's
1071 much too hard to do anything else and we're just determining
1072 which exception to raise. */
1073 if (sip->si_code == SEGV_ACCERR
1074 || (((long) sip->si_addr) & 3) != 0
1077 exception = &constraint_error;
1082 /* See if the page before the faulting page is accessible. Do that
1083 by trying to access it. We'd like to simply try to access
1084 4096 + the faulting address, but it's not guaranteed to be
1085 the actual address, just to be on the same page. */
1088 ((long) sip->si_addr & - getpagesize ()))[getpagesize ()];
1089 exception = &storage_error;
1090 msg = "stack overflow (or erroneous memory access)";
1095 exception = &program_error;
1100 exception = &constraint_error;
1105 exception = &program_error;
1106 msg = "unhandled signal";
1111 Raise_From_Signal_Handler (exception, msg);
1115 __gnat_install_handler (void)
1117 struct sigaction act;
1119 /* Set up signal handler to map synchronous signals to appropriate
1120 exceptions. Make sure that the handler isn't interrupted by another
1121 signal that might cause a scheduling event! */
1123 act.sa_handler = __gnat_error_handler;
1124 act.sa_flags = SA_NODEFER | SA_RESTART | SA_SIGINFO;
1125 sigemptyset (&act.sa_mask);
1127 /* Do not install handlers if interrupt state is "System". */
1128 if (__gnat_get_interrupt_state (SIGABRT) != 's')
1129 sigaction (SIGABRT, &act, NULL);
1130 if (__gnat_get_interrupt_state (SIGFPE) != 's')
1131 sigaction (SIGFPE, &act, NULL);
1132 if (__gnat_get_interrupt_state (SIGSEGV) != 's')
1133 sigaction (SIGSEGV, &act, NULL);
1134 if (__gnat_get_interrupt_state (SIGBUS) != 's')
1135 sigaction (SIGBUS, &act, NULL);
1137 __gnat_handler_installed = 1;
1146 long __gnat_error_handler (int *, void *);
1149 #define lib_get_curr_invo_context LIB$I64_GET_CURR_INVO_CONTEXT
1150 #define lib_get_prev_invo_context LIB$I64_GET_PREV_INVO_CONTEXT
1151 #define lib_get_invo_handle LIB$I64_GET_INVO_HANDLE
1153 #define lib_get_curr_invo_context LIB$GET_CURR_INVO_CONTEXT
1154 #define lib_get_prev_invo_context LIB$GET_PREV_INVO_CONTEXT
1155 #define lib_get_invo_handle LIB$GET_INVO_HANDLE
1158 #if defined (IN_RTS) && !defined (__IA64)
1160 /* The prehandler actually gets control first on a condition. It swaps the
1161 stack pointer and calls the handler (__gnat_error_handler). */
1162 extern long __gnat_error_prehandler (void);
1164 extern char *__gnat_error_prehandler_stack; /* Alternate signal stack */
1167 /* Define macro symbols for the VMS conditions that become Ada exceptions.
1168 Most of these are also defined in the header file ssdef.h which has not
1169 yet been converted to be recognized by GNU C. */
1171 /* Defining these as macros, as opposed to external addresses, allows
1172 them to be used in a case statement below. */
1173 #define SS$_ACCVIO 12
1174 #define SS$_HPARITH 1284
1175 #define SS$_STKOVF 1364
1176 #define SS$_RESIGNAL 2328
1178 /* These codes are in standard message libraries. */
1179 extern int CMA$_EXIT_THREAD;
1180 extern int SS$_DEBUG;
1181 extern int SS$_INTDIV;
1182 extern int LIB$_KEYNOTFOU;
1183 extern int LIB$_ACTIMAGE;
1184 extern int MTH$_FLOOVEMAT; /* Some ACVC_21 CXA tests */
1186 /* These codes are non standard, which is to say the author is
1187 not sure if they are defined in the standard message libraries
1188 so keep them as macros for now. */
1189 #define RDB$_STREAM_EOF 20480426
1190 #define FDL$_UNPRIKW 11829410
1192 struct cond_except {
1194 const struct Exception_Data *except;
1197 struct descriptor_s {unsigned short len, mbz; __char_ptr32 adr; };
1199 /* Conditions that don't have an Ada exception counterpart must raise
1200 Non_Ada_Error. Since this is defined in s-auxdec, it should only be
1201 referenced by user programs, not the compiler or tools. Hence the
1206 #define Status_Error ada__io_exceptions__status_error
1207 extern struct Exception_Data Status_Error;
1209 #define Mode_Error ada__io_exceptions__mode_error
1210 extern struct Exception_Data Mode_Error;
1212 #define Name_Error ada__io_exceptions__name_error
1213 extern struct Exception_Data Name_Error;
1215 #define Use_Error ada__io_exceptions__use_error
1216 extern struct Exception_Data Use_Error;
1218 #define Device_Error ada__io_exceptions__device_error
1219 extern struct Exception_Data Device_Error;
1221 #define End_Error ada__io_exceptions__end_error
1222 extern struct Exception_Data End_Error;
1224 #define Data_Error ada__io_exceptions__data_error
1225 extern struct Exception_Data Data_Error;
1227 #define Layout_Error ada__io_exceptions__layout_error
1228 extern struct Exception_Data Layout_Error;
1230 #define Non_Ada_Error system__aux_dec__non_ada_error
1231 extern struct Exception_Data Non_Ada_Error;
1233 #define Coded_Exception system__vms_exception_table__coded_exception
1234 extern struct Exception_Data *Coded_Exception (Exception_Code);
1236 #define Base_Code_In system__vms_exception_table__base_code_in
1237 extern Exception_Code Base_Code_In (Exception_Code);
1239 /* DEC Ada exceptions are not defined in a header file, so they
1240 must be declared as external addresses. */
1242 extern int ADA$_PROGRAM_ERROR;
1243 extern int ADA$_LOCK_ERROR;
1244 extern int ADA$_EXISTENCE_ERROR;
1245 extern int ADA$_KEY_ERROR;
1246 extern int ADA$_KEYSIZERR;
1247 extern int ADA$_STAOVF;
1248 extern int ADA$_CONSTRAINT_ERRO;
1249 extern int ADA$_IOSYSFAILED;
1250 extern int ADA$_LAYOUT_ERROR;
1251 extern int ADA$_STORAGE_ERROR;
1252 extern int ADA$_DATA_ERROR;
1253 extern int ADA$_DEVICE_ERROR;
1254 extern int ADA$_END_ERROR;
1255 extern int ADA$_MODE_ERROR;
1256 extern int ADA$_NAME_ERROR;
1257 extern int ADA$_STATUS_ERROR;
1258 extern int ADA$_NOT_OPEN;
1259 extern int ADA$_ALREADY_OPEN;
1260 extern int ADA$_USE_ERROR;
1261 extern int ADA$_UNSUPPORTED;
1262 extern int ADA$_FAC_MODE_MISMAT;
1263 extern int ADA$_ORG_MISMATCH;
1264 extern int ADA$_RFM_MISMATCH;
1265 extern int ADA$_RAT_MISMATCH;
1266 extern int ADA$_MRS_MISMATCH;
1267 extern int ADA$_MRN_MISMATCH;
1268 extern int ADA$_KEY_MISMATCH;
1269 extern int ADA$_MAXLINEXC;
1270 extern int ADA$_LINEXCMRS;
1272 /* DEC Ada specific conditions. */
1273 static const struct cond_except dec_ada_cond_except_table [] = {
1274 {&ADA$_PROGRAM_ERROR, &program_error},
1275 {&ADA$_USE_ERROR, &Use_Error},
1276 {&ADA$_KEYSIZERR, &program_error},
1277 {&ADA$_STAOVF, &storage_error},
1278 {&ADA$_CONSTRAINT_ERRO, &constraint_error},
1279 {&ADA$_IOSYSFAILED, &Device_Error},
1280 {&ADA$_LAYOUT_ERROR, &Layout_Error},
1281 {&ADA$_STORAGE_ERROR, &storage_error},
1282 {&ADA$_DATA_ERROR, &Data_Error},
1283 {&ADA$_DEVICE_ERROR, &Device_Error},
1284 {&ADA$_END_ERROR, &End_Error},
1285 {&ADA$_MODE_ERROR, &Mode_Error},
1286 {&ADA$_NAME_ERROR, &Name_Error},
1287 {&ADA$_STATUS_ERROR, &Status_Error},
1288 {&ADA$_NOT_OPEN, &Use_Error},
1289 {&ADA$_ALREADY_OPEN, &Use_Error},
1290 {&ADA$_USE_ERROR, &Use_Error},
1291 {&ADA$_UNSUPPORTED, &Use_Error},
1292 {&ADA$_FAC_MODE_MISMAT, &Use_Error},
1293 {&ADA$_ORG_MISMATCH, &Use_Error},
1294 {&ADA$_RFM_MISMATCH, &Use_Error},
1295 {&ADA$_RAT_MISMATCH, &Use_Error},
1296 {&ADA$_MRS_MISMATCH, &Use_Error},
1297 {&ADA$_MRN_MISMATCH, &Use_Error},
1298 {&ADA$_KEY_MISMATCH, &Use_Error},
1299 {&ADA$_MAXLINEXC, &constraint_error},
1300 {&ADA$_LINEXCMRS, &constraint_error},
1305 /* Already handled by a pragma Import_Exception
1306 in Aux_IO_Exceptions */
1307 {&ADA$_LOCK_ERROR, &Lock_Error},
1308 {&ADA$_EXISTENCE_ERROR, &Existence_Error},
1309 {&ADA$_KEY_ERROR, &Key_Error},
1314 /* Non-DEC Ada specific conditions. We could probably also put
1315 SS$_HPARITH here and possibly SS$_ACCVIO, SS$_STKOVF. */
1316 static const struct cond_except cond_except_table [] = {
1317 {&MTH$_FLOOVEMAT, &constraint_error},
1318 {&SS$_INTDIV, &constraint_error},
1322 /* To deal with VMS conditions and their mapping to Ada exceptions,
1323 the __gnat_error_handler routine below is installed as an exception
1324 vector having precedence over DEC frame handlers. Some conditions
1325 still need to be handled by such handlers, however, in which case
1326 __gnat_error_handler needs to return SS$_RESIGNAL. Consider for
1327 instance the use of a third party library compiled with DECAda and
1328 performing its own exception handling internally.
1330 To allow some user-level flexibility, which conditions should be
1331 resignaled is controlled by a predicate function, provided with the
1332 condition value and returning a boolean indication stating whether
1333 this condition should be resignaled or not.
1335 That predicate function is called indirectly, via a function pointer,
1336 by __gnat_error_handler, and changing that pointer is allowed to the
1337 the user code by way of the __gnat_set_resignal_predicate interface.
1339 The user level function may then implement what it likes, including
1340 for instance the maintenance of a dynamic data structure if the set
1341 of to be resignalled conditions has to change over the program's
1344 ??? This is not a perfect solution to deal with the possible
1345 interactions between the GNAT and the DECAda exception handling
1346 models and better (more general) schemes are studied. This is so
1347 just provided as a convenient workaround in the meantime, and
1348 should be use with caution since the implementation has been kept
1352 resignal_predicate (int code);
1354 const int *cond_resignal_table [] = {
1359 (int *) RDB$_STREAM_EOF,
1360 (int *) FDL$_UNPRIKW,
1364 const int facility_resignal_table [] = {
1365 0x1380000, /* RDB */
1366 0x2220000, /* SQL */
1370 /* Default GNAT predicate for resignaling conditions. */
1373 __gnat_default_resignal_p (int code)
1377 for (i = 0; facility_resignal_table [i]; i++)
1378 if ((code & 0xfff0000) == facility_resignal_table [i])
1381 for (i = 0, iexcept = 0;
1382 cond_resignal_table [i] &&
1383 !(iexcept = LIB$MATCH_COND (&code, &cond_resignal_table [i]));
1389 /* Static pointer to predicate that the __gnat_error_handler exception
1390 vector invokes to determine if it should resignal a condition. */
1392 static resignal_predicate * __gnat_resignal_p = __gnat_default_resignal_p;
1394 /* User interface to change the predicate pointer to PREDICATE. Reset to
1395 the default if PREDICATE is null. */
1398 __gnat_set_resignal_predicate (resignal_predicate * predicate)
1401 __gnat_resignal_p = __gnat_default_resignal_p;
1403 __gnat_resignal_p = predicate;
1406 /* Should match System.Parameters.Default_Exception_Msg_Max_Length. */
1407 #define Default_Exception_Msg_Max_Length 512
1409 /* Action routine for SYS$PUTMSG. There may be multiple
1410 conditions, each with text to be appended to MESSAGE
1411 and separated by line termination. */
1414 copy_msg (msgdesc, message)
1415 struct descriptor_s *msgdesc;
1418 int len = strlen (message);
1421 /* Check for buffer overflow and skip. */
1422 if (len > 0 && len <= Default_Exception_Msg_Max_Length - 3)
1424 strcat (message, "\r\n");
1428 /* Check for buffer overflow and truncate if necessary. */
1429 copy_len = (len + msgdesc->len <= Default_Exception_Msg_Max_Length - 1 ?
1431 Default_Exception_Msg_Max_Length - 1 - len);
1432 strncpy (&message [len], msgdesc->adr, copy_len);
1433 message [len + copy_len] = 0;
1439 __gnat_handle_vms_condition (int *sigargs, void *mechargs)
1441 struct Exception_Data *exception = 0;
1442 Exception_Code base_code;
1443 struct descriptor_s gnat_facility = {4,0,"GNAT"};
1444 char message [Default_Exception_Msg_Max_Length];
1446 const char *msg = "";
1448 /* Check for conditions to resignal which aren't effected by pragma
1449 Import_Exception. */
1450 if (__gnat_resignal_p (sigargs [1]))
1451 return SS$_RESIGNAL;
1454 /* See if it's an imported exception. Beware that registered exceptions
1455 are bound to their base code, with the severity bits masked off. */
1456 base_code = Base_Code_In ((Exception_Code) sigargs [1]);
1457 exception = Coded_Exception (base_code);
1463 /* Subtract PC & PSL fields which messes with PUTMSG. */
1465 SYS$PUTMSG (sigargs, copy_msg, &gnat_facility, message);
1469 exception->Name_Length = 19;
1470 /* ??? The full name really should be get sys$getmsg returns. */
1471 exception->Full_Name = "IMPORTED_EXCEPTION";
1472 exception->Import_Code = base_code;
1475 /* Do not adjust the program counter as already points to the next
1476 instruction (just after the call to LIB$STOP). */
1477 Raise_From_Signal_Handler (exception, msg);
1486 if (sigargs[3] == 0)
1488 exception = &constraint_error;
1489 msg = "access zero";
1493 exception = &storage_error;
1494 msg = "stack overflow (or erroneous memory access)";
1496 __gnat_adjust_context_for_raise (0, (void *)mechargs);
1500 exception = &storage_error;
1501 msg = "stack overflow";
1502 __gnat_adjust_context_for_raise (0, (void *)mechargs);
1507 return SS$_RESIGNAL; /* toplev.c handles for compiler */
1509 exception = &constraint_error;
1510 msg = "arithmetic error";
1512 /* No need to adjust pc on Alpha: the pc is already on the instruction
1513 after the trapping one. */
1514 __gnat_adjust_context_for_raise (0, (void *)mechargs);
1524 /* Scan the DEC Ada exception condition table for a match and fetch
1525 the associated GNAT exception pointer. */
1527 dec_ada_cond_except_table [i].cond &&
1528 !LIB$MATCH_COND (&sigargs [1],
1529 &dec_ada_cond_except_table [i].cond);
1531 exception = (struct Exception_Data *)
1532 dec_ada_cond_except_table [i].except;
1536 /* Scan the VMS standard condition table for a match and fetch
1537 the associated GNAT exception pointer. */
1539 cond_except_table [i].cond &&
1540 !LIB$MATCH_COND (&sigargs [1], &cond_except_table [i].cond);
1542 exception = (struct Exception_Data *)
1543 cond_except_table [i].except;
1546 /* User programs expect Non_Ada_Error to be raised, reference
1547 DEC Ada test CXCONDHAN. */
1548 exception = &Non_Ada_Error;
1552 exception = &program_error;
1555 /* Subtract PC & PSL fields which messes with PUTMSG. */
1557 SYS$PUTMSG (sigargs, copy_msg, &gnat_facility, message);
1563 Raise_From_Signal_Handler (exception, msg);
1567 __gnat_error_handler (int *sigargs, void *mechargs)
1569 return __gnat_handle_vms_condition (sigargs, mechargs);
1573 __gnat_install_handler (void)
1575 long prvhnd ATTRIBUTE_UNUSED;
1577 #if !defined (IN_RTS)
1578 SYS$SETEXV (1, __gnat_error_handler, 3, &prvhnd);
1581 /* On alpha-vms, we avoid the global vector annoyance thanks to frame based
1582 handlers to turn conditions into exceptions since GCC 3.4. The global
1583 vector is still required for earlier GCC versions. We're resorting to
1584 the __gnat_error_prehandler assembly function in this case. */
1586 #if defined (IN_RTS) && defined (__alpha__)
1587 if ((__GNUC__ * 10 + __GNUC_MINOR__) < 34)
1589 char * c = (char *) xmalloc (2049);
1591 __gnat_error_prehandler_stack = &c[2048];
1592 SYS$SETEXV (1, __gnat_error_prehandler, 3, &prvhnd);
1596 __gnat_handler_installed = 1;
1599 /* __gnat_adjust_context_for_raise for Alpha - see comments along with the
1600 default version later in this file. */
1602 #if defined (IN_RTS) && defined (__alpha__)
1604 #include <vms/chfctxdef.h>
1605 #include <vms/chfdef.h>
1607 #define HAVE_GNAT_ADJUST_CONTEXT_FOR_RAISE
1610 __gnat_adjust_context_for_raise (int signo ATTRIBUTE_UNUSED, void *ucontext)
1612 /* Add one to the address of the instruction signaling the condition,
1613 located in the sigargs array. */
1615 CHF$MECH_ARRAY * mechargs = (CHF$MECH_ARRAY *) ucontext;
1616 CHF$SIGNAL_ARRAY * sigargs
1617 = (CHF$SIGNAL_ARRAY *) mechargs->chf$q_mch_sig_addr;
1619 int vcount = sigargs->chf$is_sig_args;
1620 int * pc_slot = & (&sigargs->chf$l_sig_name)[vcount-2];
1627 /* __gnat_adjust_context_for_raise for ia64. */
1629 #if defined (IN_RTS) && defined (__IA64)
1631 #include <vms/chfctxdef.h>
1632 #include <vms/chfdef.h>
1634 #define HAVE_GNAT_ADJUST_CONTEXT_FOR_RAISE
1636 typedef unsigned long long u64;
1639 __gnat_adjust_context_for_raise (int signo ATTRIBUTE_UNUSED, void *ucontext)
1641 /* Add one to the address of the instruction signaling the condition,
1642 located in the 64bits sigargs array. */
1644 CHF$MECH_ARRAY * mechargs = (CHF$MECH_ARRAY *) ucontext;
1646 CHF64$SIGNAL_ARRAY *chfsig64
1647 = (CHF64$SIGNAL_ARRAY *) mechargs->chf$ph_mch_sig64_addr;
1650 = (u64 *)chfsig64 + 1 + chfsig64->chf64$l_sig_args;
1652 u64 * ih_pc_loc = post_sigarray - 2;
1659 /*******************/
1660 /* FreeBSD Section */
1661 /*******************/
1663 #elif defined (__FreeBSD__)
1666 #include <sys/ucontext.h>
1669 static void __gnat_error_handler (int, siginfo_t *, ucontext_t *);
1670 void __gnat_adjust_context_for_raise (int, void*);
1672 /* __gnat_adjust_context_for_raise - see comments along with the default
1673 version later in this file. */
1675 #define HAVE_GNAT_ADJUST_CONTEXT_FOR_RAISE
1678 __gnat_adjust_context_for_raise (int signo ATTRIBUTE_UNUSED, void *ucontext)
1680 mcontext_t *mcontext = &((ucontext_t *) ucontext)->uc_mcontext;
1685 __gnat_error_handler (int sig, siginfo_t *info __attribute__ ((unused)),
1686 ucontext_t *ucontext)
1688 struct Exception_Data *exception;
1694 exception = &constraint_error;
1699 exception = &constraint_error;
1704 exception = &storage_error;
1705 msg = "stack overflow or erroneous memory access";
1709 exception = &constraint_error;
1714 exception = &program_error;
1715 msg = "unhandled signal";
1718 __gnat_adjust_context_for_raise (sig, ucontext);
1719 Raise_From_Signal_Handler (exception, msg);
1723 __gnat_install_handler ()
1725 struct sigaction act;
1727 /* Set up signal handler to map synchronous signals to appropriate
1728 exceptions. Make sure that the handler isn't interrupted by another
1729 signal that might cause a scheduling event! */
1732 = (void (*)(int, struct __siginfo *, void*)) __gnat_error_handler;
1733 act.sa_flags = SA_NODEFER | SA_RESTART | SA_SIGINFO;
1734 (void) sigemptyset (&act.sa_mask);
1736 (void) sigaction (SIGILL, &act, NULL);
1737 (void) sigaction (SIGFPE, &act, NULL);
1738 (void) sigaction (SIGSEGV, &act, NULL);
1739 (void) sigaction (SIGBUS, &act, NULL);
1741 __gnat_handler_installed = 1;
1744 /*******************/
1745 /* VxWorks Section */
1746 /*******************/
1748 #elif defined(__vxworks)
1751 #include <taskLib.h>
1759 #include "private/vThreadsP.h"
1762 void __gnat_error_handler (int, void *, struct sigcontext *);
1766 /* Directly vectored Interrupt routines are not supported when using RTPs. */
1768 extern int __gnat_inum_to_ivec (int);
1770 /* This is needed by the GNAT run time to handle Vxworks interrupts. */
1772 __gnat_inum_to_ivec (int num)
1774 return INUM_TO_IVEC (num);
1778 #if !defined(__alpha_vxworks) && (_WRS_VXWORKS_MAJOR != 6) && !defined(__RTP__)
1780 /* getpid is used by s-parint.adb, but is not defined by VxWorks, except
1781 on Alpha VxWorks and VxWorks 6.x (including RTPs). */
1783 extern long getpid (void);
1788 return taskIdSelf ();
1792 /* VxWorks expects the field excCnt to be zeroed when a signal is handled.
1793 The VxWorks version of longjmp does this; GCC's builtin_longjmp doesn't. */
1795 __gnat_clear_exception_count (void)
1798 WIND_TCB *currentTask = (WIND_TCB *) taskIdSelf();
1800 currentTask->vThreads.excCnt = 0;
1805 /* VxWorks context adjustment for targets that need/support it. */
1807 void __gnat_adjust_context_for_raise (int, void*);
1809 #if defined (_ARCH_PPC) && !defined (VTHREADS) && !defined (__RTP__)
1811 #define HAVE_GNAT_ADJUST_CONTEXT_FOR_RAISE
1813 /* We need the constant and structure definitions describing the machine
1814 state. Part of this is normally retrieved from the VxWorks "regs.h" but
1815 #including it here gets the GCC internals instance of this file instead.
1816 We need to #include the version we need directly here, and prevent the
1817 possibly indirect inclusion of the GCC one, as its contents is useless to
1818 us and it depends on several other headers that we don't have at hand. */
1819 #include <arch/ppc/regsPpc.h>
1824 __gnat_adjust_context_for_raise (int signo ATTRIBUTE_UNUSED, void *sigcontext)
1826 REG_SET * mcontext = ((struct sigcontext *) sigcontext)->sc_pregs;
1832 /* Handle different SIGnal to exception mappings in different VxWorks
1835 __gnat_map_signal (int sig)
1837 struct Exception_Data *exception;
1843 exception = &constraint_error;
1848 exception = &constraint_error;
1849 msg = "Floating point exception or SIGILL";
1852 exception = &storage_error;
1853 msg = "SIGSEGV: possible stack overflow";
1856 exception = &storage_error;
1857 msg = "SIGBUS: possible stack overflow";
1861 /* In RTP mode a SIGSEGV is most likely due to a stack overflow,
1862 since stack checking uses the probing mechanism. */
1864 exception = &constraint_error;
1868 exception = &storage_error;
1869 msg = "SIGSEGV: possible stack overflow";
1872 /* In kernel mode a SIGILL is most likely due to a stack overflow,
1873 since stack checking uses the stack limit mechanism. */
1875 exception = &storage_error;
1876 msg = "SIGILL: possible stack overflow";
1879 exception = &program_error;
1884 exception = &program_error;
1889 exception = &program_error;
1890 msg = "unhandled signal";
1893 __gnat_clear_exception_count ();
1894 Raise_From_Signal_Handler (exception, msg);
1897 /* Tasking and Non-tasking signal handler. Map SIGnal to Ada exception
1898 propagation after the required low level adjustments. */
1901 __gnat_error_handler (int sig, void * si ATTRIBUTE_UNUSED,
1902 struct sigcontext * sc)
1906 /* VxWorks will always mask out the signal during the signal handler and
1907 will reenable it on a longjmp. GNAT does not generate a longjmp to
1908 return from a signal handler so the signal will still be masked unless
1910 sigprocmask (SIG_SETMASK, NULL, &mask);
1911 sigdelset (&mask, sig);
1912 sigprocmask (SIG_SETMASK, &mask, NULL);
1914 __gnat_adjust_context_for_raise (sig, (void *)sc);
1915 __gnat_map_signal (sig);
1919 __gnat_install_handler (void)
1921 struct sigaction act;
1923 /* Setup signal handler to map synchronous signals to appropriate
1924 exceptions. Make sure that the handler isn't interrupted by another
1925 signal that might cause a scheduling event! */
1927 act.sa_handler = __gnat_error_handler;
1928 act.sa_flags = SA_SIGINFO | SA_ONSTACK;
1929 sigemptyset (&act.sa_mask);
1931 /* For VxWorks, install all signal handlers, since pragma Interrupt_State
1932 applies to vectored hardware interrupts, not signals. */
1933 sigaction (SIGFPE, &act, NULL);
1934 sigaction (SIGILL, &act, NULL);
1935 sigaction (SIGSEGV, &act, NULL);
1936 sigaction (SIGBUS, &act, NULL);
1938 __gnat_handler_installed = 1;
1941 #define HAVE_GNAT_INIT_FLOAT
1944 __gnat_init_float (void)
1946 /* Disable overflow/underflow exceptions on the PPC processor, needed
1947 to get correct Ada semantics. Note that for AE653 vThreads, the HW
1948 overflow settings are an OS configuration issue. The instructions
1949 below have no effect. */
1950 #if defined (_ARCH_PPC) && !defined (_SOFT_FLOAT) && !defined (VTHREADS)
1955 #if (defined (__i386__) || defined (i386)) && !defined (VTHREADS)
1956 /* This is used to properly initialize the FPU on an x86 for each
1961 /* Similarly for SPARC64. Achieved by masking bits in the Trap Enable Mask
1962 field of the Floating-point Status Register (see the SPARC Architecture
1963 Manual Version 9, p 48). */
1964 #if defined (sparc64)
1966 #define FSR_TEM_NVM (1 << 27) /* Invalid operand */
1967 #define FSR_TEM_OFM (1 << 26) /* Overflow */
1968 #define FSR_TEM_UFM (1 << 25) /* Underflow */
1969 #define FSR_TEM_DZM (1 << 24) /* Division by Zero */
1970 #define FSR_TEM_NXM (1 << 23) /* Inexact result */
1974 __asm__("st %%fsr, %0" : "=m" (fsr));
1975 fsr &= ~(FSR_TEM_OFM | FSR_TEM_UFM);
1976 __asm__("ld %0, %%fsr" : : "m" (fsr));
1981 /* This subprogram is called by System.Task_Primitives.Operations.Enter_Task
1982 (if not null) when a new task is created. It is initialized by
1983 System.Stack_Checking.Operations.Initialize_Stack_Limit.
1984 The use of a hook avoids to drag stack checking subprograms if stack
1985 checking is not used. */
1986 void (*__gnat_set_stack_limit_hook)(void) = (void (*)(void))0;
1989 /******************/
1990 /* NetBSD Section */
1991 /******************/
1993 #elif defined(__NetBSD__)
1999 __gnat_error_handler (int sig)
2001 struct Exception_Data *exception;
2007 exception = &constraint_error;
2011 exception = &constraint_error;
2015 exception = &storage_error;
2016 msg = "stack overflow or erroneous memory access";
2019 exception = &constraint_error;
2023 exception = &program_error;
2024 msg = "unhandled signal";
2027 Raise_From_Signal_Handler(exception, msg);
2031 __gnat_install_handler(void)
2033 struct sigaction act;
2035 act.sa_handler = __gnat_error_handler;
2036 act.sa_flags = SA_NODEFER | SA_RESTART;
2037 sigemptyset (&act.sa_mask);
2039 /* Do not install handlers if interrupt state is "System". */
2040 if (__gnat_get_interrupt_state (SIGFPE) != 's')
2041 sigaction (SIGFPE, &act, NULL);
2042 if (__gnat_get_interrupt_state (SIGILL) != 's')
2043 sigaction (SIGILL, &act, NULL);
2044 if (__gnat_get_interrupt_state (SIGSEGV) != 's')
2045 sigaction (SIGSEGV, &act, NULL);
2046 if (__gnat_get_interrupt_state (SIGBUS) != 's')
2047 sigaction (SIGBUS, &act, NULL);
2049 __gnat_handler_installed = 1;
2052 /*******************/
2053 /* OpenBSD Section */
2054 /*******************/
2056 #elif defined(__OpenBSD__)
2062 __gnat_error_handler (int sig)
2064 struct Exception_Data *exception;
2070 exception = &constraint_error;
2074 exception = &constraint_error;
2078 exception = &storage_error;
2079 msg = "stack overflow or erroneous memory access";
2082 exception = &constraint_error;
2086 exception = &program_error;
2087 msg = "unhandled signal";
2090 Raise_From_Signal_Handler(exception, msg);
2094 __gnat_install_handler(void)
2096 struct sigaction act;
2098 act.sa_handler = __gnat_error_handler;
2099 act.sa_flags = SA_NODEFER | SA_RESTART;
2100 sigemptyset (&act.sa_mask);
2102 /* Do not install handlers if interrupt state is "System" */
2103 if (__gnat_get_interrupt_state (SIGFPE) != 's')
2104 sigaction (SIGFPE, &act, NULL);
2105 if (__gnat_get_interrupt_state (SIGILL) != 's')
2106 sigaction (SIGILL, &act, NULL);
2107 if (__gnat_get_interrupt_state (SIGSEGV) != 's')
2108 sigaction (SIGSEGV, &act, NULL);
2109 if (__gnat_get_interrupt_state (SIGBUS) != 's')
2110 sigaction (SIGBUS, &act, NULL);
2112 __gnat_handler_installed = 1;
2117 /* For all other versions of GNAT, the handler does nothing. */
2119 /*******************/
2120 /* Default Section */
2121 /*******************/
2124 __gnat_install_handler (void)
2126 __gnat_handler_installed = 1;
2131 /*********************/
2132 /* __gnat_init_float */
2133 /*********************/
2135 /* This routine is called as each process thread is created, for possible
2136 initialization of the FP processor. This version is used under INTERIX,
2137 WIN32 and could be used under OS/2. */
2139 #if defined (_WIN32) || defined (__INTERIX) || defined (__EMX__) \
2140 || defined (__Lynx__) || defined(__NetBSD__) || defined(__FreeBSD__) \
2141 || defined (__OpenBSD__)
2143 #define HAVE_GNAT_INIT_FLOAT
2146 __gnat_init_float (void)
2148 #if defined (__i386__) || defined (i386)
2150 /* This is used to properly initialize the FPU on an x86 for each
2155 #endif /* Defined __i386__ */
2159 #ifndef HAVE_GNAT_INIT_FLOAT
2161 /* All targets without a specific __gnat_init_float will use an empty one. */
2163 __gnat_init_float (void)
2168 /***********************************/
2169 /* __gnat_adjust_context_for_raise */
2170 /***********************************/
2172 #ifndef HAVE_GNAT_ADJUST_CONTEXT_FOR_RAISE
2174 /* All targets without a specific version will use an empty one. */
2176 /* Given UCONTEXT a pointer to a context structure received by a signal
2177 handler for SIGNO, perform the necessary adjustments to let the handler
2178 raise an exception. Calls to this routine are not conditioned by the
2179 propagation scheme in use. */
2182 __gnat_adjust_context_for_raise (int signo ATTRIBUTE_UNUSED,
2183 void *ucontext ATTRIBUTE_UNUSED)
2185 /* Adjustments are currently required for the GCC ZCX propagation scheme
2186 only. These adjustments (described below) are harmless for the other
2187 schemes, so may be applied unconditionally. */
2189 /* Adjustments required for a GCC ZCX propagation scheme:
2190 ------------------------------------------------------
2192 The GCC unwinder expects to be dealing with call return addresses, since
2193 this is the "nominal" case of what we retrieve while unwinding a regular
2196 To evaluate if a handler applies at some point identified by a return
2197 address, the propagation engine needs to determine what region the
2198 corresponding call instruction pertains to. Because the return address
2199 may not be attached to the same region as the call, the unwinder always
2200 subtracts "some" amount from a return address to search the region
2201 tables, amount chosen to ensure that the resulting address is inside the
2204 When we raise an exception from a signal handler, e.g. to transform a
2205 SIGSEGV into Storage_Error, things need to appear as if the signal
2206 handler had been "called" by the instruction which triggered the signal,
2207 so that exception handlers that apply there are considered. What the
2208 unwinder will retrieve as the return address from the signal handler is
2209 what it will find as the faulting instruction address in the signal
2210 context pushed by the kernel. Leaving this address untouched looses, if
2211 the triggering instruction happens to be the very first of a region, as
2212 the later adjustments performed by the unwinder would yield an address
2213 outside that region. We need to compensate for the unwinder adjustments
2214 at some point, and this is what this routine is expected to do.
2216 signo is passed because on some targets for some signals the PC in
2217 context points to the instruction after the faulting one, in which case
2218 the unwinder adjustment is still desired.
2220 We used to perform the compensation in the GCC unwinding fallback macro.
2221 The thread at http://gcc.gnu.org/ml/gcc-patches/2004-05/msg00343.html
2222 describes a couple of issues with this approach. First, on some targets
2223 the adjustment to apply depends on the triggering signal, which is not
2224 easily accessible from the macro. Besides, other languages, e.g. Java,
2225 deal with this by performing the adjustment in the signal handler before
2226 the raise, so fallback adjustments just break those front-ends. */