summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGabriel Kerneis2014-02-28 12:09:44 +0000
committerGabriel Kerneis2014-02-28 12:20:18 +0000
commit4baec1546cd0f1ddf43eba93e4daa4634ce1d9df (patch)
tree2140debc0341b33e2c197a5f8c47211254083432 /src
parent98231d112693ef6815e79a6aba3ba0a5b7f027a7 (diff)
Load ELF sections to virtual memory addresses
Roughly 110KB/s (~5 seconds to load "hello" test).
Diffstat (limited to 'src')
-rw-r--r--src/Makefile2
-rw-r--r--src/_tags2
-rw-r--r--src/lem_interp/run_interp.ml8
-rw-r--r--src/test/run_power.ml81
4 files changed, 69 insertions, 24 deletions
diff --git a/src/Makefile b/src/Makefile
index 66e83fca..c26f1a06 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -7,7 +7,7 @@ test: all
./run_tests.native
test_power: all
- ./run_power.native ../../../rsem/idl/power/binary/main.bin
+ ../../../rsem/idl/power/binary/run.sh
clean:
-ocamlbuild -clean
diff --git a/src/_tags b/src/_tags
index 68043fb4..0938900a 100644
--- a/src/_tags
+++ b/src/_tags
@@ -3,5 +3,5 @@ true: -traverse, debug
<lem_interp> or <test>: include
# see http://caml.inria.fr/mantis/view.php?id=4943
<lem_interp/*> and not <lem_interp/*.cmxa>: use_nums, use_lem
-<test/*> and not <test/*.cmxa>: use_nums, use_lem
+<test/*> and not <test/*.cmxa>: use_nums, use_lem, use_str
diff --git a/src/lem_interp/run_interp.ml b/src/lem_interp/run_interp.ml
index 66880ade..0ed3edaa 100644
--- a/src/lem_interp/run_interp.ml
+++ b/src/lem_interp/run_interp.ml
@@ -105,11 +105,12 @@ module Mem = struct
include Map.Make(struct
type t = (id * big_int)
let compare (i1, v1) (i2, v2) =
- match id_compare i1 i2 with
- | 0 -> compare_big_int v1 v2
+ (* optimize for common case: different addresses, same id *)
+ match compare_big_int v1 v2 with
+ | 0 -> id_compare i1 i2
| n -> n
end)
- (* debugging memory accesses *)
+ (* debugging memory accesses
let add (n, idx) v m =
eprintf "%s[%s] <- %s\n" (id_to_string n) (string_of_big_int idx) (val_to_string v);
add (n, idx) v m
@@ -117,6 +118,7 @@ module Mem = struct
let v = find (n, idx) m in
eprintf "%s[%s] -> %s\n" (id_to_string n) (string_of_big_int idx) (val_to_string v);
v
+ *)
end ;;
let slice v = function
diff --git a/src/test/run_power.ml b/src/test/run_power.ml
index b06f79e3..28345ae9 100644
--- a/src/test/run_power.ml
+++ b/src/test/run_power.ml
@@ -4,6 +4,25 @@ open Interp_ast ;;
open Interp_lib ;;
open Run_interp ;;
+let startaddr = ref 0 ;;
+let mainaddr = ref 0 ;;
+let sections = ref [] ;;
+let file = ref "" ;;
+
+let add_section s =
+ match Str.split (Str.regexp ",") s with
+ | [name;offset;size;addr] ->
+ begin try
+ sections := (
+ int_of_string offset,
+ int_of_string size,
+ Big_int.big_int_of_int64 (Int64.of_string addr)) ::
+ !sections
+ with Failure msg -> raise (Arg.Bad (msg ^ ": " ^ s))
+ end
+ | _ -> raise (Arg.Bad ("Wrong section format: "^s))
+;;
+
let rec foldli f acc ?(i=0) = function
| [] -> acc
| x::xs -> foldli f (f i acc x) ~i:(i+1) xs
@@ -12,30 +31,54 @@ let rec foldli f acc ?(i=0) = function
(* POWER is big-endian *)
let little_endian = false ;;
-let binary file =
- let ic = open_in_bin file in
- let rec read acc =
- match try Some (input_byte ic) with End_of_file -> None
- with
- | Some b -> read ((V_lit (L_aux (L_num (Big_int.big_int_of_int b), Unknown))) :: acc)
- | None -> close_in ic; acc in
- let bytes = read [] in
- List.rev_map ((if little_endian then to_vec_inc else to_vec_dec) 8) bytes
+let mem = ref Mem.empty ;;
+
+let add_mem byte addr =
+ assert(byte >= 0 && byte < 256);
+ let lit_byte = V_lit (L_aux (L_num (Big_int.big_int_of_int byte), Unknown)) in
+ let vector = (if little_endian then to_vec_inc else to_vec_dec) 8 lit_byte in
+ let key = Id_aux (Id "MEM", Unknown), addr in
+ mem := Mem.add key vector !mem
;;
-let init_mem bytes =
- foldli
- (fun i m b -> Mem.add (Id_aux (Id "MEM", Unknown), Big_int.big_int_of_int i) b m)
- Mem.empty bytes
+let load_section ic (offset,size,addr) =
+ seek_in ic offset;
+ for i = 0 to size - 1 do
+ add_mem (input_byte ic) (Big_int.add_int_big_int i addr);
+ done
+;;
+
+let args = [
+ ("--file", Arg.Set_string file, "filename binary code to load in memory");
+ ("--data", Arg.String add_section, "name,offset,size,addr add a data section");
+ ("--code", Arg.String add_section, "name,offset,size,addr add a code section");
+ ("--startaddr", Arg.Set_int startaddr, "addr initial address");
+ ("--mainaddr", Arg.Set_int mainaddr, "addr address of the main section");
+] ;;
+
+let time_it action arg =
+ let start_time = Sys.time () in
+ ignore (action arg);
+ let finish_time = Sys.time () in
+ finish_time -. start_time
;;
let run () =
- let file = Sys.argv.(1) in
- let bytes = binary file in
- eprintf "bytes read\n";
- let mem = init_mem bytes in
- eprintf "memory initialized\n";
- let r = Run_interp.run ~mem (file, Power.defs) in
+ Arg.parse args (fun _ -> raise (Arg.Bad "anonymous parameter")) "" ;
+ if !file = "" then begin
+ Arg.usage args "";
+ exit 1;
+ end;
+ let ic = open_in_bin !file in
+ if !sections = [] then begin
+ sections := [(0, in_channel_length ic, Big_int.zero_big_int)];
+ end;
+ let total_size = List.fold_left (fun n (_,s,_) -> n+s) 0 !sections in
+ eprintf "Loading binary into memory (%d bytes)... %!" total_size;
+ let t = time_it (List.iter (load_section ic)) !sections in
+ eprintf "done. (%f seconds)\n%!" t;
+ close_in ic;
+ let r = Run_interp.run ~mem:!mem (!file, Power.defs) in
eprintf "%s\n" (if r then "SUCCESS" else "FAILURE")
;;