about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorserpilliere <fabrice.desclaux@cea.fr>2015-02-21 21:34:52 +0100
committerFabrice Desclaux <fabrice.desclaux@cea.fr>2016-11-04 16:45:46 +0100
commit895263f702876a2cdf3bd1e9359ce1b0340f87fd (patch)
tree23135227a64390adcf153120f841d28f4d2ed530
parent8e8a60b5d55db6209d05577d038ed3b4dc961b60 (diff)
downloadmiasm-895263f702876a2cdf3bd1e9359ce1b0340f87fd.tar.gz
miasm-895263f702876a2cdf3bd1e9359ce1b0340f87fd.zip
Expression: remove is_term attribute
-rw-r--r--miasm2/analysis/data_analysis.py7
-rw-r--r--miasm2/arch/sh4/regs.py1
-rw-r--r--miasm2/arch/x86/regs.py1
-rw-r--r--miasm2/expression/expression.py248
-rw-r--r--miasm2/expression/expression_helper.py10
-rw-r--r--miasm2/ir/analysis.py7
-rw-r--r--miasm2/ir/symbexec.py603
-rw-r--r--test/ir/symbexec.py24
8 files changed, 435 insertions, 466 deletions
diff --git a/miasm2/analysis/data_analysis.py b/miasm2/analysis/data_analysis.py
index 88f9b680..9fee22af 100644
--- a/miasm2/analysis/data_analysis.py
+++ b/miasm2/analysis/data_analysis.py
@@ -75,12 +75,7 @@ def intra_bloc_flow_symbexec(ir_arch, flow_graph, irb):
     out_nodes = {}
     current_nodes = {}
 
-    symbols_init = {}
-    for r in ir_arch.arch.regs.all_regs_ids:
-        # symbols_init[r] = ir_arch.arch.regs.all_regs_ids_init[i]
-        x = ExprId(r.name, r.size)
-        x.is_term = True
-        symbols_init[r] = x
+    symbols_init = dict(ir_arch.arch.regs.all_regs_ids_init)
 
     sb = symbexec(ir_arch, dict(symbols_init))
     sb.emulbloc(irb)
diff --git a/miasm2/arch/sh4/regs.py b/miasm2/arch/sh4/regs.py
index cfbca187..89ff42f8 100644
--- a/miasm2/arch/sh4/regs.py
+++ b/miasm2/arch/sh4/regs.py
@@ -78,7 +78,6 @@ all_regs_ids_init = [ExprId("%s_init" % x.name, x.size) for x in all_regs_ids]
 
 regs_init = {}
 for i, r in enumerate(all_regs_ids):
-    all_regs_ids_init[i].is_term = True
     regs_init[r] = all_regs_ids_init[i]
 
 regs_flt_expr = []
diff --git a/miasm2/arch/x86/regs.py b/miasm2/arch/x86/regs.py
index 18083a04..34585dae 100644
--- a/miasm2/arch/x86/regs.py
+++ b/miasm2/arch/x86/regs.py
@@ -430,7 +430,6 @@ all_regs_ids_init = [ExprId("%s_init" % x.name, x.size) for x in all_regs_ids]
 
 regs_init = {}
 for i, r in enumerate(all_regs_ids):
-    all_regs_ids_init[i].is_term = True
     regs_init[r] = all_regs_ids_init[i]
 
 regs_flt_expr = [float_st0, float_st1, float_st2, float_st3,
diff --git a/miasm2/expression/expression.py b/miasm2/expression/expression.py
index ad76f01c..59e809a5 100644
--- a/miasm2/expression/expression.py
+++ b/miasm2/expression/expression.py
@@ -114,18 +114,12 @@ class Expr(object):
 
     "Parent class for Miasm Expressions"
 
-    __slots__ = ["is_term", "is_simp", "is_canon",
-                 "is_eval", "__hash", "__repr", "__size",
-                 "is_var_ident"]
-
     all_exprs = set()
     args2expr = {}
     simp_exprs = set()
     canon_exprs = set()
     use_singleton = True
 
-    is_term = False   # Terminal expression
-
     def set_size(self, value):
         raise ValueError('size is not mutable')
 
@@ -134,7 +128,7 @@ class Expr(object):
         self.__repr = None
         self.__size = None
 
-    size = property(lambda self: self._size)
+    size = property(lambda self: self.__size)
 
     @staticmethod
     def get_object(cls, args):
@@ -191,9 +185,9 @@ class Expr(object):
         return False
 
     def __repr__(self):
-        if self._repr is None:
-            self._repr = self._exprrepr()
-        return self._repr
+        if self.__repr is None:
+            self.__repr = self._exprrepr()
+        return self.__repr
 
     def __hash__(self):
         if self.__hash is None:
@@ -379,7 +373,6 @@ class ExprInt(Expr):
      - Constant 0x12345678 on 32bits
      """
 
-    __slots__ = ["__arg"]
 
     def __init__(self, num, size=None):
         """Create an ExprInt from a modint or num/size
@@ -389,31 +382,30 @@ class ExprInt(Expr):
         super(ExprInt, self).__init__()
 
         if is_modint(num):
-            self._arg = num
-            self._size = self.arg.size
+            self.__arg = num
+            self.__size = self.arg.size
             if size is not None and num.size != size:
                 raise RuntimeError("size must match modint size")
         elif size is not None:
-            self._arg = mod_size2uint[size](num)
-            self._size = self.arg.size
+            self.__arg = mod_size2uint[size](num)
+            self.__size = self.arg.size
         else:
             raise ValueError('arg must by modint or (int,size)! %s' % num)
 
-        self.__arg = arg
-        self.__size = self.arg.size
-
     size = property(lambda self: self.__size)
     arg = property(lambda self: self.__arg)
 
-    def __new__(cls, arg):
-        return Expr.get_object(cls, (arg, arg.size))
+    def __new__(cls, arg, size=None):
+        if size is None:
+            size = arg.size
+        return Expr.get_object(cls, (arg, size))
 
     def __get_int(self):
         "Return self integer representation"
-        return int(self._arg & size2mask(self._size))
+        return int(self.__arg & size2mask(self.__size))
 
     def __str__(self):
-        if self._arg < 0:
+        if self.__arg < 0:
             return str("-0x%X" % (- self.__get_int()))
         else:
             return str("0x%X" % self.__get_int())
@@ -428,7 +420,7 @@ class ExprInt(Expr):
         return set()
 
     def _exprhash(self):
-        return hash((EXPRINT, self._arg, self._size))
+        return hash((EXPRINT, self.__arg, self.__size))
 
     def _exprrepr(self):
         return "%s(0x%X)" % (self.__class__.__name__, self.__get_int())
@@ -441,7 +433,7 @@ class ExprInt(Expr):
         return self
 
     def copy(self):
-        return ExprInt(self._arg)
+        return ExprInt(self.__arg)
 
     def depth(self):
         return 1
@@ -466,7 +458,6 @@ class ExprId(Expr):
      - variable v1
      """
 
-    __slots__ = ["_name"]
 
     def __init__(self, name, size=32):
         """Create an identifier
@@ -476,7 +467,6 @@ class ExprId(Expr):
         super(ExprId, self).__init__()
 
         self.__name, self.__size = name, size
-        self.is_term = is_term
 
     size = property(lambda self: self.__size)
     name = property(lambda self: self.__name)
@@ -485,7 +475,7 @@ class ExprId(Expr):
         return Expr.get_object(cls, (name, size))
 
     def __str__(self):
-        return str(self._name)
+        return str(self.__name)
 
     def get_r(self, mem_read=False, cst_read=False):
         return set([self])
@@ -525,7 +515,6 @@ class ExprAff(Expr):
      - var1 <- 2
     """
 
-    __slots__ = ["_src", "_dst"]
 
     def __init__(self, dst, src):
         """Create an ExprAff for dst <- src
@@ -562,41 +551,41 @@ class ExprAff(Expr):
         return Expr.get_object(cls, (dst, src))
 
     def __str__(self):
-        return "%s = %s" % (str(self._dst), str(self._src))
+        return "%s = %s" % (str(self.__dst), str(self.__src))
 
     def get_r(self, mem_read=False, cst_read=False):
-        elements = self._src.get_r(mem_read, cst_read)
-        if isinstance(self._dst, ExprMem) and mem_read:
-            elements.update(self._dst.arg.get_r(mem_read, cst_read))
+        elements = self.__src.get_r(mem_read, cst_read)
+        if isinstance(self.__dst, ExprMem) and mem_read:
+            elements.update(self.__dst.arg.get_r(mem_read, cst_read))
         return elements
 
     def get_w(self):
-        if isinstance(self._dst, ExprMem):
-            return set([self._dst])  # [memreg]
+        if isinstance(self.__dst, ExprMem):
+            return set([self.__dst])  # [memreg]
         else:
-            return self._dst.get_w()
+            return self.__dst.get_w()
 
     def _exprhash(self):
-        return hash((EXPRAFF, hash(self._dst), hash(self._src)))
+        return hash((EXPRAFF, hash(self.__dst), hash(self.__src)))
 
     def _exprrepr(self):
-        return "%s(%r, %r)" % (self.__class__.__name__, self._dst, self._src)
+        return "%s(%r, %r)" % (self.__class__.__name__, self.__dst, self.__src)
 
     def __contains__(self, expr):
         return (self == expr or
-                self._src.__contains__(expr) or
-                self._dst.__contains__(expr))
+                self.__src.__contains__(expr) or
+                self.__dst.__contains__(expr))
 
     # XXX /!\ for hackish expraff to slice
     def get_modified_slice(self):
         """Return an Expr list of extra expressions needed during the
         object instanciation"""
 
