Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
 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
Ejemplo n.º 3
0
    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))
Ejemplo n.º 4
0
    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
Ejemplo n.º 5
0
 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)
Ejemplo n.º 6
0
 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
Ejemplo n.º 7
0
    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)
Ejemplo n.º 8
0
                               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: