def build_field_tuple_and_path(self, ctx, path): typ = self._type fields = [] newpath = [] while len(path) > 0: if typ.is_int(): assert False, "Can't have base type if there is more left in path" elif typ.is_array() or typ.is_pointer(): if typ.is_array(): if not util.path_condition_implies( ctx, z3.ULT(path[0], typ.length()), print_model=True): util.print_stacktrace(ctx) raise IndexError( "Can not prove index %s is within array bounds %s" % (path[0], typ.length())) if typ.is_pointer(): if not util.path_condition_implies(ctx, path[0] == 0): util.print_stacktrace(ctx) raise RuntimeError("Pointer arithmetic not supported") typ = typ.deref() newpath.append(path[0]) elif typ.is_struct(): field = util.simplify(path[0]).as_long() fields.append(field) typ = typ.field(field) else: assert False, "Unhandled case" path = path[1:] return tuple(fields), newpath
def add(self, ctx, return_type, a, atype, b, btype, nuw=False, nsw=False): assert atype == return_type assert atype == btype if nuw: assert util.path_condition_implies(ctx, util.bvadd_no_overflow( a, b, signed=False), print_model=True) if nsw: assert util.path_condition_implies(ctx, util.bvadd_no_overflow( a, b, signed=True), print_model=True) return a + b
def test_merge3(self): ctx = context.newctx() x = util.FreshBitVec('x', 32) ctx.globals['%4'] = x cond = util.FreshBool('cond') ctx.push(cond) ctx.globals['%4'] += 1 g1 = ctx.pop() ctx.push(z3.Not(cond)) ctx.globals['%4'] += 1 g2 = ctx.pop() assert not util.path_condition_implies(g1, cond) assert not util.path_condition_implies(g2, z3.Not(cond)) assert not util.path_condition_implies(ctx, cond) assert not util.path_condition_implies(ctx, z3.Not(cond)) ctx.merge(cond, g1, g2) assert not util.path_condition_implies(ctx, cond) assert not util.path_condition_implies(ctx, z3.Not(cond))
def branch(self, ctx, cond, cond_type, iftrue, iffalse): self.assertion(ctx, not cond.is_poison(), "path condition is poison") assert itypes.integer_size(cond_type) == 1 scond = util.simplify(cond) can_be_true = not z3.is_false(scond) can_be_false = not z3.is_true(scond) if ctx['depth'] >= ctx['prune_depth']: can_be_true = not z3.is_false( scond) and not util.path_condition_implies(ctx, z3.Not(scond)) can_be_false = not can_be_true or ( not z3.is_true(scond) and not util.path_condition_implies(ctx, scond)) true_branch_exc = None false_branch_exc = None trueval = None falseval = None if can_be_true: try: ctx.push(path_condition=scond) trueval = iftrue() except ex.UnreachableException, e: stacktrace = getattr(e, 'stacktrace', None) self.assertion(ctx, util.path_condition_implies(ctx, z3.BoolVal(False), print_model=True), "Panic " + repr(e), stacktrace=stacktrace) can_be_true = False except BaseException, e: true_branch_exc = e
def srem(self, ctx, return_type, a, atype, b, btype, nuw=False, nsw=False, exact=False): assert atype == return_type assert atype == btype assert not nuw and not nsw and not exact assert util.path_condition_implies( ctx, b != z3.BitVecVal(0, btype.size())), "srem by zero" return z3.SRem(a, b)
def sdiv(self, ctx, return_type, a, atype, b, btype, nuw=False, nsw=False, exact=False): assert atype == return_type assert atype == btype assert not nuw and not nsw and not exact assert util.path_condition_implies(ctx, b != z3.BitVecVal(0, btype.size()), print_model=True), "sdiv by zero" return a / b
def _nest(self, ctx, depth): assert util.path_condition_implies(ctx, z3.And(*ctx.path_condition)) assert not util.path_condition_implies( ctx, z3.Not(z3.And(*ctx.path_condition))) if depth == 0: return cond = util.FreshBool('cond') ctx.push(cond) ctx.globals['%4'] += 1 self._nest(ctx, depth - 1) assert util.path_condition_implies(ctx, cond) ctx.pop() assert not util.path_condition_implies(ctx, cond) ctx.push(z3.Not(cond)) self._nest(ctx, depth - 1) assert util.path_condition_implies(ctx, z3.Not(cond)) ctx.pop() assert not util.path_condition_implies(ctx, z3.Not(cond)) self._nest(ctx, depth - 1)
stacktrace=stacktrace) can_be_true = False except BaseException, e: true_branch_exc = e finally: true_ctx = ctx.pop() if can_be_false: try: ctx.push(path_condition=z3.Not(scond)) falseval = iffalse() except ex.UnreachableException, e: stacktrace = getattr(e, 'stacktrace', None) self.assertion(ctx, util.path_condition_implies(ctx, z3.BoolVal(False), print_model=True), "Panic " + repr(e), stacktrace=stacktrace) can_be_false = False except BaseException, e: false_branch_exc = e finally: false_ctx = ctx.pop() if not can_be_false and not can_be_true: raise ex.UnreachableException('Branch unreachable', cond) if not can_be_false: ctx.restore(true_ctx) if true_branch_exc is not None: