mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-01-11 04:14:31 +08:00
ec6d1fc09f
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.
259 lines
8.7 KiB
C++
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);
|
|
}
|