about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorFabrice Desclaux <fabrice.desclaux@cea.fr>2020-04-03 14:47:55 +0200
committerFabrice Desclaux <fabrice.desclaux@cea.fr>2020-04-03 15:07:36 +0200
commit3644ef26b43014dccf3937769d644202a78c218b (patch)
treef83bb9bf25bbe346f2b0a834e4a5da7d9e535dca
parente47d3f973bae44a504b8f8dc9df3b32ea6298178 (diff)
downloadmiasm-3644ef26b43014dccf3937769d644202a78c218b.tar.gz
miasm-3644ef26b43014dccf3937769d644202a78c218b.zip
Fix int(expr)
-rw-r--r--miasm/analysis/data_flow.py12
-rw-r--r--miasm/analysis/depgraph.py6
-rw-r--r--miasm/analysis/dse.py10
-rw-r--r--miasm/arch/aarch64/arch.py4
-rw-r--r--miasm/arch/arm/arch.py35
-rw-r--r--miasm/arch/arm/sem.py1
-rw-r--r--miasm/arch/mep/arch.py40
-rw-r--r--miasm/arch/mep/sem.py6
-rw-r--r--miasm/arch/mips32/arch.py18
-rw-r--r--miasm/arch/ppc/sem.py20
-rw-r--r--miasm/arch/x86/arch.py10
-rw-r--r--miasm/expression/expression.py17
-rw-r--r--miasm/expression/simplifications_common.py50
-rw-r--r--miasm/ir/translators/z3_ir.py2
-rw-r--r--test/analysis/depgraph.py2
15 files changed, 125 insertions, 108 deletions
diff --git a/miasm/analysis/data_flow.py b/miasm/analysis/data_flow.py
index 6395fa8c..5202fbd9 100644
--- a/miasm/analysis/data_flow.py
+++ b/miasm/analysis/data_flow.py
@@ -6,8 +6,8 @@ from future.utils import viewitems, viewvalues
 from miasm.core.utils import encode_hex
 from miasm.core.graph import DiGraph
 from miasm.ir.ir import AssignBlock, IRBlock
-from miasm.expression.expression import ExprLoc, ExprMem, ExprSlice, ExprId, \
-    ExprInt, ExprAssign, ExprOp, ExprCompose, ExprCond, ExprWalk
+from miasm.expression.expression import ExprLoc, ExprMem, ExprId, ExprInt,\
+    ExprAssign, ExprOp, ExprWalk, is_function_call
 from miasm.expression.simplifications import expr_simp
 from miasm.core.interval import interval
 from miasm.expression.expression_helper import possible_values
@@ -223,7 +223,7 @@ class DeadRemoval(object):
                 lval.is_mem() or
                 self.ir_arch.IRDst == lval or
                 lval.is_id("exception_flags") or
-                rval.is_function_call()
+                is_function_call(rval)
         ):
             return True
         return False
@@ -760,7 +760,7 @@ class PropagateThroughExprId(object):
         """
         for assignblk in assignblks:
             for dst, src in viewitems(assignblk):
-                if src.is_function_call():
+                if is_function_call(src):
                     return True
                 if dst.is_mem():
                     return True
@@ -857,7 +857,7 @@ class PropagateThroughExprId(object):
             src = defuse.get_node_target(node)
             if max_expr_depth is not None and len(str(src)) > max_expr_depth:
                 continue
-            if src.is_function_call():
+            if is_function_call(src):
                 continue
             if node.var.is_mem():
                 continue
@@ -938,7 +938,7 @@ class PropagateExprIntThroughExprId(PropagateThroughExprId):
             src = defuse.get_node_target(node)
             if not src.is_int():
                 continue
-            if src.is_function_call():
+            if is_function_call(src):
                 continue
             if node.var.is_mem():
                 continue
diff --git a/miasm/analysis/depgraph.py b/miasm/analysis/depgraph.py
index b0d13318..964dcef4 100644
--- a/miasm/analysis/depgraph.py
+++ b/miasm/analysis/depgraph.py
@@ -5,7 +5,7 @@ from functools import total_ordering
 from future.utils import viewitems
 
 from miasm.expression.expression import ExprInt, ExprLoc, ExprAssign, \
-    ExprWalk
+    ExprWalk, canonize_to_exprloc
 from miasm.core.graph import DiGraph
 from miasm.core.locationdb import LocationDB
 from miasm.expression.simplifications import expr_simp_explicit
@@ -334,10 +334,10 @@ class DependencyResultImplicit(DependencyResult):
         generated loc_keys
         """
         out = []
-        expected = self._ircfg.loc_db.canonize_to_exprloc(expected)
+        expected = canonize_to_exprloc(self._ircfg.loc_db, expected)
         expected_is_loc_key = expected.is_loc()
         for consval in possible_values(expr):
-            value = self._ircfg.loc_db.canonize_to_exprloc(consval.value)
+            value = canonize_to_exprloc(self._ircfg.loc_db, consval.value)
             if expected_is_loc_key and value != expected:
                 continue
             if not expected_is_loc_key and value.is_loc_key():
