diff --git a/base/src/test/ada/README b/base/src/test/ada/README new file mode 100644 index 000000000..452206bbe --- /dev/null +++ b/base/src/test/ada/README @@ -0,0 +1,20 @@ +This directory contains a test for using freestanding Ada code with Genode. + +The program relies on the normal startup procedure of a Genode process. +Execution starts at the 'crt0' assembly entry provided by the startup library. +The 'crt0' code sets up the stack of the main thread and calls the '_main' +function implemented in the C++ portion of Genode's startup library. In turn, +the '_main' function calls 'main' of the actual program. The main function of +this example calls the Ada main procedure. The test further exercises the call +of C functions from Ada code. So the integration of Ada and C code is almost +seamless. + +For building the Ada test program, you must have installed the GNU GNAT Ada +compiler. Right now, we are using the host version of this compiler, which +is save as long as we do not use advanced Ada features such as exceptions. +To enable building the test program, add 'gnat' to the 'SPECS' declaration +of your '/etc/specs.conf'. Otherwise, the Genode build system +will skip the target. + +Please note that the current version of this program does not use 'gnatbind'. +Therefore, package elaboration is not executed. diff --git a/base/src/test/ada/add.cc b/base/src/test/ada/add.cc new file mode 100644 index 000000000..5fb5bccc3 --- /dev/null +++ b/base/src/test/ada/add.cc @@ -0,0 +1,24 @@ +/* + * \brief C functions referenced by Ada code + * \author Norman Feske + * \date 2009-09-23 + */ + +/* Genode includes */ +#include + +using namespace Genode; + + +extern "C" void add(int a, int b, int *result) +{ + printf("add called with a=%d, b=%d, result at address 0x%p\n", + a, b, result); + *result = a + b; +} + + +extern "C" void print_int(int a) +{ + printf("print_int called with argument %d\n", a); +} diff --git a/base/src/test/ada/main.adb b/base/src/test/ada/main.adb new file mode 100644 index 000000000..168fd2d51 --- /dev/null +++ b/base/src/test/ada/main.adb @@ -0,0 +1,30 @@ +-- +-- \brief Ada test program that calls a external C functions +-- \author Norman Feske +-- \date 2009-09-23 +-- + +with test_package; + +-- +-- Main program +-- +procedure main is + + result : Integer; + + r : test_package.some_range_t; + + -- + -- Declarations of external C functions + -- + procedure ext_c_add(a, b : Integer; result : out Integer); + pragma import(C, ext_c_add, "add"); + + procedure ext_c_print_int(a : Integer); + pragma import(C, ext_c_print_int, "print_int"); + +begin + ext_c_add(13, 14, result); + ext_c_print_int(result); +end main; diff --git a/base/src/test/ada/startup.cc b/base/src/test/ada/startup.cc new file mode 100644 index 000000000..dba0c1a54 --- /dev/null +++ b/base/src/test/ada/startup.cc @@ -0,0 +1,34 @@ +/* + * \brief Wrapper for the Ada main program + * \author Norman Feske + * \date 2009-09-23 + */ + +/* Genode includes */ +#include + +/** + * Declaration of the Ada main procedure + */ +extern "C" void _ada_main(void); + +/** + * Make the linker happy + */ +extern "C" void __gnat_eh_personality() +{ + PDBG("not implemented"); +} + +/** + * C wrapper for the Ada main program + * + * This function is called by the '_main' startup code. It may be used to + * initialize memory objects at fixed virtual addresses prior calling the Ada + * main program. + */ +extern "C" int main(int argc, char **argv) +{ + _ada_main(); + return 0; +} diff --git a/base/src/test/ada/target.mk b/base/src/test/ada/target.mk new file mode 100644 index 000000000..25e10633f --- /dev/null +++ b/base/src/test/ada/target.mk @@ -0,0 +1,5 @@ +TARGET = test-ada +REQUIRES = gnat +SRC_ADA = main.adb +SRC_CC = add.cc startup.cc +LIBS = env cxx diff --git a/base/src/test/ada/test_package.ads b/base/src/test/ada/test_package.ads new file mode 100644 index 000000000..11a0bad03 --- /dev/null +++ b/base/src/test/ada/test_package.ads @@ -0,0 +1,6 @@ +package test_package +is + + type some_range_t is range 1..99; + +end test_package;