[[!meta copyright="Copyright © 2011, 2012, 2013, 2016 Free Software Foundation, Inc."]] [[!meta license="""[[!toggle id="license" text="GFDL 1.2+"]][[!toggleable id="license" text="Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled [[GNU Free Documentation License|/fdl]]."]]"""]] [[!meta title="Enable Ada programming (GCC: GNAT)"]] [[!tag open_issue_gcc]] Make the Ada programming language available on GNU/Hurd in its [[GCC]] GNAT implementation, and enable Hurd-specific features. There is a [[!FF_project 259]][[!tag bounty]] on this task. --- # Part I First, make the language functional, have its test suite pass without errors. Using, for example, the build instructions from [[GCC]], you'll need to add `ada` to `--enable-languages`. ## Original [[community/GSoC]] Task Description [[!inline pages=community/gsoc/project_ideas/gnat feeds=no]] ## Debian GCC There has a patch been added for GNU/kFreeBSD: `bfe081336914729fc0180c07ab4afa41965100f2`, `git-svn-id: svn://svn.debian.org/gcccvs/branches/sid@5638 6ca36cf4-e1d1-0310-8c6f-e303bb2178ca' ## IRC, freenode, #hurd, 2012-07-17 I've found the remaining problem with gnat backtrace for Hurd! Related to the stack frame. This version does not work: one relying on static assumptions about the frame layout Causing segfaults. Any interest to create a test case out of that piece of code, taken from gcc/ada/tracebak.c? gnu_srs: sure ### IRC, freenode, #hurd, 2012-07-18 "Digging further revealed that the GNU/Hurd stack frame does not seem to be static enough to define USE_GENERIC_UNWINDER in gcc/ada/tracebak.c. " what do you mean by a "stack frame does not seem to be static enough" ? I can qoute from the source file if you want. Otherwise look at the code yourself: gcc/ada/tracebak,c I mean that something is wrong with the stack frame for Hurd. This is the code I wanted to use as a test case for the stack. Remember? more or less ah, "static assumptions" all right, i don't think anything is "wrong" with stack frames but if you use a recent version of gcc, as indicated in the code, -fomit-frame-pointer is enabled by default so your stack frame won't look like it used to be without the option hence the need for USE_GCC_UNWINDER http://en.wikipedia.org/wiki/Call_stack explains this very well However, kfreebsd does not seem to need USE_GCC_UNWINDER, how come? i guess they don't omit the frame pointer your fix is good btw thanks ### IRC, freenode, #hurd, 2012-07-19 tschwinge: The bug in #681998 should go upstream. Applied in Debian already. Hopefully this is the last patch needed for the port of GNAT to Hurd. ### 2015-11-27 Is this related to: `gcc/ada/tracebak.c`: #if (defined (__x86_64__) || defined (__linux__)) && !defined (__USING_SJLJ_EXCEPTIONS__) #define USE_GCC_UNWINDER #else #define USE_GENERIC_UNWINDER ## Svante's patch A basic port has been done by Svante, [[!debbug 668425]], [[!debbug 681998]], [[!message-id "1333104917.2962.439.camel@s1499.it.kth.se"]], but there's still lots of work remaining. The port is not yet upstream: the maintainer raised some concerns that [[I|tschwinge]] have not yet found the time to follow up on, [[!message-id "1339857758-5032-1-git-send-email-thomas@codesourcery.com"]]. While the test results of the GCC/GNAT testsuite don't look bad (but there are a few unresolved issues, and the testsuite appears to be a rather small one), I don't know if the port has yet seen any real-world usage, such as using it for any bigger Ada code bases, or any Ada testsuites. ### "try2" [[!message-id "1456875776.5852.194.camel@gmail.com"]]. GCC trunk r234252. Still incomplete. ## `getcontext`/`makecontext`/`setcontext`/`swapcontext` usage analysis In context of [[glibc/t/tls-threadvar]]. Looking at GCC trunk commit f6568ea476aa52a6e23c6db43b3e240cde55783a (2013-04-26). gcc/ada/init.c: sigaltstack (&stack, NULL); gcc/ada/init.c: sigaltstack (&stack, NULL); gcc/ada/init.c: sigaltstack (&stack, NULL); gcc/ada/s-osinte-aix.ads: function sigaltstack gcc/ada/s-osinte-aix.ads: pragma Import (C, sigaltstack, "sigaltstack"); gcc/ada/s-osinte-android.ads: function sigaltstack gcc/ada/s-osinte-android.ads: pragma Import (C, sigaltstack, "sigaltstack"); gcc/ada/s-osinte-darwin.ads: function sigaltstack gcc/ada/s-osinte-darwin.ads: pragma Import (C, sigaltstack, "sigaltstack"); gcc/ada/s-osinte-freebsd.ads: function sigaltstack gcc/ada/s-osinte-freebsd.ads: pragma Import (C, sigaltstack, "sigaltstack"); gcc/ada/s-osinte-hpux.ads: function sigaltstack gcc/ada/s-osinte-hpux.ads: pragma Import (C, sigaltstack, "sigaltstack"); gcc/ada/s-osinte-kfreebsd-gnu.ads: function sigaltstack gcc/ada/s-osinte-kfreebsd-gnu.ads: pragma Import (C, sigaltstack, "sigaltstack"); gcc/ada/s-osinte-linux.ads: function sigaltstack gcc/ada/s-osinte-linux.ads: pragma Import (C, sigaltstack, "sigaltstack"); gcc/ada/s-osinte-rtems.adb: -- sigaltstack -- gcc/ada/s-osinte-rtems.adb: function sigaltstack gcc/ada/s-osinte-rtems.adb: end sigaltstack; gcc/ada/s-osinte-rtems.ads: function sigaltstack gcc/ada/s-osinte-solaris-posix.ads: function sigaltstack gcc/ada/s-osinte-solaris-posix.ads: pragma Import (C, sigaltstack, "sigaltstack"); gcc/ada/s-taprop-linux.adb: Result := sigaltstack (Stack'Access, null); gcc/ada/s-taprop-posix.adb: Result := sigaltstack (Stack'Access, null); gcc/ada/init.c: stack.ss_sp = __gnat_alternate_stack; gcc/ada/init.c: stack.ss_sp = __gnat_alternate_stack; gcc/ada/init.c: stack.ss_sp = __gnat_alternate_stack; gcc/ada/s-osinte-aix.ads: ss_sp : System.Address; gcc/ada/s-osinte-android.ads: ss_sp : System.Address; gcc/ada/s-osinte-darwin.ads: ss_sp : System.Address; gcc/ada/s-osinte-darwin.ads: uc_stack : stack_t; -- Stack Used By This Context gcc/ada/s-osinte-freebsd.ads: ss_sp : System.Address; gcc/ada/s-osinte-hpux.ads: ss_sp : System.Address; gcc/ada/s-osinte-kfreebsd-gnu.ads: ss_sp : System.Address; gcc/ada/s-osinte-linux.ads: ss_sp : System.Address; gcc/ada/s-osinte-rtems.ads: ss_sp : System.Address; gcc/ada/s-osinte-solaris-posix.ads: ss_sp : System.Address; gcc/ada/s-osinte-solaris.ads: ss_sp : System.Address; gcc/ada/s-osinte-solaris.ads: uc_stack : record_type_2; gcc/ada/s-taprop-linux.adb: Stack.ss_sp := Self_ID.Common.Task_Alternate_Stack; gcc/ada/s-taprop-posix.adb: Stack.ss_sp := Self_ID.Common.Task_Alternate_Stack; gcc/ada/init.c: act.sa_flags |= SA_ONSTACK; gcc/ada/init.c: act.sa_flags |= SA_ONSTACK; gcc/ada/init.c: act.sa_flags = SA_SIGINFO | SA_ONSTACK; gcc/ada/init.c: act.sa_flags |= SA_ONSTACK; gcc/ada/s-intman-posix.adb: act.sa_flags := act.sa_flags + SA_ONSTACK; gcc/ada/s-linux-alpha.ads: SA_ONSTACK : constant := 16#01#; gcc/ada/s-linux-hppa.ads: SA_ONSTACK : constant := 16#01#; gcc/ada/s-linux-mipsel.ads: SA_ONSTACK : constant := 16#08000000#; gcc/ada/s-linux-sparc.ads: SA_ONSTACK : constant := 16#001#; gcc/ada/s-linux.ads: SA_ONSTACK : constant := 16#08000000#; gcc/ada/s-osinte-aix.ads: SA_ONSTACK : constant := 16#0001#; gcc/ada/s-osinte-android.ads: SA_ONSTACK : constant := System.Linux.SA_ONSTACK; gcc/ada/s-osinte-darwin.ads: SA_ONSTACK : constant := 16#0001#; gcc/ada/s-osinte-freebsd.ads: SA_ONSTACK : constant := 16#0001#; gcc/ada/s-osinte-hpux-dce.ads: SA_ONSTACK : constant := 16#01#; gcc/ada/s-osinte-hpux.ads: SA_ONSTACK : constant := 16#01#; gcc/ada/s-osinte-kfreebsd-gnu.ads: SA_ONSTACK : constant := 16#0001#; gcc/ada/s-osinte-linux.ads: SA_ONSTACK : constant := System.Linux.SA_ONSTACK; gcc/ada/s-osinte-lynxos.ads: SA_ONSTACK : constant := 16#00#; gcc/ada/s-osinte-lynxos.ads: -- SA_ONSTACK is not defined on LynxOS, but it is referred to in the POSIX gcc/ada/s-osinte-rtems.ads: SA_ONSTACK : constant := 16#00#; gcc/ada/s-osinte-rtems.ads: -- SA_ONSTACK is not defined on RTEMS, but it is referred to in the POSIX gcc/ada/s-osinte-solaris-posix.ads: SA_ONSTACK : constant := 16#0001#; gcc/ada/s-osinte-vxworks.ads: SA_ONSTACK : constant := 16#0004#; ## TODO diff --git ./gcc/ada/init.c ./gcc/ada/init.c @@ -2002,6 +2021,15 @@ __gnat_install_handler (void) trap_0_entry->inst_fourth = 0xa1480000; #endif {+#if (defined (i386) || defined (__i386__)) && !defined (VTHREADS)+} {+ /* By experiment, found that sysModel () returns the following string+} {+ prefix for vxsim when running on Linux and Windows. */+} {+ model = sysModel ();+} {+ if ((strncmp (model, "Linux", 5) == 0)+} {+ || (strncmp (model, "Windows", 7) == 0))+} {+ is_vxsim = 1;+} {+#endif+} __gnat_handler_installed = 1; } diff --git ./gcc/ada/sigtramp.h ./gcc/ada/sigtramp.h @@ -62,8 +62,14 @@ typedef struct ucontext system headers so call it something unique. */ typedef void __sigtramphandler_t (int signo, void *siginfo, void *sigcontext); {+#if CPU == SIMNT || CPU == SIMPENTIUM || CPU == SIMLINUX+} {+ /* Vxsim requires a specially compiled handler. */+} {+ void __gnat_sigtramp_vxsim (int signo, void *siginfo, void *sigcontext,+} {+ __sigtramphandler_t * handler);+} {+#else+} void __gnat_sigtramp (int signo, void *siginfo, void *sigcontext, __sigtramphandler_t * handler); {+#endif+} diff --git ./gcc/ada/gcc-interface/Makefile.in ./gcc/ada/gcc-interface/Makefile.in @@ -923,13 +928,49 @@ ifeq ($(strip $(filter-out %86 wrs vxworks vxworks7,$(target_cpu) $(target_vendo {+ VXSIM_CPU =+} {+ ifeq ($(strip $(filter-out vxworks rtp rtp-smp,$(target_os) $(THREAD_KIND))),)+} {+ VXSIM_CPU = SIMPENTIUM+} {+ else+} {+ ifeq ($(strip $(filter-out kernel kernel-smp rtp rtp-smp,$(THREAD_KIND))),)+} {+ ifeq ($(strip $(filter-out linux%,$(host_os))),)+} {+ # Linux+} {+ VXSIM_CPU = SIMLINUX+} {+ else+} {+ # Windows+} {+ VXSIM_CPU = SIMNT+} {+ endif+} {+ endif+} diff --git ./gcc/ada/gcc-interface/Makefile.in ./gcc/ada/gcc-interface/Makefile.in @@ -2413,6 +2468,14 @@ ifeq ($(filter a-except%,$(LIBGNAT_TARGET_PAIRS)),) {+# Configuration of host tools+} {+# Under linux, host tools need to be linked with -ldl+} {+ifeq ($(strip $(filter-out linux%,$(host_os))),)+} {+ TOOLS1_LIBS=-ldl+} {+endif+} diff --git ./gcc/ada/s-osinte-linux.ads ./gcc/ada/s-osinte-linux.ads @@ -224,6 +224,10 @@ package System.OS_Interface is {+function clock_gettime+} {+ (clock_id : clockid_t; tp : access timespec) return int;+} {+ pragma Import (C, clock_gettime, "clock_gettime");+} diff --git ./gcc/ada/s-taprop-linux.adb ./gcc/ada/s-taprop-linux.adb @@ -39,7 +39,6 @@ pragma Polling (Off); with Interfaces.C; [-with Interfaces.C.Extensions;-] @@ -64,7 +63,6 @@ package body System.Task_Primitives.Operations is use Interfaces.C; [- use Interfaces.C.Extensions;-] @@ -629,30 +627,14 @@ package body System.Task_Primitives.Operations is function Monotonic_Clock return Duration is [-use Interfaces;-] [- procedure timeval_to_duration-] [- (T : not null access timeval;-] [- sec : not null access C.Extensions.long_long;-] [- usec : not null access C.long);-] [- pragma Import (C, timeval_to_duration, "__gnat_timeval_to_duration");-] [- Micro : constant := 10**6;-] [- sec : aliased C.Extensions.long_long;-] [- usec : aliased C.long;-] [- TV-]{+TS+} : aliased [-timeval;-]{+timespec;+} Result : int; [- function gettimeofday-] [- (Tv : access timeval;-] [- Tz : System.Address := System.Null_Address) return int;-] [- pragma Import (C, gettimeofday, "gettimeofday");-] begin Result := [-gettimeofday (TV'Access, System.Null_Address);-]{+clock_gettime+} {+ (clock_id => OSC.CLOCK_RT_Ada, tp => TS'Unchecked_Access);+} pragma Assert (Result = 0); [-timeval_to_duration (TV'Access, sec'Access, usec'Access);-] return [-Duration (sec) + Duration (usec) / Micro;-]{+To_Duration (TS);+} end Monotonic_Clock; diff --git ./gcc/ada/adaint.c ./gcc/ada/adaint.c @@ -3220,6 +3220,107 @@ __gnat_kill (int pid, int sig, int close ATTRIBUTE_UNUSED) #endif } {+void __gnat_killprocesstree (int pid, int sig_num)+} {+{+} {+[...]+} {+#elif defined (__linux__)+} {+ DIR *dir;+} {+ struct dirent *d;+} {+ /* read all processes' pid and ppid */+} {+ dir = opendir ("/proc");+} {+[...]+} {+ /* kill process */+} {+ __gnat_kill (pid, sig_num, 1);+} {+#else+} {+ __gnat_kill (pid, sig_num, 1);+} {+#endif+} {+[...]+} {+}+} diff --git ./gcc/ada/s-os_lib.ads ./gcc/ada/s-os_lib.ads @@ -740,6 +744,19 @@ package System.OS_Lib is {+ procedure Kill_Process_Tree (Pid : Process_Id; Hard_Kill : Boolean := True);+} {+ -- Kill the process designated by Pid and all it's children processes.+} {+ -- [...] {+ -- Note that this routine is not atomic and is supported only on Linux+} {+ -- and Windows. On other OS it will only kill the process identified by+} {+ -- Pid.+} GCC includes (TODO: some version of) the Ada Conformity Assessment Test Suite (ACATS), . Additional tests to be found at . TODO: results? --- # Part II Next, Hurd-specific features can be added. Add an interface to the language/environment for being able to do [[RPC]] calls, in order to program [[hurd/translator]]s natively in Ada. ## Original [[community/GSoC]] Task Description [[!inline pages=community/gsoc/project_ideas/language_bindings feeds=no]]