bpf_jit_machdep.c revision 153151
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 153151 2005-12-06 02:58:12Z 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 106153151Sjkim /* Allocate the reference table for the jumps */ 107153151Sjkim stream.refs = (u_int *)malloc((nins + 1) * sizeof(u_int), 108153151Sjkim M_BPFJIT, M_WAITOK); 109153151Sjkim if (stream.refs == NULL) 110153151Sjkim return NULL; 111153151Sjkim 112153151Sjkim /* Reset the reference table */ 113153151Sjkim for (i = 0; i < nins + 1; i++) 114153151Sjkim stream.refs[i] = 0; 115153151Sjkim 116153151Sjkim stream.cur_ip = 0; 117153151Sjkim stream.bpf_pc = 0; 118153151Sjkim 119153151Sjkim /* 120153151Sjkim * the first pass will emit the lengths of the instructions 121153151Sjkim * to create the reference table 122153151Sjkim */ 123153151Sjkim emitm = emit_length; 124153151Sjkim 125153151Sjkim pass = 0; 126153151Sjkim for (;;) { 127153151Sjkim ins = prog; 128153151Sjkim 129153151Sjkim /* create the procedure header */ 130153151Sjkim PUSH(EBP); 131153151Sjkim MOVrd(EBP, ESP); 132153151Sjkim PUSH(EDI); 133153151Sjkim PUSH(ESI); 134153151Sjkim PUSH(EBX); 135153151Sjkim MOVodd(EBX, EBP, 8); 136153151Sjkim 137153151Sjkim for (i = 0; i < nins; i++) { 138153151Sjkim stream.bpf_pc++; 139153151Sjkim 140153151Sjkim switch (ins->code) { 141153151Sjkim default: 142153151Sjkim return NULL; 143153151Sjkim 144153151Sjkim case BPF_RET|BPF_K: 145153151Sjkim MOVid(EAX, ins->k); 146153151Sjkim POP(EBX); 147153151Sjkim POP(ESI); 148153151Sjkim POP(EDI); 149153151Sjkim LEAVE_RET(); 150153151Sjkim break; 151153151Sjkim 152153151Sjkim case BPF_RET|BPF_A: 153153151Sjkim POP(EBX); 154153151Sjkim POP(ESI); 155153151Sjkim POP(EDI); 156153151Sjkim LEAVE_RET(); 157153151Sjkim break; 158153151Sjkim 159153151Sjkim case BPF_LD|BPF_W|BPF_ABS: 160153151Sjkim MOVid(ECX, ins->k); 161153151Sjkim MOVrd(ESI, ECX); 162153151Sjkim ADDib(ECX, sizeof(int)); 163153151Sjkim CMPodd(ECX, EBP, 0x10); 164153151Sjkim JLEb(7); 165153151Sjkim ZERO_EAX(); 166153151Sjkim POP(EBX); 167153151Sjkim POP(ESI); 168153151Sjkim POP(EDI); 169153151Sjkim LEAVE_RET(); 170153151Sjkim MOVobd(EAX, EBX, ESI); 171153151Sjkim BSWAP(EAX); 172153151Sjkim break; 173153151Sjkim 174153151Sjkim case BPF_LD|BPF_H|BPF_ABS: 175153151Sjkim ZERO_EAX(); 176153151Sjkim MOVid(ECX, ins->k); 177153151Sjkim MOVrd(ESI, ECX); 178153151Sjkim ADDib(ECX, sizeof(short)); 179153151Sjkim CMPodd(ECX, EBP, 0x10); 180153151Sjkim JLEb(5); 181153151Sjkim POP(EBX); 182153151Sjkim POP(ESI); 183153151Sjkim POP(EDI); 184153151Sjkim LEAVE_RET(); 185153151Sjkim MOVobw(AX, EBX, ESI); 186153151Sjkim SWAP_AX(); 187153151Sjkim break; 188153151Sjkim 189153151Sjkim case BPF_LD|BPF_B|BPF_ABS: 190153151Sjkim ZERO_EAX(); 191153151Sjkim MOVid(ECX, ins->k); 192153151Sjkim CMPodd(ECX, EBP, 0x10); 193153151Sjkim JLEb(5); 194153151Sjkim POP(EBX); 195153151Sjkim POP(ESI); 196153151Sjkim POP(EDI); 197153151Sjkim LEAVE_RET(); 198153151Sjkim MOVobb(AL, EBX, ECX); 199153151Sjkim break; 200153151Sjkim 201153151Sjkim case BPF_LD|BPF_W|BPF_LEN: 202153151Sjkim MOVodd(EAX, EBP, 0xc); 203153151Sjkim break; 204153151Sjkim 205153151Sjkim case BPF_LDX|BPF_W|BPF_LEN: 206153151Sjkim MOVodd(EDX, EBP, 0xc); 207153151Sjkim break; 208153151Sjkim 209153151Sjkim case BPF_LD|BPF_W|BPF_IND: 210153151Sjkim MOVid(ECX, ins->k); 211153151Sjkim ADDrd(ECX, EDX); 212153151Sjkim MOVrd(ESI, ECX); 213153151Sjkim ADDib(ECX, sizeof(int)); 214153151Sjkim CMPodd(ECX, EBP, 0x10); 215153151Sjkim JLEb(7); 216153151Sjkim ZERO_EAX(); 217153151Sjkim POP(EBX); 218153151Sjkim POP(ESI); 219153151Sjkim POP(EDI); 220153151Sjkim LEAVE_RET(); 221153151Sjkim MOVobd(EAX, EBX, ESI); 222153151Sjkim BSWAP(EAX); 223153151Sjkim break; 224153151Sjkim 225153151Sjkim case BPF_LD|BPF_H|BPF_IND: 226153151Sjkim ZERO_EAX(); 227153151Sjkim MOVid(ECX, ins->k); 228153151Sjkim ADDrd(ECX, EDX); 229153151Sjkim MOVrd(ESI, ECX); 230153151Sjkim ADDib(ECX, sizeof(short)); 231153151Sjkim CMPodd(ECX, EBP, 0x10); 232153151Sjkim JLEb(5); 233153151Sjkim POP(EBX); 234153151Sjkim POP(ESI); 235153151Sjkim POP(EDI); 236153151Sjkim LEAVE_RET(); 237153151Sjkim MOVobw(AX, EBX, ESI); 238153151Sjkim SWAP_AX(); 239153151Sjkim break; 240153151Sjkim 241153151Sjkim case BPF_LD|BPF_B|BPF_IND: 242153151Sjkim ZERO_EAX(); 243153151Sjkim MOVid(ECX, ins->k); 244153151Sjkim ADDrd(ECX, EDX); 245153151Sjkim CMPodd(ECX, EBP, 0x10); 246153151Sjkim JLEb(5); 247153151Sjkim POP(EBX); 248153151Sjkim POP(ESI); 249153151Sjkim POP(EDI); 250153151Sjkim LEAVE_RET(); 251153151Sjkim MOVobb(AL, EBX, ECX); 252153151Sjkim break; 253153151Sjkim 254153151Sjkim case BPF_LDX|BPF_MSH|BPF_B: 255153151Sjkim MOVid(ECX, ins->k); 256153151Sjkim CMPodd(ECX, EBP, 0x10); 257153151Sjkim JLEb(7); 258153151Sjkim ZERO_EAX(); 259153151Sjkim POP(EBX); 260153151Sjkim POP(ESI); 261153151Sjkim POP(EDI); 262153151Sjkim LEAVE_RET(); 263153151Sjkim MOVid(EDX, 0); 264153151Sjkim MOVobb(DL, EBX, ECX); 265153151Sjkim ANDib(DL, 0xf); 266153151Sjkim SHLib(EDX, 2); 267153151Sjkim break; 268153151Sjkim 269153151Sjkim case BPF_LD|BPF_IMM: 270153151Sjkim MOVid(EAX, ins->k); 271153151Sjkim break; 272153151Sjkim 273153151Sjkim case BPF_LDX|BPF_IMM: 274153151Sjkim MOVid(EDX, ins->k); 275153151Sjkim break; 276153151Sjkim 277153151Sjkim case BPF_LD|BPF_MEM: 278153151Sjkim MOVid(ECX, (uintptr_t)mem); 279153151Sjkim MOVid(ESI, ins->k * 4); 280153151Sjkim MOVobd(EAX, ECX, ESI); 281153151Sjkim break; 282153151Sjkim 283153151Sjkim case BPF_LDX|BPF_MEM: 284153151Sjkim MOVid(ECX, (uintptr_t)mem); 285153151Sjkim MOVid(ESI, ins->k * 4); 286153151Sjkim MOVobd(EDX, ECX, ESI); 287153151Sjkim break; 288153151Sjkim 289153151Sjkim case BPF_ST: 290153151Sjkim /* 291153151Sjkim * XXX this command and the following could 292153151Sjkim * be optimized if the previous instruction 293153151Sjkim * was already of this type 294153151Sjkim */ 295153151Sjkim MOVid(ECX, (uintptr_t)mem); 296153151Sjkim MOVid(ESI, ins->k * 4); 297153151Sjkim MOVomd(ECX, ESI, EAX); 298153151Sjkim break; 299153151Sjkim 300153151Sjkim case BPF_STX: 301153151Sjkim MOVid(ECX, (uintptr_t)mem); 302153151Sjkim MOVid(ESI, ins->k * 4); 303153151Sjkim MOVomd(ECX, ESI, EDX); 304153151Sjkim break; 305153151Sjkim 306153151Sjkim case BPF_JMP|BPF_JA: 307153151Sjkim JMP(stream.refs[stream.bpf_pc + ins->k] - 308153151Sjkim stream.refs[stream.bpf_pc]); 309153151Sjkim break; 310153151Sjkim 311153151Sjkim case BPF_JMP|BPF_JGT|BPF_K: 312153151Sjkim CMPid(EAX, ins->k); 313153151Sjkim /* 5 is the size of the following JMP */ 314153151Sjkim JG(stream.refs[stream.bpf_pc + ins->jt] - 315153151Sjkim stream.refs[stream.bpf_pc] + 5 ); 316153151Sjkim JMP(stream.refs[stream.bpf_pc + ins->jf] - 317153151Sjkim stream.refs[stream.bpf_pc]); 318153151Sjkim break; 319153151Sjkim 320153151Sjkim case BPF_JMP|BPF_JGE|BPF_K: 321153151Sjkim CMPid(EAX, ins->k); 322153151Sjkim JGE(stream.refs[stream.bpf_pc + ins->jt] - 323153151Sjkim stream.refs[stream.bpf_pc] + 5); 324153151Sjkim JMP(stream.refs[stream.bpf_pc + ins->jf] - 325153151Sjkim stream.refs[stream.bpf_pc]); 326153151Sjkim break; 327153151Sjkim 328153151Sjkim case BPF_JMP|BPF_JEQ|BPF_K: 329153151Sjkim CMPid(EAX, ins->k); 330153151Sjkim JE(stream.refs[stream.bpf_pc + ins->jt] - 331153151Sjkim stream.refs[stream.bpf_pc] + 5); 332153151Sjkim JMP(stream.refs[stream.bpf_pc + ins->jf] - 333153151Sjkim stream.refs[stream.bpf_pc]); 334153151Sjkim break; 335153151Sjkim 336153151Sjkim case BPF_JMP|BPF_JSET|BPF_K: 337153151Sjkim MOVrd(ECX, EAX); 338153151Sjkim ANDid(ECX, ins->k); 339153151Sjkim JE(stream.refs[stream.bpf_pc + ins->jf] - 340153151Sjkim stream.refs[stream.bpf_pc] + 5); 341153151Sjkim JMP(stream.refs[stream.bpf_pc + ins->jt] - 342153151Sjkim stream.refs[stream.bpf_pc]); 343153151Sjkim break; 344153151Sjkim 345153151Sjkim case BPF_JMP|BPF_JGT|BPF_X: 346153151Sjkim CMPrd(EAX, EDX); 347153151Sjkim JA(stream.refs[stream.bpf_pc + ins->jt] - 348153151Sjkim stream.refs[stream.bpf_pc] + 5); 349153151Sjkim JMP(stream.refs[stream.bpf_pc + ins->jf] - 350153151Sjkim stream.refs[stream.bpf_pc]); 351153151Sjkim break; 352153151Sjkim 353153151Sjkim case BPF_JMP|BPF_JGE|BPF_X: 354153151Sjkim CMPrd(EAX, EDX); 355153151Sjkim JAE(stream.refs[stream.bpf_pc + ins->jt] - 356153151Sjkim stream.refs[stream.bpf_pc] + 5); 357153151Sjkim JMP(stream.refs[stream.bpf_pc + ins->jf] - 358153151Sjkim stream.refs[stream.bpf_pc]); 359153151Sjkim break; 360153151Sjkim 361153151Sjkim case BPF_JMP|BPF_JEQ|BPF_X: 362153151Sjkim CMPrd(EAX, EDX); 363153151Sjkim JE(stream.refs[stream.bpf_pc + ins->jt] - 364153151Sjkim stream.refs[stream.bpf_pc] + 5); 365153151Sjkim JMP(stream.refs[stream.bpf_pc + ins->jf] - 366153151Sjkim stream.refs[stream.bpf_pc]); 367153151Sjkim break; 368153151Sjkim 369153151Sjkim case BPF_JMP|BPF_JSET|BPF_X: 370153151Sjkim MOVrd(ECX, EAX); 371153151Sjkim ANDrd(ECX, EDX); 372153151Sjkim JE(stream.refs[stream.bpf_pc + ins->jf] - 373153151Sjkim stream.refs[stream.bpf_pc] + 5); 374153151Sjkim JMP(stream.refs[stream.bpf_pc + ins->jt] - 375153151Sjkim stream.refs[stream.bpf_pc]); 376153151Sjkim break; 377153151Sjkim 378153151Sjkim case BPF_ALU|BPF_ADD|BPF_X: 379153151Sjkim ADDrd(EAX, EDX); 380153151Sjkim break; 381153151Sjkim 382153151Sjkim case BPF_ALU|BPF_SUB|BPF_X: 383153151Sjkim SUBrd(EAX, EDX); 384153151Sjkim break; 385153151Sjkim 386153151Sjkim case BPF_ALU|BPF_MUL|BPF_X: 387153151Sjkim MOVrd(ECX, EDX); 388153151Sjkim MULrd(EDX); 389153151Sjkim MOVrd(EDX, ECX); 390153151Sjkim break; 391153151Sjkim 392153151Sjkim case BPF_ALU|BPF_DIV|BPF_X: 393153151Sjkim CMPid(EDX, 0); 394153151Sjkim JNEb(7); 395153151Sjkim ZERO_EAX(); 396153151Sjkim POP(EBX); 397153151Sjkim POP(ESI); 398153151Sjkim POP(EDI); 399153151Sjkim LEAVE_RET(); 400153151Sjkim MOVrd(ECX, EDX); 401153151Sjkim MOVid(EDX, 0); 402153151Sjkim DIVrd(ECX); 403153151Sjkim MOVrd(EDX, ECX); 404153151Sjkim break; 405153151Sjkim 406153151Sjkim case BPF_ALU|BPF_AND|BPF_X: 407153151Sjkim ANDrd(EAX, EDX); 408153151Sjkim break; 409153151Sjkim 410153151Sjkim case BPF_ALU|BPF_OR|BPF_X: 411153151Sjkim ORrd(EAX, EDX); 412153151Sjkim break; 413153151Sjkim 414153151Sjkim case BPF_ALU|BPF_LSH|BPF_X: 415153151Sjkim MOVrd(ECX, EDX); 416153151Sjkim SHL_CLrb(EAX); 417153151Sjkim break; 418153151Sjkim 419153151Sjkim case BPF_ALU|BPF_RSH|BPF_X: 420153151Sjkim MOVrd(ECX, EDX); 421153151Sjkim SHR_CLrb(EAX); 422153151Sjkim break; 423153151Sjkim 424153151Sjkim case BPF_ALU|BPF_ADD|BPF_K: 425153151Sjkim ADD_EAXi(ins->k); 426153151Sjkim break; 427153151Sjkim 428153151Sjkim case BPF_ALU|BPF_SUB|BPF_K: 429153151Sjkim SUB_EAXi(ins->k); 430153151Sjkim break; 431153151Sjkim 432153151Sjkim case BPF_ALU|BPF_MUL|BPF_K: 433153151Sjkim MOVrd(ECX, EDX); 434153151Sjkim MOVid(EDX, ins->k); 435153151Sjkim MULrd(EDX); 436153151Sjkim MOVrd(EDX, ECX); 437153151Sjkim break; 438153151Sjkim 439153151Sjkim case BPF_ALU|BPF_DIV|BPF_K: 440153151Sjkim MOVrd(ECX, EDX); 441153151Sjkim MOVid(EDX, 0); 442153151Sjkim MOVid(ESI, ins->k); 443153151Sjkim DIVrd(ESI); 444153151Sjkim MOVrd(EDX, ECX); 445153151Sjkim break; 446153151Sjkim 447153151Sjkim case BPF_ALU|BPF_AND|BPF_K: 448153151Sjkim ANDid(EAX, ins->k); 449153151Sjkim break; 450153151Sjkim 451153151Sjkim case BPF_ALU|BPF_OR|BPF_K: 452153151Sjkim ORid(EAX, ins->k); 453153151Sjkim break; 454153151Sjkim 455153151Sjkim case BPF_ALU|BPF_LSH|BPF_K: 456153151Sjkim SHLib(EAX, (ins->k) & 255); 457153151Sjkim break; 458153151Sjkim 459153151Sjkim case BPF_ALU|BPF_RSH|BPF_K: 460153151Sjkim SHRib(EAX, (ins->k) & 255); 461153151Sjkim break; 462153151Sjkim 463153151Sjkim case BPF_ALU|BPF_NEG: 464153151Sjkim NEGd(EAX); 465153151Sjkim break; 466153151Sjkim 467153151Sjkim case BPF_MISC|BPF_TAX: 468153151Sjkim MOVrd(EDX, EAX); 469153151Sjkim break; 470153151Sjkim 471153151Sjkim case BPF_MISC|BPF_TXA: 472153151Sjkim MOVrd(EAX, EDX); 473153151Sjkim break; 474153151Sjkim } 475153151Sjkim ins++; 476153151Sjkim } 477153151Sjkim 478153151Sjkim pass++; 479153151Sjkim if (pass == 2) 480153151Sjkim break; 481153151Sjkim 482153151Sjkim stream.ibuf = (char *)malloc(stream.cur_ip, M_BPFJIT, M_WAITOK); 483153151Sjkim if (stream.ibuf == NULL) { 484153151Sjkim free(stream.refs, M_BPFJIT); 485153151Sjkim return NULL; 486153151Sjkim } 487153151Sjkim 488153151Sjkim /* 489153151Sjkim * modify the reference table to contain the offsets and 490153151Sjkim * not the lengths of the instructions 491153151Sjkim */ 492153151Sjkim for (i = 1; i < nins + 1; i++) 493153151Sjkim stream.refs[i] += stream.refs[i - 1]; 494153151Sjkim 495153151Sjkim /* Reset the counters */ 496153151Sjkim stream.cur_ip = 0; 497153151Sjkim stream.bpf_pc = 0; 498153151Sjkim 499153151Sjkim /* the second pass creates the actual code */ 500153151Sjkim emitm = emit_code; 501153151Sjkim } 502153151Sjkim 503153151Sjkim /* 504153151Sjkim * the reference table is needed only during compilation, 505153151Sjkim * now we can free it 506153151Sjkim */ 507153151Sjkim free(stream.refs, M_BPFJIT); 508153151Sjkim 509153151Sjkim return (bpf_filter_func)stream.ibuf; 510153151Sjkim} 511