2001-08-08 01:30:26 -07:00
|
|
|
/***********************************************************************/
|
|
|
|
/* */
|
|
|
|
/* Objective Caml */
|
|
|
|
/* */
|
|
|
|
/* Xavier Leroy, projet Cristal, INRIA Rocquencourt */
|
|
|
|
/* */
|
|
|
|
/* Copyright 2001 Institut National de Recherche en Informatique et */
|
|
|
|
/* en Automatique. All rights reserved. This file is distributed */
|
2001-12-07 05:41:02 -08:00
|
|
|
/* under the terms of the GNU Library General Public License, with */
|
|
|
|
/* the special exception on linking described in file ../../LICENSE. */
|
2001-08-08 01:30:26 -07:00
|
|
|
/* */
|
|
|
|
/***********************************************************************/
|
|
|
|
|
|
|
|
/* $Id$ */
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <signal.h>
|
|
|
|
#include <sys/resource.h>
|
|
|
|
|
|
|
|
static char sig_alt_stack[SIGSTKSZ];
|
|
|
|
static char * system_stack_top;
|
|
|
|
|
|
|
|
#if defined(TARGET_i386) && defined(SYS_linux_elf)
|
|
|
|
static void segv_handler(int signo, struct sigcontext sc)
|
|
|
|
{
|
|
|
|
char * fault_addr = (char *) sc.cr2;
|
|
|
|
#else
|
|
|
|
static void segv_handler(int signo, siginfo_t * info, void * context)
|
|
|
|
{
|
|
|
|
char * fault_addr = (char *) info->si_addr;
|
|
|
|
#endif
|
|
|
|
struct rlimit limit;
|
|
|
|
|
|
|
|
if (getrlimit(RLIMIT_STACK, &limit) == 0 &&
|
|
|
|
((long) fault_addr & (sizeof(long) - 1)) == 0 &&
|
|
|
|
fault_addr < system_stack_top &&
|
|
|
|
fault_addr >= system_stack_top - limit.rlim_cur - 0x2000) {
|
|
|
|
_exit(0);
|
|
|
|
} else {
|
|
|
|
_exit(4);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void f(char * c);
|
|
|
|
void g(char * c) { char d[1024]; f(d); }
|
|
|
|
void f(char * c) { char d[1024]; g(d); }
|
|
|
|
|
|
|
|
int main(int argc, char ** argv)
|
|
|
|
{
|
|
|
|
struct sigaltstack stk;
|
|
|
|
struct sigaction act;
|
2001-08-28 07:42:52 -07:00
|
|
|
struct rlimit limit;
|
|
|
|
|
2001-08-08 01:30:26 -07:00
|
|
|
stk.ss_sp = sig_alt_stack;
|
|
|
|
stk.ss_size = SIGSTKSZ;
|
|
|
|
stk.ss_flags = 0;
|
|
|
|
#if defined(TARGET_i386) && defined(SYS_linux_elf)
|
|
|
|
act.sa_handler = (void (*)(int)) segv_handler;
|
|
|
|
act.sa_flags = SA_ONSTACK | SA_NODEFER;
|
|
|
|
#else
|
|
|
|
act.sa_sigaction = segv_handler;
|
|
|
|
act.sa_flags = SA_SIGINFO | SA_ONSTACK | SA_NODEFER;
|
2001-08-28 07:42:52 -07:00
|
|
|
#endif
|
2001-08-08 01:30:26 -07:00
|
|
|
sigemptyset(&act.sa_mask);
|
|
|
|
system_stack_top = (char *) &act;
|
2001-08-28 07:42:52 -07:00
|
|
|
limit.rlim_max = limit.rlim_cur = 0x20000;
|
2001-08-08 01:30:26 -07:00
|
|
|
if (sigaltstack(&stk, NULL) != 0) { perror("sigaltstack"); return 2; }
|
|
|
|
if (sigaction(SIGSEGV, &act, NULL) != 0) { perror("sigaction"); return 2; }
|
2001-08-28 07:42:52 -07:00
|
|
|
if (setrlimit(RLIMIT_STACK, &limit) != 0) { perror("setrlimit"); return 2; }
|
2001-08-08 01:30:26 -07:00
|
|
|
f(NULL);
|
|
|
|
return 2;
|
|
|
|
}
|