#ifdef __vxworks
#include "vxWorks.h"
#endif
#ifdef IN_RTS
#include "tconfig.h"
#include "tsystem.h"
#include <sys/stat.h>
#define xmalloc(S) malloc (S)
#else
#include "config.h"
#include "system.h"
#endif
#include "adaint.h"
#include "raise.h"
extern void __gnat_raise_program_error (const char *, int);
extern struct Exception_Data constraint_error;
extern struct Exception_Data numeric_error;
extern struct Exception_Data program_error;
extern struct Exception_Data storage_error;
extern struct Exception_Data tasking_error;
extern struct Exception_Data _abort_signal;
#define Lock_Task system__soft_links__lock_task
extern void (*Lock_Task) (void);
#define Unlock_Task system__soft_links__unlock_task
extern void (*Unlock_Task) (void);
#define Get_Machine_State_Addr \
system__soft_links__get_machine_state_addr
extern struct Machine_State *(*Get_Machine_State_Addr) (void);
#define Check_Abort_Status \
system__soft_links__check_abort_status
extern int (*Check_Abort_Status) (void);
#define Raise_From_Signal_Handler \
ada__exceptions__raise_from_signal_handler
extern void Raise_From_Signal_Handler (struct Exception_Data *, const char *);
#define Propagate_Signal_Exception \
__gnat_propagate_sig_exc
extern void Propagate_Signal_Exception (struct Machine_State *,
struct Exception_Data *,
const char *);
int __gl_main_priority = -1;
int __gl_time_slice_val = -1;
char __gl_wc_encoding = 'n';
char __gl_locking_policy = ' ';
char __gl_queuing_policy = ' ';
char __gl_task_dispatching_policy = ' ';
char *__gl_restrictions = 0;
char *__gl_interrupt_states = 0;
int __gl_num_interrupt_states = 0;
int __gl_unreserve_all_interrupts = 0;
int __gl_exception_tracebacks = 0;
int __gl_zero_cost_exceptions = 0;
int __gl_detect_blocking = 0;
int __gnat_handler_installed = 0;
#undef HAVE_GNAT_INIT_FLOAT
char __gnat_get_interrupt_state (int);
char
__gnat_get_interrupt_state (int intrup)
{
if (intrup >= __gl_num_interrupt_states)
return 'n';
else
return __gl_interrupt_states [intrup];
}
void
__gnat_set_globals (int main_priority,
int time_slice_val,
char wc_encoding,
char locking_policy,
char queuing_policy,
char task_dispatching_policy,
char *restrictions,
char *interrupt_states,
int num_interrupt_states,
int unreserve_all_interrupts,
int exception_tracebacks,
int zero_cost_exceptions,
int detect_blocking)
{
static int already_called = 0;
if (already_called)
{
if (__gl_locking_policy != locking_policy
|| __gl_queuing_policy != queuing_policy
|| __gl_task_dispatching_policy != task_dispatching_policy
|| __gl_unreserve_all_interrupts != unreserve_all_interrupts
|| __gl_zero_cost_exceptions != zero_cost_exceptions)
__gnat_raise_program_error (__FILE__, __LINE__);
if (exception_tracebacks != 0)
__gl_exception_tracebacks = exception_tracebacks;
return;
}
already_called = 1;
__gl_main_priority = main_priority;
__gl_time_slice_val = time_slice_val;
__gl_wc_encoding = wc_encoding;
__gl_locking_policy = locking_policy;
__gl_queuing_policy = queuing_policy;
__gl_restrictions = restrictions;
__gl_interrupt_states = interrupt_states;
__gl_num_interrupt_states = num_interrupt_states;
__gl_task_dispatching_policy = task_dispatching_policy;
__gl_unreserve_all_interrupts = unreserve_all_interrupts;
__gl_exception_tracebacks = exception_tracebacks;
__gl_detect_blocking = detect_blocking;
#ifdef IN_RTS
__gl_zero_cost_exceptions = zero_cost_exceptions;
#else
__gl_zero_cost_exceptions = 0;
#endif
}
#if defined (_AIX)
#include <signal.h>
#include <sys/time.h>
#ifndef SA_NODEFER
#define SA_NODEFER 0
#endif
#ifndef _AIXVERSION_430
extern int nanosleep (struct timestruc_t *, struct timestruc_t *);
int
nanosleep (struct timestruc_t *Rqtp, struct timestruc_t *Rmtp)
{
return nsleep (Rqtp, Rmtp);
}
#endif
static void __gnat_error_handler (int);
static void
__gnat_error_handler (int sig)
{
struct Exception_Data *exception;
const char *msg;
switch (sig)
{
case SIGSEGV:
exception = &storage_error;
msg = "stack overflow or erroneous memory access";
break;
case SIGBUS:
exception = &constraint_error;
msg = "SIGBUS";
break;
case SIGFPE:
exception = &constraint_error;
msg = "SIGFPE";
break;
default:
exception = &program_error;
msg = "unhandled signal";
}
Raise_From_Signal_Handler (exception, msg);
}
void
__gnat_install_handler (void)
{
struct sigaction act;
act.sa_handler = __gnat_error_handler;
act.sa_flags = SA_NODEFER | SA_RESTART;
sigemptyset (&act.sa_mask);
if (__gnat_get_interrupt_state (SIGABRT) != 's')
sigaction (SIGABRT, &act, NULL);
if (__gnat_get_interrupt_state (SIGFPE) != 's')
sigaction (SIGFPE, &act, NULL);
if (__gnat_get_interrupt_state (SIGILL) != 's')
sigaction (SIGILL, &act, NULL);
if (__gnat_get_interrupt_state (SIGSEGV) != 's')
sigaction (SIGSEGV, &act, NULL);
if (__gnat_get_interrupt_state (SIGBUS) != 's')
sigaction (SIGBUS, &act, NULL);
__gnat_handler_installed = 1;
}
void
__gnat_initialize (void *eh ATTRIBUTE_UNUSED)
{
}
#elif defined(__rtems__)
extern void __gnat_install_handler (void);
void
__gnat_initialize (void *eh ATTRIBUTE_UNUSED)
{
__gnat_install_handler ();
}
#elif defined(__alpha__) && defined(__osf__) && ! defined(__alpha_vxworks)
#include <signal.h>
#include <sys/siginfo.h>
static void __gnat_error_handler (int, siginfo_t *, struct sigcontext *);
extern char *__gnat_get_code_loc (struct sigcontext *);
extern void __gnat_enter_handler (struct sigcontext *, char *);
extern size_t __gnat_machine_state_length (void);
extern long exc_lookup_gp (char *);
extern void exc_resume (struct sigcontext *);
static void
__gnat_error_handler (int sig, siginfo_t *sip, struct sigcontext *context)
{
struct Exception_Data *exception;
static int recurse = 0;
struct sigcontext *mstate;
const char *msg;
if (SI_FROMUSER (sip))
{
signal (sig, SIG_DFL);
kill (getpid(), sig);
}
switch (sig)
{
case SIGSEGV:
if (sip->si_code == SEGV_ACCERR
|| (((long) sip->si_addr) & 3) != 0
|| recurse)
{
exception = &constraint_error;
msg = "SIGSEGV";
}
else
{
recurse++;
((volatile char *)
((long) sip->si_addr & - getpagesize ()))[getpagesize ()];
msg = "stack overflow (or erroneous memory access)";
exception = &storage_error;
}
break;
case SIGBUS:
exception = &program_error;
msg = "SIGBUS";
break;
case SIGFPE:
exception = &constraint_error;
msg = "SIGFPE";
break;
default:
exception = &program_error;
msg = "unhandled signal";
}
recurse = 0;
mstate = (struct sigcontext *) (*Get_Machine_State_Addr) ();
if (mstate != 0)
*mstate = *context;
Raise_From_Signal_Handler (exception, (char *) msg);
}
void
__gnat_install_handler (void)
{
struct sigaction act;
act.sa_handler = (void (*) (int)) __gnat_error_handler;
act.sa_flags = SA_RESTART | SA_NODEFER | SA_SIGINFO;
sigemptyset (&act.sa_mask);
if (__gnat_get_interrupt_state (SIGABRT) != 's')
sigaction (SIGABRT, &act, NULL);
if (__gnat_get_interrupt_state (SIGFPE) != 's')
sigaction (SIGFPE, &act, NULL);
if (__gnat_get_interrupt_state (SIGILL) != 's')
sigaction (SIGILL, &act, NULL);
if (__gnat_get_interrupt_state (SIGSEGV) != 's')
sigaction (SIGSEGV, &act, NULL);
if (__gnat_get_interrupt_state (SIGBUS) != 's')
sigaction (SIGBUS, &act, NULL);
__gnat_handler_installed = 1;
}
void
__gnat_initialize (void *eh ATTRIBUTE_UNUSED)
{
}
#define SC_GP 29
char *
__gnat_get_code_loc (struct sigcontext *context)
{
return (char *) context->sc_pc;
}
void
__gnat_enter_handler ( struct sigcontext *context, char *pc)
{
context->sc_pc = (long) pc;
context->sc_regs[SC_GP] = exc_lookup_gp (pc);
exc_resume (context);
}
size_t
__gnat_machine_state_length (void)
{
return sizeof (struct sigcontext);
}
#elif defined (__hpux__)
#include <signal.h>
static void __gnat_error_handler (int);
static void
__gnat_error_handler (int sig)
{
struct Exception_Data *exception;
char *msg;
switch (sig)
{
case SIGSEGV:
exception = &storage_error;
msg = "stack overflow or erroneous memory access";
break;
case SIGBUS:
exception = &constraint_error;
msg = "SIGBUS";
break;
case SIGFPE:
exception = &constraint_error;
msg = "SIGFPE";
break;
default:
exception = &program_error;
msg = "unhandled signal";
}
Raise_From_Signal_Handler (exception, msg);
}
void
__gnat_install_handler (void)
{
struct sigaction act;
static char handler_stack[SIGSTKSZ*2];
stack_t stack;
stack.ss_sp = handler_stack;
stack.ss_size = sizeof (handler_stack);
stack.ss_flags = 0;
sigaltstack (&stack, NULL);
act.sa_handler = __gnat_error_handler;
act.sa_flags = SA_NODEFER | SA_RESTART | SA_ONSTACK;
sigemptyset (&act.sa_mask);
if (__gnat_get_interrupt_state (SIGABRT) != 's')
sigaction (SIGABRT, &act, NULL);
if (__gnat_get_interrupt_state (SIGFPE) != 's')
sigaction (SIGFPE, &act, NULL);
if (__gnat_get_interrupt_state (SIGILL) != 's')
sigaction (SIGILL, &act, NULL);
if (__gnat_get_interrupt_state (SIGSEGV) != 's')
sigaction (SIGSEGV, &act, NULL);
if (__gnat_get_interrupt_state (SIGBUS) != 's')
sigaction (SIGBUS, &act, NULL);
__gnat_handler_installed = 1;
}
void
__gnat_initialize (void *eh ATTRIBUTE_UNUSED)
{
}
#elif defined (linux) && defined (i386) && !defined (__RT__)
#include <signal.h>
#include <asm/sigcontext.h>
#if !defined (NULL)
#define NULL ((void *) 0)
#endif
struct Machine_State
{
unsigned long eip;
unsigned long ebx;
unsigned long esp;
unsigned long ebp;
unsigned long esi;
unsigned long edi;
};
static void __gnat_error_handler (int);
static void
__gnat_error_handler (int sig)
{
struct Exception_Data *exception;
const char *msg;
static int recurse = 0;
struct sigcontext *info
= (struct sigcontext *) (((char *) &sig) + sizeof (int));
struct Machine_State *mstate;
switch (sig)
{
case SIGSEGV:
if (recurse)
{
exception = &constraint_error;
msg = "SIGSEGV";
}
else
{
msg = "stack overflow (or erroneous memory access)";
exception = &storage_error;
}
break;
case SIGBUS:
exception = &constraint_error;
msg = "SIGBUS";
break;
case SIGFPE:
exception = &constraint_error;
msg = "SIGFPE";
break;
default:
exception = &program_error;
msg = "unhandled signal";
}
mstate = (*Get_Machine_State_Addr) ();
if (mstate)
{
mstate->eip = info->eip;
mstate->ebx = info->ebx;
mstate->esp = info->esp_at_signal;
mstate->ebp = info->ebp;
mstate->esi = info->esi;
mstate->edi = info->edi;
}
recurse = 0;
Raise_From_Signal_Handler (exception, msg);
}
void
__gnat_install_handler (void)
{
struct sigaction act;
act.sa_handler = __gnat_error_handler;
act.sa_flags = SA_NODEFER | SA_RESTART;
sigemptyset (&act.sa_mask);
if (__gnat_get_interrupt_state (SIGABRT) != 's')
sigaction (SIGABRT, &act, NULL);
if (__gnat_get_interrupt_state (SIGFPE) != 's')
sigaction (SIGFPE, &act, NULL);
if (__gnat_get_interrupt_state (SIGILL) != 's')
sigaction (SIGILL, &act, NULL);
if (__gnat_get_interrupt_state (SIGSEGV) != 's')
sigaction (SIGSEGV, &act, NULL);
if (__gnat_get_interrupt_state (SIGBUS) != 's')
sigaction (SIGBUS, &act, NULL);
__gnat_handler_installed = 1;
}
void
__gnat_initialize (void *eh ATTRIBUTE_UNUSED)
{
}
#elif defined (__MINGW32__)
#include <windows.h>
void
__gnat_install_handler (void)
{
}
void
__gnat_initialize (void *eh ATTRIBUTE_UNUSED)
{
__gnat_init_float ();
__gnat_plist_init();
if (eh)
__gnat_install_SEH_handler (eh);
}
#elif defined (__INTERIX)
#include <signal.h>
static void __gnat_error_handler (int);
static void
__gnat_error_handler (int sig)
{
struct Exception_Data *exception;
char *msg;
switch (sig)
{
case SIGSEGV:
exception = &storage_error;
msg = "stack overflow or erroneous memory access";
break;
case SIGBUS:
exception = &constraint_error;
msg = "SIGBUS";
break;
case SIGFPE:
exception = &constraint_error;
msg = "SIGFPE";
break;
default:
exception = &program_error;
msg = "unhandled signal";
}
Raise_From_Signal_Handler (exception, msg);
}
void
__gnat_install_handler (void)
{
struct sigaction act;
act.sa_handler = __gnat_error_handler;
act.sa_flags = 0;
sigemptyset (&act.sa_mask);
if (__gnat_get_interrupt_state (SIGSEGV) != 's')
sigaction (SIGSEGV, &act, NULL);
__gnat_handler_installed = 1;
}
void
__gnat_initialize (void *eh ATTRIBUTE_UNUSED)
{
__gnat_init_float ();
}
#elif defined (__Lynx__)
void
__gnat_initialize (void *eh ATTRIBUTE_UNUSED)
{
__gnat_init_float ();
}
void
__gnat_install_handler (void)
{
__gnat_handler_installed = 1;
}
#elif defined (__EMX__)
void
__gnat_initialize (void *eh ATTRIBUTE_UNUSED)
{
}
void
__gnat_install_handler (void)
{
__gnat_handler_installed = 1;
}
#elif defined (sgi)
#include <signal.h>
#include <siginfo.h>
#ifndef NULL
#define NULL 0
#endif
#define SIGADAABORT 48
#define SIGNAL_STACK_SIZE 4096
#define SIGNAL_STACK_ALIGNMENT 64
struct Machine_State
{
sigcontext_t context;
};
static void __gnat_error_handler (int, int, sigcontext_t *);
static void
__gnat_error_handler (int sig, int code, sigcontext_t *sc)
{
struct Machine_State *mstate;
struct Exception_Data *exception;
const char *msg;
switch (sig)
{
case SIGSEGV:
if (code == EFAULT)
{
exception = &program_error;
msg = "SIGSEGV: (Invalid virtual address)";
}
else if (code == ENXIO)
{
exception = &program_error;
msg = "SIGSEGV: (Read beyond mapped object)";
}
else if (code == ENOSPC)
{
exception = &program_error;
msg = "SIGSEGV: (Autogrow for file failed)";
}
else if (code == EACCES || code == EEXIST)
{
exception = &storage_error;
msg = "SIGSEGV: (stack overflow or erroneous memory access)";
}
else
{
exception = &program_error;
msg = "SIGSEGV: (Undocumented reason)";
}
break;
case SIGBUS:
exception = &program_error;
msg = "SIGBUS";
break;
case SIGFPE:
exception = &constraint_error;
msg = "SIGFPE";
break;
case SIGADAABORT:
if ((*Check_Abort_Status) ())
{
exception = &_abort_signal;
msg = "";
}
else
return;
break;
default:
exception = &program_error;
msg = "unhandled signal";
}
mstate = (*Get_Machine_State_Addr) ();
if (mstate != 0)
memcpy ((void *) mstate, (const void *) sc, sizeof (sigcontext_t));
Raise_From_Signal_Handler (exception, msg);
}
void
__gnat_install_handler (void)
{
struct sigaction act;
act.sa_handler = __gnat_error_handler;
act.sa_flags = SA_NODEFER + SA_RESTART;
sigfillset (&act.sa_mask);
sigemptyset (&act.sa_mask);
if (__gnat_get_interrupt_state (SIGABRT) != 's')
sigaction (SIGABRT, &act, NULL);
if (__gnat_get_interrupt_state (SIGFPE) != 's')
sigaction (SIGFPE, &act, NULL);
if (__gnat_get_interrupt_state (SIGILL) != 's')
sigaction (SIGILL, &act, NULL);
if (__gnat_get_interrupt_state (SIGSEGV) != 's')
sigaction (SIGSEGV, &act, NULL);
if (__gnat_get_interrupt_state (SIGBUS) != 's')
sigaction (SIGBUS, &act, NULL);
if (__gnat_get_interrupt_state (SIGADAABORT) != 's')
sigaction (SIGADAABORT, &act, NULL);
__gnat_handler_installed = 1;
}
void
__gnat_initialize (void *eh ATTRIBUTE_UNUSED)
{
}
#elif defined (sun) && defined (__SVR4) && !defined (__vxworks)
#include <signal.h>
#include <siginfo.h>
static void __gnat_error_handler (int, siginfo_t *);
static void
__gnat_error_handler (int sig, siginfo_t *sip)
{
struct Exception_Data *exception;
static int recurse = 0;
const char *msg;
if (SI_FROMUSER (sip))
{
signal (sig, SIG_DFL);
kill (getpid(), sig);
}
switch (sig)
{
case SIGSEGV:
if (sip->si_code == SEGV_ACCERR
|| (((long) sip->si_addr) & 3) != 0
|| recurse)
{
exception = &constraint_error;
msg = "SIGSEGV";
}
else
{
recurse++;
((volatile char *)
((long) sip->si_addr & - getpagesize ()))[getpagesize ()];
exception = &storage_error;
msg = "stack overflow (or erroneous memory access)";
}
break;
case SIGBUS:
exception = &program_error;
msg = "SIGBUS";
break;
case SIGFPE:
exception = &constraint_error;
msg = "SIGFPE";
break;
default:
exception = &program_error;
msg = "unhandled signal";
}
recurse = 0;
Raise_From_Signal_Handler (exception, msg);
}
void
__gnat_install_handler (void)
{
struct sigaction act;
act.sa_handler = __gnat_error_handler;
act.sa_flags = SA_NODEFER | SA_RESTART | SA_SIGINFO;
sigemptyset (&act.sa_mask);
if (__gnat_get_interrupt_state (SIGABRT) != 's')
sigaction (SIGABRT, &act, NULL);
if (__gnat_get_interrupt_state (SIGFPE) != 's')
sigaction (SIGFPE, &act, NULL);
if (__gnat_get_interrupt_state (SIGSEGV) != 's')
sigaction (SIGSEGV, &act, NULL);
if (__gnat_get_interrupt_state (SIGBUS) != 's')
sigaction (SIGBUS, &act, NULL);
__gnat_handler_installed = 1;
}
void
__gnat_initialize (void *eh ATTRIBUTE_UNUSED)
{
}
#elif defined (VMS)
#ifdef __IA64
#define lib_get_curr_invo_context LIB$I64_GET_CURR_INVO_CONTEXT
#define lib_get_prev_invo_context LIB$I64_GET_PREV_INVO_CONTEXT
#define lib_get_invo_handle LIB$I64_GET_INVO_HANDLE
#else
#define lib_get_curr_invo_context LIB$GET_CURR_INVO_CONTEXT
#define lib_get_prev_invo_context LIB$GET_PREV_INVO_CONTEXT
#define lib_get_invo_handle LIB$GET_INVO_HANDLE
#endif
#if defined (IN_RTS) && !defined (__IA64)
extern long __gnat_error_prehandler (void);
extern char *__gnat_error_prehandler_stack;
#endif
#ifdef IN_RTS
#define Non_Ada_Error system__aux_dec__non_ada_error
extern struct Exception_Data Non_Ada_Error;
#define Coded_Exception system__vms_exception_table__coded_exception
extern struct Exception_Data *Coded_Exception (Exception_Code);
#define Base_Code_In system__vms_exception_table__base_code_in
extern Exception_Code Base_Code_In (Exception_Code);
#endif
#define SS$_ACCVIO 12
#define SS$_DEBUG 1132
#define SS$_INTDIV 1156
#define SS$_HPARITH 1284
#define SS$_STKOVF 1364
#define SS$_RESIGNAL 2328
#define MTH$_FLOOVEMAT 1475268
#define SS$_CE24VRU 3253636
#define SS$_C980VTE 3246436
#define CMA$_EXIT_THREAD 4227492
#define CMA$_EXCCOPLOS 4228108
#define CMA$_ALERTED 4227460
struct descriptor_s {unsigned short len, mbz; char *adr; };
long __gnat_error_handler (int *, void *);
long
__gnat_error_handler (int *sigargs, void *mechargs)
{
struct Exception_Data *exception = 0;
Exception_Code base_code;
char *msg = "";
char message[256];
long prvhnd;
struct descriptor_s msgdesc;
int msg_flag = 0x000f;
unsigned short outlen;
char curr_icb[544];
long curr_invo_handle;
long *mstate;
switch (sigargs[1])
{
case CMA$_EXIT_THREAD:
return SS$_RESIGNAL;
case SS$_DEBUG:
return SS$_RESIGNAL;
case 1409786:
return SS$_RESIGNAL;
case 1381050:
return SS$_RESIGNAL;
case 20480426:
return SS$_RESIGNAL;
case 11829410:
return SS$_RESIGNAL;
}
#ifdef IN_RTS
base_code = Base_Code_In ((Exception_Code) sigargs [1]);
exception = Coded_Exception (base_code);
if (exception)
{
msgdesc.len = 256;
msgdesc.mbz = 0;
msgdesc.adr = message;
SYS$GETMSG (sigargs[1], &outlen, &msgdesc, msg_flag, 0);
message[outlen] = 0;
msg = message;
exception->Name_Length = 19;
exception->Full_Name = "IMPORTED_EXCEPTION";
exception->Import_Code = base_code;
}
#endif
if (exception == 0)
switch (sigargs[1])
{
case SS$_ACCVIO:
if (sigargs[3] == 0)
{
exception = &constraint_error;
msg = "access zero";
}
else
{
exception = &storage_error;
msg = "stack overflow (or erroneous memory access)";
}
break;
case SS$_STKOVF:
exception = &storage_error;
msg = "stack overflow";
break;
case SS$_INTDIV:
exception = &constraint_error;
msg = "division by zero";
break;
case SS$_HPARITH:
#ifndef IN_RTS
return SS$_RESIGNAL;
#else
{
exception = &constraint_error;
msg = "arithmetic error";
}
#endif
break;
case MTH$_FLOOVEMAT:
exception = &constraint_error;
msg = "floating overflow in math library";
break;
case SS$_CE24VRU:
exception = &constraint_error;
msg = "";
break;
case SS$_C980VTE:
exception = &program_error;
msg = "";
break;
default:
#ifndef IN_RTS
exception = &program_error;
#else
exception = &Non_Ada_Error;
#endif
msgdesc.len = 256;
msgdesc.mbz = 0;
msgdesc.adr = message;
SYS$GETMSG (sigargs[1], &outlen, &msgdesc, msg_flag, 0);
message[outlen] = 0;
msg = message;
break;
}
mstate = (long *) (*Get_Machine_State_Addr) ();
if (mstate != 0)
{
lib_get_curr_invo_context (&curr_icb);
lib_get_prev_invo_context (&curr_icb);
lib_get_prev_invo_context (&curr_icb);
curr_invo_handle = lib_get_invo_handle (&curr_icb);
*mstate = curr_invo_handle;
}
Raise_From_Signal_Handler (exception, msg);
}
void
__gnat_install_handler (void)
{
long prvhnd;
#if defined (IN_RTS) && !defined (__IA64)
char *c;
c = (char *) xmalloc (2049);
__gnat_error_prehandler_stack = &c[2048];
SYS$SETEXV (1, __gnat_error_prehandler, 3, &prvhnd);
#else
SYS$SETEXV (1, __gnat_error_handler, 3, &prvhnd);
#endif
__gnat_handler_installed = 1;
}
void
__gnat_initialize(void *eh ATTRIBUTE_UNUSED)
{
}
#elif defined (__FreeBSD__)
#include <signal.h>
#include <unistd.h>
static void __gnat_error_handler (int, int, struct sigcontext *);
static void
__gnat_error_handler (int sig, int code __attribute__ ((unused)),
struct sigcontext *sc __attribute__ ((unused)))
{
struct Exception_Data *exception;
const char *msg;
switch (sig)
{
case SIGFPE:
exception = &constraint_error;
msg = "SIGFPE";
break;
case SIGILL:
exception = &constraint_error;
msg = "SIGILL";
break;
case SIGSEGV:
exception = &storage_error;
msg = "stack overflow or erroneous memory access";
break;
case SIGBUS:
exception = &constraint_error;
msg = "SIGBUS";
break;
default:
exception = &program_error;
msg = "unhandled signal";
}
Raise_From_Signal_Handler (exception, msg);
}
void
__gnat_install_handler ()
{
struct sigaction act;
act.sa_handler = __gnat_error_handler;
act.sa_flags = SA_NODEFER | SA_RESTART;
(void) sigemptyset (&act.sa_mask);
(void) sigaction (SIGILL, &act, NULL);
(void) sigaction (SIGFPE, &act, NULL);
(void) sigaction (SIGSEGV, &act, NULL);
(void) sigaction (SIGBUS, &act, NULL);
}
void
__gnat_initialize (void *eh ATTRIBUTE_UNUSED)
{
__gnat_install_handler ();
__gnat_init_float ();
}
#elif defined(__vxworks)
#include <signal.h>
#include <taskLib.h>
#include <intLib.h>
#include <iv.h>
#ifdef VTHREADS
#include "private/vThreadsP.h"
#endif
extern int __gnat_inum_to_ivec (int);
static void __gnat_error_handler (int, int, struct sigcontext *);
void __gnat_map_signal (int);
#ifndef __alpha_vxworks
extern long getpid (void);
long
getpid (void)
{
return taskIdSelf ();
}
#endif
int
__gnat_inum_to_ivec (int num)
{
return INUM_TO_IVEC (num);
}
void
__gnat_clear_exception_count (void)
{
#ifdef VTHREADS
WIND_TCB *currentTask = (WIND_TCB *) taskIdSelf();
currentTask->vThreads.excCnt = 0;
#endif
}
void
__gnat_map_signal (int sig)
{
struct Exception_Data *exception;
char *msg;
switch (sig)
{
case SIGFPE:
exception = &constraint_error;
msg = "SIGFPE";
break;
#ifdef VTHREADS
case SIGILL:
exception = &constraint_error;
msg = "Floating point exception or SIGILL";
break;
case SIGSEGV:
exception = &storage_error;
msg = "SIGSEGV: possible stack overflow";
break;
case SIGBUS:
exception = &storage_error;
msg = "SIGBUS: possible stack overflow";
break;
#else
case SIGILL:
exception = &constraint_error;
msg = "SIGILL";
break;
case SIGSEGV:
exception = &program_error;
msg = "SIGSEGV";
break;
case SIGBUS:
exception = &program_error;
msg = "SIGBUS";
break;
#endif
default:
exception = &program_error;
msg = "unhandled signal";
}
__gnat_clear_exception_count ();
Raise_From_Signal_Handler (exception, msg);
}
static void
__gnat_error_handler (int sig, int code, struct sigcontext *sc)
{
sigset_t mask;
int result;
sigprocmask (SIG_SETMASK, NULL, &mask);
sigdelset (&mask, sig);
sigprocmask (SIG_SETMASK, &mask, NULL);
__gnat_map_signal (sig);
}
void
__gnat_install_handler (void)
{
struct sigaction act;
act.sa_handler = __gnat_error_handler;
act.sa_flags = SA_SIGINFO | SA_ONSTACK;
sigemptyset (&act.sa_mask);
sigaction (SIGFPE, &act, NULL);
sigaction (SIGILL, &act, NULL);
sigaction (SIGSEGV, &act, NULL);
sigaction (SIGBUS, &act, NULL);
__gnat_handler_installed = 1;
}
#define HAVE_GNAT_INIT_FLOAT
void
__gnat_init_float (void)
{
#if defined (_ARCH_PPC) && !defined (_SOFT_FLOAT) && !defined (VTHREADS)
asm ("mtfsb0 25");
asm ("mtfsb0 26");
#endif
#if defined (sparc64)
#define FSR_TEM_NVM (1 << 27)
#define FSR_TEM_OFM (1 << 26)
#define FSR_TEM_UFM (1 << 25)
#define FSR_TEM_DZM (1 << 24)
#define FSR_TEM_NXM (1 << 23)
{
unsigned int fsr;
__asm__("st %%fsr, %0" : "=m" (fsr));
fsr &= ~(FSR_TEM_OFM | FSR_TEM_UFM);
__asm__("ld %0, %%fsr" : : "m" (fsr));
}
#endif
}
void
__gnat_initialize (void *eh ATTRIBUTE_UNUSED)
{
__gnat_init_float ();
#if (__GNUC__ >= 3) && (defined (_ARCH_PPC) || defined (__ppc))
{
extern void __gnat_vxw_setup_for_eh (void);
__gnat_vxw_setup_for_eh ();
}
#endif
}
#elif defined(__NetBSD__)
#include <signal.h>
#include <unistd.h>
static void
__gnat_error_handler (int sig)
{
struct Exception_Data *exception;
const char *msg;
switch(sig)
{
case SIGFPE:
exception = &constraint_error;
msg = "SIGFPE";
break;
case SIGILL:
exception = &constraint_error;
msg = "SIGILL";
break;
case SIGSEGV:
exception = &storage_error;
msg = "stack overflow or erroneous memory access";
break;
case SIGBUS:
exception = &constraint_error;
msg = "SIGBUS";
break;
default:
exception = &program_error;
msg = "unhandled signal";
}
Raise_From_Signal_Handler(exception, msg);
}
void
__gnat_install_handler(void)
{
struct sigaction act;
act.sa_handler = __gnat_error_handler;
act.sa_flags = SA_NODEFER | SA_RESTART;
sigemptyset (&act.sa_mask);
if (__gnat_get_interrupt_state (SIGFPE) != 's')
sigaction (SIGFPE, &act, NULL);
if (__gnat_get_interrupt_state (SIGILL) != 's')
sigaction (SIGILL, &act, NULL);
if (__gnat_get_interrupt_state (SIGSEGV) != 's')
sigaction (SIGSEGV, &act, NULL);
if (__gnat_get_interrupt_state (SIGBUS) != 's')
sigaction (SIGBUS, &act, NULL);
__gnat_handler_installed = 1;
}
void
__gnat_initialize (void *eh ATTRIBUTE_UNUSED)
{
__gnat_install_handler ();
__gnat_init_float ();
}
#else
void
__gnat_initialize (void *eh ATTRIBUTE_UNUSED)
{
}
void
__gnat_install_handler (void)
{
__gnat_handler_installed = 1;
}
#endif
#if defined (_WIN32) || defined (__INTERIX) || defined (__EMX__) \
|| defined (__Lynx__) || defined(__NetBSD__) || defined(__FreeBSD__)
#define HAVE_GNAT_INIT_FLOAT
void
__gnat_init_float (void)
{
#if defined (__i386__) || defined (i386)
asm ("finit");
#endif
}
#endif
#ifndef HAVE_GNAT_INIT_FLOAT
void
__gnat_init_float (void)
{
}
#endif