You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
let state =Thread.add_already_checked_condition_to_pc state condition in
29
+
set_state state
35
30
[@@inline]
36
31
37
32
letget_pc()=
38
33
let+ state in
39
-
let pc = state.pc in
40
-
let pc =Symex.Path_condition.slice pc in
34
+
let pc =Symex.Path_condition.to_list state.pc in
41
35
List.fold_left Smtml.Expr.Set.union Smtml.Expr.Set.empty pc
42
36
43
37
letadd_breadcrumbcrumb= modify_state (funt -> Thread.add_breadcrumb t crumb)
@@ -60,16 +54,24 @@ let with_new_symbol ty f =
60
54
let n = state.num_symbols in
61
55
let sym =Fmt.kstr (Smtml.Symbol.make ty) "symbol_%d" n in
62
56
let+()=
63
-
modify_state (funthread ->
64
-
letthread=Thread.add_symbol thread sym in
65
-
Thread.incr_num_symbols thread )
57
+
modify_state (funstate ->
58
+
letstate=Thread.add_symbol state sym in
59
+
Thread.incr_num_symbols state )
66
60
in
67
61
f sym
68
62
69
-
letcheck_reachabilityv=
63
+
letcheck_reachabilitycondition=
70
64
let* state in
71
65
let solver = solver ()in
72
-
let pc = state.pc |>Symex.Path_condition.slice_on_condition v in
66
+
let pc =Symex.Path_condition.slice_on_new_condition condition state.pc in
67
+
(* the condition must be simplified only *after* slicing when we don't know if it is SAT, otherwise, we may exclude some slices and go to an unsat path! *)
68
+
let condition =
69
+
let equalities =Symex.Path_condition.get_known_equalities state.pc in
70
+
Smtml.Expr.inline_symbol_values equalities
71
+
(Smtml.Typed.Unsafe.unwrap condition)
72
+
|>Smtml.Typed.Unsafe.wrap |>Smtml.Typed.simplify
73
+
in
74
+
let pc =Smtml.Expr.Set.add (Smtml.Typed.Unsafe.unwrap condition) pc in
@@ -111,24 +113,25 @@ let select_inner ~with_breadcrumbs (cond : Symbolic_boolean.t)
111
113
|_ ->
112
114
let is_other_branch_unsat =Atomic.make falsein
113
115
letbranchconditionfinal_valuepriority=
114
-
let*()= add_pc condition in
115
116
let*()=
116
117
if with_breadcrumbs then add_breadcrumb (if final_value then1else0)
117
118
else return ()
118
119
in
120
+
let*()= yield priority in
119
121
(* this is an optimisation under the assumption that the PC is always SAT (i.e. we are performing eager pruning), in such a case, when a branch is unsat, we don't have to check the reachability of the other's branch negation, because it is always going to be SAT. *)
120
122
ifAtomic.get is_other_branch_unsat thenbegin
123
+
let*()= add_already_checked_condition_to_pc condition in
121
124
Log.debug (funm ->
122
125
m "The SMT call for the %b branch was optimized away" final_value );
123
126
(* the other branch is unsat, we must be SAT and don't need to check reachability! *)
124
127
return final_value
125
128
end
126
129
elsebegin
127
130
(* the other branch is SAT (or we haven't computed it yet), so we have to check reachability *)
128
-
let*()= yield priority in
129
131
let* satisfiability = check_reachability condition in
130
132
beginmatch satisfiability with
131
133
|`Sat ->
134
+
let*()= add_already_checked_condition_to_pc condition in
132
135
let*()= modify_state (Thread.set_priority priority) in
133
136
return final_value
134
137
|`Unsat ->
@@ -137,7 +140,7 @@ let select_inner ~with_breadcrumbs (cond : Symbolic_boolean.t)
137
140
|`Unknown ->
138
141
(* It can happen when the solver is interrupted *)
139
142
(* TODO: once https://github.com/formalsec/smtml/pull/479 is merged
140
-
if solver was interrupted then prune () else assert false *)
143
+
if solver was interrupted then prune () else assert false *)
let sym =Smtml.Symbol.make Smtml.Typed.Types.(to_ty bitv32) name in
200
+
let assign =Smtml.Typed.Bitv32.(eq (symbol sym) e) in
201
+
(Some assign, sym)
202
+
in
198
203
let*()=
199
-
match assign withSomeassign -> add_pc assign |None -> return ()
204
+
match assign with
205
+
|Someassign ->
206
+
(* it must be SAT because we only introduced a constraint: new_symbol = e *)
207
+
add_already_checked_condition_to_pc assign
208
+
|None -> return ()
200
209
in
201
210
letrec generator()=
202
211
let* possible_value = get_model_or_prune symbol in
@@ -215,16 +224,26 @@ let select_i32 (i : Symbolic_i32.t) : int32 t =
215
224
in
216
225
let this_val_branch =
217
226
let*()= add_breadcrumb (Int32.to_int i) in
218
-
let*()=add_pc this_value_cond in
227
+
let*()=add_already_checked_condition_to_pc this_value_cond in
219
228
return i
220
229
in
221
230
222
-
let not_this_value_cond =Symbolic_boolean.not this_value_cond in
223
231
let not_this_val_branch =
224
-
let*()= add_pc not_this_value_cond in
225
-
generator ()
232
+
let not_this_value_cond =Symbolic_boolean.not this_value_cond in
233
+
(* TODO: this is annoying as the next call to get_model_or_prune is also going to check for satisfiability which is useless! it can probably be simplified.
234
+
I'm leaving it for now to be sure this is correct. It may actually not be required but better safe than sorry! *)
235
+
let* satisfiability = check_reachability not_this_value_cond in
236
+
match satisfiability with
237
+
|`Sat ->
238
+
let*()= add_already_checked_condition_to_pc not_this_value_cond in
239
+
generator ()
240
+
|`Unsat -> prune ()
241
+
|`Unknown ->
242
+
(* It can happen when the solver is interrupted *)
243
+
(* TODO: once https://github.com/formalsec/smtml/pull/479 is merged
244
+
if solver was interrupted then prune () else assert false *)
245
+
prune ()
226
246
in
227
-
let* state in
228
247
Thread.incr_path_count state;
229
248
230
249
(* TODO: better prio here? *)
@@ -289,13 +308,14 @@ let assume condition =
289
308
|ValTrue -> return ()
290
309
|ValFalse -> prune ()
291
310
|_ -> (
292
-
let*()= add_pc condition in
293
311
let* satisfiability = check_reachability condition in
294
312
match satisfiability with
295
-
|`Sat -> return ()
313
+
|`Sat ->
314
+
let*()= add_already_checked_condition_to_pc condition in
315
+
return ()
296
316
|`Unsat -> prune ()
297
317
|`Unknown ->
298
318
(* It can happen when the solver is interrupted *)
299
319
(* TODO: once https://github.com/formalsec/smtml/pull/479 is merged
300
-
if solver was interrupted then prune () else assert false *)
320
+
if solver was interrupted then prune () else assert false *)
0 commit comments