about summary refs log tree commit diff stats
path: root/miasm2/ir/analysis.py
diff options
context:
space:
mode:
Diffstat (limited to 'miasm2/ir/analysis.py')
-rw-r--r--miasm2/ir/analysis.py124
1 files changed, 16 insertions, 108 deletions
diff --git a/miasm2/ir/analysis.py b/miasm2/ir/analysis.py
index 31f6294c..40a3bf64 100644
--- a/miasm2/ir/analysis.py
+++ b/miasm2/ir/analysis.py
@@ -4,7 +4,7 @@
 import logging
 
 from miasm2.ir.symbexec import symbexec
-from miasm2.core.graph import DiGraph
+from miasm2.ir.ir import ir
 from miasm2.expression.expression \
     import ExprAff, ExprCond, ExprId, ExprInt, ExprMem
 
@@ -14,109 +14,21 @@ console_handler.setFormatter(logging.Formatter("%(levelname)-5s: %(message)s"))
 log.addHandler(console_handler)
 log.setLevel(logging.WARNING)
 
-class ira:
+
+class ira(ir):
+    """IR Analysis
+    This class provides higher level manipulations on IR, such as dead
+    instruction removals.
+
+    This class can be used as a common parent with `miasm2.ir.ir::ir` class.
+    For instance:
+        class ira_x86_16(ir_x86_16, ira)
+    """
 
     def ira_regs_ids(self):
         """Returns ids of all registers used in the IR"""
         return self.arch.regs.all_regs_ids + [self.IRDst]
 
-    def sort_dst(self, todo, done):
-        out = set()
-        while todo:
-            dst = todo.pop()
-            if self.ExprIsLabel(dst):
-                done.add(dst)
-            elif isinstance(dst, ExprMem) or isinstance(dst, ExprInt):
-                done.add(dst)
-            elif isinstance(dst, ExprCond):
-                todo.add(dst.src1)
-                todo.add(dst.src2)
-            elif isinstance(dst, ExprId):
-                out.add(dst)
-            else:
-                done.add(dst)
-        return out
-
-    def dst_trackback(self, b):
-        dst = b.dst
-        todo = set([dst])
-        done = set()
-
-        for irs in reversed(b.irs):
-            if len(todo) == 0:
-                break
-            out = self.sort_dst(todo, done)
-            found = set()
-            follow = set()
-            for i in irs:
-                if not out:
-                    break
-                for o in out:
-                    if i.dst == o:
-                        follow.add(i.src)
-                        found.add(o)
-                for o in found:
-                    out.remove(o)
-
-            for o in out:
-                if o not in found:
-                    follow.add(o)
-            todo = follow
-
-        return done
-
-    def gen_graph(self, link_all = True):
-        """
-        Gen irbloc digraph
-        @link_all: also gen edges to non present irblocs
-        """
-        self.g = DiGraph()
-        for lbl, b in self.blocs.items():
-            # print 'add', lbl
-            self.g.add_node(lbl)
-            # dst = self.get_bloc_dst(b)
-            dst = self.dst_trackback(b)
-            # print "\tdst", dst
-            for d in dst:
-                if isinstance(d, ExprInt):
-                    d = ExprId(
-                        self.symbol_pool.getby_offset_create(int(d.arg)))
-                if self.ExprIsLabel(d):
-                    if d.name in self.blocs or link_all is True:
-                        self.g.add_edge(lbl, d.name)
-
-    def graph(self):
-        """Output the graphviz script"""
-        out = """
-    digraph asm_graph {
-    size="80,50";
-    node [
-    fontsize = "16",
-    shape = "box"
-    ];
-        """
-        all_lbls = {}
-        for lbl in self.g.nodes():
-            if lbl not in self.blocs:
-                continue
-            irb = self.blocs[lbl]
-            ir_txt = [str(lbl)]
-            for irs in irb.irs:
-                for l in irs:
-                    ir_txt.append(str(l))
-                ir_txt.append("")
-            ir_txt.append("")
-            all_lbls[hash(lbl)] = "\l\\\n".join(ir_txt)
-        for l, v in all_lbls.items():
-            # print l, v
-            out += '%s [label="%s"];\n' % (l, v)
-
-        for a, b in self.g.edges():
-            # print 'edge', a, b, hash(a), hash(b)
-            out += '%s -> %s;\n' % (hash(a), hash(b))
-        out += '}'
-        return out
-
     def remove_dead_instr(self, irb, useful):
         """Remove dead affectations using previous reaches analysis
         @irb: irbloc instance
@@ -149,12 +61,12 @@ class ira:
 
         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:
@@ -274,7 +186,7 @@ class ira:
                       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
@@ -313,7 +225,7 @@ class ira:
         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
@@ -329,13 +241,11 @@ class ira:
 
         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()
@@ -347,8 +257,6 @@ class ira:
 
         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())