1 /* SysExceptions.c configure the signals to create m2 exceptions.
3 Copyright (C) 2009-2022 Free Software Foundation, Inc.
4 Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
6 This file is part of GNU Modula-2.
8 GNU Modula-2 is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GNU Modula-2 is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 Under Section 7 of GPL version 3, you are granted additional
19 permissions described in the GCC Runtime Library Exception, version
20 3.1, as published by the Free Software Foundation.
22 You should have received a copy of the GNU General Public License and
23 a copy of the GCC Runtime Library Exception along with this program;
24 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25 <http://www.gnu.org/licenses/>. */
30 #define EXPORT(FUNC) m2pim ## _SysExceptions_ ## FUNC
31 #define M2EXPORT(FUNC) m2pim ## _M2_SysExceptions_ ## FUNC
32 #define M2LIBNAME "m2pim"
34 #if defined(HAVE_SIGNAL_H)
38 #if defined(HAVE_ERRNO_H)
42 #if defined(HAVE_SYS_ERRNO_H)
43 #include <sys/errno.h>
46 #if defined(HAVE_STDIO_H)
54 #define SIGHUP 1 /* Hangup (POSIX). */
55 #define SIGINT 2 /* Interrupt (ANSI). */
56 #define SIGQUIT 3 /* Quit (POSIX). */
57 #define SIGILL 4 /* Illegal instruction (ANSI). */
58 #define SIGTRAP 5 /* Trace trap (POSIX). */
59 #define SIGABRT 6 /* Abort (ANSI). */
60 #define SIGIOT 6 /* IOT trap (4.2 BSD). */
61 #define SIGBUS 7 /* BUS error (4.2 BSD). */
62 #define SIGFPE 8 /* Floating-point exception (ANSI). */
63 #define SIGKILL 9 /* Kill, unblockable (POSIX). */
64 #define SIGUSR1 10 /* User-defined signal 1 (POSIX). */
65 #define SIGSEGV 11 /* Segmentation violation (ANSI). */
66 #define SIGUSR2 12 /* User-defined signal 2 (POSIX). */
67 #define SIGPIPE 13 /* Broken pipe (POSIX). */
68 #define SIGALRM 14 /* Alarm clock (POSIX). */
69 #define SIGTERM 15 /* Termination (ANSI). */
70 #define SIGSTKFLT 16 /* Stack fault. */
71 #define SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */
72 #define SIGCHLD 17 /* Child status has changed (POSIX). */
73 #define SIGCONT 18 /* Continue (POSIX). */
74 #define SIGSTOP 19 /* Stop, unblockable (POSIX). */
75 #define SIGTSTP 20 /* Keyboard stop (POSIX). */
76 #define SIGTTIN 21 /* Background read from tty (POSIX). */
77 #define SIGTTOU 22 /* Background write to tty (POSIX). */
78 #define SIGURG 23 /* Urgent condition on socket (4.2 BSD). */
79 #define SIGXCPU 24 /* CPU limit exceeded (4.2 BSD). */
80 #define SIGXFSZ 25 /* File size limit exceeded (4.2 BSD). */
81 #define SIGVTALRM 26 /* Virtual alarm clock (4.2 BSD). */
82 #define SIGPROF 27 /* Profiling alarm clock (4.2 BSD). */
83 #define SIGWINCH 28 /* Window size change (4.3 BSD, Sun). */
84 #define SIGPOLL SIGIO /* Pollable event occurred (System V). */
85 #define SIGIO 29 /* I/O now possible (4.2 BSD). */
86 #define SIGPWR 30 /* Power failure restart (System V). */
87 #define SIGSYS 31 /* Bad system call. */
90 /* The list of Modula-2 exceptions is shown below */
92 (indexException
, rangeException
, caseSelectException
, invalidLocation
,
93 functionException
, wholeValueException
, wholeDivException
, realValueException
,
94 realDivException
, complexValueException
, complexDivException
, protException
,
95 sysException
, coException
, exException
100 /* Note: wholeDivException and realDivException are caught by SIGFPE
101 and depatched to the appropriate Modula-2 runtime routine upon
102 testing FPE_INTDIV or FPE_FLTDIV. realValueException is also
103 caught by SIGFPE and dispatched by testing FFE_FLTOVF or FPE_FLTUND
104 or FPE_FLTRES or FPE_FLTINV. indexException is caught by SIGFPE
105 and dispatched by FPE_FLTSUB. */
107 #if defined(HAVE_SIGNAL_H)
108 static struct sigaction sigbus
;
109 static struct sigaction sigfpe
;
110 static struct sigaction sigsegv
;
112 static void (*indexProc
) (void *);
113 static void (*rangeProc
) (void *);
114 static void (*assignmentrangeProc
) (void *);
115 static void (*caseProc
) (void *);
116 static void (*invalidlocProc
) (void *);
117 static void (*functionProc
) (void *);
118 static void (*wholevalueProc
) (void *);
119 static void (*wholedivProc
) (void *);
120 static void (*realvalueProc
) (void *);
121 static void (*realdivProc
) (void *);
122 static void (*complexvalueProc
) (void *);
123 static void (*complexdivProc
) (void *);
124 static void (*protectionProc
) (void *);
125 static void (*systemProc
) (void *);
126 static void (*coroutineProc
) (void *);
127 static void (*exceptionProc
) (void *);
130 sigbusDespatcher (int signum
, siginfo_t
*info
, void *ucontext
)
138 (*invalidlocProc
) (info
->si_addr
);
141 perror ("not expecting to arrive here with this signal");
146 sigfpeDespatcher (int signum
, siginfo_t
*info
, void *ucontext
)
154 if (info
->si_code
| FPE_INTDIV
)
155 (*wholedivProc
) (info
->si_addr
); /* Integer divide by zero. */
156 if (info
->si_code
| FPE_INTOVF
)
157 (*wholevalueProc
) (info
->si_addr
); /* Integer overflow. */
158 if (info
->si_code
| FPE_FLTDIV
)
159 (*realdivProc
) (info
->si_addr
); /* Floating-point divide by zero. */
160 if (info
->si_code
| FPE_FLTOVF
)
161 (*realvalueProc
) (info
->si_addr
); /* Floating-point overflow. */
162 if (info
->si_code
| FPE_FLTUND
)
163 (*realvalueProc
) (info
->si_addr
); /* Floating-point underflow. */
164 if (info
->si_code
| FPE_FLTRES
)
166 info
->si_addr
); /* Floating-point inexact result. */
167 if (info
->si_code
| FPE_FLTINV
)
169 info
->si_addr
); /* Floating-point invalid result. */
170 if (info
->si_code
| FPE_FLTSUB
)
171 (*indexProc
) (info
->si_addr
); /* Subscript out of range. */
175 perror ("not expecting to arrive here with this signal");
180 EXPORT(InitExceptionHandlers
) (
181 void (*indexf
) (void *), void (*range
) (void *), void (*casef
) (void *),
182 void (*invalidloc
) (void *), void (*function
) (void *),
183 void (*wholevalue
) (void *), void (*wholediv
) (void *),
184 void (*realvalue
) (void *), void (*realdiv
) (void *),
185 void (*complexvalue
) (void *), void (*complexdiv
) (void *),
186 void (*protection
) (void *), void (*systemf
) (void *),
187 void (*coroutine
) (void *), void (*exception
) (void *))
189 struct sigaction old
;
194 invalidlocProc
= invalidloc
;
195 functionProc
= function
;
196 wholevalueProc
= wholevalue
;
197 wholedivProc
= wholediv
;
198 realvalueProc
= realvalue
;
199 realdivProc
= realdiv
;
200 complexvalueProc
= complexvalue
;
201 complexdivProc
= complexdiv
;
202 protectionProc
= protection
;
203 systemProc
= systemf
;
204 coroutineProc
= coroutine
;
205 exceptionProc
= exception
;
207 sigbus
.sa_sigaction
= sigbusDespatcher
;
208 sigbus
.sa_flags
= (SA_SIGINFO
);
209 sigemptyset (&sigbus
.sa_mask
);
211 if (sigaction (SIGBUS
, &sigbus
, &old
) != 0)
212 perror ("unable to install the sigbus signal handler");
214 sigsegv
.sa_sigaction
= sigbusDespatcher
;
215 sigsegv
.sa_flags
= (SA_SIGINFO
);
216 sigemptyset (&sigsegv
.sa_mask
);
218 if (sigaction (SIGSEGV
, &sigsegv
, &old
) != 0)
219 perror ("unable to install the sigsegv signal handler");
221 sigfpe
.sa_sigaction
= sigfpeDespatcher
;
222 sigfpe
.sa_flags
= (SA_SIGINFO
);
223 sigemptyset (&sigfpe
.sa_mask
);
225 if (sigaction (SIGFPE
, &sigfpe
, &old
) != 0)
226 perror ("unable to install the sigfpe signal handler");
231 EXPORT(InitExceptionHandlers
) (void *indexf
, void *range
, void *casef
,
232 void *invalidloc
, void *function
,
233 void *wholevalue
, void *wholediv
,
234 void *realvalue
, void *realdiv
,
235 void *complexvalue
, void *complexdiv
,
236 void *protection
, void *systemf
,
237 void *coroutine
, void *exception
)
244 M2EXPORT(init
) (int, char **, char **)
249 M2EXPORT(fini
) (int, char **, char **)
258 extern "C" void __attribute__((__constructor__
))
259 M2EXPORT(ctor
) (void)
261 m2pim_M2RTS_RegisterModule ("SysExceptions", M2LIBNAME
,
262 M2EXPORT(init
), M2EXPORT(fini
),