summaryrefslogtreecommitdiff
path: root/test/isabelle
diff options
context:
space:
mode:
authorThomas Bauereiss2018-05-08 18:48:18 +0100
committerThomas Bauereiss2018-05-09 14:40:30 +0100
commit972d349919fc5ebe911604330ea3c80e70fdcfad (patch)
tree4307d3580852321185337e41ebe77307f746e6e2 /test/isabelle
parentb6b46102fc49eae53c27d5d6540d41981c75da0c (diff)
Add tests for Isabelle->OCaml generation for CHERI and AArch64
Diffstat (limited to 'test/isabelle')
-rw-r--r--test/isabelle/Aarch64_code.thy61
-rw-r--r--test/isabelle/Cheri_code.thy62
-rw-r--r--test/isabelle/Makefile27
-rw-r--r--test/isabelle/ROOT9
-rw-r--r--test/isabelle/elf_loader.ml139
-rw-r--r--test/isabelle/run_aarch64.ml93
-rw-r--r--test/isabelle/run_cheri.ml92
-rwxr-xr-xtest/isabelle/run_tests.sh90
8 files changed, 573 insertions, 0 deletions
diff --git a/test/isabelle/Aarch64_code.thy b/test/isabelle/Aarch64_code.thy
new file mode 100644
index 00000000..05e5bb2e
--- /dev/null
+++ b/test/isabelle/Aarch64_code.thy
@@ -0,0 +1,61 @@
+theory Aarch64_code
+ imports
+ Aarch64_lemmas
+ "HOL-Library.Code_Char"
+ "HOL-Library.Code_Target_Nat"
+ "HOL-Library.Code_Target_Int"
+ "HOL-Library.Code_Real_Approx_By_Float"
+begin
+
+declare [[code abort: failwith]]
+
+termination shl_int by lexicographic_order
+termination while sorry
+termination whileM sorry
+termination untilM sorry
+
+declare insert_code[code del]
+declare union_coset_filter[code del]
+
+lemma [code]: "(set xs) \<union> (set ys) = set (xs @ ys)"
+ by auto
+
+lemma [code]: "insert x (set xs) = set (x # xs)"
+ by auto
+
+declare [[code drop:
+ "less :: real \<Rightarrow> real \<Rightarrow> bool"
+ "less_eq :: real \<Rightarrow> real \<Rightarrow> bool"
+ "floor :: real \<Rightarrow> int"]]
+
+code_printing constant "floor :: real \<Rightarrow> int" \<rightharpoonup> (OCaml) "(Int'_of'_integer (Big'_int.big'_int'_of'_int (Pervasives.int'_of'_float (Pervasives.floor _))))"
+
+code_identifier constant ASR \<rightharpoonup> (OCaml) "Aarch64.asr0"
+code_identifier constant LSL \<rightharpoonup> (OCaml) "Aarch64.lsl0"
+code_identifier constant LSR \<rightharpoonup> (OCaml) "Aarch64.lsr0"
+
+fun prerr_endline' :: "String.literal \<Rightarrow> unit" where "prerr_endline' _ = ()"
+lemma [code]: "prerr_endline s = prerr_endline' (String.implode s)" by auto
+
+fun putchar' :: "char \<Rightarrow> unit" where "putchar' _ = ()"
+lemma [code]: "putchar c = putchar' (char_of_nat (nat c))" by auto
+
+code_identifier code_module List \<rightharpoonup> (OCaml) "List0"
+code_printing constant String.implode \<rightharpoonup> (OCaml) "!(let l = _ in let res = Bytes.create (List.length l) in let rec imp i = function | [] -> res | c :: l -> Bytes.set res i c; imp (i + 1) l in imp 0 l)"
+
+code_printing constant prerr_endline' \<rightharpoonup> (OCaml) "Pervasives.prerr'_endline"
+code_printing constant putchar' \<rightharpoonup> (OCaml) "Pervasives.print'_char"
+
+fun write_char_mem :: "int \<Rightarrow> char \<Rightarrow> (regstate, unit, exception) monadS" where
+ "write_char_mem addr c =
+ bindS (write_mem_eaS BC_bitU_list Write_plain (bits_of_int 64 addr) 1) (\<lambda>_.
+ bindS (write_mem_valS BC_bitU_list (bits_of_nat 8 (nat_of_char c))) (\<lambda>_.
+ returnS ()))"
+
+definition "initial_state \<equiv> init_state initial_regstate (\<lambda>seed. (False, seed)) 0"
+
+code_printing constant elf_entry \<rightharpoonup> (OCaml) "(Int'_of'_integer (Elf'_loader.elf'_entry _))"
+termination BigEndianReverse sorry
+export_code main initial_state liftState get_regval set_regval bindS returnS iteriS iterS write_char_mem integer_of_int int_of_integer "op + :: int \<Rightarrow> int \<Rightarrow> int" prerr_results in OCaml module_name "Aarch64" file "aarch64_export.ml"
+
+end
diff --git a/test/isabelle/Cheri_code.thy b/test/isabelle/Cheri_code.thy
new file mode 100644
index 00000000..cfd01413
--- /dev/null
+++ b/test/isabelle/Cheri_code.thy
@@ -0,0 +1,62 @@
+theory Cheri_code
+ imports Cheri_lemmas "HOL-Library.Code_Char" "HOL-Library.Code_Target_Nat" "HOL-Library.Code_Target_Int"
+begin
+
+declare [[code abort: failwith]]
+
+code_datatype
+ DADDIU DADDU DADDI DADD ADD ADDI ADDU ADDIU DSUBU DSUB SUB SUBU AND0 ANDI OR0
+ ORI NOR XOR0 XORI LUI DSLL DSLL32 DSLLV DSRA DSRA32 DSRAV DSRL DSRL32 DSRLV SLL
+ SLLV SRA SRAV SRL SRLV SLT SLTI SLTU SLTIU MOVN MOVZ MFHI MFLO MTHI MTLO MUL
+ MULT MULTU DMULT DMULTU MADD MADDU MSUB MSUBU DIV DIVU DDIV DDIVU J JAL JR JALR
+ BEQ BCMPZ SYSCALL_THREAD_START ImplementationDefinedStopFetching SYSCALL BREAK
+ WAIT TRAPREG TRAPIMM Load Store LWL LWR SWL SWR LDL LDR SDL SDR CACHE PREF SYNC
+ MFC0 HCF MTC0 TLBWI TLBWR TLBR TLBP RDHWR ERET CGetPerm CGetType CGetBase
+ CGetLen CGetTag CGetSealed CGetOffset CGetPCC CGetPCCSetOffset CGetCause
+ CSetCause CReadHwr CWriteHwr CAndPerm CToPtr CSub CPtrCmp CIncOffset
+ CIncOffsetImmediate CSetOffset CSetBounds CSetBoundsImmediate CSetBoundsExact
+ CClearTag CMOVX ClearRegs CFromPtr CBuildCap CCopyType CCheckPerm CCheckType
+ CTestSubset CSeal CCSeal CUnseal CCall CReturn CBX CBZ CJALR CLoad CStore CSC
+ CLC C2Dump RI CGetAddr
+
+termination whileM sorry
+
+fun prerr_endline' :: "String.literal \<Rightarrow> unit" where "prerr_endline' _ = ()"
+lemma [code]: "prerr_endline s = prerr_endline' (String.implode s)" by auto
+
+fun putchar' :: "char \<Rightarrow> unit" where "putchar' _ = ()"
+lemma [code]: "putchar c = putchar' (char_of_nat (nat c))" by auto
+
+code_identifier code_module List \<rightharpoonup> (OCaml) "List0"
+code_printing constant String.implode \<rightharpoonup> (OCaml) "!(let l = _ in let res = Bytes.create (List.length l) in let rec imp i = function | [] -> res | c :: l -> Bytes.set res i c; imp (i + 1) l in imp 0 l)"
+
+code_printing constant prerr_endline' \<rightharpoonup> (OCaml) "Pervasives.prerr'_endline"
+code_printing constant putchar' \<rightharpoonup> (OCaml) "Pervasives.print'_char"
+
+declare insert_code[code del]
+declare union_coset_filter[code del]
+
+lemma set_union_append[code]: "(set xs) \<union> (set ys) = set (xs @ ys)"
+ by auto
+
+lemma set_insert_Cons[code]: "insert x (set xs) = set (x # xs)"
+ by auto
+
+declare ast.case[code]
+
+fun write_char_mem :: "int \<Rightarrow> char \<Rightarrow> (regstate, unit, exception) monadS" where
+ "write_char_mem addr c =
+ bindS (write_mem_eaS BC_bitU_list Write_plain (bits_of_int 64 addr) 1) (\<lambda>_.
+ bindS (write_mem_valS BC_bitU_list (bits_of_nat 8 (nat_of_char c))) (\<lambda>_.
+ returnS ()))"
+
+definition "initial_state \<equiv> init_state initial_regstate (\<lambda>seed. (False, seed)) 0"
+
+code_printing constant elf_entry \<rightharpoonup> (OCaml) "(Arith.Int'_of'_integer (Elf'_loader.elf'_entry _))"
+code_printing constant get_time_ns \<rightharpoonup> (OCaml) "(Arith.Int'_of'_integer (Big'_int.big'_int'_of'_int (Pervasives.int'_of'_float (1e9 *. Unix.gettimeofday _))))"
+
+export_code main initial_state liftState get_regval set_regval bindS returnS iteriS iterS
+ write_char_mem integer_of_int int_of_integer "op + :: int \<Rightarrow> int \<Rightarrow> int" prerr_results
+ in OCaml file "cheri_export.ml"
+
+end
diff --git a/test/isabelle/Makefile b/test/isabelle/Makefile
new file mode 100644
index 00000000..43028fed
--- /dev/null
+++ b/test/isabelle/Makefile
@@ -0,0 +1,27 @@
+CHERI_DIR = ../../cheri
+AARCH64_DIR = ../../aarch64
+TGTS = run_cheri.native run_aarch64.native
+SESSION_DIRS = -d $(CHERI_DIR) -d $(AARCH64_DIR) -d .
+
+.PHONY: all clean
+
+all: $(TGTS)
+
+%.native: %.ml elf_loader.ml
+ ocamlbuild -use-ocamlfind -pkg lem -pkg linksem -pkg num -pkg unix $@
+
+run_cheri.native: cheri_export.ml
+run_aarch64.native: aarch64_export.ml
+
+cheri_export.ml: Cheri_code.thy
+ make -C $(CHERI_DIR) Cheri.thy
+ isabelle build -c $(SESSION_DIRS) Sail-CHERI-Code
+
+aarch64_export.ml: Aarch64_code.thy
+ make -C $(AARCH64_DIR) Aarch64.thy
+ isabelle build -c $(SESSION_DIRS) Sail-AArch64-Code
+
+clean:
+ -ocamlbuild -clean
+ -rm -f cheri_export.ml
+ -rm -f aarch64_export.ml
diff --git a/test/isabelle/ROOT b/test/isabelle/ROOT
new file mode 100644
index 00000000..97544a58
--- /dev/null
+++ b/test/isabelle/ROOT
@@ -0,0 +1,9 @@
+session "Sail-CHERI-Code" = "Sail-CHERI" +
+ options [document = false, quick_and_dirty]
+ theories
+ Cheri_code
+
+session "Sail-AArch64-Code" = "Sail-AArch64" +
+ options [document = false, quick_and_dirty]
+ theories
+ Aarch64_code
diff --git a/test/isabelle/elf_loader.ml b/test/isabelle/elf_loader.ml
new file mode 100644
index 00000000..f68e6693
--- /dev/null
+++ b/test/isabelle/elf_loader.ml
@@ -0,0 +1,139 @@
+(**************************************************************************)
+(* Sail *)
+(* *)
+(* Copyright (c) 2013-2017 *)
+(* Kathyrn Gray *)
+(* Shaked Flur *)
+(* Stephen Kell *)
+(* Gabriel Kerneis *)
+(* Robert Norton-Wright *)
+(* Christopher Pulte *)
+(* Peter Sewell *)
+(* Alasdair Armstrong *)
+(* *)
+(* All rights reserved. *)
+(* *)
+(* This software was developed by the University of Cambridge Computer *)
+(* Laboratory as part of the Rigorous Engineering of Mainstream Systems *)
+(* (REMS) project, funded by EPSRC grant EP/K008528/1. *)
+(* *)
+(* Redistribution and use in source and binary forms, with or without *)
+(* modification, are permitted provided that the following conditions *)
+(* are met: *)
+(* 1. Redistributions of source code must retain the above copyright *)
+(* notice, this list of conditions and the following disclaimer. *)
+(* 2. Redistributions in binary form must reproduce the above copyright *)
+(* notice, this list of conditions and the following disclaimer in *)
+(* the documentation and/or other materials provided with the *)
+(* distribution. *)
+(* *)
+(* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' *)
+(* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *)
+(* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *)
+(* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR *)
+(* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *)
+(* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *)
+(* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF *)
+(* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND *)
+(* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, *)
+(* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT *)
+(* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF *)
+(* SUCH DAMAGE. *)
+(**************************************************************************)
+
+(*module Big_int = Nat_big_num*)
+
+let opt_elf_threads = ref 1
+let opt_elf_entry = ref Nat_big_num.zero
+let opt_elf_tohost = ref Nat_big_num.zero
+
+type word8 = int
+
+let escape_char c =
+ if int_of_char c <= 31 then '.'
+ else if int_of_char c >= 127 then '.'
+ else c
+
+let hex_line bs =
+ let hex_char i c =
+ (if i mod 2 == 0 && i <> 0 then " " else "") ^ Printf.sprintf "%02x" (int_of_char c)
+ in
+ String.concat "" (List.mapi hex_char bs) ^ " " ^ String.concat "" (List.map (fun c -> Printf.sprintf "%c" (escape_char c)) bs)
+
+let rec break n = function
+ | [] -> []
+ | (_ :: _ as xs) -> [Lem_list.take n xs] @ break n (Lem_list.drop n xs)
+
+let print_segment seg =
+ let (Byte_sequence.Sequence bs) = seg.Elf_interpreted_segment.elf64_segment_body in
+ prerr_endline "0011 2233 4455 6677 8899 aabb ccdd eeff 0123456789abcdef";
+ List.iter (fun bs -> prerr_endline (hex_line bs)) (break 16 bs)
+
+let read name =
+ let info = Sail_interface.populate_and_obtain_global_symbol_init_info name in
+
+ prerr_endline "Elf read:";
+ let (elf_file, elf_epi, symbol_map) =
+ begin match info with
+ | Error.Fail s -> failwith (Printf.sprintf "populate_and_obtain_global_symbol_init_info: %s" s)
+ | Error.Success ((elf_file: Elf_file.elf_file),
+ (elf_epi: Sail_interface.executable_process_image),
+ (symbol_map: Elf_file.global_symbol_init_info))
+ ->
+ (* XXX disabled because it crashes if entry_point overflows an ocaml int :-(
+ prerr_endline (Sail_interface.string_of_executable_process_image elf_epi);*)
+ (elf_file, elf_epi, symbol_map)
+ end
+ in
+
+ prerr_endline "\nElf segments:";
+ let (segments, e_entry, e_machine) =
+ begin match elf_epi, elf_file with
+ | (Sail_interface.ELF_Class_32 _, _) -> failwith "cannot handle ELF_Class_32"
+ | (_, Elf_file.ELF_File_32 _) -> failwith "cannot handle ELF_File_32"
+ | (Sail_interface.ELF_Class_64 (segments, e_entry, e_machine), Elf_file.ELF_File_64 f1) ->
+ (* remove all the auto generated segments (they contain only 0s) *)
+ let segments =
+ Lem_list.mapMaybe
+ (fun (seg, prov) -> if prov = Elf_file.FromELF then Some seg else None)
+ segments
+ in
+ (segments, e_entry, e_machine)
+ end
+ in
+ (segments, e_entry, symbol_map)
+
+(*let write_sail_lib paddr i byte =
+ Sail_lib.wram (Nat_big_num.add paddr (Nat_big_num.of_int i)) byte*)
+
+let write_file chan paddr i byte =
+ output_string chan (Nat_big_num.to_string (Nat_big_num.add paddr (Nat_big_num.of_int i)) ^ "\n");
+ output_string chan (string_of_int byte ^ "\n")
+
+(*let load_segment ?writer:(writer=write_sail_lib) seg =
+ let open Elf_interpreted_segment in
+ let (Byte_sequence.Sequence bs) = seg.elf64_segment_body in
+ let paddr = seg.elf64_segment_paddr in
+ let base = seg.elf64_segment_base in
+ let offset = seg.elf64_segment_offset in
+ prerr_endline "\nLoading Segment";
+ prerr_endline ("Segment offset: " ^ Nat_big_num.to_string offset);
+ prerr_endline ("Segment base address: " ^ Nat_big_num.to_string base);
+ prerr_endline ("Segment physical address: " ^ Nat_big_num.to_string paddr);
+ print_segment seg;
+ List.iteri (writer paddr) (List.map int_of_char bs)*)
+
+let load_elf name =
+ let segments, e_entry, symbol_map = read name in
+ opt_elf_entry := e_entry;
+ (if List.mem_assoc "tohost" symbol_map then
+ let (_, _, tohost_addr, _, _) = List.assoc "tohost" symbol_map in
+ opt_elf_tohost := tohost_addr);
+ (*List.iter (load_segment ~writer:writer) segments*)
+ segments
+
+(* The sail model can access this by externing a unit -> Big_int.t function
+ as Elf_loader.elf_entry. *)
+let elf_entry () = Big_int.big_int_of_string (Nat_big_num.to_string !opt_elf_entry)
+(* Used by RISCV sail model test harness for exiting test *)
+let elf_tohost () = Big_int.big_int_of_string (Nat_big_num.to_string !opt_elf_tohost)
diff --git a/test/isabelle/run_aarch64.ml b/test/isabelle/run_aarch64.ml
new file mode 100644
index 00000000..67600e81
--- /dev/null
+++ b/test/isabelle/run_aarch64.ml
@@ -0,0 +1,93 @@
+open Aarch64_export;;
+
+
+
+(**************************************************************************)
+(* Sail *)
+(* *)
+(* Copyright (c) 2013-2017 *)
+(* Kathyrn Gray *)
+(* Shaked Flur *)
+(* Stephen Kell *)
+(* Gabriel Kerneis *)
+(* Robert Norton-Wright *)
+(* Christopher Pulte *)
+(* Peter Sewell *)
+(* Alasdair Armstrong *)
+(* Brian Campbell *)
+(* Thomas Bauereiss *)
+(* Anthony Fox *)
+(* Jon French *)
+(* Dominic Mulligan *)
+(* Stephen Kell *)
+(* Mark Wassell *)
+(* *)
+(* All rights reserved. *)
+(* *)
+(* This software was developed by the University of Cambridge Computer *)
+(* Laboratory as part of the Rigorous Engineering of Mainstream Systems *)
+(* (REMS) project, funded by EPSRC grant EP/K008528/1. *)
+(* *)
+(* Redistribution and use in source and binary forms, with or without *)
+(* modification, are permitted provided that the following conditions *)
+(* are met: *)
+(* 1. Redistributions of source code must retain the above copyright *)
+(* notice, this list of conditions and the following disclaimer. *)
+(* 2. Redistributions in binary form must reproduce the above copyright *)
+(* notice, this list of conditions and the following disclaimer in *)
+(* the documentation and/or other materials provided with the *)
+(* distribution. *)
+(* *)
+(* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' *)
+(* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *)
+(* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *)
+(* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR *)
+(* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *)
+(* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *)
+(* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF *)
+(* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND *)
+(* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, *)
+(* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT *)
+(* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF *)
+(* SUCH DAMAGE. *)
+(**************************************************************************)
+
+open Elf_loader;;
+
+let opt_file_arguments = ref ([] : string list)
+
+let options = Arg.align []
+
+let usage_msg = "Sail OCaml RTS options:"
+
+let () =
+ Arg.parse options (fun s -> opt_file_arguments := !opt_file_arguments @ [s]) usage_msg
+
+let (>>) = Aarch64.bindS
+let liftS = Aarch64.liftState (Aarch64.get_regval, Aarch64.set_regval)
+
+let load_elf_segment seg =
+ let open Elf_interpreted_segment in
+ let open Aarch64_export in
+ let (Byte_sequence.Sequence bs) = seg.elf64_segment_body in
+ let paddr = Big_int.big_int_of_string (Nat_big_num.to_string seg.elf64_segment_paddr) in
+ let base = Big_int.big_int_of_string (Nat_big_num.to_string seg.elf64_segment_base) in
+ let offset = Big_int.big_int_of_string (Nat_big_num.to_string seg.elf64_segment_offset) in
+ let writer i byte = Aarch64.write_char_mem (Aarch64.plus_int (Aarch64.Int_of_integer paddr) i) byte in
+ prerr_endline "\nLoading Segment";
+ prerr_endline ("Segment offset: " ^ Big_int.string_of_big_int offset);
+ prerr_endline ("Segment base address: " ^ Big_int.string_of_big_int base);
+ prerr_endline ("Segment physical address: " ^ Big_int.string_of_big_int paddr);
+ print_segment seg;
+ Aarch64.iteriS writer bs
+
+let _ =
+ Random.self_init ();
+ let elf_segments = match !opt_file_arguments with
+ | f :: _ -> load_elf f
+ | _ -> []
+ in
+ Aarch64.prerr_results
+ (Aarch64.initial_state |>
+ (Aarch64.iterS load_elf_segment elf_segments >> (fun _ ->
+ liftS (Aarch64.main ()))));
diff --git a/test/isabelle/run_cheri.ml b/test/isabelle/run_cheri.ml
new file mode 100644
index 00000000..1f9fbc0e
--- /dev/null
+++ b/test/isabelle/run_cheri.ml
@@ -0,0 +1,92 @@
+open Cheri_export;;
+
+
+
+(**************************************************************************)
+(* Sail *)
+(* *)
+(* Copyright (c) 2013-2017 *)
+(* Kathyrn Gray *)
+(* Shaked Flur *)
+(* Stephen Kell *)
+(* Gabriel Kerneis *)
+(* Robert Norton-Wright *)
+(* Christopher Pulte *)
+(* Peter Sewell *)
+(* Alasdair Armstrong *)
+(* Brian Campbell *)
+(* Thomas Bauereiss *)
+(* Anthony Fox *)
+(* Jon French *)
+(* Dominic Mulligan *)
+(* Stephen Kell *)
+(* Mark Wassell *)
+(* *)
+(* All rights reserved. *)
+(* *)
+(* This software was developed by the University of Cambridge Computer *)
+(* Laboratory as part of the Rigorous Engineering of Mainstream Systems *)
+(* (REMS) project, funded by EPSRC grant EP/K008528/1. *)
+(* *)
+(* Redistribution and use in source and binary forms, with or without *)
+(* modification, are permitted provided that the following conditions *)
+(* are met: *)
+(* 1. Redistributions of source code must retain the above copyright *)
+(* notice, this list of conditions and the following disclaimer. *)
+(* 2. Redistributions in binary form must reproduce the above copyright *)
+(* notice, this list of conditions and the following disclaimer in *)
+(* the documentation and/or other materials provided with the *)
+(* distribution. *)
+(* *)
+(* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' *)
+(* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *)
+(* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *)
+(* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR *)
+(* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *)
+(* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *)
+(* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF *)
+(* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND *)
+(* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, *)
+(* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT *)
+(* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF *)
+(* SUCH DAMAGE. *)
+(**************************************************************************)
+
+open Elf_loader;;
+
+let opt_file_arguments = ref ([] : string list)
+
+let options = Arg.align []
+
+let usage_msg = "Sail OCaml RTS options:"
+
+let () =
+ Arg.parse options (fun s -> opt_file_arguments := !opt_file_arguments @ [s]) usage_msg
+
+let (>>) = State_monad.bindS
+let liftS = State.liftState (Cheri_types.get_regval, Cheri_types.set_regval)
+
+let load_elf_segment seg =
+ let open Elf_interpreted_segment in
+ let (Byte_sequence.Sequence bs) = seg.elf64_segment_body in
+ let paddr = Big_int.big_int_of_string (Nat_big_num.to_string seg.elf64_segment_paddr) in
+ let base = Big_int.big_int_of_string (Nat_big_num.to_string seg.elf64_segment_base) in
+ let offset = Big_int.big_int_of_string (Nat_big_num.to_string seg.elf64_segment_offset) in
+ let writer i byte = Cheri_code.write_char_mem (Arith.plus_int (Arith.Int_of_integer paddr) i) byte in
+ prerr_endline "\nLoading Segment";
+ prerr_endline ("Segment offset: " ^ Big_int.string_of_big_int offset);
+ prerr_endline ("Segment base address: " ^ Big_int.string_of_big_int base);
+ prerr_endline ("Segment physical address: " ^ Big_int.string_of_big_int paddr);
+ print_segment seg;
+ State.iteriS writer bs
+
+let _ =
+ Random.self_init ();
+ let elf_segments = match !opt_file_arguments with
+ | f :: _ -> load_elf f
+ | _ -> []
+ in
+ State_monad.prerr_results
+ (Cheri_code.initial_state |>
+ (State.iterS load_elf_segment elf_segments >> (fun _ ->
+ liftS (Cheri.main ()))));
diff --git a/test/isabelle/run_tests.sh b/test/isabelle/run_tests.sh
new file mode 100755
index 00000000..7b3f7bc1
--- /dev/null
+++ b/test/isabelle/run_tests.sh
@@ -0,0 +1,90 @@
+#!/usr/bin/env bash
+set -e
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+cd $DIR
+SAILDIR="$DIR/../.."
+AARCH64_TEST_DIR="$DIR/../arm"
+
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[0;33m'
+NC='\033[0m'
+
+rm -f $DIR/tests.xml
+
+pass=0
+fail=0
+XML=""
+
+function green {
+ (( pass += 1 ))
+ printf "$1: ${GREEN}$2${NC}\n"
+ XML+=" <testcase name=\"$1\"/>\n"
+}
+
+function yellow {
+ (( fail += 1 ))
+ printf "$1: ${YELLOW}$2${NC}\n"
+ XML+=" <testcase name=\"$1\">\n <error message=\"$2\">$2</error>\n </testcase>\n"
+}
+
+function red {
+ (( fail += 1 ))
+ printf "$1: ${RED}$2${NC}\n"
+ XML+=" <testcase name=\"$1\">\n <error message=\"$2\">$2</error>\n </testcase>\n"
+}
+
+function finish_suite {
+ printf "$1: Passed ${pass} out of $(( pass + fail ))\n\n"
+ XML=" <testsuite name=\"$1\" tests=\"$(( pass + fail ))\" failures=\"${fail}\" timestamp=\"$(date)\">\n$XML </testsuite>\n"
+ printf "$XML" >> $DIR/tests.xml
+ XML=""
+ pass=0
+ fail=0
+}
+
+SAILLIBDIR="$DIR/../../lib/"
+
+printf "<testsuites>\n" >> $DIR/tests.xml
+
+printf "Compiling AArch64 specification (Sail->Isabelle->OCaml)...\n"
+
+if make "run_aarch64.native" 1> /dev/null 2> /dev/null;
+then
+ green "compiled no_vector specification" "ok";
+
+ for i in `ls ${AARCH64_TEST_DIR}/*.elf`;
+ do
+ $DIR/run_aarch64.native $i 2> /dev/null 1> ${i%.elf}.result
+ if diff ${i%.elf}.result ${i%.elf}.expect;
+ then
+ green "ran $(basename $i)" "ok"
+ else
+ red "failed $(basename $i)" "fail"
+ fi;
+ rm -f ${i%.elf}.result
+ done;
+else
+ red "compiling no_vector specification" "fail";
+
+ for i in `ls ${AARCH64_TEST_DIR}/*.elf`;
+ do
+ red "failed $(basename $i)" "fail"
+ done
+fi
+
+printf "Compiling CHERI specification (Sail->Isabelle->OCaml)...\n"
+
+if make "run_cheri.native" 1> /dev/null 2> /dev/null;
+then
+ green "compiled CHERI-256 specification" "ok";
+else
+ red "compiling CHERI-256 specification" "fail";
+fi
+
+make clean 1> /dev/null 2> /dev/null
+
+finish_suite "Isabelle code generation tests"
+
+printf "</testsuites>\n" >> $DIR/tests.xml