bpf_jit_machdep.c revision 181648
1153151Sjkim/*- 2181648Sjkim * Copyright (C) 2002-2003 NetGroup, Politecnico di Torino (Italy) 3181648Sjkim * Copyright (C) 2005-2008 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 181648 2008-08-12 21:31:31Z 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) 108181648Sjkim 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) 114181648Sjkim 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); 140181645Sjkim MOVodd(16, EBP, EDI); 141153151Sjkim 142153151Sjkim for (i = 0; i < nins; i++) { 143153151Sjkim stream.bpf_pc++; 144153151Sjkim 145153151Sjkim switch (ins->code) { 146153151Sjkim default: 147181648Sjkim return (NULL); 148153151Sjkim 149153151Sjkim case BPF_RET|BPF_K: 150179968Sjkim MOVid(ins->k, EAX); 151153151Sjkim POP(EBX); 152153151Sjkim POP(ESI); 153153151Sjkim POP(EDI); 154153151Sjkim LEAVE_RET(); 155153151Sjkim break; 156153151Sjkim 157153151Sjkim case BPF_RET|BPF_A: 158153151Sjkim POP(EBX); 159153151Sjkim POP(ESI); 160153151Sjkim POP(EDI); 161153151Sjkim LEAVE_RET(); 162153151Sjkim break; 163153151Sjkim 164153151Sjkim case BPF_LD|BPF_W|BPF_ABS: 165179968Sjkim MOVid(ins->k, ECX); 166179968Sjkim MOVrd(ECX, ESI); 167179968Sjkim ADDib(sizeof(int), ECX); 168181645Sjkim CMPrd(EDI, ECX); 169153151Sjkim JLEb(7); 170179978Sjkim ZEROrd(EAX); 171153151Sjkim POP(EBX); 172153151Sjkim POP(ESI); 173153151Sjkim POP(EDI); 174153151Sjkim LEAVE_RET(); 175179968Sjkim MOVobd(EBX, ESI, EAX); 176153151Sjkim BSWAP(EAX); 177153151Sjkim break; 178153151Sjkim 179153151Sjkim case BPF_LD|BPF_H|BPF_ABS: 180179978Sjkim ZEROrd(EAX); 181179968Sjkim MOVid(ins->k, ECX); 182179968Sjkim MOVrd(ECX, ESI); 183179968Sjkim ADDib(sizeof(short), ECX); 184181645Sjkim CMPrd(EDI, ECX); 185153151Sjkim JLEb(5); 186153151Sjkim POP(EBX); 187153151Sjkim POP(ESI); 188153151Sjkim POP(EDI); 189153151Sjkim LEAVE_RET(); 190179968Sjkim MOVobw(EBX, ESI, AX); 191153151Sjkim SWAP_AX(); 192153151Sjkim break; 193153151Sjkim 194153151Sjkim case BPF_LD|BPF_B|BPF_ABS: 195179978Sjkim ZEROrd(EAX); 196179968Sjkim MOVid(ins->k, ECX); 197181645Sjkim CMPrd(EDI, ECX); 198153151Sjkim JLEb(5); 199153151Sjkim POP(EBX); 200153151Sjkim POP(ESI); 201153151Sjkim POP(EDI); 202153151Sjkim LEAVE_RET(); 203179968Sjkim MOVobb(EBX, ECX, AL); 204153151Sjkim break; 205153151Sjkim 206153151Sjkim case BPF_LD|BPF_W|BPF_LEN: 207181648Sjkim MOVodd(12, EBP, EAX); 208153151Sjkim break; 209153151Sjkim 210153151Sjkim case BPF_LDX|BPF_W|BPF_LEN: 211181648Sjkim MOVodd(12, EBP, EDX); 212153151Sjkim break; 213153151Sjkim 214153151Sjkim case BPF_LD|BPF_W|BPF_IND: 215179968Sjkim MOVid(ins->k, ECX); 216179968Sjkim ADDrd(EDX, ECX); 217179968Sjkim MOVrd(ECX, ESI); 218179968Sjkim ADDib(sizeof(int), ECX); 219181645Sjkim CMPrd(EDI, ECX); 220153151Sjkim JLEb(7); 221179978Sjkim ZEROrd(EAX); 222153151Sjkim POP(EBX); 223153151Sjkim POP(ESI); 224153151Sjkim POP(EDI); 225153151Sjkim LEAVE_RET(); 226179968Sjkim MOVobd(EBX, ESI, EAX); 227153151Sjkim BSWAP(EAX); 228153151Sjkim break; 229153151Sjkim 230153151Sjkim case BPF_LD|BPF_H|BPF_IND: 231179978Sjkim ZEROrd(EAX); 232179968Sjkim MOVid(ins->k, ECX); 233179968Sjkim ADDrd(EDX, ECX); 234179968Sjkim MOVrd(ECX, ESI); 235179968Sjkim ADDib(sizeof(short), ECX); 236181645Sjkim CMPrd(EDI, ECX); 237153151Sjkim JLEb(5); 238153151Sjkim POP(EBX); 239153151Sjkim POP(ESI); 240153151Sjkim POP(EDI); 241153151Sjkim LEAVE_RET(); 242179968Sjkim MOVobw(EBX, ESI, AX); 243153151Sjkim SWAP_AX(); 244153151Sjkim break; 245153151Sjkim 246153151Sjkim case BPF_LD|BPF_B|BPF_IND: 247179978Sjkim ZEROrd(EAX); 248179968Sjkim MOVid(ins->k, ECX); 249179968Sjkim ADDrd(EDX, ECX); 250181645Sjkim CMPrd(EDI, ECX); 251153151Sjkim JLEb(5); 252153151Sjkim POP(EBX); 253153151Sjkim POP(ESI); 254153151Sjkim POP(EDI); 255153151Sjkim LEAVE_RET(); 256179968Sjkim MOVobb(EBX, ECX, AL); 257153151Sjkim break; 258153151Sjkim 259153151Sjkim case BPF_LDX|BPF_MSH|BPF_B: 260179968Sjkim MOVid(ins->k, ECX); 261181645Sjkim CMPrd(EDI, ECX); 262153151Sjkim JLEb(7); 263179978Sjkim ZEROrd(EAX); 264153151Sjkim POP(EBX); 265153151Sjkim POP(ESI); 266153151Sjkim POP(EDI); 267153151Sjkim LEAVE_RET(); 268179978Sjkim ZEROrd(EDX); 269179968Sjkim MOVobb(EBX, ECX, DL); 270181648Sjkim ANDib(0x0f, DL); 271179968Sjkim SHLib(2, EDX); 272153151Sjkim break; 273153151Sjkim 274153151Sjkim case BPF_LD|BPF_IMM: 275179968Sjkim MOVid(ins->k, EAX); 276153151Sjkim break; 277153151Sjkim 278153151Sjkim case BPF_LDX|BPF_IMM: 279179968Sjkim MOVid(ins->k, EDX); 280153151Sjkim break; 281153151Sjkim 282153151Sjkim case BPF_LD|BPF_MEM: 283179968Sjkim MOVid((uintptr_t)mem, ECX); 284179968Sjkim MOVid(ins->k * 4, ESI); 285179968Sjkim MOVobd(ECX, ESI, EAX); 286153151Sjkim break; 287153151Sjkim 288153151Sjkim case BPF_LDX|BPF_MEM: 289179968Sjkim MOVid((uintptr_t)mem, ECX); 290179968Sjkim MOVid(ins->k * 4, ESI); 291179968Sjkim MOVobd(ECX, ESI, EDX); 292153151Sjkim break; 293153151Sjkim 294153151Sjkim case BPF_ST: 295153151Sjkim /* 296153151Sjkim * XXX this command and the following could 297153151Sjkim * be optimized if the previous instruction 298153151Sjkim * was already of this type 299153151Sjkim */ 300179968Sjkim MOVid((uintptr_t)mem, ECX); 301179968Sjkim MOVid(ins->k * 4, ESI); 302179968Sjkim MOVomd(EAX, ECX, ESI); 303153151Sjkim break; 304153151Sjkim 305153151Sjkim case BPF_STX: 306179968Sjkim MOVid((uintptr_t)mem, ECX); 307179968Sjkim MOVid(ins->k * 4, ESI); 308179968Sjkim MOVomd(EDX, ECX, ESI); 309153151Sjkim break; 310153151Sjkim 311153151Sjkim case BPF_JMP|BPF_JA: 312153151Sjkim JMP(stream.refs[stream.bpf_pc + ins->k] - 313153151Sjkim stream.refs[stream.bpf_pc]); 314153151Sjkim break; 315153151Sjkim 316153151Sjkim case BPF_JMP|BPF_JGT|BPF_K: 317179968Sjkim CMPid(ins->k, EAX); 318153151Sjkim /* 5 is the size of the following JMP */ 319153151Sjkim JG(stream.refs[stream.bpf_pc + ins->jt] - 320153151Sjkim stream.refs[stream.bpf_pc] + 5 ); 321153151Sjkim JMP(stream.refs[stream.bpf_pc + ins->jf] - 322153151Sjkim stream.refs[stream.bpf_pc]); 323153151Sjkim break; 324153151Sjkim 325153151Sjkim case BPF_JMP|BPF_JGE|BPF_K: 326179968Sjkim CMPid(ins->k, EAX); 327153151Sjkim JGE(stream.refs[stream.bpf_pc + ins->jt] - 328153151Sjkim stream.refs[stream.bpf_pc] + 5); 329153151Sjkim JMP(stream.refs[stream.bpf_pc + ins->jf] - 330153151Sjkim stream.refs[stream.bpf_pc]); 331153151Sjkim break; 332153151Sjkim 333153151Sjkim case BPF_JMP|BPF_JEQ|BPF_K: 334179968Sjkim CMPid(ins->k, EAX); 335153151Sjkim JE(stream.refs[stream.bpf_pc + ins->jt] - 336153151Sjkim stream.refs[stream.bpf_pc] + 5); 337153151Sjkim JMP(stream.refs[stream.bpf_pc + ins->jf] - 338153151Sjkim stream.refs[stream.bpf_pc]); 339153151Sjkim break; 340153151Sjkim 341153151Sjkim case BPF_JMP|BPF_JSET|BPF_K: 342179968Sjkim MOVrd(EAX, ECX); 343179968Sjkim ANDid(ins->k, ECX); 344153151Sjkim JE(stream.refs[stream.bpf_pc + ins->jf] - 345153151Sjkim stream.refs[stream.bpf_pc] + 5); 346153151Sjkim JMP(stream.refs[stream.bpf_pc + ins->jt] - 347153151Sjkim stream.refs[stream.bpf_pc]); 348153151Sjkim break; 349153151Sjkim 350153151Sjkim case BPF_JMP|BPF_JGT|BPF_X: 351179968Sjkim CMPrd(EDX, EAX); 352153151Sjkim JA(stream.refs[stream.bpf_pc + ins->jt] - 353153151Sjkim stream.refs[stream.bpf_pc] + 5); 354153151Sjkim JMP(stream.refs[stream.bpf_pc + ins->jf] - 355153151Sjkim stream.refs[stream.bpf_pc]); 356153151Sjkim break; 357153151Sjkim 358153151Sjkim case BPF_JMP|BPF_JGE|BPF_X: 359179968Sjkim CMPrd(EDX, EAX); 360153151Sjkim JAE(stream.refs[stream.bpf_pc + ins->jt] - 361153151Sjkim stream.refs[stream.bpf_pc] + 5); 362153151Sjkim JMP(stream.refs[stream.bpf_pc + ins->jf] - 363153151Sjkim stream.refs[stream.bpf_pc]); 364153151Sjkim break; 365153151Sjkim 366153151Sjkim case BPF_JMP|BPF_JEQ|BPF_X: 367179968Sjkim CMPrd(EDX, EAX); 368153151Sjkim JE(stream.refs[stream.bpf_pc + ins->jt] - 369153151Sjkim stream.refs[stream.bpf_pc] + 5); 370153151Sjkim JMP(stream.refs[stream.bpf_pc + ins->jf] - 371153151Sjkim stream.refs[stream.bpf_pc]); 372153151Sjkim break; 373153151Sjkim 374153151Sjkim case BPF_JMP|BPF_JSET|BPF_X: 375179968Sjkim MOVrd(EAX, ECX); 376179968Sjkim ANDrd(EDX, ECX); 377153151Sjkim JE(stream.refs[stream.bpf_pc + ins->jf] - 378153151Sjkim stream.refs[stream.bpf_pc] + 5); 379153151Sjkim JMP(stream.refs[stream.bpf_pc + ins->jt] - 380153151Sjkim stream.refs[stream.bpf_pc]); 381153151Sjkim break; 382153151Sjkim 383153151Sjkim case BPF_ALU|BPF_ADD|BPF_X: 384179968Sjkim ADDrd(EDX, EAX); 385153151Sjkim break; 386153151Sjkim 387153151Sjkim case BPF_ALU|BPF_SUB|BPF_X: 388179968Sjkim SUBrd(EDX, EAX); 389153151Sjkim break; 390153151Sjkim 391153151Sjkim case BPF_ALU|BPF_MUL|BPF_X: 392179968Sjkim MOVrd(EDX, ECX); 393179968Sjkim MULrd(EDX); 394153151Sjkim MOVrd(ECX, EDX); 395153151Sjkim break; 396153151Sjkim 397153151Sjkim case BPF_ALU|BPF_DIV|BPF_X: 398179968Sjkim CMPid(0, EDX); 399153151Sjkim JNEb(7); 400179978Sjkim ZEROrd(EAX); 401153151Sjkim POP(EBX); 402153151Sjkim POP(ESI); 403153151Sjkim POP(EDI); 404153151Sjkim LEAVE_RET(); 405179968Sjkim MOVrd(EDX, ECX); 406179978Sjkim ZEROrd(EDX); 407153151Sjkim DIVrd(ECX); 408179968Sjkim MOVrd(ECX, EDX); 409153151Sjkim break; 410153151Sjkim 411153151Sjkim case BPF_ALU|BPF_AND|BPF_X: 412179968Sjkim ANDrd(EDX, EAX); 413153151Sjkim break; 414153151Sjkim 415153151Sjkim case BPF_ALU|BPF_OR|BPF_X: 416179968Sjkim ORrd(EDX, EAX); 417153151Sjkim break; 418153151Sjkim 419153151Sjkim case BPF_ALU|BPF_LSH|BPF_X: 420179968Sjkim MOVrd(EDX, ECX); 421153151Sjkim SHL_CLrb(EAX); 422153151Sjkim break; 423153151Sjkim 424153151Sjkim case BPF_ALU|BPF_RSH|BPF_X: 425179968Sjkim MOVrd(EDX, ECX); 426153151Sjkim SHR_CLrb(EAX); 427153151Sjkim break; 428153151Sjkim 429153151Sjkim case BPF_ALU|BPF_ADD|BPF_K: 430153151Sjkim ADD_EAXi(ins->k); 431153151Sjkim break; 432153151Sjkim 433153151Sjkim case BPF_ALU|BPF_SUB|BPF_K: 434153151Sjkim SUB_EAXi(ins->k); 435153151Sjkim break; 436153151Sjkim 437153151Sjkim case BPF_ALU|BPF_MUL|BPF_K: 438179968Sjkim MOVrd(EDX, ECX); 439179968Sjkim MOVid(ins->k, EDX); 440179968Sjkim MULrd(EDX); 441153151Sjkim MOVrd(ECX, EDX); 442153151Sjkim break; 443153151Sjkim 444153151Sjkim case BPF_ALU|BPF_DIV|BPF_K: 445179968Sjkim MOVrd(EDX, ECX); 446179978Sjkim ZEROrd(EDX); 447179968Sjkim MOVid(ins->k, ESI); 448153151Sjkim DIVrd(ESI); 449179968Sjkim MOVrd(ECX, EDX); 450153151Sjkim break; 451153151Sjkim 452153151Sjkim case BPF_ALU|BPF_AND|BPF_K: 453179968Sjkim ANDid(ins->k, EAX); 454153151Sjkim break; 455153151Sjkim 456153151Sjkim case BPF_ALU|BPF_OR|BPF_K: 457179968Sjkim ORid(ins->k, EAX); 458153151Sjkim break; 459153151Sjkim 460153151Sjkim case BPF_ALU|BPF_LSH|BPF_K: 461179968Sjkim SHLib((ins->k) & 0xff, EAX); 462153151Sjkim break; 463153151Sjkim 464153151Sjkim case BPF_ALU|BPF_RSH|BPF_K: 465179968Sjkim SHRib((ins->k) & 0xff, EAX); 466153151Sjkim break; 467153151Sjkim 468153151Sjkim case BPF_ALU|BPF_NEG: 469153151Sjkim NEGd(EAX); 470153151Sjkim break; 471153151Sjkim 472153151Sjkim case BPF_MISC|BPF_TAX: 473179968Sjkim MOVrd(EAX, EDX); 474153151Sjkim break; 475153151Sjkim 476153151Sjkim case BPF_MISC|BPF_TXA: 477179968Sjkim MOVrd(EDX, EAX); 478153151Sjkim break; 479153151Sjkim } 480153151Sjkim ins++; 481153151Sjkim } 482153151Sjkim 483153151Sjkim pass++; 484153151Sjkim if (pass == 2) 485153151Sjkim break; 486153151Sjkim 487153157Sjkim stream.ibuf = (char *)malloc(stream.cur_ip, M_BPFJIT, M_NOWAIT); 488153151Sjkim if (stream.ibuf == NULL) { 489153151Sjkim free(stream.refs, M_BPFJIT); 490181648Sjkim return (NULL); 491153151Sjkim } 492153151Sjkim 493153151Sjkim /* 494153151Sjkim * modify the reference table to contain the offsets and 495153151Sjkim * not the lengths of the instructions 496153151Sjkim */ 497153151Sjkim for (i = 1; i < nins + 1; i++) 498153151Sjkim stream.refs[i] += stream.refs[i - 1]; 499153151Sjkim 500153151Sjkim /* Reset the counters */ 501153151Sjkim stream.cur_ip = 0; 502153151Sjkim stream.bpf_pc = 0; 503153151Sjkim 504153151Sjkim /* the second pass creates the actual code */ 505153151Sjkim emitm = emit_code; 506153151Sjkim } 507153151Sjkim 508153151Sjkim /* 509153151Sjkim * the reference table is needed only during compilation, 510153151Sjkim * now we can free it 511153151Sjkim */ 512153151Sjkim free(stream.refs, M_BPFJIT); 513153151Sjkim 514181648Sjkim return ((bpf_filter_func)stream.ibuf); 515153151Sjkim} 516