about summary refs log tree commit diff stats
path: root/miasm2
diff options
context:
space:
mode:
authorAjax <commial@gmail.com>2015-12-04 18:46:48 +0100
committerAjax <commial@gmail.com>2015-12-07 11:15:43 +0100
commit308a634b7c2c20692e85f5b72178e00d072b7bcd (patch)
tree3e091aef76acdf18d6592c2a058345d87489227b /miasm2
parent42d4998c1646e48fd9cb150d1aa0e9970b5717c8 (diff)
downloadmiasm-308a634b7c2c20692e85f5b72178e00d072b7bcd.tar.gz
miasm-308a634b7c2c20692e85f5b72178e00d072b7bcd.zip
IR: replace `.g` with a lazy built `.graph`, avoiding the need of `gen_graph`
Diffstat (limited to '')
-rw-r--r--miasm2/analysis/data_analysis.py6
-rw-r--r--miasm2/analysis/depgraph.py6
-rw-r--r--miasm2/ir/analysis.py14
-rw-r--r--miasm2/ir/ir.py18
4 files changed, 21 insertions, 23 deletions
diff --git a/miasm2/analysis/data_analysis.py b/miasm2/analysis/data_analysis.py
index 8462f150..9451a407 100644
--- a/miasm2/analysis/data_analysis.py
+++ b/miasm2/analysis/data_analysis.py
@@ -150,7 +150,7 @@ def inter_bloc_flow_link(ir_arch, flow_graph, todo, link_exec_to_data):
     x_nodes = tuple(sorted(list(irb.dst.get_r())))
 
     todo = set()
-    for lbl_dst in ir_arch.g.successors(irb.label):
+    for lbl_dst in ir_arch.graph.successors(irb.label):
         todo.add((lbl_dst, tuple(current_nodes.items()), x_nodes))
 
     # pp(('OUT', lbl, [(str(x[0]), str(x[1])) for x in current_nodes.items()]))
@@ -166,7 +166,7 @@ def create_implicit_flow(ir_arch, flow_graph):
     while todo:
         lbl = todo.pop()
         irb = ir_arch.blocs[lbl]
-        for lbl_son in ir_arch.g.successors(irb.label):
+        for lbl_son in ir_arch.graph.successors(irb.label):
             if not lbl_son in ir_arch.blocs:
                 print "cannot find bloc!!", lbl
                 continue
@@ -189,7 +189,7 @@ def create_implicit_flow(ir_arch, flow_graph):
                     irb.in_nodes[n_r] = irb.label, 0, n_r
                 node_n_r = irb.in_nodes[n_r]
                 # print "###", node_n_r
-                for lbl_p in ir_arch.g.predecessors(irb.label):
+                for lbl_p in ir_arch.graph.predecessors(irb.label):
                     todo.add(lbl_p)
 
                 flow_graph.add_uniq_edge(node_n_r, node_n_w)