-        dst = self._dst
-        if not isinstance(self._src, ExprCompose):
+        dst = self.__dst
+        if not isinstance(self.__src, ExprCompose):
             raise ValueError("Get mod slice not on expraff slice", str(self))
         modified_s = []
-        for arg in self._src.args:
+        for arg in self.__src.args:
             if (not isinstance(arg[0], ExprSlice) or
                     arg[0].arg != dst or
                     arg[1] != arg[0].start or
@@ -607,21 +596,21 @@ class ExprAff(Expr):
 
     @visit_chk
     def visit(self, cb, tv=None):
-        dst, src = self._dst.visit(cb, tv), self._src.visit(cb, tv)
-        if dst == self._dst and src == self._src:
+        dst, src = self.__dst.visit(cb, tv), self.__src.visit(cb, tv)
+        if dst == self.__dst and src == self.__src:
             return self
         else:
             return ExprAff(dst, src)
 
     def copy(self):
-        return ExprAff(self._dst.copy(), self._src.copy())
+        return ExprAff(self.__dst.copy(), self.__src.copy())
 
     def depth(self):
-        return max(self._src.depth(), self._dst.depth()) + 1
+        return max(self.__src.depth(), self.__dst.depth()) + 1
 
     def graph_recursive(self, graph):
         graph.add_node(self)
-        for arg in [self._src, self._dst]:
+        for arg in [self.__src, self.__dst]:
             arg.graph_recursive(graph)
             graph.add_uniq_edge(self, arg)
 
@@ -636,7 +625,6 @@ class ExprCond(Expr):
      - if (cond) then ... else ...
     """
 
-    __slots__ = ["_cond", "_src1", "_src2"]
 
     def __init__(self, cond, src1, src2):
         """Create an ExprCond
@@ -660,7 +648,7 @@ class ExprCond(Expr):
         return Expr.get_object(cls, (cond, src1, src2))
 
     def __str__(self):
-        return "(%s?(%s,%s))" % (str(self._cond), str(self._src1), str(self._src2))
+        return "(%s?(%s,%s))" % (str(self.__cond), str(self.__src1), str(self.__src2))
 
     def get_r(self, mem_read=False, cst_read=False):
         out_src1 = self.src1.get_r(mem_read, cst_read)
@@ -673,11 +661,11 @@ class ExprCond(Expr):
 
     def _exprhash(self):
         return hash((EXPRCOND, hash(self.cond),
-                     hash(self._src1), hash(self._src2)))
+                     hash(self.__src1), hash(self.__src2)))
 
     def _exprrepr(self):
         return "%s(%r, %r, %r)" % (self.__class__.__name__,
-                                   self._cond, self._src1, self._src2)
+                                   self.__cond, self.__src1, self.__src2)
 
     def __contains__(self, e):
         return (self == e or
@@ -687,28 +675,28 @@ class ExprCond(Expr):
 
     @visit_chk
     def visit(self, cb, tv=None):
-        cond = self._cond.visit(cb, tv)
-        src1 = self._src1.visit(cb, tv)
-        src2 = self._src2.visit(cb, tv)
-        if (cond == self._cond and
-            src1 == self._src1 and
-                src2 == self._src2):
+        cond = self.__cond.visit(cb, tv)
+        src1 = self.__src1.visit(cb, tv)
+        src2 = self.__src2.visit(cb, tv)
+        if (cond == self.__cond and
+            src1 == self.__src1 and
+                src2 == self.__src2):
             return self
         return ExprCond(cond, src1, src2)
 
     def copy(self):
-        return ExprCond(self._cond.copy(),
-                        self._src1.copy(),
-                        self._src2.copy())
+        return ExprCond(self.__cond.copy(),
+                        self.__src1.copy(),
+                        self.__src2.copy())
 
     def depth(self):
-        return max(self._cond.depth(),
-                   self._src1.depth(),
-                   self._src2.depth()) + 1
+        return max(self.__cond.depth(),
+                   self.__src1.depth(),
+                   self.__src2.depth()) + 1
 
     def graph_recursive(self, graph):
         graph.add_node(self)
-        for arg in [self._cond, self._src1, self._src2]:
+        for arg in [self.__cond, self.__src1, self.__src2]:
             arg.graph_recursive(graph)
             graph.add_uniq_edge(self, arg)
 
@@ -722,7 +710,6 @@ class ExprMem(Expr):
      - Memory write
     """
 
-    __slots__ = ["_arg", "_size"]
 
     def __init__(self, arg, size=32):
         """Create an ExprMem
@@ -749,7 +736,7 @@ class ExprMem(Expr):
 
     def get_r(self, mem_read=False, cst_read=False):
         if mem_read:
-            return set(self._arg.get_r(mem_read, cst_read).union(set([self])))
+            return set(self.__arg.get_r(mem_read, cst_read).union(set([self])))
         else:
             return set([self])
 
@@ -757,19 +744,19 @@ class ExprMem(Expr):
         return set([self])  # [memreg]
 
     def _exprhash(self):
-        return hash((EXPRMEM, hash(self._arg), self._size))
+        return hash((EXPRMEM, hash(self.__arg), self.__size))
 
     def _exprrepr(self):
         return "%s(%r, %r)" % (self.__class__.__name__,
-                               self._arg, self._size)
+                               self.__arg, self.__size)
 
     def __contains__(self, expr):
