gcc/libgm2/libm2pim/SysExceptions.cc
Iain Sandoe ec6d1fc09f modula-2: Fix registration of modules via constructors [PR108183].
This reworks the mechanism used for module registration to use init-
time constructors.  The order of registration is not important, the
actual initialization dependency tree will be computed early in the
execution (all that matters is that we have registered before that).

This fixes a potential issue in which the external name known to the
m2 system is of the form _M2_XXXXXX_ctor() but the C++ code was
producing a static variable instance with the same name.

Signed-off-by: Iain Sandoe <iain@sandoe.co.uk>

	PR modula2/108183

gcc/m2/ChangeLog:

	* gm2-libs-ch/UnixArgs.cc (_M2_UnixArgs_ctor): Rework to use
	an extern "C" function with 'constructor' attribute.
	* gm2-libs-ch/dtoa.cc (_M2_dtoa_ctor): Likewise.
	* gm2-libs-ch/ldtoa.cc (_M2_ldtoa_ctor): Likewise.

libgm2/ChangeLog:

	* libm2cor/KeyBoardLEDs.cc (_M2_KeyBoardLEDs_ctor): Rework to use
	an extern "C" function with 'constructor' attribute.
	* libm2iso/ErrnoCategory.cc (_M2_ErrnoCategory_ctor): Likewise.
	* libm2iso/RTco.cc (_M2_RTco_ctor): Likewise.
	* libm2pim/Selective.cc (_M2_Selective_ctor): Likewise.
	* libm2pim/SysExceptions.cc (_M2_SysExceptions_ctor): Likewise.
	* libm2pim/UnixArgs.cc (_M2_UnixArgs_ctor): Likewise.
	* libm2pim/cgetopt.cc (_M2_cgetopt_ctor): Likewise.
	* libm2pim/dtoa.cc (_M2_dtoa_ctor): Likewise.
	* libm2pim/errno.cc (_M2_errno_ctor): Likewise.
	* libm2pim/ldtoa.cc (_M2_ldtoa_ctor): Likewise.
	* libm2pim/sckt.cc (_M2_sckt_ctor): Likewise.
	* libm2pim/termios.cc (_M2_termios_ctor): Likewise.
	* libm2pim/wrapc.c: Add a new line to the file end.
2023-01-04 14:54:41 +00:00

259 lines
8.7 KiB
C++

/* 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)
{
}
extern "C" void __attribute__((__constructor__))
_M2_SysExceptions_ctor (void)
{
M2RTS_RegisterModule ("SysExceptions", _M2_SysExceptions_init, _M2_SysExceptions_fini,
_M2_SysExceptions_dep);
}