diff --git a/miasm/analysis/dse.py b/miasm/analysis/dse.py
index ada3c4bd..ec76e60b 100644
--- a/miasm/analysis/dse.py
+++ b/miasm/analysis/dse.py
@@ -59,7 +59,7 @@ from future.utils import viewitems
 
 from miasm.core.utils import encode_hex, force_bytes
 from miasm.expression.expression import ExprMem, ExprInt, ExprCompose, \
-    ExprAssign, ExprId, ExprLoc, LocKey
+    ExprAssign, ExprId, ExprLoc, LocKey, canonize_to_exprloc
 from miasm.core.bin_stream import bin_stream_vm
 from miasm.jitter.emulatedsymbexec import EmulatedSymbExec
 from miasm.expression.expression_helper import possible_values
@@ -633,19 +633,17 @@ class DSEPathConstraint(DSEEngine):
             self.cur_solver.add(self.z3_trans.from_expr(cons))
 
     def handle(self, cur_addr):
-        cur_addr = self.ir_arch.loc_db.canonize_to_exprloc(cur_addr)
+        cur_addr = canonize_to_exprloc(self.ir_arch.loc_db, cur_addr)
         symb_pc = self.eval_expr(self.ir_arch.IRDst)
         possibilities = possible_values(symb_pc)
         cur_path_constraint = set() # path_constraint for the concrete path
         if len(possibilities) == 1:
             dst = next(iter(possibilities)).value
-            dst = self.ir_arch.loc_db.canonize_to_exprloc(dst)
+            dst = canonize_to_exprloc(self.ir_arch.loc_db, dst)
             assert dst == cur_addr
         else:
             for possibility in possibilities:
-                target_addr = self.ir_arch.loc_db.canonize_to_exprloc(
-                    possibility.value
-                )
+                target_addr = canonize_to_exprloc(self.ir_arch.loc_db, possibility.value)
                 path_constraint = set() # Set of ExprAssign for the possible path
 
                 # Get constraint associated to the possible path
diff --git a/miasm/arch/aarch64/arch.py b/miasm/arch/aarch64/arch.py
index 464d7eff..768f1b03 100644
--- a/miasm/arch/aarch64/arch.py
+++ b/miasm/arch/aarch64/arch.py
@@ -375,7 +375,7 @@ class instruction_aarch64(instruction):
         expr = self.args[index]
         if not expr.is_int():
             return
-        addr = (int(expr) + self.offset) & 0xFFFFFFFFFFFFFFFF
+        addr = (int(expr) + self.offset) & int(expr.mask)
         loc_key = loc_db.get_or_create_offset_location(addr)
         self.args[index] = m2_expr.ExprLoc(loc_key, expr.size)
 
@@ -403,7 +403,7 @@ class instruction_aarch64(instruction):
         if not isinstance(e, m2_expr.ExprInt):
             log.debug('dyn dst %r', e)
             return
-        off = (int(e) + 0x10000000000000000 - self.offset) & 0xFFFFFFFFFFFFFFFF
+        off = (int(e) - self.offset) & int(e.mask)
         if int(off % 4):
             raise ValueError('strange offset! %r' % off)
         self.args[index] = m2_expr.ExprInt(int(off), 64)
diff --git a/miasm/arch/arm/arch.py b/miasm/arch/arm/arch.py
index 4aac13c6..fbccd329 100644
--- a/miasm/arch/arm/arch.py
+++ b/miasm/arch/arm/arch.py
@@ -413,10 +413,10 @@ class instruction_arm(instruction):
 
         if isinstance(expr, ExprOp) and expr.op == 'postinc':
             o = '[%s]' % r
-            if s and not (isinstance(s, ExprInt) and s.arg == 0):
+            if s and not (isinstance(s, ExprInt) and int(s) == 0):
                 o += ', %s' % s
         else:
-            if s and not (isinstance(s, ExprInt) and s.arg == 0):
+            if s and not (isinstance(s, ExprInt) and int(s) == 0):
                 o = '[%s, %s]' % (r, s)
             else:
                 o = '[%s]' % (r)
@@ -437,9 +437,9 @@ class instruction_arm(instruction):
         if not isinstance(expr, ExprInt):
             return
         if self.name == 'BLX':
-            addr = (expr.arg + self.offset) & 0xFFFFFFFF
+            addr = (int(expr) + self.offset) & int(expr.mask)
         else:
-            addr = (expr.arg + self.offset) & 0xFFFFFFFF
+            addr = (int(expr) + self.offset) & int(expr.mask)
         loc_key = loc_db.get_or_create_offset_location(addr)
         self.args[0] = ExprLoc(loc_key, expr.size)
 
@@ -481,7 +481,7 @@ class instruction_arm(instruction):
         if not isinstance(e, ExprInt):
             log.debug('dyn dst %r', e)
             return
-        off = (e.arg + 0x100000000 - self.offset) & 0xFFFFFFFF
+        off = (int(e) - self.offset) & int(e.mask)
         if int(off % 4):
             raise ValueError('strange offset! %r' % off)
         self.args[0] = ExprInt(off, 32)