-        return self == expr or self._arg.__contains__(expr)
+        return self == expr or self.__arg.__contains__(expr)
 
     @visit_chk
     def visit(self, cb, tv=None):
-        arg = self._arg.visit(cb, tv)
-        if arg == self._arg:
+        arg = self.__arg.visit(cb, tv)
+        if arg == self.__arg:
             return self
         return ExprMem(arg, self.size)
 
@@ -778,15 +765,15 @@ class ExprMem(Expr):
         return ExprMem(arg, size=self.size)
 
     def is_op_segm(self):
-        return isinstance(self._arg, ExprOp) and self._arg.op == 'segm'
+        return isinstance(self.__arg, ExprOp) and self.__arg.op == 'segm'
 
     def depth(self):
-        return self._arg.depth() + 1
+        return self.__arg.depth() + 1
 
     def graph_recursive(self, graph):
         graph.add_node(self)
-        self._arg.graph_recursive(graph)
-        graph.add_uniq_edge(self, self._arg)
+        self.__arg.graph_recursive(graph)
+        graph.add_uniq_edge(self, self.__arg)
 
 
 class ExprOp(Expr):
@@ -799,7 +786,6 @@ class ExprOp(Expr):
      - parity bit(var1)
     """
 
-    __slots__ = ["_op", "_args"]
 
     def __init__(self, op, *args):
         """Create an ExprOp
@@ -821,7 +807,7 @@ class ExprOp(Expr):
         if not isinstance(op, str):
             raise ValueError("ExprOp: 'op' argument must be a string")
 
-        self.__op, self._args = op, tuple(args)
+        self.__op, self.__args = op, tuple(args)
 
         # Set size for special cases
         if self.__op in [
@@ -858,7 +844,7 @@ class ExprOp(Expr):
                            'double_trunc_to_int_80']:
             sz = 80
         elif self.__op in ['segm']:
-            sz = self._args[1].size
+            sz = self.__args[1].size
         else:
             if None in sizes:
                 sz = None
@@ -877,19 +863,19 @@ class ExprOp(Expr):
 
     def __str__(self):
         if self.is_associative():
-            return '(' + self._op.join([str(arg) for arg in self._args]) + ')'
-        if (self._op.startswith('call_func_') or
-            self._op == 'cpuid' or
-            len(self._args) > 2 or
-                self._op in ['parity', 'segm']):
-            return self._op + '(' + ', '.join([str(arg) for arg in self._args]) + ')'
-        if len(self._args) == 2:
-            return ('(' + str(self._args[0]) +
-                    ' ' + self.op + ' ' + str(self._args[1]) + ')')
+            return '(' + self.__op.join([str(arg) for arg in self.__args]) + ')'
+        if (self.__op.startswith('call_func_') or
+            self.__op == 'cpuid' or
+            len(self.__args) > 2 or
+                self.__op in ['parity', 'segm']):
+            return self.__op + '(' + ', '.join([str(arg) for arg in self.__args]) + ')'
+        if len(self.__args) == 2:
+            return ('(' + str(self.__args[0]) +
+                    ' ' + self.op + ' ' + str(self.__args[1]) + ')')
         else:
             return reduce(lambda x, y: x + ' ' + str(y),
-                          self._args,
-                          '(' + str(self._op)) + ')'
+                          self.__args,
+                          '(' + str(self.__op)) + ')'
 
     def get_r(self, mem_read=False, cst_read=False):
         return reduce(lambda elements, arg:
@@ -899,58 +885,57 @@ class ExprOp(Expr):
         raise ValueError('op cannot be written!', self)
 
     def _exprhash(self):
-        h_hargs = [hash(arg) for arg in self._args]
-        return hash((EXPROP, self._op, tuple(h_hargs)))
+        h_hargs = [hash(arg) for arg in self.__args]
+        return hash((EXPROP, self.__op, tuple(h_hargs)))
 
     def _exprrepr(self):
-        return "%s(%r, %s)" % (self.__class__.__name__, self._op,
-                               ', '.join(repr(arg) for arg in self._args))
+        return "%s(%r, %s)" % (self.__class__.__name__, self.__op,
+                               ', '.join(repr(arg) for arg in self.__args))
 
     def __contains__(self, e):
         if self == e:
             return True
-        for arg in self._args:
+        for arg in self.__args:
             if arg.__contains__(e):
                 return True
         return False
 
     def is_function_call(self):
-        return self._op.startswith('call')
+        return self.__op.startswith('call')
 
     def is_associative(self):
         "Return True iff current operation is associative"
-        return (self._op in ['+', '*', '^', '&', '|'])
+        return (self.__op in ['+', '*', '^', '&', '|'])
 
     def is_commutative(self):
         "Return True iff current operation is commutative"
-        return (self._op in ['+', '*', '^', '&', '|'])
+        return (self.__op in ['+', '*', '^', '&', '|'])
 
     @visit_chk
     def visit(self, cb, tv=None):
-        args = [arg.visit(cb, tv) for arg in self._args]
-        modified = any([arg[0] != arg[1] for arg in zip(self._args, args)])
+        args = [arg.visit(cb, tv) for arg in self.__args]
+        modified = any([arg[0] != arg[1] for arg in zip(self.__args, args)])
         if modified:
-            return ExprOp(self._op, *args)
+            return ExprOp(self.__op, *args)
         return self
 
     def copy(self):
-        args = [arg.copy() for arg in self._args]
-        return ExprOp(self._op, *args)
+        args = [arg.copy() for arg in self.__args]
+        return ExprOp(self.__op, *args)
 
     def depth(self):
-        depth = [arg.depth() for arg in self._args]
+        depth = [arg.depth() for arg in self.__args]
         return max(depth) + 1
 
     def graph_recursive(self, graph):
         graph.add_node(self)
-        for arg in self._args:
+        for arg in self.__args:
             arg.graph_recursive(graph)
             graph.add_uniq_edge(self, arg)
 
 
 class ExprSlice(Expr):
 
-    __slots__ = ["_arg", "_start", "_stop"]
 
     def __init__(self, arg, start, stop):
         super(ExprSlice, self).__init__()
@@ -968,20 +953,20 @@ class ExprSlice(Expr):
         return Expr.get_object(cls, (arg, start, stop))
 
     def __str__(self):
-        return "%s[%d:%d]" % (str(self._arg), self._start, self._stop)
+        return "%s[%d:%d]" % (str(self.__arg), self.__start, self.__stop)
 
     def get_r(self, mem_read=False, cst_read=False):
-        return self._arg.get_r(mem_read, cst_read)
+        return self.__arg.get_r(mem_read, cst_read)
 
     def get_w(self):
-        return self._arg.get_w()
+        return self.__arg.get_w()
 
     def _exprhash(self):
-        return hash((EXPRSLICE, hash(self._arg), self._start, self._stop))
+        return hash((EXPRSLICE, hash(self.__arg), self.__start, self.__stop))
 
     def _exprrepr(self):
-        return "%s(%r, %d, %d)" % (self.__class__.__name__, self._arg,
-                                   self._start, self._stop)
+        return "%s(%r, %d, %d)" % (self.__class__.__name__, self.__arg,
+                                   self.__start, self.__stop)
 
     def __contains__(self, expr):
         if self == expr:
@@ -990,39 +975,39 @@ class ExprSlice(Expr):
 
     @visit_chk
     def visit(self, cb, tv=None):
-        arg = self._arg.visit(cb, tv)
-        if arg == self._arg:
+        arg = self.__arg.visit(cb, tv)
+        if arg == self.__arg:
             return self
-        return ExprSlice(arg, self._start, self._stop)
+        return ExprSlice(arg, self.__start, self.__stop)
 
     def copy(self):
-        return ExprSlice(self._arg.copy(), self._start, self._stop)
+        return ExprSlice(self.__arg.copy(), self.__start, self.__stop)
 
     def depth(self):
-        return self._arg.depth() + 1
+        return self.__arg.depth() + 1
 
     def slice_rest(self):
         "Return the completion of the current slice"
-        size = self._arg.size
-        if self._start >= size or self._stop > size:
+        size = self.__arg.size
+        if self.__start >= size or self.__stop > size:
             raise ValueError('bad slice rest %s %s %s' %
-                             (size, self._start, self._stop))
+                             (size, self.__start, self.__stop))
 