diff --git a/miasm2/analysis/depgraph.py b/miasm2/analysis/depgraph.py
index 838183bf..0a5d38aa 100644
--- a/miasm2/analysis/depgraph.py
+++ b/miasm2/analysis/depgraph.py
@@ -686,7 +686,6 @@ class DependencyGraph(object):
     def __init__(self, ira, implicit=False, apply_simp=True, follow_mem=True,
                  follow_call=True):
         """Create a DependencyGraph linked to @ira
-        The IRA graph must have been computed
 
         @ira: IRAnalysis instance
         @implicit: (optional) Imply implicit dependencies
@@ -702,9 +701,6 @@ class DependencyGraph(object):
         self._step_counter = itertools.count()
         self._current_step = next(self._step_counter)
 
-        # The IRA graph must be computed
-        assert hasattr(self._ira, 'g')
-
         # Create callback filters. The order is relevant.
         self._cb_follow = []
         if apply_simp:
@@ -892,7 +888,7 @@ class DependencyGraph(object):
     def _get_previousblocks(self, label):
         """Return an iterator on predecessors blocks of @label, with their
         lengths"""
-        preds = self._ira.g.predecessors_iter(label)
+        preds = self._ira.graph.predecessors_iter(label)
         for pred_label in preds:
             length = len(self._get_irs(pred_label))
             yield (pred_label, length)
diff --git a/miasm2/ir/analysis.py b/miasm2/ir/analysis.py
index 9844f58f..40a3bf64 100644
--- a/miasm2/ir/analysis.py
+++ b/miasm2/ir/analysis.py
@@ -61,12 +61,12 @@ class ira(ir):
 
         useful = set()
 
-        for node in self.g.nodes():
+        for node in self.graph.nodes():
             if node not in self.blocs:
                 continue
 
             block = self.blocs[node]
-            successors = self.g.successors(node)
+            successors = self.graph.successors(node)
             has_son = bool(successors)
             for p_son in successors:
                 if p_son not in self.blocs:
@@ -186,7 +186,7 @@ class ira(ir):
                       for key, value in irb.cur_reach[0].iteritems()}
 
         # Compute reach from predecessors
-        for n_pred in self.g.predecessors(irb.label):
+        for n_pred in self.graph.predecessors(irb.label):
             p_block = self.blocs[n_pred]
 
             # Handle each register definition
@@ -225,7 +225,7 @@ class ira(ir):
         analysis"""
 
         fixed = True
-        for node in self.g.nodes():
+        for node in self.graph.nodes():
             if node in self.blocs:
                 irb = self.blocs[node]
                 if (irb.cur_reach != irb.prev_reach or
@@ -241,13 +241,11 @@ class ira(ir):
 
         Source : Kennedy, K. (1979). A survey of data flow analysis techniques.
         IBM Thomas J. Watson Research Division, page 43
-
-        PRE: gen_graph()
         """
         fixed_point = False
         log.debug('iteration...')
         while not fixed_point:
-            for node in self.g.nodes():
+            for node in self.graph.nodes():
                 if node in self.blocs:
                     self.compute_reach_block(self.blocs[node])
             fixed_point = self._test_kill_reach_fix()
@@ -259,8 +257,6 @@ class ira(ir):
 
         Source : Kennedy, K. (1979). A survey of data flow analysis techniques.
         IBM Thomas J. Watson Research Division, page 43
-
-        PRE: gen_graph()
         """
         # Update r/w variables for all irblocs
         self.get_rw(self.ira_regs_ids())
diff --git a/miasm2/ir/ir.py b/miasm2/ir/ir.py
index c2bc96b6..eec24ba0 100644
--- a/miasm2/ir/ir.py
+++ b/miasm2/ir/ir.py
@@ -172,6 +172,8 @@ class ir(object):
         self.sp = arch.getsp(attrib)
         self.arch = arch
         self.attrib = attrib
+        # Lazy structure
+        self._graph = None
 
     def instr2ir(self, l):
         ir_bloc_cur, ir_blocs_extra = self.get_ir(l)
@@ -421,14 +423,14 @@ class ir(object):
 
         return done
 
-    def gen_graph(self, link_all = True):
+    def _gen_graph(self, link_all = True):
         """
         Gen irbloc digraph
         @link_all: also gen edges to non present irblocs
         """
-        self.g = DiGraphIR(self.blocs)
+        self._graph = DiGraphIR(self.blocs)
         for lbl, b in self.blocs.items():
-            self.g.add_node(lbl)
+            self._graph.add_node(lbl)
             dst = self.dst_trackback(b)
             for d in dst:
                 if isinstance(d, m2_expr.ExprInt):
@@ -436,8 +438,12 @@ class ir(object):
                         self.symbol_pool.getby_offset_create(int(d.arg)))
                 if asmbloc.expr_is_label(d):
                     if d.name in self.blocs or link_all is True:
-                        self.g.add_edge(lbl, d.name)
+                        self._graph.add_edge(lbl, d.name)
 
+    @property
     def graph(self):
-        """Output the graphviz script"""
-        return self.g.dot()
+        """Get a DiGraph representation of current IR instance.
+        Lazy property, building the graph on-demand"""
+        if self._graph is None:
+            self._gen_graph()
+        return self._graph