@@ -514,15 +514,15 @@ class instruction_armt(instruction_arm):
         if not isinstance(expr, ExprInt):
             return
         if self.name == 'BLX':
-            addr = expr.arg + (self.offset & 0xfffffffc)
+            addr = (int(expr) + (self.offset & 0xfffffffc)) & int(expr.mask)
         elif self.name == 'BL':
-            addr = (expr.arg + self.offset) & 0xFFFFFFFF
+            addr = (int(expr) + self.offset) & int(expr.mask)
         elif self.name.startswith('BP'):
-            addr = (expr.arg + self.offset) & 0xFFFFFFFF
+            addr = (int(expr) + self.offset) & int(expr.mask)
         elif self.name.startswith('CB'):
-            addr = (expr.arg + self.offset + self.l + 2) & 0xFFFFFFFF
+            addr = (int(expr) + self.offset + self.l + 2) & int(expr.mask)
         else:
-            addr = (expr.arg + self.offset) & 0xFFFFFFFF
+            addr = (int(expr) + self.offset) & int(expr.mask)
 
         loc_key = loc_db.get_or_create_offset_location(addr)
         dst = ExprLoc(loc_key, expr.size)
@@ -564,7 +564,7 @@ class instruction_armt(instruction_arm):
         # The first +2 is to compensate instruction len, but strangely, 32 bits
         # thumb2 instructions len is 2... For the second +2, didn't find it in
         # the doc.
-        off = (e.arg + 0x100000000 - self.offset) & 0xFFFFFFFF
+        off = (int(e) - self.offset) & int(e.mask)
         if int(off % 2):
             raise ValueError('strange offset! %r' % off)
         self.args[0] = ExprInt(off, 32)
@@ -798,6 +798,9 @@ class arm_arg(m_arg):
             args = [self.asm_ast_to_expr(tmp, loc_db) for tmp in arg.args]
             if None in args:
                 return None
+            if arg.op == "-":
+                assert len(args) == 2
+                return args[0] - args[1]
             return ExprOp(arg.op, *args)
         if isinstance(arg, AstInt):
             return ExprInt(arg.value, 32)
@@ -1345,7 +1348,7 @@ class arm_offs_blx(arm_imm):
         if not isinstance(self.expr, ExprInt):
             return False
         # Remove pipeline offset
-        v = int(self.expr.arg - 8)
+        v = (int(self.expr) - 8) & int(self.expr.mask)
         if v & 0x80000000:
             v &= (1 << 26) - 1
         self.parent.lowb.value = (v >> 1) & 1
@@ -2738,7 +2741,7 @@ class armt2_imm10l(arm_imm):
     def encode(self):
         if not isinstance(self.expr, ExprInt):
             return False
-        v = self.expr.arg.arg
+        v = int(self.expr)
         s = 0
         if v & 0x80000000:
             s = 1
@@ -2775,7 +2778,7 @@ class armt2_imm11l(arm_imm):
     def encode(self):
         if not isinstance(self.expr, ExprInt):
             return False
-        v = self.expr.arg.arg - 4
+        v = (int(self.expr) - 4) & int(self.expr.mask)
         s = 0
         if v & 0x80000000:
             s = 1
@@ -2813,7 +2816,7 @@ class armt2_imm6_11l(arm_imm):
     def encode(self):
         if not isinstance(self.expr, ExprInt):
             return False
-        v = self.expr.arg.arg - 4
+        v = (int(self.expr) - 4) & int(self.expr.mask)
         s = 0
         if v != sign_ext(v & ((1 << 22) - 1), 21, 32):
             return False
@@ -2881,7 +2884,7 @@ class armt_imm5_1(arm_imm):
     def encode(self):
         if not isinstance(self.expr, ExprInt):
             return False
-        v = self.expr.arg.arg
+        v = int(self.expr)
         if v & 0x1:
             return False
         self.parent.imm1.value = (v >> 6) & 1
diff --git a/miasm/arch/arm/sem.py b/miasm/arch/arm/sem.py
index 981a5060..569a9a23 100644
--- a/miasm/arch/arm/sem.py
+++ b/miasm/arch/arm/sem.py
@@ -762,7 +762,6 @@ def blx(ir, instr, a):
 def st_ld_r(ir, instr, a, a2, b, store=False, size=32, s_ext=False, z_ext=False):
     e = []
     wb = False
-    b = b.copy()
     postinc = False
     b = b.ptr
     if isinstance(b, ExprOp):
diff --git a/miasm/arch/mep/arch.py b/miasm/arch/mep/arch.py
index d06a93ca..073acc57 100644
--- a/miasm/arch/mep/arch.py
+++ b/miasm/arch/mep/arch.py
@@ -4,8 +4,8 @@
 from builtins import range
 from miasm.core.cpu import *
 from miasm.core.utils import Disasm_Exception
-from miasm.expression.expression import Expr, ExprId, ExprInt, ExprLoc, \
-    ExprMem, ExprOp
+from miasm.expression.expression import ExprId, ExprInt, ExprLoc, \
+    ExprMem, ExprOp, is_expr
 from miasm.core.asm_ast import AstId, AstMem
 
 from miasm.arch.mep.regs import *
