Skip to content

Commit ffdd56a

Browse files
committed
distinguish null_terminated and known-length strings in the API
1 parent a50fe0e commit ffdd56a

4 files changed

Lines changed: 64 additions & 20 deletions

File tree

src/cmd/cmd_replay.ml

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -123,28 +123,40 @@ let compile_file ~unsafe ~entry_point ~invoke_with_symbols filename model =
123123

124124
let in_replay_mode () = Ok 1l
125125

126-
let rec make_str m accu i =
126+
let rec make_str_null_terminated m accu i =
127127
let open Concrete_choice in
128128
let* p = Concrete_memory.load_8_u m i in
129-
if Int32.lt 255l p || Int32.lt p 0l then trap `Invalid_character_in_memory
129+
let ch = char_of_int (Int32.to_int p) in
130+
if Char.equal ch '\x00' then return (List.rev accu |> Array.of_list)
130131
else
131-
let ch = char_of_int (Int32.to_int p) in
132-
if Char.equal ch '\x00' then return (List.rev accu |> Array.of_list)
133-
else make_str m (ch :: accu) (Int32.add i (Int32.of_int 1))
132+
make_str_null_terminated m (ch :: accu) (Int32.add i (Int32.of_int 1))
133+
134+
let rec make_str_of_length m accu i len =
135+
let open Concrete_choice in
136+
if Int32.lt len i then return (List.rev accu |> Array.of_list)
137+
else
138+
let* c = Concrete_memory.load_8_u m i in
139+
let ch = char_of_int (Int32.to_int c) in
140+
make_str_of_length m (ch :: accu) (Int32.add i 1l) len
134141

135142
let cov_label_is_covered id =
136143
let open Concrete_choice in
137144
let+ id = select_i32 id in
138145
if Hashtbl.mem covered_labels id then 1l else 0l
139146

140147
let cov_label_set m id str_ptr =
141-
let+ chars = make_str m [] str_ptr in
148+
let+ chars = make_str_null_terminated m [] str_ptr in
142149
let str = String.init (Array.length chars) (Array.get chars) in
143150
Hashtbl.add covered_labels id str;
144151
Log.debug (fun m -> m "reached %ld@." id)
145152

146-
let open_scope m strptr =
147-
let+ chars = make_str m [] strptr in
153+
let open_scope_null_terminated m strptr =
154+
let+ chars = make_str_null_terminated m [] strptr in
155+
let str = String.init (Array.length chars) (Array.get chars) in
156+
scopes := Symbol_scope.open_scope str !scopes
157+
158+
let open_scope_of_length m strptr length =
159+
let+ chars = make_str_of_length m [] strptr length in
148160
let str = String.init (Array.length chars) (Array.get chars) in
149161
scopes := Symbol_scope.open_scope str !scopes
150162

@@ -171,7 +183,12 @@ let compile_file ~unsafe ~entry_point ~invoke_with_symbols filename model =
171183
, Extern_func (i32 ^->. i32, cov_label_is_covered) )
172184
; ( "cov_label_set"
173185
, Extern_func (memory 0 ^-> i32 ^-> i32 ^->. unit, cov_label_set) )
174-
; ("open_scope", Extern_func (memory 0 ^-> i32 ^->. unit, open_scope))
186+
; ( "open_scope_null_terminated"
187+
, Extern_func (memory 0 ^-> i32 ^->. unit, open_scope_null_terminated)
188+
)
189+
; ( "open_scope_of_length"
190+
, Extern_func (memory 0 ^-> i32 ^-> i32 ^->. unit, open_scope_of_length)
191+
)
175192
; ("close_scope", Extern_func (unit ^->. unit, close_scope))
176193
; ("alloc", Extern_func (memory 0 ^-> i32 ^-> i32 ^->. i32, alloc))
177194
; ("dealloc", Extern_func (memory 0 ^-> i32 ^->. i32, free))

src/intf/wasm_ffi_intf.ml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@ module type S0 = sig
4444

4545
val cov_label_set : memory -> Value.i32 -> Value.i32 -> unit t
4646

47-
val open_scope : memory -> Value.i32 -> unit t
47+
val open_scope_null_terminated : memory -> Value.i32 -> unit t
48+
49+
val open_scope_of_length : memory -> Value.i32 -> Value.i32 -> unit t
4850

4951
val close_scope : unit -> unit t
5052
end

src/lang_c/libowi/include/owi.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ __attribute__((import_module("owi"), import_name("invisible_bool_symbol"))) int
8585

8686
#endif
8787

88-
__attribute__((import_module("owi"), import_name("open_scope"))) void owi_open_scope(const char *name);
88+
__attribute__((import_module("owi"), import_name("open_scope_null_terminated"))) void owi_open_scope(const char *name);
8989
__attribute__((import_module("owi"), import_name("close_scope"))) void owi_close_scope(void);
9090

9191
__attribute__((import_module("owi"), import_name("assume"))) void owi_assume(int);

src/symbolic/symbolic_wasm_ffi.ml

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -103,19 +103,30 @@ module M :
103103
Log.app (fun m -> m "%c@?" (char_of_int (Int32.to_int c)));
104104
return ()
105105

106-
let rec make_str m accu i =
106+
let rec make_str_null_terminated m accu i =
107107
let open Symbolic_choice in
108108
let* p = Symbolic_memory.load_8_u m (Symbolic_i32.of_int32 i) in
109109
match Smtml.Typed.view p with
110110
| Val (Bitv bv) when Smtml.Bitvector.numbits bv = 32 ->
111111
let c = Smtml.Bitvector.to_int32 bv in
112-
if Int32.lt 255l c || Int32.lt c 0l then trap `Invalid_character_in_memory
112+
let ch = char_of_int (Int32.to_int c) in
113+
if Char.equal ch '\x00' then return (List.rev accu |> Array.of_list)
113114
else
114-
let ch = char_of_int (Int32.to_int c) in
115-
if Char.equal ch '\x00' then return (List.rev accu |> Array.of_list)
116-
else make_str m (ch :: accu) (Int32.add i (Int32.of_int 1))
115+
make_str_null_terminated m (ch :: accu) (Int32.add i (Int32.of_int 1))
117116
| _ -> assert false
118117

