Example #1
0
void
npfctl_bpf_endgroup(npf_bpf_t *ctx)
{
	struct bpf_program *bp = &ctx->prog;
	const size_t curoff = bp->bf_len;

	/* If there are no blocks or only one - nothing to do. */
	if ((ctx->nblocks - ctx->gblock) <= 1) {
		ctx->goff = ctx->gblock = 0;
		return;
	}

	/*
	 * Append a failure return as a fall-through i.e. if there is
	 * no match within the group.
	 */
	struct bpf_insn insns_ret[] = {
		BPF_STMT(BPF_RET+BPF_K, NPF_BPF_FAILURE),
	};
	add_insns(ctx, insns_ret, __arraycount(insns_ret));

	/*
	 * Adjust jump offsets: on match - jump outside the group i.e.
	 * to the current offset.  Otherwise, jump to the next instruction
	 * which would lead to the fall-through code above if none matches.
	 */
	fixup_jumps(ctx, ctx->goff, curoff, true);
	ctx->goff = ctx->gblock = 0;
}
Example #2
0
void unroll_this(pTHX_ OP* op) {
    struct sljit_compiler* compiler = sljit_create_compiler();
    HV* seenops = newHV();

#ifdef DEBUG
    if (getenv("RUNOPS_OPTIMIZED_DEBUG")) {
        CV *runcv = Perl_find_runcv(NULL);
        sljit_compiler_verbose(compiler, stderr);

        DEBUGf(("Unroll %s::%s cv=%p, op=%p (%s)\n", HvNAME_get(CvSTASH(runcv)),
                GvENAME(CvGV(runcv)), runcv, op, sljit_get_platform_name()));
    }
#endif

    sljit_emit_enter(compiler, 0, 2, 1, 0);
    unroll_tree(compiler, seenops, op, NULL);
    fixup_jumps(compiler, needjumps, labels);
    // This is needed for things that drop off the runloop without a
    // return, e.g. S_sortcv. TODO: Make conditional?
    sljit_emit_return(compiler, SLJIT_MEM, (sljit_w) &PL_op);

    op->op_ppaddr = sljit_generate_code(compiler);
    op->op_spare = 3;
    DEBUGf(("Code at %p\n", op->op_ppaddr));

    labels = NULL;
    needjumps = NULL;
    SvREFCNT_dec(seenops);
    sljit_free_compiler(compiler);
}
Example #3
0
struct bpf_program *
npfctl_bpf_complete(npf_bpf_t *ctx)
{
	struct bpf_program *bp = &ctx->prog;
	const u_int retoff = bp->bf_len;

	/* Add the return fragment (success and failure paths). */
	struct bpf_insn insns_ret[] = {
		BPF_STMT(BPF_RET+BPF_K, NPF_BPF_SUCCESS),
		BPF_STMT(BPF_RET+BPF_K, NPF_BPF_FAILURE),
	};
	add_insns(ctx, insns_ret, __arraycount(insns_ret));

	/* Fixup all jumps to the main failure path. */
	fixup_jumps(ctx, 0, retoff, false);

	return &ctx->prog;
}