@@ -35,7 +35,7 @@ def ExprInt2SignedString(expr, pos_fmt="%d", neg_fmt="%d", size=None, offset=0):
     else:
         mask_length = size
     mask = (1 << mask_length) - 1
-    value = int(expr.arg) & mask
+    value = int(expr) & mask
 
     # Return a signed integer if necessary
     if (value >> mask_length - 1) == 1:
@@ -90,7 +90,7 @@ class instruction_mep(instruction):
             return "(%s)" % expr.ptr
 
         elif isinstance(expr, ExprMem) and isinstance(expr.ptr, ExprOp):
-            return "0x%X(%s)" % (expr.ptr.args[1].arg, expr.ptr.args[0])
+            return "0x%X(%s)" % (int(expr.ptr.args[1]), expr.ptr.args[0])
 
         # Raise an exception if the expression type was not processed
         message = "instruction_mep.arg2str(): don't know what \
@@ -111,13 +111,13 @@ class instruction_mep(instruction):
 
         if self.name == "SSARB":
             # The first operand is displayed in decimal, not in hex
-            o += " %d" % self.args[0].arg
+            o += " %d" % int(self.args[0])
             o += self.arg2str(self.args[1])
 
         elif self.name in ["MOV", "ADD"] and isinstance(self.args[1], ExprInt):
             # The second operand is displayed in decimal, not in hex
             o += " " + self.arg2str(self.args[0])
-            o += ", %s" % ExprInt2SignedString(self.args[1].arg)
+            o += ", %s" % ExprInt2SignedString(self.args[1])
 
         elif "CPI" in self.name:
             # The second operand ends with the '+' sign
@@ -131,7 +131,7 @@ class instruction_mep(instruction):
             deref_reg_str = self.arg2str(self.args[1])
             o += ", %s+)" % deref_reg_str[:-1]  # GV: looks ugly
             # The third operand is displayed in decimal, not in hex
-            o += ", %s" % ExprInt2SignedString(self.args[2].arg)
+            o += ", %s" % ExprInt2SignedString(self.args[2])
 
         elif len(self.args) == 2 and self.name in ["SB", "SH", "LBU", "LB", "LH", "LW"] and \
                 isinstance(self.args[1], ExprMem) and isinstance(self.args[1].ptr, ExprOp):  # Major Opcodes #12
@@ -150,13 +150,13 @@ class instruction_mep(instruction):
         elif self.name == "SLL" and isinstance(self.args[1], ExprInt):  # Major Opcodes #6
             # The second operand is displayed in hex, not in decimal
             o += " " + self.arg2str(self.args[0])
-            o += ", 0x%X" % self.args[1].arg
+            o += ", 0x%X" % int(self.args[1])
 
         elif self.name in ["ADD3", "SLT3"] and isinstance(self.args[2], ExprInt):
             o += " %s" % self.arg2str(self.args[0])
             o += ", %s" % self.arg2str(self.args[1])
             # The third operand is displayed in decimal, not in hex
-            o += ", %s" % ExprInt2SignedString(self.args[2].arg, pos_fmt="0x%X")
+            o += ", %s" % ExprInt2SignedString(self.args[2], pos_fmt="0x%X")
 
         elif self.name == "(RI)":
             return o
@@ -166,7 +166,7 @@ class instruction_mep(instruction):
             if self.args:
                 o += " "
             for i, arg in enumerate(self.args):
-                if not isinstance(arg, Expr):
+                if not is_expr(arg):
                     raise ValueError('zarb arg type')
                 x = self.arg2str(arg, pos=i)
                 args.append(x)
@@ -218,7 +218,7 @@ class instruction_mep(instruction):
 
         # Compute the correct address
         num = self.get_dst_num()
-        addr = self.args[num].arg
+        addr = int(self.args[num])
         if not self.name == "JMP":
             addr += self.offset
 
@@ -671,7 +671,7 @@ class mep_deref_reg_offset(mep_arg):
             return False
 
         # Get the integer and check the upper bound
-        v = int(self.expr.ptr.args[1].arg & 0xFFFF)
+        v = int(self.expr.ptr.args[1]) & 0xFFFF
 
         # Encode the values
         self.parent.reg04_deref.value = gpr_exprs.index(self.expr.ptr.args[0])
@@ -845,7 +845,7 @@ class mep_int32_noarg(int32_noarg):
     def encode(self):
         if not isinstance(self.expr, ExprInt):
             return False
-        v = int(self.expr.arg)
+        v = int(self.expr)
         # Note: the following lines were commented on purpose
         #if sign_ext(v & self.lmask, self.l, self.intsize) != v:
         #    return False
@@ -923,7 +923,7 @@ class mep_target24(mep_imm):
             return False
 
         # Get the integer and apply a mask
-        v = int(self.expr.arg) & 0x00FFFFFF
+        v = int(self.expr) & 0x00FFFFFF
 
         # Encode the value into two parts
         self.parent.imm7.value = (v & 0xFF) >> 1
