OSDN Git Service

* 5tsystem.ads: Removed, no longer used.
[pf3gnuchains/gcc-fork.git] / gcc / ada / init.c
index b27e059..4a54aff 100644 (file)
@@ -111,6 +111,7 @@ 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;
 
 /* Indication of whether synchronous signal handler has already been
    installed by a previous call to adainit */
@@ -173,7 +174,8 @@ __gnat_set_globals (int main_priority,
                     int num_interrupt_states,
                     int unreserve_all_interrupts,
                     int exception_tracebacks,
-                    int zero_cost_exceptions)
+                    int zero_cost_exceptions,
+                    int detect_blocking)
 {
   static int already_called = 0;
 
@@ -236,6 +238,7 @@ __gnat_set_globals (int main_priority,
   __gl_task_dispatching_policy  = task_dispatching_policy;
   __gl_unreserve_all_interrupts = unreserve_all_interrupts;
   __gl_exception_tracebacks     = exception_tracebacks;
+  __gl_detect_blocking          = detect_blocking;
 
   /* ??? __gl_zero_cost_exceptions is new in 3.15 and is referenced from
      a-except.adb, which is also part of the compiler sources. Since the
@@ -262,6 +265,51 @@ __gnat_set_globals (int main_priority,
    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 :
+
+   What we call Zero Cost Exceptions is implemented using the GCC eh
+   circuitry, even if the underlying implementation is setjmp/longjmp
+   based. In any case ...
+
+   The GCC unwinder expects to be dealing with call return addresses, since
+   this is the "nominal" case of what we retrieve while unwinding a regular
+   call chain. To evaluate if a handler applies at some point in this chain,
+   the propagation engine needs to determine what region the corresponding
+   call instruction pertains to. The return address may not be attached to the
+   same region as the call, so the unwinder unconditionally substracts "some"
+   amount to the return addresses it gets to search the region tables. The
+   exact amount is computed to ensure that the resulting address is inside the
+   call instruction, and is thus target dependant (think about delay slots for
+   instance).
+
+   When we raise an exception from a signal handler, e.g. to transform a
+   SIGSEGV into Storage_Error, things need to appear as if the signal handler
+   had been "called" by the instruction which triggered the signal, so that
+   exception handlers that apply there are considered. What the unwinder will
+   retrieve as the return address from the signal handler is what it will find
+   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 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.
+
+   The thread at http://gcc.gnu.org/ml/gcc-patches/2004-05/msg00343.html
+   describes a couple of issues with our current approach. Basically: on some
+   targets the adjustment to apply depends on the triggering signal, which is
+   not easily accessible from the macro, and we actually do not tackle this as
+   of today. Besides, other languages, e.g. Java, deal with this by performing
+   the adjustment in the signal handler before the raise, so our adjustments
+   may break those front-ends.
+
+   To have it all right, we should either find a way to deal with the signal
+   variants from the macro and convert Java on all targets (ugh), or remove
+   our macro adjustments and update our signal handlers a-la-java way.  The
+   latter option appears the simplest, although some targets have their share
+   of subtleties to account for.  See for instance the syscall(SYS_sigaction)
+   story in libjava/include/i386-signal.h.  */
+
 /***********************************/
 /* __gnat_initialize (AIX Version) */
 /***********************************/
@@ -1051,6 +1099,18 @@ struct Machine_State
 
 static void __gnat_error_handler (int, int, sigcontext_t *);
 
+/* We are not setting the SA_SIGINFO bit in the sigaction flags when
+   connecting that handler, with the effects described in the sigaction
+   man page:
+
+          SA_SIGINFO [...]
+          If cleared and the signal is caught, the first argument is
+          also the signal number but the second argument is the signal
+          code identifying the cause of the signal. The third argument
+          points to a sigcontext_t structure containing the receiving
+         process's context when the signal was delivered.
+*/
+
 static void
 __gnat_error_handler (int sig, int code, sigcontext_t *sc)
 {
@@ -1076,8 +1136,13 @@ __gnat_error_handler (int sig, int code, sigcontext_t *sc)
          exception = &program_error; /* ??? storage_error ??? */
          msg = "SIGSEGV: (Autogrow for file failed)";
        }
-      else if (code == EACCES)
+      else if (code == EACCES || code == EEXIST)
        {
+         /* ??? We handle stack overflows here, some of which do trigger
+                SIGSEGV + EEXIST on Irix 6.5 although EEXIST is not part of
+                the documented valid codes for SEGV in the signal(5) man
+                page.  */
+
          /* ??? Re-add smarts to further verify that we launched
                 the stack into a guard page, not an attempt to
                 write to .text or something */
@@ -1750,27 +1815,34 @@ __gnat_initialize (void)
   /* On targets where we might be using the ZCX scheme, we need to register
      the frame tables.
 
-     For application "modules", the crtstuff objects linked in (crtbegin/endS)
-     are tailored to provide this service a-la C++ constructor fashion,
-     typically triggered by the dynamic 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 call is handled symetrically, a-la C++
-     destructor fashion and typically triggered by the dynamic unloader. With
-     this scheme, a mixed Ada/C++ application has to be linked and loaded as
-     separate modules for each language, which is not unreasonable anyway.
-
-     For applications statically linked with the kernel, the module scheme
-     above would lead to duplicated symbols because the VxWorks kernel build
-     "munches" by default. To prevent those conflicts, we link against
-     crtbegin/end 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 applications loaded as a set of "modules", the crtstuff objects
+     linked in (crtbegin/endS) are tailored to provide this service a-la C++
+     static 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 call 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/end 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 intended
-     for applications to be statically linked with the kernel is triggered by
-     adding "-static" to the gcc *link* command line options.
+     by each class of crt objects. As of today, selecting the crt set with the
+     static ctors/dtors capabilities (first scheme above) is triggered by
+     adding "-static" to the gcc *link* command line options. Without this,
+     the other set of crt objects is fetched.
 
      This is a first approach, tightly synchronized with a number of GCC
      configuration and crtstuff changes. We need to ensure that those changes