@@ -39,6 +39,18 @@ let pp_encoding ppf {coding} =
39
39
let order_encoding = KB.Domain. order Theory.Language. domain
40
40
41
41
module Machine : sig
42
+
43
+ (*
44
+ - Dest {dst; parent} - [dst] is either a destination of
45
+ a [Jump t], when parent is [Some (Jump t)], or an initial
46
+ root (function start), when parent is [None].
47
+
48
+ - Fall {dst; parent} - is a fallthrough task either from
49
+ [parent];
50
+
51
+ - Jump {src; dsts} - is a jump from src to the set of dests,
52
+ potentially delayed and waiting until its age is 0.
53
+ *)
42
54
type task = private
43
55
| Dest of {dst : addr ; parent : task option ; encoding : encoding }
44
56
| Fall of {dst : addr ; parent : task ; delay : slot ; encoding : encoding }
@@ -148,44 +160,39 @@ end = struct
148
160
149
161
let sexp_of_task t = Sexp. Atom (Format. asprintf " %a" pp_task t)
150
162
151
- let rec cancel task s =
152
- match task with
163
+
164
+ (* * [revert t s] reverts the chain that produced the task [t].*)
165
+ let rec revert task s = match task with
153
166
| Dest {parent =None } -> s
154
167
| Dest {parent =Some parent } | Fall {parent} | Jump {parent} ->
155
168
match parent with
156
- | Dest _ | Fall _ -> cancel_parent parent s
157
- | Jump {dsts} -> match task with
169
+ | Fall _ | Dest _ -> cancel parent s
170
+ | Jump _ -> match task with
158
171
| Fall {delay =(Ready (Some _ ) | Delay )} ->
159
- cancel_parent parent s
160
- | Fall _ when has_valid s dsts -> s
161
- | Fall _ | Dest _ -> cancel_parent parent s
162
- | Jump _ -> assert false
163
- and cancel_parent task s =
164
- cancel task (cancel_task task s)
165
- and cancel_task task s =
166
- match task with
167
- | Dest {dst} | Fall {dst} -> mark_data s dst
172
+ cancel parent s
173
+ | _ -> s
174
+
175
+ (* * [cancel t s] marks the address of [t] as data and reverts [t] *)
176
+ and cancel task s = revert task @@ match task with
177
+ | Dest {dst} | Fall {dst} -> delete s dst
168
178
| Jump {dsts} when has_valid s dsts -> s
169
- | Jump {src} -> mark_data s src
170
- and cancel_beg s addr = match Map. find s.begs addr with
179
+ | Jump {src} -> delete s src
180
+
181
+ and revert_incoming s addr = match Map. find s.begs addr with
171
182
| None -> s
172
183
| Some tasks ->
173
- List. fold_right tasks ~f: cancel ~init: {
184
+ List. fold_right tasks ~f: revert ~init: {
174
185
s with begs = Map. remove s.begs addr;
175
186
}
176
- and mark_data s addr =
177
- cancel_beg {
178
- s with
179
- data = Set. add s.data addr;
180
- begs = Map. remove s.begs addr;
181
- usat = Set. remove s.usat addr;
182
- code = Map. remove s.code addr;
183
- jmps = Map. filter_map (Map. remove s.jmps addr) ~f: (fun dsts ->
184
- let resolved = Set. remove dsts.resolved addr in
185
- if Set. is_empty resolved && not dsts.indirect
186
- then None
187
- else Some {dsts with resolved});
188
- } addr
187
+
188
+ and delete s addr = {
189
+ (revert_incoming s addr) with
190
+ data = Set. add s.data addr;
191
+ begs = Map. remove s.begs addr;
192
+ usat = Set. remove s.usat addr;
193
+ code = Map. remove s.code addr;
194
+ jmps = Map. remove s.jmps addr;
195
+ }
189
196
190
197
let is_slot s addr = Set. mem s.dels addr
191
198
@@ -197,10 +204,10 @@ end = struct
197
204
| [] -> restart s
198
205
| Dest {dst= next; encoding} as curr :: work
199
206
when wrong_encoding s next encoding ->
200
- step @@ cancel curr {s with work}
207
+ step @@ revert curr {s with work}
201
208
| Dest {dst= next} as curr :: work
202
209
when is_data s next || is_slot s next ->
203
- step @@ cancel curr {s with work}
210
+ step @@ revert curr {s with work}
204
211
| Dest {dst =next } as curr :: work ->
205
212
let s = {s with begs = Map. add_multi s.begs next curr} in
206
213
if is_visited s next
@@ -210,20 +217,20 @@ end = struct
210
217
if is_code s next
211
218
then
212
219
if is_slot s next
213
- then step @@ cancel curr {s with work}
220
+ then step @@ revert curr {s with work}
214
221
else if wrong_encoding s next encoding
215
- then step @@ cancel curr {s with work}
222
+ then step @@ revert curr {s with work}
216
223
else step {s with begs = Map. add_multi s.begs next curr; work}
217
- else if is_data s next then step @@ cancel curr {s with work}
224
+ else if is_data s next then step @@ revert curr {s with work}
218
225
else {s with work; addr= next; curr}
219
226
| (Jump {src; dsts} as jump) :: ([] as work)
220
227
| (Jump {src; dsts; age =0 } as jump ) :: work ->
221
228
if Set. mem s.data src
222
- then step @@ cancel jump {s with work}
229
+ then step @@ revert jump {s with work}
223
230
else
224
231
let resolved = Set. diff dsts.resolved s.data in
225
232
if Set. is_empty resolved && not dsts.indirect
226
- then step@@ cancel jump {s with work}
233
+ then step@@ revert jump {s with work}
227
234
else
228
235
let dsts = {dsts with resolved} in
229
236
let init = {s with jmps = Map. add_exn s.jmps src dsts; work} in
@@ -234,7 +241,7 @@ end = struct
234
241
dst= next; parent = Some jump; encoding = dsts.encoding;
235
242
} :: s.work})
236
243
| Jump jmp as self :: Fall ({dst =next } as slot ) :: work ->
237
- let s = cancel_beg s next in
244
+ let s = revert_incoming s next in
238
245
let delay = if jmp.age = 1 then Ready (Some self) else Delay in
239
246
let jump = Jump {
240
247
jmp with age = jmp.age-1 ; src = next;
@@ -267,11 +274,11 @@ end = struct
267
274
let parent = s.curr in
268
275
let src = Memory. min_addr mem in
269
276
let jump = Jump {src; age= delay; dsts; parent; encoding} in
270
- let next = Addr. succ (Memory. max_addr mem) in
277
+ let dst = Addr. succ (Memory. max_addr mem) in
271
278
let next =
272
279
if dsts.barrier && delay = 0
273
- then Dest {dst= next ; parent= None ; encoding= unknown}
274
- else Fall {dst= next ; parent= jump; delay = Ready None ; encoding} in
280
+ then Dest {dst; parent= None ; encoding= unknown}
281
+ else Fall {dst; parent= jump; delay = Ready None ; encoding} in
275
282
step {s with work = jump :: next :: s .work }
276
283
277
284
let insert_delayed t = function
@@ -300,14 +307,14 @@ end = struct
300
307
| _ -> next :: s.work in
301
308
step @@ decoded {s with work} mem encoding
302
309
303
- let failed s _encoding addr =
304
- step @@ cancel s.curr @@ mark_data s addr
310
+ let failed s _ _ = step @@ cancel s.curr s
305
311
306
312
let skipped s addr =
307
313
step {s with usat = Set. remove s.usat addr }
308
314
309
- let stopped s _encoding =
310
- step @@ cancel s.curr @@ mark_data s s.addr
315
+
316
+ let stopped s _ =
317
+ step @@ cancel s.curr s
311
318
312
319
let with_encoding encoding = function
313
320
| Fall s -> Fall {s with encoding}
@@ -327,7 +334,7 @@ end = struct
327
334
| Ok mem -> ready s (task_encoding s.curr) mem
328
335
| Error _ ->
329
336
let s = match s.curr with
330
- | Fall _ | Jump _ as task -> cancel task s
337
+ | Fall _ | Jump _ as task -> revert task s
331
338
| t -> {s with debt = t :: s .debt} in
332
339
match s.work with
333
340
| [] -> empty (step s)
@@ -502,13 +509,11 @@ let disassemble ~code ~data ~funs debt base : Machine.state KB.t =
502
509
let encoding = Machine. encoding s in
503
510
KB. provide Theory.Label. encoding label encoding.coding >> = fun () ->
504
511
collect_dests encoding label >> = fun dests ->
505
- if Set. is_empty dests.resolved &&
506
- not dests.indirect then
507
- step d @@ Machine. moved s encoding mem
512
+ if Set. is_empty dests.resolved && not dests.indirect
513
+ then step d @@ Machine. moved s encoding mem
508
514
else
509
515
delay label >> = fun delay ->
510
- step d @@ Machine. jumped s encoding mem dests
511
- delay
516
+ step d @@ Machine. jumped s encoding mem dests delay
512
517
end @@ fun problem ->
513
518
warning " rejecting %a due to a conflict %a"
514
519
Memory. pp mem KB.Conflict. pp problem;
@@ -599,6 +604,11 @@ let scan_step ?(code=empty) ?(data=empty) ?(funs=empty) s mem =
599
604
let begs = Set. of_map_keys begs - data in
600
605
let funs = Set. union s.funs funs - data in
601
606
let begs = Set. union s.begs begs - dels in
607
+ let jmps = Map. filter_map jmps ~f: (fun dsts ->
608
+ let resolved = dsts.resolved - data in
609
+ if Set. is_empty resolved && not dsts.indirect
610
+ then None
611
+ else Some {dsts with resolved}) in
602
612
let s = {funs; begs; data; jmps; mems = s.mems; debt} in
603
613
commit_calls s.jmps >> | fun funs ->
604
614
{s with funs = Set. union s.funs funs - dels}
@@ -689,7 +699,9 @@ let explore
689
699
let last = Memory. max_addr mem in
690
700
let next = Addr. succ last in
691
701
let is_terminator =
692
- Set. mem begs next || Map. mem jmps curr in
702
+ Set. mem begs next ||
703
+ Map. mem jmps curr ||
704
+ Set. mem data next in
693
705
if is_terminator
694
706
then KB. return (curr, len, insn::insns)
695
707
else Dis. jump s (view next base)
0 commit comments