From ea8b7d8128bad488cc5362c38fca46b91095c687 Mon Sep 17 00:00:00 2001 From: Johannes Kliemann Date: Mon, 25 Jun 2018 10:45:36 +0200 Subject: [PATCH] Ada: exception support --- repos/libports/include/ada/exception.h | 18 ++++ repos/libports/lib/mk/ada.mk | 6 +- repos/libports/run/ada_exception.run | 33 +++++++ .../libports/src/lib/ada/runtime/a-except.adb | 70 +++++++++++++++ .../libports/src/lib/ada/runtime/a-except.ads | 60 +++++++++++++ .../libports/src/lib/ada/runtime/s-secsta.ads | 3 + .../src/lib/ada/runtimelib/a-except.h | 7 -- .../src/lib/ada/runtimelib/a-except_c.cc | 89 ++++++++++++++++++- .../src/lib/ada/runtimelib/a-exctab_c.cc | 11 +++ .../src/lib/ada/runtimelib/gnat_except.cc | 21 ----- .../src/lib/ada/runtimelib/s-soflin.h | 9 -- .../src/lib/ada/runtimelib/s-soflin_c.cc | 10 +++ .../src/test/ada_exception/except.adb | 9 ++ .../src/test/ada_exception/except.ads | 5 ++ repos/libports/src/test/ada_exception/main.cc | 14 +++ .../libports/src/test/ada_exception/target.mk | 5 ++ 16 files changed, 326 insertions(+), 44 deletions(-) create mode 100644 repos/libports/include/ada/exception.h create mode 100644 repos/libports/run/ada_exception.run create mode 100644 repos/libports/src/lib/ada/runtime/a-except.adb create mode 100644 repos/libports/src/lib/ada/runtime/a-except.ads delete mode 100644 repos/libports/src/lib/ada/runtimelib/a-except.h create mode 100644 repos/libports/src/lib/ada/runtimelib/a-exctab_c.cc delete mode 100644 repos/libports/src/lib/ada/runtimelib/gnat_except.cc delete mode 100644 repos/libports/src/lib/ada/runtimelib/s-soflin.h create mode 100644 repos/libports/src/test/ada_exception/except.adb create mode 100644 repos/libports/src/test/ada_exception/except.ads create mode 100644 repos/libports/src/test/ada_exception/main.cc create mode 100644 repos/libports/src/test/ada_exception/target.mk diff --git a/repos/libports/include/ada/exception.h b/repos/libports/include/ada/exception.h new file mode 100644 index 0000000000..8d0b9ecf45 --- /dev/null +++ b/repos/libports/include/ada/exception.h @@ -0,0 +1,18 @@ + +#include + +namespace Ada { + namespace Exception { + class Program_Error : Genode::Exception {}; + class Constraint_Error : Genode::Exception {}; + class Storage_Error : Genode::Exception {}; + + class Length_Check : Constraint_Error {}; + class Overflow_Check : Constraint_Error {}; + class Invalid_Data : Constraint_Error {}; + class Range_Check : Constraint_Error {}; + class Index_Check : Constraint_Error {}; + class Discriminant_Check : Constraint_Error {}; + class Divide_By_Zero : Constraint_Error {}; + }; +}; diff --git a/repos/libports/lib/mk/ada.mk b/repos/libports/lib/mk/ada.mk index b11cf89abb..ee819678ad 100644 --- a/repos/libports/lib/mk/ada.mk +++ b/repos/libports/lib/mk/ada.mk @@ -3,7 +3,7 @@ include $(REP_DIR)/lib/import/import-ada.mk ADALIB = $(ADA_RTS)/adalib ADAINCLUDE = $(ADA_RTS)/adainclude -PACKAGES = system s-stoele s-secsta +PACKAGES = system s-stoele s-secsta a-except s-conca2 body_exists := $(filter $1.adb,$(shell if [ -e $2/$1.adb ]; then echo $1.adb; fi)) @@ -18,10 +18,10 @@ CUSTOM_ADA_OPT = $(CC_ADA_OPT) CUSTOM_ADA_INCLUDE = -I- -I$(REP_DIR)/src/lib/ada/runtime -I$(ADA_RTS_SOURCE) -I$(REP_DIR)/src/lib/ada/runtimelib # pure C runtime implementations -SRC_CC += a-except_c.cc s-soflin_c.cc +SRC_CC += a-except_c.cc s-soflin_c.cc a-exctab_c.cc # C runtime glue code -SRC_CC += s-secsta_c.cc gnat_except.cc +SRC_CC += s-secsta_c.cc # Ada packages that implement runtime functionality SRC_ADB += ss_utils.adb diff --git a/repos/libports/run/ada_exception.run b/repos/libports/run/ada_exception.run new file mode 100644 index 0000000000..837e8ddd3f --- /dev/null +++ b/repos/libports/run/ada_exception.run @@ -0,0 +1,33 @@ +build "core init test/ada_exception" + +create_boot_directory + +install_config { + + + + + + + + + + + + + + + +} + +build_boot_image "core ld.lib.so ada.lib.so init test-ada_exception" + +append qemu_args "-nographic " + +run_genode_until {child "test-ada_secondary_stack" exited with exit value 0.*} 20 + +grep_output {successful} + +compare_output_to { + [init -> test-ada_secondary_stack] secondary stack test successful +} diff --git a/repos/libports/src/lib/ada/runtime/a-except.adb b/repos/libports/src/lib/ada/runtime/a-except.adb new file mode 100644 index 0000000000..e60cecf39a --- /dev/null +++ b/repos/libports/src/lib/ada/runtime/a-except.adb @@ -0,0 +1,70 @@ +package body Ada.Exceptions is + + ---------------------------- + -- Raise_Exception_Always -- + ---------------------------- + + procedure Raise_Exception_Always ( + E : Exception_Id; + Message : String := "" + ) + is + procedure Raise_Ada_Exception ( + Name : System.Address; + Msg : System.Address + ) + with + Import, + Convention => C, + External_Name => "raise_ada_exception"; + C_Msg : String := Message & Character'Val (0); + begin + Warn_Not_Implemented ("Raise_Exception_Always"); + Raise_Ada_Exception (E.Full_Name, C_Msg'Address); + end Raise_Exception_Always; + + procedure Raise_Exception ( + E : Exception_Id; + Message : String := "" + ) + is + begin + Raise_Exception_Always (E, Message); + end Raise_Exception; + + procedure Reraise_Occurrence_No_Defer ( + X : Exception_Occurrence + ) + is + pragma Unreferenced (X); + begin + Warn_Not_Implemented ("Reraise_Occurrence_No_Defer"); + end Reraise_Occurrence_No_Defer; + + procedure Save_Occurrence ( + Target : out Exception_Occurrence; + Source : Exception_Occurrence + ) + is + begin + Warn_Not_Implemented ("Save_Occurrence"); + Target := Source; + end Save_Occurrence; + + procedure Warn_Not_Implemented ( + Name : String + ) + is + procedure C_Warn_Unimplemented_Function ( + Func : System.Address + ) + with + Import, + Convention => C, + External_Name => "warn_unimplemented_function"; + C_Name : String := Name & Character'Val (0); + begin + C_Warn_Unimplemented_Function (C_Name'Address); + end Warn_Not_Implemented; + +end Ada.Exceptions; diff --git a/repos/libports/src/lib/ada/runtime/a-except.ads b/repos/libports/src/lib/ada/runtime/a-except.ads new file mode 100644 index 0000000000..1f183d1a88 --- /dev/null +++ b/repos/libports/src/lib/ada/runtime/a-except.ads @@ -0,0 +1,60 @@ +with System; + +package Ada.Exceptions is + + type Exception_Id is private; + type Exception_Occurrence is limited private; + type Exception_Occurrence_Access is access all Exception_Occurrence; + + procedure Raise_Exception_Always ( + E : Exception_Id; + Message : String := "" + ) + with + Export, + Convention => Ada, + External_Name => "__gnat_raise_exception"; + + procedure Raise_Exception ( + E : Exception_Id; + Message : String := "" + ); + + procedure Reraise_Occurrence_No_Defer ( + X : Exception_Occurrence + ); + + procedure Save_Occurrence ( + Target : out Exception_Occurrence; + Source : Exception_Occurrence + ); + +private + + -- the following declarations belong to s-stalib.ads + -- begin s-stalib.ads + type Exception_Data; + type Exception_Data_Ptr is access all Exception_Data; + type Raise_Action is access procedure; + + type Exception_Data is record + Not_Handled_By_Others : Boolean; + Lang : Character; + Name_Length : Natural; + Full_Name : System.Address; + HTable_Ptr : Exception_Data_Ptr; + Foreign_Data : System.Address; + Raise_Hook : Raise_Action; + end record; + -- end s-stalib.ads + + type Exception_Id is new Exception_Data_Ptr; + type Exception_Occurrence is record + null; + end record; + + procedure Warn_Not_Implemented ( + Name : String + ); + +end Ada.Exceptions; diff --git a/repos/libports/src/lib/ada/runtime/s-secsta.ads b/repos/libports/src/lib/ada/runtime/s-secsta.ads index 49e36d2dd1..c073d7ee42 100644 --- a/repos/libports/src/lib/ada/runtime/s-secsta.ads +++ b/repos/libports/src/lib/ada/runtime/s-secsta.ads @@ -21,6 +21,9 @@ package System.Secondary_Stack is private + SS_Pool : Integer; + -- This is not used but needed since the build will fail otherwise + type Mark_Id is record Sstk : System.Address; Sptr : SSE.Integer_Address; diff --git a/repos/libports/src/lib/ada/runtimelib/a-except.h b/repos/libports/src/lib/ada/runtimelib/a-except.h deleted file mode 100644 index 09802235f2..0000000000 --- a/repos/libports/src/lib/ada/runtimelib/a-except.h +++ /dev/null @@ -1,7 +0,0 @@ - -extern "C" { - - void ada__exceptions__reraise_occurrence_no_defer(); - void ada__exceptions__save_occurrence(); - -} diff --git a/repos/libports/src/lib/ada/runtimelib/a-except_c.cc b/repos/libports/src/lib/ada/runtimelib/a-except_c.cc index a7eaf0daee..7f40dda94f 100644 --- a/repos/libports/src/lib/ada/runtimelib/a-except_c.cc +++ b/repos/libports/src/lib/ada/runtimelib/a-except_c.cc @@ -1,16 +1,97 @@ #include +#include +#include extern "C" { - void ada__exceptions__reraise_occurrence_no_defer() + /* Program Error */ + void __gnat_rcheck_PE_Explicit_Raise(char *file, int line) { - Genode::warning(__func__, " not implemented"); + Genode::error("Program Error in ", Genode::Cstring(file), " at line ", line); + throw Ada::Exception::Program_Error(); } - void ada__exceptions__save_occurrence() + /* Constraint Error */ + void __gnat_rcheck_CE_Explicit_Raise(char *file, int line) { - Genode::warning(__func__, " not implemented"); + Genode::error("Constraint Error in ", Genode::Cstring(file), " at line ", line); + throw Ada::Exception::Constraint_Error(); + } + + /* Storage Error */ + void __gnat_rcheck_SE_Explicit_Raise(char *file, int line) + { + Genode::error("Storage Error in ", Genode::Cstring(file), " at line ", line); + throw Ada::Exception::Storage_Error(); + } + + /* Constraint Error subtypes */ + + /* Length check failed */ + void __gnat_rcheck_CE_Length_Check(char *file, int line) + { + Genode::error("Constraint Error: Length check failed in ", + Genode::Cstring(file), " at line ", line); + throw Ada::Exception::Length_Check(); + } + + /* Overflow check failed */ + void __gnat_rcheck_CE_Overflow_Check(char *file, int line) + { + Genode::error("Constraint Error: Overflow check failed in ", + Genode::Cstring(file), " at line ", line); + throw Ada::Exception::Overflow_Check(); + } + + /* Invalid data */ + void __gnat_rcheck_CE_Invalid_Data(char *file, int line) + { + Genode::error("Constraint Error: Invalid data in ", + Genode::Cstring(file), " at line ", line); + throw Ada::Exception::Invalid_Data(); + } + + /* Range check failed */ + void __gnat_rcheck_CE_Range_Check(char *file, int line) + { + Genode::error("Constraint Error: Range check failed in ", + Genode::Cstring(file), " at line ", line); + throw Ada::Exception::Range_Check(); + } + + /* Index check failed */ + void __gnat_rcheck_CE_Index_Check(char *file, int line) + { + Genode::error("Constraint Error: Index check failed in ", + Genode::Cstring(file), " at line ", line); + throw Ada::Exception::Index_Check(); + } + + /* Discriminant check failed */ + void __gnat_rcheck_CE_Discriminant_Check(char *file, int line) + { + Genode::error("Constraint Error: Discriminant check failed in ", + Genode::Cstring(file), " at line ", line); + throw Ada::Exception::Discriminant_Check(); + } + + /* Divide by 0 */ + void __gnat_rcheck_CE_Divide_By_Zero (char *file, int line) + { + Genode::error("Constraint Error: Divide by zero in ", + Genode::Cstring(file), " at line ", line); + throw Ada::Exception::Divide_By_Zero(); + } + + void raise_ada_exception(char *name, char *message) + { + Genode::error(Genode::Cstring(name), " raised: ", Genode::Cstring(message)); + } + + void warn_unimplemented_function(char *func) + { + Genode::warning(Genode::Cstring(func), " unimplemented"); } } diff --git a/repos/libports/src/lib/ada/runtimelib/a-exctab_c.cc b/repos/libports/src/lib/ada/runtimelib/a-exctab_c.cc new file mode 100644 index 0000000000..292caaf1d0 --- /dev/null +++ b/repos/libports/src/lib/ada/runtimelib/a-exctab_c.cc @@ -0,0 +1,11 @@ + +#include + +extern "C" { + + void system__exception_table__register() + { + Genode::warning(__func__, " not implemented"); + } + +} diff --git a/repos/libports/src/lib/ada/runtimelib/gnat_except.cc b/repos/libports/src/lib/ada/runtimelib/gnat_except.cc deleted file mode 100644 index 14a9fac826..0000000000 --- a/repos/libports/src/lib/ada/runtimelib/gnat_except.cc +++ /dev/null @@ -1,21 +0,0 @@ - -#include - -extern "C" { - - void __gnat_rcheck_CE_Explicit_Raise() - { - Genode::warning("Unhandled Ada exception: Constraint_Error"); - } - - void __gnat_rcheck_SE_Explicit_Raise() - { - Genode::warning("Unhandled Ada exception: Storage_Error"); - } - - void __gnat_rcheck_PE_Explicit_Raise() - { - Genode::warning("Unhandled Ada exception: Program_Error"); - } - -} diff --git a/repos/libports/src/lib/ada/runtimelib/s-soflin.h b/repos/libports/src/lib/ada/runtimelib/s-soflin.h deleted file mode 100644 index fec085f916..0000000000 --- a/repos/libports/src/lib/ada/runtimelib/s-soflin.h +++ /dev/null @@ -1,9 +0,0 @@ - -extern "C" { - - void system__soft_links__get_current_excep(); - void system__soft_links__get_gnat_exception(); - void system__soft_links__get_jmpbuf_address_soft(); - void system__soft_links__set_jmpbuf_address_soft(); - -} diff --git a/repos/libports/src/lib/ada/runtimelib/s-soflin_c.cc b/repos/libports/src/lib/ada/runtimelib/s-soflin_c.cc index 998f008345..18ecd34631 100644 --- a/repos/libports/src/lib/ada/runtimelib/s-soflin_c.cc +++ b/repos/libports/src/lib/ada/runtimelib/s-soflin_c.cc @@ -23,4 +23,14 @@ extern "C" { Genode::warning(__func__, " not implemented"); } + void system__soft_links__lock_task() + { + Genode::warning(__func__, " not implemented"); + } + + void system__soft_links__unlock_task() + { + Genode::warning(__func__, " not implemented"); + } + } diff --git a/repos/libports/src/test/ada_exception/except.adb b/repos/libports/src/test/ada_exception/except.adb new file mode 100644 index 0000000000..ecc9a6157b --- /dev/null +++ b/repos/libports/src/test/ada_exception/except.adb @@ -0,0 +1,9 @@ +package body Except is + + procedure Raise_Task + is + begin + raise Program_Error; + end Raise_Task; + +end Except; diff --git a/repos/libports/src/test/ada_exception/except.ads b/repos/libports/src/test/ada_exception/except.ads new file mode 100644 index 0000000000..0234d6ba0d --- /dev/null +++ b/repos/libports/src/test/ada_exception/except.ads @@ -0,0 +1,5 @@ +package Except is + + procedure Raise_Task; + +end Except; diff --git a/repos/libports/src/test/ada_exception/main.cc b/repos/libports/src/test/ada_exception/main.cc new file mode 100644 index 0000000000..10543c1b58 --- /dev/null +++ b/repos/libports/src/test/ada_exception/main.cc @@ -0,0 +1,14 @@ + +#include +#include + +extern "C" void except__raise_task(); + +void Component::construct(Genode::Env &env) +{ + Genode::log("Ada exception test"); + + except__raise_task(); + + env.parent().exit(0); +} diff --git a/repos/libports/src/test/ada_exception/target.mk b/repos/libports/src/test/ada_exception/target.mk new file mode 100644 index 0000000000..34d19273ed --- /dev/null +++ b/repos/libports/src/test/ada_exception/target.mk @@ -0,0 +1,5 @@ +TARGET = test-ada_exception +SRC_ADB = except.adb +SRC_CC = main.cc +LIBS = base ada +INC_DIR += $(PRG_DIR)