aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/init.c
diff options
context:
space:
mode:
authorArnaud Charlet <charlet@gcc.gnu.org>2009-04-16 14:29:14 +0200
committerArnaud Charlet <charlet@gcc.gnu.org>2009-04-16 14:29:14 +0200
commitb61ebe4ff8d7cba1182e23591ef53a421fea8509 (patch)
tree36eca1fbafa5d71c98adccf5a4a896b086d8474d /gcc/ada/init.c
parent468ee33782f620eee72571ee61df0e3e83eb80fb (diff)
downloadgcc-b61ebe4ff8d7cba1182e23591ef53a421fea8509.zip
gcc-b61ebe4ff8d7cba1182e23591ef53a421fea8509.tar.gz
gcc-b61ebe4ff8d7cba1182e23591ef53a421fea8509.tar.bz2
[multiple changes]
2009-04-16 Ed Schonberg <schonberg@adacore.com> * sprint.adb (Write_Itype): If the itype is an array subtype, preserve the original location of the index expressions and the index subtypes, to prevent spurious out-of-scope references in gigi. 2009-04-16 Tristan Gingold <gingold@adacore.com> * init.c, s-osinte-darwin.ads, system-darwin-x86_64.ads: Add support for stack checking on darwin. 2009-04-16 Vincent Celier <celier@adacore.com> * prj-attr.adb: New attribute Runtime_Source_Dir * prj-nmsc.adb (Process_Project_Level_Array_Attributes): Process attribute Runtime_Source_Dir. (Check_Naming_Schemes): Give default values to out parameters to avoid invalid data. * prj.ads (Language_Config): New component Runtime_Source_Dir * snames.ads-tmpl: New standard name Runtime_Source_Dir From-SVN: r146177
Diffstat (limited to 'gcc/ada/init.c')
-rw-r--r--gcc/ada/init.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/gcc/ada/init.c b/gcc/ada/init.c
index 5b97d56..af9ae61 100644
--- a/gcc/ada/init.c
+++ b/gcc/ada/init.c
@@ -2099,8 +2099,15 @@ __gnat_install_handler(void)
#include <signal.h>
+/* This must be in keeping with System.OS_Interface.Alternate_Stack_Size. */
+char __gnat_alternate_stack[64 * 1024]; /* 2 * MINSIGSTKSZ */
+
static void __gnat_error_handler (int sig, siginfo_t * si, void * uc);
+/* Defined in xnu unix_signal.c */
+#define UC_RESET_ALT_STACK 0x80000000
+extern int sigreturn (void *uc, int flavour);
+
static void
__gnat_error_handler (int sig, siginfo_t * si, void * uc)
{
@@ -2113,6 +2120,9 @@ __gnat_error_handler (int sig, siginfo_t * si, void * uc)
/* FIXME: we need to detect the case of a *real* SIGSEGV. */
exception = &storage_error;
msg = "stack overflow or erroneous memory access";
+ /* Reset the use of alt stack, so that the alt stack will be used
+ for the next signal delivery. */
+ sigreturn (NULL, UC_RESET_ALT_STACK);
break;
case SIGBUS:
@@ -2140,7 +2150,16 @@ __gnat_install_handler (void)
/* Set up signal handler to map synchronous signals to appropriate
exceptions. Make sure that the handler isn't interrupted by another
- signal that might cause a scheduling event! */
+ signal that might cause a scheduling event! Also setup an alternate
+ stack region for the handler execution so that stack overflows can be
+ handled properly, avoiding a SEGV generation from stack usage by the
+ handler itself (and it is required by Darwin). */
+
+ stack_t stack;
+ stack.ss_sp = __gnat_alternate_stack;
+ stack.ss_size = sizeof (__gnat_alternate_stack);
+ stack.ss_flags = 0;
+ sigaltstack (&stack, NULL);
act.sa_flags = SA_NODEFER | SA_RESTART | SA_SIGINFO;
act.sa_sigaction = __gnat_error_handler;
@@ -2153,11 +2172,13 @@ __gnat_install_handler (void)
sigaction (SIGFPE, &act, NULL);
if (__gnat_get_interrupt_state (SIGILL) != 's')
sigaction (SIGILL, &act, NULL);
- if (__gnat_get_interrupt_state (SIGSEGV) != 's')
- sigaction (SIGSEGV, &act, NULL);
if (__gnat_get_interrupt_state (SIGBUS) != 's')
sigaction (SIGBUS, &act, NULL);
+ act.sa_flags |= SA_ONSTACK;
+ if (__gnat_get_interrupt_state (SIGSEGV) != 's')
+ sigaction (SIGSEGV, &act, NULL);
+
__gnat_handler_installed = 1;
}