bpf_jit_machdep.c revision 179978
1153151Sjkim/*- 2153151Sjkim * Copyright (c) 2002 - 2003 NetGroup, Politecnico di Torino (Italy) 3153151Sjkim * Copyright (c) 2005 Jung-uk Kim <jkim@FreeBSD.org> 4153151Sjkim * All rights reserved. 5153151Sjkim * 6153151Sjkim * Redistribution and use in source and binary forms, with or without 7153151Sjkim * modification, are permitted provided that the following conditions 8153151Sjkim * are met: 9153151Sjkim * 10153151Sjkim * 1. Redistributions of source code must retain the above copyright 11153151Sjkim * notice, this list of conditions and the following disclaimer. 12153151Sjkim * 2. Redistributions in binary form must reproduce the above copyright 13153151Sjkim * notice, this list of conditions and the following disclaimer in the 14153151Sjkim * documentation and/or other materials provided with the distribution. 15153151Sjkim * 3. Neither the name of the Politecnico di Torino nor the names of its 16153151Sjkim * contributors may be used to endorse or promote products derived from 17153151Sjkim * this software without specific prior written permission. 18153151Sjkim * 19153151Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20153151Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21153151Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22153151Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23153151Sjkim * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24153151Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25153151Sjkim * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26153151Sjkim * DATA, OR PROFITS; OR BUSINESS intERRUPTION) HOWEVER CAUSED AND ON ANY 27153151Sjkim * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28153151Sjkim * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29153151Sjkim * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30153151Sjkim */ 31153151Sjkim 32153151Sjkim#include <sys/cdefs.h> 33153151Sjkim__FBSDID("$FreeBSD: head/sys/i386/i386/bpf_jit_machdep.c 179978 2008-06-24 20:12:44Z jkim $"); 34153151Sjkim 35153151Sjkim#include "opt_bpf.h" 36153151Sjkim 37153151Sjkim#include <sys/param.h> 38153151Sjkim#include <sys/systm.h> 39153151Sjkim#include <sys/kernel.h> 40153151Sjkim#include <sys/types.h> 41153151Sjkim#include <sys/socket.h> 42153151Sjkim#include <sys/malloc.h> 43153151Sjkim 44153151Sjkim#include <net/if.h> 45153151Sjkim#include <net/bpf.h> 46153151Sjkim#include <net/bpf_jitter.h> 47153151Sjkim 48153151Sjkim#include <i386/i386/bpf_jit_machdep.h> 49153151Sjkim 50153151Sjkimbpf_filter_func bpf_jit_compile(struct bpf_insn *, u_int, int *); 51153151Sjkim 52153151Sjkim/* 53153151Sjkim * emit routine to update the jump table 54153151Sjkim */ 55153151Sjkimstatic void 56153151Sjkimemit_length(bpf_bin_stream *stream, u_int value, u_int len) 57153151Sjkim{ 58153151Sjkim 59153151Sjkim (stream->refs)[stream->bpf_pc] += len; 60153151Sjkim stream->cur_ip += len; 61153151Sjkim} 62153151Sjkim 63153151Sjkim/* 64153151Sjkim * emit routine to output the actual binary code 65153151Sjkim */ 66153151Sjkimstatic void 67153151Sjkimemit_code(bpf_bin_stream *stream, u_int value, u_int len) 68153151Sjkim{ 69153151Sjkim 70153151Sjkim switch (len) { 71153151Sjkim case 1: 72153151Sjkim stream->ibuf[stream->cur_ip] = (u_char)value; 73153151Sjkim stream->cur_ip++; 74153151Sjkim break; 75153151Sjkim 76153151Sjkim case 2: 77153151Sjkim *((u_short *)(stream->ibuf + stream->cur_ip)) = (u_short)value; 78153151Sjkim stream->cur_ip += 2; 79153151Sjkim break; 80153151Sjkim 81153151Sjkim case 4: 82153151Sjkim *((u_int *)(stream->ibuf + stream->cur_ip)) = value; 83153151Sjkim stream->cur_ip += 4; 84153151Sjkim break; 85153151Sjkim } 86153151Sjkim 87153151Sjkim return; 88153151Sjkim} 89153151Sjkim 90153151Sjkim/* 91153151Sjkim * Function that does the real stuff 92153151Sjkim */ 93153151Sjkimbpf_filter_func 94153151Sjkimbpf_jit_compile(struct bpf_insn *prog, u_int nins, int *mem) 95153151Sjkim{ 96153151Sjkim struct bpf_insn *ins; 97153151Sjkim u_int i, pass; 98153151Sjkim bpf_bin_stream stream; 99153151Sjkim 100153151Sjkim /* 101153151Sjkim * NOTE: do not modify the name of this variable, as it's used by 102153151Sjkim * the macros to emit code. 103153151Sjkim */ 104153151Sjkim emit_func emitm; 105153151Sjkim 106153995Sjkim /* Do not compile an empty filter. */ 107153995Sjkim if (nins == 0) 108153995Sjkim return NULL; 109153995Sjkim 110153151Sjkim /* Allocate the reference table for the jumps */ 111153151Sjkim stream.refs = (u_int *)malloc((nins + 1) * sizeof(u_int), 112153157Sjkim M_BPFJIT, M_NOWAIT); 113153151Sjkim if (stream.refs == NULL) 114153151Sjkim return NULL; 115153151Sjkim 116153151Sjkim /* Reset the reference table */ 117153151Sjkim for (i = 0; i < nins + 1; i++) 118153151Sjkim stream.refs[i] = 0; 119153151Sjkim 120153151Sjkim stream.cur_ip = 0; 121153151Sjkim stream.bpf_pc = 0; 122153151Sjkim 123153151Sjkim /* 124153151Sjkim * the first pass will emit the lengths of the instructions 125153151Sjkim * to create the reference table 126153151Sjkim */ 127153151Sjkim emitm = emit_length; 128153151Sjkim 129153151Sjkim pass = 0; 130153151Sjkim for (;;) { 131153151Sjkim ins = prog; 132153151Sjkim 133153151Sjkim /* create the procedure header */ 134153151Sjkim PUSH(EBP); 135179968Sjkim MOVrd(ESP, EBP); 136153151Sjkim PUSH(EDI); 137153151Sjkim PUSH(ESI); 138153151Sjkim PUSH(EBX); 139179968Sjkim MOVodd(8, EBP, EBX); 140153151Sjkim 141153151Sjkim for (i = 0; i < nins; i++) { 142153151Sjkim stream.bpf_pc++; 143153151Sjkim 144153151Sjkim switch (ins->code) { 145153151Sjkim default: 146153151Sjkim return NULL; 147153151Sjkim 148153151Sjkim case BPF_RET|BPF_K: 149179968Sjkim MOVid(ins->k, EAX); 150153151Sjkim POP(EBX); 151153151Sjkim POP(ESI); 152153151Sjkim POP(EDI); 153153151Sjkim LEAVE_RET(); 154153151Sjkim break; 155153151Sjkim 156153151Sjkim case BPF_RET|BPF_A: 157153151Sjkim POP(EBX); 158153151Sjkim POP(ESI); 159153151Sjkim POP(EDI); 160153151Sjkim LEAVE_RET(); 161153151Sjkim break; 162153151Sjkim 163153151Sjkim case BPF_LD|BPF_W|BPF_ABS: 164179968Sjkim MOVid(ins->k, ECX); 165179968Sjkim MOVrd(ECX, ESI); 166179968Sjkim ADDib(sizeof(int), ECX); 167179968Sjkim CMPodd(0x10, EBP, ECX); 168153151Sjkim JLEb(7); 169179978Sjkim ZEROrd(EAX); 170153151Sjkim POP(EBX); 171153151Sjkim POP(ESI); 172153151Sjkim POP(EDI); 173153151Sjkim LEAVE_RET(); 174179968Sjkim MOVobd(EBX, ESI, EAX); 175153151Sjkim BSWAP(EAX); 176153151Sjkim break; 177153151Sjkim 178153151Sjkim case BPF_LD|BPF_H|BPF_ABS: 179179978Sjkim ZEROrd(EAX); 180179968Sjkim MOVid(ins->k, ECX); 181179968Sjkim MOVrd(ECX, ESI); 182179968Sjkim ADDib(sizeof(short), ECX); 183179968Sjkim CMPodd(0x10, EBP, ECX); 184153151Sjkim JLEb(5); 185153151Sjkim POP(EBX); 186153151Sjkim POP(ESI); 187153151Sjkim POP(EDI); 188153151Sjkim LEAVE_RET(); 189179968Sjkim MOVobw(EBX, ESI, AX); 190153151Sjkim SWAP_AX(); 191153151Sjkim break; 192153151Sjkim 193153151Sjkim case BPF_LD|BPF_B|BPF_ABS: 194179978Sjkim ZEROrd(EAX); 195179968Sjkim MOVid(ins->k, ECX); 196179968Sjkim CMPodd(0x10, EBP, ECX); 197153151Sjkim JLEb(5); 198153151Sjkim POP(EBX); 199153151Sjkim POP(ESI); 200153151Sjkim POP(EDI); 201153151Sjkim LEAVE_RET(); 202179968Sjkim MOVobb(EBX, ECX, AL); 203153151Sjkim break; 204153151Sjkim 205153151Sjkim case BPF_LD|BPF_W|BPF_LEN: 206179968Sjkim MOVodd(0xc, EBP, EAX); 207153151Sjkim break; 208153151Sjkim 209153151Sjkim case BPF_LDX|BPF_W|BPF_LEN: 210179968Sjkim MOVodd(0xc, EBP, EDX); 211153151Sjkim break; 212153151Sjkim 213153151Sjkim case BPF_LD|BPF_W|BPF_IND: 214179968Sjkim MOVid(ins->k, ECX); 215179968Sjkim ADDrd(EDX, ECX); 216179968Sjkim MOVrd(ECX, ESI); 217179968Sjkim ADDib(sizeof(int), ECX); 218179968Sjkim CMPodd(0x10, EBP, ECX); 219153151Sjkim JLEb(7); 220179978Sjkim ZEROrd(EAX); 221153151Sjkim POP(EBX); 222153151Sjkim POP(ESI); 223153151Sjkim POP(EDI); 224153151Sjkim LEAVE_RET(); 225179968Sjkim MOVobd(EBX, ESI, EAX); 226153151Sjkim BSWAP(EAX); 227153151Sjkim break; 228153151Sjkim 229153151Sjkim case BPF_LD|BPF_H|BPF_IND: 230179978Sjkim ZEROrd(EAX); 231179968Sjkim MOVid(ins->k, ECX); 232179968Sjkim ADDrd(EDX, ECX); 233179968Sjkim MOVrd(ECX, ESI); 234179968Sjkim ADDib(sizeof(short), ECX); 235179968Sjkim CMPodd(0x10, EBP, ECX); 236153151Sjkim JLEb(5); 237153151Sjkim POP(EBX); 238153151Sjkim POP(ESI); 239153151Sjkim POP(EDI); 240153151Sjkim LEAVE_RET(); 241179968Sjkim MOVobw(EBX, ESI, AX); 242153151Sjkim SWAP_AX(); 243153151Sjkim break; 244153151Sjkim 245153151Sjkim case BPF_LD|BPF_B|BPF_IND: 246179978Sjkim ZEROrd(EAX); 247179968Sjkim MOVid(ins->k, ECX); 248179968Sjkim ADDrd(EDX, ECX); 249179968Sjkim CMPodd(0x10, EBP, ECX); 250153151Sjkim JLEb(5); 251153151Sjkim POP(EBX); 252153151Sjkim POP(ESI); 253153151Sjkim POP(EDI); 254153151Sjkim LEAVE_RET(); 255179968Sjkim MOVobb(EBX, ECX, AL); 256153151Sjkim break; 257153151Sjkim 258153151Sjkim case BPF_LDX|BPF_MSH|BPF_B: 259179968Sjkim MOVid(ins->k, ECX); 260179968Sjkim CMPodd(0x10, EBP, ECX); 261153151Sjkim JLEb(7); 262179978Sjkim ZEROrd(EAX); 263153151Sjkim POP(EBX); 264153151Sjkim POP(ESI); 265153151Sjkim POP(EDI); 266153151Sjkim LEAVE_RET(); 267179978Sjkim ZEROrd(EDX); 268179968Sjkim MOVobb(EBX, ECX, DL); 269179968Sjkim ANDib(0xf, DL); 270179968Sjkim SHLib(2, EDX); 271153151Sjkim break; 272153151Sjkim 273153151Sjkim case BPF_LD|BPF_IMM: 274179968Sjkim MOVid(ins->k, EAX); 275153151Sjkim break; 276153151Sjkim 277153151Sjkim case BPF_LDX|BPF_IMM: 278179968Sjkim MOVid(ins->k, EDX); 279153151Sjkim break; 280153151Sjkim 281153151Sjkim case BPF_LD|BPF_MEM: 282179968Sjkim MOVid((uintptr_t)mem, ECX); 283179968Sjkim MOVid(ins->k * 4, ESI); 284179968Sjkim MOVobd(ECX, ESI, EAX); 285153151Sjkim break; 286153151Sjkim 287153151Sjkim case BPF_LDX|BPF_MEM: 288179968Sjkim MOVid((uintptr_t)mem, ECX); 289179968Sjkim MOVid(ins->k * 4, ESI); 290179968Sjkim MOVobd(ECX, ESI, EDX); 291153151Sjkim break; 292153151Sjkim 293153151Sjkim case BPF_ST: 294153151Sjkim /* 295153151Sjkim * XXX this command and the following could 296153151Sjkim * be optimized if the previous instruction 297153151Sjkim * was already of this type 298153151Sjkim */ 299179968Sjkim MOVid((uintptr_t)mem, ECX); 300179968Sjkim MOVid(ins->k * 4, ESI); 301179968Sjkim MOVomd(EAX, ECX, ESI); 302153151Sjkim break; 303153151Sjkim 304153151Sjkim case BPF_STX: 305179968Sjkim MOVid((uintptr_t)mem, ECX); 306179968Sjkim MOVid(ins->k * 4, ESI); 307179968Sjkim MOVomd(EDX, ECX, ESI); 308153151Sjkim break; 309153151Sjkim 310153151Sjkim case BPF_JMP|BPF_JA: 311153151Sjkim JMP(stream.refs[stream.bpf_pc + ins->k] - 312153151Sjkim stream.refs[stream.bpf_pc]); 313153151Sjkim break; 314153151Sjkim 315153151Sjkim case BPF_JMP|BPF_JGT|BPF_K: 316179968Sjkim CMPid(ins->k, EAX); 317153151Sjkim /* 5 is the size of the following JMP */ 318153151Sjkim JG(stream.refs[stream.bpf_pc + ins->jt] - 319153151Sjkim stream.refs[stream.bpf_pc] + 5 ); 320153151Sjkim JMP(stream.refs[stream.bpf_pc + ins->jf] - 321153151Sjkim stream.refs[stream.bpf_pc]); 322153151Sjkim break; 323153151Sjkim 324153151Sjkim case BPF_JMP|BPF_JGE|BPF_K: 325179968Sjkim CMPid(ins->k, EAX); 326153151Sjkim JGE(stream.refs[stream.bpf_pc + ins->jt] - 327153151Sjkim stream.refs[stream.bpf_pc] + 5); 328153151Sjkim JMP(stream.refs[stream.bpf_pc + ins->jf] - 329153151Sjkim stream.refs[stream.bpf_pc]); 330153151Sjkim break; 331153151Sjkim 332153151Sjkim case BPF_JMP|BPF_JEQ|BPF_K: 333179968Sjkim CMPid(ins->k, EAX); 334153151Sjkim JE(stream.refs[stream.bpf_pc + ins->jt] - 335153151Sjkim stream.refs[stream.bpf_pc] + 5); 336153151Sjkim JMP(stream.refs[stream.bpf_pc + ins->jf] - 337153151Sjkim stream.refs[stream.bpf_pc]); 338153151Sjkim break; 339153151Sjkim 340153151Sjkim case BPF_JMP|BPF_JSET|BPF_K: 341179968Sjkim MOVrd(EAX, ECX); 342179968Sjkim ANDid(ins->k, ECX); 343153151Sjkim JE(stream.refs[stream.bpf_pc + ins->jf] - 344153151Sjkim stream.refs[stream.bpf_pc] + 5); 345153151Sjkim JMP(stream.refs[stream.bpf_pc + ins->jt] - 346153151Sjkim stream.refs[stream.bpf_pc]); 347153151Sjkim break; 348153151Sjkim 349153151Sjkim case BPF_JMP|BPF_JGT|BPF_X: 350179968Sjkim CMPrd(EDX, EAX); 351153151Sjkim JA(stream.refs[stream.bpf_pc + ins->jt] - 352153151Sjkim stream.refs[stream.bpf_pc] + 5); 353153151Sjkim JMP(stream.refs[stream.bpf_pc + ins->jf] - 354153151Sjkim stream.refs[stream.bpf_pc]); 355153151Sjkim break; 356153151Sjkim 357153151Sjkim case BPF_JMP|BPF_JGE|BPF_X: 358179968Sjkim CMPrd(EDX, EAX); 359153151Sjkim JAE(stream.refs[stream.bpf_pc + ins->jt] - 360153151Sjkim stream.refs[stream.bpf_pc] + 5); 361153151Sjkim JMP(stream.refs[stream.bpf_pc + ins->jf] - 362153151Sjkim stream.refs[stream.bpf_pc]); 363153151Sjkim break; 364153151Sjkim 365153151Sjkim case BPF_JMP|BPF_JEQ|BPF_X: 366179968Sjkim CMPrd(EDX, EAX); 367153151Sjkim JE(stream.refs[stream.bpf_pc + ins->jt] - 368153151Sjkim stream.refs[stream.bpf_pc] + 5); 369153151Sjkim JMP(stream.refs[stream.bpf_pc + ins->jf] - 370153151Sjkim stream.refs[stream.bpf_pc]); 371153151Sjkim break; 372153151Sjkim 373153151Sjkim case BPF_JMP|BPF_JSET|BPF_X: 374179968Sjkim MOVrd(EAX, ECX); 375179968Sjkim ANDrd(EDX, ECX); 376153151Sjkim JE(stream.refs[stream.bpf_pc + ins->jf] - 377153151Sjkim stream.refs[stream.bpf_pc] + 5); 378153151Sjkim JMP(stream.refs[stream.bpf_pc + ins->jt] - 379153151Sjkim stream.refs[stream.bpf_pc]); 380153151Sjkim break; 381153151Sjkim 382153151Sjkim case BPF_ALU|BPF_ADD|BPF_X: 383179968Sjkim ADDrd(EDX, EAX); 384153151Sjkim break; 385153151Sjkim 386153151Sjkim case BPF_ALU|BPF_SUB|BPF_X: 387179968Sjkim SUBrd(EDX, EAX); 388153151Sjkim break; 389153151Sjkim 390153151Sjkim case BPF_ALU|BPF_MUL|BPF_X: 391179968Sjkim MOVrd(EDX, ECX); 392179968Sjkim MULrd(EDX); 393153151Sjkim MOVrd(ECX, EDX); 394153151Sjkim break; 395153151Sjkim 396153151Sjkim case BPF_ALU|BPF_DIV|BPF_X: 397179968Sjkim CMPid(0, EDX); 398153151Sjkim JNEb(7); 399179978Sjkim ZEROrd(EAX); 400153151Sjkim POP(EBX); 401153151Sjkim POP(ESI); 402153151Sjkim POP(EDI); 403153151Sjkim LEAVE_RET(); 404179968Sjkim MOVrd(EDX, ECX); 405179978Sjkim ZEROrd(EDX); 406153151Sjkim DIVrd(ECX); 407179968Sjkim MOVrd(ECX, EDX); 408153151Sjkim break; 409153151Sjkim 410153151Sjkim case BPF_ALU|BPF_AND|BPF_X: 411179968Sjkim ANDrd(EDX, EAX); 412153151Sjkim break; 413153151Sjkim 414153151Sjkim case BPF_ALU|BPF_OR|BPF_X: 415179968Sjkim ORrd(EDX, EAX); 416153151Sjkim break; 417153151Sjkim 418153151Sjkim case BPF_ALU|BPF_LSH|BPF_X: 419179968Sjkim MOVrd(EDX, ECX); 420153151Sjkim SHL_CLrb(EAX); 421153151Sjkim break; 422153151Sjkim 423153151Sjkim case BPF_ALU|BPF_RSH|BPF_X: 424179968Sjkim MOVrd(EDX, ECX); 425153151Sjkim SHR_CLrb(EAX); 426153151Sjkim break; 427153151Sjkim 428153151Sjkim case BPF_ALU|BPF_ADD|BPF_K: 429153151Sjkim ADD_EAXi(ins->k); 430153151Sjkim break; 431153151Sjkim 432153151Sjkim case BPF_ALU|BPF_SUB|BPF_K: 433153151Sjkim SUB_EAXi(ins->k); 434153151Sjkim break; 435153151Sjkim 436153151Sjkim case BPF_ALU|BPF_MUL|BPF_K: 437179968Sjkim MOVrd(EDX, ECX); 438179968Sjkim MOVid(ins->k, EDX); 439179968Sjkim MULrd(EDX); 440153151Sjkim MOVrd(ECX, EDX); 441153151Sjkim break; 442153151Sjkim 443153151Sjkim case BPF_ALU|BPF_DIV|BPF_K: 444179968Sjkim MOVrd(EDX, ECX); 445179978Sjkim ZEROrd(EDX); 446179968Sjkim MOVid(ins->k, ESI); 447153151Sjkim DIVrd(ESI); 448179968Sjkim MOVrd(ECX, EDX); 449153151Sjkim break; 450153151Sjkim 451153151Sjkim case BPF_ALU|BPF_AND|BPF_K: 452179968Sjkim ANDid(ins->k, EAX); 453153151Sjkim break; 454153151Sjkim 455153151Sjkim case BPF_ALU|BPF_OR|BPF_K: 456179968Sjkim ORid(ins->k, EAX); 457153151Sjkim break; 458153151Sjkim 459153151Sjkim case BPF_ALU|BPF_LSH|BPF_K: 460179968Sjkim SHLib((ins->k) & 0xff, EAX); 461153151Sjkim break; 462153151Sjkim 463153151Sjkim case BPF_ALU|BPF_RSH|BPF_K: 464179968Sjkim SHRib((ins->k) & 0xff, EAX); 465153151Sjkim break; 466153151Sjkim 467153151Sjkim case BPF_ALU|BPF_NEG: 468153151Sjkim NEGd(EAX); 469153151Sjkim break; 470153151Sjkim 471153151Sjkim case BPF_MISC|BPF_TAX: 472179968Sjkim MOVrd(EAX, EDX); 473153151Sjkim break; 474153151Sjkim 475153151Sjkim case BPF_MISC|BPF_TXA: 476179968Sjkim MOVrd(EDX, EAX); 477153151Sjkim break; 478153151Sjkim } 479153151Sjkim ins++; 480153151Sjkim } 481153151Sjkim 482153151Sjkim pass++; 483153151Sjkim if (pass == 2) 484153151Sjkim break; 485153151Sjkim 486153157Sjkim stream.ibuf = (char *)malloc(stream.cur_ip, M_BPFJIT, M_NOWAIT); 487153151Sjkim if (stream.ibuf == NULL) { 488153151Sjkim free(stream.refs, M_BPFJIT); 489153151Sjkim return NULL; 490153151Sjkim } 491153151Sjkim 492153151Sjkim /* 493153151Sjkim * modify the reference table to contain the offsets and 494153151Sjkim * not the lengths of the instructions 495153151Sjkim */ 496153151Sjkim for (i = 1; i < nins + 1; i++) 497153151Sjkim stream.refs[i] += stream.refs[i - 1]; 498153151Sjkim 499153151Sjkim /* Reset the counters */ 500153151Sjkim stream.cur_ip = 0; 501153151Sjkim stream.bpf_pc = 0; 502153151Sjkim 503153151Sjkim /* the second pass creates the actual code */ 504153151Sjkim emitm = emit_code; 505153151Sjkim } 506153151Sjkim 507153151Sjkim /* 508153151Sjkim * the reference table is needed only during compilation, 509153151Sjkim * now we can free it 510153151Sjkim */ 511153151Sjkim free(stream.refs, M_BPFJIT); 512153151Sjkim 513153151Sjkim return (bpf_filter_func)stream.ibuf; 514153151Sjkim} 515