-        if self._start == self._stop:
+        if self.__start == self.__stop:
             return [(0, size)]
 
         rest = []
-        if self._start != 0:
-            rest.append((0, self._start))
-        if self._stop < size:
-            rest.append((self._stop, size))
+        if self.__start != 0:
+            rest.append((0, self.__start))
+        if self.__stop < size:
+            rest.append((self.__stop, size))
 
         return rest
 
     def graph_recursive(self, graph):
         graph.add_node(self)
-        self._arg.graph_recursive(graph)
-        graph.add_uniq_edge(self, self._arg)
+        self.__arg.graph_recursive(graph)
+        graph.add_uniq_edge(self, self.__arg)
 
 
 class ExprCompose(Expr):
@@ -1037,7 +1022,6 @@ class ExprCompose(Expr):
     In the example, salad.size == 3.
     """
 
-    __slots__ = ["_args"]
 
     def __init__(self, args):
         """Create an ExprCompose
@@ -1098,7 +1082,7 @@ class ExprCompose(Expr):
     def __contains__(self, e):
         if self == e:
             return True
-        for arg in self._args:
+        for arg in self.__args:
             if arg == e:
                 return True
             if arg[0].__contains__(e):
@@ -1107,18 +1091,18 @@ class ExprCompose(Expr):
 
     @visit_chk
     def visit(self, cb, tv=None):
-        args = [(arg[0].visit(cb, tv), arg[1], arg[2]) for arg in self._args]
-        modified = any([arg[0] != arg[1] for arg in zip(self._args, args)])
+        args = [(arg[0].visit(cb, tv), arg[1], arg[2]) for arg in self.__args]
+        modified = any([arg[0] != arg[1] for arg in zip(self.__args, args)])
         if modified:
             return ExprCompose(args)
         return self
 
     def copy(self):
-        args = [(arg[0].copy(), arg[1], arg[2]) for arg in self._args]
+        args = [(arg[0].copy(), arg[1], arg[2]) for arg in self.__args]
         return ExprCompose(args)
 
     def depth(self):
-        depth = [arg[0].depth() for arg in self._args]
+        depth = [arg[0].depth() for arg in self.__args]
         return max(depth) + 1
 
     def graph_recursive(self, graph):
diff --git a/miasm2/expression/expression_helper.py b/miasm2/expression/expression_helper.py
index 3b85d720..178ee25f 100644
--- a/miasm2/expression/expression_helper.py
+++ b/miasm2/expression/expression_helper.py
@@ -210,9 +210,6 @@ class Variables_Identifier(object):
     - original expression with variables translated
     """
 
-    # Attribute used to distinguish created variables from original ones
-    is_var_ident = "is_var_ident"
-
     def __init__(self, expr, var_prefix="v"):
         """Set the expression @expr to handle and launch variable identification
         process
@@ -287,13 +284,11 @@ class Variables_Identifier(object):
             for element_done in done:
                 todo.remove(element_done)
 
-    @classmethod
-    def is_var_identifier(cls, expr):
+    def is_var_identifier(self, expr):
         "Return True iff @expr is a variable identifier"
         if not isinstance(expr, m2_expr.ExprId):
             return False
