diff options
author | Arnaud Charlet <charlet@gcc.gnu.org> | 2009-04-16 14:52:28 +0200 |
---|---|---|
committer | Arnaud Charlet <charlet@gcc.gnu.org> | 2009-04-16 14:52:28 +0200 |
commit | d15d61c671cb02b6dce9d583962750875e3178e9 (patch) | |
tree | 30c6a373132e5d4e1de4bb03bdf7beda67d1d2a3 /gcc/ada/init.c | |
parent | 0a0a18c30fbacdade52fa538575ff4889e145275 (diff) | |
download | gcc-d15d61c671cb02b6dce9d583962750875e3178e9.zip gcc-d15d61c671cb02b6dce9d583962750875e3178e9.tar.gz gcc-d15d61c671cb02b6dce9d583962750875e3178e9.tar.bz2 |
[multiple changes]
2009-04-16 Tristan Gingold <gingold@adacore.com>
* init.c: Detect real stack overflow on Darwin.
* system-darwin-x86.ads: Use stack probing on darwin x86.
2009-04-16 Ed Schonberg <schonberg@adacore.com>
* sem_attr.adb (Analyze_Attribute, case 'Address): It is illegal to
take the address of an intrinsic subprogram.
2009-04-16 Vincent Celier <celier@adacore.com>
* g-trasym-unimplemented.ads, g-trasym-unimplemented.adb: New file.
* g-trasym.ads: Update comments.
2009-04-16 Vasiliy Fofanov <fofanov@adacore.com>
* tracebak.c (STOP_FRAME): Verify validity of the current address
before dereferencing.
From-SVN: r146182
Diffstat (limited to 'gcc/ada/init.c')
-rw-r--r-- | gcc/ada/init.c | 40 |
1 files changed, 37 insertions, 3 deletions
diff --git a/gcc/ada/init.c b/gcc/ada/init.c index e86a975..fab0942 100644 --- a/gcc/ada/init.c +++ b/gcc/ada/init.c @@ -2098,6 +2098,8 @@ __gnat_install_handler(void) #elif defined(__APPLE__) #include <signal.h> +#include <mach/mach_vm.h> +#include <mach/vm_statistics.h> /* This must be in keeping with System.OS_Interface.Alternate_Stack_Size. */ char __gnat_alternate_stack[64 * 1024]; /* 2 * MINSIGSTKSZ */ @@ -2108,6 +2110,31 @@ static void __gnat_error_handler (int sig, siginfo_t * si, void * uc); #define UC_RESET_ALT_STACK 0x80000000 extern int sigreturn (void *uc, int flavour); +/* Return true if ADDR is within a stack guard area. */ +static int +__gnat_is_stack_guard (mach_vm_address_t addr) +{ + kern_return_t kret; + vm_region_submap_info_data_64_t info; + mach_vm_address_t start; + mach_vm_size_t size; + natural_t depth; + mach_msg_type_number_t count; + + count = VM_REGION_SUBMAP_INFO_COUNT_64; + start = addr; + size = -1; + depth = 9999; + kret = mach_vm_region_recurse (mach_task_self (), &start, &size, &depth, + (vm_region_recurse_info_t) &info, &count); + if (kret == KERN_SUCCESS + && addr >= start && addr < (start + size) + && info.protection == VM_PROT_NONE + && info.user_tag == VM_MEMORY_STACK) + return 1; + return 0; +} + static void __gnat_error_handler (int sig, siginfo_t * si, void * uc) { @@ -2118,9 +2145,16 @@ __gnat_error_handler (int sig, siginfo_t * si, void * uc) { case SIGSEGV: case SIGBUS: - /* FIXME: we need to detect the case of a *real* SIGSEGV. */ - exception = &storage_error; - msg = "stack overflow or erroneous memory access"; + if (__gnat_is_stack_guard ((mach_vm_address_t)si->si_addr)) + { + exception = &storage_error; + msg = "stack overflow"; + } + else + { + exception = &constraint_error; + msg = "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); |