2004-12-10 22:47:03 -05:00
|
|
|
#include "../factor.h"
|
2005-10-23 20:50:29 -04:00
|
|
|
#include "mach_signal.h"
|
2004-10-17 19:01:16 -04:00
|
|
|
|
2006-02-07 17:29:36 -05:00
|
|
|
// this function tests if a given faulting location is in a poison page. The
|
|
|
|
// page address is taken from area + round_up_to_page_size(area_size) +
|
|
|
|
// pagesize*offset
|
|
|
|
static bool in_page(void *fault, void *i_area, CELL area_size, int offset) {
|
|
|
|
const int pagesize = getpagesize();
|
|
|
|
intptr_t area = (intptr_t) i_area;
|
|
|
|
area += pagesize * ((area_size + (pagesize - 1)) / pagesize);
|
|
|
|
area += offset * pagesize;
|
|
|
|
|
|
|
|
const int page = area / pagesize;
|
|
|
|
const int fault_page = (intptr_t)fault / pagesize;
|
|
|
|
return page == fault_page;
|
|
|
|
}
|
|
|
|
|
2004-10-17 19:01:16 -04:00
|
|
|
void signal_handler(int signal, siginfo_t* siginfo, void* uap)
|
|
|
|
{
|
2005-05-12 03:52:56 -04:00
|
|
|
if(nursery.here > nursery.limit)
|
2004-10-17 19:01:16 -04:00
|
|
|
{
|
2005-12-24 23:01:49 -05:00
|
|
|
fprintf(stderr,"Nursery space exhausted\n");
|
|
|
|
factorbug();
|
|
|
|
}
|
|
|
|
else if(compiling.here + sizeof(CELL) > compiling.limit)
|
|
|
|
{
|
|
|
|
fprintf(stderr,"Code space exhausted\n");
|
2005-05-12 01:02:39 -04:00
|
|
|
factorbug();
|
2004-10-17 19:01:16 -04:00
|
|
|
}
|
2006-02-07 17:29:36 -05:00
|
|
|
/* we wish to catch the case where we underflow/overflow the data or
|
|
|
|
// return stacks. These stacks have poison pages above and below the
|
|
|
|
// memory so we just need to test if the faulting addresss is in one of
|
|
|
|
// these pages */
|
|
|
|
|
|
|
|
/* first, underflowing the data stack */
|
|
|
|
else if(in_page(siginfo->si_addr, (void *) ds_bot, 0, -1))
|
|
|
|
{
|
|
|
|
signal_stack_error(false, false);
|
|
|
|
}
|
|
|
|
else if(in_page(siginfo->si_addr, (void *) ds_bot, ds_size, 0)) {
|
|
|
|
signal_stack_error(false, true);
|
|
|
|
}
|
|
|
|
else if(in_page(siginfo->si_addr, (void *) cs_bot, 0, -1))
|
|
|
|
{
|
|
|
|
signal_stack_error(true, false);
|
|
|
|
}
|
|
|
|
else if(in_page(siginfo->si_addr, (void *) cs_bot, cs_size, 0)) {
|
|
|
|
signal_stack_error(true, true);
|
|
|
|
}
|
|
|
|
|
2004-10-17 19:01:16 -04:00
|
|
|
else
|
2004-11-09 12:29:25 -05:00
|
|
|
signal_error(signal);
|
2004-10-17 19:01:16 -04:00
|
|
|
}
|
|
|
|
|
2006-01-30 20:11:22 -05:00
|
|
|
static void sigaction_safe(int signum, const struct sigaction *act, struct sigaction *oldact)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
ret = sigaction(signum, act, oldact);
|
|
|
|
} while(ret == -1 && errno == EINTR);
|
|
|
|
}
|
|
|
|
|
2004-10-17 19:01:16 -04:00
|
|
|
void init_signals(void)
|
|
|
|
{
|
|
|
|
struct sigaction custom_sigaction;
|
|
|
|
struct sigaction ign_sigaction;
|
2005-11-15 12:58:44 -05:00
|
|
|
|
2005-05-12 01:02:39 -04:00
|
|
|
sigemptyset(&custom_sigaction.sa_mask);
|
2004-10-17 19:01:16 -04:00
|
|
|
custom_sigaction.sa_sigaction = signal_handler;
|
|
|
|
custom_sigaction.sa_flags = SA_SIGINFO;
|
2006-01-30 20:11:22 -05:00
|
|
|
sigaction_safe(SIGABRT,&custom_sigaction,NULL);
|
|
|
|
sigaction_safe(SIGFPE,&custom_sigaction,NULL);
|
|
|
|
sigaction_safe(SIGBUS,&custom_sigaction,NULL);
|
|
|
|
sigaction_safe(SIGQUIT,&custom_sigaction,NULL);
|
|
|
|
sigaction_safe(SIGSEGV,&custom_sigaction,NULL);
|
2005-11-15 12:58:44 -05:00
|
|
|
|
|
|
|
sigemptyset(&ign_sigaction.sa_mask);
|
|
|
|
ign_sigaction.sa_handler = SIG_IGN;
|
2006-01-30 20:11:22 -05:00
|
|
|
sigaction_safe(SIGPIPE,&ign_sigaction,NULL);
|
2005-10-23 20:50:29 -04:00
|
|
|
|
|
|
|
#ifdef __APPLE__
|
|
|
|
mach_initialize();
|
|
|
|
#endif
|
2004-10-17 19:01:16 -04:00
|
|
|
}
|