-
-        return expr.is_var_ident
+        return expr in self._vars
 
     def find_variables_rec(self, expr):
         """Recursive method called by find_variable to expand @expr.
@@ -310,7 +305,6 @@ class Variables_Identifier(object):
                 identifier = m2_expr.ExprId("%s%s" % (self.var_prefix,
                                                       self.var_indice.next()),
                                             size = expr.size)
-                identifier.is_var_ident = True
                 self._vars[identifier] = expr
 
             # Recursion stop case
diff --git a/miasm2/ir/analysis.py b/miasm2/ir/analysis.py
index 2aa853f0..70fda11c 100644
--- a/miasm2/ir/analysis.py
+++ b/miasm2/ir/analysis.py
@@ -283,11 +283,8 @@ class ira(ir):
 
     def gen_equations(self):
         for irb in self.blocs.values():
-            symbols_init = {}
-            for r in self.arch.regs.all_regs_ids:
-                x = ExprId(r.name, r.size)
-                x.is_term = True
-                symbols_init[r] = x
+            symbols_init = dict(self.arch.regs.all_regs_ids_init)
+
             sb = symbexec(self, dict(symbols_init))
             sb.emulbloc(irb)
             eqs = []
diff --git a/miasm2/ir/symbexec.py b/miasm2/ir/symbexec.py
index 1dc8dde1..d3c56f70 100644
--- a/miasm2/ir/symbexec.py
+++ b/miasm2/ir/symbexec.py
@@ -3,6 +3,8 @@ from miasm2.expression.modint import int32
 from miasm2.expression.simplifications import expr_simp
 from miasm2.core import asmbloc
 from miasm2.ir.ir import AssignBlock
+from miasm2.core.interval import interval
+
 import logging
 
 
@@ -13,72 +15,82 @@ log.addHandler(console_handler)
 log.setLevel(logging.INFO)
 
 
-class symbols():
+class symbols(object):
 
     def __init__(self, init=None):
         if init is None:
             init = {}
         self.symbols_id = {}
         self.symbols_mem = {}
-        for k, v in init.items():
-            self[k] = v
+        for expr, value in init.items():
+            self[expr] = value
 
-    def __contains__(self, a):
-        if not isinstance(a, m2_expr.ExprMem):
-            return self.symbols_id.__contains__(a)
-        if not self.symbols_mem.__contains__(a.arg):
+    def __contains__(self, expr):
+        if not isinstance(expr, m2_expr.ExprMem):
+            return self.symbols_id.__contains__(expr)
+        if not self.symbols_mem.__contains__(expr.arg):
             return False
-        return self.symbols_mem[a.arg][0].size == a.size
-
-    def __getitem__(self, a):
-        if not isinstance(a, m2_expr.ExprMem):
-            return self.symbols_id.__getitem__(a)
-        if not a.arg in self.symbols_mem:
-            raise KeyError(a)
-        m = self.symbols_mem.__getitem__(a.arg)
-        if m[0].size != a.size:
-            raise KeyError(a)
-        return m[1]
-
-    def __setitem__(self, a, v):
-        if not isinstance(a, m2_expr.ExprMem):
-            self.symbols_id.__setitem__(a, v)
+        return self.symbols_mem[expr.arg][0].size == expr.size
+
+    def __getitem__(self, expr):
+        if not isinstance(expr, m2_expr.ExprMem):
+            return self.symbols_id.__getitem__(expr)
+        if not expr.arg in self.symbols_mem:
+            raise KeyError(expr)
+        mem, value = self.symbols_mem.__getitem__(expr.arg)
+        if mem.size != expr.size:
+            raise KeyError(expr)
+        return value
+
+    def get(self, expr, default=None):
+        if not isinstance(expr, m2_expr.ExprMem):
+            return self.symbols_id.get(expr, default)
+        if not expr.arg in self.symbols_mem:
+            return default
+        mem, value = self.symbols_mem.__getitem__(expr.arg)
+        if mem.size != expr.size:
+            return default
+        return value
+
+    def __setitem__(self, expr, value):
+        if not isinstance(expr, m2_expr.ExprMem):
+            self.symbols_id.__setitem__(expr, value)
             return
-        self.symbols_mem.__setitem__(a.arg, (a, v))
+        assert expr.size == value.size
+        self.symbols_mem.__setitem__(expr.arg, (expr, value))
 
     def __iter__(self):
-        for a in self.symbols_id:
-            yield a
-        for a in self.symbols_mem:
-            yield self.symbols_mem[a][0]
-
-    def __delitem__(self, a):
-        if not isinstance(a, m2_expr.ExprMem):
-            self.symbols_id.__delitem__(a)
+        for expr in self.symbols_id:
+            yield expr
+        for expr in self.symbols_mem:
+            yield self.symbols_mem[expr][0]
+
+    def __delitem__(self, expr):
+        if not isinstance(expr, m2_expr.ExprMem):
+            self.symbols_id.__delitem__(expr)
         else:
-            self.symbols_mem.__delitem__(a.arg)
+            self.symbols_mem.__delitem__(expr.arg)
 
     def items(self):
-        k = self.symbols_id.items() + [x for x in self.symbols_mem.values()]
-        return k
+        return self.symbols_id.items() + [x for x in self.symbols_mem.values()]
 
     def keys(self):
-        k = self.symbols_id.keys() + [x[0] for x in self.symbols_mem.values()]
-        return k
+        return (self.symbols_id.keys() +
+                [x[0] for x in self.symbols_mem.values()])
 
     def copy(self):
-        p = symbols()
-        p.symbols_id = dict(self.symbols_id)
-        p.symbols_mem = dict(self.symbols_mem)
-        return p
+        new_symbols = symbols()
+        new_symbols.symbols_id = dict(self.symbols_id)
+        new_symbols.symbols_mem = dict(self.symbols_mem)
+        return new_symbols
 
     def inject_info(self, info):
-        s = symbols()
-        for k, v in self.items():
-            k = expr_simp(k.replace_expr(info))
-            v = expr_simp(v.replace_expr(info))
-            s[k] = v
-        return s
+        new_symbols = symbols()
+        for expr, value in self.items():
+            expr = expr_simp(expr.replace_expr(info))
+            value = expr_simp(value.replace_expr(info))
+            new_symbols[expr] = value
+        return new_symbols
 
 
 class symbexec(object):
@@ -88,154 +100,152 @@ class symbexec(object):
                  func_write=None,
                  sb_expr_simp=expr_simp):
         self.symbols = symbols()
-        for k, v in known_symbols.items():
-            self.symbols[k] = v
+        for expr, value in known_symbols.items():
+            self.symbols[expr] = value
         self.func_read = func_read
         self.func_write = func_write
         self.ir_arch = ir_arch
         self.expr_simp = sb_expr_simp
 
-    def find_mem_by_addr(self, e):
-        if e in self.symbols.symbols_mem:
-            return self.symbols.symbols_mem[e][0]
+    def find_mem_by_addr(self, expr):
+        """
+        Return memory keys with pointer equal to @expr
+        @expr: address of the searched memory variable
+        """
+        if expr in self.symbols.symbols_mem:
+            return self.symbols.symbols_mem[expr][0]
         return None
 
-    def eval_ExprId(self, e, eval_cache=None):
-        if eval_cache is None:
-            eval_cache = {}
-        if isinstance(e.name, asmbloc.asm_label) and e.name.offset is not None:
-            return m2_expr.ExprInt_from(e, e.name.offset)
-        if not e in self.symbols:
-            # raise ValueError('unknown symbol %s'% e)
-            return e
-        return self.symbols[e]
-
-    def eval_ExprInt(self, e, eval_cache=None):
-        return e
-
-    def eval_ExprMem(self, e, eval_cache=None):
-        if eval_cache is None:
-            eval_cache = {}
-        a_val = self.expr_simp(self.eval_expr(e.arg, eval_cache))
-        if a_val != e.arg:
-            a = self.expr_simp(m2_expr.ExprMem(a_val, size=e.size))
-        else:
-            a = e
-        if a in self.symbols:
-            return self.symbols[a]
-        tmp = None
-        # test if mem lookup is known
-        if a_val in self.symbols.symbols_mem:
-            tmp = self.symbols.symbols_mem[a_val][0]
-        if tmp is None:
-
-            v = self.find_mem_by_addr(a_val)
-            if not v:
-                out = []
-                ov = self.get_mem_overlapping(a, eval_cache)
-                off_base = 0
-                ov.sort()
-                # ov.reverse()
-                for off, x in ov:
-                    # off_base = off * 8
-                    # x_size = self.symbols[x].size
-                    if off >= 0:
-                        m = min(a.size - off * 8, x.size)
-                        ee = m2_expr.ExprSlice(self.symbols[x], 0, m)
-                        ee = self.expr_simp(ee)
-                        out.append((ee, off_base, off_base + m))
-                        off_base += m
-                    else:
-                        m = min(a.size - off * 8, x.size)
-                        ee = m2_expr.ExprSlice(self.symbols[x], -off * 8, m)
-                        ff = self.expr_simp(ee)
-                        new_off_base = off_base + m + off * 8
-                        out.append((ff, off_base, new_off_base))
-                        off_base = new_off_base
-                if out:
-                    missing_slice = self.rest_slice(out, 0, a.size)
-                    for sa, sb in missing_slice:
-                        ptr = self.expr_simp(
-                            a_val + m2_expr.ExprInt_from(a_val, sa / 8)
-                        )
-                        mm = m2_expr.ExprMem(ptr, size=sb - sa)
-                        mm.is_term = True
-                        mm.is_simp = True
-                        out.append((mm, sa, sb))
-                    out.sort(key=lambda x: x[1])
-                    # for e, sa, sb in out:
-                    #    print str(e), sa, sb
-                    ee = m2_expr.ExprSlice(m2_expr.ExprCompose(out), 0, a.size)
-                    ee = self.expr_simp(ee)
-                    return ee
-            if self.func_read and isinstance(a.arg, m2_expr.ExprInt):
-                return self.func_read(a)
+    def get_mem_state(self, expr):
+        """
+        Evaluate the @expr memory in the current state using @cache
+        @expr: the memory key
+        """
+        ptr, size = expr.arg, expr.size
+        ret = self.find_mem_by_addr(ptr)
+        if not ret:
+            out = []
+            overlaps = self.get_mem_overlapping(expr)
+            off_base = 0
+            for off, mem in overlaps:
+                if off >= 0:
+                    new_size = min(size - off * 8, mem.size)
+                    tmp = self.expr_simp(self.symbols[mem][0:new_size])
+                    out.append((tmp, off_base, off_base + new_size))
+                    off_base += new_size
+                else:
+                    new_size = min(size - off * 8, mem.size)
+                    tmp = self.expr_simp(self.symbols[mem][-off * 8:new_size])
+                    new_off_base = off_base + new_size + off * 8
+                    out.append((tmp, off_base, new_off_base))
+                    off_base = new_off_base
+            if out:
+                missing_slice = self.rest_slice(out, 0, size)
+                for slice_start, slice_stop in missing_slice:
+                    ptr = self.expr_simp(ptr + m2_expr.ExprInt(slice_start / 8, ptr.size))
+                    mem = m2_expr.ExprMem(ptr, slice_stop - slice_start)
+                    out.append((mem, slice_start, slice_stop))
+                out.sort(key=lambda x: x[1])
+                tmp = m2_expr.ExprSlice(m2_expr.ExprCompose(out), 0, size)
+                tmp = self.expr_simp(tmp)
+                return tmp
+
+
+            if self.func_read and isinstance(ptr, m2_expr.ExprInt):
+                return self.func_read(expr)
             else:
-                # XXX hack test
-                a.is_term = True
-                return a
+                return expr
         # bigger lookup
-        if a.size > tmp.size:
-            rest = a.size
-            ptr = a_val
+        if size > ret.size:
+            rest = size
+            ptr = ptr
             out = []
             ptr_index = 0
             while rest:
-                v = self.find_mem_by_addr(ptr)
-                if v is None:
-                    # raise ValueError("cannot find %s in mem"%str(ptr))
-                    val = m2_expr.ExprMem(ptr, 8)
-                    v = val
+                mem = self.find_mem_by_addr(ptr)
+                if mem is None:
+                    value = m2_expr.ExprMem(ptr, 8)
+                    mem = value
                     diff_size = 8
-                elif rest >= v.size:
-                    val = self.symbols[v]
-                    diff_size = v.size
+                elif rest >= mem.size:
+                    value = self.symbols[mem]
+                    diff_size = mem.size
                 else:
                     diff_size = rest
-                    val = self.symbols[v][0:diff_size]
-                val = (val, ptr_index, ptr_index + diff_size)
-                out.append(val)
+                    value = self.symbols[mem][0:diff_size]
+                out.append((value, ptr_index, ptr_index + diff_size))
                 ptr_index += diff_size
                 rest -= diff_size
-                ptr = self.expr_simp(
-                    self.eval_expr(
-                        m2_expr.ExprOp('+', ptr,
-                                       m2_expr.ExprInt_from(ptr, v.size / 8)),
-                        eval_cache)
-                )
-            e = self.expr_simp(m2_expr.ExprCompose(out))
-            return e
+                ptr = self.expr_simp(ptr + m2_expr.ExprInt(mem.size / 8, ptr.size))
+            ret = self.expr_simp(m2_expr.ExprCompose(out))
+            return ret
         # part lookup
-        tmp = self.expr_simp(m2_expr.ExprSlice(self.symbols[tmp], 0, a.size))
-        return tmp
-
-    def eval_expr_visit(self, e, eval_cache=None):
-        if eval_cache is None:
-            eval_cache = {}
-        # print 'visit', e, e.is_term
-        if e.is_term:
-            return e
-        if e in eval_cache:
-            return eval_cache[e]
-        c = e.__class__
-        deal_class = {m2_expr.ExprId: self.eval_ExprId,
-                      m2_expr.ExprInt: self.eval_ExprInt,
-                      m2_expr.ExprMem: self.eval_ExprMem,
-                      }
-        # print 'eval', e
-        if c in deal_class:
-            e = deal_class[c](e, eval_cache)
-        # print "ret", e
-        if not (isinstance(e, m2_expr.ExprId) or isinstance(e,
-                                                            m2_expr.ExprInt)):
-            e.is_term = True
-        return e
-
-    def eval_expr(self, e, eval_cache=None):
-        if eval_cache is None:
-            eval_cache = {}
-        r = e.visit(lambda x: self.eval_expr_visit(x, eval_cache))
-        return r
+        ret = self.expr_simp(self.symbols[ret][:size])
+        return ret
+
+
+    def apply_expr_on_state_visit_cache(self, expr, state, cache, level=0):
+        """
+        Deep First evaluate nodes:
+            1. evaluate node's sons
+            2. simplify
+        """
+
+        #print '\t'*level, "Eval:", expr
+        if expr in cache:
+            ret = cache[expr]
+            #print "In cache!", ret
+        elif isinstance(expr, m2_expr.ExprInt):
+            return expr
+        elif isinstance(expr, m2_expr.ExprId):
+            if isinstance(expr.name, asmbloc.asm_label) and expr.name.offset is not None:
+                ret = m2_expr.ExprInt_from(expr, expr.name.offset)
+            else:
+                ret = state.get(expr, expr)
+        elif isinstance(expr, m2_expr.ExprMem):
+            ptr = self.apply_expr_on_state_visit_cache(expr.arg, state, cache, level+1)
+            ret = m2_expr.ExprMem(ptr, expr.size)
+            ret = self.get_mem_state(ret)
+            assert expr.size == ret.size
+        elif isinstance(expr, m2_expr.ExprCond):
+            cond = self.apply_expr_on_state_visit_cache(expr.cond, state, cache, level+1)
+            src1 = self.apply_expr_on_state_visit_cache(expr.src1, state, cache, level+1)
+            src2 = self.apply_expr_on_state_visit_cache(expr.src2, state, cache, level+1)
+            ret = m2_expr.ExprCond(cond, src1, src2)
+        elif isinstance(expr, m2_expr.ExprSlice):
+            arg = self.apply_expr_on_state_visit_cache(expr.arg, state, cache, level+1)
+            ret = m2_expr.ExprSlice(arg, expr.start, expr.stop)
+        elif isinstance(expr, m2_expr.ExprOp):
+            args = []
+            for oarg in expr.args:
+                arg = self.apply_expr_on_state_visit_cache(oarg, state, cache, level+1)
+                assert oarg.size == arg.size
+                args.append(arg)
+            ret = m2_expr.ExprOp(expr.op, *args)
+        elif isinstance(expr, m2_expr.ExprCompose):
+            args = []
+            for (arg, start, stop) in expr.args:
+                arg = self.apply_expr_on_state_visit_cache(arg, state, cache, level+1)
+                args.append((arg, start, stop))
+            ret = m2_expr.ExprCompose(args)
+        else:
+            raise TypeError("Unknown expr type")
+        #print '\t'*level, "Result", ret
+        ret = self.expr_simp(ret)
+        #print '\t'*level, "Result simpl", ret
+
+        assert expr.size == ret.size
+        cache[expr] = ret
+        return ret
+
+    def apply_expr_on_state(self, expr, cache):
+        if cache is None:
+            cache = {}
+        ret = self.apply_expr_on_state_visit_cache(expr, self.symbols, cache)
+        return ret
+
+    def eval_expr(self, expr, eval_cache=None):
+        return self.apply_expr_on_state(expr, eval_cache)
 
     def modified_regs(self, init_state=None):
         if init_state is None:
@@ -250,121 +260,111 @@ class symbexec(object):
             yield i
 
     def modified_mems(self, init_state=None):
+        if init_state is None:
+            init_state = self.ir_arch.arch.regs.regs_init
         mems = self.symbols.symbols_mem.values()
         mems.sort()
-        for m, _ in mems:
-            yield m
+        for mem, _ in mems:
+            if mem in init_state and \
+                    mem in self.symbols.symbols_mem and \
+                    self.symbols.symbols_mem[mem] == init_state[mem]:
+                continue
+            yield mem
 
     def modified(self, init_state=None):
-        for r in self.modified_regs(init_state):
-            yield r
-        for m in self.modified_mems(init_state):
-            yield m
+        for reg in self.modified_regs(init_state):
+            yield reg
+        for mem in self.modified_mems(init_state):
+            yield mem
 
     def dump_id(self):
+        """
+        Dump modififed registers symbols only
+        """
         ids = self.symbols.symbols_id.keys()
         ids.sort()
-        for i in ids:
-            if i in self.ir_arch.arch.regs.regs_init and \
-                    i in self.symbols.symbols_id and \
-                    self.symbols.symbols_id[i] == self.ir_arch.arch.regs.regs_init[i]:
+        for expr in ids:
+            if (expr in self.ir_arch.arch.regs.regs_init and
+                expr in self.symbols.symbols_id and
+                self.symbols.symbols_id[expr] == self.ir_arch.arch.regs.regs_init[expr]):
                 continue
-            print i, self.symbols.symbols_id[i]
+            print expr, "=", self.symbols.symbols_id[expr]
 
     def dump_mem(self):
+        """
+        Dump modififed memory symbols
+        """
         mems = self.symbols.symbols_mem.values()
         mems.sort()
-        for m, v in mems:
-            print m, v
+        for mem, value in mems:
+            print mem, value
 
     def rest_slice(self, slices, start, stop):
-        o = []
+        """
+        Return the complementary slices of @slices in the range @start, @stop
+        @slices: base slices
+        @start, @stop: interval range
+        """
+        out = []
         last = start
-        for _, a, b in slices:
-            if a == last:
-                last = b
+        for _, slice_start, slice_stop in slices:
+            if slice_start == last:
+                last = slice_stop
                 continue
-            o.append((last, a))
-            last = b
+            out.append((last, slice_start))
+            last = slice_stop
         if last != stop:
-            o.append((b, stop))
-        return o
-
-    def substract_mems(self, a, b):
-        ex = b.arg - a.arg
-        ex = self.expr_simp(self.eval_expr(ex, {}))
-        if not isinstance(ex, m2_expr.ExprInt):
-            return None
-        ptr_diff = int(int32(ex.arg))
-        out = []
-        if ptr_diff < 0:
-            #    [a     ]
-            #[b      ]XXX
-            sub_size = b.size + ptr_diff * 8
-            if sub_size >= a.size:
-                pass
-            else:
-                ex = m2_expr.ExprOp('+', a.arg,
-                                    m2_expr.ExprInt_from(a.arg, sub_size / 8))
-                ex = self.expr_simp(self.eval_expr(ex, {}))
+            out.append((slice_stop, stop))
+        return out
 
-                rest_ptr = ex
-                rest_size = a.size - sub_size
+    def substract_mems(self, arg1, arg2):
+        """
+        Return the remaining memory areas of @arg1 - @arg2
+        @arg1, @arg2: ExprMem
+        """
 
-                val = self.symbols[a][sub_size:a.size]
-                out = [(m2_expr.ExprMem(rest_ptr, rest_size), val)]
-        else:
-            #[a         ]
-            # XXXX[b   ]YY
+        ptr_diff = self.expr_simp(arg2.arg - arg1.arg)
+        ptr_diff = int(int32(ptr_diff.arg))
 
-            #[a     ]
-            # XXXX[b     ]
+        zone1 = interval([(0, arg1.size/8-1)])
+        zone2 = interval([(ptr_diff, ptr_diff + arg2.size/8-1)])
+        zones = zone1 - zone2
+
+        out = []
+        for start, stop in zones:
+            ptr = arg1.arg + m2_expr.ExprInt(start, arg1.arg.size)
+            ptr = self.expr_simp(ptr)
+            value = self.expr_simp(self.symbols[arg1][start*8:(stop+1)*8])
+            mem = m2_expr.ExprMem(ptr, (stop - start + 1)*8)
+            assert mem.size == value.size
+            out.append((mem, value))
 
-            out = []
-            # part X
-            if ptr_diff > 0:
-                val = self.symbols[a][0:ptr_diff * 8]
-                out.append((m2_expr.ExprMem(a.arg, ptr_diff * 8), val))
-            # part Y
-            if ptr_diff * 8 + b.size < a.size:
-
-                ex = m2_expr.ExprOp('+', b.arg,
-                                    m2_expr.ExprInt_from(b.arg, b.size / 8))
-                ex = self.expr_simp(self.eval_expr(ex, {}))
-
-                rest_ptr = ex
-                rest_size = a.size - (ptr_diff * 8 + b.size)
-                val = self.symbols[a][ptr_diff * 8 + b.size:a.size]
-                out.append((m2_expr.ExprMem(ex, val.size), val))
         return out
-    # give mem stored overlapping requested mem ptr
-    def get_mem_overlapping(self, e, eval_cache=None):
-        if eval_cache is None:
-            eval_cache = {}
-        if not isinstance(e, m2_expr.ExprMem):
-            raise ValueError('mem overlap bad arg')
-        ov = []
-        # suppose max mem size is 64 bytes, compute all reachable addresses
-        to_test = []
-        base_ptr = self.expr_simp(e.arg)
-        for i in xrange(-7, e.size / 8):
-            ex = self.expr_simp(
-                self.eval_expr(base_ptr + m2_expr.ExprInt_from(e.arg, i),
-                               eval_cache))
-            to_test.append((i, ex))
-
-        for i, x in to_test:
-            if not x in self.symbols.symbols_mem:
+
+    def get_mem_overlapping(self, expr):
+        """
+        Gives mem stored overlapping memory in @expr
+        Hypothesis: Max mem size is 64 bytes, compute all reachable addresses
+        @expr: target memory
+        """
+
+        overlaps = []
+        base_ptr = self.expr_simp(expr.arg)
+        for i in xrange(-7, expr.size / 8):
+            new_ptr = base_ptr + m2_expr.ExprInt(i, expr.arg.size)
+            new_ptr = self.expr_simp(new_ptr)
+
+            mem, origin = self.symbols.symbols_mem.get(new_ptr, (None, None))
+            if mem is None:
                 continue
-            ex = self.expr_simp(self.eval_expr(e.arg - x, eval_cache))
-            if not isinstance(ex, m2_expr.ExprInt):
-                raise ValueError('ex is not ExprInt')
-            ptr_diff = int32(ex.arg)
-            if ptr_diff >= self.symbols.symbols_mem[x][1].size / 8:
-                # print "too long!"
+
+            ptr_diff = -i
+            if ptr_diff >= origin.size / 8:
+                # access is too small to overlap the memory target
                 continue
-            ov.append((i, self.symbols.symbols_mem[x][0]))
-        return ov
+            overlaps.append((i, mem))
+
+        return overlaps
 
     def eval_ir_expr(self, assignblk):
         """
