diff options
| author | Thomas Bauereiss | 2018-05-11 12:04:10 +0100 |
|---|---|---|
| committer | Thomas Bauereiss | 2018-05-11 12:04:10 +0100 |
| commit | ff18bac6654a73cedf32a45ee406fe3e74ae3efd (patch) | |
| tree | ed940ea575c93d741c84cd24cd3e029d0a590b81 /test/isabelle/elf_loader.ml | |
| parent | 823fe1d82e753add2d54ba010689a81af027ba6d (diff) | |
| parent | db3b6d21c18f4ac516c2554db6890274d2b8292c (diff) | |
Merge branch 'sail2' into cheri-mono
In order to use up-to-date sequential CHERI model for test suite
Diffstat (limited to 'test/isabelle/elf_loader.ml')
| -rw-r--r-- | test/isabelle/elf_loader.ml | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/test/isabelle/elf_loader.ml b/test/isabelle/elf_loader.ml new file mode 100644 index 00000000..6ec89ee6 --- /dev/null +++ b/test/isabelle/elf_loader.ml @@ -0,0 +1,126 @@ +(**************************************************************************) +(* 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 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 (Byte_sequence.char_list_of_byte_sequence 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_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) |
