diff options
| author | Gabriel Kerneis | 2014-02-28 12:09:44 +0000 |
|---|---|---|
| committer | Gabriel Kerneis | 2014-02-28 12:20:18 +0000 |
| commit | 4baec1546cd0f1ddf43eba93e4daa4634ce1d9df (patch) | |
| tree | 2140debc0341b33e2c197a5f8c47211254083432 /src | |
| parent | 98231d112693ef6815e79a6aba3ba0a5b7f027a7 (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/Makefile | 2 | ||||
| -rw-r--r-- | src/_tags | 2 | ||||
| -rw-r--r-- | src/lem_interp/run_interp.ml | 8 | ||||
| -rw-r--r-- | src/test/run_power.ml | 81 |
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 @@ -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") ;; |
