Module Cil2cfg


module Cil2cfg: sig .. end
Build a CFG of a function keeping some information of the initial structure.
Raises Not_found if stmt_opt v = None


type node_type =
| Vstart of int
| Vexit of int
| VfctIn of int
| VfctOut of int
| VblkIn of Cil_types.stmt
| VblkOut of Cil_types.stmt
| Vstmt of Cil_types.stmt
| Vtest of Cil_types.stmt * Cil_types.exp
| Vloop of bool * Cil_types.stmt
val node_type_id : node_type -> int
gives a number to each CFG node in order to hash them
module VL: sig .. end
the CFG nodes

type edge_type =
| Enone
| Ethen
| Eelse
| Eback
| EbackThen
| EbackElse
module EL: sig .. end
the CFG edges
module CFG: Graph.Imperative.Digraph.ConcreteLabeled(VL)(EL)
the CFG is an ocamlgraph
val pretty_edge : Format.formatter -> CFG.E.t -> unit
val set_back_edge : CFG.E.t -> unit
val is_back_edge : CFG.E.t -> bool
val get_test_edges : CFG.t -> CFG.vertex -> CFG.edge * CFG.edge
Get the edges going out a test node with the then branch first

similar to CFG.succ_e g v but tests the branch to return (then-edge, else-edge)
Raises Invalid_argument if the node is not a test.


type t = {
   kernel_function : Db_types.kernel_function;
   graph : CFG.t;
   stmt_node : (int, CFG.V.t) Hashtbl.t;
   start_id : int;
}
The final CFG is composed of the graph, but also : the function that it represents, an hashtable to find a CFG node knowing its hashcode, and the hashcode of the start node

abstract type of a cfg

val new_cfg_env : Db_types.kernel_function -> t
val cfg_kf : t -> Db_types.kernel_function
val cfg_graph : t -> CFG.t
get the graph itself
val cfg_start_id : t -> int
val cfg_fct_in_id : t -> int
val cfg_fct_out_id : t -> int
val cfg_exit_id : t -> int
val cfg_start : t -> CFG.V.t
get the starting node
val cfg_fct_in : t -> CFG.V.t
val cfg_fct_out : t -> CFG.V.t
val cfg_exit : t -> CFG.V.t
val cfg_blk_in : t -> Cil_types.stmt -> CFG.V.t
val cfg_blk_out : t -> Cil_types.stmt -> CFG.V.t
val add_node : t -> node_type -> CFG.V.t
val add_edge : t ->
CFG.E.vertex -> edge_type -> CFG.E.vertex -> unit
val init_cfg : Db_types.kernel_function -> t * CFG.V.t * CFG.V.t
module type HEsig = sig .. end
signature of a mapping table from cfg edges to some information.
module HE: 
functor (I : sig
type t 
end) -> sig .. end
module Hpred: HE(sig
type t = Cil_types.predicate Cil_types.named list 
end)
module Hfol: HE(sig
type t = Fol.predicate 
end)
val get_node : t -> node_type -> CFG.V.t
While building the CFG, it can happend that we need to create a node without knowing its kind yet. So we build it as a Vstmt. Then, when we try to build the node with its real kind, if we already have a node Vstmt for the statement, we simply change it.
val get_stmt_node : t -> Cil_types.stmt -> CFG.V.t
val cfg_block : t ->
CFG.E.vertex ->
edge_type -> Cil_types.block -> CFG.V.t -> unit
val cfg_stmt : t -> Cil_types.stmt -> CFG.V.t -> unit

About loops

Let's first remind some definitions about loops : A loop is not a natural loop if it has several entries (no loop header), or if it has some irreducible region (no back edge).

Below, we use an algorithm from the paper : "A New Algorithm for Identifying Loops in Decompilation" of Tao Wei, Jian Mao, Wei Zou, and Yu Chen, to gather information about the loops in the builted CFG.

module type WeiMaoZouChenInput = sig .. end
module WeiMaoZouChen: 
functor (G : WeiMaoZouChenInput) -> sig .. end
Implementation of "A New Algorithm for Identifying Loops in Decompilation"
module LoopInfo: sig .. end
To use WeiMaoZouChen algorithm, we need to define how to interact with our CFG graph
module Mloop: WeiMaoZouChen(LoopInfo)
val mark_loops : LoopInfo.graph -> unit
val loop_stmts : CFG.t -> CFG.vertex -> Cil_types.stmt list
Raises

Create CFG


val create : Kernel_function.t -> t
Raises

Export dot graph


module Printer: 
functor (PE : sig
val edge_txt : CFG.E.t -> string
end) -> sig .. end
val display : file:string -> ?edge_txt:(CFG.E.t -> string) -> t -> unit
output the graph in a dot file named file with optional text on the edges.