@@ -372,16 +372,14 @@ class symbexec(object):
         @assignblk: AssignBlock instance
         """
         pool_out = {}
-
-        eval_cache = dict(self.symbols.items())
+        eval_cache = {}
 
         for dst, src in assignblk.iteritems():
             src = self.eval_expr(src, eval_cache)
             if isinstance(dst, m2_expr.ExprMem):
-                a = self.eval_expr(dst.arg, eval_cache)
-                a = self.expr_simp(a)
+                ptr = self.eval_expr(dst.arg, eval_cache)
                 # test if mem lookup is known
-                tmp = m2_expr.ExprMem(a, dst.size)
+                tmp = m2_expr.ExprMem(ptr, dst.size)
                 pool_out[tmp] = src
 
             elif isinstance(dst, m2_expr.ExprId):
@@ -398,18 +396,18 @@ class symbexec(object):
         """
         mem_dst = []
         src_dst = self.eval_ir_expr(assignblk)
-        eval_cache = dict(self.symbols.items())
         for dst, src in src_dst:
             if isinstance(dst, m2_expr.ExprMem):
-                mem_overlap = self.get_mem_overlapping(dst, eval_cache)
+                mem_overlap = self.get_mem_overlapping(dst)
                 for _, base in mem_overlap:
                     diff_mem = self.substract_mems(base, dst)
                     del self.symbols[base]
                     for new_mem, new_val in diff_mem:
