def check(expr_in, expr_out): """Check that expr_in is always equals to expr_out""" print "Ensure %s = %s" % (expr_in, expr_out) solver = z3.Solver() solver.add(trans.from_expr(expr_in) != trans.from_expr(expr_out)) result = solver.check() if result != z3.unsat: print "ERROR: a counter-example has been founded:" model = solver.model() print model print "Reinjecting in the simplifier:" to_rep = {} expressions = expr_in.get_r().union(expr_out.get_r()) for expr in expressions: value = model.eval(trans.from_expr(expr)) if hasattr(value, "as_long"): new_val = ExprInt(value.as_long(), expr.size) else: raise RuntimeError("Unable to reinject %r" % value) to_rep[expr] = new_val new_expr_in = expr_in.replace_expr(to_rep) new_expr_out = expr_out.replace_expr(to_rep) print "Check %s = %s" % (new_expr_in, new_expr_out) simp_in = expr_simp_explicit(new_expr_in) simp_out = expr_simp_explicit(new_expr_out) print "[%s] %s = %s" % (simp_in == simp_out, simp_in, simp_out) # Either the simplification does not stand, either the test is wrong raise RuntimeError("Bad simplification")
def _follow_simp_expr(exprs): """Simplify expression so avoid tracking useless elements, as: XOR EAX, EAX """ follow = set() for expr in exprs: follow.add(expr_simp_explicit(expr)) return follow, set()
((a<<i1) - (a<<i2), a*im2), ((a<<i1) - a - a, i0), ((a<<i2) - (a<<i1) - (a<<i1), i0), ((a<<i2) - a*i3, a), (((a+b) * i3) - (a + b), (a+b) * i2), (((a+b) * i2) + a + b, (a+b) * i3), (((a+b) * i3) - a - b, (a+b) * i2), (((a+b) * i2) - a - b, a+b), (((a+b) * i2) - i2 * a - i2 * b, i0), ] for e_input, e_check in to_test: print "#" * 80 e_new = expr_simp_explicit(e_input) print "original: ", str(e_input), "new: ", str(e_new) rez = e_new == e_check if not rez: raise ValueError( 'bug in expr_simp_explicit simp(%s) is %s and should be %s' % (e_input, e_new, e_check) ) check(e_input, e_check) # Test high level op to_test = [ (ExprOp(TOK_EQUAL, a+i2, i1), ExprOp(TOK_EQUAL, a+i1, i0)), (ExprOp(TOK_INF_SIGNED, a+i2, i1), ExprOp(TOK_INF_SIGNED, a+i2, i1)), (ExprOp(TOK_INF_UNSIGNED, a+i2, i1), ExprOp(TOK_INF_UNSIGNED, a+i2, i1)),
ExprMem(ExprInt(0x39E21, 19), 1))), (ExprOp('>>', ExprInt(0x5E580475, 92), ExprInt(0x7D800000000000000331720, 92)), ExprInt(0x0, 92)), (ExprOp('a>>', ExprInt(0x5E580475, 92), ExprInt(0x7D800000000000000331720, 92)), ExprInt(0x0, 92)), (ExprOp('a>>', ExprInt(-0x5E580475, 92), ExprInt(0x7D800000000000000331720, 92)), ExprInt(-1, 92)), (ExprOp("zeroExt_16", ExprInt(0x8, 8)), ExprInt(0x8, 16)), (ExprOp("zeroExt_16", ExprInt(0x88, 8)), ExprInt(0x88, 16)), (ExprOp("signExt_16", ExprInt(0x8, 8)), ExprInt(0x8, 16)), (ExprOp("signExt_16", ExprInt(-0x8, 8)), ExprInt(-0x8, 16)), ] for e_input, e_check in to_test: print "#" * 80 e_new = expr_simp_explicit(e_input) print "original: ", str(e_input), "new: ", str(e_new) rez = e_new == e_check if not rez: raise ValueError( 'bug in expr_simp_explicit simp(%s) is %s and should be %s' % (e_input, e_new, e_check)) check(e_input, e_check) # Test conds to_test = [ (((a - b) ^ ((a ^ b) & ((a - b) ^ a))).msb(), ExprOp_inf_signed(a, b)), ((((a - b) ^ ((a ^ b) & ((a - b) ^ a))) ^ a ^ b).msb(), ExprOp_inf_unsigned(a, b)), (ExprOp_inf_unsigned(ExprInt(-1, 32), ExprInt(3, 32)), ExprInt(0, 1)),