diff options
Diffstat (limited to 'miasm2/expression')
| -rw-r--r-- | miasm2/expression/expression.py | 103 | ||||
| -rw-r--r-- | miasm2/expression/expression_helper.py | 2 | ||||
| -rw-r--r-- | miasm2/expression/modint.py | 2 | ||||
| -rw-r--r-- | miasm2/expression/simplifications_common.py | 9 | ||||
| -rw-r--r-- | miasm2/expression/simplifications_cond.py | 10 |
5 files changed, 68 insertions, 58 deletions
diff --git a/miasm2/expression/expression.py b/miasm2/expression/expression.py index e134e503..85471e05 100644 --- a/miasm2/expression/expression.py +++ b/miasm2/expression/expression.py @@ -30,7 +30,8 @@ import itertools from operator import itemgetter -from miasm2.expression.modint import * +from miasm2.expression.modint import mod_size2uint, is_modint, size2mask, \ + define_uint from miasm2.core.graph import DiGraph import warnings @@ -143,10 +144,6 @@ class Expr(object): Expr.args2expr[(cls, args)] = expr return expr - def __new__(cls, *args, **kwargs): - expr = object.__new__(cls, *args, **kwargs) - return expr - def get_is_canon(self): return self in Expr.canon_exprs @@ -187,23 +184,18 @@ class Expr(object): self.__hash = self._exprhash() return self.__hash - def pre_eq(self, other): - """Return True if ids are equal; - False if instances are obviously not equal - None if we cannot simply decide""" - - if id(self) == id(other): + def __eq__(self, other): + if self is other: return True + elif self.use_singleton: + # In case of Singleton, pointer comparison is sufficient + # Avoid computation of hash and repr + return False + if self.__class__ is not other.__class__: return False if hash(self) != hash(other): return False - return None - - def __eq__(self, other): - res = self.pre_eq(other) - if res is not None: - return res return repr(self) == repr(other) def __ne__(self, a): @@ -246,8 +238,7 @@ class Expr(object): return ExprOp("**",self, a) def __invert__(self): - s = self.size - return ExprOp('^', self, ExprInt(mod_size2uint[s](size2mask(s)))) + return ExprOp('^', self, self.mask) def copy(self): "Deep copy of the expression" @@ -398,25 +389,12 @@ class ExprInt(Expr): __slots__ = Expr.__slots__ + ["__arg"] - def __init__(self, num, size=None): + def __init__(self, arg, size): """Create an ExprInt from a modint or num/size - @arg: modint or num - @size: (optionnal) int size""" - + @arg: 'intable' number + @size: int size""" super(ExprInt, self).__init__() - - if is_modint(num): - 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: - if size not in mod_size2uint: - define_uint(size) - self.__arg = mod_size2uint[size](num) - self.__size = self.arg.size - else: - raise ValueError('arg must by modint or (int,size)! %s' % num) + # Work is done in __new__ size = property(lambda self: self.__size) arg = property(lambda self: self.__arg) @@ -427,10 +405,29 @@ class ExprInt(Expr): def __setstate__(self, state): self.__init__(*state) - def __new__(cls, arg, size=None): - if size is None: - size = arg.size - return Expr.get_object(cls, (arg, size)) + def __new__(cls, arg, size): + """Create an ExprInt from a modint or num/size + @arg: 'intable' number + @size: int size""" + + if is_modint(arg): + assert size == arg.size + # Avoid a common blunder + assert not isinstance(arg, ExprInt) + + # Ensure arg is always a moduint + arg = int(arg) + if size not in mod_size2uint: + define_uint(size) + arg = mod_size2uint[size](arg) + + # Get the Singleton instance + expr = Expr.get_object(cls, (arg, size)) + + # Save parameters (__init__ is called with parameters unchanged) + expr.__arg = arg + expr.__size = expr.__arg.size + return expr def __get_int(self): "Return self integer representation" @@ -466,7 +463,7 @@ class ExprInt(Expr): return self def copy(self): - return ExprInt(self.__arg) + return ExprInt(self.__arg, self.__size) def depth(self): return 1 @@ -1321,28 +1318,40 @@ def canonize_expr_list_compose(l): def ExprInt1(i): - return ExprInt(uint1(i)) + warnings.warn('DEPRECATION WARNING: use ExprInt(i, 1) instead of '\ + 'ExprInt1(i))') + return ExprInt(i, 1) def ExprInt8(i): - return ExprInt(uint8(i)) + warnings.warn('DEPRECATION WARNING: use ExprInt(i, 8) instead of '\ + 'ExprInt8(i))') + return ExprInt(i, 8) def ExprInt16(i): - return ExprInt(uint16(i)) + warnings.warn('DEPRECATION WARNING: use ExprInt(i, 16) instead of '\ + 'ExprInt16(i))') + return ExprInt(i, 16) def ExprInt32(i): - return ExprInt(uint32(i)) + warnings.warn('DEPRECATION WARNING: use ExprInt(i, 32) instead of '\ + 'ExprInt32(i))') + return ExprInt(i, 32) def ExprInt64(i): - return ExprInt(uint64(i)) + warnings.warn('DEPRECATION WARNING: use ExprInt(i, 64) instead of '\ + 'ExprInt64(i))') + return ExprInt(i, 64) def ExprInt_from(e, i): "Generate ExprInt with size equal to expression" - return ExprInt(mod_size2uint[e.size](i)) + warnings.warn('DEPRECATION WARNING: use ExprInt(i, expr.size) instead of'\ + 'ExprInt_from(expr, i))') + return ExprInt(i, e.size) def get_expr_ids_visit(e, ids): diff --git a/miasm2/expression/expression_helper.py b/miasm2/expression/expression_helper.py index 36e5f1d5..1e718faa 100644 --- a/miasm2/expression/expression_helper.py +++ b/miasm2/expression/expression_helper.py @@ -521,7 +521,7 @@ class CondConstraintNotZero(CondConstraint): operator = "!=" def to_constraint(self): - cst1, cst2 = m2_expr.ExprInt1(0), m2_expr.ExprInt1(1) + cst1, cst2 = m2_expr.ExprInt(0, 1), m2_expr.ExprInt(1, 1) return m2_expr.ExprAff(cst1, m2_expr.ExprCond(self.expr, cst1, cst2)) diff --git a/miasm2/expression/modint.py b/miasm2/expression/modint.py index b6a0e4ee..51a2620e 100644 --- a/miasm2/expression/modint.py +++ b/miasm2/expression/modint.py @@ -224,7 +224,7 @@ def define_uint(size): return cls def define_common_int(): - "Define common int: ExprInt1, ExprInt2, .." + "Define common int" common_int = xrange(1, 257) for i in common_int: diff --git a/miasm2/expression/simplifications_common.py b/miasm2/expression/simplifications_common.py index 503a0e77..01db7597 100644 --- a/miasm2/expression/simplifications_common.py +++ b/miasm2/expression/simplifications_common.py @@ -3,6 +3,7 @@ # ----------------------------- # +from miasm2.expression.modint import mod_size2int, mod_size2uint from miasm2.expression.expression import * from miasm2.expression.expression_helper import * @@ -103,7 +104,7 @@ def simp_cst_propagation(e_s, e): # -(int) => -int if op == '-' and len(args) == 1 and args[0].is_int(): - return ExprInt(-args[0].arg) + return ExprInt(-int(args[0]), e.size) # A op 0 =>A if op in ['+', '|', "^", "<<", ">>", "<<<", ">>>"] and len(args) > 1: if args[-1].is_int(0): @@ -237,7 +238,7 @@ def simp_cst_propagation(e_s, e): # parity(int) => int if op == 'parity' and args[0].is_int(): - return ExprInt1(parity(args[0].arg)) + return ExprInt(parity(int(args[0])), 1) # (-a) * b * (-c) * (-d) => (-a) * b * c * d if op == "*" and len(args) > 1: @@ -580,8 +581,8 @@ def simp_cond(e_s, e): # eval exprcond src1/src2 with satifiable/unsatisfiable condition # propagation if (not e.cond.is_int()) and e.cond.size == 1: - src1 = e.src1.replace_expr({e.cond: ExprInt1(1)}) - src2 = e.src2.replace_expr({e.cond: ExprInt1(0)}) + src1 = e.src1.replace_expr({e.cond: ExprInt(1, 1)}) + src2 = e.src2.replace_expr({e.cond: ExprInt(0, 1)}) if src1 != e.src1 or src2 != e.src2: return ExprCond(e.cond, src1, src2) diff --git a/miasm2/expression/simplifications_cond.py b/miasm2/expression/simplifications_cond.py index 03bf6166..0d194d9a 100644 --- a/miasm2/expression/simplifications_cond.py +++ b/miasm2/expression/simplifications_cond.py @@ -169,7 +169,7 @@ def expr_simp_inverse(expr_simp, e): def expr_simp_equal(expr_simp, e): """(x - y)?(0:1) == (x == y)""" - to_match = m2_expr.ExprCond(jok1 + jok2, m2_expr.ExprInt1(0), m2_expr.ExprInt1(1)) + to_match = m2_expr.ExprCond(jok1 + jok2, m2_expr.ExprInt(0, 1), m2_expr.ExprInt(1, 1)) r = __MatchExprWrap(e, to_match, [jok1, jok2]) @@ -188,13 +188,13 @@ def exec_inf_unsigned(expr_simp, e): arg1, arg2 = e.args if isinstance(arg1, m2_expr.ExprInt) and isinstance(arg2, m2_expr.ExprInt): - return m2_expr.ExprInt1(1) if (arg1.arg < arg2.arg) else m2_expr.ExprInt1(0) + return m2_expr.ExprInt(1, 1) if (arg1.arg < arg2.arg) else m2_expr.ExprInt(0, 1) else: return e def __comp_signed(arg1, arg2): - """Return ExprInt1(1) if arg1 <s arg2 else ExprInt1(0) + """Return ExprInt(1, 1) if arg1 <s arg2 else ExprInt(0, 1) @arg1, @arg2: ExprInt""" val1 = int(arg1) @@ -205,7 +205,7 @@ def __comp_signed(arg1, arg2): if val2 >> (arg2.size - 1) == 1: val2 = - ((int(arg2.mask) ^ val2) + 1) - return m2_expr.ExprInt1(1) if (val1 < val2) else m2_expr.ExprInt1(0) + return m2_expr.ExprInt(1, 1) if (val1 < val2) else m2_expr.ExprInt(0, 1) def exec_inf_signed(expr_simp, e): "Compute x <s y" @@ -228,6 +228,6 @@ def exec_equal(expr_simp, e): arg1, arg2 = e.args if isinstance(arg1, m2_expr.ExprInt) and isinstance(arg2, m2_expr.ExprInt): - return m2_expr.ExprInt1(1) if (arg1.arg == arg2.arg) else m2_expr.ExprInt1(0) + return m2_expr.ExprInt(1, 1) if (arg1.arg == arg2.arg) else m2_expr.ExprInt(0, 1) else: return e |