#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 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 *);
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 __gl_default_stack_size = -1;
int __gnat_handler_installed = 0;
#ifndef IN_RTS
int __gnat_inside_elab_final_code = 0;
#endif
#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,
int default_stack_size)
{
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
|| __gl_default_stack_size != default_stack_size)
__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;
__gl_default_stack_size = default_stack_size;
#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;
}
#elif defined(__alpha__) && defined(__osf__)
#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_set_code_loc (struct sigcontext *, char *);
extern size_t __gnat_machine_state_length (void);
static void
__gnat_error_handler
(int sig, siginfo_t *sip, struct sigcontext *context ATTRIBUTE_UNUSED)
{
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 ()];
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;
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;
}
#define SC_GP 29
char *
__gnat_get_code_loc (struct sigcontext *context)
{
return (char *) context->sc_pc;
}
void
__gnat_set_code_loc (struct sigcontext *context, char *pc)
{
context->sc_pc = (long) pc;
}
size_t
__gnat_machine_state_length (void)
{
return sizeof (struct sigcontext);
}
#elif defined (__hppa__) && defined (__hpux__)
#include <signal.h>
#include <sys/ucontext.h>
static void
__gnat_error_handler (int sig, siginfo_t *siginfo, void *ucontext);
#define HAVE_GNAT_ADJUST_CONTEXT_FOR_RAISE
void
__gnat_adjust_context_for_raise (int signo ATTRIBUTE_UNUSED, void *ucontext)
{
mcontext_t *mcontext = &((ucontext_t *) ucontext)->uc_mcontext;
if (UseWideRegs (mcontext))
mcontext->ss_wide.ss_32.ss_pcoq_head_lo ++;
else
mcontext->ss_narrow.ss_pcoq_head ++;
}
static void
__gnat_error_handler
(int sig, siginfo_t *siginfo ATTRIBUTE_UNUSED, void *ucontext)
{
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";
}
__gnat_adjust_context_for_raise (sig, ucontext);
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_sigaction = __gnat_error_handler;
act.sa_flags = SA_NODEFER | SA_RESTART | SA_ONSTACK | 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;
}
#elif defined (linux) && (defined (i386) || defined (__x86_64__) \
|| defined (__ia64__))
#include <signal.h>
#define __USE_GNU 1
#include <sys/ucontext.h>
#if !defined (NULL)
#define NULL ((void *) 0)
#endif
static void __gnat_error_handler (int, siginfo_t *siginfo, void *ucontext);
#define HAVE_GNAT_ADJUST_CONTEXT_FOR_RAISE
void
__gnat_adjust_context_for_raise (int signo ATTRIBUTE_UNUSED, void *ucontext)
{
mcontext_t *mcontext = &((ucontext_t *) ucontext)->uc_mcontext;
#if defined (i386)
mcontext->gregs[REG_EIP]++;
#elif defined (__x86_64__)
mcontext->gregs[REG_RIP]++;
#elif defined (__ia64__)
mcontext->sc_ip++;
#endif
}
static void
__gnat_error_handler (int sig,
siginfo_t *siginfo ATTRIBUTE_UNUSED,
void *ucontext)
{
struct Exception_Data *exception;
const char *msg;
static int recurse = 0;
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";
}
recurse = 0;
__gnat_adjust_context_for_raise (sig, ucontext);
Raise_From_Signal_Handler (exception, msg);
}
void
__gnat_install_handler (void)
{
struct sigaction act;
act.sa_sigaction = __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 (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;
}
#elif defined (__INTERIX)
#include <signal.h>
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 = 0;
sigemptyset (&act.sa_mask);
if (__gnat_get_interrupt_state (SIGSEGV) != 's')
sigaction (SIGSEGV, &act, NULL);
__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
static void __gnat_error_handler (int, int, sigcontext_t *);
static void
__gnat_error_handler (int sig, int code, sigcontext_t *sc ATTRIBUTE_UNUSED)
{
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";
}
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;
}
#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;
}
#elif defined (VMS)
long __gnat_error_handler (int *, void *);
#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
#define SS$_ACCVIO 12
#define SS$_HPARITH 1284
#define SS$_STKOVF 1364
#define SS$_RESIGNAL 2328
extern int CMA$_EXIT_THREAD;
extern int SS$_DEBUG;
extern int SS$_INTDIV;
extern int LIB$_KEYNOTFOU;
extern int LIB$_ACTIMAGE;
extern int MTH$_FLOOVEMAT;
#define RDB$_STREAM_EOF 20480426
#define FDL$_UNPRIKW 11829410
struct cond_except {
const int *cond;
const struct Exception_Data *except;
};
struct descriptor_s {unsigned short len, mbz; __char_ptr32 adr; };
#ifdef IN_RTS
#define Status_Error ada__io_exceptions__status_error
extern struct Exception_Data Status_Error;
#define Mode_Error ada__io_exceptions__mode_error
extern struct Exception_Data Mode_Error;
#define Name_Error ada__io_exceptions__name_error
extern struct Exception_Data Name_Error;
#define Use_Error ada__io_exceptions__use_error
extern struct Exception_Data Use_Error;
#define Device_Error ada__io_exceptions__device_error
extern struct Exception_Data Device_Error;
#define End_Error ada__io_exceptions__end_error
extern struct Exception_Data End_Error;
#define Data_Error ada__io_exceptions__data_error
extern struct Exception_Data Data_Error;
#define Layout_Error ada__io_exceptions__layout_error
extern struct Exception_Data Layout_Error;
#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);
extern int ADA$_PROGRAM_ERROR __attribute__ ((weak));
extern int ADA$_LOCK_ERROR __attribute__ ((weak));
extern int ADA$_EXISTENCE_ERROR __attribute__ ((weak));
extern int ADA$_KEY_ERROR __attribute__ ((weak));
extern int ADA$_KEYSIZERR __attribute__ ((weak));
extern int ADA$_STAOVF __attribute__ ((weak));
extern int ADA$_CONSTRAINT_ERRO __attribute__ ((weak));
extern int ADA$_IOSYSFAILED __attribute__ ((weak));
extern int ADA$_LAYOUT_ERROR __attribute__ ((weak));
extern int ADA$_STORAGE_ERROR __attribute__ ((weak));
extern int ADA$_DATA_ERROR __attribute__ ((weak));
extern int ADA$_DEVICE_ERROR __attribute__ ((weak));
extern int ADA$_END_ERROR __attribute__ ((weak));
extern int ADA$_MODE_ERROR __attribute__ ((weak));
extern int ADA$_NAME_ERROR __attribute__ ((weak));
extern int ADA$_STATUS_ERROR __attribute__ ((weak));
extern int ADA$_NOT_OPEN __attribute__ ((weak));
extern int ADA$_ALREADY_OPEN __attribute__ ((weak));
extern int ADA$_USE_ERROR __attribute__ ((weak));
extern int ADA$_UNSUPPORTED __attribute__ ((weak));
extern int ADA$_FAC_MODE_MISMAT __attribute__ ((weak));
extern int ADA$_ORG_MISMATCH __attribute__ ((weak));
extern int ADA$_RFM_MISMATCH __attribute__ ((weak));
extern int ADA$_RAT_MISMATCH __attribute__ ((weak));
extern int ADA$_MRS_MISMATCH __attribute__ ((weak));
extern int ADA$_MRN_MISMATCH __attribute__ ((weak));
extern int ADA$_KEY_MISMATCH __attribute__ ((weak));
extern int ADA$_MAXLINEXC __attribute__ ((weak));
extern int ADA$_LINEXCMRS __attribute__ ((weak));
static const struct cond_except dec_ada_cond_except_table [] = {
{&ADA$_PROGRAM_ERROR, &program_error},
{&ADA$_USE_ERROR, &Use_Error},
{&ADA$_KEYSIZERR, &program_error},
{&ADA$_STAOVF, &storage_error},
{&ADA$_CONSTRAINT_ERRO, &constraint_error},
{&ADA$_IOSYSFAILED, &Device_Error},
{&ADA$_LAYOUT_ERROR, &Layout_Error},
{&ADA$_STORAGE_ERROR, &storage_error},
{&ADA$_DATA_ERROR, &Data_Error},
{&ADA$_DEVICE_ERROR, &Device_Error},
{&ADA$_END_ERROR, &End_Error},
{&ADA$_MODE_ERROR, &Mode_Error},
{&ADA$_NAME_ERROR, &Name_Error},
{&ADA$_STATUS_ERROR, &Status_Error},
{&ADA$_NOT_OPEN, &Use_Error},
{&ADA$_ALREADY_OPEN, &Use_Error},
{&ADA$_USE_ERROR, &Use_Error},
{&ADA$_UNSUPPORTED, &Use_Error},
{&ADA$_FAC_MODE_MISMAT, &Use_Error},
{&ADA$_ORG_MISMATCH, &Use_Error},
{&ADA$_RFM_MISMATCH, &Use_Error},
{&ADA$_RAT_MISMATCH, &Use_Error},
{&ADA$_MRS_MISMATCH, &Use_Error},
{&ADA$_MRN_MISMATCH, &Use_Error},
{&ADA$_KEY_MISMATCH, &Use_Error},
{&ADA$_MAXLINEXC, &constraint_error},
{&ADA$_LINEXCMRS, &constraint_error},
{0, 0}
};
#if 0
{&ADA$_LOCK_ERROR, &Lock_Error},
{&ADA$_EXISTENCE_ERROR, &Existence_Error},
{&ADA$_KEY_ERROR, &Key_Error},
#endif
#endif
static const struct cond_except cond_except_table [] = {
{&MTH$_FLOOVEMAT, &constraint_error},
{&SS$_INTDIV, &constraint_error},
{0, 0}
};
typedef int
resignal_predicate (int code);
const int *cond_resignal_table [] = {
&CMA$_EXIT_THREAD,
&SS$_DEBUG,
&LIB$_KEYNOTFOU,
&LIB$_ACTIMAGE,
(int *) RDB$_STREAM_EOF,
(int *) FDL$_UNPRIKW,
0
};
const int facility_resignal_table [] = {
0x1380000,
0x2220000,
0
};
static int
__gnat_default_resignal_p (int code)
{
int i, iexcept;
for (i = 0; facility_resignal_table [i]; i++)
if ((code & 0xfff0000) == facility_resignal_table [i])
return 1;
for (i = 0, iexcept = 0;
cond_resignal_table [i] &&
!(iexcept = LIB$MATCH_COND (&code, &cond_resignal_table [i]));
i++);
return iexcept;
}
static resignal_predicate * __gnat_resignal_p = __gnat_default_resignal_p;
void
__gnat_set_resignal_predicate (resignal_predicate * predicate)
{
if (predicate == 0)
__gnat_resignal_p = __gnat_default_resignal_p;
else
__gnat_resignal_p = predicate;
}
#define Default_Exception_Msg_Max_Length 512
static int
copy_msg (msgdesc, message)
struct descriptor_s *msgdesc;
char *message;
{
int len = strlen (message);
int copy_len;
if (len > 0 && len <= Default_Exception_Msg_Max_Length - 3)
{
strcat (message, "\r\n");
len += 2;
}
copy_len = (len + msgdesc->len <= Default_Exception_Msg_Max_Length - 1 ?
msgdesc->len :
Default_Exception_Msg_Max_Length - 1 - len);
strncpy (&message [len], msgdesc->adr, copy_len);
message [len + copy_len] = 0;
return 0;
}
long
__gnat_handle_vms_condition (int *sigargs, void *mechargs)
{
struct Exception_Data *exception = 0;
Exception_Code base_code;
struct descriptor_s gnat_facility = {4,0,"GNAT"};
char message [Default_Exception_Msg_Max_Length];
const char *msg = "";
if (__gnat_resignal_p (sigargs [1]))
return SS$_RESIGNAL;
#ifdef IN_RTS
base_code = Base_Code_In ((Exception_Code) sigargs [1]);
exception = Coded_Exception (base_code);
if (exception)
{
message [0] = 0;
sigargs [0] -= 2;
SYS$PUTMSG (sigargs, copy_msg, &gnat_facility, message);
sigargs [0] += 2;
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$_HPARITH:
#ifndef IN_RTS
return SS$_RESIGNAL;
#else
{
exception = &constraint_error;
msg = "arithmetic error";
}
#endif
break;
default:
#ifdef IN_RTS
{
int i;
for (i = 0;
dec_ada_cond_except_table [i].cond &&
!LIB$MATCH_COND (&sigargs [1],
&dec_ada_cond_except_table [i].cond);
i++);
exception = (struct Exception_Data *)
dec_ada_cond_except_table [i].except;
if (!exception)
{
for (i = 0;
cond_except_table [i].cond &&
!LIB$MATCH_COND (&sigargs [1], &cond_except_table [i].cond);
i++);
exception =(struct Exception_Data *) cond_except_table [i].except;
if (!exception)
exception = &Non_Ada_Error;
}
}
#else
exception = &program_error;
#endif
message [0] = 0;
sigargs [0] -= 2;
SYS$PUTMSG (sigargs, copy_msg, &gnat_facility, message);
sigargs [0] += 2;
msg = message;
break;
}
__gnat_adjust_context_for_raise (0, (void *)sigargs);
Raise_From_Signal_Handler (exception, msg);
}
long
__gnat_error_handler (int *sigargs, void *mechargs)
{
return __gnat_handle_vms_condition (sigargs, mechargs);
}
void
__gnat_install_handler (void)
{
long prvhnd ATTRIBUTE_UNUSED;
#if !defined (IN_RTS)
SYS$SETEXV (1, __gnat_error_handler, 3, &prvhnd);
#endif
#if defined (IN_RTS) && defined (__IA64)
if (getenv ("DBG$TDBG"))
printf ("DBG$TDBG defined, __gnat_error_handler not installed!\n");
else
SYS$SETEXV (1, __gnat_error_handler, 3, &prvhnd);
#endif
#if defined (IN_RTS) && defined (__alpha__)
if ((__GNUC__ * 10 + __GNUC_MINOR__) < 34)
{
char * c = (char *) xmalloc (2049);
__gnat_error_prehandler_stack = &c[2048];
SYS$SETEXV (1, __gnat_error_prehandler, 3, &prvhnd);
}
#endif
__gnat_handler_installed = 1;
}
#if defined (IN_RTS) && defined (__alpha__)
#include <vms/chfctxdef.h>
#include <vms/chfdef.h>
#define HAVE_GNAT_ADJUST_CONTEXT_FOR_RAISE
void
__gnat_adjust_context_for_raise (int signo ATTRIBUTE_UNUSED, void *ucontext)
{
CHF$SIGNAL_ARRAY * sigargs = (CHF$SIGNAL_ARRAY *) ucontext;
int vcount = sigargs->chf$is_sig_args;
int * pc_slot = & (&sigargs->chf$l_sig_name)[vcount-2];
(*pc_slot) ++;
}
#endif
#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);
__gnat_handler_installed = 1;
}
#elif defined(__vxworks)
#include <signal.h>
#include <taskLib.h>
#ifndef __RTP__
#include <intLib.h>
#include <iv.h>
#endif
#ifdef VTHREADS
#include "private/vThreadsP.h"
#endif
static void __gnat_error_handler (int, int, struct sigcontext *);
void __gnat_map_signal (int);
#ifndef __RTP__
extern int __gnat_inum_to_ivec (int);
int
__gnat_inum_to_ivec (int num)
{
return INUM_TO_IVEC (num);
}
#endif
#if !defined(__alpha_vxworks) && (_WRS_VXWORKS_MAJOR != 6) && !defined(__RTP__)
extern long getpid (void);
long
getpid (void)
{
return taskIdSelf ();
}
#endif
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;
const 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
}
#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;
}
#else
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
#ifndef HAVE_GNAT_ADJUST_CONTEXT_FOR_RAISE
void
__gnat_adjust_context_for_raise (int signo ATTRIBUTE_UNUSED,
void *ucontext ATTRIBUTE_UNUSED)
{
}
#endif