diff options
author | Tristan Gingold <tgingold@free.fr> | 2015-09-04 21:52:38 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2015-09-04 21:52:38 +0200 |
commit | 8520993b4d1eadefa488dfc96dff25333f1b19db (patch) | |
tree | 818d4fe917d3e6b765932ed3d1ab1ee70dc3c508 /src/grt/config | |
parent | 2d8f611cb63b72aa0373efe0ffa0df47e25519c9 (diff) | |
download | ghdl-8520993b4d1eadefa488dfc96dff25333f1b19db.tar.gz ghdl-8520993b4d1eadefa488dfc96dff25333f1b19db.tar.bz2 ghdl-8520993b4d1eadefa488dfc96dff25333f1b19db.zip |
Suppress stack switching; save process state in secondary stack.
Diffstat (limited to 'src/grt/config')
-rw-r--r-- | src/grt/config/jumps.c | 171 | ||||
-rw-r--r-- | src/grt/config/math.c | 55 |
2 files changed, 226 insertions, 0 deletions
diff --git a/src/grt/config/jumps.c b/src/grt/config/jumps.c new file mode 100644 index 000000000..360ea8089 --- /dev/null +++ b/src/grt/config/jumps.c @@ -0,0 +1,171 @@ +/* Longjump/Setjump wrapper + Copyright (C) 2002 - 2015 Tristan Gingold. + + GHDL is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2, or (at your option) any later + version. + + GHDL is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. + + As a special exception, if other files instantiate generics from this + unit, or you link this unit with other files to produce an executable, + this unit does not by itself cause the resulting executable to be + covered by the GNU General Public License. This exception does not + however invalidate any other reasons why the executable file might be + covered by the GNU Public License. +*/ + +#include <stddef.h> +#include <signal.h> +#include <fcntl.h> +#include <sys/ucontext.h> + +/* There is a simple setjmp/longjmp mechanism used to report failures. + We have the choice between 3 mechanisms: + * USE_BUITLIN_SJLJ: gcc builtin setjmp/longjmp, very fast but gcc specific. + * USE__SETJMP: _setjmp/_longjmp + * USE_SETJMP: setjmp/longjmp, slower because signals mask is saved/restored. +*/ + +#if defined (__GNUC__) && !defined (__clang__) +#define USE_BUILTIN_SJLJ +#else +#define USE__SETJMP +#endif +/* #define USE_SETJMP */ + +#ifdef USE_BUILTIN_SJLJ +typedef void *JMP_BUF[5]; +static int sjlj_val; +# define SETJMP(BUF) (__builtin_setjmp (BUF), sjlj_val) +# define LONGJMP(BUF, VAL) \ + do { sjlj_val = (VAL); __builtin_longjmp (BUF, 1); } while (0) +#else +# include <setjmp.h> +typedef jmp_buf JMP_BUF; +# ifdef USE__SETJMP +# define SETJMP _setjmp +# define LONGJMP _longjmp +# elif defined (USE_SETJMP) +# define SETJMP setjmp +# define LONGJMP longjmp +# else +# error "SETJMP/LONGJMP not configued" +# endif +#endif + +static int run_env_en; +static JMP_BUF run_env; + +extern void grt_overflow_error (void); + +#ifdef __APPLE__ +#define NEED_SIGFPE_HANDLER +#endif +#if defined (__linux__) && defined (__i386__) +#define NEED_SIGSEGV_HANDLER +#endif + +#ifdef NEED_SIGFPE_HANDLER +static struct sigaction prev_sigfpe_act; + +/* Handler for SIGFPE signal, raised in case of overflow (i386). */ +static void grt_overflow_handler (int signo, siginfo_t *info, void *ptr) +{ + grt_overflow_error (); +} +#endif + +#ifdef NEED_SIGSEGV_HANDLER +static struct sigaction prev_sigsegv_act; + +/* Linux handler for overflow. This is used only by mcode. */ +static void grt_sigsegv_handler (int signo, siginfo_t *info, void *ptr) +{ +#if defined (__linux__) && defined (__i386__) + /* Linux generates a SIGSEGV (!) for an overflow exception. */ + if (uctxt->uc_mcontext.gregs[REG_TRAPNO] == 4) + { + grt_overflow_error (); + } +#endif + + /* We loose. */ +} +#endif /* __linux__ && __i386__ */ + +static void grt_signal_setup (void) +{ +#ifdef NEED_SIGSEGV_HANDLER + { + struct sigaction sigsegv_act; + + sigsegv_act.sa_sigaction = &grt_sigsegv_handler; + sigemptyset (&sigsegv_act.sa_mask); + sigsegv_act.sa_flags = SA_ONSTACK | SA_SIGINFO; +#ifdef SA_ONESHOT + sigsegv_act.sa_flags |= SA_ONESHOT; +#elif defined (SA_RESETHAND) + sigsegv_act.sa_flags |= SA_RESETHAND; +#endif + + /* We don't care about the return status. + If the handler is not installed, then some feature are lost. */ + sigaction (SIGSEGV, &sigsegv_act, &prev_sigsegv_act); + } +#endif + +#ifdef NEED_SIGFPE_HANDLER + { + struct sigaction sig_ovf_act; + + sig_ovf_act.sa_sigaction = &grt_overflow_handler; + sigemptyset (&sig_ovf_act.sa_mask); + sig_ovf_act.sa_flags = SA_SIGINFO; + + sigaction (SIGFPE, &sig_ovf_act, &prev_sigfpe_act); + } +#endif +} + +static void grt_signal_restore (void) +{ +#ifdef NEED_SIGSEGV_HANDLER + sigaction (SIGSEGV, &prev_sigsegv_act, NULL); +#endif + +#ifdef NEED_SIGFPE_HANDLER + sigaction (SIGFPE, &prev_sigfpe_act, NULL); +#endif +} + +void +__ghdl_maybe_return_via_longjump (int val) +{ + if (run_env_en) + LONGJMP (run_env, val); +} + +int +__ghdl_run_through_longjump (int (*func)(void)) +{ + int res; + + run_env_en = 1; + grt_signal_setup (); + res = SETJMP (run_env); + if (res == 0) + res = (*func)(); + grt_signal_restore (); + run_env_en = 0; + return res; +} diff --git a/src/grt/config/math.c b/src/grt/config/math.c new file mode 100644 index 000000000..704225f67 --- /dev/null +++ b/src/grt/config/math.c @@ -0,0 +1,55 @@ +/* Math routines for Win32 + Copyright (C) 2005 - 2015 Tristan Gingold. + + GHDL is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2, or (at your option) any later + version. + + GHDL is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. + + As a special exception, if other files instantiate generics from this + unit, or you link this unit with other files to produce an executable, + this unit does not by itself cause the resulting executable to be + covered by the GNU General Public License. This exception does not + however invalidate any other reasons why the executable file might be + covered by the GNU Public License. +*/ + +#include <math.h> + +double acosh (double x) +{ + return log (x + sqrt (x*x - 1)); +} + +double asinh (double x) +{ + return log (x + sqrt (x*x + 1)); +} + +double atanh (double x) +{ + return log ((1 + x) / (1 - x)) / 2; +} + +#ifndef WITH_GNAT_RUN_TIME +void __gnat_raise_storage_error(void) +{ + abort (); +} + +void __gnat_raise_program_error(void) +{ + abort (); +} +#endif + |