From 5c5a76d5669bb01840fb8ed6f93e74d523239437 Mon Sep 17 00:00:00 2001 From: alnsn Date: Thu, 27 Sep 2012 18:28:53 +0000 Subject: [PATCH] Remove bpf_jit which was ported from FreeBSD recently. It will soon be replaced with the new bpfjit kernel module. --- distrib/sets/lists/comp/mi | 4 +- sys/arch/amd64/amd64/bpf_jit_machdep.c | 657 ----------------------- sys/arch/amd64/amd64/bpf_jit_machdep.h | 485 ----------------- sys/arch/amd64/conf/files.amd64 | 3 +- sys/arch/amd64/conf/std.amd64 | 3 +- sys/arch/i386/conf/files.i386 | 3 +- sys/arch/i386/conf/std.i386 | 3 +- sys/arch/i386/i386/bpf_jit_machdep.c | 686 ------------------------- sys/arch/i386/i386/bpf_jit_machdep.h | 430 ---------------- sys/conf/files | 4 +- sys/modules/bpf/Makefile | 14 +- sys/net/Makefile | 4 +- sys/net/bpf.c | 39 +- sys/net/bpf_filter.c | 13 +- sys/net/bpf_jit.c | 142 ----- sys/net/bpf_jit.h | 81 --- sys/net/bpfdesc.h | 5 +- 17 files changed, 20 insertions(+), 2556 deletions(-) delete mode 100644 sys/arch/amd64/amd64/bpf_jit_machdep.c delete mode 100644 sys/arch/amd64/amd64/bpf_jit_machdep.h delete mode 100644 sys/arch/i386/i386/bpf_jit_machdep.c delete mode 100644 sys/arch/i386/i386/bpf_jit_machdep.h delete mode 100644 sys/net/bpf_jit.c delete mode 100644 sys/net/bpf_jit.h diff --git a/distrib/sets/lists/comp/mi b/distrib/sets/lists/comp/mi index 302cf602c175..214ba9932114 100644 --- a/distrib/sets/lists/comp/mi +++ b/distrib/sets/lists/comp/mi @@ -1,4 +1,4 @@ -# $NetBSD: mi,v 1.1781 2012/09/18 15:14:41 skrll Exp $ +# $NetBSD: mi,v 1.1782 2012/09/27 18:28:53 alnsn Exp $ # # Note: don't delete entries from here - mark them as "obsolete" instead. # @@ -1805,7 +1805,7 @@ ./usr/include/net/agr/if_agrioctl.h comp-c-include ./usr/include/net/bpf.h comp-c-include ./usr/include/net/bpfdesc.h comp-c-include -./usr/include/net/bpf_jit.h comp-c-include +./usr/include/net/bpf_jit.h comp-c-include obsolete ./usr/include/net/dlt.h comp-c-include ./usr/include/net/ethertypes.h comp-c-include ./usr/include/net/if.h comp-c-include diff --git a/sys/arch/amd64/amd64/bpf_jit_machdep.c b/sys/arch/amd64/amd64/bpf_jit_machdep.c deleted file mode 100644 index 472b9140078a..000000000000 --- a/sys/arch/amd64/amd64/bpf_jit_machdep.c +++ /dev/null @@ -1,657 +0,0 @@ -/* $NetBSD: bpf_jit_machdep.c,v 1.1 2012/08/01 23:24:28 rmind Exp $ */ - -/*- - * Copyright (C) 2002-2003 NetGroup, Politecnico di Torino (Italy) - * Copyright (C) 2005-2009 Jung-uk Kim - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Politecnico di Torino nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD: src/sys/amd64/amd64/bpf_jit_machdep.c, - * v 1.22 2010/04/22 23:47:19 jkim Exp $ - */ - -#include -__KERNEL_RCSID(0, "$NetBSD: bpf_jit_machdep.c,v 1.1 2012/08/01 23:24:28 rmind Exp $"); - -#ifdef _KERNEL -#if defined(_KERNEL_OPT) -#include "opt_bpf.h" -#endif - -#include -#include -#include -#include -#include -#include -#else -#include -#include -#include -#include -#endif - -#include - -#include -#include - -#include - -bpf_filter_func bpf_jit_compile(struct bpf_insn *, u_int, size_t *); - -/* - * Emit routine to update the jump table. - */ -static void -emit_length(bpf_bin_stream *stream, __unused u_int value, u_int len) -{ - - if (stream->refs != NULL) - (stream->refs)[stream->bpf_pc] += len; - stream->cur_ip += len; -} - -/* - * Emit routine to output the actual binary code. - */ -static void -emit_code(bpf_bin_stream *stream, u_int value, u_int len) -{ - - switch (len) { - case 1: - stream->ibuf[stream->cur_ip] = (u_char)value; - stream->cur_ip++; - break; - case 2: - *((u_short *)(stream->ibuf + stream->cur_ip)) = (u_short)value; - stream->cur_ip += 2; - break; - case 4: - *((u_int *)(stream->ibuf + stream->cur_ip)) = value; - stream->cur_ip += 4; - break; - } -} - -/* - * Scan the filter program and find possible optimization. - */ -static int -bpf_jit_optimize(struct bpf_insn *prog, u_int nins) -{ - int flags; - u_int i; - - /* Do we return immediately? */ - if (BPF_CLASS(prog[0].code) == BPF_RET) - return (BPF_JIT_FRET); - - for (flags = 0, i = 0; i < nins; i++) { - switch (prog[i].code) { - case BPF_LD|BPF_W|BPF_ABS: - case BPF_LD|BPF_H|BPF_ABS: - case BPF_LD|BPF_B|BPF_ABS: - case BPF_LD|BPF_W|BPF_IND: - case BPF_LD|BPF_H|BPF_IND: - case BPF_LD|BPF_B|BPF_IND: - case BPF_LDX|BPF_MSH|BPF_B: - flags |= BPF_JIT_FPKT; - break; - case BPF_LD|BPF_MEM: - case BPF_LDX|BPF_MEM: - case BPF_ST: - case BPF_STX: - flags |= BPF_JIT_FMEM; - break; - case BPF_LD|BPF_W|BPF_LEN: - case BPF_LDX|BPF_W|BPF_LEN: - flags |= BPF_JIT_FLEN; - break; - case BPF_JMP|BPF_JA: - case BPF_JMP|BPF_JGT|BPF_K: - case BPF_JMP|BPF_JGE|BPF_K: - case BPF_JMP|BPF_JEQ|BPF_K: - case BPF_JMP|BPF_JSET|BPF_K: - case BPF_JMP|BPF_JGT|BPF_X: - case BPF_JMP|BPF_JGE|BPF_X: - case BPF_JMP|BPF_JEQ|BPF_X: - case BPF_JMP|BPF_JSET|BPF_X: - flags |= BPF_JIT_FJMP; - break; - } - if (flags == BPF_JIT_FLAG_ALL) - break; - } - - return (flags); -} - -/* - * Function that does the real stuff. - */ -bpf_filter_func -bpf_jit_compile(struct bpf_insn *prog, u_int nins, size_t *size) -{ - bpf_bin_stream stream; - struct bpf_insn *ins; - int flags, fret, fpkt, fmem, fjmp, flen; - u_int i, pass; - - /* - * NOTE: Do not modify the name of this variable, as it's used by - * the macros to emit code. - */ - emit_func emitm; - - flags = bpf_jit_optimize(prog, nins); - fret = (flags & BPF_JIT_FRET) != 0; - fpkt = (flags & BPF_JIT_FPKT) != 0; - fmem = (flags & BPF_JIT_FMEM) != 0; - fjmp = (flags & BPF_JIT_FJMP) != 0; - flen = (flags & BPF_JIT_FLEN) != 0; - - if (fret) - nins = 1; - - memset(&stream, 0, sizeof(stream)); - - /* Allocate the reference table for the jumps. */ - if (fjmp) { -#ifdef _KERNEL - stream.refs = malloc((nins + 1) * sizeof(u_int), M_TEMP, - M_NOWAIT | M_ZERO); -#else - stream.refs = calloc(nins + 1, sizeof(u_int)); -#endif - if (stream.refs == NULL) - return (NULL); - } - - /* - * The first pass will emit the lengths of the instructions - * to create the reference table. - */ - emitm = emit_length; - - for (pass = 0; pass < 2; pass++) { - ins = prog; - - /* Create the procedure header. */ - if (fmem) { - PUSH(RBP); - MOVrq(RSP, RBP); - SUBib(BPF_MEMWORDS * sizeof(uint32_t), RSP); - } - if (flen) - MOVrd2(ESI, R9D); - if (fpkt) { - MOVrq2(RDI, R8); - MOVrd(EDX, EDI); - } - - for (i = 0; i < nins; i++) { - stream.bpf_pc++; - - switch (ins->code) { - default: -#ifdef _KERNEL - return (NULL); -#else - abort(); -#endif - - case BPF_RET|BPF_K: - MOVid(ins->k, EAX); - if (fmem) - LEAVE(); - RET(); - break; - - case BPF_RET|BPF_A: - if (fmem) - LEAVE(); - RET(); - break; - - case BPF_LD|BPF_W|BPF_ABS: - MOVid(ins->k, ESI); - CMPrd(EDI, ESI); - JAb(12); - MOVrd(EDI, ECX); - SUBrd(ESI, ECX); - CMPid(sizeof(int32_t), ECX); - if (fmem) { - JAEb(4); - ZEROrd(EAX); - LEAVE(); - } else { - JAEb(3); - ZEROrd(EAX); - } - RET(); - MOVrq3(R8, RCX); - MOVobd(RCX, RSI, EAX); - BSWAP(EAX); - break; - - case BPF_LD|BPF_H|BPF_ABS: - ZEROrd(EAX); - MOVid(ins->k, ESI); - CMPrd(EDI, ESI); - JAb(12); - MOVrd(EDI, ECX); - SUBrd(ESI, ECX); - CMPid(sizeof(int16_t), ECX); - if (fmem) { - JAEb(2); - LEAVE(); - } else - JAEb(1); - RET(); - MOVrq3(R8, RCX); - MOVobw(RCX, RSI, AX); - SWAP_AX(); - break; - - case BPF_LD|BPF_B|BPF_ABS: - ZEROrd(EAX); - MOVid(ins->k, ESI); - CMPrd(EDI, ESI); - if (fmem) { - JBb(2); - LEAVE(); - } else - JBb(1); - RET(); - MOVrq3(R8, RCX); - MOVobb(RCX, RSI, AL); - break; - - case BPF_LD|BPF_W|BPF_LEN: - MOVrd3(R9D, EAX); - break; - - case BPF_LDX|BPF_W|BPF_LEN: - MOVrd3(R9D, EDX); - break; - - case BPF_LD|BPF_W|BPF_IND: - CMPrd(EDI, EDX); - JAb(27); - MOVid(ins->k, ESI); - MOVrd(EDI, ECX); - SUBrd(EDX, ECX); - CMPrd(ESI, ECX); - JBb(14); - ADDrd(EDX, ESI); - MOVrd(EDI, ECX); - SUBrd(ESI, ECX); - CMPid(sizeof(int32_t), ECX); - if (fmem) { - JAEb(4); - ZEROrd(EAX); - LEAVE(); - } else { - JAEb(3); - ZEROrd(EAX); - } - RET(); - MOVrq3(R8, RCX); - MOVobd(RCX, RSI, EAX); - BSWAP(EAX); - break; - - case BPF_LD|BPF_H|BPF_IND: - ZEROrd(EAX); - CMPrd(EDI, EDX); - JAb(27); - MOVid(ins->k, ESI); - MOVrd(EDI, ECX); - SUBrd(EDX, ECX); - CMPrd(ESI, ECX); - JBb(14); - ADDrd(EDX, ESI); - MOVrd(EDI, ECX); - SUBrd(ESI, ECX); - CMPid(sizeof(int16_t), ECX); - if (fmem) { - JAEb(2); - LEAVE(); - } else - JAEb(1); - RET(); - MOVrq3(R8, RCX); - MOVobw(RCX, RSI, AX); - SWAP_AX(); - break; - - case BPF_LD|BPF_B|BPF_IND: - ZEROrd(EAX); - CMPrd(EDI, EDX); - JAEb(13); - MOVid(ins->k, ESI); - MOVrd(EDI, ECX); - SUBrd(EDX, ECX); - CMPrd(ESI, ECX); - if (fmem) { - JAb(2); - LEAVE(); - } else - JAb(1); - RET(); - MOVrq3(R8, RCX); - ADDrd(EDX, ESI); - MOVobb(RCX, RSI, AL); - break; - - case BPF_LDX|BPF_MSH|BPF_B: - MOVid(ins->k, ESI); - CMPrd(EDI, ESI); - if (fmem) { - JBb(4); - ZEROrd(EAX); - LEAVE(); - } else { - JBb(3); - ZEROrd(EAX); - } - RET(); - ZEROrd(EDX); - MOVrq3(R8, RCX); - MOVobb(RCX, RSI, DL); - ANDib(0x0f, DL); - SHLib(2, EDX); - break; - - case BPF_LD|BPF_IMM: - MOVid(ins->k, EAX); - break; - - case BPF_LDX|BPF_IMM: - MOVid(ins->k, EDX); - break; - - case BPF_LD|BPF_MEM: - MOVid(ins->k * sizeof(uint32_t), ESI); - MOVobd(RSP, RSI, EAX); - break; - - case BPF_LDX|BPF_MEM: - MOVid(ins->k * sizeof(uint32_t), ESI); - MOVobd(RSP, RSI, EDX); - break; - - case BPF_ST: - /* - * XXX this command and the following could - * be optimized if the previous instruction - * was already of this type - */ - MOVid(ins->k * sizeof(uint32_t), ESI); - MOVomd(EAX, RSP, RSI); - break; - - case BPF_STX: - MOVid(ins->k * sizeof(uint32_t), ESI); - MOVomd(EDX, RSP, RSI); - break; - - case BPF_JMP|BPF_JA: - JUMP(ins->k); - break; - - case BPF_JMP|BPF_JGT|BPF_K: - if (ins->jt == ins->jf) { - JUMP(ins->jt); - break; - } - CMPid(ins->k, EAX); - JCC(JA, JBE); - break; - - case BPF_JMP|BPF_JGE|BPF_K: - if (ins->jt == ins->jf) { - JUMP(ins->jt); - break; - } - CMPid(ins->k, EAX); - JCC(JAE, JB); - break; - - case BPF_JMP|BPF_JEQ|BPF_K: - if (ins->jt == ins->jf) { - JUMP(ins->jt); - break; - } - CMPid(ins->k, EAX); - JCC(JE, JNE); - break; - - case BPF_JMP|BPF_JSET|BPF_K: - if (ins->jt == ins->jf) { - JUMP(ins->jt); - break; - } - TESTid(ins->k, EAX); - JCC(JNE, JE); - break; - - case BPF_JMP|BPF_JGT|BPF_X: - if (ins->jt == ins->jf) { - JUMP(ins->jt); - break; - } - CMPrd(EDX, EAX); - JCC(JA, JBE); - break; - - case BPF_JMP|BPF_JGE|BPF_X: - if (ins->jt == ins->jf) { - JUMP(ins->jt); - break; - } - CMPrd(EDX, EAX); - JCC(JAE, JB); - break; - - case BPF_JMP|BPF_JEQ|BPF_X: - if (ins->jt == ins->jf) { - JUMP(ins->jt); - break; - } - CMPrd(EDX, EAX); - JCC(JE, JNE); - break; - - case BPF_JMP|BPF_JSET|BPF_X: - if (ins->jt == ins->jf) { - JUMP(ins->jt); - break; - } - TESTrd(EDX, EAX); - JCC(JNE, JE); - break; - - case BPF_ALU|BPF_ADD|BPF_X: - ADDrd(EDX, EAX); - break; - - case BPF_ALU|BPF_SUB|BPF_X: - SUBrd(EDX, EAX); - break; - - case BPF_ALU|BPF_MUL|BPF_X: - MOVrd(EDX, ECX); - MULrd(EDX); - MOVrd(ECX, EDX); - break; - - case BPF_ALU|BPF_DIV|BPF_X: - TESTrd(EDX, EDX); - if (fmem) { - JNEb(4); - ZEROrd(EAX); - LEAVE(); - } else { - JNEb(3); - ZEROrd(EAX); - } - RET(); - MOVrd(EDX, ECX); - ZEROrd(EDX); - DIVrd(ECX); - MOVrd(ECX, EDX); - break; - - case BPF_ALU|BPF_AND|BPF_X: - ANDrd(EDX, EAX); - break; - - case BPF_ALU|BPF_OR|BPF_X: - ORrd(EDX, EAX); - break; - - case BPF_ALU|BPF_LSH|BPF_X: - MOVrd(EDX, ECX); - SHL_CLrb(EAX); - break; - - case BPF_ALU|BPF_RSH|BPF_X: - MOVrd(EDX, ECX); - SHR_CLrb(EAX); - break; - - case BPF_ALU|BPF_ADD|BPF_K: - ADD_EAXi(ins->k); - break; - - case BPF_ALU|BPF_SUB|BPF_K: - SUB_EAXi(ins->k); - break; - - case BPF_ALU|BPF_MUL|BPF_K: - MOVrd(EDX, ECX); - MOVid(ins->k, EDX); - MULrd(EDX); - MOVrd(ECX, EDX); - break; - - case BPF_ALU|BPF_DIV|BPF_K: - MOVrd(EDX, ECX); - ZEROrd(EDX); - MOVid(ins->k, ESI); - DIVrd(ESI); - MOVrd(ECX, EDX); - break; - - case BPF_ALU|BPF_AND|BPF_K: - ANDid(ins->k, EAX); - break; - - case BPF_ALU|BPF_OR|BPF_K: - ORid(ins->k, EAX); - break; - - case BPF_ALU|BPF_LSH|BPF_K: - SHLib((ins->k) & 0xff, EAX); - break; - - case BPF_ALU|BPF_RSH|BPF_K: - SHRib((ins->k) & 0xff, EAX); - break; - - case BPF_ALU|BPF_NEG: - NEGd(EAX); - break; - - case BPF_MISC|BPF_TAX: - MOVrd(EAX, EDX); - break; - - case BPF_MISC|BPF_TXA: - MOVrd(EDX, EAX); - break; - } - ins++; - } - - if (pass > 0) - continue; - - *size = stream.cur_ip; -#ifdef _KERNEL - stream.ibuf = malloc(*size, M_TEMP, M_NOWAIT); - if (stream.ibuf == NULL) - break; -#else - stream.ibuf = mmap(NULL, *size, PROT_READ | PROT_WRITE, - MAP_ANON, -1, 0); - if (stream.ibuf == MAP_FAILED) { - stream.ibuf = NULL; - break; - } -#endif - - /* - * Modify the reference table to contain the offsets and - * not the lengths of the instructions. - */ - if (fjmp) - for (i = 1; i < nins + 1; i++) - stream.refs[i] += stream.refs[i - 1]; - - /* Reset the counters. */ - stream.cur_ip = 0; - stream.bpf_pc = 0; - - /* The second pass creates the actual code. */ - emitm = emit_code; - } - - /* - * The reference table is needed only during compilation, - * now we can free it. - */ - if (fjmp) -#ifdef _KERNEL - free(stream.refs, M_TEMP); -#else - free(stream.refs); -#endif - -#ifndef _KERNEL - if (stream.ibuf != NULL && - mprotect(stream.ibuf, *size, PROT_READ | PROT_EXEC) != 0) { - munmap(stream.ibuf, *size); - stream.ibuf = NULL; - } -#endif - - return ((bpf_filter_func)stream.ibuf); -} diff --git a/sys/arch/amd64/amd64/bpf_jit_machdep.h b/sys/arch/amd64/amd64/bpf_jit_machdep.h deleted file mode 100644 index cae04db645c6..000000000000 --- a/sys/arch/amd64/amd64/bpf_jit_machdep.h +++ /dev/null @@ -1,485 +0,0 @@ -/* $NetBSD: bpf_jit_machdep.h,v 1.1 2012/08/01 23:24:28 rmind Exp $ */ - -/*- - * Copyright (C) 2002-2003 NetGroup, Politecnico di Torino (Italy) - * Copyright (C) 2005-2009 Jung-uk Kim - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Politecnico di Torino nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD: src/sys/amd64/amd64/bpf_jit_machdep.h, - * v 1.15 2010/04/22 23:47:19 jkim Exp $ - */ - -#ifndef _BPF_JIT_MACHDEP_H_ -#define _BPF_JIT_MACHDEP_H_ - -/* - * Registers - */ -#define RAX 0 -#define RCX 1 -#define RDX 2 -#define RBX 3 -#define RSP 4 -#define RBP 5 -#define RSI 6 -#define RDI 7 -#define R8 0 -#define R9 1 -#define R10 2 -#define R11 3 -#define R12 4 -#define R13 5 -#define R14 6 -#define R15 7 - -#define EAX 0 -#define ECX 1 -#define EDX 2 -#define EBX 3 -#define ESP 4 -#define EBP 5 -#define ESI 6 -#define EDI 7 -#define R8D 0 -#define R9D 1 -#define R10D 2 -#define R11D 3 -#define R12D 4 -#define R13D 5 -#define R14D 6 -#define R15D 7 - -#define AX 0 -#define CX 1 -#define DX 2 -#define BX 3 -#define SP 4 -#define BP 5 -#define SI 6 -#define DI 7 - -#define AL 0 -#define CL 1 -#define DL 2 -#define BL 3 - -/* Optimization flags */ -#define BPF_JIT_FRET 0x01 -#define BPF_JIT_FPKT 0x02 -#define BPF_JIT_FMEM 0x04 -#define BPF_JIT_FJMP 0x08 -#define BPF_JIT_FLEN 0x10 - -#define BPF_JIT_FLAG_ALL \ - (BPF_JIT_FPKT | BPF_JIT_FMEM | BPF_JIT_FJMP | BPF_JIT_FLEN) - -/* A stream of native binary code */ -typedef struct bpf_bin_stream { - /* Current native instruction pointer. */ - int cur_ip; - - /* - * Current BPF instruction pointer, i.e. position in - * the BPF program reached by the jitter. - */ - int bpf_pc; - - /* Instruction buffer, contains the generated native code. */ - char *ibuf; - - /* Jumps reference table. */ - u_int *refs; -} bpf_bin_stream; - -/* - * Prototype of the emit functions. - * - * Different emit functions are used to create the reference table and - * to generate the actual filtering code. This allows to have simpler - * instruction macros. - * The first parameter is the stream that will receive the data. - * The second one is a variable containing the data. - * The third one is the length, that can be 1, 2, or 4 since it is possible - * to emit a byte, a short, or a word at a time. - */ -typedef void (*emit_func)(bpf_bin_stream *, u_int, u_int); - -/* - * Native instruction macros - */ - -/* movl i32,r32 */ -#define MOVid(i32, r32) do { \ - emitm(&stream, (11 << 4) | (1 << 3) | (r32 & 0x7), 1); \ - emitm(&stream, i32, 4); \ -} while (0) - -/* movq i64,r64 */ -#define MOViq(i64, r64) do { \ - emitm(&stream, 0x48, 1); \ - emitm(&stream, (11 << 4) | (1 << 3) | (r64 & 0x7), 1); \ - emitm(&stream, i64, 4); \ - emitm(&stream, (i64 >> 32), 4); \ -} while (0) - -/* movl sr32,dr32 */ -#define MOVrd(sr32, dr32) do { \ - emitm(&stream, 0x89, 1); \ - emitm(&stream, \ - (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ -} while (0) - -/* movl sr32,dr32 (dr32 = %r8-15d) */ -#define MOVrd2(sr32, dr32) do { \ - emitm(&stream, 0x8941, 2); \ - emitm(&stream, \ - (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ -} while (0) - -/* movl sr32,dr32 (sr32 = %r8-15d) */ -#define MOVrd3(sr32, dr32) do { \ - emitm(&stream, 0x8944, 2); \ - emitm(&stream, \ - (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ -} while (0) - -/* movq sr64,dr64 */ -#define MOVrq(sr64, dr64) do { \ - emitm(&stream, 0x8948, 2); \ - emitm(&stream, \ - (3 << 6) | ((sr64 & 0x7) << 3) | (dr64 & 0x7), 1); \ -} while (0) - -/* movq sr64,dr64 (dr64 = %r8-15) */ -#define MOVrq2(sr64, dr64) do { \ - emitm(&stream, 0x8949, 2); \ - emitm(&stream, \ - (3 << 6) | ((sr64 & 0x7) << 3) | (dr64 & 0x7), 1); \ -} while (0) - -/* movq sr64,dr64 (sr64 = %r8-15) */ -#define MOVrq3(sr64, dr64) do { \ - emitm(&stream, 0x894c, 2); \ - emitm(&stream, \ - (3 << 6) | ((sr64 & 0x7) << 3) | (dr64 & 0x7), 1); \ -} while (0) - -/* movl (sr64,or64,1),dr32 */ -#define MOVobd(sr64, or64, dr32) do { \ - emitm(&stream, 0x8b, 1); \ - emitm(&stream, ((dr32 & 0x7) << 3) | 4, 1); \ - emitm(&stream, ((or64 & 0x7) << 3) | (sr64 & 0x7), 1); \ -} while (0) - -/* movw (sr64,or64,1),dr16 */ -#define MOVobw(sr64, or64, dr16) do { \ - emitm(&stream, 0x8b66, 2); \ - emitm(&stream, ((dr16 & 0x7) << 3) | 4, 1); \ - emitm(&stream, ((or64 & 0x7) << 3) | (sr64 & 0x7), 1); \ -} while (0) - -/* movb (sr64,or64,1),dr8 */ -#define MOVobb(sr64, or64, dr8) do { \ - emitm(&stream, 0x8a, 1); \ - emitm(&stream, ((dr8 & 0x7) << 3) | 4, 1); \ - emitm(&stream, ((or64 & 0x7) << 3) | (sr64 & 0x7), 1); \ -} while (0) - -/* movl sr32,(dr64,or64,1) */ -#define MOVomd(sr32, dr64, or64) do { \ - emitm(&stream, 0x89, 1); \ - emitm(&stream, ((sr32 & 0x7) << 3) | 4, 1); \ - emitm(&stream, ((or64 & 0x7) << 3) | (dr64 & 0x7), 1); \ -} while (0) - -/* bswapl dr32 */ -#define BSWAP(dr32) do { \ - emitm(&stream, 0xf, 1); \ - emitm(&stream, (0x19 << 3) | dr32, 1); \ -} while (0) - -/* xchgb %al,%ah */ -#define SWAP_AX() do { \ - emitm(&stream, 0xc486, 2); \ -} while (0) - -/* pushq r64 */ -#define PUSH(r64) do { \ - emitm(&stream, (5 << 4) | (0 << 3) | (r64 & 0x7), 1); \ -} while (0) - -/* leaveq */ -#define LEAVE() do { \ - emitm(&stream, 0xc9, 1); \ -} while (0) - -/* retq */ -#define RET() do { \ - emitm(&stream, 0xc3, 1); \ -} while (0) - -/* addl sr32,dr32 */ -#define ADDrd(sr32, dr32) do { \ - emitm(&stream, 0x01, 1); \ - emitm(&stream, \ - (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ -} while (0) - -/* addl i32,%eax */ -#define ADD_EAXi(i32) do { \ - emitm(&stream, 0x05, 1); \ - emitm(&stream, i32, 4); \ -} while (0) - -/* addl i8,r32 */ -#define ADDib(i8, r32) do { \ - emitm(&stream, 0x83, 1); \ - emitm(&stream, (24 << 3) | r32, 1); \ - emitm(&stream, i8, 1); \ -} while (0) - -/* subl sr32,dr32 */ -#define SUBrd(sr32, dr32) do { \ - emitm(&stream, 0x29, 1); \ - emitm(&stream, \ - (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ -} while (0) - -/* subl i32,%eax */ -#define SUB_EAXi(i32) do { \ - emitm(&stream, 0x2d, 1); \ - emitm(&stream, i32, 4); \ -} while (0) - -/* subq i8,r64 */ -#define SUBib(i8, r64) do { \ - emitm(&stream, 0x8348, 2); \ - emitm(&stream, (29 << 3) | (r64 & 0x7), 1); \ - emitm(&stream, i8, 1); \ -} while (0) - -/* mull r32 */ -#define MULrd(r32) do { \ - emitm(&stream, 0xf7, 1); \ - emitm(&stream, (7 << 5) | (r32 & 0x7), 1); \ -} while (0) - -/* divl r32 */ -#define DIVrd(r32) do { \ - emitm(&stream, 0xf7, 1); \ - emitm(&stream, (15 << 4) | (r32 & 0x7), 1); \ -} while (0) - -/* andb i8,r8 */ -#define ANDib(i8, r8) do { \ - if (r8 == AL) { \ - emitm(&stream, 0x24, 1); \ - } else { \ - emitm(&stream, 0x80, 1); \ - emitm(&stream, (7 << 5) | r8, 1); \ - } \ - emitm(&stream, i8, 1); \ -} while (0) - -/* andl i32,r32 */ -#define ANDid(i32, r32) do { \ - if (r32 == EAX) { \ - emitm(&stream, 0x25, 1); \ - } else { \ - emitm(&stream, 0x81, 1); \ - emitm(&stream, (7 << 5) | r32, 1); \ - } \ - emitm(&stream, i32, 4); \ -} while (0) - -/* andl sr32,dr32 */ -#define ANDrd(sr32, dr32) do { \ - emitm(&stream, 0x21, 1); \ - emitm(&stream, \ - (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ -} while (0) - -/* testl i32,r32 */ -#define TESTid(i32, r32) do { \ - if (r32 == EAX) { \ - emitm(&stream, 0xa9, 1); \ - } else { \ - emitm(&stream, 0xf7, 1); \ - emitm(&stream, (3 << 6) | r32, 1); \ - } \ - emitm(&stream, i32, 4); \ -} while (0) - -/* testl sr32,dr32 */ -#define TESTrd(sr32, dr32) do { \ - emitm(&stream, 0x85, 1); \ - emitm(&stream, \ - (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ -} while (0) - -/* orl sr32,dr32 */ -#define ORrd(sr32, dr32) do { \ - emitm(&stream, 0x09, 1); \ - emitm(&stream, \ - (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ -} while (0) - -/* orl i32,r32 */ -#define ORid(i32, r32) do { \ - if (r32 == EAX) { \ - emitm(&stream, 0x0d, 1); \ - } else { \ - emitm(&stream, 0x81, 1); \ - emitm(&stream, (25 << 3) | r32, 1); \ - } \ - emitm(&stream, i32, 4); \ -} while (0) - -/* shll i8,r32 */ -#define SHLib(i8, r32) do { \ - emitm(&stream, 0xc1, 1); \ - emitm(&stream, (7 << 5) | (r32 & 0x7), 1); \ - emitm(&stream, i8, 1); \ -} while (0) - -/* shll %cl,dr32 */ -#define SHL_CLrb(dr32) do { \ - emitm(&stream, 0xd3, 1); \ - emitm(&stream, (7 << 5) | (dr32 & 0x7), 1); \ -} while (0) - -/* shrl i8,r32 */ -#define SHRib(i8, r32) do { \ - emitm(&stream, 0xc1, 1); \ - emitm(&stream, (29 << 3) | (r32 & 0x7), 1); \ - emitm(&stream, i8, 1); \ -} while (0) - -/* shrl %cl,dr32 */ -#define SHR_CLrb(dr32) do { \ - emitm(&stream, 0xd3, 1); \ - emitm(&stream, (29 << 3) | (dr32 & 0x7), 1); \ -} while (0) - -/* negl r32 */ -#define NEGd(r32) do { \ - emitm(&stream, 0xf7, 1); \ - emitm(&stream, (27 << 3) | (r32 & 0x7), 1); \ -} while (0) - -/* cmpl sr32,dr32 */ -#define CMPrd(sr32, dr32) do { \ - emitm(&stream, 0x39, 1); \ - emitm(&stream, \ - (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ -} while (0) - -/* cmpl i32,dr32 */ -#define CMPid(i32, dr32) do { \ - if (dr32 == EAX){ \ - emitm(&stream, 0x3d, 1); \ - emitm(&stream, i32, 4); \ - } else { \ - emitm(&stream, 0x81, 1); \ - emitm(&stream, (0x1f << 3) | (dr32 & 0x7), 1); \ - emitm(&stream, i32, 4); \ - } \ -} while (0) - -/* jb off8 */ -#define JBb(off8) do { \ - emitm(&stream, 0x72, 1); \ - emitm(&stream, off8, 1); \ -} while (0) - -/* jae off8 */ -#define JAEb(off8) do { \ - emitm(&stream, 0x73, 1); \ - emitm(&stream, off8, 1); \ -} while (0) - -/* jne off8 */ -#define JNEb(off8) do { \ - emitm(&stream, 0x75, 1); \ - emitm(&stream, off8, 1); \ -} while (0) - -/* ja off8 */ -#define JAb(off8) do { \ - emitm(&stream, 0x77, 1); \ - emitm(&stream, off8, 1); \ -} while (0) - -/* jmp off32 */ -#define JMP(off32) do { \ - emitm(&stream, 0xe9, 1); \ - emitm(&stream, off32, 4); \ -} while (0) - -/* xorl r32,r32 */ -#define ZEROrd(r32) do { \ - emitm(&stream, 0x31, 1); \ - emitm(&stream, (3 << 6) | ((r32 & 0x7) << 3) | (r32 & 0x7), 1); \ -} while (0) - -/* - * Conditional long jumps - */ -#define JB 0x82 -#define JAE 0x83 -#define JE 0x84 -#define JNE 0x85 -#define JBE 0x86 -#define JA 0x87 - -#define JCC(t, f) do { \ - if (ins->jt != 0 && ins->jf != 0) { \ - /* 5 is the size of the following jmp */ \ - emitm(&stream, ((t) << 8) | 0x0f, 2); \ - emitm(&stream, stream.refs[stream.bpf_pc + ins->jt] - \ - stream.refs[stream.bpf_pc] + 5, 4); \ - JMP(stream.refs[stream.bpf_pc + ins->jf] - \ - stream.refs[stream.bpf_pc]); \ - } else if (ins->jt != 0) { \ - emitm(&stream, ((t) << 8) | 0x0f, 2); \ - emitm(&stream, stream.refs[stream.bpf_pc + ins->jt] - \ - stream.refs[stream.bpf_pc], 4); \ - } else { \ - emitm(&stream, ((f) << 8) | 0x0f, 2); \ - emitm(&stream, stream.refs[stream.bpf_pc + ins->jf] - \ - stream.refs[stream.bpf_pc], 4); \ - } \ -} while (0) - -#define JUMP(off) do { \ - if ((off) != 0) \ - JMP(stream.refs[stream.bpf_pc + (off)] - \ - stream.refs[stream.bpf_pc]); \ -} while (0) - -#endif /* _BPF_JIT_MACHDEP_H_ */ diff --git a/sys/arch/amd64/conf/files.amd64 b/sys/arch/amd64/conf/files.amd64 index d7f2c6df43f1..8317af3a7f29 100644 --- a/sys/arch/amd64/conf/files.amd64 +++ b/sys/arch/amd64/conf/files.amd64 @@ -1,4 +1,4 @@ -# $NetBSD: files.amd64,v 1.76 2012/08/01 23:24:29 rmind Exp $ +# $NetBSD: files.amd64,v 1.77 2012/09/27 18:28:55 alnsn Exp $ # # new style config file for amd64 architecture # @@ -31,7 +31,6 @@ defflag eisa.h EISA file arch/amd64/amd64/amd64func.S file arch/amd64/amd64/autoconf.c file arch/amd64/amd64/busfunc.S -file arch/amd64/amd64/bpf_jit_machdep.c bpf_filter file arch/amd64/amd64/cpu_in_cksum.S (inet | inet6) & cpu_in_cksum file arch/amd64/amd64/cpufunc.S file arch/amd64/amd64/db_disasm.c ddb diff --git a/sys/arch/amd64/conf/std.amd64 b/sys/arch/amd64/conf/std.amd64 index 1ef8ed325af0..0692dd2adb53 100644 --- a/sys/arch/amd64/conf/std.amd64 +++ b/sys/arch/amd64/conf/std.amd64 @@ -1,11 +1,10 @@ -# $NetBSD: std.amd64,v 1.8 2012/08/01 23:24:29 rmind Exp $ +# $NetBSD: std.amd64,v 1.9 2012/09/27 18:28:55 alnsn Exp $ # # standard, required NetBSD/amd64 'options' machine amd64 x86 include "conf/std" # MI standard options -options BPF_JIT options CPU_IN_CKSUM options EXEC_ELF64 # exec ELF binaries options EXEC_SCRIPT # exec #! scripts diff --git a/sys/arch/i386/conf/files.i386 b/sys/arch/i386/conf/files.i386 index 2e7e7ac97f0d..2063e0f90712 100644 --- a/sys/arch/i386/conf/files.i386 +++ b/sys/arch/i386/conf/files.i386 @@ -1,4 +1,4 @@ -# $NetBSD: files.i386,v 1.364 2012/08/01 23:24:29 rmind Exp $ +# $NetBSD: files.i386,v 1.365 2012/09/27 18:28:55 alnsn Exp $ # # new style config file for i386 architecture # @@ -61,7 +61,6 @@ file arch/i386/i386/multiboot.c multiboot file arch/i386/i386/autoconf.c file arch/i386/i386/aout_machdep.c exec_aout -file arch/i386/i386/bpf_jit_machdep.c bpf_filter file arch/i386/i386/busfunc.S file arch/i386/i386/cpufunc.S file arch/i386/i386/cpu_in_cksum.S (inet | inet6) & cpu_in_cksum diff --git a/sys/arch/i386/conf/std.i386 b/sys/arch/i386/conf/std.i386 index 1cd8e590e0c6..b5d2154e30d1 100644 --- a/sys/arch/i386/conf/std.i386 +++ b/sys/arch/i386/conf/std.i386 @@ -1,11 +1,10 @@ -# $NetBSD: std.i386,v 1.32 2012/08/01 23:24:29 rmind Exp $ +# $NetBSD: std.i386,v 1.33 2012/09/27 18:28:55 alnsn Exp $ # # standard, required NetBSD/i386 'options' machine i386 x86 include "conf/std" # MI standard options -options BPF_JIT options CPU_IN_CKSUM options EXEC_AOUT # exec a.out binaries options EXEC_ELF32 # exec ELF binaries diff --git a/sys/arch/i386/i386/bpf_jit_machdep.c b/sys/arch/i386/i386/bpf_jit_machdep.c deleted file mode 100644 index b4025be022c9..000000000000 --- a/sys/arch/i386/i386/bpf_jit_machdep.c +++ /dev/null @@ -1,686 +0,0 @@ -/* $NetBSD: bpf_jit_machdep.c,v 1.1 2012/08/01 23:24:28 rmind Exp $ */ - -/*- - * Copyright (C) 2002-2003 NetGroup, Politecnico di Torino (Italy) - * Copyright (C) 2005-2009 Jung-uk Kim - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Politecnico di Torino nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD: src/sys/i386/i386/bpf_jit_machdep.c, - * v 1.22 2010/04/22 23:47:19 jkim Exp $ - */ - -#include -__KERNEL_RCSID(0, "$NetBSD: bpf_jit_machdep.c,v 1.1 2012/08/01 23:24:28 rmind Exp $"); - -#ifdef _KERNEL -#if defined(_KERNEL_OPT) -#include "opt_bpf.h" -#endif - -#include -#include -#include -#include -#include -#include -#else -#include -#include -#include -#include -#endif - -#include - -#include -#include - -#include - -bpf_filter_func bpf_jit_compile(struct bpf_insn *, u_int, size_t *); - -/* - * Emit routine to update the jump table. - */ -static void -emit_length(bpf_bin_stream *stream, __unused u_int value, u_int len) -{ - - if (stream->refs != NULL) - (stream->refs)[stream->bpf_pc] += len; - stream->cur_ip += len; -} - -/* - * Emit routine to output the actual binary code. - */ -static void -emit_code(bpf_bin_stream *stream, u_int value, u_int len) -{ - - switch (len) { - case 1: - stream->ibuf[stream->cur_ip] = (u_char)value; - stream->cur_ip++; - break; - case 2: - *((u_short *)(stream->ibuf + stream->cur_ip)) = (u_short)value; - stream->cur_ip += 2; - break; - case 4: - *((u_int *)(stream->ibuf + stream->cur_ip)) = value; - stream->cur_ip += 4; - break; - } -} - -/* - * Scan the filter program and find possible optimization. - */ -static int -bpf_jit_optimize(struct bpf_insn *prog, u_int nins) -{ - int flags; - u_int i; - - /* Do we return immediately? */ - if (BPF_CLASS(prog[0].code) == BPF_RET) - return (BPF_JIT_FRET); - - for (flags = 0, i = 0; i < nins; i++) { - switch (prog[i].code) { - case BPF_LD|BPF_W|BPF_ABS: - case BPF_LD|BPF_H|BPF_ABS: - case BPF_LD|BPF_B|BPF_ABS: - case BPF_LD|BPF_W|BPF_IND: - case BPF_LD|BPF_H|BPF_IND: - case BPF_LD|BPF_B|BPF_IND: - case BPF_LDX|BPF_MSH|BPF_B: - flags |= BPF_JIT_FPKT; - break; - case BPF_LD|BPF_MEM: - case BPF_LDX|BPF_MEM: - case BPF_ST: - case BPF_STX: - flags |= BPF_JIT_FMEM; - break; - case BPF_JMP|BPF_JA: - case BPF_JMP|BPF_JGT|BPF_K: - case BPF_JMP|BPF_JGE|BPF_K: - case BPF_JMP|BPF_JEQ|BPF_K: - case BPF_JMP|BPF_JSET|BPF_K: - case BPF_JMP|BPF_JGT|BPF_X: - case BPF_JMP|BPF_JGE|BPF_X: - case BPF_JMP|BPF_JEQ|BPF_X: - case BPF_JMP|BPF_JSET|BPF_X: - flags |= BPF_JIT_FJMP; - break; - case BPF_ALU|BPF_DIV|BPF_K: - flags |= BPF_JIT_FADK; - break; - } - if (flags == BPF_JIT_FLAG_ALL) - break; - } - - return (flags); -} - -/* - * Function that does the real stuff. - */ -bpf_filter_func -bpf_jit_compile(struct bpf_insn *prog, u_int nins, size_t *size) -{ - bpf_bin_stream stream; - struct bpf_insn *ins; - int flags, fret, fpkt, fmem, fjmp, fadk; - int save_esp; - u_int i, pass; - - /* - * NOTE: Do not modify the name of this variable, as it's used by - * the macros to emit code. - */ - emit_func emitm; - - flags = bpf_jit_optimize(prog, nins); - fret = (flags & BPF_JIT_FRET) != 0; - fpkt = (flags & BPF_JIT_FPKT) != 0; - fmem = (flags & BPF_JIT_FMEM) != 0; - fjmp = (flags & BPF_JIT_FJMP) != 0; - fadk = (flags & BPF_JIT_FADK) != 0; - save_esp = (fpkt || fmem || fadk); /* Stack is used. */ - - if (fret) - nins = 1; - - memset(&stream, 0, sizeof(stream)); - - /* Allocate the reference table for the jumps. */ - if (fjmp) { -#ifdef _KERNEL - stream.refs = malloc((nins + 1) * sizeof(u_int), M_TEMP, - M_NOWAIT | M_ZERO); -#else - stream.refs = calloc(nins + 1, sizeof(u_int)); -#endif - if (stream.refs == NULL) - return (NULL); - } - - /* - * The first pass will emit the lengths of the instructions - * to create the reference table. - */ - emitm = emit_length; - - for (pass = 0; pass < 2; pass++) { - ins = prog; - - /* Create the procedure header. */ - if (save_esp) { - PUSH(EBP); - MOVrd(ESP, EBP); - } - if (fmem) - SUBib(BPF_MEMWORDS * sizeof(uint32_t), ESP); - if (save_esp) - PUSH(ESI); - if (fpkt) { - PUSH(EDI); - PUSH(EBX); - MOVodd(8, EBP, EBX); - MOVodd(16, EBP, EDI); - } - - for (i = 0; i < nins; i++) { - stream.bpf_pc++; - - switch (ins->code) { - default: -#ifdef _KERNEL - return (NULL); -#else - abort(); -#endif - - case BPF_RET|BPF_K: - MOVid(ins->k, EAX); - if (save_esp) { - if (fpkt) { - POP(EBX); - POP(EDI); - } - POP(ESI); - LEAVE(); - } - RET(); - break; - - case BPF_RET|BPF_A: - if (save_esp) { - if (fpkt) { - POP(EBX); - POP(EDI); - } - POP(ESI); - LEAVE(); - } - RET(); - break; - - case BPF_LD|BPF_W|BPF_ABS: - MOVid(ins->k, ESI); - CMPrd(EDI, ESI); - JAb(12); - MOVrd(EDI, ECX); - SUBrd(ESI, ECX); - CMPid(sizeof(int32_t), ECX); - JAEb(7); - ZEROrd(EAX); - POP(EBX); - POP(EDI); - POP(ESI); - LEAVE(); - RET(); - MOVobd(EBX, ESI, EAX); - BSWAP(EAX); - break; - - case BPF_LD|BPF_H|BPF_ABS: - ZEROrd(EAX); - MOVid(ins->k, ESI); - CMPrd(EDI, ESI); - JAb(12); - MOVrd(EDI, ECX); - SUBrd(ESI, ECX); - CMPid(sizeof(int16_t), ECX); - JAEb(5); - POP(EBX); - POP(EDI); - POP(ESI); - LEAVE(); - RET(); - MOVobw(EBX, ESI, AX); - SWAP_AX(); - break; - - case BPF_LD|BPF_B|BPF_ABS: - ZEROrd(EAX); - MOVid(ins->k, ESI); - CMPrd(EDI, ESI); - JBb(5); - POP(EBX); - POP(EDI); - POP(ESI); - LEAVE(); - RET(); - MOVobb(EBX, ESI, AL); - break; - - case BPF_LD|BPF_W|BPF_LEN: - if (save_esp) - MOVodd(12, EBP, EAX); - else { - MOVrd(ESP, ECX); - MOVodd(12, ECX, EAX); - } - break; - - case BPF_LDX|BPF_W|BPF_LEN: - if (save_esp) - MOVodd(12, EBP, EDX); - else { - MOVrd(ESP, ECX); - MOVodd(12, ECX, EDX); - } - break; - - case BPF_LD|BPF_W|BPF_IND: - CMPrd(EDI, EDX); - JAb(27); - MOVid(ins->k, ESI); - MOVrd(EDI, ECX); - SUBrd(EDX, ECX); - CMPrd(ESI, ECX); - JBb(14); - ADDrd(EDX, ESI); - MOVrd(EDI, ECX); - SUBrd(ESI, ECX); - CMPid(sizeof(int32_t), ECX); - JAEb(7); - ZEROrd(EAX); - POP(EBX); - POP(EDI); - POP(ESI); - LEAVE(); - RET(); - MOVobd(EBX, ESI, EAX); - BSWAP(EAX); - break; - - case BPF_LD|BPF_H|BPF_IND: - ZEROrd(EAX); - CMPrd(EDI, EDX); - JAb(27); - MOVid(ins->k, ESI); - MOVrd(EDI, ECX); - SUBrd(EDX, ECX); - CMPrd(ESI, ECX); - JBb(14); - ADDrd(EDX, ESI); - MOVrd(EDI, ECX); - SUBrd(ESI, ECX); - CMPid(sizeof(int16_t), ECX); - JAEb(5); - POP(EBX); - POP(EDI); - POP(ESI); - LEAVE(); - RET(); - MOVobw(EBX, ESI, AX); - SWAP_AX(); - break; - - case BPF_LD|BPF_B|BPF_IND: - ZEROrd(EAX); - CMPrd(EDI, EDX); - JAEb(13); - MOVid(ins->k, ESI); - MOVrd(EDI, ECX); - SUBrd(EDX, ECX); - CMPrd(ESI, ECX); - JAb(5); - POP(EBX); - POP(EDI); - POP(ESI); - LEAVE(); - RET(); - ADDrd(EDX, ESI); - MOVobb(EBX, ESI, AL); - break; - - case BPF_LDX|BPF_MSH|BPF_B: - MOVid(ins->k, ESI); - CMPrd(EDI, ESI); - JBb(7); - ZEROrd(EAX); - POP(EBX); - POP(EDI); - POP(ESI); - LEAVE(); - RET(); - ZEROrd(EDX); - MOVobb(EBX, ESI, DL); - ANDib(0x0f, DL); - SHLib(2, EDX); - break; - - case BPF_LD|BPF_IMM: - MOVid(ins->k, EAX); - break; - - case BPF_LDX|BPF_IMM: - MOVid(ins->k, EDX); - break; - - case BPF_LD|BPF_MEM: - MOVrd(EBP, ECX); - MOVid(((int)ins->k - BPF_MEMWORDS) * - sizeof(uint32_t), ESI); - MOVobd(ECX, ESI, EAX); - break; - - case BPF_LDX|BPF_MEM: - MOVrd(EBP, ECX); - MOVid(((int)ins->k - BPF_MEMWORDS) * - sizeof(uint32_t), ESI); - MOVobd(ECX, ESI, EDX); - break; - - case BPF_ST: - /* - * XXX this command and the following could - * be optimized if the previous instruction - * was already of this type - */ - MOVrd(EBP, ECX); - MOVid(((int)ins->k - BPF_MEMWORDS) * - sizeof(uint32_t), ESI); - MOVomd(EAX, ECX, ESI); - break; - - case BPF_STX: - MOVrd(EBP, ECX); - MOVid(((int)ins->k - BPF_MEMWORDS) * - sizeof(uint32_t), ESI); - MOVomd(EDX, ECX, ESI); - break; - - case BPF_JMP|BPF_JA: - JUMP(ins->k); - break; - - case BPF_JMP|BPF_JGT|BPF_K: - if (ins->jt == ins->jf) { - JUMP(ins->jt); - break; - } - CMPid(ins->k, EAX); - JCC(JA, JBE); - break; - - case BPF_JMP|BPF_JGE|BPF_K: - if (ins->jt == ins->jf) { - JUMP(ins->jt); - break; - } - CMPid(ins->k, EAX); - JCC(JAE, JB); - break; - - case BPF_JMP|BPF_JEQ|BPF_K: - if (ins->jt == ins->jf) { - JUMP(ins->jt); - break; - } - CMPid(ins->k, EAX); - JCC(JE, JNE); - break; - - case BPF_JMP|BPF_JSET|BPF_K: - if (ins->jt == ins->jf) { - JUMP(ins->jt); - break; - } - TESTid(ins->k, EAX); - JCC(JNE, JE); - break; - - case BPF_JMP|BPF_JGT|BPF_X: - if (ins->jt == ins->jf) { - JUMP(ins->jt); - break; - } - CMPrd(EDX, EAX); - JCC(JA, JBE); - break; - - case BPF_JMP|BPF_JGE|BPF_X: - if (ins->jt == ins->jf) { - JUMP(ins->jt); - break; - } - CMPrd(EDX, EAX); - JCC(JAE, JB); - break; - - case BPF_JMP|BPF_JEQ|BPF_X: - if (ins->jt == ins->jf) { - JUMP(ins->jt); - break; - } - CMPrd(EDX, EAX); - JCC(JE, JNE); - break; - - case BPF_JMP|BPF_JSET|BPF_X: - if (ins->jt == ins->jf) { - JUMP(ins->jt); - break; - } - TESTrd(EDX, EAX); - JCC(JNE, JE); - break; - - case BPF_ALU|BPF_ADD|BPF_X: - ADDrd(EDX, EAX); - break; - - case BPF_ALU|BPF_SUB|BPF_X: - SUBrd(EDX, EAX); - break; - - case BPF_ALU|BPF_MUL|BPF_X: - MOVrd(EDX, ECX); - MULrd(EDX); - MOVrd(ECX, EDX); - break; - - case BPF_ALU|BPF_DIV|BPF_X: - TESTrd(EDX, EDX); - if (save_esp) { - if (fpkt) { - JNEb(7); - ZEROrd(EAX); - POP(EBX); - POP(EDI); - } else { - JNEb(5); - ZEROrd(EAX); - } - POP(ESI); - LEAVE(); - } else { - JNEb(3); - ZEROrd(EAX); - } - RET(); - MOVrd(EDX, ECX); - ZEROrd(EDX); - DIVrd(ECX); - MOVrd(ECX, EDX); - break; - - case BPF_ALU|BPF_AND|BPF_X: - ANDrd(EDX, EAX); - break; - - case BPF_ALU|BPF_OR|BPF_X: - ORrd(EDX, EAX); - break; - - case BPF_ALU|BPF_LSH|BPF_X: - MOVrd(EDX, ECX); - SHL_CLrb(EAX); - break; - - case BPF_ALU|BPF_RSH|BPF_X: - MOVrd(EDX, ECX); - SHR_CLrb(EAX); - break; - - case BPF_ALU|BPF_ADD|BPF_K: - ADD_EAXi(ins->k); - break; - - case BPF_ALU|BPF_SUB|BPF_K: - SUB_EAXi(ins->k); - break; - - case BPF_ALU|BPF_MUL|BPF_K: - MOVrd(EDX, ECX); - MOVid(ins->k, EDX); - MULrd(EDX); - MOVrd(ECX, EDX); - break; - - case BPF_ALU|BPF_DIV|BPF_K: - MOVrd(EDX, ECX); - ZEROrd(EDX); - MOVid(ins->k, ESI); - DIVrd(ESI); - MOVrd(ECX, EDX); - break; - - case BPF_ALU|BPF_AND|BPF_K: - ANDid(ins->k, EAX); - break; - - case BPF_ALU|BPF_OR|BPF_K: - ORid(ins->k, EAX); - break; - - case BPF_ALU|BPF_LSH|BPF_K: - SHLib((ins->k) & 0xff, EAX); - break; - - case BPF_ALU|BPF_RSH|BPF_K: - SHRib((ins->k) & 0xff, EAX); - break; - - case BPF_ALU|BPF_NEG: - NEGd(EAX); - break; - - case BPF_MISC|BPF_TAX: - MOVrd(EAX, EDX); - break; - - case BPF_MISC|BPF_TXA: - MOVrd(EDX, EAX); - break; - } - ins++; - } - - if (pass > 0) - continue; - - *size = stream.cur_ip; -#ifdef _KERNEL - stream.ibuf = malloc(*size, M_TEMP, M_NOWAIT); - if (stream.ibuf == NULL) - break; -#else - stream.ibuf = mmap(NULL, *size, PROT_READ | PROT_WRITE, - MAP_ANON, -1, 0); - if (stream.ibuf == MAP_FAILED) { - stream.ibuf = NULL; - break; - } -#endif - - /* - * Modify the reference table to contain the offsets and - * not the lengths of the instructions. - */ - if (fjmp) - for (i = 1; i < nins + 1; i++) - stream.refs[i] += stream.refs[i - 1]; - - /* Reset the counters. */ - stream.cur_ip = 0; - stream.bpf_pc = 0; - - /* The second pass creates the actual code. */ - emitm = emit_code; - } - - /* - * The reference table is needed only during compilation, - * now we can free it. - */ - if (fjmp) -#ifdef _KERNEL - free(stream.refs, M_TEMP); -#else - free(stream.refs); -#endif - -#ifndef _KERNEL - if (stream.ibuf != NULL && - mprotect(stream.ibuf, *size, PROT_READ | PROT_EXEC) != 0) { - munmap(stream.ibuf, *size); - stream.ibuf = NULL; - } -#endif - - return ((bpf_filter_func)stream.ibuf); -} diff --git a/sys/arch/i386/i386/bpf_jit_machdep.h b/sys/arch/i386/i386/bpf_jit_machdep.h deleted file mode 100644 index 87bc7f3ad066..000000000000 --- a/sys/arch/i386/i386/bpf_jit_machdep.h +++ /dev/null @@ -1,430 +0,0 @@ -/* $NetBSD: bpf_jit_machdep.h,v 1.1 2012/08/01 23:24:28 rmind Exp $ */ - -/*- - * Copyright (C) 2002-2003 NetGroup, Politecnico di Torino (Italy) - * Copyright (C) 2005-2009 Jung-uk Kim - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Politecnico di Torino nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD: src/sys/i386/i386/bpf_jit_machdep.h, - * v 1.15 2010/04/22 23:47:19 jkim Exp $ - */ - -#ifndef _BPF_JIT_MACHDEP_H_ -#define _BPF_JIT_MACHDEP_H_ - -/* - * Registers - */ -#define EAX 0 -#define ECX 1 -#define EDX 2 -#define EBX 3 -#define ESP 4 -#define EBP 5 -#define ESI 6 -#define EDI 7 - -#define AX 0 -#define CX 1 -#define DX 2 -#define BX 3 -#define SP 4 -#define BP 5 -#define SI 6 -#define DI 7 - -#define AL 0 -#define CL 1 -#define DL 2 -#define BL 3 - -/* Optimization flags */ -#define BPF_JIT_FRET 0x01 -#define BPF_JIT_FPKT 0x02 -#define BPF_JIT_FMEM 0x04 -#define BPF_JIT_FJMP 0x08 -#define BPF_JIT_FADK 0x10 - -#define BPF_JIT_FLAG_ALL \ - (BPF_JIT_FPKT | BPF_JIT_FMEM | BPF_JIT_FJMP | BPF_JIT_FADK) - -/* A stream of native binary code */ -typedef struct bpf_bin_stream { - /* Current native instruction pointer. */ - int cur_ip; - - /* - * Current BPF instruction pointer, i.e. position in - * the BPF program reached by the jitter. - */ - int bpf_pc; - - /* Instruction buffer, contains the generated native code. */ - char *ibuf; - - /* Jumps reference table. */ - u_int *refs; -} bpf_bin_stream; - -/* - * Prototype of the emit functions. - * - * Different emit functions are used to create the reference table and - * to generate the actual filtering code. This allows to have simpler - * instruction macros. - * The first parameter is the stream that will receive the data. - * The second one is a variable containing the data. - * The third one is the length, that can be 1, 2, or 4 since it is possible - * to emit a byte, a short, or a word at a time. - */ -typedef void (*emit_func)(bpf_bin_stream *, u_int, u_int); - -/* - * Native instruction macros - */ - -/* movl i32,r32 */ -#define MOVid(i32, r32) do { \ - emitm(&stream, (11 << 4) | (1 << 3) | (r32 & 0x7), 1); \ - emitm(&stream, i32, 4); \ -} while (0) - -/* movl sr32,dr32 */ -#define MOVrd(sr32, dr32) do { \ - emitm(&stream, 0x89, 1); \ - emitm(&stream, \ - (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ -} while (0) - -/* movl off(sr32),dr32 */ -#define MOVodd(off, sr32, dr32) do { \ - emitm(&stream, 0x8b, 1); \ - emitm(&stream, \ - (1 << 6) | ((dr32 & 0x7) << 3) | (sr32 & 0x7), 1); \ - emitm(&stream, off, 1); \ -} while (0) - -/* movl (sr32,or32,1),dr32 */ -#define MOVobd(sr32, or32, dr32) do { \ - emitm(&stream, 0x8b, 1); \ - emitm(&stream, ((dr32 & 0x7) << 3) | 4, 1); \ - emitm(&stream, ((or32 & 0x7) << 3) | (sr32 & 0x7), 1); \ -} while (0) - -/* movw (sr32,or32,1),dr16 */ -#define MOVobw(sr32, or32, dr16) do { \ - emitm(&stream, 0x8b66, 2); \ - emitm(&stream, ((dr16 & 0x7) << 3) | 4, 1); \ - emitm(&stream, ((or32 & 0x7) << 3) | (sr32 & 0x7), 1); \ -} while (0) - -/* movb (sr32,or32,1),dr8 */ -#define MOVobb(sr32, or32, dr8) do { \ - emitm(&stream, 0x8a, 1); \ - emitm(&stream, ((dr8 & 0x7) << 3) | 4, 1); \ - emitm(&stream, ((or32 & 0x7) << 3) | (sr32 & 0x7), 1); \ -} while (0) - -/* movl sr32,(dr32,or32,1) */ -#define MOVomd(sr32, dr32, or32) do { \ - emitm(&stream, 0x89, 1); \ - emitm(&stream, ((sr32 & 0x7) << 3) | 4, 1); \ - emitm(&stream, ((or32 & 0x7) << 3) | (dr32 & 0x7), 1); \ -} while (0) - -/* bswapl dr32 */ -#define BSWAP(dr32) do { \ - emitm(&stream, 0xf, 1); \ - emitm(&stream, (0x19 << 3) | dr32, 1); \ -} while (0) - -/* xchgb %al,%ah */ -#define SWAP_AX() do { \ - emitm(&stream, 0xc486, 2); \ -} while (0) - -/* pushl r32 */ -#define PUSH(r32) do { \ - emitm(&stream, (5 << 4) | (0 << 3) | (r32 & 0x7), 1); \ -} while (0) - -/* popl r32 */ -#define POP(r32) do { \ - emitm(&stream, (5 << 4) | (1 << 3) | (r32 & 0x7), 1); \ -} while (0) - -/* leave */ -#define LEAVE() do { \ - emitm(&stream, 0xc9, 1); \ -} while (0) - -/* ret */ -#define RET() do { \ - emitm(&stream, 0xc3, 1); \ -} while (0) - -/* addl sr32,dr32 */ -#define ADDrd(sr32, dr32) do { \ - emitm(&stream, 0x01, 1); \ - emitm(&stream, \ - (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ -} while (0) - -/* addl i32,%eax */ -#define ADD_EAXi(i32) do { \ - emitm(&stream, 0x05, 1); \ - emitm(&stream, i32, 4); \ -} while (0) - -/* addl i8,r32 */ -#define ADDib(i8, r32) do { \ - emitm(&stream, 0x83, 1); \ - emitm(&stream, (24 << 3) | r32, 1); \ - emitm(&stream, i8, 1); \ -} while (0) - -/* subl sr32,dr32 */ -#define SUBrd(sr32, dr32) do { \ - emitm(&stream, 0x29, 1); \ - emitm(&stream, \ - (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ -} while (0) - -/* subl i32,%eax */ -#define SUB_EAXi(i32) do { \ - emitm(&stream, 0x2d, 1); \ - emitm(&stream, i32, 4); \ -} while (0) - -/* subl i8,r32 */ -#define SUBib(i8, r32) do { \ - emitm(&stream, 0x83, 1); \ - emitm(&stream, (29 << 3) | (r32 & 0x7), 1); \ - emitm(&stream, i8, 1); \ -} while (0) - -/* mull r32 */ -#define MULrd(r32) do { \ - emitm(&stream, 0xf7, 1); \ - emitm(&stream, (7 << 5) | (r32 & 0x7), 1); \ -} while (0) - -/* divl r32 */ -#define DIVrd(r32) do { \ - emitm(&stream, 0xf7, 1); \ - emitm(&stream, (15 << 4) | (r32 & 0x7), 1); \ -} while (0) - -/* andb i8,r8 */ -#define ANDib(i8, r8) do { \ - if (r8 == AL) { \ - emitm(&stream, 0x24, 1); \ - } else { \ - emitm(&stream, 0x80, 1); \ - emitm(&stream, (7 << 5) | r8, 1); \ - } \ - emitm(&stream, i8, 1); \ -} while (0) - -/* andl i32,r32 */ -#define ANDid(i32, r32) do { \ - if (r32 == EAX) { \ - emitm(&stream, 0x25, 1); \ - } else { \ - emitm(&stream, 0x81, 1); \ - emitm(&stream, (7 << 5) | r32, 1); \ - } \ - emitm(&stream, i32, 4); \ -} while (0) - -/* andl sr32,dr32 */ -#define ANDrd(sr32, dr32) do { \ - emitm(&stream, 0x21, 1); \ - emitm(&stream, \ - (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ -} while (0) - -/* testl i32,r32 */ -#define TESTid(i32, r32) do { \ - if (r32 == EAX) { \ - emitm(&stream, 0xa9, 1); \ - } else { \ - emitm(&stream, 0xf7, 1); \ - emitm(&stream, (3 << 6) | r32, 1); \ - } \ - emitm(&stream, i32, 4); \ -} while (0) - -/* testl sr32,dr32 */ -#define TESTrd(sr32, dr32) do { \ - emitm(&stream, 0x85, 1); \ - emitm(&stream, \ - (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ -} while (0) - -/* orl sr32,dr32 */ -#define ORrd(sr32, dr32) do { \ - emitm(&stream, 0x09, 1); \ - emitm(&stream, \ - (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ -} while (0) - -/* orl i32,r32 */ -#define ORid(i32, r32) do { \ - if (r32 == EAX) { \ - emitm(&stream, 0x0d, 1); \ - } else { \ - emitm(&stream, 0x81, 1); \ - emitm(&stream, (25 << 3) | r32, 1); \ - } \ - emitm(&stream, i32, 4); \ -} while (0) - -/* shll i8,r32 */ -#define SHLib(i8, r32) do { \ - emitm(&stream, 0xc1, 1); \ - emitm(&stream, (7 << 5) | (r32 & 0x7), 1); \ - emitm(&stream, i8, 1); \ -} while (0) - -/* shll %cl,dr32 */ -#define SHL_CLrb(dr32) do { \ - emitm(&stream, 0xd3, 1); \ - emitm(&stream, (7 << 5) | (dr32 & 0x7), 1); \ -} while (0) - -/* shrl i8,r32 */ -#define SHRib(i8, r32) do { \ - emitm(&stream, 0xc1, 1); \ - emitm(&stream, (29 << 3) | (r32 & 0x7), 1); \ - emitm(&stream, i8, 1); \ -} while (0) - -/* shrl %cl,dr32 */ -#define SHR_CLrb(dr32) do { \ - emitm(&stream, 0xd3, 1); \ - emitm(&stream, (29 << 3) | (dr32 & 0x7), 1); \ -} while (0) - -/* negl r32 */ -#define NEGd(r32) do { \ - emitm(&stream, 0xf7, 1); \ - emitm(&stream, (27 << 3) | (r32 & 0x7), 1); \ -} while (0) - -/* cmpl sr32,dr32 */ -#define CMPrd(sr32, dr32) do { \ - emitm(&stream, 0x39, 1); \ - emitm(&stream, \ - (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ -} while (0) - -/* cmpl i32,dr32 */ -#define CMPid(i32, dr32) do { \ - if (dr32 == EAX){ \ - emitm(&stream, 0x3d, 1); \ - emitm(&stream, i32, 4); \ - } else { \ - emitm(&stream, 0x81, 1); \ - emitm(&stream, (0x1f << 3) | (dr32 & 0x7), 1); \ - emitm(&stream, i32, 4); \ - } \ -} while (0) - -/* jb off8 */ -#define JBb(off8) do { \ - emitm(&stream, 0x72, 1); \ - emitm(&stream, off8, 1); \ -} while (0) - -/* jae off8 */ -#define JAEb(off8) do { \ - emitm(&stream, 0x73, 1); \ - emitm(&stream, off8, 1); \ -} while (0) - -/* jne off8 */ -#define JNEb(off8) do { \ - emitm(&stream, 0x75, 1); \ - emitm(&stream, off8, 1); \ -} while (0) - -/* ja off8 */ -#define JAb(off8) do { \ - emitm(&stream, 0x77, 1); \ - emitm(&stream, off8, 1); \ -} while (0) - -/* jmp off32 */ -#define JMP(off32) do { \ - emitm(&stream, 0xe9, 1); \ - emitm(&stream, off32, 4); \ -} while (0) - -/* xorl r32,r32 */ -#define ZEROrd(r32) do { \ - emitm(&stream, 0x31, 1); \ - emitm(&stream, (3 << 6) | ((r32 & 0x7) << 3) | (r32 & 0x7), 1); \ -} while (0) - -/* - * Conditional long jumps - */ -#define JB 0x82 -#define JAE 0x83 -#define JE 0x84 -#define JNE 0x85 -#define JBE 0x86 -#define JA 0x87 - -#define JCC(t, f) do { \ - if (ins->jt != 0 && ins->jf != 0) { \ - /* 5 is the size of the following jmp */ \ - emitm(&stream, ((t) << 8) | 0x0f, 2); \ - emitm(&stream, stream.refs[stream.bpf_pc + ins->jt] - \ - stream.refs[stream.bpf_pc] + 5, 4); \ - JMP(stream.refs[stream.bpf_pc + ins->jf] - \ - stream.refs[stream.bpf_pc]); \ - } else if (ins->jt != 0) { \ - emitm(&stream, ((t) << 8) | 0x0f, 2); \ - emitm(&stream, stream.refs[stream.bpf_pc + ins->jt] - \ - stream.refs[stream.bpf_pc], 4); \ - } else { \ - emitm(&stream, ((f) << 8) | 0x0f, 2); \ - emitm(&stream, stream.refs[stream.bpf_pc + ins->jf] - \ - stream.refs[stream.bpf_pc], 4); \ - } \ -} while (0) - -#define JUMP(off) do { \ - if ((off) != 0) \ - JMP(stream.refs[stream.bpf_pc + (off)] - \ - stream.refs[stream.bpf_pc]); \ -} while (0) - -#endif /* _BPF_JIT_MACHDEP_H_ */ diff --git a/sys/conf/files b/sys/conf/files index 41bbf62160a1..4e093b25fc89 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1,4 +1,4 @@ -# $NetBSD: files,v 1.1057 2012/09/01 11:21:22 matt Exp $ +# $NetBSD: files,v 1.1058 2012/09/27 18:28:56 alnsn Exp $ # @(#)files.newconf 7.5 (Berkeley) 5/10/93 version 20100430 @@ -184,7 +184,6 @@ include "dev/sysmon/files.sysmon" # define bpf_filter defparam opt_bpf.h BPF_BUFSIZE -defflag opt_bpf.h BPF_JIT include "net80211/files.net80211" include "netatalk/files.netatalk" @@ -1648,7 +1647,6 @@ file miscfs/syncfs/sync_vnops.c file net/bpf.c bpfilter file net/bpf_filter.c bpf_filter -file net/bpf_jit.c bpf_filter & bpf_jit file net/bpf_stub.c file net/bsd-comp.c ppp & ppp_bsdcomp file net/if.c diff --git a/sys/modules/bpf/Makefile b/sys/modules/bpf/Makefile index b664d7910db7..cafcfba4cf92 100644 --- a/sys/modules/bpf/Makefile +++ b/sys/modules/bpf/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.3 2012/08/02 00:22:32 matt Exp $ +# $NetBSD: Makefile,v 1.4 2012/09/27 18:28:56 alnsn Exp $ # .include "../Makefile.inc" @@ -10,16 +10,4 @@ KMOD= bpf # inseparable from bpfilter?) SRCS= bpf.c bpf_filter.c -.PATH: ${S}/arch/${MACHINE}/${MACHINE} -.PATH: ${S}/arch/${MACHINE_ARCH}/${MACHINE_ARCH} -.PATH: ${S}/arch/${MACHINE_CPU}/${MACHINE_CPU} - -.if (exists(${S}/arch/${MACHINE}/${MACHINE}/bpf_jit_machdep.c)) || \ - (exists(${S}/arch/${MACHINE_ARCH}/${MACHINE_ARCH}/bpf_jit_machdep.c)) || \ - (exists(${S}/arch/${MACHINE_CPU}/${MACHINE_CPU}/bpf_jit_machdep.c)) -SRCS+= bpf_jit.c -SRCS+= bpf_jit_machdep.c -CPPFLAGS+= -DBPF_JIT -.endif - .include diff --git a/sys/net/Makefile b/sys/net/Makefile index 1ca03a071dbb..52bfd24c1025 100644 --- a/sys/net/Makefile +++ b/sys/net/Makefile @@ -1,8 +1,8 @@ -# $NetBSD: Makefile,v 1.30 2012/08/02 01:16:36 matt Exp $ +# $NetBSD: Makefile,v 1.31 2012/09/27 18:28:56 alnsn Exp $ INCSDIR= /usr/include/net -INCS= bpf.h bpfdesc.h bpf_jit.h dlt.h ethertypes.h if.h if_arc.h if_arp.h \ +INCS= bpf.h bpfdesc.h dlt.h ethertypes.h if.h if_arc.h if_arp.h \ if_atm.h if_bridgevar.h if_dl.h if_ether.h if_etherip.h if_fddi.h if_gif.h \ if_gre.h if_hippi.h if_ieee1394.h if_llc.h if_media.h if_mpls.h \ if_pflog.h if_ppp.h if_pppoe.h if_sppp.h if_srt.h if_stf.h \ diff --git a/sys/net/bpf.c b/sys/net/bpf.c index 2389d3976d82..784c4699f242 100644 --- a/sys/net/bpf.c +++ b/sys/net/bpf.c @@ -1,4 +1,4 @@ -/* $NetBSD: bpf.c,v 1.171 2012/08/15 20:59:51 alnsn Exp $ */ +/* $NetBSD: bpf.c,v 1.172 2012/09/27 18:28:56 alnsn Exp $ */ /* * Copyright (c) 1990, 1991, 1993 @@ -39,7 +39,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.171 2012/08/15 20:59:51 alnsn Exp $"); +__KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.172 2012/09/27 18:28:56 alnsn Exp $"); #if defined(_KERNEL_OPT) #include "opt_bpf.h" @@ -79,7 +79,6 @@ __KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.171 2012/08/15 20:59:51 alnsn Exp $"); #include #include -#include #include #include @@ -120,14 +119,6 @@ struct bpf_stat bpf_gstats; */ static kmutex_t bpf_mtx; -/* BPF JIT compilation. */ -static bool bpf_jit_enable __read_mostly = false; - -#ifndef BPF_JIT -#define bpf_jit(x, y) NULL -#define bpf_destroy_jit_filter(x) (void)x -#endif - /* * bpf_iflist is the list of interfaces; each corresponds to an ifnet * bpf_dtab holds the descriptors, indexed by minor device # @@ -1063,7 +1054,6 @@ int bpf_setf(struct bpf_d *d, struct bpf_program *fp) { struct bpf_insn *fcode, *old; - bpf_jit_filter *jfunc, *ofunc; size_t flen, size; int s; @@ -1085,28 +1075,20 @@ bpf_setf(struct bpf_d *d, struct bpf_program *fp) free(fcode, M_DEVBUF); return EINVAL; } - - /* Perform JIT compilation. */ - jfunc = bpf_jit(fcode, flen); } else { fcode = NULL; - jfunc = NULL; } s = splnet(); old = d->bd_filter; - ofunc = d->bd_bfilter; d->bd_filter = fcode; - d->bd_bfilter = jfunc; reset_d(d); splx(s); if (old) { free(old, M_DEVBUF); } - if (ofunc) { - bpf_destroy_jit_filter(ofunc); - } + return 0; } @@ -1368,7 +1350,6 @@ bpf_deliver(struct bpf_if *bp, void *(*cpfn)(void *, const void *, size_t), * interfaces shared any data. This is not the case. */ for (d = bp->bif_dlist; d != NULL; d = d->bd_next) { - bpf_jit_filter *bf; u_int slen; if (!d->bd_seesent && !rcv) { @@ -1377,17 +1358,7 @@ bpf_deliver(struct bpf_if *bp, void *(*cpfn)(void *, const void *, size_t), d->bd_rcount++; bpf_gstats.bs_recv++; - bf = bpf_jit_enable ? d->bd_bfilter : NULL; - if (bf) { - /* - * XXX THIS is totally broken when pkt - * points to mbuf. FreeBSD does a runtime - * check, we don't. - */ - slen = (*(bf->func))(pkt, pktlen, pktlen); - } else { - slen = bpf_filter(d->bd_filter, pkt, pktlen, buflen); - } + slen = bpf_filter(d->bd_filter, pkt, pktlen, buflen); if (!slen) { continue; } @@ -1716,8 +1687,6 @@ bpf_freed(struct bpf_d *d) } if (d->bd_filter) free(d->bd_filter, M_DEVBUF); - if (d->bd_bfilter) - bpf_destroy_jit_filter(d->bd_bfilter); } /* diff --git a/sys/net/bpf_filter.c b/sys/net/bpf_filter.c index 232341d504a3..c68b07fdfdbf 100644 --- a/sys/net/bpf_filter.c +++ b/sys/net/bpf_filter.c @@ -1,4 +1,4 @@ -/* $NetBSD: bpf_filter.c,v 1.53 2012/08/15 21:31:39 alnsn Exp $ */ +/* $NetBSD: bpf_filter.c,v 1.54 2012/09/27 18:28:56 alnsn Exp $ */ /*- * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: bpf_filter.c,v 1.53 2012/08/15 21:31:39 alnsn Exp $"); +__KERNEL_RCSID(0, "$NetBSD: bpf_filter.c,v 1.54 2012/09/27 18:28:56 alnsn Exp $"); #if 0 #if !(defined(lint) || defined(KERNEL)) @@ -86,10 +86,8 @@ m_xword(const struct mbuf *m, uint32_t k, int *err) return EXTRACT_LONG(cp); } m0 = m->m_next; - if (m0 == 0 || m0->m_len + len - k < 4) { - *err = 1; + if (m0 == 0 || m0->m_len + len - k < 4) return 0; - } *err = 0; np = mtod(m0, u_char *); @@ -118,16 +116,13 @@ m_xhalf(const struct mbuf *m, uint32_t k, int *err) return EXTRACT_SHORT(cp); } m0 = m->m_next; - if (m0 == 0) { - *err = 1; + if (m0 == 0) return 0; - } *err = 0; return (cp[0] << 8) | mtod(m0, u_char *)[0]; } #else /* _KERNEL */ #include -#include #endif /* !_KERNEL */ #include diff --git a/sys/net/bpf_jit.c b/sys/net/bpf_jit.c deleted file mode 100644 index 63426fd449fc..000000000000 --- a/sys/net/bpf_jit.c +++ /dev/null @@ -1,142 +0,0 @@ -/* $NetBSD: bpf_jit.c,v 1.1 2012/08/01 23:24:29 rmind Exp $ */ - -/*- - * Copyright (C) 2002-2003 NetGroup, Politecnico di Torino (Italy) - * Copyright (C) 2005-2009 Jung-uk Kim - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Politecnico di Torino nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD: src/sys/net/bpf_jitter.c,v 1.11 2009/11/20 18:49:20 jkim Exp $ - */ - -#include -__KERNEL_RCSID(0, "$NetBSD: bpf_jit.c,v 1.1 2012/08/01 23:24:29 rmind Exp $"); - -#ifdef _KERNEL -#if defined(_KERNEL_OPT) -#include "opt_bpf.h" -#endif - -#include -#include -#include -#include -#else -#include -#include -#include -#include -#include -#endif - -#include -#include - -bpf_filter_func bpf_jit_compile(struct bpf_insn *, u_int, size_t *); - -static u_int bpf_jit_accept_all(u_char *, u_int, u_int); - -#ifdef _KERNEL - -bpf_jit_filter * -bpf_jit(struct bpf_insn *fp, int nins) -{ - bpf_jit_filter *filter; - - /* Allocate the filter structure */ - filter = malloc(sizeof(*filter), M_TEMP, M_NOWAIT); - if (filter == NULL) - return (NULL); - - /* No filter means accept all */ - if (fp == NULL || nins == 0) { - filter->func = bpf_jit_accept_all; - return (filter); - } - - /* Create the binary */ - if ((filter->func = bpf_jit_compile(fp, nins, &filter->size)) == NULL) { - free(filter, M_TEMP); - return (NULL); - } - - return (filter); -} - -void -bpf_destroy_jit_filter(bpf_jit_filter *filter) -{ - - if (filter->func != bpf_jit_accept_all) - free(filter->func, M_TEMP); - free(filter, M_TEMP); -} - -#else - -bpf_jit_filter * -bpf_jit(struct bpf_insn *fp, int nins) -{ - bpf_jit_filter *filter; - - /* Allocate the filter structure */ - filter = (struct bpf_jit_filter *)malloc(sizeof(*filter)); - if (filter == NULL) - return (NULL); - - /* No filter means accept all */ - if (fp == NULL || nins == 0) { - filter->func = bpf_jit_accept_all; - return (filter); - } - - /* Create the binary */ - if ((filter->func = bpf_jit_compile(fp, nins, &filter->size)) == NULL) { - free(filter); - return (NULL); - } - - return (filter); -} - -void -bpf_destroy_jit_filter(bpf_jit_filter *filter) -{ - - if (filter->func != bpf_jit_accept_all) - munmap(filter->func, filter->size); - free(filter); -} -#endif - -static u_int -bpf_jit_accept_all(__unused u_char *p, __unused u_int wirelen, - __unused u_int buflen) -{ - - return ((u_int)-1); -} diff --git a/sys/net/bpf_jit.h b/sys/net/bpf_jit.h deleted file mode 100644 index 9b8360ce0642..000000000000 --- a/sys/net/bpf_jit.h +++ /dev/null @@ -1,81 +0,0 @@ -/* $NetBSD: bpf_jit.h,v 1.2 2012/08/02 01:05:05 rmind Exp $ */ - -/*- - * Copyright (C) 2002-2003 NetGroup, Politecnico di Torino (Italy) - * Copyright (C) 2005-2009 Jung-uk Kim - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Politecnico di Torino nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD: src/sys/net/bpf_jitter.h,v 1.8 2009/11/20 18:49:20 jkim Exp $ - */ - -#ifndef _NET_BPF_JIT_H_ -#define _NET_BPF_JIT_H_ - -struct bpf_insn; - -/* - * Prototype of a filtering function created by the JIT compiler. - * - * The syntax and the meaning of the parameters is analogous to the one of - * bpf_filter(). Notice that the filter is not among the parameters because - * it is hardwired in the function. - */ -typedef u_int (*bpf_filter_func)(u_char *, u_int, u_int); - -/* Structure describing a native filtering program by the JIT compiler. */ -typedef struct bpf_jit_filter { - /* The native filtering binary, in the form of a bpf_filter_func. */ - bpf_filter_func func; - size_t size; -} bpf_jit_filter; - -/* - * BPF JIT compiler, builds a machine function from a BPF program. - * - * param fp The BPF pseudo-assembly filter that will be translated - * into native code. - * param nins Number of instructions of the input filter. - * return The bpf_jit_filter structure containing the native filtering - * binary. - * - * bpf_jit allocates the buffers for the new native filter and - * then translates the program pointed by fp calling bpf_jit_compile(). - */ -bpf_jit_filter *bpf_jit(struct bpf_insn *, int); - -/* - * Deletes a filtering function that was previously created by bpf_jit(). - * - * param filter The filter to destroy. - * - * This function frees the variuos buffers (code, memory, etc.) associated - * with a filtering function. - */ -void bpf_destroy_jit_filter(bpf_jit_filter *); - -#endif /* _NET_BPF_JIT_H_ */ diff --git a/sys/net/bpfdesc.h b/sys/net/bpfdesc.h index 7d8344d4876e..27587e57608a 100644 --- a/sys/net/bpfdesc.h +++ b/sys/net/bpfdesc.h @@ -1,4 +1,4 @@ -/* $NetBSD: bpfdesc.h,v 1.34 2012/08/01 23:24:29 rmind Exp $ */ +/* $NetBSD: bpfdesc.h,v 1.35 2012/09/27 18:28:56 alnsn Exp $ */ /* * Copyright (c) 1990, 1991, 1993 @@ -44,7 +44,6 @@ #include #include /* for struct selinfo */ #include /* for IFNAMSIZ */ -#include /* * Descriptor associated with each open bpf file. @@ -71,7 +70,6 @@ struct bpf_d { struct bpf_if * bd_bif; /* interface descriptor */ u_long bd_rtout; /* Read timeout in 'ticks' */ struct bpf_insn *bd_filter; /* filter code */ - bpf_jit_filter *bd_bfilter; /* binary filter code */ u_long bd_rcount; /* number of packets received */ u_long bd_dcount; /* number of packets dropped */ u_long bd_ccount; /* number of packets captured */ @@ -102,6 +100,7 @@ struct bpf_d { #ifdef _LP64 int bd_compat32; /* 32-bit stream on LP64 system */ #endif + void *bd_dummy; /* to be replaced shortly with bd_jitcode */ };