Commit 844e7daa by Doug Rupp Committed by Arnaud Charlet

Make-lang.in: Add initialize.o when needed.

2005-06-10  Doug Rupp  <rupp@adacore.com>
	    Arnaud Charlet  <charlet@adacore.com>
	    Olivier Hainque  <hainque@adacore.com>
	    Jose Ruiz  <ruiz@adacore.com>

	* Make-lang.in: Add initialize.o when needed.
	Remove obsolete references to RT_FLAGS.
	Add missing dependencies for sdefault.o

	* initialize.c: New file.

	* init.c [VMS] Declare ADA$ externs weak to fix build problem in IVMS.
	[VMS] cond_signal_table: Fix problem in declaration.
	[VMS] __gnat_error_handler: rewrite.
	Move all __gnat_initialize() routines to initialize.c
	Specialize the former "hpux" section to "hppa hpux", as this is what the
	section really is here for and we now have other hpux ports that need
	different contents.
	(__gnat_adjust_context_for_raise) i386-linux: First version of this
	function for this target. Adjust PC by one in the machine context. This
	adjustment was previously done in the MD_FALLBACK_FRAME_STATE_FOR, but
	it is more reliable to do that in the signal handler itself.
	(__gnat_install_handler) i386-linux: Set SA_SIGINFO in the sigaction
	flags, so that the handler is passed the context structure to adjust
	prior to the raise.
	(__gnat_error_handler) i386-linux: Adjust the signature to match what a
	SA_SIGINFO sigaction should look like. Call
	__gnat_adjust_context_for_raise before actually raising. Cleanup unused
	Machine_State_Operations stuff.
	Add conditional code so that the x86_64 is also supported.

From-SVN: r101047
parent 217efe16
# Top level -*- makefile -*- fragment for GNU Ada (GNAT).
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004 Free Software Foundation, Inc.
# 2003, 2004, 2005 Free Software Foundation, Inc.
#This file is part of GCC.
......@@ -105,7 +105,8 @@ ADA_TOOLS_FLAGS_TO_PASS=\
# Object files for gnat1 from C sources.
GNAT1_C_OBJS = ada/b_gnat1.o ada/adadecode.o ada/adaint.o ada/cstreams.o \
ada/cio.o ada/targtyps.o ada/decl.o ada/misc.o ada/utils.o ada/utils2.o \
ada/trans.o ada/cuintp.o ada/argv.o ada/raise.o ada/init.o ada/tracebak.o
ada/trans.o ada/cuintp.o ada/argv.o ada/raise.o ada/init.o ada/tracebak.o \
ada/initialize.o
# Object files from Ada sources that are used by gnat1
......@@ -162,6 +163,7 @@ GNATBIND_OBJS = \
ada/cstreams.o \
ada/final.o \
ada/init.o \
ada/initialize.o \
ada/seh_init.o \
ada/link.o \
ada/raise.o \
......@@ -942,7 +944,7 @@ ada/stamp-sdefault : $(srcdir)/version.c Makefile
ada/sdefault.o : ada/sdefault.ads ada/sdefault.adb ada/types.ads \
ada/unchdeal.ads ada/system.ads ada/s-exctab.ads ada/s-stalib.ads \
ada/unchconv.ads ada/osint.ads
ada/unchconv.ads ada/osint.ads ada/g-os_lib.ads ada/g-string.ads
ADA_TREE_H = ada/ada-tree.h ada/ada-tree.def
......@@ -1009,15 +1011,19 @@ ada/final.o : ada/final.c $(CONFIG_H) $(SYSTEM_H) ada/raise.h
ada/link.o : ada/link.c
ada/cio.o : ada/cio.c $(CONFIG_H) $(SYSTEM_H) ada/adaint.h
$(CC) -c $(ALL_CFLAGS) $(ALL_ADA_CFLAGS) $(RT_FLAGS) \
$(CC) -c $(ALL_CFLAGS) $(ALL_ADA_CFLAGS) \
$(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
ada/init.o : ada/init.c $(CONFIG_H) $(SYSTEM_H) ada/adaint.h ada/raise.h
$(CC) -c $(ALL_CFLAGS) $(ALL_ADA_CFLAGS) $(RT_FLAGS) \
$(CC) -c $(ALL_CFLAGS) $(ALL_ADA_CFLAGS) \
$(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
ada/initialize.o : ada/initialize.c
$(CC) -c $(ALL_CFLAGS) $(ALL_ADA_CFLAGS) \
$(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
ada/raise.o : ada/raise.c $(CONFIG_H) $(SYSTEM_H) ada/adaint.h ada/raise.h
$(CC) -c $(ALL_CFLAGS) $(ALL_ADA_CFLAGS) $(RT_FLAGS) \
$(CC) -c $(ALL_CFLAGS) $(ALL_ADA_CFLAGS) \
$(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
# Need to keep the frame pointer in this file to pop the stack properly on
......
......@@ -256,15 +256,6 @@ __gnat_set_globals (int main_priority,
#endif
}
/*********************/
/* __gnat_initialize */
/*********************/
/* __gnat_initialize is called at the start of execution of an Ada program
(the call is generated by the binder). The standard routine does nothing
at all; the intention is that this be replaced by system specific
code where initialization is required. */
/* Notes on the Zero Cost Exceptions scheme and its impact on the signal
handlers implemented below :
......@@ -291,7 +282,7 @@ __gnat_set_globals (int main_priority,
as the faulting instruction address in the corresponding signal context
pushed by the kernel. Leaving this address untouched may loose, because if
the triggering instruction happens to be the very first of a region, the
later adjustments performed by the unwinder would yield an address outside
later adjustements performed by the unwinder would yield an address outside
that region. We need to compensate for those adjustments at some point,
which we currently do in the GCC unwinding fallback macro.
......@@ -310,9 +301,9 @@ __gnat_set_globals (int main_priority,
of subtleties to account for. See for instance the syscall(SYS_sigaction)
story in libjava/include/i386-signal.h. */
/***********************************/
/* __gnat_initialize (AIX Version) */
/***********************************/
/***************/
/* AIX Section */
/***************/
#if defined (_AIX)
......@@ -402,36 +393,11 @@ __gnat_install_handler (void)
__gnat_handler_installed = 1;
}
void
__gnat_initialize (void *eh ATTRIBUTE_UNUSED)
{
}
/***************************************/
/* __gnat_initialize (RTEMS version) */
/***************************************/
#elif defined(__rtems__)
extern void __gnat_install_handler (void);
/* For RTEMS, each bsp will provide a custom __gnat_install_handler (). */
void
__gnat_initialize (void *eh ATTRIBUTE_UNUSED)
{
__gnat_install_handler ();
}
/****************************************/
/* __gnat_initialize (Dec Unix Version) */
/****************************************/
#elif defined(__alpha__) && defined(__osf__) && ! defined(__alpha_vxworks)
/*****************/
/* Tru64 section */
/*****************/
/* Note: it seems that __osf__ is defined for the Alpha VXWorks case. Not
clear that this is reasonable, but in any case we have to be sure to
exclude this case in the above test. */
#elif defined(__alpha__) && defined(__osf__)
#include <signal.h>
#include <sys/siginfo.h>
......@@ -542,11 +508,6 @@ __gnat_install_handler (void)
__gnat_handler_installed = 1;
}
void
__gnat_initialize (void *eh ATTRIBUTE_UNUSED)
{
}
/* Routines called by s-mastop-tru64.adb. */
#define SC_GP 29
......@@ -571,11 +532,11 @@ __gnat_machine_state_length (void)
return sizeof (struct sigcontext);
}
/************************************/
/* __gnat_initialize (HPUX Version) */
/************************************/
/********************/
/* PA HP-UX section */
/********************/
#elif defined (__hpux__)
#elif defined (__hppa__) && defined (__hpux__)
#include <signal.h>
#include <sys/ucontext.h>
......@@ -676,19 +637,16 @@ __gnat_install_handler (void)
__gnat_handler_installed = 1;
}
void
__gnat_initialize (void *eh ATTRIBUTE_UNUSED)
{
}
/*****************************************/
/* __gnat_initialize (GNU/Linux Version) */
/*****************************************/
/*********************/
/* GNU/Linux Section */
/*********************/
#elif defined (linux) && defined (i386) && !defined (__RT__)
#elif defined (linux) && (defined (i386) || defined (__x86_64__))
#include <signal.h>
#include <asm/sigcontext.h>
#define __USE_GNU 1 /* required to get REG_EIP/RIP from glibc's ucontext.h */
#include <sys/ucontext.h>
/* GNU/Linux, which uses glibc, does not define NULL in included
header files */
......@@ -697,35 +655,34 @@ __gnat_initialize (void *eh ATTRIBUTE_UNUSED)
#define NULL ((void *) 0)
#endif
struct Machine_State
static void __gnat_error_handler (int, siginfo_t *siginfo, void *ucontext);
/* __gnat_adjust_context_for_raise - see comments along with the default
version later in this file. */
#define HAVE_GNAT_ADJUST_CONTEXT_FOR_RAISE
void
__gnat_adjust_context_for_raise (int signo ATTRIBUTE_UNUSED, void *ucontext)
{
unsigned long eip;
unsigned long ebx;
unsigned long esp;
unsigned long ebp;
unsigned long esi;
unsigned long edi;
};
mcontext_t *mcontext = &((ucontext_t *) ucontext)->uc_mcontext;
static void __gnat_error_handler (int);
#if defined (i386)
mcontext->gregs[REG_EIP]++;
#elif defined (__x86_64__)
mcontext->gregs[REG_RIP]++;
#endif
}
static void
__gnat_error_handler (int sig)
__gnat_error_handler (int sig,
siginfo_t *siginfo ATTRIBUTE_UNUSED,
void *ucontext)
{
struct Exception_Data *exception;
const char *msg;
static int recurse = 0;
struct sigcontext *info
= (struct sigcontext *) (((char *) &sig) + sizeof (int));
/* The Linux kernel does not document how to get the machine state in a
signal handler, but in fact the necessary data is in a sigcontext_struct
value that is on the stack immediately above the signal number
parameter, and the above messing accesses this value on the stack. */
struct Machine_State *mstate;
switch (sig)
{
case SIGSEGV:
......@@ -781,19 +738,15 @@ __gnat_error_handler (int sig)
exception = &program_error;
msg = "unhandled signal";
}
recurse = 0;
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;
}
/* We adjust the interrupted context here (and not in the
MD_FALLBACK_FRAME_STATE_FOR macro) because recent versions of the Native
POSIX Thread Library (NPTL) are compiled with DWARF 2 unwind information,
and hence the later macro is never executed for signal frames. */
__gnat_adjust_context_for_raise (sig, ucontext);
recurse = 0;
Raise_From_Signal_Handler (exception, msg);
}
......@@ -806,8 +759,8 @@ __gnat_install_handler (void)
exceptions. Make sure that the handler isn't interrupted by another
signal that might cause a scheduling event! */
act.sa_handler = __gnat_error_handler;
act.sa_flags = SA_NODEFER | SA_RESTART;
act.sa_sigaction = __gnat_error_handler;
act.sa_flags = SA_NODEFER | SA_RESTART | SA_SIGINFO;
sigemptyset (&act.sa_mask);
/* Do not install handlers if interrupt state is "System" */
......@@ -825,51 +778,9 @@ __gnat_install_handler (void)
__gnat_handler_installed = 1;
}
void
__gnat_initialize (void *eh ATTRIBUTE_UNUSED)
{
}
/******************************************/
/* __gnat_initialize (NT-mingw32 Version) */
/******************************************/
#elif defined (__MINGW32__)
#include <windows.h>
void
__gnat_install_handler (void)
{
}
void
__gnat_initialize (void *eh ATTRIBUTE_UNUSED)
{
/* Initialize floating-point coprocessor. This call is needed because
the MS libraries default to 64-bit precision instead of 80-bit
precision, and we require the full precision for proper operation,
given that we have set Max_Digits etc with this in mind */
__gnat_init_float ();
/* Initialize a lock for a process handle list - see a-adaint.c for the
implementation of __gnat_portable_no_block_spawn, __gnat_portable_wait */
__gnat_plist_init();
/* Note that we do not activate this for the compiler itself to avoid a
bootstrap path problem. Older version of gnatbind will generate a call
to __gnat_initialize() without argument. Therefore we cannot use eh in
this case. It will be possible to remove the following #ifdef at some
point. */
#ifdef IN_RTS
/* Install the Structured Exception handler. */
if (eh)
__gnat_install_SEH_handler (eh);
#endif
}
/***************************************/
/* __gnat_initialize (Interix Version) */
/***************************************/
/*******************/
/* Interix Section */
/*******************/
#elif defined (__INTERIX)
......@@ -934,58 +845,9 @@ __gnat_install_handler (void)
__gnat_handler_installed = 1;
}
void
__gnat_initialize (void *eh ATTRIBUTE_UNUSED)
{
__gnat_init_float ();
}
/**************************************/
/* __gnat_initialize (LynxOS Version) */
/**************************************/
#elif defined (__Lynx__)
void
__gnat_initialize (void *eh ATTRIBUTE_UNUSED)
{
__gnat_init_float ();
}
/*********************************/
/* __gnat_install_handler (Lynx) */
/*********************************/
void
__gnat_install_handler (void)
{
__gnat_handler_installed = 1;
}
/****************************/
/* __gnat_initialize (OS/2) */
/****************************/
#elif defined (__EMX__) /* OS/2 dependent initialization */
void
__gnat_initialize (void *eh ATTRIBUTE_UNUSED)
{
}
/*********************************/
/* __gnat_install_handler (OS/2) */
/*********************************/
void
__gnat_install_handler (void)
{
__gnat_handler_installed = 1;
}
/***********************************/
/* __gnat_initialize (SGI Version) */
/***********************************/
/****************/
/* IRIX Section */
/****************/
#elif defined (sgi)
......@@ -1135,14 +997,9 @@ __gnat_install_handler (void)
__gnat_handler_installed = 1;
}
void
__gnat_initialize (void *eh ATTRIBUTE_UNUSED)
{
}
/*************************************************/
/* __gnat_initialize (Solaris and SunOS Version) */
/*************************************************/
/*******************/
/* Solaris Section */
/*******************/
#elif defined (sun) && defined (__SVR4) && !defined (__vxworks)
......@@ -1243,17 +1100,14 @@ __gnat_install_handler (void)
__gnat_handler_installed = 1;
}
void
__gnat_initialize (void *eh ATTRIBUTE_UNUSED)
{
}
/***********************************/
/* __gnat_initialize (VMS Version) */
/***********************************/
/***************/
/* VMS Section */
/***************/
#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
......@@ -1273,12 +1127,69 @@ extern long __gnat_error_prehandler (void);
extern char *__gnat_error_prehandler_stack; /* Alternate signal stack */
#endif
/* Define macro symbols for the VMS conditions that become Ada exceptions.
Most of these are also defined in the header file ssdef.h which has not
yet been converted to be recoginized by Gnu C. */
/* Defining these as macros, as opposed to external addresses, allows
them to be used in a case statement (below */
#define SS$_ACCVIO 12
#define SS$_HPARITH 1284
#define SS$_STKOVF 1364
#define SS$_RESIGNAL 2328
/* These codes are in standard message libraries */
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; /* Some ACVC_21 CXA tests */
/* These codes are non standard, which is to say the author is
not sure if they are defined in the standar message libraries
so keep them as macros for now. */
#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; };
/* Conditions that don't have an Ada exception counterpart must raise
Non_Ada_Error. Since this is defined in s-auxdec, it should only be
referenced by user programs, not the compiler or tools. Hence the
#ifdef IN_RTS. */
#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;
......@@ -1287,30 +1198,89 @@ 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 macro symbols for the VMS conditions that become Ada exceptions.
Most of these are also defined in the header file ssdef.h which has not
yet been converted to be recognized by Gnu C. Some, which couldn't be
located, are assigned names based on the DEC test suite tests which
raise them. */
/* DEC Ada exceptions are not defined in a header file, so they
must be declared as external addresses */
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));
/* DEC Ada specific conditions */
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}
};
#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 /* Some ACVC_21 CXA tests */
#define SS$_CE24VRU 3253636 /* Write to unopened file */
#define SS$_C980VTE 3246436 /* AST requests time slice */
#define CMA$_EXIT_THREAD 4227492
#define CMA$_EXCCOPLOS 4228108
#define CMA$_ALERTED 4227460
#if 0
/* Already handled by a pragma Import_Exception
in Aux_IO_Exceptions */
{&ADA$_LOCK_ERROR, &Lock_Error},
{&ADA$_EXISTENCE_ERROR, &Existence_Error},
{&ADA$_KEY_ERROR, &Key_Error},
#endif
struct descriptor_s {unsigned short len, mbz; char *adr; };
#endif /* IN_RTS */
long __gnat_error_handler (int *, void *);
/* Non DEC Ada specific conditions. We could probably also put
SS$_HPARITH here and possibly SS$_ACCVIO, SS$_STKOVF. */
static const struct cond_except cond_except_table [] = {
{&MTH$_FLOOVEMAT, &constraint_error},
{&SS$_INTDIV, &constraint_error},
{0, 0}
};
/* To deal with VMS conditions and their mapping to Ada exceptions,
the __gnat_error_handler routine below is installed as an exception
......@@ -1318,7 +1288,7 @@ long __gnat_error_handler (int *, void *);
still need to be handled by such handlers, however, in which case
__gnat_error_handler needs to return SS$_RESIGNAL. Consider for
instance the use of a third party library compiled with DECAda and
performing its own exception handling internally.
performing it's own exception handling internally.
To allow some user-level flexibility, which conditions should be
resignaled is controlled by a predicate function, provided with the
......@@ -1337,26 +1307,36 @@ long __gnat_error_handler (int *, void *);
??? This is not a perfect solution to deal with the possible
interactions between the GNAT and the DECAda exception handling
models and better (more general) schemes are studied. This is so
just provided as a convenient workaround in the meantime, and
just provided as a conveniency workaround in the meantime, and
should be use with caution since the implementation has been kept
very simple. */
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
};
/* Default GNAT predicate for resignaling conditions. */
static int
__gnat_default_resignal_p (int code)
{
return
code == CMA$_EXIT_THREAD
|| code == SS$_DEBUG /* Gdb attach, resignal to merge activate gdbstub. */
|| code == 1409786 /* Nickerson bug #33 ??? */
|| code == 1381050 /* Nickerson bug #33 ??? */
|| code == 20480426 /* RDB-E-STREAM_EOF */
|| code == 11829410 /* Resignalled as Use_Error for CE10VRC */
;
int i, iexcept;
for (i = 0, iexcept = 0;
cond_resignal_table [i] &&
!(iexcept = LIB$MATCH_COND (&code, &cond_resignal_table [i]));
i++);
return iexcept;
}
/* Static pointer to predicate that the __gnat_error_handler exception
......@@ -1376,18 +1356,47 @@ __gnat_set_resignal_predicate (resignal_predicate * predicate)
__gnat_resignal_p = predicate;
}
/* Should match System.Parameters.Default_Exception_Msg_Max_Length */
#define Default_Exception_Msg_Max_Length 512
/* Action routine for SYS$PUTMSG. There may be
multiple conditions, each with text to be appended to
MESSAGE and separated by line termination. */
static int
copy_msg (msgdesc, message)
struct descriptor_s *msgdesc;
char *message;
{
int len = strlen (message);
int copy_len;
/* Check for buffer overflow and skip */
if (len > 0 && len <= Default_Exception_Msg_Max_Length - 3)
{
strcat (message, "\r\n");
len += 2;
}
/* Check for buffer overflow and truncate if necessary */
copy_len = (len + msgdesc->len <= Default_Exception_Msg_Max_Length - 1 ?
msgdesc->len :
len + msgdesc->len - Default_Exception_Msg_Max_Length);
strncpy (&message [len], msgdesc->adr, copy_len);
message [len + copy_len] = 0;
return 0;
}
long
__gnat_error_handler (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];
char *msg = "";
char message[256];
long prvhnd;
struct descriptor_s msgdesc;
int msg_flag = 0x000f; /* 1 bit for each of the four message parts */
unsigned short outlen;
char curr_icb[544];
long curr_invo_handle;
long *mstate;
......@@ -1405,11 +1414,8 @@ __gnat_error_handler (int *sigargs, void *mechargs)
if (exception)
{
msgdesc.len = 256;
msgdesc.mbz = 0;
msgdesc.adr = message;
SYS$GETMSG (sigargs[1], &outlen, &msgdesc, msg_flag, 0);
message[outlen] = 0;
message [0] = 0;
SYS$PUTMSG (sigargs, copy_msg, &gnat_facility, message);
msg = message;
exception->Name_Length = 19;
......@@ -1440,11 +1446,6 @@ __gnat_error_handler (int *sigargs, void *mechargs)
msg = "stack overflow";
break;
case SS$_INTDIV:
exception = &constraint_error;
msg = "division by zero";
break;
case SS$_HPARITH:
#ifndef IN_RTS
return SS$_RESIGNAL; /* toplev.c handles for compiler */
......@@ -1456,34 +1457,46 @@ __gnat_error_handler (int *sigargs, void *mechargs)
#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;
#ifdef IN_RTS
{
int i;
/* Scan the DEC Ada exception condition table for a match and fetch the
associated GNAT exception pointer */
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)
/* DEC Ada exceptions never have a PC and PSL appended, but LIB$STOP
(which is how we got here from Bliss code)
allows slots for them and the result is 2 words of garbage on the
end, so the count must be decremented. */
sigargs [0] -= 2;
else
{
/* Scan the VMS standard condition table for a match and fetch the
associated GNAT exception pointer */
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)
/* User programs expect Non_Ada_Error to be raised, reference
DEC Ada test CXCONDHAN. */
exception = &Non_Ada_Error;
}
}
#else
/* User programs expect Non_Ada_Error to be raised, reference
DEC Ada test CXCONDHAN. */
exception = &Non_Ada_Error;
exception = &program_error;
#endif
msgdesc.len = 256;
msgdesc.mbz = 0;
msgdesc.adr = message;
SYS$GETMSG (sigargs[1], &outlen, &msgdesc, msg_flag, 0);
message[outlen] = 0;
message [0] = 0;
SYS$PUTMSG (sigargs, copy_msg, &gnat_facility, message);
msg = message;
break;
}
......@@ -1516,17 +1529,13 @@ __gnat_install_handler (void)
#else
SYS$SETEXV (1, __gnat_error_handler, 3, &prvhnd);
#endif
__gnat_handler_installed = 1;
}
void
__gnat_initialize(void *eh ATTRIBUTE_UNUSED)
{
__gnat_handler_installed = 1;
}
/*************************************************/
/* __gnat_initialize (FreeBSD version) */
/*************************************************/
/*******************/
/* FreeBSD Section */
/*******************/
#elif defined (__FreeBSD__)
......@@ -1589,24 +1598,13 @@ __gnat_install_handler ()
(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 ();
/* XXX - Initialize floating-point coprocessor. This call is
needed because FreeBSD defaults to 64-bit precision instead
of 80-bit precision? We require the full precision for
proper operation, given that we have set Max_Digits etc
with this in mind */
__gnat_init_float ();
__gnat_handler_installed = 1;
}
/***************************************/
/* __gnat_initialize (VXWorks Version) */
/***************************************/
/*******************/
/* VxWorks Section */
/*******************/
#elif defined(__vxworks)
......@@ -1761,7 +1759,7 @@ __gnat_init_float (void)
asm ("mtfsb0 26");
#endif
/* Similarly for sparc64. Achieved by masking bits in the Trap Enable Mask
/* Similarily for sparc64. Achieved by masking bits in the Trap Enable Mask
field of the Floating-point Status Register (see the Sparc Architecture
Manual Version 9, p 48). */
#if defined (sparc64)
......@@ -1781,69 +1779,9 @@ __gnat_init_float (void)
#endif
}
void
__gnat_initialize (void *eh ATTRIBUTE_UNUSED)
{
__gnat_init_float ();
/* On targets where we might be using the ZCX scheme, we need to register
the frame tables.
For applications loaded as a set of "modules", the crtstuff objects
linked in (crtbegin/end) are tailored to provide this service a-la C++
constructor fashion, typically triggered by the VxWorks loader. This is
achieved by way of a special variable declaration in the crt object, the
name of which has been deduced by analyzing the output of the "munching"
step documented for C++. The de-registration is handled symmetrically,
a-la C++ destructor fashion and typically triggered by the dynamic
unloader. Note that since the tables shall be registered against a
common datastructure, libgcc should be one of the modules (vs being
partially linked against all the others at build time) and shall be
loaded first.
For applications linked with the kernel, the scheme above would lead to
duplicated symbols because the VxWorks kernel build "munches" by default.
To prevent those conflicts, we link against crtbegin/endS objects that
don't include the special variable and directly call the appropriate
function here. We'll never unload that, so there is no de-registration to
worry about.
For whole applications loaded as a single module, we may use one scheme
or the other, except for the mixed Ada/C++ case in which the first scheme
would fail for the same reason as in the linked-with-kernel situation.
We can differentiate by looking at the __module_has_ctors value provided
by each class of crt objects. As of today, selecting the crt set with the
ctors/dtors capabilities (first scheme above) is triggered by adding
"-dynamic" to the gcc *link* command line options. Selecting the other
set of crt objects is achieved by "-static" instead.
This is a first approach, tightly synchronized with a number of GCC
configuration and crtstuff changes. We need to ensure that those changes
are there to activate this circuitry. */
#if (__GNUC__ >= 3) && (defined (_ARCH_PPC) || defined (__ppc))
{
/* The scheme described above is only useful for the actual ZCX case, and
we don't want any reference to the crt provided symbols otherwise. We
may not link with any of the crt objects in the non-ZCX case, e.g. from
documented procedures instructing the use of -nostdlib, and references
to the ctors symbols here would just remain unsatisfied.
We have no way to avoid those references in the right conditions in this
C module, because we have nothing like a IN_ZCX_RTS macro. This aspect
is then deferred to an Ada routine, which can do that based on a test
against a constant System flag value. */
extern void __gnat_vxw_setup_for_eh (void);
__gnat_vxw_setup_for_eh ();
}
#endif
}
/********************************/
/* __gnat_initialize for NetBSD */
/********************************/
/******************/
/* NetBSD Section */
/******************/
#elif defined(__NetBSD__)
......@@ -1904,30 +1842,13 @@ __gnat_install_handler(void)
__gnat_handler_installed = 1;
}
void
__gnat_initialize (void *eh ATTRIBUTE_UNUSED)
{
__gnat_install_handler ();
__gnat_init_float ();
}
#else
/* For all other versions of GNAT, the initialize routine and handler
installation do nothing */
/***************************************/
/* __gnat_initialize (Default Version) */
/***************************************/
void
__gnat_initialize (void *eh ATTRIBUTE_UNUSED)
{
}
/* For all other versions of GNAT, the handler does nothing */
/********************************************/
/* __gnat_install_handler (Default Version) */
/********************************************/
/*******************/
/* Default Section */
/*******************/
void
__gnat_install_handler (void)
......
/****************************************************************************
* *
* GNAT COMPILER COMPONENTS *
* *
* I N I T I A L I Z E *
* *
* C Implementation File *
* *
* Copyright (C) 1992-2005, Free Software Foundation, Inc. *
* *
* GNAT is free software; you can redistribute it and/or modify it under *
* terms of the GNU General Public License as published by the Free Soft- *
* ware Foundation; either version 2, or (at your option) any later ver- *
* sion. GNAT is distributed in the hope that it will be useful, but WITH- *
* OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
* for more details. You should have received a copy of the GNU General *
* Public License distributed with GNAT; see file COPYING. If not, write *
* to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, *
* MA 02111-1307, USA. *
* *
* As a special exception, if you link this file with other files to *
* produce an executable, this file does not by itself cause the resulting *
* executable to be covered by the GNU General Public License. This except- *
* ion does not however invalidate any other reasons why the executable *
* file might be covered by the GNU Public License. *
* *
* GNAT was originally developed by the GNAT team at New York University. *
* Extensive contributions were provided by Ada Core Technologies Inc. *
* *
****************************************************************************/
/* This unit provides default implementation for __gnat_initialize ()
which is called before the elaboration of the partition. It is provided
in a separate file/object so that users can replace it easily.
The default implementation should be null on most targets. */
/* The following include is here to meet the published VxWorks requirement
that the __vxworks header appear before any other include. */
#ifdef __vxworks
#include "vxWorks.h"
#endif
#ifdef IN_RTS
#include "tconfig.h"
#include "tsystem.h"
#else
#include "config.h"
#include "system.h"
#endif
#include "raise.h"
/******************************************/
/* __gnat_initialize (NT-mingw32 Version) */
/******************************************/
#if defined (__MINGW32__)
#include <windows.h>
extern void __gnat_init_float (void);
extern void __gnat_plist_init (void);
extern void __gnat_install_SEH_handler (void *);
void
__gnat_initialize (void *eh)
{
/* Initialize floating-point coprocessor. This call is needed because
the MS libraries default to 64-bit precision instead of 80-bit
precision, and we require the full precision for proper operation,
given that we have set Max_Digits etc with this in mind */
__gnat_init_float ();
/* Initialize a lock for a process handle list - see adaint.c for the
implementation of __gnat_portable_no_block_spawn, __gnat_portable_wait */
__gnat_plist_init();
/* Note that we do not activate this for the compiler itself to avoid a
bootstrap path problem. Older version of gnatbind will generate a call
to __gnat_initialize() without argument. Therefore we cannot use eh in
this case. It will be possible to remove the following #ifdef at some
point. */
#ifdef IN_RTS
/* Install the Structured Exception handler. */
if (eh)
__gnat_install_SEH_handler (eh);
#endif
}
/******************************************/
/* __gnat_initialize (init_float version) */
/******************************************/
#elif defined (__INTERIX) || defined (__Lynx__) || \
defined (__FreeBSD__) || defined(__NetBSD__)
extern void __gnat_init_float (void);
void
__gnat_initialize (void *eh ATTRIBUTE_UNUSED)
{
__gnat_init_float ();
}
/***************************************/
/* __gnat_initialize (VxWorks Version) */
/***************************************/
#elif defined(__vxworks)
extern void __gnat_init_float (void);
void
__gnat_initialize (void *eh)
{
__gnat_init_float ();
/* On targets where we might be using the ZCX scheme, we need to register
the frame tables.
For applications loaded as a set of "modules", the crtstuff objects
linked in (crtbegin/end) are tailored to provide this service a-la C++
constructor fashion, typically triggered by the VxWorks loader. This is
achieved by way of a special variable declaration in the crt object, the
name of which has been deduced by analyzing the output of the "munching"
step documented for C++. The de-registration is handled symetrically,
a-la C++ destructor fashion and typically triggered by the dynamic
unloader. Note that since the tables shall be registered against a
common datastructure, libgcc should be one of the modules (vs beeing
partially linked against all the others at build time) and shall be
loaded first.
For applications linked with the kernel, the scheme above would lead to
duplicated symbols because the VxWorks kernel build "munches" by default.
To prevent those conflicts, we link against crtbegin/endS objects that
don't include the special variable and directly call the appropriate
function here. We'll never unload that, so there is no de-registration to
worry about.
For whole applications loaded as a single module, we may use one scheme
or the other, except for the mixed Ada/C++ case in which the first scheme
would fail for the same reason as in the linked-with-kernel situation.
We can differentiate by looking at the __module_has_ctors value provided
by each class of crt objects. As of today, selecting the crt set with the
ctors/dtors capabilities (first scheme above) is triggered by adding
"-dynamic" to the gcc *link* command line options. Selecting the other
set of crt objects is achieved by "-static" instead.
This is a first approach, tightly synchronized with a number of GCC
configuration and crtstuff changes. We need to ensure that those changes
are there to activate this circuitry. */
#if (__GNUC__ >= 3) && (defined (_ARCH_PPC) || defined (__ppc))
{
/* The scheme described above is only useful for the actual ZCX case, and
we don't want any reference to the crt provided symbols otherwise. We
may not link with any of the crt objects in the non-ZCX case, e.g. from
documented procedures instructing the use of -nostdlib, and references
to the ctors symbols here would just remain unsatisfied.
We have no way to avoid those references in the right conditions in this
C module, because we have nothing like a IN_ZCX_RTS macro. This aspect
is then deferred to an Ada routine, which can do that based on a test
against a constant System flag value. */
extern void __gnat_vxw_setup_for_eh (void);
__gnat_vxw_setup_for_eh ();
}
#endif
}
#else
/* For all other versions of GNAT, the initialize routine and handler
installation do nothing */
/***************************************/
/* __gnat_initialize (Default Version) */
/***************************************/
void
__gnat_initialize (void *eh ATTRIBUTE_UNUSED)
{
}
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment