about summary refs log tree commit diff stats
path: root/miasm2/ir/ir.py
diff options
context:
space:
mode:
Diffstat (limited to 'miasm2/ir/ir.py')
-rw-r--r--miasm2/ir/ir.py173
1 files changed, 33 insertions, 140 deletions
diff --git a/miasm2/ir/ir.py b/miasm2/ir/ir.py
index bf9b4e9a..721101e2 100644
--- a/miasm2/ir/ir.py
+++ b/miasm2/ir/ir.py
@@ -302,6 +302,20 @@ class IRBlock(object):
         self._dst = None
         self._dst_linenb = None
 
+    def __eq__(self, other):
+        if self.__class__ is not other.__class__:
+            return False
+        if self.loc_key != other.loc_key:
+            return False
+        if len(self.assignblks) != len(other.assignblks):
+            return False
+        for assignblk1, assignblk2 in zip(self.assignblks, other.assignblks):
+            if assignblk1 != assignblk2:
+                return False
+        return True
+
+    def __ne__(self, other):
+        return not self.__eq__(other)
 
     def get_label(self):
         warnings.warn('DEPRECATION WARNING: use ".loc_key" instead of ".label"')
@@ -421,7 +435,7 @@ class IRBlock(object):
                 node_name = "".join("%s:\n" % name for name in names)
         out.append(node_name)
 
-        for i, assignblk in enumerate(self):
+        for assignblk in self:
             out.append(assignblk.to_string(loc_db))
         return '\n'.join(out)
 
@@ -437,12 +451,12 @@ class irbloc(IRBlock):
         super(irbloc, self).__init__(loc_key, irs)
 
 
-class DiGraphIR(DiGraph):
+class IRCFG(DiGraph):
 
     """DiGraph for IR instances"""
 
     def __init__(self, irdst, loc_db, blocks=None, *args, **kwargs):
-        """Instanciate a DiGraphIR
+        """Instanciate a IRCFG
         @loc_db: LocationDB instance
         @blocks: IR blocks
         """
@@ -451,7 +465,7 @@ class DiGraphIR(DiGraph):
             blocks = {}
         self._blocks = blocks
         self._irdst = irdst
-        super(DiGraphIR, self).__init__(*args, **kwargs)
+        super(IRCFG, self).__init__(*args, **kwargs)
 
     @property
     def IRDst(self):
@@ -463,7 +477,7 @@ class DiGraphIR(DiGraph):
 
     def add_irblock(self, irblock):
         """
-        Add the @irblock to the current DiGraphIR
+        Add the @irblock to the current IRCFG
         @irblock: IRBlock instance
         """
         self.blocks[irblock.loc_key] = irblock
@@ -533,7 +547,7 @@ class DiGraphIR(DiGraph):
         node
         """
         self._dot_offset = offset
