Skip to content

Commit fb0414c

Browse files
authored
wraps proposals into with_empty and adds more guards (#1442)
The proposals (promises with options) now can use the choice monad interface as well as other promises. Also adds a few guards to the existing code to make it more readable and improve performance.
1 parent 0f38e2e commit fb0414c

File tree

6 files changed

+61
-57
lines changed

6 files changed

+61
-57
lines changed

lib/knowledge/bap_knowledge.ml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2949,14 +2949,22 @@ module Knowledge = struct
29492949
current slot obj >>= fun opinions ->
29502950
provide slot obj (Opinions.add agent x opinions)
29512951

2952+
let wrap_opinion get obj =
2953+
with_empty ~missing:None @@ fun () ->
2954+
get obj >>| Option.some
2955+
29522956
let propose agent s get =
29532957
ignore @@
29542958
register_promise s @@ fun obj ->
2955-
get obj >>= suggest agent s obj
2959+
wrap_opinion get obj >>= function
2960+
| None -> Knowledge.return ()
2961+
| Some opinions -> suggest agent s obj opinions
29562962

29572963
let proposing agent s ~propose:get scoped =
29582964
let pid = register_promise s @@ fun obj ->
2959-
get obj >>= suggest agent s obj in
2965+
wrap_opinion get obj >>= function
2966+
| None -> Knowledge.return ()
2967+
| Some opinions -> suggest agent s obj opinions in
29602968
scoped () >>= fun r ->
29612969
remove_promise s pid;
29622970
Knowledge.return r

plugins/bil/bil_lifter.ml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,16 @@ let package = "bap"
1515
module Optimizer = Theory.Parser.Make(Theory.Pass.Desugar(Bil_semantics.Core))
1616
[@@inlined]
1717

18-
1918
let provide_bir () =
2019
KB.Rule.(declare ~package "reify-ir" |>
2120
require Theory.Semantics.slot |>
2221
require Bil_ir.slot |>
2322
provide Theory.Semantics.slot |>
2423
comment "reifies IR");
2524
KB.promise Theory.Semantics.slot @@ fun obj ->
26-
KB.collect Theory.Semantics.slot obj >>| fun sema ->
25+
KB.collect Theory.Semantics.slot obj >>= fun sema ->
26+
KB.proceed ~unless:(KB.Value.has Term.slot sema) >>= fun () ->
27+
KB.return @@
2728
match Bil_ir.reify @@ KB.Value.get Bil_ir.slot sema with
2829
| [] -> Insn.empty
2930
| bir -> KB.Value.put Term.slot sema bir

plugins/mips/mips.ml

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -90,22 +90,18 @@ module Std = struct
9090
include Model
9191
end
9292

93-
let () =
94-
let provide_delay obj =
95-
let open KB.Syntax in
96-
Theory.Label.target obj >>= fun target ->
97-
if Theory.Target.belongs Bap_mips_target.parent target
98-
then
99-
KB.collect Theory.Semantics.slot obj >>| fun insn ->
100-
let name = KB.Value.get Insn.Slot.name insn in
101-
Hashtbl.find_and_call Std.delayed_opcodes name
102-
~if_found:(fun delay ->
103-
KB.Value.put Insn.Slot.delay insn (Some delay))
104-
~if_not_found:(fun _ -> Insn.empty)
105-
else !!Insn.empty in
106-
Bap_main.Extension.declare @@ fun _ctxt ->
93+
let promise_delay_slots () =
10794
KB.Rule.(declare ~package:"mips" "delay-slot" |>
10895
require Insn.Slot.name |>
10996
provide Insn.Slot.delay |>
11097
comment "provides the delay slot length for branches");
111-
Ok (KB.promise Theory.Semantics.slot provide_delay)
98+
KB.promise Theory.Semantics.slot @@ fun obj ->
99+
let open KB.Syntax in
100+
Theory.Label.target obj >>= fun target ->
101+
KB.guard (Theory.Target.belongs Bap_mips_target.parent target) >>= fun () ->
102+
KB.collect Theory.Semantics.slot obj >>| fun insn ->
103+
let name = KB.Value.get Insn.Slot.name insn in
104+
Hashtbl.find_and_call Std.delayed_opcodes name
105+
~if_found:(fun delay ->
106+
KB.Value.put Insn.Slot.delay insn (Some delay))
107+
~if_not_found:(fun _ -> Insn.empty)

plugins/mips/mips_main.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,5 @@ let () =
4747
register_target `mipsel (module MIPS32_le);
4848
register_target `mips64 (module MIPS64);
4949
register_target `mips64el (module MIPS64_le);
50+
Mips.promise_delay_slots ();
5051
Mips_abi.setup ());

plugins/relocatable/rel_symbolizer.ml

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -200,32 +200,31 @@ let resolve_stubs () =
200200
KB.collect References.slot unit >>= fun refs ->
201201
KB.collect Theory.Label.addr label >>=? fun addr ->
202202
KB.collect (Value.Tag.slot Sub.stub) label >>= fun is_stub ->
203-
if not (Option.is_some is_stub) then KB.return None
204-
else match References.lookup refs addr with
205-
| Some (Name s) -> KB.return (Some s)
206-
| _ ->
207-
plt_size label >>=? fun size ->
208-
collect_insns size addr >>| fun bil ->
209-
find_references bil |>
210-
List.find_map ~f:(function
211-
| Name s -> Some s
212-
| Addr dst -> match References.lookup refs dst with
213-
| Some (Name s) -> Some s
214-
| _ -> None)
203+
KB.guard (Option.is_some is_stub) >>= fun () ->
204+
match References.lookup refs addr with
205+
| Some (Name s) -> KB.return (Some s)
206+
| _ ->
207+
plt_size label >>=? fun size ->
208+
collect_insns size addr >>| fun bil ->
209+
find_references bil |>
210+
List.find_map ~f:(function
211+
| Name s -> Some s
212+
| Addr dst -> match References.lookup refs dst with
213+
| Some (Name s) -> Some s
214+
| _ -> None)
215215

216216
let label_for_ref = function
217217
| Name s -> Theory.Label.for_name s
218218
| Addr x -> Theory.Label.for_addr x
219219

220220
let mark_mips_stubs_as_functions () : unit =
221221
KB.promise Theory.Label.is_subroutine @@ fun label ->
222-
KB.collect Theory.Label.addr label >>=? fun addr ->
223-
KB.collect Theory.Label.unit label >>=? fun unit ->
224-
KB.collect References.slot unit >>= fun refs ->
225-
KB.collect Theory.Unit.target unit >>| fun target ->
226-
let is_entry = (Theory.Target.matches target "mips") &&
227-
Option.is_some (References.lookup refs addr) in
228-
Option.some_if is_entry true
222+
let* unit = label-->?Theory.Label.unit in
223+
let* target = unit-->Theory.Unit.target in
224+
KB.guard (Theory.Target.matches target "mips") >>= fun () ->
225+
let* addr = label-->?Theory.Label.addr in
226+
KB.collect References.slot unit >>| fun refs ->
227+
Option.(some_if (is_some (References.lookup refs addr))) true
229228

230229
let () = Extension.declare ~doc @@ fun _ctxt ->
231230
References.prepare ();

plugins/thumb/thumb_main.ml

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -222,25 +222,24 @@ module Main = struct
222222
let load () =
223223
KB.promise Theory.Semantics.slot @@ fun label ->
224224
KB.collect Theory.Label.encoding label >>= fun encoding ->
225-
if Theory.Language.equal Target.llvm_t32 encoding then
226-
KB.collect MC.Insn.slot label >>=? fun insn ->
227-
KB.collect Memory.slot label >>=? fun mem ->
228-
Theory.instance () >>= Theory.require >>= fun (module Core) ->
229-
let module Thumb = Thumb(Core) in
230-
let addr = Word.to_bitvec@@Memory.min_addr mem in
231-
match decode_opcode (MC.Insn.name insn) with
232-
| None -> !!Insn.empty
233-
| Some opcode ->
234-
try
235-
Thumb.lift_insn addr opcode insn >>| fun sema ->
236-
Insn.with_basic sema insn
237-
with uncaught ->
238-
warning "failed to decode a thumb instruction: \
239-
uncaught exception %s\nBacktrace:\n %s\n"
240-
(Exn.to_string uncaught)
241-
(Caml.Printexc.get_backtrace ());
242-
KB.return Insn.empty
243-
else KB.return Insn.empty
225+
KB.guard (Theory.Language.equal Target.llvm_t32 encoding) >>= fun () ->
226+
KB.collect MC.Insn.slot label >>=? fun insn ->
227+
KB.collect Memory.slot label >>=? fun mem ->
228+
Theory.instance () >>= Theory.require >>= fun (module Core) ->
229+
let module Thumb = Thumb(Core) in
230+
let addr = Word.to_bitvec@@Memory.min_addr mem in
231+
match decode_opcode (MC.Insn.name insn) with
232+
| None -> !!Insn.empty
233+
| Some opcode ->
234+
try
235+
Thumb.lift_insn addr opcode insn >>| fun sema ->
236+
Insn.with_basic sema insn
237+
with uncaught ->
238+
warning "failed to decode a thumb instruction: \
239+
uncaught exception %s\nBacktrace:\n %s\n"
240+
(Exn.to_string uncaught)
241+
(Caml.Printexc.get_backtrace ());
242+
KB.return Insn.empty
244243
end
245244

246245
let () = Bap_main.Extension.declare @@ fun _ctxt ->

0 commit comments

Comments
 (0)