aboutsummaryrefslogtreecommitdiff
path: root/libgm2/libm2pim/SysExceptions.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libgm2/libm2pim/SysExceptions.cc')
-rw-r--r--libgm2/libm2pim/SysExceptions.cc259
1 files changed, 259 insertions, 0 deletions
diff --git a/libgm2/libm2pim/SysExceptions.cc b/libgm2/libm2pim/SysExceptions.cc
new file mode 100644
index 0000000..780b097
--- /dev/null
+++ b/libgm2/libm2pim/SysExceptions.cc
@@ -0,0 +1,259 @@
+/* SysExceptions.c configure the signals to create m2 exceptions.
+
+Copyright (C) 2009-2022 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaius.mulley@southwales.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.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+#if defined(HAVE_SIGNAL_H)
+#include <signal.h>
+#endif
+
+#if defined(HAVE_ERRNO_H)
+#include <errno.h>
+#endif
+
+#if defined(HAVE_SYS_ERRNO_H)
+#include <sys/errno.h>
+#endif
+
+#if defined(HAVE_STDIO_H)
+#include <stdio.h>
+#endif
+
+#include "m2rts.h"
+
+#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
+
+/* The list of Modula-2 exceptions is shown below */
+
+ (indexException, rangeException, caseSelectException, invalidLocation,
+ functionException, wholeValueException, wholeDivException, realValueException,
+ realDivException, complexValueException, complexDivException, protException,
+ sysException, coException, exException
+ );
+
+#endif
+
+/* Note: 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 "C" 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 "C" 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
+
+
+extern "C" void
+_M2_SysExceptions_init (int, char *[], char *[])
+{
+}
+
+extern "C" void
+_M2_SysExceptions_fini (int, char *[], char *[])
+{
+}
+
+extern "C" void
+_M2_SysExceptions_dep (void)
+{
+}
+
+struct _M2_SysExceptions_ctor { _M2_SysExceptions_ctor (); } _M2_SysExceptions_ctor;
+
+_M2_SysExceptions_ctor::_M2_SysExceptions_ctor (void)
+{
+ M2RTS_RegisterModule ("SysExceptions", _M2_SysExceptions_init, _M2_SysExceptions_fini,
+ _M2_SysExceptions_dep);
+}