-                        new_val.is_term = True
                         self.symbols[new_mem] = new_val
             src_o = self.expr_simp(src)
             self.symbols[dst] = src_o
+            if dst == src_o:
+                del self.symbols[dst]
             if isinstance(dst, m2_expr.ExprMem):
                 if self.func_write and isinstance(dst.arg, m2_expr.ExprInt):
                     self.func_write(self, dst, src_o)
@@ -424,51 +422,52 @@ class symbexec(object):
         @step: display intermediate steps
         """
         for assignblk in irb.irs:
-            self.eval_ir(assignblk)
             if step:
+                print 'Assignblk:'
+                print assignblk
                 print '_' * 80
+            self.eval_ir(assignblk)
+            if step:
                 self.dump_id()
-        eval_cache = dict(self.symbols.items())
-        return self.eval_expr(self.ir_arch.IRDst, eval_cache)
+                self.dump_mem()
+                print '_' * 80
+        return self.eval_expr(self.ir_arch.IRDst)
 
-    def emul_ir_bloc(self, myir, ad, step=False):
-        b = myir.get_bloc(ad)
-        if b is not None:
-            ad = self.emulbloc(b, step=step)
-        return ad
+    def emul_ir_bloc(self, myir, addr, step=False):
+        irblock = myir.get_bloc(addr)
+        if irblock is not None:
+            addr = self.emulbloc(irblock, step=step)
+        return addr
 
-    def emul_ir_blocs(self, myir, ad, lbl_stop=None, step=False):
+    def emul_ir_blocs(self, myir, addr, lbl_stop=None, step=False):
         while True:
-            b = myir.get_bloc(ad)
-            if b is None:
+            irblock = myir.get_bloc(addr)
+            if irblock is None:
                 break
-            if b.label == lbl_stop:
+            if irblock.label == lbl_stop:
                 break
-            ad = self.emulbloc(b, step=step)
-        return ad
-
-    def del_mem_above_stack(self, sp):
-        sp_val = self.symbols[sp]
-        for mem_ad, (mem, _) in self.symbols.symbols_mem.items():
-            # print mem_ad, sp_val
-            diff = self.eval_expr(mem_ad - sp_val, {})
-            diff = expr_simp(diff)
+            addr = self.emulbloc(irblock, step=step)
+        return addr
+
+    def del_mem_above_stack(self, stack_ptr):
+        stack_ptr = self.eval_expr(stack_ptr)
+        for mem_addr, (mem, _) in self.symbols.symbols_mem.items():
+            diff = self.expr_simp(mem_addr - stack_ptr)
             if not isinstance(diff, m2_expr.ExprInt):
                 continue
-            m = expr_simp(diff.msb())
-            if m.arg == 1:
+            sign_bit = self.expr_simp(diff.msb())
+            if sign_bit.arg == 1:
                 del self.symbols[mem]
 
     def apply_expr(self, expr):
         """Evaluate @expr and apply side effect if needed (ie. if expr is an
         assignment). Return the evaluated value"""
 
-        # Eval expression
-        to_eval = expr.src if isinstance(expr, m2_expr.ExprAff) else expr
-        ret = self.expr_simp(self.eval_expr(to_eval))
-
         # Update value if needed
         if isinstance(expr, m2_expr.ExprAff):
-            self.eval_ir(AssignBlock([m2_expr.ExprAff(expr.dst, ret)]))
+            ret = self.eval_expr(expr.src)
+            self.eval_ir(AssignBlock([expr]))
+        else:
+            ret = self.eval_expr(expr)
 
         return ret
diff --git a/test/ir/symbexec.py b/test/ir/symbexec.py
index 9165fccb..19cc47db 100644
--- a/test/ir/symbexec.py
+++ b/test/ir/symbexec.py
@@ -21,7 +21,7 @@ class TestSymbExec(unittest.TestCase):
         addr40 = ExprInt32(40)
         addr50 = ExprInt32(50)
         mem0 = ExprMem(addr0)
-        mem1 = ExprMem(addr1)
+        mem1 = ExprMem(addr1, 8)
         mem8 = ExprMem(addr8)
         mem9 = ExprMem(addr9)
         mem20 = ExprMem(addr20)
@@ -34,22 +34,24 @@ class TestSymbExec(unittest.TestCase):
         id_a = ExprId('a')
         id_eax = ExprId('eax_init')
 
-        e = symbexec(
-            ir_x86_32(), {mem0: id_x, mem1: id_y, mem9: id_x, mem40w: id_x, mem50v: id_y, id_a: addr0, id_eax: addr0})
+        e = symbexec(ir_x86_32(),
+                     {mem0: id_x, mem1: id_y, mem9: id_x,
+                      mem40w: id_x[:16], mem50v: id_y,
+                      id_a: addr0, id_eax: addr0})
         self.assertEqual(e.find_mem_by_addr(addr0), mem0)
         self.assertEqual(e.find_mem_by_addr(addrX), None)
-        self.assertEqual(e.eval_ExprMem(ExprMem(addr1 - addr1)), id_x)
-        self.assertEqual(e.eval_ExprMem(ExprMem(addr1,  8)),     id_y)
-        self.assertEqual(e.eval_ExprMem(ExprMem(addr1 + addr1)), ExprCompose(
+        self.assertEqual(e.eval_expr(ExprMem(addr1 - addr1)), id_x)
+        self.assertEqual(e.eval_expr(ExprMem(addr1, 8)), id_y)
+        self.assertEqual(e.eval_expr(ExprMem(addr1 + addr1)), ExprCompose(
             [(id_x[16:32], 0, 16), (ExprMem(ExprInt32(4), 16), 16, 32)]))
-        self.assertEqual(e.eval_ExprMem(mem8),                   ExprCompose(
+        self.assertEqual(e.eval_expr(mem8), ExprCompose(
             [(id_x[0:24], 0, 24), (ExprMem(ExprInt32(11), 8), 24, 32)]))
-        self.assertEqual(e.eval_ExprMem(mem40v),                 id_x[:8])
-        self.assertEqual(e.eval_ExprMem(mem50w),                 ExprCompose(
+        self.assertEqual(e.eval_expr(mem40v), id_x[:8])
+        self.assertEqual(e.eval_expr(mem50w), ExprCompose(
             [(id_y, 0, 8), (ExprMem(ExprInt32(51), 8), 8, 16)]))
-        self.assertEqual(e.eval_ExprMem(mem20), mem20)
+        self.assertEqual(e.eval_expr(mem20), mem20)
         e.func_read = lambda x: x
-        self.assertEqual(e.eval_ExprMem(mem20), mem20)
+        self.assertEqual(e.eval_expr(mem20), mem20)
         self.assertEqual(set(e.modified()), set(e.symbols))
         self.assertRaises(
             KeyError, e.symbols.__getitem__, ExprMem(ExprInt32(100)))