diff options
Diffstat (limited to 'gcc/m2/mc-boot-ch/GSysExceptions.c')
-rw-r--r-- | gcc/m2/mc-boot-ch/GSysExceptions.c | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/gcc/m2/mc-boot-ch/GSysExceptions.c b/gcc/m2/mc-boot-ch/GSysExceptions.c new file mode 100644 index 0000000..f6cddf9 --- /dev/null +++ b/gcc/m2/mc-boot-ch/GSysExceptions.c @@ -0,0 +1,237 @@ +/* GSysExceptions.c low level module interfacing exceptions to the OS. + +Copyright (C) 2016-2022 Free Software Foundation, Inc. +Contributed by Gaius Mulley <gaius@glam.ac.uk>. + +This file is part of GNU Modula-2. + +GNU Modula-2 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 3, or (at your option) +any later version. + +GNU Modula-2 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 GNU Modula-2; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" + +#include "gm2-libs-host.h" + +#if defined(__cplusplus) +#define EXTERN extern "C" +#else +#define EXTERN +#endif + +#if 0 +/* Signals. */ +#define SIGHUP 1 /* Hangup (POSIX). */ +#define SIGINT 2 /* Interrupt (ANSI). */ +#define SIGQUIT 3 /* Quit (POSIX). */ +#define SIGILL 4 /* Illegal instruction (ANSI). */ +#define SIGTRAP 5 /* Trace trap (POSIX). */ +#define SIGABRT 6 /* Abort (ANSI). */ +#define SIGIOT 6 /* IOT trap (4.2 BSD). */ +#define SIGBUS 7 /* BUS error (4.2 BSD). */ +#define SIGFPE 8 /* Floating-point exception (ANSI). */ +#define SIGKILL 9 /* Kill, unblockable (POSIX). */ +#define SIGUSR1 10 /* User-defined signal 1 (POSIX). */ +#define SIGSEGV 11 /* Segmentation violation (ANSI). */ +#define SIGUSR2 12 /* User-defined signal 2 (POSIX). */ +#define SIGPIPE 13 /* Broken pipe (POSIX). */ +#define SIGALRM 14 /* Alarm clock (POSIX). */ +#define SIGTERM 15 /* Termination (ANSI). */ +#define SIGSTKFLT 16 /* Stack fault. */ +#define SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */ +#define SIGCHLD 17 /* Child status has changed (POSIX). */ +#define SIGCONT 18 /* Continue (POSIX). */ +#define SIGSTOP 19 /* Stop, unblockable (POSIX). */ +#define SIGTSTP 20 /* Keyboard stop (POSIX). */ +#define SIGTTIN 21 /* Background read from tty (POSIX). */ +#define SIGTTOU 22 /* Background write to tty (POSIX). */ +#define SIGURG 23 /* Urgent condition on socket (4.2 BSD). */ +#define SIGXCPU 24 /* CPU limit exceeded (4.2 BSD). */ +#define SIGXFSZ 25 /* File size limit exceeded (4.2 BSD). */ +#define SIGVTALRM 26 /* Virtual alarm clock (4.2 BSD). */ +#define SIGPROF 27 /* Profiling alarm clock (4.2 BSD). */ +#define SIGWINCH 28 /* Window size change (4.3 BSD, Sun). */ +#define SIGPOLL SIGIO /* Pollable event occurred (System V). */ +#define SIGIO 29 /* I/O now possible (4.2 BSD). */ +#define SIGPWR 30 /* Power failure restart (System V). */ +#define SIGSYS 31 /* Bad system call. */ +#define SIGUNUSED 31 + + + (indexException, rangeException, caseSelectException, invalidLocation, + functionException, wholeValueException, wholeDivException, realValueException, + realDivException, complexValueException, complexDivException, protException, + sysException, coException, exException + ); + +#endif + +/* wholeDivException and realDivException are caught by SIGFPE + and depatched to the appropriate Modula-2 runtime routine upon + testing FPE_INTDIV or FPE_FLTDIV. realValueException is also + caught by SIGFPE and dispatched by testing FFE_FLTOVF or + FPE_FLTUND or FPE_FLTRES or FPE_FLTINV. indexException is + caught by SIGFPE and dispatched by FPE_FLTSUB. */ + +#if defined(HAVE_SIGNAL_H) +static struct sigaction sigbus; +static struct sigaction sigfpe_; +static struct sigaction sigsegv; + +static void (*indexProc) (void *); +static void (*rangeProc) (void *); +static void (*assignmentrangeProc) (void *); +static void (*caseProc) (void *); +static void (*invalidlocProc) (void *); +static void (*functionProc) (void *); +static void (*wholevalueProc) (void *); +static void (*wholedivProc) (void *); +static void (*realvalueProc) (void *); +static void (*realdivProc) (void *); +static void (*complexvalueProc) (void *); +static void (*complexdivProc) (void *); +static void (*protectionProc) (void *); +static void (*systemProc) (void *); +static void (*coroutineProc) (void *); +static void (*exceptionProc) (void *); + +static void +sigbusDespatcher (int signum, siginfo_t *info, void *ucontext) +{ + switch (signum) + { + + case SIGSEGV: + case SIGBUS: + if (info) + (*invalidlocProc) (info->si_addr); + break; + default: + perror ("not expecting to arrive here with this signal"); + } +} + +static void +sigfpeDespatcher (int signum, siginfo_t *info, void *ucontext) +{ + switch (signum) + { + + case SIGFPE: + if (info) + { + if (info->si_code | FPE_INTDIV) + (*wholedivProc) (info->si_addr); /* integer divide by zero. */ + if (info->si_code | FPE_INTOVF) + (*wholevalueProc) (info->si_addr); /* integer overflow. */ + if (info->si_code | FPE_FLTDIV) + (*realdivProc) ( + info->si_addr); /* floating-point divide by zero. */ + if (info->si_code | FPE_FLTOVF) + (*realvalueProc) (info->si_addr); /* floating-point overflow. */ + if (info->si_code | FPE_FLTUND) + (*realvalueProc) (info->si_addr); /* floating-point underflow. */ + if (info->si_code | FPE_FLTRES) + (*realvalueProc) ( + info->si_addr); /* floating-point inexact result. */ + if (info->si_code | FPE_FLTINV) + (*realvalueProc) ( + info->si_addr); /* floating-point invalid result. */ + if (info->si_code | FPE_FLTSUB) + (*indexProc) (info->si_addr); /* subscript out of range. */ + } + break; + default: + perror ("not expecting to arrive here with this signal"); + } +} + +EXTERN +void +SysExceptions_InitExceptionHandlers ( + void (*indexf) (void *), void (*range) (void *), void (*casef) (void *), + void (*invalidloc) (void *), void (*function) (void *), + void (*wholevalue) (void *), void (*wholediv) (void *), + void (*realvalue) (void *), void (*realdiv) (void *), + void (*complexvalue) (void *), void (*complexdiv) (void *), + void (*protection) (void *), void (*systemf) (void *), + void (*coroutine) (void *), void (*exception) (void *)) +{ + struct sigaction old; + + indexProc = indexf; + rangeProc = range; + caseProc = casef; + invalidlocProc = invalidloc; + functionProc = function; + wholevalueProc = wholevalue; + wholedivProc = wholediv; + realvalueProc = realvalue; + realdivProc = realdiv; + complexvalueProc = complexvalue; + complexdivProc = complexdiv; + protectionProc = protection; + systemProc = systemf; + coroutineProc = coroutine; + exceptionProc = exception; + + sigbus.sa_sigaction = sigbusDespatcher; + sigbus.sa_flags = (SA_SIGINFO); + sigemptyset (&sigbus.sa_mask); + + if (sigaction (SIGBUS, &sigbus, &old) != 0) + perror ("unable to install the sigbus signal handler"); + + sigsegv.sa_sigaction = sigbusDespatcher; + sigsegv.sa_flags = (SA_SIGINFO); + sigemptyset (&sigsegv.sa_mask); + + if (sigaction (SIGSEGV, &sigsegv, &old) != 0) + perror ("unable to install the sigsegv signal handler"); + + sigfpe_.sa_sigaction = sigfpeDespatcher; + sigfpe_.sa_flags = (SA_SIGINFO); + sigemptyset (&sigfpe_.sa_mask); + + if (sigaction (SIGFPE, &sigfpe_, &old) != 0) + perror ("unable to install the sigfpe signal handler"); +} + +#else +EXTERN +void +SysExceptions_InitExceptionHandlers (void *indexf, void *range, void *casef, + void *invalidloc, void *function, + void *wholevalue, void *wholediv, + void *realvalue, void *realdiv, + void *complexvalue, void *complexdiv, + void *protection, void *systemf, + void *coroutine, void *exception) +{ +} +#endif + +/* GNU Modula-2 linking fodder. */ + +EXTERN +void +_M2_SysExceptions_init (void) +{ +} + +EXTERN +void +_M2_SysExceptions_finish (void) +{ +} |