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