@@ -940,7 +940,7 @@ class mep_target24_signed(mep_target24):
         """
 
         mep_target24.decode(self, v)
-        v = int(self.expr.arg)
+        v = int(self.expr)
         self.expr = ExprInt(sign_ext(v, 24, 32), 32)
 
         return True
@@ -1046,7 +1046,7 @@ class mep_imm7_align4(mep_imm):
             return False
 
         # Get the integer and check the upper bound
-        v = int(self.expr.arg)
+        v = int(self.expr)
         if v > 0x80:
             return False
 
@@ -1129,7 +1129,7 @@ class mep_disp7_align2(mep_imm):
             return False
 
         # Get the integer
-        v = int(self.expr.arg) & self.upper_bound
+        v = int(self.expr) & self.upper_bound
 
         # Encode the value
         self.value = (v >> self.bits_shift) & self.upper_bound
@@ -1161,7 +1161,7 @@ class mep_disp12_align2_signed(mep_disp12_align2):
         """Perform sign extension.
         """
         mep_disp12_align2.decode(self, v)
-        v = int(self.expr.arg)
+        v = int(self.expr)
 
         self.expr = ExprInt(sign_ext(v, 12, 32), 32)
         return True
@@ -1198,7 +1198,7 @@ class mep_imm24(mep_imm):
             return False
 
         # Get the integer and check the upper bound
-        v = int(self.expr.arg)
+        v = int(self.expr)
         if v > 0xFFFFFF:
             return False
 
@@ -1236,7 +1236,7 @@ class mep_abs24(mep_imm):
             return False
 
         # Get the integer and check the upper bound
-        v = int(self.expr.ptr.arg)
+        v = int(self.expr.ptr)
         if v > 0xffffff:
             return False
 
diff --git a/miasm/arch/mep/sem.py b/miasm/arch/mep/sem.py
index 1736b139..c1585d35 100644
--- a/miasm/arch/mep/sem.py
+++ b/miasm/arch/mep/sem.py
@@ -239,7 +239,7 @@ def add3(ir, instr, reg_dst, reg_src, reg_or_imm):
         result = ExprOp("+", reg_src, reg_or_imm)
     else:
         # Rn <- Rm + SignExt(imm16)
-        value = int(reg_or_imm.arg)
+        value = int(reg_or_imm)
         result = ExprOp("+", reg_src, ExprInt(value, 32))
 
     return [ExprAssign(reg_dst, result)], []
@@ -645,7 +645,7 @@ def repeat(rn, disp17):
     # RPB <- pc+4 // Repeat Begin
     RPB = PC + i32(4)
     # RPE <- pc+SignExt((disp17)16..1||0)) // Repeat End
-    RPE = PC + i32(disp17.arg & 0xFFFFFFFE)
+    RPE = PC + i32(int(disp17) & 0xFFFFFFFE)
     # RPC <- Rn
     RPC = rn
     in_erepeat = ExprInt(0, 32)
@@ -660,7 +660,7 @@ def erepeat(disp17):
     # RPB <- pc+4 // Repeat Begin
     RPB = PC + i32(4)
     # RPE <- pc+SignExt((disp17)16..1||1)) (EREPEAT)
-    RPE = PC + i32(disp17.arg + 1)
+    RPE = PC + i32(int(disp17) + 1)
     # RPC <- undefined
     in_erepeat = ExprInt(1, 32)
 
diff --git a/miasm/arch/mips32/arch.py b/miasm/arch/mips32/arch.py
index 09ff0a24..d0403ba0 100644
--- a/miasm/arch/mips32/arch.py
+++ b/miasm/arch/mips32/arch.py
@@ -95,7 +95,7 @@ class instruction_mips32(cpu.instruction):
 
     def dstflow2label(self, loc_db):
         if self.name in ["J", 'JAL']:
-            expr = self.args[0].arg
+            expr = int(self.args[0])
             addr = (self.offset & (0xFFFFFFFF ^ ((1<< 28)-1))) + expr
             loc_key = loc_db.get_or_create_offset_location(addr)
             self.args[0] = ExprLoc(loc_key, expr.size)
@@ -106,7 +106,7 @@ class instruction_mips32(cpu.instruction):
 
         if not isinstance(expr, ExprInt):
             return
-        addr = expr.arg + self.offset
+        addr = int(expr) + self.offset
         loc_key = loc_db.get_or_create_offset_location(addr)
         self.args[ndx] = ExprLoc(loc_key, expr.size)
 
@@ -157,7 +157,7 @@ class instruction_mips32(cpu.instruction):
             raise ValueError('symbol not resolved %s' % self.l)
         if not isinstance(e, ExprInt):
             return
-        off = e.arg - self.offset
+        off = (int(e) - self.offset) & int(e.mask)
         if int(off % 4):
             raise ValueError('strange offset! %r' % off)
         self.args[ndx] = ExprInt(off, 32)
@@ -312,7 +312,7 @@ class mips32_s16imm_noarg(mips32_imm):
     def encode(self):
         if not isinstance(self.expr, ExprInt):
             return False
-        v = self.expr.arg.arg
+        v = int(self.expr)
         if v & 0x80000000:
             nv = v & ((1 << 16) - 1)
             assert( v == cpu.sign_ext(nv, 16, 32))
@@ -333,7 +333,7 @@ class mips32_soff_noarg(mips32_imm):
         if not isinstance(self.expr, ExprInt):
             return False
         # Remove pipeline offset
-        v = int(self.expr.arg - 4)
+        v = (int(self.expr) - 4) & 0xFFFFFFFF
         if v & 0x80000000:
             nv = v & ((1 << 16+2) - 1)
             assert( v == cpu.sign_ext(nv, 16+2, 32))
@@ -358,7 +358,7 @@ class mips32_instr_index(mips32_imm, mips32_arg):
     def encode(self):
         if not isinstance(self.expr, ExprInt):
             return False
-        v = self.expr.arg.arg
+        v = int(self.expr)
         if v & 3:
             return False
         v>>=2
@@ -377,7 +377,7 @@ class mips32_u16imm(mips32_imm, mips32_arg):
     def encode(self):
         if not isinstance(self.expr, ExprInt):
             return False
-        v = self.expr.arg.arg
+        v = int(self.expr)
         assert(v < (1<<16))
         self.value = v
         return True
@@ -424,7 +424,7 @@ class mips32_esize(mips32_imm, mips32_arg):
     def encode(self):
         if not isinstance(self.expr, ExprInt):
             return False
-        v = self.expr.arg.arg -1
+        v = int(self.expr) -1
         assert(v < (1<<16))
         self.value = v
         return True
@@ -437,7 +437,7 @@ class mips32_eposh(mips32_imm, mips32_arg):
     def encode(self):
         if not isinstance(self.expr, ExprInt):
             return False
-        v = int(self.expr.arg) + int(self.parent.epos.expr) -1
+        v = int(self.expr) + int(self.parent.epos.expr) -1
         self.value = v
         return True
 
diff --git a/miasm/arch/ppc/sem.py b/miasm/arch/ppc/sem.py
index fd6db8f3..cc0be7d7 100644
--- a/miasm/arch/ppc/sem.py
+++ b/miasm/arch/ppc/sem.py
@@ -125,7 +125,7 @@ def mn_do_cntlzw(ir, instr, ra, rs):
     return ret, []
 
 def crbit_to_reg(bit):
-    bit = bit.arg.arg
+    bit = int(bit)
     crid = bit // 4
     bitname = [ 'LT', 'GT', 'EQ', 'SO' ][bit % 4]
     return all_regs_ids_byname["CR%d_%s" % (crid, bitname)]
@@ -298,7 +298,7 @@ def mn_do_load(ir, instr, arg1, arg2, arg3=None):
 
 def mn_do_lmw(ir, instr, rd, src):
     ret = []
-    address = src.arg
+    address = int(src)
     ri = int(rd.name[1:],10)
     i = 0
     while ri <= 31:
@@ -348,7 +348,7 @@ def mn_mfmsr(rd):
     rd = MSR
 
 def mn_mfspr(ir, instr, arg1, arg2):
-    sprid = arg2.arg.arg
+    sprid = int(arg2)
     gprid = int(arg1.name[1:])
     if sprid in spr_dict:
         return [ ExprAssign(arg1, spr_dict[sprid]) ], []
@@ -365,7 +365,7 @@ def mn_mtcrf(ir, instr, crm, rs):
     ret = []
 
     for i in range(8):
-        if crm.arg.arg & (1 << (7 - i)):
+        if int(crm) & (1 << (7 - i)):
             j = (28 - 4 * i) + 3
             for b in ['LT', 'GT', 'EQ', 'SO']:
                 ret.append(ExprAssign(all_regs_ids_byname["CR%d_%s" % (i, b)],
@@ -379,7 +379,7 @@ def mn_mtmsr(ir, instr, rs):
     return [ ExprAssign(MSR, rs) ], []
 
 def mn_mtspr(ir, instr, arg1, arg2):
-    sprid = arg1.arg.arg
+    sprid = int(arg1)
     gprid = int(arg2.name[1:])
     if sprid in spr_dict:
         return [ ExprAssign(spr_dict[sprid], arg2) ], []
@@ -562,7 +562,7 @@ def mn_do_srawi(ir, instr, ra, rs, imm):
     if instr.name[-1] == '.':
         ret += mn_compute_flags(rvalue)
 
-    mask = ExprInt(0xFFFFFFFF >> (32 - imm.arg.arg), 32)
+    mask = ExprInt(0xFFFFFFFF >> (32 - int(imm)), 32)
 
     ret.append(ExprAssign(XER_CA, rs.msb() &
                        ExprCond(rs & mask, ExprInt(1, 1), ExprInt(0, 1))))
@@ -580,7 +580,7 @@ def mn_do_srw(ir, instr, ra, rs, rb):
 
 def mn_do_stmw(ir, instr, rs, dest):
     ret = []
-    address = dest.arg
+    address = int(dest)
     ri = int(rs.name[1:],10)
     i = 0
     while ri <= 31:
@@ -879,7 +879,7 @@ class ir_ppc32b(IntermediateRepresentation):
     def get_ir(self, instr):
         args = instr.args[:]
         if instr.name[0:5] in [ 'ADDIS', 'ORIS', 'XORIS', 'ANDIS' ]:
-            args[2] = ExprInt(args[2].arg << 16, 32)
+            args[2] = ExprInt(int(args[2]) << 16, 32)
         if instr.name[0:3] == 'ADD':
             if instr.name[0:4] == 'ADDZ':
                 last_arg = ExprInt(0, 32)
@@ -920,8 +920,8 @@ class ir_ppc32b(IntermediateRepresentation):
             instr_ir, extra_ir = mn_do_or(self, instr, *args)
         elif instr.name[0:2] == 'RL':
             instr_ir, extra_ir = mn_do_rotate(self, instr, args[0], args[1],
-                                              args[2], args[3].arg.arg,
-                                              args[4].arg.arg)
+                                              args[2], int(args[3]),
+                                              int(args[4]))
         elif instr.name == 'STMW':
             instr_ir, extra_ir = mn_do_stmw(self, instr, *args)
         elif instr.name[0:2] == 'ST':
diff --git a/miasm/arch/x86/arch.py b/miasm/arch/x86/arch.py
index 52ea1663..725f3126 100644
--- a/miasm/arch/x86/arch.py
+++ b/miasm/arch/x86/arch.py
@@ -1706,7 +1706,7 @@ def exprfindmod(e, o=None):
 
 def test_addr_size(ptr, size):
     if isinstance(ptr, ExprInt):
-        return ptr.arg < (1 << size)
+        return int(ptr) < (1 << size)
     else:
         return ptr.size == size
 
@@ -1767,13 +1767,13 @@ def parse_mem(expr, parent, w8, sx=0, xmm=0, mm=0, bnd=0):
             value = ExprInt(int(disp), cast_size)
             if admode < value.size:
                 if signed:
-                    if int(disp.arg) != sign_ext(int(value), admode, disp.size):
+                    if int(disp) != sign_ext(int(value), admode, disp.size):
                         continue
                 else:
-                    if int(disp.arg) != int(value):
+                    if int(disp) != int(value):
                         continue
             else:
-                if int(disp.arg) != sign_ext(int(value), value.size, admode):
+                if int(disp) != sign_ext(int(value), value.size, admode):
                     continue
             x1 = dict(dct_expr)
             x1[f_imm] = (encoding, value)
@@ -2918,7 +2918,7 @@ class bs_rel_off(bs_cond_imm):
         parent_len = len(prefix) * 8 + self.parent.l + self.l
         assert(parent_len % 8 == 0)
 
-        v = int(self.expr.arg) - parent_len // 8
+        v = int(self.expr) - parent_len // 8
         if prefix is None:
             return
         mask = ((1 << self.l) - 1)
diff --git a/miasm/expression/expression.py b/miasm/expression/expression.py
index d6813cec..18fcb77a 100644
--- a/miasm/expression/expression.py
+++ b/miasm/expression/expression.py
@@ -166,6 +166,23 @@ def is_mem_segm(expr):
     """Returns True if is ExprMem and ptr is_op_segm"""
     return expr.is_mem() and is_op_segm(expr.ptr)
 
+def canonize_to_exprloc(locdb, expr):
+    """
+    If expr is ExprInt, return ExprLoc with corresponding loc_key
+    Else, return expr
+
+    @expr: Expr instance
+    """
+    if expr.is_int():
+        loc_key = locdb.get_or_create_offset_location(int(expr))
+        ret = ExprLoc(loc_key, expr.size)
+        return ret
+    return expr
+
+def is_function_call(expr):
+    """Returns true if the considered Expr is a function call
+    """
+    return expr.is_op() and expr.op.startswith('call')
 
 @total_ordering
 class LocKey(object):
diff --git a/miasm/expression/simplifications_common.py b/miasm/expression/simplifications_common.py
index 2b69ed0e..f12ccfcf 100644
--- a/miasm/expression/simplifications_common.py
+++ b/miasm/expression/simplifications_common.py
@@ -54,8 +54,8 @@ def simp_cst_propagation(e_s, expr):
                 else:
                     out = mod_size2uint[int1.size](int(int1) << int(int2))
             elif op_name == 'a>>':
-                tmp1 = mod_size2int[int1.size](int1.arg)
-                tmp2 = mod_size2uint[int2.arg.size](int2.arg)
+                tmp1 = mod_size2int[int1.size](int(int1))
+                tmp2 = mod_size2uint[int2.size](int(int2))
                 if tmp2 > int1.size:
                     is_signed = int(int1) & (1 << (int1.size - 1))
                     if is_signed:
@@ -65,34 +65,34 @@ def simp_cst_propagation(e_s, expr):
                 else:
                     out = mod_size2uint[int1.size](tmp1 >> tmp2)
             elif op_name == '>>>':
-                shifter = int2.arg % int2.size
-                out = (int1.arg >> shifter) | (int1.arg << (int2.size - shifter))
+                shifter = int(int2) % int2.size
+                out = (int(int1) >> shifter) | (int(int1) << (int2.size - shifter))
             elif op_name == '<<<':
-                shifter = int2.arg % int2.size
-                out = (int1.arg << shifter) | (int1.arg >> (int2.size - shifter))
+                shifter = int(int2) % int2.size
+                out = (int(int1) << shifter) | (int(int1) >> (int2.size - shifter))
             elif op_name == '/':
-                out = int1.arg // int2.arg
+                out = int(int1) // int(int2)
             elif op_name == '%':
-                out = int1.arg % int2.arg
+                out = int(int1) % int(int2)
             elif op_name == 'sdiv':
-                assert int2.arg.arg
-                tmp1 = mod_size2int[int1.size](int1.arg)
-                tmp2 = mod_size2int[int2.arg.size](int2.arg)
+                assert int(int2)
+                tmp1 = mod_size2int[int1.size](int(int1))
+                tmp2 = mod_size2int[int2.size](int(int2))
                 out = mod_size2uint[int1.size](tmp1 // tmp2)
             elif op_name == 'smod':
-                assert int2.arg.arg
-                tmp1 = mod_size2int[int1.size](int1.arg)
-                tmp2 = mod_size2int[int2.arg.size](int2.arg)
+                assert int(int2)
+                tmp1 = mod_size2int[int1.size](int(int1))
+                tmp2 = mod_size2int[int2.size](int(int2))
                 out = mod_size2uint[int1.size](tmp1 % tmp2)
             elif op_name == 'umod':
-                assert int2.arg.arg
-                tmp1 = mod_size2uint[int1.size](int1.arg)
-                tmp2 = mod_size2uint[int2.arg.size](int2.arg)
+                assert int(int2)
+                tmp1 = mod_size2uint[int1.size](int(int1))
+                tmp2 = mod_size2uint[int2.size](int(int2))
                 out = mod_size2uint[int1.size](tmp1 % tmp2)
             elif op_name == 'udiv':
-                assert int2.arg.arg
-                tmp1 = mod_size2uint[int1.size](int1.arg)
-                tmp2 = mod_size2uint[int2.arg.size](int2.arg)
+                assert int(int2)
+                tmp1 = mod_size2uint[int1.size](int(int1))
+                tmp2 = mod_size2uint[int2.size](int(int2))
                 out = mod_size2uint[int1.size](tmp1 // tmp2)
 
 
@@ -102,16 +102,16 @@ def simp_cst_propagation(e_s, expr):
     # cnttrailzeros(int) => int
     if op_name == "cnttrailzeros" and args[0].is_int():
         i = 0
-        while args[0].arg & (1 << i) == 0 and i < args[0].size:
+        while int(args[0]) & (1 << i) == 0 and i < args[0].size:
             i += 1
         return ExprInt(i, args[0].size)
 
     # cntleadzeros(int) => int
     if op_name == "cntleadzeros" and args[0].is_int():
-        if args[0].arg == 0:
+        if int(args[0]) == 0:
             return ExprInt(args[0].size, args[0].size)
         i = args[0].size - 1
-        while args[0].arg & (1 << i) == 0:
+        while int(args[0]) & (1 << i) == 0:
             i -= 1
         return ExprInt(expr.size - (i + 1), args[0].size)
 
@@ -649,8 +649,8 @@ def simp_cond(_, expr):
     elif (expr.cond.is_cond() and
           expr.cond.src1.is_int() and
           expr.cond.src2.is_int()):
-        int1 = expr.cond.src1.arg.arg
-        int2 = expr.cond.src2.arg.arg
+        int1 = int(expr.cond.src1)
+        int2 = int(expr.cond.src2)
         if int1 and int2:
             expr = expr.src1
         elif int1 == 0 and int2 == 0:
diff --git a/miasm/ir/translators/z3_ir.py b/miasm/ir/translators/z3_ir.py
index 3452f162..6b706770 100644
--- a/miasm/ir/translators/z3_ir.py
+++ b/miasm/ir/translators/z3_ir.py
@@ -129,7 +129,7 @@ class TranslatorZ3(Translator):
         self.loc_db = loc_db
 
     def from_ExprInt(self, expr):
-        return z3.BitVecVal(expr.arg.arg, expr.size)
+        return z3.BitVecVal(int(expr), expr.size)
 
     def from_ExprId(self, expr):
         return z3.BitVec(str(expr), expr.size)
diff --git a/test/analysis/depgraph.py b/test/analysis/depgraph.py
index 69b93f69..eb6507dc 100644
--- a/test/analysis/depgraph.py
+++ b/test/analysis/depgraph.py
@@ -748,7 +748,7 @@ def flatNode(node):
         if isinstance(node.element, ExprId):
             element = node.element.name
         elif isinstance(node.element, ExprInt):
-            element = int(node.element.arg)
+            element = int(node.element)
         else:
             RuntimeError("Unsupported type '%s'" % type(enode.element))
         names = loc_db.get_location_names(node.loc_key)