2022-12-15 01:43:08 +08:00
|
|
|
/* 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)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2022-12-31 03:46:13 +08:00
|
|
|
extern "C" void __attribute__((__constructor__))
|
|
|
|
_M2_SysExceptions_ctor (void)
|
2022-12-15 01:43:08 +08:00
|
|
|
{
|
|
|
|
M2RTS_RegisterModule ("SysExceptions", _M2_SysExceptions_init, _M2_SysExceptions_fini,
|
|
|
|
_M2_SysExceptions_dep);
|
|
|
|
}
|