Пример #1
0
 def eval(self, ctx):
     cond = z3.simplify(
         z3.And(z3.Not(z3.Or(*ctx.forward_conds)), ctx.tmp_forward_cond))
     if not z3.is_false(cond):
         ctx.return_states.append((cond, ctx.copy_attrs()))
         ctx.has_returned = True
     ctx.forward_conds.append(ctx.tmp_forward_cond)
Пример #2
0
    def handle_select(self, ctx):
        switches = []
        select_conds = []
        forward_cond_copy = ctx.tmp_forward_cond
        match_list = ctx.resolve_expr(self.match)
        for parser_cond, parser_node in self.child:
            case_expr = ctx.resolve_expr(parser_cond)
            cond = build_select_cond(ctx, case_expr, match_list)
            # state forks here
            var_store = ctx.checkpoint()
            ctx.tmp_forward_cond = z3.And(forward_cond_copy, cond)
            parser_node.eval(ctx)
            select_conds.append(cond)
            if not (ctx.get_exited() or z3.is_false(cond)):
                switches.append((ctx.tmp_forward_cond, ctx.get_attrs()))
            ctx.set_exited(False)
            ctx.has_returned = False
            ctx.restore(var_store)

        # this hits when no select matches
        cond = z3.Not(z3.Or(*select_conds))
        ctx.tmp_forward_cond = z3.And(forward_cond_copy, cond)
        self.default.eval(ctx)
        ctx.set_exited(False)
        ctx.has_returned = False
        ctx.tmp_forward_cond = forward_cond_copy
        for cond, then_vars in reversed(switches):
            merge_attrs(ctx, cond, then_vars)
Пример #3
0
    def eval(self, ctx):
        cond = z3.simplify(ctx.resolve_expr(self.cond))
        forward_cond_copy = ctx.tmp_forward_cond
        then_vars = None
        if not z3.is_false(cond):
            var_store = ctx.checkpoint()
            ctx.tmp_forward_cond = z3.And(forward_cond_copy, cond)
            try:
                self.then_block.eval(ctx)
            except ParserException:
                RejectState().eval(ctx)
            if not(ctx.has_returned or ctx.get_exited()):
                then_vars = ctx.get_attrs()
            ctx.set_exited(False)
            ctx.has_returned = False
            ctx.restore(var_store)

        if not z3.is_true(cond):
            var_store = ctx.checkpoint()
            ctx.tmp_forward_cond = z3.And(forward_cond_copy, z3.Not(cond))
            try:
                self.else_block.eval(ctx)
            except ParserException:
                RejectState().eval(ctx)
            if ctx.get_exited() or ctx.has_returned:
                ctx.restore(var_store)
            ctx.set_exited(False)
            ctx.has_returned = False

        ctx.tmp_forward_cond = forward_cond_copy

        if then_vars:
            merge_attrs(ctx, cond, then_vars)
Пример #4
0
    def eval_table(self, ctx):
        action_exprs = []
        action_matches = []
        forward_cond_copy = ctx.tmp_forward_cond

        # only bother to evaluate if the table can actually hit
        if not z3.is_false(self.locals["hit"]):
            # note: the action lists are pass by reference here
            # first evaluate all the constant entries
            self.eval_const_entries(ctx, action_exprs, action_matches)
            # then append dynamic table entries to the constant entries
            # only do this if the table can actually be manipulated
            if not self.immutable:
                self.eval_table_entries(ctx, action_exprs, action_matches)
        # finally start evaluating the default entry
        var_store = ctx.checkpoint()
        # this hits when the table is either missed, or no action matches
        cond = z3.Or(self.locals["miss"], z3.Not(z3.Or(*action_matches)))
        ctx.tmp_forward_cond = z3.And(forward_cond_copy, cond)
        self.eval_default(ctx)
        if ctx.get_exited():
            ctx.restore(var_store)
        ctx.set_exited(False)
        ctx.tmp_forward_cond = forward_cond_copy
        # generate a nested set of if expressions per available action
        for cond, then_vars in action_exprs:
            merge_attrs(ctx, cond, then_vars)
Пример #5
0
    def eval(self, ctx):
        # FIXME: This checkpointing should not be necessary
        # Figure out what is going on
        var_store = ctx.checkpoint()
        forward_conds = []
        tmp_forward_conds = []
        sub_ctx = ctx
        while not isinstance(sub_ctx, StaticContext):
            sub_ctx.copy_out(ctx)
            forward_conds.extend(sub_ctx.forward_conds)
            tmp_forward_conds.append(sub_ctx.tmp_forward_cond)
            sub_ctx = sub_ctx.parent_ctx

        cond = z3.simplify(
            z3.And(z3.Not(z3.Or(*forward_conds)), z3.And(*tmp_forward_conds)))
        if not z3.is_false(cond):
            ctx.add_exit_state(cond, ctx.get_p4_state().get_members(ctx))
            ctx.set_exited(True)
        ctx.restore(var_store)
        ctx.forward_conds.append(ctx.tmp_forward_cond)
Пример #6
0
 def eval_cases(self, ctx, cases):
     case_exprs = []
     case_matches = []
     forward_cond_copy = ctx.tmp_forward_cond
     fall_through_matches = []
     for case_match, case_block in cases.values():
         # there is no block for the switch
         # this expressions falls through to the next switch case
         if not case_block:
             fall_through_matches.append(case_match)
             continue
         # matches the condition OR all the other fall-through switches
         case_match = z3.Or(case_match, *fall_through_matches)
         fall_through_matches.clear()
         var_store = ctx.checkpoint()
         ctx.tmp_forward_cond = z3.And(
             forward_cond_copy, case_match)
         case_block.eval(ctx)
         if not (ctx.has_returned or ctx.get_exited()):
             then_vars = ctx.get_attrs()
             case_exprs.append((case_match, then_vars))
         ctx.has_returned = False
         ctx.set_exited(False)
         ctx.restore(var_store)
         case_matches.append(case_match)
     var_store = ctx.checkpoint()
     # process the default expression
     cond = z3.Not(z3.Or(*case_matches))
     if not z3.is_false(cond):
         ctx.tmp_forward_cond = z3.And(forward_cond_copy, cond)
         self.default_case.eval(ctx)
         if ctx.has_returned or ctx.get_exited():
             ctx.restore(var_store)
         ctx.has_returned = False
         ctx.set_exited(False)
         ctx.tmp_forward_cond = forward_cond_copy
     # merge all the expressions in reverse order
     for cond, then_vars in reversed(case_exprs):
         merge_attrs(ctx, cond, then_vars)
Пример #7
0
    def eval(self, ctx):

        if self.expr is None:
            expr = None
        else:
            # resolve the expr before restoring the state
            expr = ctx.resolve_expr(self.expr)
            if isinstance(ctx.return_type, z3.BitVecSortRef):
                expr = z3_cast(expr, ctx.return_type)
            # we return a complex typed expression list, instantiate
            if isinstance(expr, list):
                # name is meaningless here so keep it empty
                instance = ctx.gen_instance("", ctx.return_type)
                instance.set_list(expr)
                expr = instance

        cond = z3.simplify(z3.And(z3.Not(z3.Or(*ctx.forward_conds)),
                                  ctx.tmp_forward_cond))
        if not z3.is_false(cond):
            ctx.return_states.append((cond, ctx.copy_attrs()))
            if expr is not None:
                ctx.return_exprs.append((cond, expr))
            ctx.has_returned = True
        ctx.forward_conds.append(ctx.tmp_forward_cond)