OSDN Git Service

2005-06-10 Doug Rupp <rupp@adacore.com>
authorcharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 16 Jun 2005 08:43:05 +0000 (08:43 +0000)
committercharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 16 Jun 2005 08:43:05 +0000 (08:43 +0000)
    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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@101047 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ada/Make-lang.in
gcc/ada/init.c
gcc/ada/initialize.c [new file with mode: 0644]

index 251fa79..b9a5692 100644 (file)
@@ -1,6 +1,6 @@
 # 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
index 7ca6800..625e7ec 100644 (file)
@@ -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)
diff --git a/gcc/ada/initialize.c b/gcc/ada/initialize.c
new file mode 100644 (file)
index 0000000..4963e66
--- /dev/null
@@ -0,0 +1,187 @@
+/****************************************************************************
+ *                                                                          *
+ *                         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