-        return super(DiGraphIR, self).dot()
+        return super(IRCFG, self).dot()
 
     def get_loc_key(self, addr):
         """Transforms an ExprId/ExprInt/loc_key/int into a loc_key
@@ -661,137 +675,16 @@ class DiGraphIR(DiGraph):
 
         return done
 
-    def remove_empty_assignblks(self):
-        modified = False
-        for loc_key, block in self.blocks.iteritems():
-            irs = []
-            for assignblk in block:
-                if len(assignblk):
-                    irs.append(assignblk)
-                else:
-                    modified = True
-            self.blocks[loc_key] = IRBlock(loc_key, irs)
-        return modified
-
-    def remove_jmp_blocks(self):
-        """
-        Remove irblock with only IRDst set, by linking it's parent destination to
-        the block destination.
-        """
-
-        # Find candidates
-        jmp_blocks = set()
-        for block in self.blocks.itervalues():
-            if len(block) != 1:
-                continue
-            assignblk = block[0]
-            if len(assignblk) > 1:
-                continue
-            assert set(assignblk.keys()) == set([self.IRDst])
-            if len(self.successors(block.loc_key)) != 1:
-                continue
-            if not assignblk[self.IRDst].is_loc():
-                continue
-            dst = assignblk[self.IRDst].loc_key
-            if dst == block.loc_key:
-                # Infinite loop block
-                continue
-            jmp_blocks.add(block.loc_key)
-
-        # Remove them, relink graph
-        modified = False
-        for loc_key in jmp_blocks:
-            block = self.blocks[loc_key]
-            dst_loc_key = block.dst
-            parents = self.predecessors(block.loc_key)
-            for lbl in parents:
-                parent = self.blocks.get(lbl, None)
-                if parent is None:
-                    continue
-                dst = parent.dst
-                if dst.is_id(block.loc_key):
-                    dst = m2_expr.ExprLoc(dst_loc_key, dst.size)
-
-                    self.discard_edge(lbl, block.loc_key)
-                    self.discard_edge(block.loc_key, dst_loc_key)
 
-                    self.add_uniq_edge(lbl, dst_loc_key)
-                    modified = True
-                elif dst.is_cond():
-                    src1, src2 = dst.src1, dst.src2
-                    if src1.is_id(block.loc_key):
-                        dst = m2_expr.ExprCond(dst.cond, m2_expr.ExprLoc(dst_loc_key, dst.size), dst.src2)
-                        self.discard_edge(lbl, block.loc_key)
-                        self.discard_edge(block.loc_key, dst_loc_key)
-                        self.add_uniq_edge(lbl, dst_loc_key)
-                        modified = True
-                    if src2.is_id(block.loc_key):
-                        dst = m2_expr.ExprCond(dst.cond, dst.src1, m2_expr.ExprLoc(dst_loc_key, dst.size))
-                        self.discard_edge(lbl, block.loc_key)
-                        self.discard_edge(block.loc_key, dst_loc_key)
-                        self.add_uniq_edge(lbl, dst_loc_key)
-                        modified = True
-                    if dst.src1 == dst.src2:
-                        dst = dst.src1
-                else:
-                    continue
-                new_parent = parent.set_dst(dst)
-                self.blocks[parent.loc_key] = new_parent
-
-        # Remove unlinked useless nodes
-        for loc_key in jmp_blocks:
-            if (len(self.predecessors(loc_key)) == 0 and
-                len(self.successors(loc_key)) == 0):
-                self.del_node(loc_key)
-                del self.blocks[loc_key]
-        return modified
+class DiGraphIR(IRCFG):
+    """
+    DEPRECATED object
+    Use IRCFG instead of DiGraphIR
+    """
 
-    def merge_blocks(self):
-        """
-        Group irblock with one and only one son if this son has one and only one
-        parent
-        """
-        modified = False
-        todo = set(self.nodes())
-        while todo:
-            block = todo.pop()
-            sons = self.successors(block)
-            if len(sons) != 1:
-                continue
-            son = list(sons)[0]
-            if self.predecessors(son) != [block]:
-                continue
-            if block not in self.blocks:
-                continue
-            if son not in self.blocks:
-                continue
-            # Block has one son, son has one parent => merge
-            assignblks = []
-            for assignblk in self.blocks[block]:
-                if self.IRDst not in assignblk:
-                    assignblks.append(assignblk)
-                    continue
-                affs = {}
-                for dst, src in assignblk.iteritems():
-                    if dst != self.IRDst:
-                        affs[dst] = src
-                assignblks.append(AssignBlock(affs, assignblk.instr))
-
-            assignblks += self.blocks[son].assignblks
-            new_block = IRBlock(block, assignblks)
-
-            self.discard_edge(block, son)
-
-            for lson in self.successors(son):
-                self.add_uniq_edge(block, lson)
-                self.discard_edge(son, lson)
-            del self.blocks[son]
-            self.del_node(son)
-
-            self.blocks[block] = new_block
-            todo.add(block)
-            modified = True
-        return modified
+    def __init__(self, irdst, loc_db, blocks=None, *args, **kwargs):
+        warnings.warn('DEPRECATION WARNING: use "IRCFG" instead of "DiGraphIR"')
+        super(IRCFG, self).__init__(irdst, loc_db, blocks=None, *args, **kwargs)
 
 
 class IntermediateRepresentation(object):
@@ -814,17 +707,17 @@ class IntermediateRepresentation(object):
 
     def new_ircfg(self, *args, **kwargs):
         """
-        Return a new instance of DiGraphIR
+        Return a new instance of IRCFG
         """
-        return DiGraphIR(self.IRDst, self.loc_db, *args, **kwargs)
+        return IRCFG(self.IRDst, self.loc_db, *args, **kwargs)
 
     def new_ircfg_from_asmcfg(self, asmcfg, *args, **kwargs):
         """
-        Return a new instance of DiGraphIR from an @asmcfg
+        Return a new instance of IRCFG from an @asmcfg
         @asmcfg: AsmCFG instance
         """
 
-        ircfg = DiGraphIR(self.IRDst, self.loc_db, *args, **kwargs)
+        ircfg = IRCFG(self.IRDst, self.loc_db, *args, **kwargs)
         for block in asmcfg.blocks:
             self.add_asmblock_to_ircfg(block, ircfg)
         return ircfg
@@ -888,7 +781,7 @@ class IntermediateRepresentation(object):
         """
         Add a native block to the current IR
         @block: native assembly block
-        @ircfg: DiGraphIR instance
+        @ircfg: IRCFG instance
         @gen_pc_updt: insert PC update effects between instructions
         """