Permalink
Browse files

This PR tentatively introduces Graphlib library.

Graphlib extends OCamlGraph with a new modern and more rich interface.
It also provides:

- two new graph types
- depth_first_search algorithm
- dominators algorithm
- dominance frontier
- strongly connected components
- shortest path and reachability algorithms
- auxiliary data structures, like Rose Trees, Partition Sets, Frontiers,
  Paths, etc;
- functor that implements new interface on top of ocamlgraph modules
- functor that implements an old ocamlgraph interface on top of modules,
  that implements a newer [Graph] interface;
- pretty-printing for all graphs and auxiliary data structures;
- generic dot printing.

The library uses first class modules instead of functors, thus making
working with graph syntactically easier.

Note: this is a pre-release. I feel there still rough edges (and nodes)
left in the library. But everyone is welcome to play with it. Feedback
is very welcome.
  • Loading branch information...
ivg committed Jun 26, 2015
1 parent 45b5e93 commit 52d628a9a65617b62556ddd75f1429c7cece5b0c
Showing with 4,464 additions and 261 deletions.
  1. +15 −7 _oasis
  2. +90 −0 benchmarks/bench_dom.ml
  3. +3 −1 benchmarks/bench_image.ml
  4. +1 −1 benchmarks/bench_image.mli
  5. +4 −2 benchmarks/run_benchmarks.ml
  6. +24 −0 lib/bap/bap.ml
  7. +1,138 −110 lib/bap/bap.mli
  8. +3 −1 lib/bap/bap_project.ml
  9. +1 −1 lib/bap_disasm/bap_disasm.ml
  10. +4 −4 lib/bap_disasm/bap_disasm_arm.ml
  11. +4 −4 lib/bap_disasm/bap_disasm_basic.ml
  12. +1 −1 lib/bap_disasm/bap_disasm_insn.ml
  13. +1 −1 lib/bap_disasm/bap_disasm_rec.ml
  14. +1 −1 lib/bap_dwarf/dwarf_fbi.ml
  15. +2 −2 lib/bap_image/bap_image.ml
  16. +1 −1 lib/bap_image/bap_memory.ml
  17. +1 −1 lib/bap_types/bap_arch.ml
  18. +2 −2 lib/bap_types/bap_bitvector.ml
  19. +2 −0 lib/bap_types/bap_common.ml
  20. +9 −3 lib/bap_types/bap_exp.ml
  21. +1,027 −0 lib/bap_types/bap_graph.ml
  22. +233 −0 lib/bap_types/bap_graph.mli
  23. +112 −0 lib/bap_types/bap_graph_intf.ml
  24. +96 −0 lib/bap_types/bap_graph_pp.ml
  25. +36 −0 lib/bap_types/bap_graph_pp.mli
  26. +385 −0 lib/bap_types/bap_graph_regular.ml
  27. +23 −0 lib/bap_types/bap_graph_regular.mli
  28. +54 −0 lib/bap_types/bap_graph_regular_intf.ml
  29. +2 −1 lib/bap_types/bap_helpers.ml
  30. +99 −72 lib/{bap_sema → bap_types}/bap_ir.ml
  31. +23 −19 lib/{bap_sema → bap_types}/bap_ir.mli
  32. +458 −0 lib/bap_types/bap_ir_graph.ml
  33. +54 −0 lib/bap_types/bap_ir_graph.mli
  34. +21 −0 lib/bap_types/bap_opaque.ml
  35. +12 −13 lib/bap_types/bap_regular.ml
  36. +2 −2 lib/bap_types/bap_regular.mli
  37. +14 −0 lib/bap_types/bap_seq.ml
  38. +1 −0 lib/bap_types/bap_seq.mli
  39. +1 −1 lib/bap_types/bap_size.ml
  40. +2 −2 lib/bap_types/bap_stmt.ml
  41. +1 −1 lib/bap_types/bap_type.ml
  42. +2 −0 lib/bap_types/bap_types.ml
  43. +2 −2 lib/bap_types/bap_value.ml
  44. +1 −1 lib/bap_types/bap_var.ml
  45. +1 −1 lib/bap_types/conceval.ml
  46. +1 −0 lib_test/.merlin
  47. +1 −0 lib_test/bap/run_tests.ml
  48. +489 −0 lib_test/bap_types/test_graph.ml
  49. +1 −0 lib_test/bap_types/test_graph.mli
  50. +1 −1 src/readbin/bap_main.ml
  51. +1 −1 src/readbin/cmdline.ml
  52. +1 −1 src/server/manager.ml