118+
let rec make_str_of_length m accu i len =
119+
let open Symbolic_choice in
120+
if len < i then return (List.rev accu |> Array.of_list)
121+
else
122+
let* p = Symbolic_memory.load_8_u m (Symbolic_i32.of_int i) in
123+
match Smtml.Typed.view p with
124+
| Val (Bitv bv) when Smtml.Bitvector.numbits bv = 32 ->
125+
let c = Smtml.Bitvector.to_int32 bv in
126+
let ch = char_of_int (Int32.to_int c) in
127+
make_str_of_length m (ch :: accu) (succ i) len
128+
| _ -> assert false
129+
119130
let cov_label_is_covered id =
120131
let open Symbolic_choice in
121132
let* id = select_i32 id in
@@ -136,7 +147,7 @@ module M :
136147
Mutex.protect cov_lock @@ fun () ->
137148
if Hashtbl.mem covered_labels id || in_seacoral_store id then abort ()
138149
else
139-
let* chars = make_str m [] ptr in
150+
let* chars = make_str_null_terminated m [] ptr in
140151
let str = String.init (Array.length chars) (Array.get chars) in
141152
Hashtbl.add covered_labels id str;
142153
add_label (Int32.to_int id, str)
@@ -148,13 +159,23 @@ module M :
148159
(Smtml.Typed.Unsafe.unwrap ptr) );
149160
assert false
150161

151-
let open_scope m ptr =
162+
let open_scope_null_terminated m ptr =
152163
let open Symbolic_choice in
153164
let* ptr = select_i32 ptr in
154-
let* chars = make_str m [] ptr in
165+
let* chars = make_str_null_terminated m [] ptr in
155166
let str = String.init (Array.length chars) (Array.get chars) in
156167
open_scope str
157168

169+
let open_scope_of_length m ptr len =
170+
let open Symbolic_choice in
171+
let* ptr = select_i32 ptr in
172+
let ptr = Int32.to_int ptr in
173+
let* len = select_i32 len in
174+
let len = Int32.to_int len in
175+
let* bytes = make_str_of_length m [] ptr len in
176+
let str = String.init len (Array.get bytes) in
177+
open_scope str
178+
158179
let close_scope = Symbolic_choice.close_scope
159180
end
160181

@@ -181,7 +202,11 @@ let symbolic_extern_module =
181202
; ( "cov_label_set"
182203
, Extern_func (memory 0 ^-> i32 ^-> i32 ^->. unit, cov_label_set) )
183204
; ("cov_label_is_covered", Extern_func (i32 ^->. i32, cov_label_is_covered))
184-
; ("open_scope", Extern_func (memory 0 ^-> i32 ^->. unit, open_scope))
205+
; ( "open_scope_null_terminated"
206+
, Extern_func (memory 0 ^-> i32 ^->. unit, open_scope_null_terminated) )
207+
; ( "open_scope_of_length"
208+
, Extern_func (memory 0 ^-> i32 ^-> i32 ^->. unit, open_scope_of_length)
209+
)
185210
; ("close_scope", Extern_func (unit ^->. unit, close_scope))
186211
; ("alloc", Extern_func (memory 0 ^-> i32 ^-> i32 ^->. i32, alloc))
187212
; ("dealloc", Extern_func (memory 0 ^-> i32 ^->. i32, free))

0 commit comments

Comments
 (0)