summaryrefslogtreecommitdiff
path: root/gcc/ada/5zinit.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/5zinit.adb')
-rw-r--r--gcc/ada/5zinit.adb285
1 files changed, 285 insertions, 0 deletions
diff --git a/gcc/ada/5zinit.adb b/gcc/ada/5zinit.adb
new file mode 100644
index 00000000000..c947057f044
--- /dev/null
+++ b/gcc/ada/5zinit.adb
@@ -0,0 +1,285 @@
+------------------------------------------------------------------------------
+-- --
+-- GNU ADA RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . I N I T --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2003 Free Software Foundation, Inc. --
+-- --
+-- GNARL 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. GNARL 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 GNARL; 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 other files instantiate generics from this --
+-- unit, or you link this unit with other files to produce an executable, --
+-- this unit does not by itself cause the resulting executable to be --
+-- covered by the GNU General Public License. This exception does not --
+-- however invalidate any other reasons why the executable file might be --
+-- covered by the GNU Public License. --
+-- --
+-- GNARL was developed by the GNARL team at Florida State University. --
+-- Extensive contributions were provided by Ada Core Technologies, Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This is the VxWorks version of this package
+
+with System.OS_Interface;
+-- used for various Constants, Signal and types
+
+with Interfaces.C;
+-- used for int and other types
+
+with Ada.Exceptions;
+-- used for Raise_Exception
+
+package body System.Init is
+
+ -- This unit contains initialization circuits that are system dependent.
+
+ use Ada.Exceptions;
+ use System.OS_Interface;
+ use type Interfaces.C.int;
+
+ -- Copies of global values computed by the binder
+ Gl_Main_Priority : Integer := -1;
+ pragma Export (C, Gl_Main_Priority, "__gl_main_priority");
+
+ Gl_Time_Slice_Val : Integer := -1;
+ pragma Export (C, Gl_Time_Slice_Val, "__gl_time_slice_val");
+
+ Gl_Wc_Encoding : Character := 'n';
+ pragma Export (C, Gl_Wc_Encoding, "__gl_wc_encoding");
+
+ Gl_Locking_Policy : Character := ' ';
+ pragma Export (C, Gl_Locking_Policy, "__gl_locking_policy");
+
+ Gl_Queuing_Policy : Character := ' ';
+ pragma Export (C, Gl_Queuing_Policy, "__gl_queuing_policy");
+
+ Gl_Task_Dispatching_Policy : Character := ' ';
+ pragma Export (C, Gl_Task_Dispatching_Policy,
+ "__gl_task_dispatching_policy");
+
+ Gl_Restrictions : Address := Null_Address;
+ pragma Export (C, Gl_Restrictions, "__gl_restrictions");
+
+ Gl_Interrupt_States : Address := Null_Address;
+ pragma Export (C, Gl_Interrupt_States, "__gl_interrupt_states");
+
+ Gl_Num_Interrupt_States : Integer := 0;
+ pragma Export (C, Gl_Num_Interrupt_States, "__gl_num_interrupt_states");
+
+ Gl_Unreserve_All_Interrupts : Integer := 0;
+ pragma Export (C, Gl_Unreserve_All_Interrupts,
+ "__gl_unreserve_all_interrupts");
+
+ Gl_Exception_Tracebacks : Integer := 0;
+ pragma Export (C, Gl_Exception_Tracebacks, "__gl_exception_tracebacks");
+
+ Gl_Zero_Cost_Exceptions : Integer := 0;
+ pragma Export (C, Gl_Zero_Cost_Exceptions, "__gl_zero_cost_exceptions");
+
+ Already_Called : Boolean := False;
+
+ Handler_Installed : Integer := 0;
+ -- Indication of whether synchronous signal handlers have already been
+ -- installed by a previous call to Install_Handler.
+ pragma Export (C, Handler_Installed, "__gnat_handler_installed");
+
+ ------------------------
+ -- Local procedures --
+ ------------------------
+
+ procedure GNAT_Error_Handler (Sig : Signal);
+ -- Common procedure that is executed when a SIGFPE, SIGILL,
+ -- SIGSEGV, or SIGBUS is captured.
+
+ procedure Install_Handler;
+ pragma Export (C, Install_Handler, "__gnat_install_handler");
+ -- Install handler for the synchronous signals. The C profile
+ -- here is what is expected by the binder-generated main.
+
+ ------------------------
+ -- GNAT_Error_Handler --
+ ------------------------
+
+ procedure GNAT_Error_Handler (Sig : Signal) is
+ Mask : aliased sigset_t;
+ Result : int;
+
+ begin
+ -- VxWorks will always mask out the signal during the signal
+ -- handler and will reenable it on a longjmp. GNAT does not
+ -- generate a longjmp to return from a signal handler so the
+ -- signal will still be masked unless we unmask it.
+
+ Result := pthread_sigmask (SIG_SETMASK, null, Mask'Unchecked_Access);
+ Result := sigdelset (Mask'Access, Sig);
+ Result := pthread_sigmask (SIG_SETMASK, Mask'Unchecked_Access, null);
+
+ case Sig is
+ when SIGFPE =>
+ Raise_Exception (Constraint_Error'Identity, "SIGFPE");
+ when SIGILL =>
+ Raise_Exception (Constraint_Error'Identity, "SIGILL");
+ when SIGSEGV =>
+ Raise_Exception
+ (Program_Error'Identity,
+ "erroneous memory access");
+ when SIGBUS =>
+ Raise_Exception
+ (Storage_Error'Identity,
+ "stack overflow or SIGBUS");
+ when others =>
+ Raise_Exception (Program_Error'Identity, "unhandled signal");
+ end case;
+ end GNAT_Error_Handler;
+
+ -----------------
+ -- Set_Globals --
+ -----------------
+
+ -- This routine is called from the binder generated main program. It
+ -- copies the values for global quantities computed by the binder
+ -- into the following global locations. The reason that we go through
+ -- this copy, rather than just define the global locations in the
+ -- binder generated file, is that they are referenced from the
+ -- runtime, which may be in a shared library, and the binder file is
+ -- not in the shared library. Global references across library
+ -- boundaries like this are not handled correctly in all systems.
+
+ procedure Set_Globals
+ (Main_Priority : Integer;
+ Time_Slice_Value : Integer;
+ WC_Encoding : Character;
+ Locking_Policy : Character;
+ Queuing_Policy : Character;
+ Task_Dispatching_Policy : Character;
+ Restrictions : System.Address;
+ Interrupt_States : System.Address;
+ Num_Interrupt_States : Integer;
+ Unreserve_All_Interrupts : Integer;
+ Exception_Tracebacks : Integer;
+ Zero_Cost_Exceptions : Integer) is
+ begin
+ -- If this procedure has been already called once, check that the
+ -- arguments in this call are consistent with the ones in the
+ -- previous calls. Otherwise, raise a Program_Error exception.
+ --
+ -- We do not check for consistency of the wide character encoding
+ -- method. This default affects only Wide_Text_IO where no
+ -- explicit coding method is given, and there is no particular
+ -- reason to let this default be affected by the source
+ -- representation of a library in any case.
+ --
+ -- We do not check either for the consistency of exception tracebacks,
+ -- because exception tracebacks are not normally set in Stand-Alone
+ -- libraries. If a library or the main program set the exception
+ -- tracebacks, then they are never reset afterwards (see below).
+ --
+ -- The value of main_priority is meaningful only when we are
+ -- invoked from the main program elaboration routine of an Ada
+ -- application. Checking the consistency of this parameter should
+ -- therefore not be done. Since it is assured that the main
+ -- program elaboration will always invoke this procedure before
+ -- any library elaboration routine, only the value of
+ -- main_priority during the first call should be taken into
+ -- account and all the subsequent ones should be ignored. Note
+ -- that the case where the main program is not written in Ada is
+ -- also properly handled, since the default value will then be
+ -- used for this parameter.
+ --
+ -- For identical reasons, the consistency of time_slice_val should
+ -- not be checked.
+
+ if Already_Called then
+ if (Gl_Locking_Policy /= Locking_Policy) or
+ (Gl_Queuing_Policy /= Queuing_Policy) or
+ (Gl_Task_Dispatching_Policy /= Task_Dispatching_Policy) or
+ (Gl_Unreserve_All_Interrupts /= Unreserve_All_Interrupts) or
+ (Gl_Exception_Tracebacks /= Exception_Tracebacks) or
+ (Gl_Zero_Cost_Exceptions /= Zero_Cost_Exceptions)
+ then
+ raise Program_Error;
+ end if;
+
+ -- If either a library or the main program set the exception
+ -- traceback flag, it is never reset later.
+
+ if Gl_Exception_Tracebacks /= 0 then
+ Gl_Exception_Tracebacks := Exception_Tracebacks;
+ end if;
+
+ else
+ Already_Called := True;
+
+ Gl_Main_Priority := Main_Priority;
+ Gl_Time_Slice_Val := Time_Slice_Value;
+ Gl_Wc_Encoding := WC_Encoding;
+ Gl_Locking_Policy := Locking_Policy;
+ Gl_Queuing_Policy := Queuing_Policy;
+ Gl_Task_Dispatching_Policy := Task_Dispatching_Policy;
+ Gl_Restrictions := Restrictions;
+ Gl_Interrupt_States := Interrupt_States;
+ Gl_Num_Interrupt_States := Num_Interrupt_States;
+ Gl_Unreserve_All_Interrupts := Unreserve_All_Interrupts;
+ Gl_Exception_Tracebacks := Exception_Tracebacks;
+ Gl_Zero_Cost_Exceptions := Zero_Cost_Exceptions;
+ end if;
+ end Set_Globals;
+
+ -----------------------------
+ -- Install_Signal_Handlers --
+ -----------------------------
+
+ function Install_Signal_Handlers return Interfaces.C.int is
+ begin
+ Install_Handler;
+ return 0;
+ end Install_Signal_Handlers;
+
+ ---------------------
+ -- Install_Handler --
+ ---------------------
+
+ procedure Install_Handler is
+ Mask : aliased sigset_t;
+ Signal_Action : aliased struct_sigaction;
+ Result : Interfaces.C.int;
+
+ begin
+ -- Set up signal handler to map synchronous signals to appropriate
+ -- exceptions. Make sure that the handler isn't interrupted by
+ -- another signal that might cause a scheduling event!
+
+ Signal_Action.sa_handler := GNAT_Error_Handler'Address;
+ Signal_Action.sa_flags := SA_ONSTACK;
+ Result := sigemptyset (Mask'Access);
+ Signal_Action.sa_mask := Mask;
+
+ Result := sigaction
+ (Signal (SIGFPE), Signal_Action'Unchecked_Access, null);
+
+ Result := sigaction
+ (Signal (SIGILL), Signal_Action'Unchecked_Access, null);
+
+ Result := sigaction
+ (Signal (SIGSEGV), Signal_Action'Unchecked_Access, null);
+
+ Result := sigaction
+ (Signal (SIGBUS), Signal_Action'Unchecked_Access, null);
+
+ Handler_Installed := 1;
+ end Install_Handler;
+
+end System.Init;