Пример #1
0
            def extract_hdr(self, ctx, merged_args):
                hdr = merged_args[self.hdr_param_name].p4_val
                # apply the local and parent extern type ctxs
                for type_name, p4_type in self.extern_ctx.items():
                    ctx.add_type(type_name, ctx.resolve_type(p4_type))
                for type_name, p4_type in self.type_ctx.items():
                    ctx.add_type(type_name, ctx.resolve_type(p4_type))

                # advance the header index if a next field has been accessed
                hdr_stack = detect_hdr_stack_next(ctx, hdr)
                if hdr_stack:
                    compare = hdr_stack.locals[
                        "nextIndex"] >= hdr_stack.locals["size"]
                    if z3.simplify(compare) == z3.BoolVal(True):
                        raise ParserException("Index out of bounds!")

                # grab the hdr value
                hdr_expr = ctx.resolve_expr(hdr)

                hdr_expr.activate()
                bind_const = z3.Const(f"{self.name}_{self.hdr_param_name}",
                                      hdr_expr.z3_type)
                hdr_expr.bind(bind_const)

                # advance the stack, if it exists
                if hdr_stack:
                    hdr_stack.locals["lastIndex"] = hdr_stack.locals[
                        "nextIndex"]
                    hdr_stack.locals["nextIndex"] += 1
                self.call_counter += 1
Пример #2
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)
Пример #3
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)
Пример #4
0
    def eval(self, p4_state):
        context = p4_state.current_context()
        cond = z3.simplify(p4_state.resolve_expr(self.cond))
        forward_cond_copy = context.tmp_forward_cond
        then_vars = None
        if not cond == z3.BoolVal(False):
            var_store, contexts = p4_state.checkpoint()
            context.tmp_forward_cond = z3.And(forward_cond_copy, cond)
            try:
                self.then_block.eval(p4_state)
            except ParserException:
                RejectState().eval(p4_state)
            if not (context.has_returned or p4_state.has_exited):
                then_vars = p4_state.get_attrs()
            p4_state.has_exited = False
            context.has_returned = False
            p4_state.restore(var_store, contexts)

        if not cond == z3.BoolVal(True):
            var_store, contexts = p4_state.checkpoint()
            context.tmp_forward_cond = z3.And(forward_cond_copy, z3.Not(cond))
            try:
                self.else_block.eval(p4_state)
            except ParserException:
                RejectState().eval(p4_state)
            if p4_state.has_exited or context.has_returned:
                p4_state.restore(var_store, contexts)
            p4_state.has_exited = False
            context.has_returned = False

        context.tmp_forward_cond = forward_cond_copy

        if then_vars:
            merge_attrs(p4_state, cond, then_vars)
Пример #5
0
    def eval(self, p4_state):
        context = p4_state.current_context()

        if self.expr is None:
            expr = None
        else:
            # resolve the expr before restoring the state
            expr = p4_state.resolve_expr(self.expr)
            if isinstance(context.return_type, z3.BitVecSortRef):
                expr = z3_cast(expr, context.return_type)
            # we return a complex typed expression list, instantiate
            if isinstance(expr, list):
                instance = gen_instance(p4_state, "undefined",
                                        context.return_type)
                instance.set_list(expr)
                expr = instance

        cond = z3.simplify(
            z3.And(z3.Not(z3.Or(*context.forward_conds)),
                   context.tmp_forward_cond))
        if not cond == z3.BoolVal(False):
            context.return_states.append((cond, p4_state.copy_attrs()))
            if expr is not None:
                context.return_exprs.append((cond, expr))
            context.has_returned = True
        context.forward_conds.append(context.tmp_forward_cond)
Пример #6
0
 def eval_callable(self, ctx, merged_args, var_buffer):
     # tables are a little bit special since they also have attributes
     # so what we do here is first initialize the key
     hit = self.eval_keys(ctx)
     self.locals["hit"] = z3.simplify(hit)
     self.locals["miss"] = z3.Not(hit)
     # then execute the table as the next expression in the chain
     self.eval_table(ctx)
Пример #7
0
    def eval(self, p4_state):
        # FIXME: This checkpointing should not be necessary
        # Figure out what is going on
        var_store, contexts = p4_state.checkpoint()
        forward_conds = []
        tmp_forward_conds = []
        for context in reversed(p4_state.contexts):
            context.copy_out(p4_state)
            forward_conds.extend(context.forward_conds)
            tmp_forward_conds.append(context.tmp_forward_cond)
        context = p4_state.current_context()

        cond = z3.simplify(
            z3.And(z3.Not(z3.Or(*forward_conds)), z3.And(*tmp_forward_conds)))
        if not cond == z3.BoolVal(False):
            p4_state.exit_states.append((cond, p4_state.get_z3_repr()))
            p4_state.has_exited = True
        p4_state.restore(var_store, contexts)
        context.forward_conds.append(context.tmp_forward_cond)
Пример #8
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)
Пример #9
0
    def eval(self, p4_state):
        cond = z3.simplify(p4_state.resolve_expr(self.cond))

        # handle side effects for function and table calls
        if cond == z3.BoolVal(False):
            return p4_state.resolve_expr(self.else_val)
        if cond == z3.BoolVal(True):
            return p4_state.resolve_expr(self.then_val)

        var_store, chain_copy = p4_state.checkpoint()
        context = p4_state.current_context()
        forward_cond_copy = context.tmp_forward_cond
        context.tmp_forward_cond = z3.And(forward_cond_copy, cond)
        then_expr = p4_state.resolve_expr(self.then_val)
        then_vars = p4_state.get_attrs()
        p4_state.restore(var_store, chain_copy)
        context.tmp_forward_cond = forward_cond_copy

        else_expr = p4_state.resolve_expr(self.else_val)
        merge_attrs(p4_state, cond, then_vars)

        return handle_mux(cond, then_expr, else_expr)
Пример #10
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)