bpf_jit_machdep.c revision 181645
11541Srgrimes/*-
21541Srgrimes * Copyright (c) 2002 - 2003 NetGroup, Politecnico di Torino (Italy)
31541Srgrimes * Copyright (c) 2005 Jung-uk Kim <jkim@FreeBSD.org>
41541Srgrimes * All rights reserved.
551138Salfred *
6194263Sjhb * Redistribution and use in source and binary forms, with or without
71541Srgrimes * modification, are permitted provided that the following conditions
81541Srgrimes * are met:
9106149Sdwmalone *
101541Srgrimes * 1. Redistributions of source code must retain the above copyright
1164002Speter * notice, this list of conditions and the following disclaimer.
121541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
131541Srgrimes * notice, this list of conditions and the following disclaimer in the
141541Srgrimes * documentation and/or other materials provided with the distribution.
151541Srgrimes * 3. Neither the name of the Politecnico di Torino nor the names of its
161541Srgrimes * contributors may be used to endorse or promote products derived from
171541Srgrimes * this software without specific prior written permission.
18171210Speter *
191541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
201541Srgrimes * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
211541Srgrimes * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
221541Srgrimes * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
231541Srgrimes * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
241541Srgrimes * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
251541Srgrimes * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
261541Srgrimes * DATA, OR PROFITS; OR BUSINESS intERRUPTION) HOWEVER CAUSED AND ON ANY
271541Srgrimes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28171210Speter * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29171210Speter * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
301541Srgrimes */
311541Srgrimes
321541Srgrimes#include <sys/cdefs.h>
331541Srgrimes__FBSDID("$FreeBSD: head/sys/i386/i386/bpf_jit_machdep.c 181645 2008-08-12 20:12:59Z jkim $");
341541Srgrimes
351541Srgrimes#include "opt_bpf.h"
361541Srgrimes
371541Srgrimes#include <sys/param.h>
381541Srgrimes#include <sys/systm.h>
391541Srgrimes#include <sys/kernel.h>
401541Srgrimes#include <sys/types.h>
411541Srgrimes#include <sys/socket.h>
421541Srgrimes#include <sys/malloc.h>
431541Srgrimes
441541Srgrimes#include <net/if.h>
451541Srgrimes#include <net/bpf.h>
461541Srgrimes#include <net/bpf_jitter.h>
471541Srgrimes
48171210Speter#include <i386/i386/bpf_jit_machdep.h>
491541Srgrimes
50171210Speterbpf_filter_func	bpf_jit_compile(struct bpf_insn *, u_int, int *);
511541Srgrimes
521541Srgrimes/*
531541Srgrimes * emit routine to update the jump table
541541Srgrimes */
551541Srgrimesstatic void
56171210Speteremit_length(bpf_bin_stream *stream, u_int value, u_int len)
571541Srgrimes{
58171210Speter
591541Srgrimes	(stream->refs)[stream->bpf_pc] += len;
601541Srgrimes	stream->cur_ip += len;
611541Srgrimes}
62171210Speter
631541Srgrimes/*
641541Srgrimes * emit routine to output the actual binary code
651541Srgrimes */
661541Srgrimesstatic void
671541Srgrimesemit_code(bpf_bin_stream *stream, u_int value, u_int len)
681541Srgrimes{
691541Srgrimes
701541Srgrimes	switch (len) {
711541Srgrimes	case 1:
72171210Speter		stream->ibuf[stream->cur_ip] = (u_char)value;
73171210Speter		stream->cur_ip++;
74171210Speter		break;
751541Srgrimes
761541Srgrimes	case 2:
771541Srgrimes		*((u_short *)(stream->ibuf + stream->cur_ip)) = (u_short)value;
781541Srgrimes		stream->cur_ip += 2;
791541Srgrimes		break;
801541Srgrimes
81171210Speter	case 4:
821541Srgrimes		*((u_int *)(stream->ibuf + stream->cur_ip)) = value;
831541Srgrimes		stream->cur_ip += 4;
841541Srgrimes		break;
851541Srgrimes	}
861541Srgrimes
871541Srgrimes	return;
881541Srgrimes}
891541Srgrimes
901541Srgrimes/*
911541Srgrimes * Function that does the real stuff
921541Srgrimes */
931541Srgrimesbpf_filter_func
94171210Speterbpf_jit_compile(struct bpf_insn *prog, u_int nins, int *mem)
951541Srgrimes{
961541Srgrimes	struct bpf_insn *ins;
97171210Speter	u_int i, pass;
98171210Speter	bpf_bin_stream stream;
991541Srgrimes
1001541Srgrimes	/*
1011541Srgrimes	 * NOTE: do not modify the name of this variable, as it's used by
1021541Srgrimes	 * the macros to emit code.
1031541Srgrimes	 */
1041541Srgrimes	emit_func emitm;
1051541Srgrimes
1061541Srgrimes	/* Do not compile an empty filter. */
1071541Srgrimes	if (nins == 0)
1081541Srgrimes		return NULL;
109171210Speter
1101541Srgrimes	/* Allocate the reference table for the jumps */
111171210Speter	stream.refs = (u_int *)malloc((nins + 1) * sizeof(u_int),
112171210Speter	    M_BPFJIT, M_NOWAIT);
113171210Speter	if (stream.refs == NULL)
1141541Srgrimes		return NULL;
1151541Srgrimes
1161541Srgrimes	/* Reset the reference table */
1171541Srgrimes	for (i = 0; i < nins + 1; i++)
118171210Speter		stream.refs[i] = 0;
119171210Speter
120171210Speter	stream.cur_ip = 0;
121171210Speter	stream.bpf_pc = 0;
122171210Speter
123171210Speter	/*
124171210Speter	 * the first pass will emit the lengths of the instructions
1251541Srgrimes	 * to create the reference table
1261541Srgrimes	 */
1271541Srgrimes	emitm = emit_length;
1281541Srgrimes
12914220Speter	pass = 0;
1301541Srgrimes	for (;;) {
1311541Srgrimes		ins = prog;
1321541Srgrimes
1331541Srgrimes		/* create the procedure header */
1341541Srgrimes		PUSH(EBP);
135171210Speter		MOVrd(ESP, EBP);
1368019Sache		PUSH(EDI);
1378019Sache		PUSH(ESI);
1381541Srgrimes		PUSH(EBX);
139171210Speter		MOVodd(8, EBP, EBX);
140171210Speter		MOVodd(16, EBP, EDI);
1411541Srgrimes
1421541Srgrimes		for (i = 0; i < nins; i++) {
1431541Srgrimes			stream.bpf_pc++;
1441541Srgrimes
1451541Srgrimes			switch (ins->code) {
1461541Srgrimes			default:
1471541Srgrimes				return NULL;
1481541Srgrimes
1491541Srgrimes			case BPF_RET|BPF_K:
1501541Srgrimes				MOVid(ins->k, EAX);
151171210Speter				POP(EBX);
152171210Speter				POP(ESI);
153171210Speter				POP(EDI);
154171210Speter				LEAVE_RET();
155171210Speter				break;
156171210Speter
1571541Srgrimes			case BPF_RET|BPF_A:
1581541Srgrimes				POP(EBX);
159171210Speter				POP(ESI);
160171210Speter				POP(EDI);
16114220Speter				LEAVE_RET();
16214220Speter				break;
16314220Speter
164177634Sdfr			case BPF_LD|BPF_W|BPF_ABS:
1651541Srgrimes				MOVid(ins->k, ECX);
166171210Speter				MOVrd(ECX, ESI);
167171210Speter				ADDib(sizeof(int), ECX);
168171210Speter				CMPrd(EDI, ECX);
1691541Srgrimes				JLEb(7);
170127891Sdfr				ZEROrd(EAX);
1711541Srgrimes				POP(EBX);
172184790Sed				POP(ESI);
173184790Sed				POP(EDI);
174184790Sed				LEAVE_RET();
1751549Srgrimes				MOVobd(EBX, ESI, EAX);
1762442Sdg				BSWAP(EAX);
1771541Srgrimes				break;
1781541Srgrimes
1792729Sdfr			case BPF_LD|BPF_H|BPF_ABS:
1802729Sdfr				ZEROrd(EAX);
1811541Srgrimes				MOVid(ins->k, ECX);
1821541Srgrimes				MOVrd(ECX, ESI);
183171210Speter				ADDib(sizeof(short), ECX);
184171210Speter				CMPrd(EDI, ECX);
185178888Sjulian				JLEb(5);
1862297Swollman				POP(EBX);
18714220Speter				POP(ESI);
18814220Speter				POP(EDI);
18914220Speter				LEAVE_RET();
1901541Srgrimes				MOVobw(EBX, ESI, AX);
1911541Srgrimes				SWAP_AX();
1921541Srgrimes				break;
1931541Srgrimes
19432889Sphk			case BPF_LD|BPF_B|BPF_ABS:
19532889Sphk				ZEROrd(EAX);
19632889Sphk				MOVid(ins->k, ECX);
19732889Sphk				CMPrd(EDI, ECX);
1981541Srgrimes				JLEb(5);
1991541Srgrimes				POP(EBX);
2001541Srgrimes				POP(ESI);
2011541Srgrimes				POP(EDI);
2021541Srgrimes				LEAVE_RET();
2031541Srgrimes				MOVobb(EBX, ECX, AL);
2041541Srgrimes				break;
2051541Srgrimes
2061541Srgrimes			case BPF_LD|BPF_W|BPF_LEN:
207171210Speter				MOVodd(0xc, EBP, EAX);
2081541Srgrimes				break;
209171210Speter
210171210Speter			case BPF_LDX|BPF_W|BPF_LEN:
211171210Speter				MOVodd(0xc, EBP, EDX);
2121541Srgrimes				break;
2131541Srgrimes
2141541Srgrimes			case BPF_LD|BPF_W|BPF_IND:
21535938Sdyson				MOVid(ins->k, ECX);
21635938Sdyson				ADDrd(EDX, ECX);
21728400Speter				MOVrd(ECX, ESI);
21825582Speter				ADDib(sizeof(int), ECX);
21929349Speter				CMPrd(EDI, ECX);
2202124Sdg				JLEb(7);
2212124Sdg				ZEROrd(EAX);
2222124Sdg				POP(EBX);
2232124Sdg				POP(ESI);
2242124Sdg				POP(EDI);
2252124Sdg				LEAVE_RET();
2262124Sdg				MOVobd(EBX, ESI, EAX);
2272124Sdg				BSWAP(EAX);
2282124Sdg				break;
2292124Sdg
23012865Speter			case BPF_LD|BPF_H|BPF_IND:
23112865Speter				ZEROrd(EAX);
23212865Speter				MOVid(ins->k, ECX);
23359829Speter				ADDrd(EDX, ECX);
23412865Speter				MOVrd(ECX, ESI);
23512865Speter				ADDib(sizeof(short), ECX);
23612865Speter				CMPrd(EDI, ECX);
23712865Speter				JLEb(5);
23812865Speter				POP(EBX);
23912865Speter				POP(ESI);
24012865Speter				POP(EDI);
24112865Speter				LEAVE_RET();
24225582Speter				MOVobw(EBX, ESI, AX);
24325582Speter				SWAP_AX();
24425582Speter				break;
245156138Sdavidxu
246156138Sdavidxu			case BPF_LD|BPF_B|BPF_IND:
247156138Sdavidxu				ZEROrd(EAX);
248156138Sdavidxu				MOVid(ins->k, ECX);
249156138Sdavidxu				ADDrd(EDX, ECX);
25025582Speter				CMPrd(EDI, ECX);
25114220Speter				JLEb(5);
25214220Speter				POP(EBX);
25314220Speter				POP(ESI);
25414220Speter				POP(EDI);
25514220Speter				LEAVE_RET();
25614220Speter				MOVobb(EBX, ECX, AL);
25714220Speter				break;
258137875Smarks
25914220Speter			case BPF_LDX|BPF_MSH|BPF_B:
26014220Speter				MOVid(ins->k, ECX);
26114220Speter				CMPrd(EDI, ECX);
26229349Speter				JLEb(7);
26324452Speter				ZEROrd(EAX);
26424440Speter				POP(EBX);
265151868Sdavidxu				POP(ESI);
266151868Sdavidxu				POP(EDI);
267151868Sdavidxu				LEAVE_RET();
268152846Sdavidxu				ZEROrd(EDX);
269152846Sdavidxu				MOVobb(EBX, ECX, DL);
270152846Sdavidxu				ANDib(0xf, DL);
271152846Sdavidxu				SHLib(2, EDX);
272152846Sdavidxu				break;
273152846Sdavidxu
27425537Sdfr			case BPF_LD|BPF_IMM:
27525537Sdfr				MOVid(ins->k, EAX);
27625537Sdfr				break;
27725537Sdfr
27825537Sdfr			case BPF_LDX|BPF_IMM:
27925537Sdfr				MOVid(ins->k, EDX);
28025537Sdfr				break;
28125537Sdfr
28235938Sdyson			case BPF_LD|BPF_MEM:
28325537Sdfr				MOVid((uintptr_t)mem, ECX);
28435938Sdyson				MOVid(ins->k * 4, ESI);
28535938Sdyson				MOVobd(ECX, ESI, EAX);
28635938Sdyson				break;
28735938Sdyson
28835938Sdyson			case BPF_LDX|BPF_MEM:
28935938Sdyson				MOVid((uintptr_t)mem, ECX);
29035938Sdyson				MOVid(ins->k * 4, ESI);
29125537Sdfr				MOVobd(ECX, ESI, EDX);
29225537Sdfr				break;
29325537Sdfr
29425537Sdfr			case BPF_ST:
29525537Sdfr				/*
29625537Sdfr				 * XXX this command and the following could
29725537Sdfr				 * be optimized if the previous instruction
29825537Sdfr				 * was already of this type
299147814Sjhb				 */
300147814Sjhb				MOVid((uintptr_t)mem, ECX);
30125537Sdfr				MOVid(ins->k * 4, ESI);
30225537Sdfr				MOVomd(EAX, ECX, ESI);
30325537Sdfr				break;
30425537Sdfr
30525537Sdfr			case BPF_STX:
30625537Sdfr				MOVid((uintptr_t)mem, ECX);
307171210Speter				MOVid(ins->k * 4, ESI);
30851138Salfred				MOVomd(EDX, ECX, ESI);
30951138Salfred				break;
31025537Sdfr
31125537Sdfr			case BPF_JMP|BPF_JA:
31225537Sdfr				JMP(stream.refs[stream.bpf_pc + ins->k] -
31325537Sdfr				    stream.refs[stream.bpf_pc]);
31425537Sdfr				break;
31525537Sdfr
31625537Sdfr			case BPF_JMP|BPF_JGT|BPF_K:
31725537Sdfr				CMPid(ins->k, EAX);
31825537Sdfr				/* 5 is the size of the following JMP */
31925537Sdfr				JG(stream.refs[stream.bpf_pc + ins->jt] -
32028400Speter				    stream.refs[stream.bpf_pc] + 5 );
32156115Speter				JMP(stream.refs[stream.bpf_pc + ins->jf] -
32256115Speter				    stream.refs[stream.bpf_pc]);
32336034Speter				break;
32426671Sdyson
32526671Sdyson			case BPF_JMP|BPF_JGE|BPF_K:
32626671Sdyson				CMPid(ins->k, EAX);
32726671Sdyson				JGE(stream.refs[stream.bpf_pc + ins->jt] -
328151868Sdavidxu				    stream.refs[stream.bpf_pc] + 5);
329151868Sdavidxu				JMP(stream.refs[stream.bpf_pc + ins->jf] -
330151868Sdavidxu				    stream.refs[stream.bpf_pc]);
33126671Sdyson				break;
33269514Sjake
33369514Sjake			case BPF_JMP|BPF_JEQ|BPF_K:
33426671Sdyson				CMPid(ins->k, EAX);
33526671Sdyson				JE(stream.refs[stream.bpf_pc + ins->jt] -
33629391Sphk				    stream.refs[stream.bpf_pc] + 5);
33734925Sdufault				JMP(stream.refs[stream.bpf_pc + ins->jf] -
33834925Sdufault				    stream.refs[stream.bpf_pc]);
33934925Sdufault				break;
34034925Sdufault
34134925Sdufault			case BPF_JMP|BPF_JSET|BPF_K:
34234925Sdufault				MOVrd(EAX, ECX);
34334925Sdufault				ANDid(ins->k, ECX);
34434925Sdufault				JE(stream.refs[stream.bpf_pc + ins->jf] -
34535938Sdyson				    stream.refs[stream.bpf_pc] + 5);
346171210Speter				JMP(stream.refs[stream.bpf_pc + ins->jt] -
34741089Speter				    stream.refs[stream.bpf_pc]);
34846155Sphk				break;
34949420Sjkh
35051791Smarcel			case BPF_JMP|BPF_JGT|BPF_X:
35151791Smarcel				CMPrd(EDX, EAX);
352171210Speter				JA(stream.refs[stream.bpf_pc + ins->jt] -
35351791Smarcel				    stream.refs[stream.bpf_pc] + 5);
354171210Speter				JMP(stream.refs[stream.bpf_pc + ins->jf] -
355112895Sjeff				    stream.refs[stream.bpf_pc]);
356112895Sjeff				break;
35756271Srwatson
35856271Srwatson			case BPF_JMP|BPF_JGE|BPF_X:
35956271Srwatson				CMPrd(EDX, EAX);
36056271Srwatson				JAE(stream.refs[stream.bpf_pc + ins->jt] -
36156271Srwatson				    stream.refs[stream.bpf_pc] + 5);
36256271Srwatson				JMP(stream.refs[stream.bpf_pc + ins->jf] -
36356271Srwatson				    stream.refs[stream.bpf_pc]);
36456271Srwatson				break;
36554803Srwatson
36654803Srwatson			case BPF_JMP|BPF_JEQ|BPF_X:
36754803Srwatson				CMPrd(EDX, EAX);
36854803Srwatson				JE(stream.refs[stream.bpf_pc + ins->jt] -
36955943Sjasone				    stream.refs[stream.bpf_pc] + 5);
37056115Speter				JMP(stream.refs[stream.bpf_pc + ins->jf] -
37156115Speter				    stream.refs[stream.bpf_pc]);
37259288Sjlemon				break;
37359288Sjlemon
37498198Srwatson			case BPF_JMP|BPF_JSET|BPF_X:
37598198Srwatson				MOVrd(EAX, ECX);
37698198Srwatson				ANDrd(EDX, ECX);
37798198Srwatson				JE(stream.refs[stream.bpf_pc + ins->jf] -
37898198Srwatson				    stream.refs[stream.bpf_pc] + 5);
37998198Srwatson				JMP(stream.refs[stream.bpf_pc + ins->jt] -
380183362Sjhb				    stream.refs[stream.bpf_pc]);
38175039Srwatson				break;
38275039Srwatson
38375039Srwatson			case BPF_ALU|BPF_ADD|BPF_X:
38475427Srwatson				ADDrd(EDX, EAX);
38583652Speter				break;
38683796Srwatson
38784884Srwatson			case BPF_ALU|BPF_SUB|BPF_X:
38885891Sphk				SUBrd(EDX, EAX);
389177091Sjeff				break;
390177091Sjeff
391177091Sjeff			case BPF_ALU|BPF_MUL|BPF_X:
392177091Sjeff				MOVrd(EDX, ECX);
393177091Sjeff				MULrd(EDX);
394100897Srwatson				MOVrd(ECX, EDX);
395100897Srwatson				break;
396100897Srwatson
397100897Srwatson			case BPF_ALU|BPF_DIV|BPF_X:
398100897Srwatson				CMPid(0, EDX);
399100897Srwatson				JNEb(7);
40094936Smux				ZEROrd(EAX);
40196084Smux				POP(EBX);
40297372Smarcel				POP(ESI);
40399856Salfred				POP(EDI);
404101426Srwatson				LEAVE_RET();
405122540Smckusick				MOVrd(EDX, ECX);
406122540Smckusick				ZEROrd(EDX);
407122540Smckusick				DIVrd(ECX);
408122540Smckusick				MOVrd(ECX, EDX);
409103575Salfred				break;
410103575Salfred
411103575Salfred			case BPF_ALU|BPF_AND|BPF_X:
412103575Salfred				ANDrd(EDX, EAX);
413103575Salfred				break;
414103575Salfred
415103575Salfred			case BPF_ALU|BPF_OR|BPF_X:
416103575Salfred				ORrd(EDX, EAX);
417103575Salfred				break;
418103575Salfred
419105692Srwatson			case BPF_ALU|BPF_LSH|BPF_X:
420105692Srwatson				MOVrd(EDX, ECX);
421105692Srwatson				SHL_CLrb(EAX);
422104731Srwatson				break;
423104731Srwatson
424104731Srwatson			case BPF_ALU|BPF_RSH|BPF_X:
425106467Srwatson				MOVrd(EDX, ECX);
426105950Speter				SHR_CLrb(EAX);
427105950Speter				break;
428105692Srwatson
429105692Srwatson			case BPF_ALU|BPF_ADD|BPF_K:
430105692Srwatson				ADD_EAXi(ins->k);
431106978Sdeischen				break;
432106978Sdeischen
433106978Sdeischen			case BPF_ALU|BPF_SUB|BPF_K:
434107914Sdillon				SUB_EAXi(ins->k);
435108406Srwatson				break;
436108406Srwatson
437108406Srwatson			case BPF_ALU|BPF_MUL|BPF_K:
438108406Srwatson				MOVrd(EDX, ECX);
439112895Sjeff				MOVid(ins->k, EDX);
440112902Sjeff				MULrd(EDX);
441112902Sjeff				MOVrd(ECX, EDX);
442112902Sjeff				break;
443112902Sjeff
444112909Sjeff			case BPF_ALU|BPF_DIV|BPF_K:
445112909Sjeff				MOVrd(EDX, ECX);
446113276Smike				ZEROrd(EDX);
447115800Srwatson				MOVid(ins->k, ESI);
448115800Srwatson				DIVrd(ESI);
449115800Srwatson				MOVrd(ECX, EDX);
450177091Sjeff				break;
451125369Sdeischen
452127484Smtm			case BPF_ALU|BPF_AND|BPF_K:
453127484Smtm				ANDid(ins->k, EAX);
454132117Sphk				break;
455136831Srwatson
456136831Srwatson			case BPF_ALU|BPF_OR|BPF_K:
457136831Srwatson				ORid(ins->k, EAX);
458136831Srwatson				break;
459136831Srwatson
460136831Srwatson			case BPF_ALU|BPF_LSH|BPF_K:
461136831Srwatson				SHLib((ins->k) & 0xff, EAX);
462136831Srwatson				break;
463136831Srwatson
464139013Sdavidxu			case BPF_ALU|BPF_RSH|BPF_K:
465145435Sdavidxu				SHRib((ins->k) & 0xff, EAX);
466151317Sdavidxu				break;
467156138Sdavidxu
468156138Sdavidxu			case BPF_ALU|BPF_NEG:
469156138Sdavidxu				NEGd(EAX);
470156138Sdavidxu				break;
471156138Sdavidxu
472156138Sdavidxu			case BPF_MISC|BPF_TAX:
473153681Sphk				MOVrd(EAX, EDX);
474155328Sdavidxu				break;
475157039Sdavidxu
476162498Sdavidxu			case BPF_MISC|BPF_TXA:
477162498Sdavidxu				MOVrd(EDX, EAX);
478162498Sdavidxu				break;
479161679Sdavidxu			}
480161679Sdavidxu			ins++;
481163953Srrs		}
482163953Srrs
483163953Srrs		pass++;
484163953Srrs		if (pass == 2)
485171210Speter			break;
486171210Speter
487171210Speter		stream.ibuf = (char *)malloc(stream.cur_ip, M_BPFJIT, M_NOWAIT);
488171210Speter		if (stream.ibuf == NULL) {
489171210Speter			free(stream.refs, M_BPFJIT);
490171210Speter			return NULL;
491171861Sdavidxu		}
492175165Sjhb
493175165Sjhb		/*
494176731Sjeff		 * modify the reference table to contain the offsets and
495176731Sjeff		 * not the lengths of the instructions
496176731Sjeff		 */
497176731Sjeff		for (i = 1; i < nins + 1; i++)
498176731Sjeff			stream.refs[i] += stream.refs[i - 1];
499177790Skib
500177790Skib		/* Reset the counters */
501177790Skib		stream.cur_ip = 0;
502177790Skib		stream.bpf_pc = 0;
503177790Skib
504177790Skib		/* the second pass creates the actual code */
505177790Skib		emitm = emit_code;
506177790Skib	}
507177790Skib
508177790Skib	/*
509177790Skib	 * the reference table is needed only during compilation,
510177790Skib	 * now we can free it
511177790Skib	 */
512177790Skib	free(stream.refs, M_BPFJIT);
513177790Skib
514181905Sed	return (bpf_filter_func)stream.ibuf;
515184589Sdfr}
516191675Sjamie