View
22 _oasis
@@ -9,7 +9,7 @@ Copyrights: (C) 2014 Carnegie Mellon University
Plugins: META (0.4)
AlphaFeatures: ocamlbuild_more_args
BuildTools: ocamlbuild, camlp4o
XOCamlbuildExtraArgs: -j 2
XOCamlbuildExtraArgs: -j 1
BuildDepends:
bin_prot.syntax,
camlp4,
@@ -100,7 +100,7 @@ Library types
FindlibParent: bap
FindlibName: types
CompiledObject: best
BuildDepends: zarith, uuidm
BuildDepends: zarith, uuidm, ocamlgraph
InternalModules:
Bap_addr,
Bap_arch,
@@ -111,10 +111,18 @@ Library types
Bap_common,
Bap_config,
Bap_exp,
Bap_graph,
Bap_graph_intf,
Bap_graph_regular,
Bap_graph_regular_intf,
Bap_graph_pp,
Bap_ir,
Bap_ir_graph,
Bap_helpers,
Bap_int_conversions,
Bap_integer,
Bap_integer_intf,
Bap_opaque,
Bap_regular,
Bap_seq,
Bap_size,
@@ -145,7 +153,7 @@ Library serialization
BuildTools: ocamlbuild, piqi
DataFiles: *.piqi
CompiledObject: best
BuildDepends: piqilib,piqirun,piqirun.pb,piqirun.ext,bap
BuildDepends: piqirun,piqirun.pb,piqirun.ext,bap
Modules: Bil_piqi
InternalModules:
Stmt_piqi,
@@ -296,7 +304,6 @@ Library sema
InternalModules:
Bap_sema,
Bap_sema_lift,
Bap_ir,
Bap_lnf
Library types_test
@@ -306,7 +313,8 @@ Library types_test
CompiledObject: best
BuildDepends: bap, bap.conceval, oUnit
Modules: Test_bitvector,
Test_conceval
Test_conceval,
Test_graph
Library image_test
Path: lib_test/bap_image
@@ -357,7 +365,7 @@ Library benchmarks
CompiledObject: best
BuildDepends: bap, core, core_bench, threads
Install: false
Modules: Bench_image
Modules: Bench_dom, Bench_image
Library core_lwt
Path: lwt
@@ -456,7 +464,7 @@ Executable run_benchmarks
Test unit_tests
TestTools: run_tests
Command: $run_tests
Command: $run_tests -runner sequential
Test inline_tests
TestTools: run_tests
View
@@ -0,0 +1,90 @@
open Core.Std
open Core_bench.Std
open Bap.Std
open Format
let filename = "arm-binaries/coreutils/coreutils_O1_ls"
let sizes_to_test = 10
module Cfg = Graphlib.Ir
module CFG = Graphlib.To_ocamlgraph(Cfg)
module DOM = Graph.Dominator.Make(CFG)
module SCC = Graph.Components.Make(CFG)
let proj = Project.from_file filename |> ok_exn
let syms = Project.symbols proj
(** [scale_linear ~input:(x1,x2) ~output:(y1,y2)]
will return a linear function $f(x) = ax + b$ such that:
{[
f x1 = y1;
f x2 = y2;
]} *)
let scale_linear ~input:(x1,x2) ~output:(y1,y2) =
let open Float in
let x1,x2,y1,y2 = float x1, float x2, float y1, float y2 in
let a = (y1 - y2) / (x1 - x2) in
let b = y1 - x1 * (y1 - y2) / (x1-x2) in
fun x -> to_int (round (a * (float x) + b))
let functions,sizes,index =
let functions = Term.enum sub_t (Project.program proj) |>
Seq.map ~f:Cfg.of_sub |> Seq.to_array in
let size g = Cfg.number_of_nodes g + Cfg.number_of_edges g in
Array.sort functions ~cmp:(fun x y -> Int.compare (size x) (size y));
let max_idx = Array.length functions - 1 in
let min_size = size functions.(0) in
let max_size = min 1000 @@ size functions.(max_idx) in
let size =
scale_linear ~input:(0,sizes_to_test-1) ~output:(min_size,max_size) in
let index =
scale_linear ~input:(min_size,max_size) ~output:(0,max_idx) in
let sizes = List.init sizes_to_test ~f:size in
functions,List.rev sizes,index
let ocamlgraph cfg entry =
DOM.compute_idom cfg entry
let graphlib cfg entry =
Tree.parent (Graphlib.dominators (module Cfg) cfg entry)
let dom algo cfg =
algo cfg (Seq.hd_exn @@ Cfg.nodes cfg)
let run f size =
stage (fun () -> f functions.(index size))
let graphlib_scc cfg =
Graphlib.strong_components (module Cfg) cfg |>
Partition.equiv
let ocamlgraph_scc cfg =
let _,get = SCC.scc cfg in
fun x y -> get x = get y
let indexed = Bench.Test.create_indexed ~args:sizes
let dom_test =
Bench.Test.create_group ~name:"dom" [
indexed ~name:"ocamlgraph" (run (dom ocamlgraph));
indexed ~name:"graphlib" (run (dom graphlib));
]
let scc_test =
Bench.Test.create_group ~name:"scc" [
indexed ~name:"graphlib" (run graphlib_scc);
indexed ~name:"ocamlgraph" (run ocamlgraph_scc);
]
let tests = [
dom_test;
scc_test;
]
@@ -37,7 +37,7 @@ let sum_fold () =
let sum_foldm () =
let (_ : word Or_error.t) =
Memory.With_error.fold mem ~f:(fun w1 w2 -> Word.Int.(!$w1 + !$w2)) ~init:zero
Memory.With_error.fold mem ~f:(fun w1 w2 -> Word.Int_err.(!$w1 + !$w2)) ~init:zero
in ()
let sum_fold_tab () =
@@ -52,3 +52,5 @@ let test = Bench.Test.create_group ~name:"image" [
Bench.Test.create ~name:"Bap_image.map_sum_foldm" sum_foldm;
Bench.Test.create ~name:"Bap_image.map_sum_table" sum_fold_tab;
]
let tests = [test]
@@ -1,3 +1,3 @@
open Core_bench.Std
val test : Bench.Test.t
val tests : Bench.Test.t list
@@ -2,8 +2,10 @@ open Core.Std
open Core_bench.Std
open Bap.Std
let benchmarks = Bench.make_command [
Bench_image.test;
let benchmarks = Bench.make_command @@ List.concat [
Bench_dom.tests;
Bench_image.tests;
]
let () = Command.run benchmarks
View
@@ -13,6 +13,30 @@ module Std = struct
type elf = Elf.t
module Signatures = Bap_signatures
module Byteweight = Bap_byteweight
include Bap_graph_intf
open Bap_graph
type nonrec 'a tree = 'a tree
type nonrec 'a frontier = 'a frontier
type nonrec 'a partition = 'a partition
type nonrec 'a group = 'a group
type nonrec 'a path = 'a path
type nonrec equiv = equiv
module Group = Group
module Tree = Tree
module Frontier = Frontier
module Partition = Partition
module Equiv = Equiv
module Path = Path
module Graphlib = struct
include Bap_graph
module type Graphs = Bap_graph_regular_intf.S
include Bap_graph_regular
module Ir = Bap_ir_graph
end
end
(* load internal plugins *)
Oops, something went wrong.

0 comments on commit 52d628a

Please sign in to comment.